Commit | Line | Data |
---|---|---|
010c3a89 RC |
1 | /* |
2 | * Linux cfg80211 driver | |
3 | * | |
4 | * Copyright (C) 1999-2017, Broadcom Corporation | |
5 | * | |
6 | * Unless you and Broadcom execute a separate written software license | |
7 | * agreement governing use of this software, this software is licensed to you | |
8 | * under the terms of the GNU General Public License version 2 (the "GPL"), | |
9 | * available at http://www.broadcom.com/licenses/GPLv2.php, with the | |
10 | * following added to such license: | |
11 | * | |
12 | * As a special exception, the copyright holders of this software give you | |
13 | * permission to link this software with independent modules, and to copy and | |
14 | * distribute the resulting executable under terms of your choice, provided that | |
15 | * you also meet, for each linked independent module, the terms and conditions of | |
16 | * the license of that module. An independent module is a module which is not | |
17 | * derived from this software. The special exception does not apply to any | |
18 | * modifications of the software. | |
19 | * | |
20 | * Notwithstanding the above, under no circumstances may you combine this | |
21 | * software in any way with any other Broadcom software provided under a license | |
22 | * other than the GPL, without Broadcom's express prior written consent. | |
23 | * | |
24 | * | |
25 | * <<Broadcom-WL-IPTag/Open:>> | |
26 | * | |
27 | * $Id: wl_cfg80211.h 710862 2017-07-14 07:43:59Z $ | |
28 | */ | |
29 | ||
30 | /** | |
31 | * Older Linux versions support the 'iw' interface, more recent ones the 'cfg80211' interface. | |
32 | */ | |
33 | ||
34 | #ifndef _wl_cfg80211_h_ | |
35 | #define _wl_cfg80211_h_ | |
36 | ||
37 | #include <linux/wireless.h> | |
38 | #include <typedefs.h> | |
39 | #include <ethernet.h> | |
40 | #include <wlioctl.h> | |
41 | #include <linux/wireless.h> | |
42 | #include <net/cfg80211.h> | |
43 | #include <linux/rfkill.h> | |
44 | ||
45 | #include <dngl_stats.h> | |
46 | #include <dhd.h> | |
47 | #include <wl_cfgp2p.h> | |
d964ce36 | 48 | #include <wl_android.h> |
010c3a89 RC |
49 | struct wl_conf; |
50 | struct wl_iface; | |
51 | struct bcm_cfg80211; | |
52 | struct wl_security; | |
53 | struct wl_ibss; | |
54 | ||
55 | ||
56 | #define htod32(i) (i) | |
57 | #define htod16(i) (i) | |
58 | #define dtoh64(i) (i) | |
59 | #define dtoh32(i) (i) | |
60 | #define dtoh16(i) (i) | |
61 | #define htodchanspec(i) (i) | |
62 | #define dtohchanspec(i) (i) | |
63 | ||
64 | #define WL_DBG_NONE 0 | |
65 | #define WL_DBG_P2P_ACTION (1 << 5) | |
66 | #define WL_DBG_TRACE (1 << 4) | |
67 | #define WL_DBG_SCAN (1 << 3) | |
68 | #define WL_DBG_DBG (1 << 2) | |
69 | #define WL_DBG_INFO (1 << 1) | |
70 | #define WL_DBG_ERR (1 << 0) | |
71 | ||
72 | #ifdef DHD_LOG_DUMP | |
73 | extern void dhd_log_dump_write(int type, const char *fmt, ...); | |
74 | extern char *dhd_log_dump_get_timestamp(void); | |
75 | #ifndef _DHD_LOG_DUMP_DEFINITIONS_ | |
76 | #define DLD_BUF_TYPE_GENERAL 0 | |
77 | #define DLD_BUF_TYPE_SPECIAL 1 | |
78 | #define DHD_LOG_DUMP_WRITE(fmt, ...) dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, fmt, ##__VA_ARGS__) | |
79 | #define DHD_LOG_DUMP_WRITE_EX(fmt, ...) dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, fmt, ##__VA_ARGS__) | |
80 | #endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */ | |
81 | #endif /* DHD_LOG_DUMP */ | |
82 | ||
83 | /* 0 invalidates all debug messages. default is 1 */ | |
84 | #define WL_DBG_LEVEL 0xFF | |
85 | ||
86 | #ifdef CUSTOMER_HW4_DEBUG | |
87 | #define CFG80211_ERROR_TEXT "CFG80211-INFO2) " | |
88 | #else | |
89 | #define CFG80211_ERROR_TEXT "CFG80211-ERROR) " | |
90 | #endif /* CUSTOMER_HW4_DEBUG */ | |
91 | ||
92 | #if defined(DHD_DEBUG) | |
93 | #ifdef DHD_LOG_DUMP | |
94 | #define WL_ERR(args) \ | |
95 | do { \ | |
96 | if (wl_dbg_level & WL_DBG_ERR) { \ | |
97 | printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ | |
98 | printk args; \ | |
99 | DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \ | |
100 | DHD_LOG_DUMP_WRITE args; \ | |
101 | } \ | |
102 | } while (0) | |
103 | #define WL_ERR_MEM(args) \ | |
104 | do { \ | |
105 | if (wl_dbg_level & WL_DBG_ERR) { \ | |
106 | DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \ | |
107 | DHD_LOG_DUMP_WRITE args; \ | |
108 | } \ | |
109 | } while (0) | |
110 | #define WL_ERR_EX(args) \ | |
111 | do { \ | |
112 | if (wl_dbg_level & WL_DBG_ERR) { \ | |
113 | printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ | |
114 | printk args; \ | |
115 | DHD_LOG_DUMP_WRITE_EX("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \ | |
116 | DHD_LOG_DUMP_WRITE_EX args; \ | |
117 | } \ | |
118 | } while (0) | |
119 | #else | |
120 | #define WL_ERR(args) \ | |
121 | do { \ | |
122 | if (wl_dbg_level & WL_DBG_ERR) { \ | |
123 | printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ | |
124 | printk args; \ | |
125 | } \ | |
126 | } while (0) | |
127 | #define WL_ERR_MEM(args) WL_ERR(args) | |
128 | #define WL_ERR_EX(args) WL_ERR(args) | |
129 | #endif /* DHD_LOG_DUMP */ | |
130 | #else /* defined(DHD_DEBUG) */ | |
131 | #define WL_ERR(args) \ | |
132 | do { \ | |
133 | if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \ | |
134 | printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \ | |
135 | printk args; \ | |
136 | } \ | |
137 | } while (0) | |
138 | #define WL_ERR_MEM(args) WL_ERR(args) | |
139 | #define WL_ERR_EX(args) WL_ERR(args) | |
140 | #endif /* defined(DHD_DEBUG) */ | |
141 | ||
142 | #ifdef WL_INFORM | |
143 | #undef WL_INFORM | |
144 | #endif | |
145 | ||
146 | #define WL_INFORM(args) \ | |
147 | do { \ | |
148 | if (wl_dbg_level & WL_DBG_INFO) { \ | |
149 | printk(KERN_INFO "CFG80211-INFO) %s : ", __func__); \ | |
150 | printk args; \ | |
151 | } \ | |
152 | } while (0) | |
153 | ||
154 | ||
155 | #ifdef WL_SCAN | |
156 | #undef WL_SCAN | |
157 | #endif | |
158 | #define WL_SCAN(args) \ | |
159 | do { \ | |
160 | if (wl_dbg_level & WL_DBG_SCAN) { \ | |
161 | printk(KERN_INFO "CFG80211-SCAN) %s :", __func__); \ | |
162 | printk args; \ | |
163 | } \ | |
164 | } while (0) | |
165 | #ifdef WL_TRACE | |
166 | #undef WL_TRACE | |
167 | #endif | |
168 | #define WL_TRACE(args) \ | |
169 | do { \ | |
170 | if (wl_dbg_level & WL_DBG_TRACE) { \ | |
171 | printk(KERN_INFO "CFG80211-TRACE) %s :", __func__); \ | |
172 | printk args; \ | |
173 | } \ | |
174 | } while (0) | |
175 | #ifdef WL_TRACE_HW4 | |
176 | #undef WL_TRACE_HW4 | |
177 | #endif | |
178 | #ifdef CUSTOMER_HW4_DEBUG | |
179 | #define WL_TRACE_HW4(args) \ | |
180 | do { \ | |
181 | if (wl_dbg_level & WL_DBG_ERR) { \ | |
182 | printk(KERN_INFO "CFG80211-TRACE) %s : ", __func__); \ | |
183 | printk args; \ | |
184 | } \ | |
185 | } while (0) | |
186 | #else | |
187 | #define WL_TRACE_HW4 WL_TRACE | |
188 | #endif /* CUSTOMER_HW4_DEBUG */ | |
189 | #if (WL_DBG_LEVEL > 0) | |
190 | #define WL_DBG(args) \ | |
191 | do { \ | |
192 | if (wl_dbg_level & WL_DBG_DBG) { \ | |
193 | printk(KERN_INFO "CFG80211-DEBUG) %s :", __func__); \ | |
194 | printk args; \ | |
195 | } \ | |
196 | } while (0) | |
197 | #else /* !(WL_DBG_LEVEL > 0) */ | |
198 | #define WL_DBG(args) | |
199 | #endif /* (WL_DBG_LEVEL > 0) */ | |
200 | #define WL_PNO(x) | |
201 | #define WL_SD(x) | |
202 | ||
ccd15baf RC |
203 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0)) |
204 | #define ieee80211_band nl80211_band | |
205 | #define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ | |
206 | #define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ | |
207 | #define IEEE80211_NUM_BANDS NUM_NL80211_BANDS | |
208 | #endif | |
dfb0f3ae RC |
209 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)) |
210 | #ifdef WLMESH | |
211 | #undef WLMESH | |
212 | #endif | |
213 | #endif | |
010c3a89 RC |
214 | |
215 | #define WL_SCAN_RETRY_MAX 3 | |
216 | #define WL_NUM_PMKIDS_MAX MAXPMKID | |
217 | #define WL_SCAN_BUF_MAX (1024 * 8) | |
218 | #define WL_TLV_INFO_MAX 1500 | |
219 | #define WL_SCAN_IE_LEN_MAX 2048 | |
220 | #define WL_BSS_INFO_MAX 2048 | |
221 | #define WL_ASSOC_INFO_MAX 512 | |
222 | #define WL_IOCTL_LEN_MAX 2048 | |
223 | #define WL_EXTRA_BUF_MAX 2048 | |
224 | #define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1) | |
225 | #define WL_AP_MAX 256 | |
226 | #define WL_FILE_NAME_MAX 256 | |
227 | #define WL_DWELL_TIME 200 | |
228 | #define WL_MED_DWELL_TIME 400 | |
229 | #define WL_MIN_DWELL_TIME 100 | |
230 | #define WL_LONG_DWELL_TIME 1000 | |
231 | #define IFACE_MAX_CNT 4 | |
232 | #define WL_SCAN_CONNECT_DWELL_TIME_MS 200 | |
233 | #define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20 | |
234 | #define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320 | |
235 | #define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400 | |
236 | #define WL_AF_TX_MAX_RETRY 5 | |
237 | ||
238 | #define WL_AF_SEARCH_TIME_MAX 450 | |
239 | #define WL_AF_TX_EXTRA_TIME_MAX 200 | |
240 | ||
241 | #define WL_SCAN_TIMER_INTERVAL_MS 10000 /* Scan timeout */ | |
242 | #define WL_CHANNEL_SYNC_RETRY 5 | |
243 | #define WL_INVALID -1 | |
244 | ||
245 | #ifdef DHD_LOSSLESS_ROAMING | |
246 | #define WL_ROAM_TIMEOUT_MS 1000 /* Roam timeout */ | |
247 | #endif | |
248 | /* Bring down SCB Timeout to 20secs from 60secs default */ | |
249 | #ifndef WL_SCB_TIMEOUT | |
250 | #define WL_SCB_TIMEOUT 20 | |
251 | #endif | |
252 | ||
253 | #ifndef WL_SCB_ACTIVITY_TIME | |
254 | #define WL_SCB_ACTIVITY_TIME 5 | |
255 | #endif | |
256 | ||
257 | #ifndef WL_SCB_MAX_PROBE | |
258 | #define WL_SCB_MAX_PROBE 3 | |
259 | #endif | |
260 | ||
261 | #ifndef WL_MIN_PSPRETEND_THRESHOLD | |
262 | #define WL_MIN_PSPRETEND_THRESHOLD 2 | |
263 | #endif | |
264 | ||
265 | /* Cipher suites */ | |
266 | #define WLAN_CIPHER_SUITE_PMK 0x00904C00 | |
267 | ||
268 | #ifndef WLAN_AKM_SUITE_FT_8021X | |
269 | #define WLAN_AKM_SUITE_FT_8021X 0x000FAC03 | |
270 | #endif /* WLAN_AKM_SUITE_FT_8021X */ | |
271 | ||
272 | #ifndef WLAN_AKM_SUITE_FT_PSK | |
273 | #define WLAN_AKM_SUITE_FT_PSK 0x000FAC04 | |
274 | #endif /* WLAN_AKM_SUITE_FT_PSK */ | |
275 | ||
276 | /* | |
277 | * BRCM local. | |
278 | * Use a high number that's unlikely to clash with linux upstream for a while until we can | |
279 | * submit these changes to the community. | |
280 | */ | |
281 | #define NL80211_FEATURE_FW_4WAY_HANDSHAKE (1<<31) | |
282 | ||
283 | /* SCAN_SUPPRESS timer values in ms */ | |
284 | #define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */ | |
285 | #define WL_SCAN_SUPPRESS_RETRY 3000 | |
286 | ||
287 | #define WL_PM_ENABLE_TIMEOUT 10000 | |
288 | ||
289 | /* cfg80211 wowlan definitions */ | |
290 | #define WL_WOWLAN_MAX_PATTERNS 8 | |
291 | #define WL_WOWLAN_MIN_PATTERN_LEN 1 | |
292 | #define WL_WOWLAN_MAX_PATTERN_LEN 255 | |
293 | #define WL_WOWLAN_PKT_FILTER_ID_FIRST 201 | |
294 | #define WL_WOWLAN_PKT_FILTER_ID_LAST (WL_WOWLAN_PKT_FILTER_ID_FIRST + \ | |
295 | WL_WOWLAN_MAX_PATTERNS - 1) | |
296 | ||
297 | #ifdef WLTDLS | |
298 | #define TDLS_TUNNELED_PRB_REQ "\x7f\x50\x6f\x9a\04" | |
299 | #define TDLS_TUNNELED_PRB_RESP "\x7f\x50\x6f\x9a\05" | |
300 | #define TDLS_MAX_IFACE_FOR_ENABLE 1 | |
301 | #endif /* WLTDLS */ | |
302 | ||
303 | ||
304 | /* driver status */ | |
305 | enum wl_status { | |
306 | WL_STATUS_READY = 0, | |
307 | WL_STATUS_SCANNING, | |
308 | WL_STATUS_SCAN_ABORTING, | |
309 | WL_STATUS_CONNECTING, | |
310 | WL_STATUS_CONNECTED, | |
311 | WL_STATUS_DISCONNECTING, | |
312 | WL_STATUS_AP_CREATING, | |
313 | WL_STATUS_AP_CREATED, | |
314 | /* whole sending action frame procedure: | |
315 | * includes a) 'finding common channel' for public action request frame | |
316 | * and b) 'sending af via 'actframe' iovar' | |
317 | */ | |
318 | WL_STATUS_SENDING_ACT_FRM, | |
319 | /* find a peer to go to a common channel before sending public action req frame */ | |
320 | WL_STATUS_FINDING_COMMON_CHANNEL, | |
321 | /* waiting for next af to sync time of supplicant. | |
322 | * it includes SENDING_ACT_FRM and WAITING_NEXT_ACT_FRM_LISTEN | |
323 | */ | |
324 | WL_STATUS_WAITING_NEXT_ACT_FRM, | |
325 | #ifdef WL_CFG80211_SYNC_GON | |
326 | /* go to listen state to wait for next af after SENDING_ACT_FRM */ | |
327 | WL_STATUS_WAITING_NEXT_ACT_FRM_LISTEN, | |
328 | #endif /* WL_CFG80211_SYNC_GON */ | |
329 | /* it will be set when upper layer requests listen and succeed in setting listen mode. | |
330 | * if set, other scan request can abort current listen state | |
331 | */ | |
332 | WL_STATUS_REMAINING_ON_CHANNEL, | |
333 | #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST | |
334 | /* it's fake listen state to keep current scan state. | |
335 | * it will be set when upper layer requests listen but scan is running. then just run | |
336 | * a expire timer without actual listen state. | |
337 | * if set, other scan request does not need to abort scan. | |
338 | */ | |
339 | WL_STATUS_FAKE_REMAINING_ON_CHANNEL, | |
340 | #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ | |
341 | WL_STATUS_NESTED_CONNECT | |
342 | }; | |
343 | ||
32c27b7a RC |
344 | enum wl_ext_status { |
345 | WL_EXT_STATUS_DISCONNECTED = 0, | |
346 | WL_EXT_STATUS_SCAN, | |
347 | WL_EXT_STATUS_CONNECTING, | |
348 | WL_EXT_STATUS_CONNECTED, | |
349 | WL_EXT_STATUS_DELETE_GC, | |
350 | WL_EXT_STATUS_GC_DISCONNECTED, | |
351 | WL_EXT_STATUS_GC_CONNECTED, | |
352 | WL_EXT_STATUS_4WAY_START, | |
353 | WL_EXT_STATUS_4WAY_DONE | |
354 | }; | |
355 | ||
010c3a89 RC |
356 | /* wi-fi mode */ |
357 | enum wl_mode { | |
358 | WL_MODE_BSS, | |
359 | WL_MODE_IBSS, | |
dfb0f3ae RC |
360 | WL_MODE_AP, |
361 | #ifdef WLMESH | |
362 | WL_MODE_MESH | |
363 | #endif | |
010c3a89 RC |
364 | }; |
365 | ||
366 | /* driver profile list */ | |
367 | enum wl_prof_list { | |
368 | WL_PROF_MODE, | |
369 | WL_PROF_SSID, | |
370 | WL_PROF_SEC, | |
371 | WL_PROF_IBSS, | |
372 | WL_PROF_BAND, | |
373 | WL_PROF_CHAN, | |
374 | WL_PROF_BSSID, | |
375 | WL_PROF_ACT, | |
376 | WL_PROF_BEACONINT, | |
377 | WL_PROF_DTIMPERIOD | |
378 | }; | |
379 | ||
380 | /* donlge escan state */ | |
381 | enum wl_escan_state { | |
382 | WL_ESCAN_STATE_IDLE, | |
383 | WL_ESCAN_STATE_SCANING | |
384 | }; | |
385 | /* fw downloading status */ | |
386 | enum wl_fw_status { | |
387 | WL_FW_LOADING_DONE, | |
388 | WL_NVRAM_LOADING_DONE | |
389 | }; | |
390 | ||
391 | enum wl_management_type { | |
392 | WL_BEACON = 0x1, | |
393 | WL_PROBE_RESP = 0x2, | |
394 | WL_ASSOC_RESP = 0x4 | |
395 | }; | |
396 | ||
397 | enum wl_pm_workq_act_type { | |
398 | WL_PM_WORKQ_SHORT, | |
399 | WL_PM_WORKQ_LONG, | |
400 | WL_PM_WORKQ_DEL | |
401 | }; | |
402 | ||
403 | enum wl_tdls_config { | |
404 | TDLS_STATE_AP_CREATE, | |
405 | TDLS_STATE_AP_DELETE, | |
406 | TDLS_STATE_CONNECT, | |
407 | TDLS_STATE_DISCONNECT, | |
408 | TDLS_STATE_SETUP, | |
409 | TDLS_STATE_TEARDOWN, | |
410 | TDLS_STATE_IF_CREATE, | |
411 | TDLS_STATE_IF_DELETE | |
412 | }; | |
413 | ||
414 | /* beacon / probe_response */ | |
415 | struct beacon_proberesp { | |
416 | __le64 timestamp; | |
417 | __le16 beacon_int; | |
418 | __le16 capab_info; | |
419 | u8 variable[0]; | |
420 | } __attribute__ ((packed)); | |
421 | ||
422 | /* driver configuration */ | |
423 | struct wl_conf { | |
424 | u32 frag_threshold; | |
425 | u32 rts_threshold; | |
426 | u32 retry_short; | |
427 | u32 retry_long; | |
428 | s32 tx_power; | |
429 | struct ieee80211_channel channel; | |
430 | }; | |
431 | ||
432 | typedef s32(*EVENT_HANDLER) (struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, | |
433 | const wl_event_msg_t *e, void *data); | |
434 | ||
435 | /* bss inform structure for cfg80211 interface */ | |
436 | struct wl_cfg80211_bss_info { | |
437 | u16 band; | |
438 | u16 channel; | |
439 | s16 rssi; | |
440 | u16 frame_len; | |
441 | u8 frame_buf[1]; | |
442 | }; | |
443 | ||
444 | /* basic structure of scan request */ | |
445 | struct wl_scan_req { | |
446 | struct wlc_ssid ssid; | |
447 | }; | |
448 | ||
449 | /* basic structure of information element */ | |
450 | struct wl_ie { | |
451 | u16 offset; | |
452 | u8 buf[WL_TLV_INFO_MAX]; | |
453 | }; | |
454 | ||
455 | /* event queue for cfg80211 main event */ | |
456 | struct wl_event_q { | |
457 | struct list_head eq_list; | |
458 | u32 etype; | |
459 | wl_event_msg_t emsg; | |
460 | s8 edata[1]; | |
461 | }; | |
462 | ||
463 | /* security information with currently associated ap */ | |
464 | struct wl_security { | |
465 | u32 wpa_versions; | |
466 | u32 auth_type; | |
467 | u32 cipher_pairwise; | |
468 | u32 cipher_group; | |
469 | u32 wpa_auth; | |
470 | u32 auth_assoc_res_status; | |
471 | }; | |
472 | ||
473 | /* ibss information for currently joined ibss network */ | |
474 | struct wl_ibss { | |
475 | u8 beacon_interval; /* in millisecond */ | |
476 | u8 atim; /* in millisecond */ | |
477 | s8 join_only; | |
478 | u8 band; | |
479 | u8 channel; | |
480 | }; | |
481 | ||
482 | typedef struct wl_bss_vndr_ies { | |
483 | u8 probe_req_ie[VNDR_IES_BUF_LEN]; | |
484 | u8 probe_res_ie[VNDR_IES_MAX_BUF_LEN]; | |
485 | u8 assoc_req_ie[VNDR_IES_BUF_LEN]; | |
486 | u8 assoc_res_ie[VNDR_IES_BUF_LEN]; | |
487 | u8 beacon_ie[VNDR_IES_MAX_BUF_LEN]; | |
488 | u32 probe_req_ie_len; | |
489 | u32 probe_res_ie_len; | |
490 | u32 assoc_req_ie_len; | |
491 | u32 assoc_res_ie_len; | |
492 | u32 beacon_ie_len; | |
493 | } wl_bss_vndr_ies_t; | |
494 | ||
495 | typedef struct wl_cfgbss { | |
496 | u8 *wpa_ie; | |
497 | u8 *rsn_ie; | |
498 | u8 *wps_ie; | |
499 | bool security_mode; | |
500 | struct wl_bss_vndr_ies ies; /* Common for STA, P2P GC, GO, AP, P2P Disc Interface */ | |
501 | } wl_cfgbss_t; | |
502 | ||
503 | /* cfg driver profile */ | |
504 | struct wl_profile { | |
505 | u32 mode; | |
506 | s32 band; | |
507 | u32 channel; | |
508 | struct wlc_ssid ssid; | |
509 | struct wl_security sec; | |
510 | struct wl_ibss ibss; | |
511 | u8 bssid[ETHER_ADDR_LEN]; | |
512 | u16 beacon_interval; | |
513 | u8 dtim_period; | |
514 | bool active; | |
515 | }; | |
516 | ||
517 | struct net_info { | |
518 | struct net_device *ndev; | |
519 | struct wireless_dev *wdev; | |
520 | struct wl_profile profile; | |
521 | s32 mode; | |
522 | s32 roam_off; | |
523 | unsigned long sme_state; | |
524 | bool pm_restore; | |
525 | bool pm_block; | |
526 | s32 pm; | |
527 | s32 bssidx; | |
528 | wl_cfgbss_t bss; | |
529 | u32 ulb_bw; | |
530 | struct list_head list; /* list of all net_info structure */ | |
531 | }; | |
532 | ||
533 | /* association inform */ | |
534 | #define MAX_REQ_LINE 1024 | |
535 | struct wl_connect_info { | |
536 | u8 req_ie[MAX_REQ_LINE]; | |
537 | s32 req_ie_len; | |
538 | u8 resp_ie[MAX_REQ_LINE]; | |
539 | s32 resp_ie_len; | |
540 | }; | |
541 | ||
542 | /* firmware /nvram downloading controller */ | |
543 | struct wl_fw_ctrl { | |
544 | const struct firmware *fw_entry; | |
545 | unsigned long status; | |
546 | u32 ptr; | |
547 | s8 fw_name[WL_FILE_NAME_MAX]; | |
548 | s8 nvram_name[WL_FILE_NAME_MAX]; | |
549 | }; | |
550 | ||
551 | /* assoc ie length */ | |
552 | struct wl_assoc_ielen { | |
553 | u32 req_len; | |
554 | u32 resp_len; | |
555 | }; | |
556 | ||
557 | /* wpa2 pmk list */ | |
558 | struct wl_pmk_list { | |
559 | pmkid_list_t pmkids; | |
560 | pmkid_t foo[MAXPMKID - 1]; | |
561 | }; | |
562 | ||
563 | #ifdef DHD_MAX_IFS | |
564 | #define WL_MAX_IFS DHD_MAX_IFS | |
565 | #else | |
566 | #define WL_MAX_IFS 16 | |
567 | #endif | |
568 | ||
569 | #define ESCAN_BUF_SIZE (64 * 1024) | |
570 | ||
571 | struct escan_info { | |
572 | u32 escan_state; | |
573 | #ifdef STATIC_WL_PRIV_STRUCT | |
574 | #ifndef CONFIG_DHD_USE_STATIC_BUF | |
575 | #error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF | |
576 | #endif /* CONFIG_DHD_USE_STATIC_BUF */ | |
577 | u8 *escan_buf; | |
578 | #else | |
579 | u8 escan_buf[ESCAN_BUF_SIZE]; | |
580 | #endif /* STATIC_WL_PRIV_STRUCT */ | |
581 | struct wiphy *wiphy; | |
582 | struct net_device *ndev; | |
583 | }; | |
584 | ||
585 | #ifdef ESCAN_BUF_OVERFLOW_MGMT | |
586 | #define BUF_OVERFLOW_MGMT_COUNT 3 | |
587 | typedef struct { | |
588 | int RSSI; | |
589 | int length; | |
590 | struct ether_addr BSSID; | |
591 | } removal_element_t; | |
592 | #endif /* ESCAN_BUF_OVERFLOW_MGMT */ | |
593 | ||
594 | struct afx_hdl { | |
595 | wl_af_params_t *pending_tx_act_frm; | |
596 | struct ether_addr tx_dst_addr; | |
597 | struct net_device *dev; | |
598 | struct work_struct work; | |
599 | s32 bssidx; | |
600 | u32 retry; | |
601 | s32 peer_chan; | |
602 | s32 peer_listen_chan; /* search channel: configured by upper layer */ | |
603 | s32 my_listen_chan; /* listen chanel: extract it from prb req or gon req */ | |
604 | bool is_listen; | |
605 | bool ack_recv; | |
606 | bool is_active; | |
607 | }; | |
608 | ||
609 | struct parsed_ies { | |
610 | wpa_ie_fixed_t *wps_ie; | |
611 | u32 wps_ie_len; | |
612 | wpa_ie_fixed_t *wpa_ie; | |
613 | u32 wpa_ie_len; | |
614 | bcm_tlv_t *wpa2_ie; | |
615 | u32 wpa2_ie_len; | |
616 | }; | |
617 | ||
618 | ||
619 | #ifdef P2P_LISTEN_OFFLOADING | |
620 | typedef struct { | |
621 | uint16 period; /* listen offload period */ | |
622 | uint16 interval; /* listen offload interval */ | |
623 | uint16 count; /* listen offload count */ | |
624 | uint16 pad; /* pad for 32bit align */ | |
625 | } wl_p2plo_listen_t; | |
626 | #endif /* P2P_LISTEN_OFFLOADING */ | |
627 | ||
628 | #ifdef WL11U | |
629 | /* Max length of Interworking element */ | |
630 | #define IW_IES_MAX_BUF_LEN 9 | |
631 | #endif | |
632 | #define MAX_EVENT_BUF_NUM 16 | |
633 | typedef struct wl_eventmsg_buf { | |
634 | u16 num; | |
635 | struct { | |
636 | u16 type; | |
637 | bool set; | |
638 | } event [MAX_EVENT_BUF_NUM]; | |
639 | } wl_eventmsg_buf_t; | |
640 | ||
641 | typedef struct wl_if_event_info { | |
642 | bool valid; | |
643 | int ifidx; | |
644 | int bssidx; | |
645 | uint8 mac[ETHER_ADDR_LEN]; | |
646 | char name[IFNAMSIZ+1]; | |
647 | uint8 role; | |
648 | } wl_if_event_info; | |
649 | ||
650 | ||
651 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
652 | typedef struct ap_rps_info { | |
653 | bool enable; | |
654 | bool sta_assoc_check; | |
655 | int pps; | |
656 | int quiet_time; | |
657 | int level; | |
658 | } ap_rps_info_t; | |
659 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
660 | ||
661 | #ifdef SUPPORT_RSSI_LOGGING | |
662 | #define RSSILOG_FLAG_FEATURE_SW 0x1 | |
663 | #define RSSILOG_FLAG_REPORT_READY 0x2 | |
664 | typedef struct rssilog_set_param { | |
665 | uint8 enable; | |
666 | uint8 rssi_threshold; | |
667 | uint8 time_threshold; | |
668 | uint8 pad; | |
669 | } rssilog_set_param_t; | |
670 | ||
671 | typedef struct rssilog_get_param { | |
672 | uint8 report_count; | |
673 | uint8 enable; | |
674 | uint8 rssi_threshold; | |
675 | uint8 time_threshold; | |
676 | } rssilog_get_param_t; | |
677 | ||
678 | typedef struct rssi_ant_param { | |
679 | struct ether_addr ea; | |
680 | chanspec_t chanspec; | |
681 | } rssi_ant_param_t; | |
682 | ||
683 | typedef struct wl_rssi_ant_mimo { | |
684 | uint32 version; | |
685 | uint32 count; | |
686 | int8 rssi_ant[WL_RSSI_ANT_MAX]; | |
687 | int8 rssi_sum; | |
688 | int8 PAD[3]; | |
689 | } wl_rssi_ant_mimo_t; | |
690 | #endif /* SUPPORT_RSSI_LOGGING */ | |
691 | ||
692 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
693 | #define GET_BSS_INFO_LEN 90 | |
694 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
695 | ||
696 | ||
697 | /* private data of cfg80211 interface */ | |
698 | struct bcm_cfg80211 { | |
699 | struct wireless_dev *wdev; /* representing cfg cfg80211 device */ | |
700 | ||
701 | struct wireless_dev *p2p_wdev; /* representing cfg cfg80211 device for P2P */ | |
702 | struct net_device *p2p_net; /* reference to p2p0 interface */ | |
703 | ||
704 | struct wl_conf *conf; | |
705 | struct cfg80211_scan_request *scan_request; /* scan request object */ | |
706 | EVENT_HANDLER evt_handler[WLC_E_LAST]; | |
707 | struct list_head eq_list; /* used for event queue */ | |
708 | struct list_head net_list; /* used for struct net_info */ | |
709 | spinlock_t net_list_sync; /* to protect scan status (and others if needed) */ | |
710 | spinlock_t eq_lock; /* for event queue synchronization */ | |
711 | spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */ | |
712 | struct completion act_frm_scan; | |
713 | struct completion iface_disable; | |
714 | struct completion wait_next_af; | |
715 | struct mutex usr_sync; /* maily for up/down synchronization */ | |
716 | struct mutex if_sync; /* maily for iface op synchronization */ | |
717 | struct mutex scan_complete; /* serialize scan_complete call */ | |
718 | struct wl_scan_results *bss_list; | |
719 | struct wl_scan_results *scan_results; | |
720 | ||
721 | /* scan request object for internal purpose */ | |
722 | struct wl_scan_req *scan_req_int; | |
723 | /* information element object for internal purpose */ | |
724 | #if defined(STATIC_WL_PRIV_STRUCT) | |
725 | struct wl_ie *ie; | |
726 | #else | |
727 | struct wl_ie ie; | |
728 | #endif | |
729 | ||
730 | /* association information container */ | |
731 | #if defined(STATIC_WL_PRIV_STRUCT) | |
732 | struct wl_connect_info *conn_info; | |
733 | #else | |
734 | struct wl_connect_info conn_info; | |
735 | #endif | |
736 | #ifdef DEBUGFS_CFG80211 | |
737 | struct dentry *debugfs; | |
738 | #endif /* DEBUGFS_CFG80211 */ | |
739 | struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ | |
740 | tsk_ctl_t event_tsk; /* task of main event handler thread */ | |
741 | dhd_pub_t *pub; | |
742 | u32 iface_cnt; | |
743 | u32 channel; /* current channel */ | |
744 | u32 af_sent_channel; /* channel action frame is sent */ | |
745 | /* next af subtype to cancel the remained dwell time in rx process */ | |
746 | u8 next_af_subtype; | |
747 | #ifdef WL_CFG80211_SYNC_GON | |
748 | ulong af_tx_sent_jiffies; | |
749 | #endif /* WL_CFG80211_SYNC_GON */ | |
750 | struct escan_info escan_info; /* escan information */ | |
751 | bool active_scan; /* current scan mode */ | |
752 | bool ibss_starter; /* indicates this sta is ibss starter */ | |
753 | bool link_up; /* link/connection up flag */ | |
754 | ||
755 | /* indicate whether chip to support power save mode */ | |
756 | bool pwr_save; | |
757 | bool roam_on; /* on/off switch for self-roaming */ | |
758 | bool scan_tried; /* indicates if first scan attempted */ | |
dfb0f3ae | 759 | #if defined(BCMSDIO) || defined(BCMDBUS) |
010c3a89 RC |
760 | bool wlfc_on; |
761 | #endif | |
762 | bool vsdb_mode; | |
763 | #define WL_ROAM_OFF_ON_CONCURRENT 0x0001 | |
764 | #define WL_ROAM_REVERT_STATUS 0x0002 | |
765 | u32 roam_flags; | |
766 | u8 *ioctl_buf; /* ioctl buffer */ | |
767 | struct mutex ioctl_buf_sync; | |
768 | u8 *escan_ioctl_buf; | |
769 | u8 *extra_buf; /* maily to grab assoc information */ | |
770 | struct dentry *debugfsdir; | |
771 | struct rfkill *rfkill; | |
772 | bool rf_blocked; | |
773 | struct ieee80211_channel remain_on_chan; | |
774 | enum nl80211_channel_type remain_on_chan_type; | |
775 | u64 send_action_id; | |
776 | u64 last_roc_id; | |
777 | wait_queue_head_t netif_change_event; | |
778 | wl_if_event_info if_event_info; | |
779 | struct completion send_af_done; | |
780 | struct afx_hdl *afx_hdl; | |
781 | struct p2p_info *p2p; | |
782 | bool p2p_supported; | |
783 | void *btcoex_info; | |
784 | struct timer_list scan_timeout; /* Timer for catch scan event timeout */ | |
785 | #if defined(P2P_IE_MISSING_FIX) | |
786 | bool p2p_prb_noti; | |
787 | #endif | |
788 | s32(*state_notifier) (struct bcm_cfg80211 *cfg, | |
789 | struct net_info *_net_info, enum wl_status state, bool set); | |
790 | unsigned long interrested_state; | |
791 | wlc_ssid_t hostapd_ssid; | |
792 | #ifdef WL11U | |
793 | bool wl11u; | |
794 | #endif /* WL11U */ | |
795 | bool sched_scan_running; /* scheduled scan req status */ | |
796 | struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ | |
797 | bool scan_suppressed; | |
798 | struct timer_list scan_supp_timer; | |
799 | struct work_struct wlan_work; | |
800 | struct mutex event_sync; /* maily for up/down synchronization */ | |
801 | bool disable_roam_event; | |
802 | struct delayed_work pm_enable_work; | |
803 | struct workqueue_struct *event_workq; /* workqueue for event */ | |
804 | struct work_struct event_work; /* work item for event */ | |
805 | struct mutex pm_sync; /* mainly for pm work synchronization */ | |
806 | ||
807 | vndr_ie_setbuf_t *ibss_vsie; /* keep the VSIE for IBSS */ | |
808 | int ibss_vsie_len; | |
809 | #ifdef WL_RELMCAST | |
810 | u32 rmc_event_pid; | |
811 | u32 rmc_event_seq; | |
812 | #endif /* WL_RELMCAST */ | |
813 | #ifdef WLAIBSS_MCHAN | |
814 | struct ether_addr ibss_if_addr; | |
815 | bcm_struct_cfgdev *ibss_cfgdev; /* For AIBSS */ | |
816 | #endif /* WLAIBSS_MCHAN */ | |
817 | bool bss_pending_op; /* indicate where there is a pending IF operation */ | |
818 | int roam_offload; | |
819 | #ifdef WL_CFG80211_P2P_DEV_IF | |
820 | bool down_disc_if; | |
821 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
822 | #ifdef P2PLISTEN_AP_SAMECHN | |
823 | bool p2p_resp_apchn_status; | |
824 | #endif /* P2PLISTEN_AP_SAMECHN */ | |
825 | struct wl_wsec_key wep_key; | |
826 | #ifdef WLTDLS | |
827 | u8 *tdls_mgmt_frame; | |
828 | u32 tdls_mgmt_frame_len; | |
829 | s32 tdls_mgmt_freq; | |
830 | #endif /* WLTDLS */ | |
831 | bool need_wait_afrx; | |
832 | #ifdef QOS_MAP_SET | |
833 | uint8 *up_table; /* user priority table, size is UP_TABLE_MAX */ | |
834 | #endif /* QOS_MAP_SET */ | |
835 | struct ether_addr last_roamed_addr; | |
836 | bool rcc_enabled; /* flag for Roam channel cache feature */ | |
837 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
838 | char bss_info[GET_BSS_INFO_LEN]; | |
839 | wl_event_msg_t event_auth_assoc; | |
840 | u32 assoc_reject_status; | |
841 | u32 roam_count; | |
842 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
843 | u16 ap_oper_channel; | |
844 | #if defined(SUPPORT_RANDOM_MAC_SCAN) | |
845 | bool random_mac_enabled; | |
846 | #endif /* SUPPORT_RANDOM_MAC_SCAN */ | |
847 | #ifdef DHD_LOSSLESS_ROAMING | |
848 | struct timer_list roam_timeout; /* Timer for catch roam timeout */ | |
849 | #endif | |
850 | uint16 escan_sync_id_cntr; | |
851 | #ifdef WLTDLS | |
852 | uint8 tdls_supported; | |
853 | struct mutex tdls_sync; /* protect tdls config operations */ | |
854 | #endif /* WLTDLS */ | |
855 | #ifdef MFP | |
856 | uint8 *bip_pos; | |
857 | int mfp_mode; | |
858 | #endif /* MFP */ | |
859 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
860 | ap_rps_info_t ap_rps_info; | |
861 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
862 | #ifdef WBTEXT | |
863 | struct list_head wbtext_bssid_list; | |
864 | #endif /* WBTEXT */ | |
865 | struct list_head vndr_oui_list; | |
866 | ||
867 | #ifdef STAT_REPORT | |
868 | void *stat_report_info; | |
869 | #endif | |
dfb0f3ae RC |
870 | #ifdef WLMESH |
871 | char sae_password[SAE_MAX_PASSWD_LEN]; | |
872 | uint sae_password_len; | |
873 | #endif /* WLMESH */ | |
d964ce36 | 874 | #if defined(RSSIAVG) |
875 | wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; | |
876 | wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl; | |
877 | #endif | |
878 | #if defined(BSSCACHE) | |
879 | wl_bss_cache_ctrl_t g_bss_cache_ctrl; | |
880 | #endif | |
010c3a89 RC |
881 | int p2p_disconnected; // terence 20130703: Fix for wrong group_capab (timing issue) |
882 | struct ether_addr disconnected_bssid; | |
d964ce36 | 883 | int autochannel; |
884 | int best_2g_ch; | |
885 | int best_5g_ch; | |
886 | uint handshaking; | |
32c27b7a RC |
887 | bool wps_done; |
888 | wait_queue_head_t wps_done_event; | |
889 | struct mutex in4way_sync; | |
010c3a89 RC |
890 | }; |
891 | ||
892 | #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \ | |
893 | 4 && __GNUC_MINOR__ >= 6)) | |
894 | #define GCC_DIAGNOSTIC_PUSH() \ | |
895 | _Pragma("GCC diagnostic push") \ | |
896 | _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") | |
897 | #define GCC_DIAGNOSTIC_POP() \ | |
898 | _Pragma("GCC diagnostic pop") | |
899 | #else | |
900 | #define GCC_DIAGNOSTIC_PUSH() | |
901 | #define GCC_DIAGNOSTIC_POP() | |
902 | #endif /* STRICT_GCC_WARNINGS */ | |
903 | ||
904 | #define BCM_LIST_FOR_EACH_ENTRY_SAFE(pos, next, head, member) \ | |
905 | list_for_each_entry_safe((pos), (next), (head), member) | |
906 | extern int ioctl_version; | |
907 | ||
908 | static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss) | |
909 | { | |
910 | return bss = bss ? | |
911 | (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info; | |
912 | } | |
913 | ||
914 | static inline void | |
915 | wl_probe_wdev_all(struct bcm_cfg80211 *cfg) | |
916 | { | |
917 | struct net_info *_net_info, *next; | |
918 | unsigned long int flags; | |
919 | int idx = 0; | |
920 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
921 | GCC_DIAGNOSTIC_PUSH(); | |
922 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, | |
923 | &cfg->net_list, list) { | |
924 | WL_ERR(("%s: net_list[%d] bssidx: %d, " | |
925 | "ndev: %p, wdev: %p \n", __FUNCTION__, | |
926 | idx++, _net_info->bssidx, | |
927 | _net_info->ndev, _net_info->wdev)); | |
928 | } | |
929 | GCC_DIAGNOSTIC_POP(); | |
930 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
931 | return; | |
932 | } | |
933 | ||
934 | static inline struct net_info * | |
935 | wl_get_netinfo_by_bssidx(struct bcm_cfg80211 *cfg, s32 bssidx) | |
936 | { | |
937 | struct net_info *_net_info, *next, *info = NULL; | |
938 | unsigned long int flags; | |
939 | ||
940 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
941 | GCC_DIAGNOSTIC_PUSH(); | |
942 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
943 | if ((bssidx >= 0) && (_net_info->bssidx == bssidx)) { | |
944 | info = _net_info; | |
945 | break; | |
946 | } | |
947 | } | |
948 | GCC_DIAGNOSTIC_POP(); | |
949 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
950 | return info; | |
951 | } | |
952 | ||
953 | static inline void | |
954 | wl_dealloc_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
955 | { | |
956 | struct net_info *_net_info, *next; | |
957 | unsigned long int flags; | |
958 | ||
959 | #ifdef DHD_IFDEBUG | |
960 | WL_ERR(("dealloc_netinfo enter wdev=%p \n", wdev)); | |
961 | #endif | |
962 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
963 | GCC_DIAGNOSTIC_PUSH(); | |
964 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
965 | if (wdev && (_net_info->wdev == wdev)) { | |
966 | wl_cfgbss_t *bss = &_net_info->bss; | |
967 | ||
968 | kfree(bss->wpa_ie); | |
969 | bss->wpa_ie = NULL; | |
970 | kfree(bss->rsn_ie); | |
971 | bss->rsn_ie = NULL; | |
972 | kfree(bss->wps_ie); | |
973 | bss->wps_ie = NULL; | |
974 | list_del(&_net_info->list); | |
975 | cfg->iface_cnt--; | |
976 | kfree(_net_info); | |
977 | } | |
978 | } | |
979 | GCC_DIAGNOSTIC_POP(); | |
980 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
981 | #ifdef DHD_IFDEBUG | |
982 | WL_ERR(("dealloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt)); | |
983 | #endif | |
984 | } | |
985 | ||
986 | static inline s32 | |
987 | wl_alloc_netinfo(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
988 | struct wireless_dev * wdev, s32 mode, bool pm_block, u8 bssidx) | |
989 | { | |
990 | struct net_info *_net_info; | |
991 | s32 err = 0; | |
992 | unsigned long int flags; | |
993 | #ifdef DHD_IFDEBUG | |
994 | WL_ERR(("alloc_netinfo enter bssidx=%d wdev=%p ndev=%p\n", bssidx, wdev, ndev)); | |
995 | #endif | |
996 | /* Check whether there is any duplicate entry for the | |
997 | * same bssidx * | |
998 | */ | |
999 | if ((_net_info = wl_get_netinfo_by_bssidx(cfg, bssidx))) { | |
1000 | /* We have a duplicate entry for the same bssidx | |
1001 | * already present which shouldn't have been the case. | |
1002 | * Attempt recovery. | |
1003 | */ | |
1004 | WL_ERR(("Duplicate entry for bssidx=%d present\n", bssidx)); | |
1005 | wl_probe_wdev_all(cfg); | |
1006 | #ifdef DHD_DEBUG | |
1007 | ASSERT(0); | |
1008 | #endif /* DHD_DEBUG */ | |
1009 | WL_ERR(("Removing the Dup entry for bssidx=%d \n", bssidx)); | |
1010 | wl_dealloc_netinfo_by_wdev(cfg, _net_info->wdev); | |
1011 | } | |
1012 | if (cfg->iface_cnt == IFACE_MAX_CNT) | |
1013 | return -ENOMEM; | |
1014 | _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL); | |
1015 | if (!_net_info) | |
1016 | err = -ENOMEM; | |
1017 | else { | |
1018 | _net_info->mode = mode; | |
1019 | _net_info->ndev = ndev; | |
1020 | _net_info->wdev = wdev; | |
1021 | _net_info->pm_restore = 0; | |
1022 | _net_info->pm = 0; | |
1023 | _net_info->pm_block = pm_block; | |
1024 | _net_info->roam_off = WL_INVALID; | |
1025 | _net_info->bssidx = bssidx; | |
1026 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1027 | cfg->iface_cnt++; | |
1028 | list_add(&_net_info->list, &cfg->net_list); | |
1029 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1030 | } | |
1031 | #ifdef DHD_IFDEBUG | |
1032 | WL_ERR(("alloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt)); | |
1033 | #endif | |
1034 | return err; | |
1035 | } | |
1036 | ||
1037 | static inline void | |
1038 | wl_delete_all_netinfo(struct bcm_cfg80211 *cfg) | |
1039 | { | |
1040 | struct net_info *_net_info, *next; | |
1041 | unsigned long int flags; | |
1042 | ||
1043 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1044 | GCC_DIAGNOSTIC_PUSH(); | |
1045 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1046 | wl_cfgbss_t *bss = &_net_info->bss; | |
1047 | ||
1048 | kfree(bss->wpa_ie); | |
1049 | bss->wpa_ie = NULL; | |
1050 | kfree(bss->rsn_ie); | |
1051 | bss->rsn_ie = NULL; | |
1052 | kfree(bss->wps_ie); | |
1053 | bss->wps_ie = NULL; | |
1054 | list_del(&_net_info->list); | |
1055 | if (_net_info->wdev) | |
1056 | kfree(_net_info->wdev); | |
1057 | kfree(_net_info); | |
1058 | } | |
1059 | cfg->iface_cnt = 0; | |
1060 | GCC_DIAGNOSTIC_POP(); | |
1061 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1062 | } | |
1063 | static inline u32 | |
1064 | wl_get_status_all(struct bcm_cfg80211 *cfg, s32 status) | |
1065 | ||
1066 | { | |
1067 | struct net_info *_net_info, *next; | |
1068 | u32 cnt = 0; | |
1069 | unsigned long int flags; | |
1070 | ||
1071 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1072 | GCC_DIAGNOSTIC_PUSH(); | |
1073 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1074 | if (_net_info->ndev && | |
1075 | test_bit(status, &_net_info->sme_state)) | |
1076 | cnt++; | |
1077 | } | |
1078 | GCC_DIAGNOSTIC_POP(); | |
1079 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1080 | return cnt; | |
1081 | } | |
1082 | static inline void | |
1083 | wl_set_status_all(struct bcm_cfg80211 *cfg, s32 status, u32 op) | |
1084 | { | |
1085 | struct net_info *_net_info, *next; | |
1086 | unsigned long int flags; | |
1087 | ||
1088 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1089 | GCC_DIAGNOSTIC_PUSH(); | |
1090 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1091 | switch (op) { | |
1092 | case 1: | |
1093 | break; /* set all status is not allowed */ | |
1094 | case 2: | |
1095 | /* | |
1096 | * Release the spinlock before calling notifier. Else there | |
1097 | * will be nested calls | |
1098 | */ | |
1099 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1100 | clear_bit(status, &_net_info->sme_state); | |
1101 | if (cfg->state_notifier && | |
1102 | test_bit(status, &(cfg->interrested_state))) | |
1103 | cfg->state_notifier(cfg, _net_info, status, false); | |
1104 | return; | |
1105 | case 4: | |
1106 | break; /* change all status is not allowed */ | |
1107 | default: | |
1108 | break; /* unknown operation */ | |
1109 | } | |
1110 | } | |
1111 | GCC_DIAGNOSTIC_POP(); | |
1112 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1113 | } | |
1114 | static inline void | |
1115 | wl_set_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status, | |
1116 | struct net_device *ndev, u32 op) | |
1117 | { | |
1118 | ||
1119 | struct net_info *_net_info, *next; | |
1120 | unsigned long int flags; | |
1121 | ||
1122 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1123 | GCC_DIAGNOSTIC_PUSH(); | |
1124 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1125 | if (ndev && (_net_info->ndev == ndev)) { | |
1126 | switch (op) { | |
1127 | case 1: | |
1128 | /* | |
1129 | * Release the spinlock before calling notifier. Else there | |
1130 | * will be nested calls | |
1131 | */ | |
1132 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1133 | set_bit(status, &_net_info->sme_state); | |
1134 | if (cfg->state_notifier && | |
1135 | test_bit(status, &(cfg->interrested_state))) | |
1136 | cfg->state_notifier(cfg, _net_info, status, true); | |
1137 | return; | |
1138 | case 2: | |
1139 | /* | |
1140 | * Release the spinlock before calling notifier. Else there | |
1141 | * will be nested calls | |
1142 | */ | |
1143 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1144 | clear_bit(status, &_net_info->sme_state); | |
1145 | if (cfg->state_notifier && | |
1146 | test_bit(status, &(cfg->interrested_state))) | |
1147 | cfg->state_notifier(cfg, _net_info, status, false); | |
1148 | return; | |
1149 | case 4: | |
1150 | change_bit(status, &_net_info->sme_state); | |
1151 | break; | |
1152 | } | |
1153 | } | |
1154 | ||
1155 | } | |
1156 | GCC_DIAGNOSTIC_POP(); | |
1157 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1158 | ||
1159 | } | |
1160 | ||
1161 | static inline wl_cfgbss_t * | |
1162 | wl_get_cfgbss_by_wdev(struct bcm_cfg80211 *cfg, | |
1163 | struct wireless_dev *wdev) | |
1164 | { | |
1165 | struct net_info *_net_info, *next; | |
1166 | wl_cfgbss_t *bss = NULL; | |
1167 | unsigned long int flags; | |
1168 | ||
1169 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1170 | GCC_DIAGNOSTIC_PUSH(); | |
1171 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1172 | if (wdev && (_net_info->wdev == wdev)) { | |
1173 | bss = &_net_info->bss; | |
1174 | break; | |
1175 | } | |
1176 | } | |
1177 | GCC_DIAGNOSTIC_POP(); | |
1178 | ||
1179 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1180 | return bss; | |
1181 | } | |
1182 | ||
1183 | static inline u32 | |
1184 | wl_get_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status, | |
1185 | struct net_device *ndev) | |
1186 | { | |
1187 | struct net_info *_net_info, *next; | |
1188 | u32 stat = 0; | |
1189 | unsigned long int flags; | |
1190 | ||
1191 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1192 | GCC_DIAGNOSTIC_PUSH(); | |
1193 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1194 | if (ndev && (_net_info->ndev == ndev)) { | |
1195 | stat = test_bit(status, &_net_info->sme_state); | |
1196 | break; | |
1197 | } | |
1198 | } | |
1199 | GCC_DIAGNOSTIC_POP(); | |
1200 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1201 | return stat; | |
1202 | } | |
1203 | ||
1204 | static inline s32 | |
1205 | wl_get_mode_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1206 | { | |
1207 | struct net_info *_net_info, *next; | |
1208 | s32 mode = -1; | |
1209 | unsigned long int flags; | |
1210 | ||
1211 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1212 | GCC_DIAGNOSTIC_PUSH(); | |
1213 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1214 | if (ndev && (_net_info->ndev == ndev)) { | |
1215 | mode = _net_info->mode; | |
1216 | break; | |
1217 | } | |
1218 | } | |
1219 | GCC_DIAGNOSTIC_POP(); | |
1220 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1221 | return mode; | |
1222 | } | |
1223 | ||
1224 | static inline void | |
1225 | wl_set_mode_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
1226 | s32 mode) | |
1227 | { | |
1228 | struct net_info *_net_info, *next; | |
1229 | unsigned long int flags; | |
1230 | ||
1231 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1232 | GCC_DIAGNOSTIC_PUSH(); | |
1233 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1234 | if (ndev && (_net_info->ndev == ndev)) | |
1235 | _net_info->mode = mode; | |
1236 | } | |
1237 | GCC_DIAGNOSTIC_POP(); | |
1238 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1239 | } | |
1240 | ||
1241 | static inline s32 | |
1242 | wl_get_bssidx_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
1243 | { | |
1244 | struct net_info *_net_info, *next; | |
1245 | s32 bssidx = -1; | |
1246 | unsigned long int flags; | |
1247 | ||
1248 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1249 | GCC_DIAGNOSTIC_PUSH(); | |
1250 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1251 | if (_net_info->wdev && (_net_info->wdev == wdev)) { | |
1252 | bssidx = _net_info->bssidx; | |
1253 | break; | |
1254 | } | |
1255 | } | |
1256 | GCC_DIAGNOSTIC_POP(); | |
1257 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1258 | return bssidx; | |
1259 | } | |
1260 | ||
1261 | static inline struct wireless_dev * | |
1262 | wl_get_wdev_by_bssidx(struct bcm_cfg80211 *cfg, s32 bssidx) | |
1263 | { | |
1264 | struct net_info *_net_info, *next; | |
1265 | struct wireless_dev *wdev = NULL; | |
1266 | unsigned long int flags; | |
1267 | ||
1268 | if (bssidx < 0) | |
1269 | return NULL; | |
1270 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1271 | GCC_DIAGNOSTIC_PUSH(); | |
1272 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1273 | if (_net_info->bssidx == bssidx) { | |
1274 | wdev = _net_info->wdev; | |
1275 | break; | |
1276 | } | |
1277 | } | |
1278 | GCC_DIAGNOSTIC_POP(); | |
1279 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1280 | return wdev; | |
1281 | } | |
1282 | ||
1283 | static inline struct wl_profile * | |
1284 | wl_get_profile_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1285 | { | |
1286 | struct net_info *_net_info, *next; | |
1287 | struct wl_profile *prof = NULL; | |
1288 | unsigned long int flags; | |
1289 | ||
1290 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1291 | GCC_DIAGNOSTIC_PUSH(); | |
1292 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1293 | if (ndev && (_net_info->ndev == ndev)) { | |
1294 | prof = &_net_info->profile; | |
1295 | break; | |
1296 | } | |
1297 | } | |
1298 | GCC_DIAGNOSTIC_POP(); | |
1299 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1300 | return prof; | |
1301 | } | |
1302 | static inline struct net_info * | |
1303 | wl_get_netinfo_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1304 | { | |
1305 | struct net_info *_net_info, *next, *info = NULL; | |
1306 | unsigned long int flags; | |
1307 | ||
1308 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1309 | GCC_DIAGNOSTIC_PUSH(); | |
1310 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1311 | if (ndev && (_net_info->ndev == ndev)) { | |
1312 | info = _net_info; | |
1313 | break; | |
1314 | } | |
1315 | } | |
1316 | GCC_DIAGNOSTIC_POP(); | |
1317 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1318 | return info; | |
1319 | } | |
1320 | ||
1321 | static inline struct net_info * | |
1322 | wl_get_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
1323 | { | |
1324 | struct net_info *_net_info, *next, *info = NULL; | |
1325 | unsigned long int flags; | |
1326 | ||
1327 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1328 | GCC_DIAGNOSTIC_PUSH(); | |
1329 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1330 | if (wdev && (_net_info->wdev == wdev)) { | |
1331 | info = _net_info; | |
1332 | break; | |
1333 | } | |
1334 | } | |
1335 | GCC_DIAGNOSTIC_POP(); | |
1336 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1337 | return info; | |
1338 | } | |
1339 | ||
1340 | #define is_p2p_group_iface(wdev) (((wdev->iftype == NL80211_IFTYPE_P2P_GO) || \ | |
1341 | (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) ? 1 : 0) | |
1342 | #define bcmcfg_to_wiphy(cfg) (cfg->wdev->wiphy) | |
1343 | #define bcmcfg_to_prmry_ndev(cfg) (cfg->wdev->netdev) | |
1344 | #define bcmcfg_to_prmry_wdev(cfg) (cfg->wdev) | |
1345 | #define bcmcfg_to_p2p_wdev(cfg) (cfg->p2p_wdev) | |
1346 | #define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) | |
1347 | #define ndev_to_wdev(ndev) (ndev->ieee80211_ptr) | |
1348 | #define wdev_to_ndev(wdev) (wdev->netdev) | |
1349 | ||
1350 | #if defined(WL_ENABLE_P2P_IF) | |
1351 | #define ndev_to_wlc_ndev(ndev, cfg) ((ndev == cfg->p2p_net) ? \ | |
1352 | bcmcfg_to_prmry_ndev(cfg) : ndev) | |
1353 | #else | |
1354 | #define ndev_to_wlc_ndev(ndev, cfg) (ndev) | |
1355 | #endif /* WL_ENABLE_P2P_IF */ | |
1356 | ||
1357 | #define wdev_to_wlc_ndev(wdev, cfg) \ | |
1358 | (wdev_to_ndev(wdev) ? \ | |
1359 | wdev_to_ndev(wdev) : bcmcfg_to_prmry_ndev(cfg)) | |
1360 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1361 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) wdev_to_wlc_ndev(cfgdev, cfg) | |
1362 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_wdev(cfg) | |
1363 | #elif defined(WL_ENABLE_P2P_IF) | |
1364 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) ndev_to_wlc_ndev(cfgdev, cfg) | |
1365 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_ndev(cfg) | |
1366 | #else | |
1367 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) (cfgdev) | |
1368 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) (cfgdev) | |
1369 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1370 | ||
1371 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1372 | #define cfgdev_to_wdev(cfgdev) (cfgdev) | |
1373 | #define ndev_to_cfgdev(ndev) ndev_to_wdev(ndev) | |
1374 | #define cfgdev_to_ndev(cfgdev) (cfgdev ? (cfgdev->netdev) : NULL) | |
1375 | #define wdev_to_cfgdev(cfgdev) (cfgdev) | |
1376 | #define discover_cfgdev(cfgdev, cfg) (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) | |
1377 | #else | |
1378 | #define cfgdev_to_wdev(cfgdev) (cfgdev->ieee80211_ptr) | |
1379 | #define wdev_to_cfgdev(cfgdev) cfgdev ? (cfgdev->netdev) : NULL | |
1380 | #define ndev_to_cfgdev(ndev) (ndev) | |
1381 | #define cfgdev_to_ndev(cfgdev) (cfgdev) | |
1382 | #define discover_cfgdev(cfgdev, cfg) (cfgdev == cfg->p2p_net) | |
1383 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1384 | ||
1385 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1386 | #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \ | |
1387 | (cfg->scan_request->wdev == cfg->p2p_wdev)) ? true : false) | |
1388 | #elif defined(WL_ENABLE_P2P_IF) | |
1389 | #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \ | |
1390 | (cfg->scan_request->dev == cfg->p2p_net)) ? true : false) | |
1391 | #else | |
1392 | #define scan_req_match(cfg) (((cfg) && p2p_is_on(cfg) && p2p_scan(cfg)) ? \ | |
1393 | true : false) | |
1394 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1395 | ||
1396 | #define PRINT_WDEV_INFO(cfgdev) \ | |
1397 | { \ | |
1398 | struct wireless_dev *wdev = cfgdev_to_wdev(cfgdev); \ | |
1399 | struct net_device *netdev = wdev ? wdev->netdev : NULL; \ | |
1400 | WL_DBG(("wdev_ptr:%p ndev_ptr:%p ifname:%s iftype:%d\n", wdev, netdev, \ | |
1401 | netdev ? netdev->name : "NULL (non-ndev device)", \ | |
1402 | wdev ? wdev->iftype : 0xff)); \ | |
1403 | } | |
1404 | ||
1405 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) | |
1406 | #define scan_req_iftype(req) (req->dev->ieee80211_ptr->iftype) | |
1407 | #else | |
1408 | #define scan_req_iftype(req) (req->wdev->iftype) | |
1409 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) */ | |
1410 | ||
1411 | #define wl_to_sr(w) (w->scan_req_int) | |
1412 | #if defined(STATIC_WL_PRIV_STRUCT) | |
1413 | #define wl_to_ie(w) (w->ie) | |
1414 | #define wl_to_conn(w) (w->conn_info) | |
1415 | #else | |
1416 | #define wl_to_ie(w) (&w->ie) | |
1417 | #define wl_to_conn(w) (&w->conn_info) | |
1418 | #endif | |
1419 | #define wiphy_from_scan(w) (w->escan_info.wiphy) | |
1420 | #define wl_get_drv_status_all(cfg, stat) \ | |
1421 | (wl_get_status_all(cfg, WL_STATUS_ ## stat)) | |
1422 | #define wl_get_drv_status(cfg, stat, ndev) \ | |
1423 | (wl_get_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev)) | |
1424 | #define wl_set_drv_status(cfg, stat, ndev) \ | |
1425 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 1)) | |
1426 | #define wl_clr_drv_status(cfg, stat, ndev) \ | |
1427 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 2)) | |
1428 | #define wl_clr_drv_status_all(cfg, stat) \ | |
1429 | (wl_set_status_all(cfg, WL_STATUS_ ## stat, 2)) | |
1430 | #define wl_chg_drv_status(cfg, stat, ndev) \ | |
1431 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 4)) | |
1432 | ||
1433 | #define for_each_bss(list, bss, __i) \ | |
1434 | for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss)) | |
1435 | ||
1436 | #define for_each_ndev(cfg, iter, next) \ | |
1437 | list_for_each_entry_safe(iter, next, &cfg->net_list, list) | |
1438 | ||
1439 | /* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0. | |
1440 | * In addtion to that, wpa_version is WPA_VERSION_1 | |
1441 | */ | |
1442 | #define is_wps_conn(_sme) \ | |
1443 | ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \ | |
1444 | (!_sme->crypto.n_ciphers_pairwise) && \ | |
1445 | (!_sme->crypto.cipher_group)) | |
1446 | ||
1447 | #define IS_AKM_SUITE_FT(sec) ({BCM_REFERENCE(sec); FALSE;}) | |
1448 | ||
1449 | #define IS_AKM_SUITE_CCKM(sec) ({BCM_REFERENCE(sec); FALSE;}) | |
1450 | ||
1451 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) | |
1452 | #define STA_INFO_BIT(info) (1ul << NL80211_STA_ ## info) | |
1453 | #ifdef strnicmp | |
1454 | #undef strnicmp | |
1455 | #endif /* strnicmp */ | |
1456 | #define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len)) | |
1457 | #else | |
1458 | #define STA_INFO_BIT(info) (STATION_ ## info) | |
1459 | #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) */ | |
1460 | ||
1461 | extern s32 wl_cfg80211_attach(struct net_device *ndev, void *context); | |
1462 | extern void wl_cfg80211_detach(struct bcm_cfg80211 *cfg); | |
1463 | ||
1464 | extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, | |
1465 | void *data); | |
1466 | void wl_cfg80211_set_parent_dev(void *dev); | |
1467 | struct device *wl_cfg80211_get_parent_dev(void); | |
1468 | ||
1469 | /* clear IEs */ | |
1470 | extern s32 wl_cfg80211_clear_mgmt_vndr_ies(struct bcm_cfg80211 *cfg); | |
1471 | extern s32 wl_cfg80211_clear_per_bss_ies(struct bcm_cfg80211 *cfg, s32 bssidx); | |
1472 | ||
1473 | extern s32 wl_cfg80211_up(struct net_device *net); | |
1474 | extern s32 wl_cfg80211_down(struct net_device *net); | |
1475 | extern s32 wl_cfg80211_notify_ifadd(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1476 | uint8 bssidx); | |
1477 | extern s32 wl_cfg80211_notify_ifdel(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1478 | uint8 bssidx); | |
1479 | extern s32 wl_cfg80211_notify_ifchange(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1480 | uint8 bssidx); | |
1481 | extern struct net_device* wl_cfg80211_allocate_if(struct bcm_cfg80211 *cfg, int ifidx, | |
1482 | const char *name, uint8 *mac, uint8 bssidx, const char *dngl_name); | |
1483 | extern int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg, | |
1484 | int ifidx, struct net_device* ndev, bool rtnl_lock_reqd); | |
1485 | extern int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg, | |
1486 | int ifidx, struct net_device* ndev, bool rtnl_lock_reqd); | |
1487 | extern int wl_cfg80211_scan_stop(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev); | |
1488 | extern void wl_cfg80211_scan_abort(struct bcm_cfg80211 *cfg); | |
1489 | extern bool wl_cfg80211_is_concurrent_mode(struct net_device * dev); | |
1490 | extern void* wl_cfg80211_get_dhdp(struct net_device * dev); | |
1491 | extern bool wl_cfg80211_is_p2p_active(struct net_device * dev); | |
1492 | extern bool wl_cfg80211_is_roam_offload(struct net_device * dev); | |
1493 | extern bool wl_cfg80211_is_event_from_connected_bssid(struct net_device * dev, | |
1494 | const wl_event_msg_t *e, int ifidx); | |
1495 | extern void wl_cfg80211_dbg_level(u32 level); | |
1496 | extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); | |
1497 | extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len); | |
1498 | extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len); | |
1499 | extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, | |
1500 | enum wl_management_type type); | |
1501 | extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); | |
1502 | extern s32 wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len); | |
1503 | extern s32 wl_cfg80211_increase_p2p_bw(struct net_device *net, char* buf, int len); | |
dfb0f3ae RC |
1504 | #ifdef WLMESH |
1505 | extern s32 wl_cfg80211_set_sae_password(struct net_device *net, char* buf, int len); | |
1506 | #endif | |
010c3a89 RC |
1507 | #ifdef WL11ULB |
1508 | extern s32 wl_cfg80211_set_ulb_mode(struct net_device *dev, int mode); | |
1509 | extern s32 wl_cfg80211_set_ulb_bw(struct net_device *dev, | |
1510 | u32 ulb_bw, char *ifname); | |
1511 | #endif /* WL11ULB */ | |
1512 | #ifdef P2PLISTEN_AP_SAMECHN | |
1513 | extern s32 wl_cfg80211_set_p2p_resp_ap_chn(struct net_device *net, s32 enable); | |
1514 | #endif /* P2PLISTEN_AP_SAMECHN */ | |
1515 | ||
1516 | /* btcoex functions */ | |
1517 | void* wl_cfg80211_btcoex_init(struct net_device *ndev); | |
1518 | void wl_cfg80211_btcoex_deinit(void); | |
1519 | ||
1520 | extern chanspec_t wl_chspec_from_legacy(chanspec_t legacy_chspec); | |
1521 | extern chanspec_t wl_chspec_driver_to_host(chanspec_t chanspec); | |
1522 | ||
1523 | #ifdef WL_SUPPORT_AUTO_CHANNEL | |
1524 | #define CHANSPEC_BUF_SIZE 1024 | |
1525 | #define CHAN_SEL_IOCTL_DELAY 300 | |
1526 | #define CHAN_SEL_RETRY_COUNT 15 | |
1527 | #define CHANNEL_IS_RADAR(channel) (((channel & WL_CHAN_RADAR) || \ | |
1528 | (channel & WL_CHAN_PASSIVE)) ? true : false) | |
1529 | #define CHANNEL_IS_2G(channel) (((channel >= 1) && (channel <= 14)) ? \ | |
1530 | true : false) | |
1531 | #define CHANNEL_IS_5G(channel) (((channel >= 36) && (channel <= 165)) ? \ | |
1532 | true : false) | |
1533 | extern s32 wl_cfg80211_get_best_channels(struct net_device *dev, char* command, | |
1534 | int total_len); | |
1535 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ | |
1536 | extern int wl_cfg80211_ether_atoe(const char *a, struct ether_addr *n); | |
1537 | extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); | |
1538 | extern s32 wl_mode_to_nl80211_iftype(s32 mode); | |
1539 | int wl_cfg80211_do_driver_init(struct net_device *net); | |
1540 | void wl_cfg80211_enable_trace(u32 level); | |
1541 | extern s32 wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify); | |
1542 | extern s32 wl_cfg80211_if_is_group_owner(void); | |
1543 | extern chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec); | |
1544 | extern chanspec_t wl_ch_host_to_driver(struct bcm_cfg80211 *cfg, s32 bssidx, u16 channel); | |
1545 | extern s32 wl_set_tx_power(struct net_device *dev, | |
1546 | enum nl80211_tx_power_setting type, s32 dbm); | |
1547 | extern s32 wl_get_tx_power(struct net_device *dev, s32 *dbm); | |
1548 | extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); | |
1549 | extern void wl_stop_wait_next_action_frame(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
1550 | u8 bsscfgidx); | |
1551 | extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set); | |
1552 | extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev, | |
1553 | struct bcm_cfg80211 *cfg, wl_eventmsg_buf_t *ev); | |
1554 | extern void get_primary_mac(struct bcm_cfg80211 *cfg, struct ether_addr *mac); | |
1555 | extern void wl_cfg80211_update_power_mode(struct net_device *dev); | |
1556 | extern void wl_cfg80211_set_passive_scan(struct net_device *dev, char *command); | |
1557 | extern void wl_terminate_event_handler(struct net_device *dev); | |
1558 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
1559 | extern s32 wl_cfg80211_get_bss_info(struct net_device *dev, char* cmd, int total_len); | |
1560 | extern s32 wl_cfg80211_get_connect_failed_status(struct net_device *dev, char* cmd, int total_len); | |
1561 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
1562 | extern struct bcm_cfg80211 *wl_get_cfg(struct net_device *ndev); | |
1563 | extern s32 wl_cfg80211_set_if_band(struct net_device *ndev, int band); | |
1564 | ||
1565 | #define SCAN_BUF_CNT 2 | |
1566 | #define SCAN_BUF_NEXT 1 | |
1567 | #define WL_SCANTYPE_LEGACY 0x1 | |
1568 | #define WL_SCANTYPE_P2P 0x2 | |
1569 | #define wl_escan_set_sync_id(a, b) ((a) = htod16((b)->escan_sync_id_cntr++)) | |
1570 | #define wl_escan_set_type(a, b) | |
1571 | #define wl_escan_get_buf(a, b) ((wl_scan_results_t *) (a)->escan_info.escan_buf) | |
1572 | #define wl_escan_check_sync_id(a, b, c) 0 | |
1573 | #define wl_escan_print_sync_id(a, b, c) | |
1574 | #define wl_escan_increment_sync_id(a, b) | |
1575 | #define wl_escan_init_sync_id(a) | |
1576 | extern void wl_cfg80211_ibss_vsie_set_buffer(struct net_device *dev, vndr_ie_setbuf_t *ibss_vsie, | |
1577 | int ibss_vsie_len); | |
1578 | extern s32 wl_cfg80211_ibss_vsie_delete(struct net_device *dev); | |
1579 | #ifdef WL_RELMCAST | |
1580 | extern void wl_cfg80211_set_rmc_pid(struct net_device *dev, int pid); | |
1581 | #endif /* WL_RELMCAST */ | |
1582 | extern int wl_cfg80211_set_mgmt_vndr_ies(struct bcm_cfg80211 *cfg, | |
1583 | bcm_struct_cfgdev *cfgdev, s32 bssidx, s32 pktflag, | |
1584 | const u8 *vndr_ie, u32 vndr_ie_len); | |
1585 | ||
1586 | ||
1587 | /* Action frame specific functions */ | |
1588 | extern u8 wl_get_action_category(void *frame, u32 frame_len); | |
1589 | extern int wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action); | |
1590 | ||
1591 | #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST | |
1592 | struct net_device *wl_cfg80211_get_remain_on_channel_ndev(struct bcm_cfg80211 *cfg); | |
1593 | #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ | |
1594 | ||
1595 | #ifdef WL_SUPPORT_ACS | |
1596 | #define ACS_MSRMNT_DELAY 1000 /* dump_obss delay in ms */ | |
1597 | #define IOCTL_RETRY_COUNT 5 | |
1598 | #define CHAN_NOISE_DUMMY -80 | |
1599 | #define OBSS_TOKEN_IDX 15 | |
1600 | #define IBSS_TOKEN_IDX 15 | |
1601 | #define TX_TOKEN_IDX 14 | |
1602 | #define CTG_TOKEN_IDX 13 | |
1603 | #define PKT_TOKEN_IDX 15 | |
1604 | #define IDLE_TOKEN_IDX 12 | |
1605 | #endif /* WL_SUPPORT_ACS */ | |
1606 | ||
1607 | ||
1608 | extern int wl_cfg80211_get_ioctl_version(void); | |
1609 | extern int wl_cfg80211_enable_roam_offload(struct net_device *dev, int enable); | |
1610 | extern s32 wl_cfg80211_dfs_ap_move(struct net_device *ndev, char *data, | |
1611 | char *command, int total_len); | |
1612 | #ifdef WBTEXT | |
1613 | extern s32 wl_cfg80211_wbtext_set_default(struct net_device *ndev); | |
1614 | extern s32 wl_cfg80211_wbtext_config(struct net_device *ndev, char *data, | |
1615 | char *command, int total_len); | |
1616 | extern int wl_cfg80211_wbtext_weight_config(struct net_device *ndev, char *data, | |
1617 | char *command, int total_len); | |
1618 | extern int wl_cfg80211_wbtext_table_config(struct net_device *ndev, char *data, | |
1619 | char *command, int total_len); | |
1620 | extern s32 wl_cfg80211_wbtext_delta_config(struct net_device *ndev, char *data, | |
1621 | char *command, int total_len); | |
1622 | #endif /* WBTEXT */ | |
1623 | extern s32 wl_cfg80211_get_chanspecs_2g(struct net_device *ndev, | |
1624 | void *buf, s32 buflen); | |
1625 | extern s32 wl_cfg80211_get_chanspecs_5g(struct net_device *ndev, | |
1626 | void *buf, s32 buflen); | |
1627 | ||
1628 | extern s32 wl_cfg80211_bss_up(struct bcm_cfg80211 *cfg, | |
1629 | struct net_device *ndev, s32 bsscfg_idx, s32 up); | |
1630 | extern bool wl_cfg80211_bss_isup(struct net_device *ndev, int bsscfg_idx); | |
1631 | ||
1632 | struct net_device *wl_cfg80211_post_ifcreate(struct net_device *ndev, | |
1633 | wl_if_event_info *event, u8 *addr, const char *name, bool rtnl_lock_reqd); | |
1634 | extern s32 wl_cfg80211_post_ifdel(struct net_device *ndev, bool rtnl_lock_reqd); | |
1635 | #if defined(WL_VIRTUAL_APSTA) | |
1636 | extern int wl_cfg80211_interface_create(struct net_device *dev, char *name); | |
1637 | extern int wl_cfg80211_interface_delete(struct net_device *dev, char *name); | |
1638 | #if defined(PKT_FILTER_SUPPORT) && defined(APSTA_BLOCK_ARP_DURING_DHCP) | |
1639 | extern void wl_cfg80211_block_arp(struct net_device *dev, int enable); | |
1640 | #endif /* PKT_FILTER_SUPPORT && APSTA_BLOCK_ARP_DURING_DHCP */ | |
1641 | #endif /* defined (WL_VIRTUAL_APSTA) */ | |
1642 | ||
1643 | ||
1644 | #ifdef WL_CFG80211_P2P_DEV_IF | |
1645 | extern void wl_cfg80211_del_p2p_wdev(struct net_device *dev); | |
1646 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1647 | #if defined(WL_SUPPORT_AUTO_CHANNEL) | |
1648 | extern int wl_cfg80211_set_spect(struct net_device *dev, int spect); | |
1649 | extern int wl_cfg80211_get_sta_channel(struct net_device *dev); | |
1650 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ | |
1651 | ||
1652 | #ifdef P2P_LISTEN_OFFLOADING | |
1653 | extern s32 wl_cfg80211_p2plo_listen_start(struct net_device *dev, u8 *buf, int len); | |
1654 | extern s32 wl_cfg80211_p2plo_listen_stop(struct net_device *dev); | |
1655 | #endif /* P2P_LISTEN_OFFLOADING */ | |
1656 | ||
1657 | #define RETURN_EIO_IF_NOT_UP(wlpriv) \ | |
1658 | do { \ | |
1659 | struct net_device *checkSysUpNDev = bcmcfg_to_prmry_ndev(wlpriv); \ | |
1660 | if (unlikely(!wl_get_drv_status(wlpriv, READY, checkSysUpNDev))) { \ | |
1661 | WL_INFORM(("device is not ready\n")); \ | |
1662 | return -EIO; \ | |
1663 | } \ | |
1664 | } while (0) | |
1665 | ||
1666 | #ifdef QOS_MAP_SET | |
1667 | extern uint8 *wl_get_up_table(void); | |
1668 | #endif /* QOS_MAP_SET */ | |
1669 | ||
1670 | #define P2PO_COOKIE 65535 | |
1671 | u64 wl_cfg80211_get_new_roc_id(struct bcm_cfg80211 *cfg); | |
1672 | ||
1673 | #if defined(SUPPORT_RANDOM_MAC_SCAN) | |
1674 | int wl_cfg80211_set_random_mac(struct net_device *dev, bool enable); | |
1675 | int wl_cfg80211_random_mac_enable(struct net_device *dev); | |
1676 | int wl_cfg80211_random_mac_disable(struct net_device *dev); | |
1677 | #endif /* SUPPORT_RANDOM_MAC_SCAN */ | |
1678 | #ifdef SUPPORT_AP_HIGHER_BEACONRATE | |
1679 | int wl_set_ap_beacon_rate(struct net_device *dev, int val, char *ifname); | |
1680 | int wl_get_ap_basic_rate(struct net_device *dev, char* command, char *ifname, int total_len); | |
1681 | #endif /* SUPPORT_AP_HIGHER_BEACONRATE */ | |
1682 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
1683 | int wl_get_ap_rps(struct net_device *dev, char* command, char *ifname, int total_len); | |
1684 | int wl_set_ap_rps(struct net_device *dev, bool enable, char *ifname); | |
1685 | int wl_update_ap_rps_params(struct net_device *dev, ap_rps_info_t* rps, char *ifname); | |
1686 | void wl_cfg80211_init_ap_rps(struct bcm_cfg80211 *cfg); | |
1687 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
1688 | #ifdef SUPPORT_RSSI_LOGGING | |
1689 | int wl_get_rssi_logging(struct net_device *dev, void *param); | |
1690 | int wl_set_rssi_logging(struct net_device *dev, void *param); | |
1691 | int wl_get_rssi_per_ant(struct net_device *dev, char *ifname, char *peer_mac, void *param); | |
1692 | #endif /* SUPPORT_RSSI_LOGGING */ | |
1693 | int wl_cfg80211_iface_count(struct net_device *dev); | |
1694 | struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname); | |
1695 | struct net_device* wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname); | |
1696 | int wl_cfg80211_get_vndr_ouilist(struct bcm_cfg80211 *cfg, uint8 *buf, int max_cnt); | |
d964ce36 | 1697 | s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len); |
010c3a89 | 1698 | #endif /* _wl_cfg80211_h_ */ |