1 /* 2 * Copyright (c) 2013 Eugene Krasnikov <k.eugene.e@gmail.com> 3 * 4 * Permission to use, copy, modify, and/or distribute this software for any 5 * purpose with or without fee is hereby granted, provided that the above 6 * copyright notice and this permission notice appear in all copies. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef _WCN36XX_H_ 18 #define _WCN36XX_H_ 19 20 #include <linux/completion.h> 21 #include <linux/printk.h> 22 #include <linux/spinlock.h> 23 #include <net/mac80211.h> 24 25 #include "hal.h" 26 #include "smd.h" 27 #include "txrx.h" 28 #include "dxe.h" 29 #include "pmc.h" 30 #include "debug.h" 31 32 #define WLAN_NV_FILE "wlan/prima/WCNSS_qcom_wlan_nv.bin" 33 #define WCN36XX_AGGR_BUFFER_SIZE 64 34 35 /* How many frames until we start a-mpdu TX session */ 36 #define WCN36XX_AMPDU_START_THRESH 20 37 38 #define WCN36XX_MAX_SCAN_SSIDS 9 39 #define WCN36XX_MAX_SCAN_IE_LEN 500 40 41 extern unsigned int wcn36xx_dbg_mask; 42 43 enum wcn36xx_debug_mask { 44 WCN36XX_DBG_DXE = 0x00000001, 45 WCN36XX_DBG_DXE_DUMP = 0x00000002, 46 WCN36XX_DBG_SMD = 0x00000004, 47 WCN36XX_DBG_SMD_DUMP = 0x00000008, 48 WCN36XX_DBG_RX = 0x00000010, 49 WCN36XX_DBG_RX_DUMP = 0x00000020, 50 WCN36XX_DBG_TX = 0x00000040, 51 WCN36XX_DBG_TX_DUMP = 0x00000080, 52 WCN36XX_DBG_HAL = 0x00000100, 53 WCN36XX_DBG_HAL_DUMP = 0x00000200, 54 WCN36XX_DBG_MAC = 0x00000400, 55 WCN36XX_DBG_BEACON = 0x00000800, 56 WCN36XX_DBG_BEACON_DUMP = 0x00001000, 57 WCN36XX_DBG_PMC = 0x00002000, 58 WCN36XX_DBG_PMC_DUMP = 0x00004000, 59 WCN36XX_DBG_ANY = 0xffffffff, 60 }; 61 62 #define wcn36xx_err(fmt, arg...) \ 63 printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg) 64 65 #define wcn36xx_warn(fmt, arg...) \ 66 printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) 67 68 #define wcn36xx_info(fmt, arg...) \ 69 printk(KERN_INFO pr_fmt(fmt), ##arg) 70 71 #define wcn36xx_dbg(mask, fmt, arg...) do { \ 72 if (wcn36xx_dbg_mask & mask) \ 73 printk(KERN_DEBUG pr_fmt(fmt), ##arg); \ 74 } while (0) 75 76 #define wcn36xx_dbg_dump(mask, prefix_str, buf, len) do { \ 77 if (wcn36xx_dbg_mask & mask) \ 78 print_hex_dump(KERN_DEBUG, pr_fmt(prefix_str), \ 79 DUMP_PREFIX_OFFSET, 32, 1, \ 80 buf, len, false); \ 81 } while (0) 82 83 enum wcn36xx_ampdu_state { 84 WCN36XX_AMPDU_NONE, 85 WCN36XX_AMPDU_INIT, 86 WCN36XX_AMPDU_START, 87 WCN36XX_AMPDU_OPERATIONAL, 88 }; 89 90 #define WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value) 91 #define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) 92 #define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) 93 #define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) 94 #define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) 95 #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) 96 97 #define RF_UNKNOWN 0x0000 98 #define RF_IRIS_WCN3620 0x3620 99 100 static inline void buff_to_be(u32 *buf, size_t len) 101 { 102 int i; 103 for (i = 0; i < len; i++) 104 buf[i] = cpu_to_be32(buf[i]); 105 } 106 107 struct nv_data { 108 int is_valid; 109 u8 table; 110 }; 111 112 /** 113 * struct wcn36xx_vif - holds VIF related fields 114 * 115 * @bss_index: bss_index is initially set to 0xFF. bss_index is received from 116 * HW after first config_bss call and must be used in delete_bss and 117 * enter/exit_bmps. 118 */ 119 struct wcn36xx_vif { 120 struct list_head list; 121 u8 dtim_period; 122 enum ani_ed_type encrypt_type; 123 bool is_joining; 124 bool sta_assoc; 125 struct wcn36xx_hal_mac_ssid ssid; 126 127 /* Power management */ 128 enum wcn36xx_power_state pw_state; 129 130 u8 bss_index; 131 /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ 132 u8 self_sta_index; 133 u8 self_dpu_desc_index; 134 u8 self_ucast_dpu_sign; 135 }; 136 137 /** 138 * struct wcn36xx_sta - holds STA related fields 139 * 140 * @tid: traffic ID that is used during AMPDU and in TX BD. 141 * @sta_index: STA index is returned from HW after config_sta call and is 142 * used in both SMD channel and TX BD. 143 * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta 144 * call and is used in TX BD. 145 * @bss_sta_index: STA index is returned from HW after config_bss call and is 146 * used in both SMD channel and TX BD. See table bellow when it is used. 147 * @bss_dpu_desc_index: DPU descriptor index is returned from HW after 148 * config_bss call and is used in TX BD. 149 * ______________________________________________ 150 * | | STA | AP | 151 * |______________|_____________|_______________| 152 * | TX BD |bss_sta_index| sta_index | 153 * |______________|_____________|_______________| 154 * |all SMD calls |bss_sta_index| sta_index | 155 * |______________|_____________|_______________| 156 * |smd_delete_sta| sta_index | sta_index | 157 * |______________|_____________|_______________| 158 */ 159 struct wcn36xx_sta { 160 struct wcn36xx_vif *vif; 161 u16 aid; 162 u16 tid; 163 u8 sta_index; 164 u8 dpu_desc_index; 165 u8 ucast_dpu_sign; 166 u8 bss_sta_index; 167 u8 bss_dpu_desc_index; 168 bool is_data_encrypted; 169 /* Rates */ 170 struct wcn36xx_hal_supported_rates supported_rates; 171 172 spinlock_t ampdu_lock; /* protects next two fields */ 173 enum wcn36xx_ampdu_state ampdu_state[16]; 174 int non_agg_frame_ct; 175 }; 176 struct wcn36xx_dxe_ch; 177 struct wcn36xx { 178 struct ieee80211_hw *hw; 179 struct device *dev; 180 struct list_head vif_list; 181 182 const struct firmware *nv; 183 184 u8 fw_revision; 185 u8 fw_version; 186 u8 fw_minor; 187 u8 fw_major; 188 u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; 189 bool is_pronto; 190 191 /* extra byte for the NULL termination */ 192 u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 193 u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; 194 195 /* IRQs */ 196 int tx_irq; 197 int rx_irq; 198 void __iomem *ccu_base; 199 void __iomem *dxe_base; 200 201 struct rpmsg_endpoint *smd_channel; 202 203 struct qcom_smem_state *tx_enable_state; 204 unsigned tx_enable_state_bit; 205 struct qcom_smem_state *tx_rings_empty_state; 206 unsigned tx_rings_empty_state_bit; 207 208 /* prevents concurrent FW reconfiguration */ 209 struct mutex conf_mutex; 210 211 /* 212 * smd_buf must be protected with smd_mutex to garantee 213 * that all messages are sent one after another 214 */ 215 u8 *hal_buf; 216 size_t hal_rsp_len; 217 struct mutex hal_mutex; 218 struct completion hal_rsp_compl; 219 struct workqueue_struct *hal_ind_wq; 220 struct work_struct hal_ind_work; 221 spinlock_t hal_ind_lock; 222 struct list_head hal_ind_queue; 223 224 struct work_struct scan_work; 225 struct cfg80211_scan_request *scan_req; 226 int scan_freq; 227 int scan_band; 228 struct mutex scan_lock; 229 bool scan_aborted; 230 231 /* DXE channels */ 232 struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ 233 struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ 234 struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ 235 struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ 236 237 /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ 238 spinlock_t dxe_lock; 239 bool queues_stopped; 240 241 /* Memory pools */ 242 struct wcn36xx_dxe_mem_pool mgmt_mem_pool; 243 struct wcn36xx_dxe_mem_pool data_mem_pool; 244 245 struct sk_buff *tx_ack_skb; 246 247 /* RF module */ 248 unsigned rf_id; 249 250 #ifdef CONFIG_WCN36XX_DEBUGFS 251 /* Debug file system entry */ 252 struct wcn36xx_dfs_entry dfs; 253 #endif /* CONFIG_WCN36XX_DEBUGFS */ 254 255 }; 256 257 static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, 258 u8 major, 259 u8 minor, 260 u8 version, 261 u8 revision) 262 { 263 return (wcn->fw_major == major && 264 wcn->fw_minor == minor && 265 wcn->fw_version == version && 266 wcn->fw_revision == revision); 267 } 268 void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); 269 270 static inline 271 struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) 272 { 273 return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); 274 } 275 276 static inline 277 struct wcn36xx_vif *wcn36xx_vif_to_priv(struct ieee80211_vif *vif) 278 { 279 return (struct wcn36xx_vif *) vif->drv_priv; 280 } 281 282 static inline 283 struct ieee80211_vif *wcn36xx_priv_to_vif(struct wcn36xx_vif *vif_priv) 284 { 285 return container_of((void *) vif_priv, struct ieee80211_vif, drv_priv); 286 } 287 288 static inline 289 struct wcn36xx_sta *wcn36xx_sta_to_priv(struct ieee80211_sta *sta) 290 { 291 return (struct wcn36xx_sta *)sta->drv_priv; 292 } 293 294 #endif /* _WCN36XX_H_ */ 295