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 | ||
344 | /* wi-fi mode */ | |
345 | enum wl_mode { | |
346 | WL_MODE_BSS, | |
347 | WL_MODE_IBSS, | |
dfb0f3ae RC |
348 | WL_MODE_AP, |
349 | #ifdef WLMESH | |
350 | WL_MODE_MESH | |
351 | #endif | |
010c3a89 RC |
352 | }; |
353 | ||
354 | /* driver profile list */ | |
355 | enum wl_prof_list { | |
356 | WL_PROF_MODE, | |
357 | WL_PROF_SSID, | |
358 | WL_PROF_SEC, | |
359 | WL_PROF_IBSS, | |
360 | WL_PROF_BAND, | |
361 | WL_PROF_CHAN, | |
362 | WL_PROF_BSSID, | |
363 | WL_PROF_ACT, | |
364 | WL_PROF_BEACONINT, | |
365 | WL_PROF_DTIMPERIOD | |
366 | }; | |
367 | ||
368 | /* donlge escan state */ | |
369 | enum wl_escan_state { | |
370 | WL_ESCAN_STATE_IDLE, | |
371 | WL_ESCAN_STATE_SCANING | |
372 | }; | |
373 | /* fw downloading status */ | |
374 | enum wl_fw_status { | |
375 | WL_FW_LOADING_DONE, | |
376 | WL_NVRAM_LOADING_DONE | |
377 | }; | |
378 | ||
379 | enum wl_management_type { | |
380 | WL_BEACON = 0x1, | |
381 | WL_PROBE_RESP = 0x2, | |
382 | WL_ASSOC_RESP = 0x4 | |
383 | }; | |
384 | ||
385 | enum wl_pm_workq_act_type { | |
386 | WL_PM_WORKQ_SHORT, | |
387 | WL_PM_WORKQ_LONG, | |
388 | WL_PM_WORKQ_DEL | |
389 | }; | |
390 | ||
391 | enum wl_tdls_config { | |
392 | TDLS_STATE_AP_CREATE, | |
393 | TDLS_STATE_AP_DELETE, | |
394 | TDLS_STATE_CONNECT, | |
395 | TDLS_STATE_DISCONNECT, | |
396 | TDLS_STATE_SETUP, | |
397 | TDLS_STATE_TEARDOWN, | |
398 | TDLS_STATE_IF_CREATE, | |
399 | TDLS_STATE_IF_DELETE | |
400 | }; | |
401 | ||
402 | /* beacon / probe_response */ | |
403 | struct beacon_proberesp { | |
404 | __le64 timestamp; | |
405 | __le16 beacon_int; | |
406 | __le16 capab_info; | |
407 | u8 variable[0]; | |
408 | } __attribute__ ((packed)); | |
409 | ||
410 | /* driver configuration */ | |
411 | struct wl_conf { | |
412 | u32 frag_threshold; | |
413 | u32 rts_threshold; | |
414 | u32 retry_short; | |
415 | u32 retry_long; | |
416 | s32 tx_power; | |
417 | struct ieee80211_channel channel; | |
418 | }; | |
419 | ||
420 | typedef s32(*EVENT_HANDLER) (struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev, | |
421 | const wl_event_msg_t *e, void *data); | |
422 | ||
423 | /* bss inform structure for cfg80211 interface */ | |
424 | struct wl_cfg80211_bss_info { | |
425 | u16 band; | |
426 | u16 channel; | |
427 | s16 rssi; | |
428 | u16 frame_len; | |
429 | u8 frame_buf[1]; | |
430 | }; | |
431 | ||
432 | /* basic structure of scan request */ | |
433 | struct wl_scan_req { | |
434 | struct wlc_ssid ssid; | |
435 | }; | |
436 | ||
437 | /* basic structure of information element */ | |
438 | struct wl_ie { | |
439 | u16 offset; | |
440 | u8 buf[WL_TLV_INFO_MAX]; | |
441 | }; | |
442 | ||
443 | /* event queue for cfg80211 main event */ | |
444 | struct wl_event_q { | |
445 | struct list_head eq_list; | |
446 | u32 etype; | |
447 | wl_event_msg_t emsg; | |
448 | s8 edata[1]; | |
449 | }; | |
450 | ||
451 | /* security information with currently associated ap */ | |
452 | struct wl_security { | |
453 | u32 wpa_versions; | |
454 | u32 auth_type; | |
455 | u32 cipher_pairwise; | |
456 | u32 cipher_group; | |
457 | u32 wpa_auth; | |
458 | u32 auth_assoc_res_status; | |
459 | }; | |
460 | ||
461 | /* ibss information for currently joined ibss network */ | |
462 | struct wl_ibss { | |
463 | u8 beacon_interval; /* in millisecond */ | |
464 | u8 atim; /* in millisecond */ | |
465 | s8 join_only; | |
466 | u8 band; | |
467 | u8 channel; | |
468 | }; | |
469 | ||
470 | typedef struct wl_bss_vndr_ies { | |
471 | u8 probe_req_ie[VNDR_IES_BUF_LEN]; | |
472 | u8 probe_res_ie[VNDR_IES_MAX_BUF_LEN]; | |
473 | u8 assoc_req_ie[VNDR_IES_BUF_LEN]; | |
474 | u8 assoc_res_ie[VNDR_IES_BUF_LEN]; | |
475 | u8 beacon_ie[VNDR_IES_MAX_BUF_LEN]; | |
476 | u32 probe_req_ie_len; | |
477 | u32 probe_res_ie_len; | |
478 | u32 assoc_req_ie_len; | |
479 | u32 assoc_res_ie_len; | |
480 | u32 beacon_ie_len; | |
481 | } wl_bss_vndr_ies_t; | |
482 | ||
483 | typedef struct wl_cfgbss { | |
484 | u8 *wpa_ie; | |
485 | u8 *rsn_ie; | |
486 | u8 *wps_ie; | |
487 | bool security_mode; | |
488 | struct wl_bss_vndr_ies ies; /* Common for STA, P2P GC, GO, AP, P2P Disc Interface */ | |
489 | } wl_cfgbss_t; | |
490 | ||
491 | /* cfg driver profile */ | |
492 | struct wl_profile { | |
493 | u32 mode; | |
494 | s32 band; | |
495 | u32 channel; | |
496 | struct wlc_ssid ssid; | |
497 | struct wl_security sec; | |
498 | struct wl_ibss ibss; | |
499 | u8 bssid[ETHER_ADDR_LEN]; | |
500 | u16 beacon_interval; | |
501 | u8 dtim_period; | |
502 | bool active; | |
503 | }; | |
504 | ||
505 | struct net_info { | |
506 | struct net_device *ndev; | |
507 | struct wireless_dev *wdev; | |
508 | struct wl_profile profile; | |
509 | s32 mode; | |
510 | s32 roam_off; | |
511 | unsigned long sme_state; | |
512 | bool pm_restore; | |
513 | bool pm_block; | |
514 | s32 pm; | |
515 | s32 bssidx; | |
516 | wl_cfgbss_t bss; | |
517 | u32 ulb_bw; | |
518 | struct list_head list; /* list of all net_info structure */ | |
519 | }; | |
520 | ||
521 | /* association inform */ | |
522 | #define MAX_REQ_LINE 1024 | |
523 | struct wl_connect_info { | |
524 | u8 req_ie[MAX_REQ_LINE]; | |
525 | s32 req_ie_len; | |
526 | u8 resp_ie[MAX_REQ_LINE]; | |
527 | s32 resp_ie_len; | |
528 | }; | |
529 | ||
530 | /* firmware /nvram downloading controller */ | |
531 | struct wl_fw_ctrl { | |
532 | const struct firmware *fw_entry; | |
533 | unsigned long status; | |
534 | u32 ptr; | |
535 | s8 fw_name[WL_FILE_NAME_MAX]; | |
536 | s8 nvram_name[WL_FILE_NAME_MAX]; | |
537 | }; | |
538 | ||
539 | /* assoc ie length */ | |
540 | struct wl_assoc_ielen { | |
541 | u32 req_len; | |
542 | u32 resp_len; | |
543 | }; | |
544 | ||
545 | /* wpa2 pmk list */ | |
546 | struct wl_pmk_list { | |
547 | pmkid_list_t pmkids; | |
548 | pmkid_t foo[MAXPMKID - 1]; | |
549 | }; | |
550 | ||
551 | #ifdef DHD_MAX_IFS | |
552 | #define WL_MAX_IFS DHD_MAX_IFS | |
553 | #else | |
554 | #define WL_MAX_IFS 16 | |
555 | #endif | |
556 | ||
557 | #define ESCAN_BUF_SIZE (64 * 1024) | |
558 | ||
559 | struct escan_info { | |
560 | u32 escan_state; | |
561 | #ifdef STATIC_WL_PRIV_STRUCT | |
562 | #ifndef CONFIG_DHD_USE_STATIC_BUF | |
563 | #error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF | |
564 | #endif /* CONFIG_DHD_USE_STATIC_BUF */ | |
565 | u8 *escan_buf; | |
566 | #else | |
567 | u8 escan_buf[ESCAN_BUF_SIZE]; | |
568 | #endif /* STATIC_WL_PRIV_STRUCT */ | |
569 | struct wiphy *wiphy; | |
570 | struct net_device *ndev; | |
571 | }; | |
572 | ||
573 | #ifdef ESCAN_BUF_OVERFLOW_MGMT | |
574 | #define BUF_OVERFLOW_MGMT_COUNT 3 | |
575 | typedef struct { | |
576 | int RSSI; | |
577 | int length; | |
578 | struct ether_addr BSSID; | |
579 | } removal_element_t; | |
580 | #endif /* ESCAN_BUF_OVERFLOW_MGMT */ | |
581 | ||
582 | struct afx_hdl { | |
583 | wl_af_params_t *pending_tx_act_frm; | |
584 | struct ether_addr tx_dst_addr; | |
585 | struct net_device *dev; | |
586 | struct work_struct work; | |
587 | s32 bssidx; | |
588 | u32 retry; | |
589 | s32 peer_chan; | |
590 | s32 peer_listen_chan; /* search channel: configured by upper layer */ | |
591 | s32 my_listen_chan; /* listen chanel: extract it from prb req or gon req */ | |
592 | bool is_listen; | |
593 | bool ack_recv; | |
594 | bool is_active; | |
595 | }; | |
596 | ||
597 | struct parsed_ies { | |
598 | wpa_ie_fixed_t *wps_ie; | |
599 | u32 wps_ie_len; | |
600 | wpa_ie_fixed_t *wpa_ie; | |
601 | u32 wpa_ie_len; | |
602 | bcm_tlv_t *wpa2_ie; | |
603 | u32 wpa2_ie_len; | |
604 | }; | |
605 | ||
606 | ||
607 | #ifdef P2P_LISTEN_OFFLOADING | |
608 | typedef struct { | |
609 | uint16 period; /* listen offload period */ | |
610 | uint16 interval; /* listen offload interval */ | |
611 | uint16 count; /* listen offload count */ | |
612 | uint16 pad; /* pad for 32bit align */ | |
613 | } wl_p2plo_listen_t; | |
614 | #endif /* P2P_LISTEN_OFFLOADING */ | |
615 | ||
616 | #ifdef WL11U | |
617 | /* Max length of Interworking element */ | |
618 | #define IW_IES_MAX_BUF_LEN 9 | |
619 | #endif | |
620 | #define MAX_EVENT_BUF_NUM 16 | |
621 | typedef struct wl_eventmsg_buf { | |
622 | u16 num; | |
623 | struct { | |
624 | u16 type; | |
625 | bool set; | |
626 | } event [MAX_EVENT_BUF_NUM]; | |
627 | } wl_eventmsg_buf_t; | |
628 | ||
629 | typedef struct wl_if_event_info { | |
630 | bool valid; | |
631 | int ifidx; | |
632 | int bssidx; | |
633 | uint8 mac[ETHER_ADDR_LEN]; | |
634 | char name[IFNAMSIZ+1]; | |
635 | uint8 role; | |
636 | } wl_if_event_info; | |
637 | ||
638 | ||
639 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
640 | typedef struct ap_rps_info { | |
641 | bool enable; | |
642 | bool sta_assoc_check; | |
643 | int pps; | |
644 | int quiet_time; | |
645 | int level; | |
646 | } ap_rps_info_t; | |
647 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
648 | ||
649 | #ifdef SUPPORT_RSSI_LOGGING | |
650 | #define RSSILOG_FLAG_FEATURE_SW 0x1 | |
651 | #define RSSILOG_FLAG_REPORT_READY 0x2 | |
652 | typedef struct rssilog_set_param { | |
653 | uint8 enable; | |
654 | uint8 rssi_threshold; | |
655 | uint8 time_threshold; | |
656 | uint8 pad; | |
657 | } rssilog_set_param_t; | |
658 | ||
659 | typedef struct rssilog_get_param { | |
660 | uint8 report_count; | |
661 | uint8 enable; | |
662 | uint8 rssi_threshold; | |
663 | uint8 time_threshold; | |
664 | } rssilog_get_param_t; | |
665 | ||
666 | typedef struct rssi_ant_param { | |
667 | struct ether_addr ea; | |
668 | chanspec_t chanspec; | |
669 | } rssi_ant_param_t; | |
670 | ||
671 | typedef struct wl_rssi_ant_mimo { | |
672 | uint32 version; | |
673 | uint32 count; | |
674 | int8 rssi_ant[WL_RSSI_ANT_MAX]; | |
675 | int8 rssi_sum; | |
676 | int8 PAD[3]; | |
677 | } wl_rssi_ant_mimo_t; | |
678 | #endif /* SUPPORT_RSSI_LOGGING */ | |
679 | ||
680 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
681 | #define GET_BSS_INFO_LEN 90 | |
682 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
683 | ||
684 | ||
685 | /* private data of cfg80211 interface */ | |
686 | struct bcm_cfg80211 { | |
687 | struct wireless_dev *wdev; /* representing cfg cfg80211 device */ | |
688 | ||
689 | struct wireless_dev *p2p_wdev; /* representing cfg cfg80211 device for P2P */ | |
690 | struct net_device *p2p_net; /* reference to p2p0 interface */ | |
691 | ||
692 | struct wl_conf *conf; | |
693 | struct cfg80211_scan_request *scan_request; /* scan request object */ | |
694 | EVENT_HANDLER evt_handler[WLC_E_LAST]; | |
695 | struct list_head eq_list; /* used for event queue */ | |
696 | struct list_head net_list; /* used for struct net_info */ | |
697 | spinlock_t net_list_sync; /* to protect scan status (and others if needed) */ | |
698 | spinlock_t eq_lock; /* for event queue synchronization */ | |
699 | spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */ | |
700 | struct completion act_frm_scan; | |
701 | struct completion iface_disable; | |
702 | struct completion wait_next_af; | |
703 | struct mutex usr_sync; /* maily for up/down synchronization */ | |
704 | struct mutex if_sync; /* maily for iface op synchronization */ | |
705 | struct mutex scan_complete; /* serialize scan_complete call */ | |
706 | struct wl_scan_results *bss_list; | |
707 | struct wl_scan_results *scan_results; | |
708 | ||
709 | /* scan request object for internal purpose */ | |
710 | struct wl_scan_req *scan_req_int; | |
711 | /* information element object for internal purpose */ | |
712 | #if defined(STATIC_WL_PRIV_STRUCT) | |
713 | struct wl_ie *ie; | |
714 | #else | |
715 | struct wl_ie ie; | |
716 | #endif | |
717 | ||
718 | /* association information container */ | |
719 | #if defined(STATIC_WL_PRIV_STRUCT) | |
720 | struct wl_connect_info *conn_info; | |
721 | #else | |
722 | struct wl_connect_info conn_info; | |
723 | #endif | |
724 | #ifdef DEBUGFS_CFG80211 | |
725 | struct dentry *debugfs; | |
726 | #endif /* DEBUGFS_CFG80211 */ | |
727 | struct wl_pmk_list *pmk_list; /* wpa2 pmk list */ | |
728 | tsk_ctl_t event_tsk; /* task of main event handler thread */ | |
729 | dhd_pub_t *pub; | |
730 | u32 iface_cnt; | |
731 | u32 channel; /* current channel */ | |
732 | u32 af_sent_channel; /* channel action frame is sent */ | |
733 | /* next af subtype to cancel the remained dwell time in rx process */ | |
734 | u8 next_af_subtype; | |
735 | #ifdef WL_CFG80211_SYNC_GON | |
736 | ulong af_tx_sent_jiffies; | |
737 | #endif /* WL_CFG80211_SYNC_GON */ | |
738 | struct escan_info escan_info; /* escan information */ | |
739 | bool active_scan; /* current scan mode */ | |
740 | bool ibss_starter; /* indicates this sta is ibss starter */ | |
741 | bool link_up; /* link/connection up flag */ | |
742 | ||
743 | /* indicate whether chip to support power save mode */ | |
744 | bool pwr_save; | |
745 | bool roam_on; /* on/off switch for self-roaming */ | |
746 | bool scan_tried; /* indicates if first scan attempted */ | |
dfb0f3ae | 747 | #if defined(BCMSDIO) || defined(BCMDBUS) |
010c3a89 RC |
748 | bool wlfc_on; |
749 | #endif | |
750 | bool vsdb_mode; | |
751 | #define WL_ROAM_OFF_ON_CONCURRENT 0x0001 | |
752 | #define WL_ROAM_REVERT_STATUS 0x0002 | |
753 | u32 roam_flags; | |
754 | u8 *ioctl_buf; /* ioctl buffer */ | |
755 | struct mutex ioctl_buf_sync; | |
756 | u8 *escan_ioctl_buf; | |
757 | u8 *extra_buf; /* maily to grab assoc information */ | |
758 | struct dentry *debugfsdir; | |
759 | struct rfkill *rfkill; | |
760 | bool rf_blocked; | |
761 | struct ieee80211_channel remain_on_chan; | |
762 | enum nl80211_channel_type remain_on_chan_type; | |
763 | u64 send_action_id; | |
764 | u64 last_roc_id; | |
765 | wait_queue_head_t netif_change_event; | |
766 | wl_if_event_info if_event_info; | |
767 | struct completion send_af_done; | |
768 | struct afx_hdl *afx_hdl; | |
769 | struct p2p_info *p2p; | |
770 | bool p2p_supported; | |
771 | void *btcoex_info; | |
772 | struct timer_list scan_timeout; /* Timer for catch scan event timeout */ | |
773 | #if defined(P2P_IE_MISSING_FIX) | |
774 | bool p2p_prb_noti; | |
775 | #endif | |
776 | s32(*state_notifier) (struct bcm_cfg80211 *cfg, | |
777 | struct net_info *_net_info, enum wl_status state, bool set); | |
778 | unsigned long interrested_state; | |
779 | wlc_ssid_t hostapd_ssid; | |
780 | #ifdef WL11U | |
781 | bool wl11u; | |
782 | #endif /* WL11U */ | |
783 | bool sched_scan_running; /* scheduled scan req status */ | |
784 | struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */ | |
785 | bool scan_suppressed; | |
786 | struct timer_list scan_supp_timer; | |
787 | struct work_struct wlan_work; | |
788 | struct mutex event_sync; /* maily for up/down synchronization */ | |
789 | bool disable_roam_event; | |
790 | struct delayed_work pm_enable_work; | |
791 | struct workqueue_struct *event_workq; /* workqueue for event */ | |
792 | struct work_struct event_work; /* work item for event */ | |
793 | struct mutex pm_sync; /* mainly for pm work synchronization */ | |
794 | ||
795 | vndr_ie_setbuf_t *ibss_vsie; /* keep the VSIE for IBSS */ | |
796 | int ibss_vsie_len; | |
797 | #ifdef WL_RELMCAST | |
798 | u32 rmc_event_pid; | |
799 | u32 rmc_event_seq; | |
800 | #endif /* WL_RELMCAST */ | |
801 | #ifdef WLAIBSS_MCHAN | |
802 | struct ether_addr ibss_if_addr; | |
803 | bcm_struct_cfgdev *ibss_cfgdev; /* For AIBSS */ | |
804 | #endif /* WLAIBSS_MCHAN */ | |
805 | bool bss_pending_op; /* indicate where there is a pending IF operation */ | |
806 | int roam_offload; | |
807 | #ifdef WL_CFG80211_P2P_DEV_IF | |
808 | bool down_disc_if; | |
809 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
810 | #ifdef P2PLISTEN_AP_SAMECHN | |
811 | bool p2p_resp_apchn_status; | |
812 | #endif /* P2PLISTEN_AP_SAMECHN */ | |
813 | struct wl_wsec_key wep_key; | |
814 | #ifdef WLTDLS | |
815 | u8 *tdls_mgmt_frame; | |
816 | u32 tdls_mgmt_frame_len; | |
817 | s32 tdls_mgmt_freq; | |
818 | #endif /* WLTDLS */ | |
819 | bool need_wait_afrx; | |
820 | #ifdef QOS_MAP_SET | |
821 | uint8 *up_table; /* user priority table, size is UP_TABLE_MAX */ | |
822 | #endif /* QOS_MAP_SET */ | |
823 | struct ether_addr last_roamed_addr; | |
824 | bool rcc_enabled; /* flag for Roam channel cache feature */ | |
825 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
826 | char bss_info[GET_BSS_INFO_LEN]; | |
827 | wl_event_msg_t event_auth_assoc; | |
828 | u32 assoc_reject_status; | |
829 | u32 roam_count; | |
830 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
831 | u16 ap_oper_channel; | |
832 | #if defined(SUPPORT_RANDOM_MAC_SCAN) | |
833 | bool random_mac_enabled; | |
834 | #endif /* SUPPORT_RANDOM_MAC_SCAN */ | |
835 | #ifdef DHD_LOSSLESS_ROAMING | |
836 | struct timer_list roam_timeout; /* Timer for catch roam timeout */ | |
837 | #endif | |
838 | uint16 escan_sync_id_cntr; | |
839 | #ifdef WLTDLS | |
840 | uint8 tdls_supported; | |
841 | struct mutex tdls_sync; /* protect tdls config operations */ | |
842 | #endif /* WLTDLS */ | |
843 | #ifdef MFP | |
844 | uint8 *bip_pos; | |
845 | int mfp_mode; | |
846 | #endif /* MFP */ | |
847 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
848 | ap_rps_info_t ap_rps_info; | |
849 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
850 | #ifdef WBTEXT | |
851 | struct list_head wbtext_bssid_list; | |
852 | #endif /* WBTEXT */ | |
853 | struct list_head vndr_oui_list; | |
854 | ||
855 | #ifdef STAT_REPORT | |
856 | void *stat_report_info; | |
857 | #endif | |
dfb0f3ae RC |
858 | #ifdef WLMESH |
859 | char sae_password[SAE_MAX_PASSWD_LEN]; | |
860 | uint sae_password_len; | |
861 | #endif /* WLMESH */ | |
d964ce36 | 862 | #if defined(RSSIAVG) |
863 | wl_rssi_cache_ctrl_t g_rssi_cache_ctrl; | |
864 | wl_rssi_cache_ctrl_t g_connected_rssi_cache_ctrl; | |
865 | #endif | |
866 | #if defined(BSSCACHE) | |
867 | wl_bss_cache_ctrl_t g_bss_cache_ctrl; | |
868 | #endif | |
010c3a89 RC |
869 | int p2p_disconnected; // terence 20130703: Fix for wrong group_capab (timing issue) |
870 | struct ether_addr disconnected_bssid; | |
d964ce36 | 871 | int autochannel; |
872 | int best_2g_ch; | |
873 | int best_5g_ch; | |
874 | uint handshaking; | |
010c3a89 RC |
875 | }; |
876 | ||
877 | #if defined(STRICT_GCC_WARNINGS) && defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == \ | |
878 | 4 && __GNUC_MINOR__ >= 6)) | |
879 | #define GCC_DIAGNOSTIC_PUSH() \ | |
880 | _Pragma("GCC diagnostic push") \ | |
881 | _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") | |
882 | #define GCC_DIAGNOSTIC_POP() \ | |
883 | _Pragma("GCC diagnostic pop") | |
884 | #else | |
885 | #define GCC_DIAGNOSTIC_PUSH() | |
886 | #define GCC_DIAGNOSTIC_POP() | |
887 | #endif /* STRICT_GCC_WARNINGS */ | |
888 | ||
889 | #define BCM_LIST_FOR_EACH_ENTRY_SAFE(pos, next, head, member) \ | |
890 | list_for_each_entry_safe((pos), (next), (head), member) | |
891 | extern int ioctl_version; | |
892 | ||
893 | static inline struct wl_bss_info *next_bss(struct wl_scan_results *list, struct wl_bss_info *bss) | |
894 | { | |
895 | return bss = bss ? | |
896 | (struct wl_bss_info *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info; | |
897 | } | |
898 | ||
899 | static inline void | |
900 | wl_probe_wdev_all(struct bcm_cfg80211 *cfg) | |
901 | { | |
902 | struct net_info *_net_info, *next; | |
903 | unsigned long int flags; | |
904 | int idx = 0; | |
905 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
906 | GCC_DIAGNOSTIC_PUSH(); | |
907 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, | |
908 | &cfg->net_list, list) { | |
909 | WL_ERR(("%s: net_list[%d] bssidx: %d, " | |
910 | "ndev: %p, wdev: %p \n", __FUNCTION__, | |
911 | idx++, _net_info->bssidx, | |
912 | _net_info->ndev, _net_info->wdev)); | |
913 | } | |
914 | GCC_DIAGNOSTIC_POP(); | |
915 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
916 | return; | |
917 | } | |
918 | ||
919 | static inline struct net_info * | |
920 | wl_get_netinfo_by_bssidx(struct bcm_cfg80211 *cfg, s32 bssidx) | |
921 | { | |
922 | struct net_info *_net_info, *next, *info = NULL; | |
923 | unsigned long int flags; | |
924 | ||
925 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
926 | GCC_DIAGNOSTIC_PUSH(); | |
927 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
928 | if ((bssidx >= 0) && (_net_info->bssidx == bssidx)) { | |
929 | info = _net_info; | |
930 | break; | |
931 | } | |
932 | } | |
933 | GCC_DIAGNOSTIC_POP(); | |
934 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
935 | return info; | |
936 | } | |
937 | ||
938 | static inline void | |
939 | wl_dealloc_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
940 | { | |
941 | struct net_info *_net_info, *next; | |
942 | unsigned long int flags; | |
943 | ||
944 | #ifdef DHD_IFDEBUG | |
945 | WL_ERR(("dealloc_netinfo enter wdev=%p \n", wdev)); | |
946 | #endif | |
947 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
948 | GCC_DIAGNOSTIC_PUSH(); | |
949 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
950 | if (wdev && (_net_info->wdev == wdev)) { | |
951 | wl_cfgbss_t *bss = &_net_info->bss; | |
952 | ||
953 | kfree(bss->wpa_ie); | |
954 | bss->wpa_ie = NULL; | |
955 | kfree(bss->rsn_ie); | |
956 | bss->rsn_ie = NULL; | |
957 | kfree(bss->wps_ie); | |
958 | bss->wps_ie = NULL; | |
959 | list_del(&_net_info->list); | |
960 | cfg->iface_cnt--; | |
961 | kfree(_net_info); | |
962 | } | |
963 | } | |
964 | GCC_DIAGNOSTIC_POP(); | |
965 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
966 | #ifdef DHD_IFDEBUG | |
967 | WL_ERR(("dealloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt)); | |
968 | #endif | |
969 | } | |
970 | ||
971 | static inline s32 | |
972 | wl_alloc_netinfo(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
973 | struct wireless_dev * wdev, s32 mode, bool pm_block, u8 bssidx) | |
974 | { | |
975 | struct net_info *_net_info; | |
976 | s32 err = 0; | |
977 | unsigned long int flags; | |
978 | #ifdef DHD_IFDEBUG | |
979 | WL_ERR(("alloc_netinfo enter bssidx=%d wdev=%p ndev=%p\n", bssidx, wdev, ndev)); | |
980 | #endif | |
981 | /* Check whether there is any duplicate entry for the | |
982 | * same bssidx * | |
983 | */ | |
984 | if ((_net_info = wl_get_netinfo_by_bssidx(cfg, bssidx))) { | |
985 | /* We have a duplicate entry for the same bssidx | |
986 | * already present which shouldn't have been the case. | |
987 | * Attempt recovery. | |
988 | */ | |
989 | WL_ERR(("Duplicate entry for bssidx=%d present\n", bssidx)); | |
990 | wl_probe_wdev_all(cfg); | |
991 | #ifdef DHD_DEBUG | |
992 | ASSERT(0); | |
993 | #endif /* DHD_DEBUG */ | |
994 | WL_ERR(("Removing the Dup entry for bssidx=%d \n", bssidx)); | |
995 | wl_dealloc_netinfo_by_wdev(cfg, _net_info->wdev); | |
996 | } | |
997 | if (cfg->iface_cnt == IFACE_MAX_CNT) | |
998 | return -ENOMEM; | |
999 | _net_info = kzalloc(sizeof(struct net_info), GFP_KERNEL); | |
1000 | if (!_net_info) | |
1001 | err = -ENOMEM; | |
1002 | else { | |
1003 | _net_info->mode = mode; | |
1004 | _net_info->ndev = ndev; | |
1005 | _net_info->wdev = wdev; | |
1006 | _net_info->pm_restore = 0; | |
1007 | _net_info->pm = 0; | |
1008 | _net_info->pm_block = pm_block; | |
1009 | _net_info->roam_off = WL_INVALID; | |
1010 | _net_info->bssidx = bssidx; | |
1011 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1012 | cfg->iface_cnt++; | |
1013 | list_add(&_net_info->list, &cfg->net_list); | |
1014 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1015 | } | |
1016 | #ifdef DHD_IFDEBUG | |
1017 | WL_ERR(("alloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt)); | |
1018 | #endif | |
1019 | return err; | |
1020 | } | |
1021 | ||
1022 | static inline void | |
1023 | wl_delete_all_netinfo(struct bcm_cfg80211 *cfg) | |
1024 | { | |
1025 | struct net_info *_net_info, *next; | |
1026 | unsigned long int flags; | |
1027 | ||
1028 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1029 | GCC_DIAGNOSTIC_PUSH(); | |
1030 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1031 | wl_cfgbss_t *bss = &_net_info->bss; | |
1032 | ||
1033 | kfree(bss->wpa_ie); | |
1034 | bss->wpa_ie = NULL; | |
1035 | kfree(bss->rsn_ie); | |
1036 | bss->rsn_ie = NULL; | |
1037 | kfree(bss->wps_ie); | |
1038 | bss->wps_ie = NULL; | |
1039 | list_del(&_net_info->list); | |
1040 | if (_net_info->wdev) | |
1041 | kfree(_net_info->wdev); | |
1042 | kfree(_net_info); | |
1043 | } | |
1044 | cfg->iface_cnt = 0; | |
1045 | GCC_DIAGNOSTIC_POP(); | |
1046 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1047 | } | |
1048 | static inline u32 | |
1049 | wl_get_status_all(struct bcm_cfg80211 *cfg, s32 status) | |
1050 | ||
1051 | { | |
1052 | struct net_info *_net_info, *next; | |
1053 | u32 cnt = 0; | |
1054 | unsigned long int flags; | |
1055 | ||
1056 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1057 | GCC_DIAGNOSTIC_PUSH(); | |
1058 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1059 | if (_net_info->ndev && | |
1060 | test_bit(status, &_net_info->sme_state)) | |
1061 | cnt++; | |
1062 | } | |
1063 | GCC_DIAGNOSTIC_POP(); | |
1064 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1065 | return cnt; | |
1066 | } | |
1067 | static inline void | |
1068 | wl_set_status_all(struct bcm_cfg80211 *cfg, s32 status, u32 op) | |
1069 | { | |
1070 | struct net_info *_net_info, *next; | |
1071 | unsigned long int flags; | |
1072 | ||
1073 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1074 | GCC_DIAGNOSTIC_PUSH(); | |
1075 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1076 | switch (op) { | |
1077 | case 1: | |
1078 | break; /* set all status is not allowed */ | |
1079 | case 2: | |
1080 | /* | |
1081 | * Release the spinlock before calling notifier. Else there | |
1082 | * will be nested calls | |
1083 | */ | |
1084 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1085 | clear_bit(status, &_net_info->sme_state); | |
1086 | if (cfg->state_notifier && | |
1087 | test_bit(status, &(cfg->interrested_state))) | |
1088 | cfg->state_notifier(cfg, _net_info, status, false); | |
1089 | return; | |
1090 | case 4: | |
1091 | break; /* change all status is not allowed */ | |
1092 | default: | |
1093 | break; /* unknown operation */ | |
1094 | } | |
1095 | } | |
1096 | GCC_DIAGNOSTIC_POP(); | |
1097 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1098 | } | |
1099 | static inline void | |
1100 | wl_set_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status, | |
1101 | struct net_device *ndev, u32 op) | |
1102 | { | |
1103 | ||
1104 | struct net_info *_net_info, *next; | |
1105 | unsigned long int flags; | |
1106 | ||
1107 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1108 | GCC_DIAGNOSTIC_PUSH(); | |
1109 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1110 | if (ndev && (_net_info->ndev == ndev)) { | |
1111 | switch (op) { | |
1112 | case 1: | |
1113 | /* | |
1114 | * Release the spinlock before calling notifier. Else there | |
1115 | * will be nested calls | |
1116 | */ | |
1117 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1118 | set_bit(status, &_net_info->sme_state); | |
1119 | if (cfg->state_notifier && | |
1120 | test_bit(status, &(cfg->interrested_state))) | |
1121 | cfg->state_notifier(cfg, _net_info, status, true); | |
1122 | return; | |
1123 | case 2: | |
1124 | /* | |
1125 | * Release the spinlock before calling notifier. Else there | |
1126 | * will be nested calls | |
1127 | */ | |
1128 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1129 | clear_bit(status, &_net_info->sme_state); | |
1130 | if (cfg->state_notifier && | |
1131 | test_bit(status, &(cfg->interrested_state))) | |
1132 | cfg->state_notifier(cfg, _net_info, status, false); | |
1133 | return; | |
1134 | case 4: | |
1135 | change_bit(status, &_net_info->sme_state); | |
1136 | break; | |
1137 | } | |
1138 | } | |
1139 | ||
1140 | } | |
1141 | GCC_DIAGNOSTIC_POP(); | |
1142 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1143 | ||
1144 | } | |
1145 | ||
1146 | static inline wl_cfgbss_t * | |
1147 | wl_get_cfgbss_by_wdev(struct bcm_cfg80211 *cfg, | |
1148 | struct wireless_dev *wdev) | |
1149 | { | |
1150 | struct net_info *_net_info, *next; | |
1151 | wl_cfgbss_t *bss = NULL; | |
1152 | unsigned long int flags; | |
1153 | ||
1154 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1155 | GCC_DIAGNOSTIC_PUSH(); | |
1156 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1157 | if (wdev && (_net_info->wdev == wdev)) { | |
1158 | bss = &_net_info->bss; | |
1159 | break; | |
1160 | } | |
1161 | } | |
1162 | GCC_DIAGNOSTIC_POP(); | |
1163 | ||
1164 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1165 | return bss; | |
1166 | } | |
1167 | ||
1168 | static inline u32 | |
1169 | wl_get_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status, | |
1170 | struct net_device *ndev) | |
1171 | { | |
1172 | struct net_info *_net_info, *next; | |
1173 | u32 stat = 0; | |
1174 | unsigned long int flags; | |
1175 | ||
1176 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1177 | GCC_DIAGNOSTIC_PUSH(); | |
1178 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1179 | if (ndev && (_net_info->ndev == ndev)) { | |
1180 | stat = test_bit(status, &_net_info->sme_state); | |
1181 | break; | |
1182 | } | |
1183 | } | |
1184 | GCC_DIAGNOSTIC_POP(); | |
1185 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1186 | return stat; | |
1187 | } | |
1188 | ||
1189 | static inline s32 | |
1190 | wl_get_mode_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1191 | { | |
1192 | struct net_info *_net_info, *next; | |
1193 | s32 mode = -1; | |
1194 | unsigned long int flags; | |
1195 | ||
1196 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1197 | GCC_DIAGNOSTIC_PUSH(); | |
1198 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1199 | if (ndev && (_net_info->ndev == ndev)) { | |
1200 | mode = _net_info->mode; | |
1201 | break; | |
1202 | } | |
1203 | } | |
1204 | GCC_DIAGNOSTIC_POP(); | |
1205 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1206 | return mode; | |
1207 | } | |
1208 | ||
1209 | static inline void | |
1210 | wl_set_mode_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
1211 | s32 mode) | |
1212 | { | |
1213 | struct net_info *_net_info, *next; | |
1214 | unsigned long int flags; | |
1215 | ||
1216 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1217 | GCC_DIAGNOSTIC_PUSH(); | |
1218 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1219 | if (ndev && (_net_info->ndev == ndev)) | |
1220 | _net_info->mode = mode; | |
1221 | } | |
1222 | GCC_DIAGNOSTIC_POP(); | |
1223 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1224 | } | |
1225 | ||
1226 | static inline s32 | |
1227 | wl_get_bssidx_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
1228 | { | |
1229 | struct net_info *_net_info, *next; | |
1230 | s32 bssidx = -1; | |
1231 | unsigned long int flags; | |
1232 | ||
1233 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1234 | GCC_DIAGNOSTIC_PUSH(); | |
1235 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1236 | if (_net_info->wdev && (_net_info->wdev == wdev)) { | |
1237 | bssidx = _net_info->bssidx; | |
1238 | break; | |
1239 | } | |
1240 | } | |
1241 | GCC_DIAGNOSTIC_POP(); | |
1242 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1243 | return bssidx; | |
1244 | } | |
1245 | ||
1246 | static inline struct wireless_dev * | |
1247 | wl_get_wdev_by_bssidx(struct bcm_cfg80211 *cfg, s32 bssidx) | |
1248 | { | |
1249 | struct net_info *_net_info, *next; | |
1250 | struct wireless_dev *wdev = NULL; | |
1251 | unsigned long int flags; | |
1252 | ||
1253 | if (bssidx < 0) | |
1254 | return NULL; | |
1255 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1256 | GCC_DIAGNOSTIC_PUSH(); | |
1257 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1258 | if (_net_info->bssidx == bssidx) { | |
1259 | wdev = _net_info->wdev; | |
1260 | break; | |
1261 | } | |
1262 | } | |
1263 | GCC_DIAGNOSTIC_POP(); | |
1264 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1265 | return wdev; | |
1266 | } | |
1267 | ||
1268 | static inline struct wl_profile * | |
1269 | wl_get_profile_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1270 | { | |
1271 | struct net_info *_net_info, *next; | |
1272 | struct wl_profile *prof = NULL; | |
1273 | unsigned long int flags; | |
1274 | ||
1275 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1276 | GCC_DIAGNOSTIC_PUSH(); | |
1277 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1278 | if (ndev && (_net_info->ndev == ndev)) { | |
1279 | prof = &_net_info->profile; | |
1280 | break; | |
1281 | } | |
1282 | } | |
1283 | GCC_DIAGNOSTIC_POP(); | |
1284 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1285 | return prof; | |
1286 | } | |
1287 | static inline struct net_info * | |
1288 | wl_get_netinfo_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev) | |
1289 | { | |
1290 | struct net_info *_net_info, *next, *info = NULL; | |
1291 | unsigned long int flags; | |
1292 | ||
1293 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1294 | GCC_DIAGNOSTIC_PUSH(); | |
1295 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1296 | if (ndev && (_net_info->ndev == ndev)) { | |
1297 | info = _net_info; | |
1298 | break; | |
1299 | } | |
1300 | } | |
1301 | GCC_DIAGNOSTIC_POP(); | |
1302 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1303 | return info; | |
1304 | } | |
1305 | ||
1306 | static inline struct net_info * | |
1307 | wl_get_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev) | |
1308 | { | |
1309 | struct net_info *_net_info, *next, *info = NULL; | |
1310 | unsigned long int flags; | |
1311 | ||
1312 | spin_lock_irqsave(&cfg->net_list_sync, flags); | |
1313 | GCC_DIAGNOSTIC_PUSH(); | |
1314 | BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) { | |
1315 | if (wdev && (_net_info->wdev == wdev)) { | |
1316 | info = _net_info; | |
1317 | break; | |
1318 | } | |
1319 | } | |
1320 | GCC_DIAGNOSTIC_POP(); | |
1321 | spin_unlock_irqrestore(&cfg->net_list_sync, flags); | |
1322 | return info; | |
1323 | } | |
1324 | ||
1325 | #define is_p2p_group_iface(wdev) (((wdev->iftype == NL80211_IFTYPE_P2P_GO) || \ | |
1326 | (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) ? 1 : 0) | |
1327 | #define bcmcfg_to_wiphy(cfg) (cfg->wdev->wiphy) | |
1328 | #define bcmcfg_to_prmry_ndev(cfg) (cfg->wdev->netdev) | |
1329 | #define bcmcfg_to_prmry_wdev(cfg) (cfg->wdev) | |
1330 | #define bcmcfg_to_p2p_wdev(cfg) (cfg->p2p_wdev) | |
1331 | #define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr)) | |
1332 | #define ndev_to_wdev(ndev) (ndev->ieee80211_ptr) | |
1333 | #define wdev_to_ndev(wdev) (wdev->netdev) | |
1334 | ||
1335 | #if defined(WL_ENABLE_P2P_IF) | |
1336 | #define ndev_to_wlc_ndev(ndev, cfg) ((ndev == cfg->p2p_net) ? \ | |
1337 | bcmcfg_to_prmry_ndev(cfg) : ndev) | |
1338 | #else | |
1339 | #define ndev_to_wlc_ndev(ndev, cfg) (ndev) | |
1340 | #endif /* WL_ENABLE_P2P_IF */ | |
1341 | ||
1342 | #define wdev_to_wlc_ndev(wdev, cfg) \ | |
1343 | (wdev_to_ndev(wdev) ? \ | |
1344 | wdev_to_ndev(wdev) : bcmcfg_to_prmry_ndev(cfg)) | |
1345 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1346 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) wdev_to_wlc_ndev(cfgdev, cfg) | |
1347 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_wdev(cfg) | |
1348 | #elif defined(WL_ENABLE_P2P_IF) | |
1349 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) ndev_to_wlc_ndev(cfgdev, cfg) | |
1350 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_ndev(cfg) | |
1351 | #else | |
1352 | #define cfgdev_to_wlc_ndev(cfgdev, cfg) (cfgdev) | |
1353 | #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) (cfgdev) | |
1354 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1355 | ||
1356 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1357 | #define cfgdev_to_wdev(cfgdev) (cfgdev) | |
1358 | #define ndev_to_cfgdev(ndev) ndev_to_wdev(ndev) | |
1359 | #define cfgdev_to_ndev(cfgdev) (cfgdev ? (cfgdev->netdev) : NULL) | |
1360 | #define wdev_to_cfgdev(cfgdev) (cfgdev) | |
1361 | #define discover_cfgdev(cfgdev, cfg) (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE) | |
1362 | #else | |
1363 | #define cfgdev_to_wdev(cfgdev) (cfgdev->ieee80211_ptr) | |
1364 | #define wdev_to_cfgdev(cfgdev) cfgdev ? (cfgdev->netdev) : NULL | |
1365 | #define ndev_to_cfgdev(ndev) (ndev) | |
1366 | #define cfgdev_to_ndev(cfgdev) (cfgdev) | |
1367 | #define discover_cfgdev(cfgdev, cfg) (cfgdev == cfg->p2p_net) | |
1368 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1369 | ||
1370 | #if defined(WL_CFG80211_P2P_DEV_IF) | |
1371 | #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \ | |
1372 | (cfg->scan_request->wdev == cfg->p2p_wdev)) ? true : false) | |
1373 | #elif defined(WL_ENABLE_P2P_IF) | |
1374 | #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \ | |
1375 | (cfg->scan_request->dev == cfg->p2p_net)) ? true : false) | |
1376 | #else | |
1377 | #define scan_req_match(cfg) (((cfg) && p2p_is_on(cfg) && p2p_scan(cfg)) ? \ | |
1378 | true : false) | |
1379 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1380 | ||
1381 | #define PRINT_WDEV_INFO(cfgdev) \ | |
1382 | { \ | |
1383 | struct wireless_dev *wdev = cfgdev_to_wdev(cfgdev); \ | |
1384 | struct net_device *netdev = wdev ? wdev->netdev : NULL; \ | |
1385 | WL_DBG(("wdev_ptr:%p ndev_ptr:%p ifname:%s iftype:%d\n", wdev, netdev, \ | |
1386 | netdev ? netdev->name : "NULL (non-ndev device)", \ | |
1387 | wdev ? wdev->iftype : 0xff)); \ | |
1388 | } | |
1389 | ||
1390 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0)) | |
1391 | #define scan_req_iftype(req) (req->dev->ieee80211_ptr->iftype) | |
1392 | #else | |
1393 | #define scan_req_iftype(req) (req->wdev->iftype) | |
1394 | #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) */ | |
1395 | ||
1396 | #define wl_to_sr(w) (w->scan_req_int) | |
1397 | #if defined(STATIC_WL_PRIV_STRUCT) | |
1398 | #define wl_to_ie(w) (w->ie) | |
1399 | #define wl_to_conn(w) (w->conn_info) | |
1400 | #else | |
1401 | #define wl_to_ie(w) (&w->ie) | |
1402 | #define wl_to_conn(w) (&w->conn_info) | |
1403 | #endif | |
1404 | #define wiphy_from_scan(w) (w->escan_info.wiphy) | |
1405 | #define wl_get_drv_status_all(cfg, stat) \ | |
1406 | (wl_get_status_all(cfg, WL_STATUS_ ## stat)) | |
1407 | #define wl_get_drv_status(cfg, stat, ndev) \ | |
1408 | (wl_get_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev)) | |
1409 | #define wl_set_drv_status(cfg, stat, ndev) \ | |
1410 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 1)) | |
1411 | #define wl_clr_drv_status(cfg, stat, ndev) \ | |
1412 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 2)) | |
1413 | #define wl_clr_drv_status_all(cfg, stat) \ | |
1414 | (wl_set_status_all(cfg, WL_STATUS_ ## stat, 2)) | |
1415 | #define wl_chg_drv_status(cfg, stat, ndev) \ | |
1416 | (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 4)) | |
1417 | ||
1418 | #define for_each_bss(list, bss, __i) \ | |
1419 | for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss)) | |
1420 | ||
1421 | #define for_each_ndev(cfg, iter, next) \ | |
1422 | list_for_each_entry_safe(iter, next, &cfg->net_list, list) | |
1423 | ||
1424 | /* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0. | |
1425 | * In addtion to that, wpa_version is WPA_VERSION_1 | |
1426 | */ | |
1427 | #define is_wps_conn(_sme) \ | |
1428 | ((wl_cfgp2p_find_wpsie((u8 *)_sme->ie, _sme->ie_len) != NULL) && \ | |
1429 | (!_sme->crypto.n_ciphers_pairwise) && \ | |
1430 | (!_sme->crypto.cipher_group)) | |
1431 | ||
1432 | #define IS_AKM_SUITE_FT(sec) ({BCM_REFERENCE(sec); FALSE;}) | |
1433 | ||
1434 | #define IS_AKM_SUITE_CCKM(sec) ({BCM_REFERENCE(sec); FALSE;}) | |
1435 | ||
1436 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) | |
1437 | #define STA_INFO_BIT(info) (1ul << NL80211_STA_ ## info) | |
1438 | #ifdef strnicmp | |
1439 | #undef strnicmp | |
1440 | #endif /* strnicmp */ | |
1441 | #define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len)) | |
1442 | #else | |
1443 | #define STA_INFO_BIT(info) (STATION_ ## info) | |
1444 | #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) */ | |
1445 | ||
1446 | extern s32 wl_cfg80211_attach(struct net_device *ndev, void *context); | |
1447 | extern void wl_cfg80211_detach(struct bcm_cfg80211 *cfg); | |
1448 | ||
1449 | extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e, | |
1450 | void *data); | |
1451 | void wl_cfg80211_set_parent_dev(void *dev); | |
1452 | struct device *wl_cfg80211_get_parent_dev(void); | |
1453 | ||
1454 | /* clear IEs */ | |
1455 | extern s32 wl_cfg80211_clear_mgmt_vndr_ies(struct bcm_cfg80211 *cfg); | |
1456 | extern s32 wl_cfg80211_clear_per_bss_ies(struct bcm_cfg80211 *cfg, s32 bssidx); | |
1457 | ||
1458 | extern s32 wl_cfg80211_up(struct net_device *net); | |
1459 | extern s32 wl_cfg80211_down(struct net_device *net); | |
1460 | extern s32 wl_cfg80211_notify_ifadd(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1461 | uint8 bssidx); | |
1462 | extern s32 wl_cfg80211_notify_ifdel(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1463 | uint8 bssidx); | |
1464 | extern s32 wl_cfg80211_notify_ifchange(struct net_device * dev, int ifidx, char *name, uint8 *mac, | |
1465 | uint8 bssidx); | |
1466 | extern struct net_device* wl_cfg80211_allocate_if(struct bcm_cfg80211 *cfg, int ifidx, | |
1467 | const char *name, uint8 *mac, uint8 bssidx, const char *dngl_name); | |
1468 | extern int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg, | |
1469 | int ifidx, struct net_device* ndev, bool rtnl_lock_reqd); | |
1470 | extern int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg, | |
1471 | int ifidx, struct net_device* ndev, bool rtnl_lock_reqd); | |
1472 | extern int wl_cfg80211_scan_stop(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev); | |
1473 | extern void wl_cfg80211_scan_abort(struct bcm_cfg80211 *cfg); | |
1474 | extern bool wl_cfg80211_is_concurrent_mode(struct net_device * dev); | |
1475 | extern void* wl_cfg80211_get_dhdp(struct net_device * dev); | |
1476 | extern bool wl_cfg80211_is_p2p_active(struct net_device * dev); | |
1477 | extern bool wl_cfg80211_is_roam_offload(struct net_device * dev); | |
1478 | extern bool wl_cfg80211_is_event_from_connected_bssid(struct net_device * dev, | |
1479 | const wl_event_msg_t *e, int ifidx); | |
1480 | extern void wl_cfg80211_dbg_level(u32 level); | |
1481 | extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr); | |
1482 | extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len); | |
1483 | extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len); | |
1484 | extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len, | |
1485 | enum wl_management_type type); | |
1486 | extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len); | |
1487 | extern s32 wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len); | |
1488 | extern s32 wl_cfg80211_increase_p2p_bw(struct net_device *net, char* buf, int len); | |
dfb0f3ae RC |
1489 | #ifdef WLMESH |
1490 | extern s32 wl_cfg80211_set_sae_password(struct net_device *net, char* buf, int len); | |
1491 | #endif | |
010c3a89 RC |
1492 | #ifdef WL11ULB |
1493 | extern s32 wl_cfg80211_set_ulb_mode(struct net_device *dev, int mode); | |
1494 | extern s32 wl_cfg80211_set_ulb_bw(struct net_device *dev, | |
1495 | u32 ulb_bw, char *ifname); | |
1496 | #endif /* WL11ULB */ | |
1497 | #ifdef P2PLISTEN_AP_SAMECHN | |
1498 | extern s32 wl_cfg80211_set_p2p_resp_ap_chn(struct net_device *net, s32 enable); | |
1499 | #endif /* P2PLISTEN_AP_SAMECHN */ | |
1500 | ||
1501 | /* btcoex functions */ | |
1502 | void* wl_cfg80211_btcoex_init(struct net_device *ndev); | |
1503 | void wl_cfg80211_btcoex_deinit(void); | |
1504 | ||
1505 | extern chanspec_t wl_chspec_from_legacy(chanspec_t legacy_chspec); | |
1506 | extern chanspec_t wl_chspec_driver_to_host(chanspec_t chanspec); | |
1507 | ||
1508 | #ifdef WL_SUPPORT_AUTO_CHANNEL | |
1509 | #define CHANSPEC_BUF_SIZE 1024 | |
1510 | #define CHAN_SEL_IOCTL_DELAY 300 | |
1511 | #define CHAN_SEL_RETRY_COUNT 15 | |
1512 | #define CHANNEL_IS_RADAR(channel) (((channel & WL_CHAN_RADAR) || \ | |
1513 | (channel & WL_CHAN_PASSIVE)) ? true : false) | |
1514 | #define CHANNEL_IS_2G(channel) (((channel >= 1) && (channel <= 14)) ? \ | |
1515 | true : false) | |
1516 | #define CHANNEL_IS_5G(channel) (((channel >= 36) && (channel <= 165)) ? \ | |
1517 | true : false) | |
1518 | extern s32 wl_cfg80211_get_best_channels(struct net_device *dev, char* command, | |
1519 | int total_len); | |
1520 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ | |
1521 | extern int wl_cfg80211_ether_atoe(const char *a, struct ether_addr *n); | |
1522 | extern int wl_cfg80211_hang(struct net_device *dev, u16 reason); | |
1523 | extern s32 wl_mode_to_nl80211_iftype(s32 mode); | |
1524 | int wl_cfg80211_do_driver_init(struct net_device *net); | |
1525 | void wl_cfg80211_enable_trace(u32 level); | |
1526 | extern s32 wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify); | |
1527 | extern s32 wl_cfg80211_if_is_group_owner(void); | |
1528 | extern chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec); | |
1529 | extern chanspec_t wl_ch_host_to_driver(struct bcm_cfg80211 *cfg, s32 bssidx, u16 channel); | |
1530 | extern s32 wl_set_tx_power(struct net_device *dev, | |
1531 | enum nl80211_tx_power_setting type, s32 dbm); | |
1532 | extern s32 wl_get_tx_power(struct net_device *dev, s32 *dbm); | |
1533 | extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add); | |
1534 | extern void wl_stop_wait_next_action_frame(struct bcm_cfg80211 *cfg, struct net_device *ndev, | |
1535 | u8 bsscfgidx); | |
1536 | extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set); | |
1537 | extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev, | |
1538 | struct bcm_cfg80211 *cfg, wl_eventmsg_buf_t *ev); | |
1539 | extern void get_primary_mac(struct bcm_cfg80211 *cfg, struct ether_addr *mac); | |
1540 | extern void wl_cfg80211_update_power_mode(struct net_device *dev); | |
1541 | extern void wl_cfg80211_set_passive_scan(struct net_device *dev, char *command); | |
1542 | extern void wl_terminate_event_handler(struct net_device *dev); | |
1543 | #if defined(DHD_ENABLE_BIGDATA_LOGGING) | |
1544 | extern s32 wl_cfg80211_get_bss_info(struct net_device *dev, char* cmd, int total_len); | |
1545 | extern s32 wl_cfg80211_get_connect_failed_status(struct net_device *dev, char* cmd, int total_len); | |
1546 | #endif /* DHD_ENABLE_BIGDATA_LOGGING */ | |
1547 | extern struct bcm_cfg80211 *wl_get_cfg(struct net_device *ndev); | |
1548 | extern s32 wl_cfg80211_set_if_band(struct net_device *ndev, int band); | |
1549 | ||
1550 | #define SCAN_BUF_CNT 2 | |
1551 | #define SCAN_BUF_NEXT 1 | |
1552 | #define WL_SCANTYPE_LEGACY 0x1 | |
1553 | #define WL_SCANTYPE_P2P 0x2 | |
1554 | #define wl_escan_set_sync_id(a, b) ((a) = htod16((b)->escan_sync_id_cntr++)) | |
1555 | #define wl_escan_set_type(a, b) | |
1556 | #define wl_escan_get_buf(a, b) ((wl_scan_results_t *) (a)->escan_info.escan_buf) | |
1557 | #define wl_escan_check_sync_id(a, b, c) 0 | |
1558 | #define wl_escan_print_sync_id(a, b, c) | |
1559 | #define wl_escan_increment_sync_id(a, b) | |
1560 | #define wl_escan_init_sync_id(a) | |
1561 | extern void wl_cfg80211_ibss_vsie_set_buffer(struct net_device *dev, vndr_ie_setbuf_t *ibss_vsie, | |
1562 | int ibss_vsie_len); | |
1563 | extern s32 wl_cfg80211_ibss_vsie_delete(struct net_device *dev); | |
1564 | #ifdef WL_RELMCAST | |
1565 | extern void wl_cfg80211_set_rmc_pid(struct net_device *dev, int pid); | |
1566 | #endif /* WL_RELMCAST */ | |
1567 | extern int wl_cfg80211_set_mgmt_vndr_ies(struct bcm_cfg80211 *cfg, | |
1568 | bcm_struct_cfgdev *cfgdev, s32 bssidx, s32 pktflag, | |
1569 | const u8 *vndr_ie, u32 vndr_ie_len); | |
1570 | ||
1571 | ||
1572 | /* Action frame specific functions */ | |
1573 | extern u8 wl_get_action_category(void *frame, u32 frame_len); | |
1574 | extern int wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action); | |
1575 | ||
1576 | #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST | |
1577 | struct net_device *wl_cfg80211_get_remain_on_channel_ndev(struct bcm_cfg80211 *cfg); | |
1578 | #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */ | |
1579 | ||
1580 | #ifdef WL_SUPPORT_ACS | |
1581 | #define ACS_MSRMNT_DELAY 1000 /* dump_obss delay in ms */ | |
1582 | #define IOCTL_RETRY_COUNT 5 | |
1583 | #define CHAN_NOISE_DUMMY -80 | |
1584 | #define OBSS_TOKEN_IDX 15 | |
1585 | #define IBSS_TOKEN_IDX 15 | |
1586 | #define TX_TOKEN_IDX 14 | |
1587 | #define CTG_TOKEN_IDX 13 | |
1588 | #define PKT_TOKEN_IDX 15 | |
1589 | #define IDLE_TOKEN_IDX 12 | |
1590 | #endif /* WL_SUPPORT_ACS */ | |
1591 | ||
1592 | ||
1593 | extern int wl_cfg80211_get_ioctl_version(void); | |
1594 | extern int wl_cfg80211_enable_roam_offload(struct net_device *dev, int enable); | |
1595 | extern s32 wl_cfg80211_dfs_ap_move(struct net_device *ndev, char *data, | |
1596 | char *command, int total_len); | |
1597 | #ifdef WBTEXT | |
1598 | extern s32 wl_cfg80211_wbtext_set_default(struct net_device *ndev); | |
1599 | extern s32 wl_cfg80211_wbtext_config(struct net_device *ndev, char *data, | |
1600 | char *command, int total_len); | |
1601 | extern int wl_cfg80211_wbtext_weight_config(struct net_device *ndev, char *data, | |
1602 | char *command, int total_len); | |
1603 | extern int wl_cfg80211_wbtext_table_config(struct net_device *ndev, char *data, | |
1604 | char *command, int total_len); | |
1605 | extern s32 wl_cfg80211_wbtext_delta_config(struct net_device *ndev, char *data, | |
1606 | char *command, int total_len); | |
1607 | #endif /* WBTEXT */ | |
1608 | extern s32 wl_cfg80211_get_chanspecs_2g(struct net_device *ndev, | |
1609 | void *buf, s32 buflen); | |
1610 | extern s32 wl_cfg80211_get_chanspecs_5g(struct net_device *ndev, | |
1611 | void *buf, s32 buflen); | |
1612 | ||
1613 | extern s32 wl_cfg80211_bss_up(struct bcm_cfg80211 *cfg, | |
1614 | struct net_device *ndev, s32 bsscfg_idx, s32 up); | |
1615 | extern bool wl_cfg80211_bss_isup(struct net_device *ndev, int bsscfg_idx); | |
1616 | ||
1617 | struct net_device *wl_cfg80211_post_ifcreate(struct net_device *ndev, | |
1618 | wl_if_event_info *event, u8 *addr, const char *name, bool rtnl_lock_reqd); | |
1619 | extern s32 wl_cfg80211_post_ifdel(struct net_device *ndev, bool rtnl_lock_reqd); | |
1620 | #if defined(WL_VIRTUAL_APSTA) | |
1621 | extern int wl_cfg80211_interface_create(struct net_device *dev, char *name); | |
1622 | extern int wl_cfg80211_interface_delete(struct net_device *dev, char *name); | |
1623 | #if defined(PKT_FILTER_SUPPORT) && defined(APSTA_BLOCK_ARP_DURING_DHCP) | |
1624 | extern void wl_cfg80211_block_arp(struct net_device *dev, int enable); | |
1625 | #endif /* PKT_FILTER_SUPPORT && APSTA_BLOCK_ARP_DURING_DHCP */ | |
1626 | #endif /* defined (WL_VIRTUAL_APSTA) */ | |
1627 | ||
1628 | ||
1629 | #ifdef WL_CFG80211_P2P_DEV_IF | |
1630 | extern void wl_cfg80211_del_p2p_wdev(struct net_device *dev); | |
1631 | #endif /* WL_CFG80211_P2P_DEV_IF */ | |
1632 | #if defined(WL_SUPPORT_AUTO_CHANNEL) | |
1633 | extern int wl_cfg80211_set_spect(struct net_device *dev, int spect); | |
1634 | extern int wl_cfg80211_get_sta_channel(struct net_device *dev); | |
1635 | #endif /* WL_SUPPORT_AUTO_CHANNEL */ | |
1636 | ||
1637 | #ifdef P2P_LISTEN_OFFLOADING | |
1638 | extern s32 wl_cfg80211_p2plo_listen_start(struct net_device *dev, u8 *buf, int len); | |
1639 | extern s32 wl_cfg80211_p2plo_listen_stop(struct net_device *dev); | |
1640 | #endif /* P2P_LISTEN_OFFLOADING */ | |
1641 | ||
1642 | #define RETURN_EIO_IF_NOT_UP(wlpriv) \ | |
1643 | do { \ | |
1644 | struct net_device *checkSysUpNDev = bcmcfg_to_prmry_ndev(wlpriv); \ | |
1645 | if (unlikely(!wl_get_drv_status(wlpriv, READY, checkSysUpNDev))) { \ | |
1646 | WL_INFORM(("device is not ready\n")); \ | |
1647 | return -EIO; \ | |
1648 | } \ | |
1649 | } while (0) | |
1650 | ||
1651 | #ifdef QOS_MAP_SET | |
1652 | extern uint8 *wl_get_up_table(void); | |
1653 | #endif /* QOS_MAP_SET */ | |
1654 | ||
1655 | #define P2PO_COOKIE 65535 | |
1656 | u64 wl_cfg80211_get_new_roc_id(struct bcm_cfg80211 *cfg); | |
1657 | ||
1658 | #if defined(SUPPORT_RANDOM_MAC_SCAN) | |
1659 | int wl_cfg80211_set_random_mac(struct net_device *dev, bool enable); | |
1660 | int wl_cfg80211_random_mac_enable(struct net_device *dev); | |
1661 | int wl_cfg80211_random_mac_disable(struct net_device *dev); | |
1662 | #endif /* SUPPORT_RANDOM_MAC_SCAN */ | |
1663 | #ifdef SUPPORT_AP_HIGHER_BEACONRATE | |
1664 | int wl_set_ap_beacon_rate(struct net_device *dev, int val, char *ifname); | |
1665 | int wl_get_ap_basic_rate(struct net_device *dev, char* command, char *ifname, int total_len); | |
1666 | #endif /* SUPPORT_AP_HIGHER_BEACONRATE */ | |
1667 | #ifdef SUPPORT_AP_RADIO_PWRSAVE | |
1668 | int wl_get_ap_rps(struct net_device *dev, char* command, char *ifname, int total_len); | |
1669 | int wl_set_ap_rps(struct net_device *dev, bool enable, char *ifname); | |
1670 | int wl_update_ap_rps_params(struct net_device *dev, ap_rps_info_t* rps, char *ifname); | |
1671 | void wl_cfg80211_init_ap_rps(struct bcm_cfg80211 *cfg); | |
1672 | #endif /* SUPPORT_AP_RADIO_PWRSAVE */ | |
1673 | #ifdef SUPPORT_RSSI_LOGGING | |
1674 | int wl_get_rssi_logging(struct net_device *dev, void *param); | |
1675 | int wl_set_rssi_logging(struct net_device *dev, void *param); | |
1676 | int wl_get_rssi_per_ant(struct net_device *dev, char *ifname, char *peer_mac, void *param); | |
1677 | #endif /* SUPPORT_RSSI_LOGGING */ | |
1678 | int wl_cfg80211_iface_count(struct net_device *dev); | |
1679 | struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname); | |
1680 | struct net_device* wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname); | |
1681 | int wl_cfg80211_get_vndr_ouilist(struct bcm_cfg80211 *cfg, uint8 *buf, int max_cnt); | |
d964ce36 | 1682 | s32 wl_cfg80211_autochannel(struct net_device *dev, char* command, int total_len); |
010c3a89 | 1683 | #endif /* _wl_cfg80211_h_ */ |