]>
Commit | Line | Data |
---|---|---|
8e84c258 EK |
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 | ||
e26dc173 BC |
35 | /* How many frames until we start a-mpdu TX session */ |
36 | #define WCN36XX_AMPDU_START_THRESH 20 | |
37 | ||
8e84c258 EK |
38 | extern unsigned int wcn36xx_dbg_mask; |
39 | ||
40 | enum wcn36xx_debug_mask { | |
41 | WCN36XX_DBG_DXE = 0x00000001, | |
42 | WCN36XX_DBG_DXE_DUMP = 0x00000002, | |
43 | WCN36XX_DBG_SMD = 0x00000004, | |
44 | WCN36XX_DBG_SMD_DUMP = 0x00000008, | |
45 | WCN36XX_DBG_RX = 0x00000010, | |
46 | WCN36XX_DBG_RX_DUMP = 0x00000020, | |
47 | WCN36XX_DBG_TX = 0x00000040, | |
48 | WCN36XX_DBG_TX_DUMP = 0x00000080, | |
49 | WCN36XX_DBG_HAL = 0x00000100, | |
50 | WCN36XX_DBG_HAL_DUMP = 0x00000200, | |
51 | WCN36XX_DBG_MAC = 0x00000400, | |
52 | WCN36XX_DBG_BEACON = 0x00000800, | |
53 | WCN36XX_DBG_BEACON_DUMP = 0x00001000, | |
54 | WCN36XX_DBG_PMC = 0x00002000, | |
55 | WCN36XX_DBG_PMC_DUMP = 0x00004000, | |
56 | WCN36XX_DBG_ANY = 0xffffffff, | |
57 | }; | |
58 | ||
59 | #define wcn36xx_err(fmt, arg...) \ | |
684e55f5 | 60 | printk(KERN_ERR pr_fmt("ERROR " fmt), ##arg) |
8e84c258 EK |
61 | |
62 | #define wcn36xx_warn(fmt, arg...) \ | |
63 | printk(KERN_WARNING pr_fmt("WARNING " fmt), ##arg) | |
64 | ||
65 | #define wcn36xx_info(fmt, arg...) \ | |
66 | printk(KERN_INFO pr_fmt(fmt), ##arg) | |
67 | ||
68 | #define wcn36xx_dbg(mask, fmt, arg...) do { \ | |
69 | if (wcn36xx_dbg_mask & mask) \ | |
70 | printk(KERN_DEBUG pr_fmt(fmt), ##arg); \ | |
71 | } while (0) | |
72 | ||
73 | #define wcn36xx_dbg_dump(mask, prefix_str, buf, len) do { \ | |
74 | if (wcn36xx_dbg_mask & mask) \ | |
75 | print_hex_dump(KERN_DEBUG, pr_fmt(prefix_str), \ | |
76 | DUMP_PREFIX_OFFSET, 32, 1, \ | |
77 | buf, len, false); \ | |
78 | } while (0) | |
79 | ||
e26dc173 BC |
80 | enum wcn36xx_ampdu_state { |
81 | WCN36XX_AMPDU_NONE, | |
82 | WCN36XX_AMPDU_INIT, | |
83 | WCN36XX_AMPDU_START, | |
84 | WCN36XX_AMPDU_OPERATIONAL, | |
85 | }; | |
86 | ||
8e84c258 EK |
87 | #define WCN36XX_HW_CHANNEL(__wcn) (__wcn->hw->conf.chandef.chan->hw_value) |
88 | #define WCN36XX_BAND(__wcn) (__wcn->hw->conf.chandef.chan->band) | |
89 | #define WCN36XX_CENTER_FREQ(__wcn) (__wcn->hw->conf.chandef.chan->center_freq) | |
90 | #define WCN36XX_LISTEN_INTERVAL(__wcn) (__wcn->hw->conf.listen_interval) | |
91 | #define WCN36XX_FLAGS(__wcn) (__wcn->hw->flags) | |
92 | #define WCN36XX_MAX_POWER(__wcn) (__wcn->hw->conf.chandef.chan->max_power) | |
93 | ||
94 | static inline void buff_to_be(u32 *buf, size_t len) | |
95 | { | |
96 | int i; | |
97 | for (i = 0; i < len; i++) | |
98 | buf[i] = cpu_to_be32(buf[i]); | |
99 | } | |
100 | ||
101 | struct nv_data { | |
102 | int is_valid; | |
103 | u8 table; | |
104 | }; | |
105 | ||
106 | /* Interface for platform control path | |
107 | * | |
108 | * @open: hook must be called when wcn36xx wants to open control channel. | |
109 | * @tx: sends a buffer. | |
110 | */ | |
111 | struct wcn36xx_platform_ctrl_ops { | |
112 | int (*open)(void *drv_priv, void *rsp_cb); | |
113 | void (*close)(void); | |
114 | int (*tx)(char *buf, size_t len); | |
115 | int (*get_hw_mac)(u8 *addr); | |
116 | int (*smsm_change_state)(u32 clear_mask, u32 set_mask); | |
117 | }; | |
118 | ||
119 | /** | |
120 | * struct wcn36xx_vif - holds VIF related fields | |
121 | * | |
122 | * @bss_index: bss_index is initially set to 0xFF. bss_index is received from | |
123 | * HW after first config_bss call and must be used in delete_bss and | |
124 | * enter/exit_bmps. | |
125 | */ | |
126 | struct wcn36xx_vif { | |
127 | struct list_head list; | |
8e84c258 EK |
128 | u8 dtim_period; |
129 | enum ani_ed_type encrypt_type; | |
130 | bool is_joining; | |
043ce546 | 131 | bool sta_assoc; |
8e84c258 EK |
132 | struct wcn36xx_hal_mac_ssid ssid; |
133 | ||
134 | /* Power management */ | |
135 | enum wcn36xx_power_state pw_state; | |
136 | ||
137 | u8 bss_index; | |
8e84c258 EK |
138 | /* Returned from WCN36XX_HAL_ADD_STA_SELF_RSP */ |
139 | u8 self_sta_index; | |
140 | u8 self_dpu_desc_index; | |
2ba0b461 | 141 | u8 self_ucast_dpu_sign; |
8e84c258 EK |
142 | }; |
143 | ||
144 | /** | |
145 | * struct wcn36xx_sta - holds STA related fields | |
146 | * | |
147 | * @tid: traffic ID that is used during AMPDU and in TX BD. | |
148 | * @sta_index: STA index is returned from HW after config_sta call and is | |
149 | * used in both SMD channel and TX BD. | |
150 | * @dpu_desc_index: DPU descriptor index is returned from HW after config_sta | |
151 | * call and is used in TX BD. | |
152 | * @bss_sta_index: STA index is returned from HW after config_bss call and is | |
153 | * used in both SMD channel and TX BD. See table bellow when it is used. | |
154 | * @bss_dpu_desc_index: DPU descriptor index is returned from HW after | |
155 | * config_bss call and is used in TX BD. | |
156 | * ______________________________________________ | |
157 | * | | STA | AP | | |
158 | * |______________|_____________|_______________| | |
159 | * | TX BD |bss_sta_index| sta_index | | |
160 | * |______________|_____________|_______________| | |
161 | * |all SMD calls |bss_sta_index| sta_index | | |
162 | * |______________|_____________|_______________| | |
163 | * |smd_delete_sta| sta_index | sta_index | | |
164 | * |______________|_____________|_______________| | |
165 | */ | |
166 | struct wcn36xx_sta { | |
167 | struct wcn36xx_vif *vif; | |
168 | u16 aid; | |
169 | u16 tid; | |
170 | u8 sta_index; | |
171 | u8 dpu_desc_index; | |
82cad2a0 | 172 | u8 ucast_dpu_sign; |
8e84c258 EK |
173 | u8 bss_sta_index; |
174 | u8 bss_dpu_desc_index; | |
175 | bool is_data_encrypted; | |
176 | /* Rates */ | |
177 | struct wcn36xx_hal_supported_rates supported_rates; | |
e26dc173 BC |
178 | |
179 | spinlock_t ampdu_lock; /* protects next two fields */ | |
180 | enum wcn36xx_ampdu_state ampdu_state[16]; | |
181 | int non_agg_frame_ct; | |
8e84c258 EK |
182 | }; |
183 | struct wcn36xx_dxe_ch; | |
184 | struct wcn36xx { | |
185 | struct ieee80211_hw *hw; | |
186 | struct device *dev; | |
187 | struct list_head vif_list; | |
188 | ||
4bda7faf PF |
189 | const struct firmware *nv; |
190 | ||
8e84c258 EK |
191 | u8 fw_revision; |
192 | u8 fw_version; | |
193 | u8 fw_minor; | |
194 | u8 fw_major; | |
c951da46 | 195 | u32 fw_feat_caps[WCN36XX_HAL_CAPS_SIZE]; |
f2ed5d24 | 196 | u32 chip_version; |
8e84c258 EK |
197 | |
198 | /* extra byte for the NULL termination */ | |
199 | u8 crm_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | |
200 | u8 wlan_version[WCN36XX_HAL_VERSION_LENGTH + 1]; | |
201 | ||
202 | /* IRQs */ | |
203 | int tx_irq; | |
204 | int rx_irq; | |
205 | void __iomem *mmio; | |
206 | ||
207 | struct wcn36xx_platform_ctrl_ops *ctrl_ops; | |
208 | /* | |
209 | * smd_buf must be protected with smd_mutex to garantee | |
210 | * that all messages are sent one after another | |
211 | */ | |
212 | u8 *hal_buf; | |
213 | size_t hal_rsp_len; | |
214 | struct mutex hal_mutex; | |
215 | struct completion hal_rsp_compl; | |
216 | struct workqueue_struct *hal_ind_wq; | |
217 | struct work_struct hal_ind_work; | |
218 | struct mutex hal_ind_mutex; | |
219 | struct list_head hal_ind_queue; | |
220 | ||
221 | /* DXE channels */ | |
222 | struct wcn36xx_dxe_ch dxe_tx_l_ch; /* TX low */ | |
223 | struct wcn36xx_dxe_ch dxe_tx_h_ch; /* TX high */ | |
224 | struct wcn36xx_dxe_ch dxe_rx_l_ch; /* RX low */ | |
225 | struct wcn36xx_dxe_ch dxe_rx_h_ch; /* RX high */ | |
226 | ||
227 | /* For synchronization of DXE resources from BH, IRQ and WQ contexts */ | |
228 | spinlock_t dxe_lock; | |
229 | bool queues_stopped; | |
230 | ||
231 | /* Memory pools */ | |
232 | struct wcn36xx_dxe_mem_pool mgmt_mem_pool; | |
233 | struct wcn36xx_dxe_mem_pool data_mem_pool; | |
234 | ||
235 | struct sk_buff *tx_ack_skb; | |
236 | ||
237 | #ifdef CONFIG_WCN36XX_DEBUGFS | |
238 | /* Debug file system entry */ | |
239 | struct wcn36xx_dfs_entry dfs; | |
240 | #endif /* CONFIG_WCN36XX_DEBUGFS */ | |
241 | ||
242 | }; | |
243 | ||
f2ed5d24 PF |
244 | #define WCN36XX_CHIP_3660 0 |
245 | #define WCN36XX_CHIP_3680 1 | |
246 | ||
8e84c258 EK |
247 | static inline bool wcn36xx_is_fw_version(struct wcn36xx *wcn, |
248 | u8 major, | |
249 | u8 minor, | |
250 | u8 version, | |
251 | u8 revision) | |
252 | { | |
253 | return (wcn->fw_major == major && | |
254 | wcn->fw_minor == minor && | |
255 | wcn->fw_version == version && | |
256 | wcn->fw_revision == revision); | |
257 | } | |
258 | void wcn36xx_set_default_rates(struct wcn36xx_hal_supported_rates *rates); | |
259 | ||
e26dc173 BC |
260 | static inline |
261 | struct ieee80211_sta *wcn36xx_priv_to_sta(struct wcn36xx_sta *sta_priv) | |
262 | { | |
263 | return container_of((void *)sta_priv, struct ieee80211_sta, drv_priv); | |
264 | } | |
265 | ||
ce75877f PF |
266 | static inline |
267 | struct wcn36xx_vif *wcn36xx_vif_to_priv(struct ieee80211_vif *vif) | |
268 | { | |
269 | return (struct wcn36xx_vif *) vif->drv_priv; | |
270 | } | |
271 | ||
272 | static inline | |
273 | struct ieee80211_vif *wcn36xx_priv_to_vif(struct wcn36xx_vif *vif_priv) | |
274 | { | |
275 | return container_of((void *) vif_priv, struct ieee80211_vif, drv_priv); | |
276 | } | |
277 | ||
a92e4696 PF |
278 | static inline |
279 | struct wcn36xx_sta *wcn36xx_sta_to_priv(struct ieee80211_sta *sta) | |
280 | { | |
281 | return (struct wcn36xx_sta *)sta->drv_priv; | |
282 | } | |
283 | ||
8e84c258 | 284 | #endif /* _WCN36XX_H_ */ |