1 /*
2 * Linux cfg80211 driver
3 *
4 * Portions of this code are copyright (c) 2021 Cypress Semiconductor Corporation
5 *
6 * Copyright (C) 1999-2017, Broadcom Corporation
7 *
8 * Unless you and Broadcom execute a separate written software license
9 * agreement governing use of this software, this software is licensed to you
10 * under the terms of the GNU General Public License version 2 (the "GPL"),
11 * available at http://www.broadcom.com/licenses/GPLv2.php, with the
12 * following added to such license:
13 *
14 * As a special exception, the copyright holders of this software give you
15 * permission to link this software with independent modules, and to copy and
16 * distribute the resulting executable under terms of your choice, provided that
17 * you also meet, for each linked independent module, the terms and conditions of
18 * the license of that module. An independent module is a module which is not
19 * derived from this software. The special exception does not apply to any
20 * modifications of the software.
21 *
22 * Notwithstanding the above, under no circumstances may you combine this
23 * software in any way with any other Broadcom software provided under a license
24 * other than the GPL, without Broadcom's express prior written consent.
25 *
26 *
27 * <<Broadcom-WL-IPTag/Open:>>
28 *
29 * $Id: wl_cfg80211.h 815697 2019-04-19 03:53:33Z $
30 */
31
32 /**
33 * Older Linux versions support the 'iw' interface, more recent ones the 'cfg80211' interface.
34 */
35
36 #ifndef _wl_cfg80211_h_
37 #define _wl_cfg80211_h_
38
39 #include <linux/wireless.h>
40 #include <typedefs.h>
41 #include <ethernet.h>
42 #include <wlioctl.h>
43 #include <linux/wireless.h>
44 #include <net/cfg80211.h>
45 #include <linux/rfkill.h>
46 #include <osl.h>
47 #include <dngl_stats.h>
48 #include <dhd.h>
49
50 #define WL_CFG_DRV_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
51 #define WL_CFG_DRV_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
52
53 #define WL_CFG_WPS_SYNC_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
54 #define WL_CFG_WPS_SYNC_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
55
56 #define WL_CFG_NET_LIST_SYNC_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
57 #define WL_CFG_NET_LIST_SYNC_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
58
59 #define WL_CFG_EQ_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
60 #define WL_CFG_EQ_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
61
62 #define WL_CFG_BAM_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
63 #define WL_CFG_BAM_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
64
65 #define WL_CFG_VNDR_OUI_SYNC_LOCK(lock, flags) (flags) = osl_spin_lock(lock)
66 #define WL_CFG_VNDR_OUI_SYNC_UNLOCK(lock, flags) osl_spin_unlock((lock), (flags))
67
68 #include <wl_cfgp2p.h>
69 #ifdef WL_NAN
70 #include <wl_cfgnan.h>
71 #endif /* WL_NAN */
72 #ifdef WL_BAM
73 #include <wl_bam.h>
74 #endif /* WL_BAM */
75 #ifdef BIGDATA_SOFTAP
76 #include <wl_bigdata.h>
77 #endif /* BIGDATA_SOFTAP */
78 struct wl_conf;
79 struct wl_iface;
80 struct bcm_cfg80211;
81 struct wl_security;
82 struct wl_ibss;
83
84 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 17, 0) && !defined(WL_SAE))
85 #define WL_SAE
86 #endif // endif
87
88 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 18, 0) && !defined(WL_FILS_ROAM_OFFLD))
89 #define WL_FILS_ROAM_OFFLD
90 #endif // endif
91
92 #ifdef WL_SAE
93 #define IS_AKM_SAE(akm) (akm == WLAN_AKM_SUITE_SAE)
94 #else
95 #define IS_AKM_SAE(akm) FALSE
96 #endif // endif
97 #ifdef WL_OWE
98 #define IS_AKM_OWE(akm) (akm == WLAN_AKM_SUITE_OWE)
99 #else
100 #define IS_AKM_OWE(akm) FALSE
101 #endif // endif
102
103 #define htod32(i) (i)
104 #define htod16(i) (i)
105 #define dtoh64(i) (i)
106 #define dtoh32(i) (i)
107 #define dtoh16(i) (i)
108 #define htodchanspec(i) (i)
109 #define dtohchanspec(i) (i)
110
111 #define WL_DBG_NONE 0
112 #define WL_DBG_P2P_ACTION (1 << 5)
113 #define WL_DBG_TRACE (1 << 4)
114 #define WL_DBG_SCAN (1 << 3)
115 #define WL_DBG_DBG (1 << 2)
116 #define WL_DBG_INFO (1 << 1)
117 #define WL_DBG_ERR (1 << 0)
118
119 #ifndef WAIT_FOR_DISCONNECT_MAX
120 #define WAIT_FOR_DISCONNECT_MAX 10
121 #endif /* WAIT_FOR_DISCONNECT_MAX */
122 #define WAIT_FOR_DISCONNECT_STATE_SYNC 10
123
124 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 7, 0))
125 /* Newer kernels use defines from nl80211.h */
126 #define IEEE80211_BAND_2GHZ NL80211_BAND_2GHZ
127 #define IEEE80211_BAND_5GHZ NL80211_BAND_5GHZ
128 #define IEEE80211_BAND_60GHZ NL80211_BAND_60GHZ
129 #define IEEE80211_NUM_BANDS NUM_NL80211_BANDS
130 #endif /* LINUX_VER >= 4.7 */
131
132 #ifdef DHD_LOG_DUMP
133 extern void dhd_log_dump_write(int type, char *binary_data,
134 int binary_len, const char *fmt, ...);
135 extern char *dhd_log_dump_get_timestamp(void);
136 #ifndef _DHD_LOG_DUMP_DEFINITIONS_
137 #define DHD_LOG_DUMP_WRITE(fmt, ...) \
138 dhd_log_dump_write(DLD_BUF_TYPE_GENERAL, NULL, 0, fmt, ##__VA_ARGS__)
139 #define DHD_LOG_DUMP_WRITE_EX(fmt, ...) \
140 dhd_log_dump_write(DLD_BUF_TYPE_SPECIAL, NULL, 0, fmt, ##__VA_ARGS__)
141 #endif /* !_DHD_LOG_DUMP_DEFINITIONS_ */
142 #endif /* DHD_LOG_DUMP */
143
144 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) || (defined(CONFIG_ARCH_MSM) && \
145 defined(CFG80211_DISCONNECTED_V2))
146 #define CFG80211_DISCONNECTED(dev, reason, ie, len, loc_gen, gfp) \
147 cfg80211_disconnected(dev, reason, ie, len, loc_gen, gfp);
148 #elif (LINUX_VERSION_CODE < KERNEL_VERSION(4, 2, 0))
149 #define CFG80211_DISCONNECTED(dev, reason, ie, len, loc_gen, gfp) \
150 BCM_REFERENCE(loc_gen); \
151 cfg80211_disconnected(dev, reason, ie, len, gfp);
152 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 2, 0)) */
153
154 /* 0 invalidates all debug messages. default is 1 */
155 #define WL_DBG_LEVEL 0xFF
156
157 #define CFG80211_INFO_TEXT "CFG80211-INFO) "
158 #ifdef CUSTOMER_HW4_DEBUG
159 #define CFG80211_ERROR_TEXT "CFG80211-INFO2) "
160 #else
161 #define CFG80211_ERROR_TEXT "CFG80211-ERROR) "
162 #endif /* CUSTOMER_HW4_DEBUG */
163
164 #if defined(DHD_DEBUG)
165 #ifdef DHD_LOG_DUMP
166 #define WL_ERR(args) \
167 do { \
168 if (wl_dbg_level & WL_DBG_ERR) { \
169 printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \
170 pr_cont args; \
171 DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \
172 DHD_LOG_DUMP_WRITE args; \
173 } \
174 } while (0)
175 #define WL_ERR_KERN(args) \
176 do { \
177 if (wl_dbg_level & WL_DBG_ERR) { \
178 printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \
179 pr_cont args; \
180 } \
181 } while (0)
182 #define WL_ERR_MEM(args) \
183 do { \
184 if (wl_dbg_level & WL_DBG_ERR) { \
185 DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \
186 DHD_LOG_DUMP_WRITE args; \
187 } \
188 } while (0)
189 #define WL_INFORM_MEM(args) \
190 do { \
191 if (wl_dbg_level & WL_DBG_INFO) { \
192 printk(KERN_INFO CFG80211_INFO_TEXT "%s : ", __func__); \
193 pr_cont args; \
194 DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \
195 DHD_LOG_DUMP_WRITE args; \
196 } \
197 } while (0)
198 #define WL_ERR_EX(args) \
199 do { \
200 if (wl_dbg_level & WL_DBG_ERR) { \
201 printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \
202 pr_cont args; \
203 DHD_LOG_DUMP_WRITE_EX("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \
204 DHD_LOG_DUMP_WRITE_EX args; \
205 } \
206 } while (0)
207 #define WL_MEM(args) \
208 do { \
209 DHD_LOG_DUMP_WRITE("[%s] %s: ", dhd_log_dump_get_timestamp(), __func__); \
210 DHD_LOG_DUMP_WRITE args; \
211 } while (0)
212 #else
213 #define WL_ERR(args) \
214 do { \
215 if (wl_dbg_level & WL_DBG_ERR) { \
216 printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \
217 pr_cont args; \
218 } \
219 } while (0)
220 #define WL_ERR_KERN(args) WL_ERR(args)
221 #define WL_ERR_MEM(args) WL_ERR(args)
222 #define WL_INFORM_MEM(args) WL_INFORM(args)
223 #define WL_ERR_EX(args) WL_ERR(args)
224 #define WL_MEM(args) WL_DBG(args)
225 #endif /* DHD_LOG_DUMP */
226 #else /* defined(DHD_DEBUG) */
227 #define WL_ERR(args) \
228 do { \
229 if ((wl_dbg_level & WL_DBG_ERR) && net_ratelimit()) { \
230 printk(KERN_INFO CFG80211_ERROR_TEXT "%s : ", __func__); \
231 pr_cont args; \
232 } \
233 } while (0)
234 #define WL_ERR_KERN(args) WL_ERR(args)
235 #define WL_ERR_MEM(args) WL_ERR(args)
236 #define WL_INFORM_MEM(args) WL_INFORM(args)
237 #define WL_ERR_EX(args) WL_ERR(args)
238 #define WL_MEM(args) WL_DBG(args)
239 #endif /* defined(DHD_DEBUG) */
240
241 #define WL_PRINT_RATE_LIMIT_PERIOD 4000000000u /* 4s in units of ns */
242 #define WL_ERR_RLMT(args) \
243 do { \
244 if (wl_dbg_level & WL_DBG_ERR) { \
245 static uint64 __err_ts = 0; \
246 static uint32 __err_cnt = 0; \
247 uint64 __cur_ts = 0; \
248 __cur_ts = local_clock(); \
249 if (__err_ts == 0 || (__cur_ts > __err_ts && \
250 (__cur_ts - __err_ts > WL_PRINT_RATE_LIMIT_PERIOD))) { \
251 __err_ts = __cur_ts; \
252 WL_ERR(args); \
253 WL_ERR(("[Repeats %u times]\n", __err_cnt)); \
254 __err_cnt = 0; \
255 } else { \
256 ++__err_cnt; \
257 } \
258 } \
259 } while (0)
260
261 #ifdef WL_INFORM
262 #undef WL_INFORM
263 #endif // endif
264
265 #define WL_INFORM(args) \
266 do { \
267 if (wl_dbg_level & WL_DBG_INFO) { \
268 printk(KERN_INFO "CFG80211-INFO) %s : ", __func__); \
269 pr_cont args; \
270 } \
271 } while (0)
272
273 #ifdef WL_SCAN
274 #undef WL_SCAN
275 #endif // endif
276 #define WL_SCAN(args) \
277 do { \
278 if (wl_dbg_level & WL_DBG_SCAN) { \
279 printk(KERN_INFO "CFG80211-SCAN) %s :", __func__); \
280 pr_cont args; \
281 } \
282 } while (0)
283 #ifdef WL_TRACE
284 #undef WL_TRACE
285 #endif // endif
286 #define WL_TRACE(args) \
287 do { \
288 if (wl_dbg_level & WL_DBG_TRACE) { \
289 printk(KERN_INFO "CFG80211-TRACE) %s :", __func__); \
290 pr_cont args; \
291 } \
292 } while (0)
293 #ifdef WL_TRACE_HW4
294 #undef WL_TRACE_HW4
295 #endif // endif
296 #ifdef CUSTOMER_HW4_DEBUG
297 #define WL_TRACE_HW4(args) \
298 do { \
299 if (wl_dbg_level & WL_DBG_ERR) { \
300 printk(KERN_INFO "CFG80211-TRACE) %s : ", __func__); \
301 pr_cont args; \
302 } \
303 } while (0)
304 #else
305 #define WL_TRACE_HW4 WL_TRACE
306 #endif /* CUSTOMER_HW4_DEBUG */
307 #if (WL_DBG_LEVEL > 0)
308 #define WL_DBG(args) \
309 do { \
310 if (wl_dbg_level & WL_DBG_DBG) { \
311 printk(KERN_INFO "CFG80211-DEBUG) %s :", __func__); \
312 pr_cont args; \
313 } \
314 } while (0)
315 #else /* !(WL_DBG_LEVEL > 0) */
316 #define WL_DBG(args)
317 #endif /* (WL_DBG_LEVEL > 0) */
318 #define WL_PNO(x)
319 #define WL_SD(x)
320
321 #define WL_SCAN_RETRY_MAX 3
322 #define WL_NUM_PMKIDS_MAX MAXPMKID
323 #define WL_SCAN_BUF_MAX (1024 * 8)
324 #define WL_TLV_INFO_MAX 1500
325 #define WL_SCAN_IE_LEN_MAX 2048
326 #define WL_BSS_INFO_MAX 2048
327 #define WL_ASSOC_INFO_MAX 512
328 #define WL_IOCTL_LEN_MAX 2048
329 #define WL_EXTRA_BUF_MAX 2048
330 #define WL_SCAN_ERSULTS_LAST (WL_SCAN_RESULTS_NO_MEM+1)
331 #define WL_AP_MAX 256
332 #define WL_FILE_NAME_MAX 256
333 #define WL_DWELL_TIME 200
334 #define WL_MED_DWELL_TIME 400
335 #define WL_MIN_DWELL_TIME 100
336 #define WL_LONG_DWELL_TIME 1000
337 #define IFACE_MAX_CNT 6
338 #define WL_SCAN_CONNECT_DWELL_TIME_MS 200
339 #define WL_SCAN_JOIN_PROBE_INTERVAL_MS 20
340 #define WL_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
341 #define WL_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
342 #define WL_AF_TX_MAX_RETRY 5
343
344 #define WL_AF_SEARCH_TIME_MAX 450
345 #define WL_AF_TX_EXTRA_TIME_MAX 200
346
347 #define WL_SCAN_TIMER_INTERVAL_MS 10000 /* Scan timeout */
348 #ifdef WL_NAN
349 #define WL_SCAN_TIMER_INTERVAL_MS_NAN 15000 /* Scan timeout */
350 #endif /* WL_NAN */
351 #define WL_CHANNEL_SYNC_RETRY 5
352 #define WL_INVALID -1
353
354 #ifdef DHD_LOSSLESS_ROAMING
355 #define WL_ROAM_TIMEOUT_MS 1000 /* Roam timeout */
356 #endif // endif
357
358 #ifdef ENABLE_HOGSQS
359 #define WL_HOGSQS_TIMEOUT_MS 5000 /* Hogger detection timeout */
360 #endif // endif
361
362 /* Bring down SCB Timeout to 20secs from 60secs default */
363 #ifndef WL_SCB_TIMEOUT
364 #define WL_SCB_TIMEOUT 20
365 #endif // endif
366
367 #if defined(ROAM_ENABLE) || defined(ROAM_CHANNEL_CACHE)
368 #define ESCAN_CHANNEL_CACHE
369 #endif // endif
370
371 #ifndef WL_SCB_ACTIVITY_TIME
372 #define WL_SCB_ACTIVITY_TIME 5
373 #endif // endif
374
375 #ifndef WL_SCB_MAX_PROBE
376 #define WL_SCB_MAX_PROBE 3
377 #endif // endif
378
379 #ifndef WL_PSPRETEND_RETRY_LIMIT
380 #define WL_PSPRETEND_RETRY_LIMIT 1
381 #endif // endif
382
383 #ifndef WL_MIN_PSPRETEND_THRESHOLD
384 #define WL_MIN_PSPRETEND_THRESHOLD 2
385 #endif // endif
386
387 /* Cipher suites */
388 #ifndef WLAN_CIPHER_SUITE_PMK
389 #define WLAN_CIPHER_SUITE_PMK 0x00904C00
390 #endif /* WLAN_CIPHER_SUITE_PMK */
391
392 #ifndef WLAN_AKM_SUITE_FT_8021X
393 #define WLAN_AKM_SUITE_FT_8021X 0x000FAC03
394 #endif /* WLAN_AKM_SUITE_FT_8021X */
395
396 #ifndef WLAN_AKM_SUITE_FT_PSK
397 #define WLAN_AKM_SUITE_FT_PSK 0x000FAC04
398 #endif /* WLAN_AKM_SUITE_FT_PSK */
399
400 #ifndef WLAN_AKM_SUITE_8021X_SUITE_B
401 #define WLAN_AKM_SUITE_8021X_SUITE_B 0x000FAC0B
402 #define WLAN_AKM_SUITE_8021X_SUITE_B_192 0x000FAC0C
403 #endif /* WLAN_AKM_SUITE_8021X_SUITE_B */
404
405 #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0))
406 /* TODO: even in upstream linux(v5.0), FT-1X-SHA384 isn't defined and supported yet.
407 * need to revisit here to sync correct name later.
408 */
409 #define WLAN_AKM_SUITE_FT_8021X_SHA384 0x000FAC0D
410 #endif /* (LINUX_VERSION_CODE < KERNEL_VERSION(5, 8, 0)) */
411
412 #define WL_AKM_SUITE_SHA256_1X 0x000FAC05
413 #define WL_AKM_SUITE_SHA256_PSK 0x000FAC06
414 #define WLAN_AKM_SUITE_DPP 0x506F9A02
415 #define WFA_AUTH_DPP 0x200000 /* WFA DPP AUTH */
416
417 #ifndef WLAN_AKM_SUITE_FILS_SHA256
418 #define WLAN_AKM_SUITE_FILS_SHA256 0x000FAC0E
419 #define WLAN_AKM_SUITE_FILS_SHA384 0x000FAC0F
420 #define WLAN_AKM_SUITE_FT_FILS_SHA256 0x000FAC10
421 #define WLAN_AKM_SUITE_FT_FILS_SHA384 0x000FAC11
422 #endif /* WLAN_AKM_SUITE_FILS_SHA256 */
423
424 #define MIN_VENDOR_EXTN_IE_LEN 2
425 #ifdef WL_OWE
426 #ifndef WLAN_AKM_SUITE_OWE
427 #define WLAN_AKM_SUITE_OWE 0X000FAC12
428 #endif /* WPA_KEY_MGMT_OWE */
429 #endif /* WL_OWE */
430
431 /*
432 * BRCM local.
433 * Use a high number that's unlikely to clash with linux upstream for a while until we can
434 * submit these changes to the community.
435 */
436 #define NL80211_FEATURE_FW_4WAY_HANDSHAKE (1<<31)
437
438 /* SCAN_SUPPRESS timer values in ms */
439 #define WL_SCAN_SUPPRESS_TIMEOUT 31000 /* default Framwork DHCP timeout is 30 sec */
440 #define WL_SCAN_SUPPRESS_RETRY 3000
441
442 #define WL_PM_ENABLE_TIMEOUT 10000
443
444 /* cfg80211 wowlan definitions */
445 #define WL_WOWLAN_MAX_PATTERNS 8
446 #define WL_WOWLAN_MIN_PATTERN_LEN 1
447 #define WL_WOWLAN_MAX_PATTERN_LEN 255
448 #define WL_WOWLAN_PKT_FILTER_ID_FIRST 201
449 #define WL_WOWLAN_PKT_FILTER_ID_LAST (WL_WOWLAN_PKT_FILTER_ID_FIRST + \
450 WL_WOWLAN_MAX_PATTERNS - 1)
451 #ifdef WLAIBSS
452 #define IBSS_COALESCE_DEFAULT 0
453 #define IBSS_INITIAL_SCAN_ALLOWED_DEFAULT 0
454 #else /* WLAIBSS */
455 #define IBSS_COALESCE_DEFAULT 1
456 #define IBSS_INITIAL_SCAN_ALLOWED_DEFAULT 1
457 #endif /* WLAIBSS */
458
459 #ifdef WLTDLS
460 #define TDLS_TUNNELED_PRB_REQ "\x7f\x50\x6f\x9a\04"
461 #define TDLS_TUNNELED_PRB_RESP "\x7f\x50\x6f\x9a\05"
462 #define TDLS_MAX_IFACE_FOR_ENABLE 1
463 #endif /* WLTDLS */
464
465 #ifdef WLAIBSS
466 /* Custom AIBSS beacon parameters */
467 #define AIBSS_INITIAL_MIN_BCN_DUR 500
468 #define AIBSS_MIN_BCN_DUR 5000
469 #define AIBSS_BCN_FLOOD_DUR 5000
470 #define AIBSS_PEER_FREE 3
471 #endif /* WLAIBSS */
472
473 #ifndef FILS_INDICATION_IE_TAG_FIXED_LEN
474 #define FILS_INDICATION_IE_TAG_FIXED_LEN 2
475 #endif // endif
476
477 /* driver status */
478 enum wl_status {
479 WL_STATUS_READY = 0,
480 WL_STATUS_SCANNING,
481 WL_STATUS_SCAN_ABORTING,
482 WL_STATUS_CONNECTING,
483 WL_STATUS_CONNECTED,
484 WL_STATUS_DISCONNECTING,
485 WL_STATUS_AP_CREATING,
486 WL_STATUS_AP_CREATED,
487 /* whole sending action frame procedure:
488 * includes a) 'finding common channel' for public action request frame
489 * and b) 'sending af via 'actframe' iovar'
490 */
491 WL_STATUS_SENDING_ACT_FRM,
492 /* find a peer to go to a common channel before sending public action req frame */
493 WL_STATUS_FINDING_COMMON_CHANNEL,
494 /* waiting for next af to sync time of supplicant.
495 * it includes SENDING_ACT_FRM and WAITING_NEXT_ACT_FRM_LISTEN
496 */
497 WL_STATUS_WAITING_NEXT_ACT_FRM,
498 #ifdef WL_CFG80211_SYNC_GON
499 /* go to listen state to wait for next af after SENDING_ACT_FRM */
500 WL_STATUS_WAITING_NEXT_ACT_FRM_LISTEN,
501 #endif /* WL_CFG80211_SYNC_GON */
502 /* it will be set when upper layer requests listen and succeed in setting listen mode.
503 * if set, other scan request can abort current listen state
504 */
505 WL_STATUS_REMAINING_ON_CHANNEL,
506 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
507 /* it's fake listen state to keep current scan state.
508 * it will be set when upper layer requests listen but scan is running. then just run
509 * a expire timer without actual listen state.
510 * if set, other scan request does not need to abort scan.
511 */
512 WL_STATUS_FAKE_REMAINING_ON_CHANNEL,
513 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
514 WL_STATUS_NESTED_CONNECT,
515 WL_STATUS_CFG80211_CONNECT
516 };
517
518 typedef enum wl_iftype {
519 WL_IF_TYPE_STA = 0,
520 WL_IF_TYPE_AP = 1,
521 WL_IF_TYPE_AWDL = 2,
522 WL_IF_TYPE_NAN_NMI = 3,
523 WL_IF_TYPE_NAN = 4,
524 WL_IF_TYPE_P2P_GO = 5,
525 WL_IF_TYPE_P2P_GC = 6,
526 WL_IF_TYPE_P2P_DISC = 7,
527 WL_IF_TYPE_IBSS = 8,
528 WL_IF_TYPE_MONITOR = 9,
529 WL_IF_TYPE_AIBSS = 10,
530 WL_IF_TYPE_MAX
531 } wl_iftype_t;
532
533 typedef enum wl_interface_state {
534 WL_IF_CREATE_REQ,
535 WL_IF_CREATE_DONE,
536 WL_IF_DELETE_REQ,
537 WL_IF_DELETE_DONE,
538 WL_IF_CHANGE_REQ,
539 WL_IF_CHANGE_DONE,
540 WL_IF_STATE_MAX, /* Retain as last one */
541 } wl_interface_state_t;
542
543 /* wi-fi mode */
544 enum wl_mode {
545 WL_MODE_BSS,
546 WL_MODE_IBSS,
547 WL_MODE_AP,
548 WL_MODE_AWDL,
549 WL_MODE_NAN
550 };
551
552 /* driver profile list */
553 enum wl_prof_list {
554 WL_PROF_MODE,
555 WL_PROF_SSID,
556 WL_PROF_SEC,
557 WL_PROF_IBSS,
558 WL_PROF_BAND,
559 WL_PROF_CHAN,
560 WL_PROF_BSSID,
561 WL_PROF_ACT,
562 WL_PROF_BEACONINT,
563 WL_PROF_DTIMPERIOD,
564 WL_PROF_LATEST_BSSID
565 };
566
567 /* donlge escan state */
568 enum wl_escan_state {
569 WL_ESCAN_STATE_IDLE,
570 WL_ESCAN_STATE_SCANING
571 };
572 /* fw downloading status */
573 enum wl_fw_status {
574 WL_FW_LOADING_DONE,
575 WL_NVRAM_LOADING_DONE
576 };
577
578 enum wl_management_type {
579 WL_BEACON = 0x1,
580 WL_PROBE_RESP = 0x2,
581 WL_ASSOC_RESP = 0x4
582 };
583
584 enum wl_pm_workq_act_type {
585 WL_PM_WORKQ_SHORT,
586 WL_PM_WORKQ_LONG,
587 WL_PM_WORKQ_DEL
588 };
589
590 enum wl_tdls_config {
591 TDLS_STATE_AP_CREATE,
592 TDLS_STATE_AP_DELETE,
593 TDLS_STATE_CONNECT,
594 TDLS_STATE_DISCONNECT,
595 TDLS_STATE_SETUP,
596 TDLS_STATE_TEARDOWN,
597 TDLS_STATE_IF_CREATE,
598 TDLS_STATE_IF_DELETE,
599 TDLS_STATE_NMI_CREATE
600 };
601
602 /* beacon / probe_response */
603 struct beacon_proberesp {
604 __le64 timestamp;
605 __le16 beacon_int;
606 __le16 capab_info;
607 u8 variable[0];
608 } __attribute__ ((packed));
609
610 /* driver configuration */
611 struct wl_conf {
612 u32 frag_threshold;
613 u32 rts_threshold;
614 u32 retry_short;
615 u32 retry_long;
616 s32 tx_power;
617 struct ieee80211_channel channel;
618 };
619
620 typedef s32(*EVENT_HANDLER) (struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
621 const wl_event_msg_t *e, void *data);
622
623 /* bss inform structure for cfg80211 interface */
624 struct wl_cfg80211_bss_info {
625 u16 band;
626 u16 channel;
627 s16 rssi;
628 u16 frame_len;
629 u8 frame_buf[1];
630 };
631
632 /* basic structure of scan request */
633 struct wl_scan_req {
634 struct wlc_ssid ssid;
635 };
636
637 /* basic structure of information element */
638 struct wl_ie {
639 u16 offset;
640 u8 buf[WL_TLV_INFO_MAX];
641 };
642
643 /* event queue for cfg80211 main event */
644 struct wl_event_q {
645 struct list_head eq_list;
646 u32 etype;
647 wl_event_msg_t emsg;
648 u32 datalen;
649 s8 edata[1];
650 };
651
652 /* security information with currently associated ap */
653 struct wl_security {
654 u32 wpa_versions;
655 u32 auth_type;
656 u32 cipher_pairwise;
657 u32 cipher_group;
658 u32 wpa_auth;
659 u32 auth_assoc_res_status;
660 };
661
662 /* ibss information for currently joined ibss network */
663 struct wl_ibss {
664 u8 beacon_interval; /* in millisecond */
665 u8 atim; /* in millisecond */
666 s8 join_only;
667 u8 band;
668 u8 channel;
669 };
670
671 typedef struct wl_bss_vndr_ies {
672 u8 probe_req_ie[VNDR_IES_BUF_LEN];
673 u8 probe_res_ie[VNDR_IES_MAX_BUF_LEN];
674 u8 assoc_req_ie[VNDR_IES_BUF_LEN];
675 u8 assoc_res_ie[VNDR_IES_BUF_LEN];
676 u8 beacon_ie[VNDR_IES_MAX_BUF_LEN];
677 u8 disassoc_ie[VNDR_IES_BUF_LEN];
678 u32 probe_req_ie_len;
679 u32 probe_res_ie_len;
680 u32 assoc_req_ie_len;
681 u32 assoc_res_ie_len;
682 u32 beacon_ie_len;
683 u32 disassoc_ie_len;
684 } wl_bss_vndr_ies_t;
685
686 typedef struct wl_cfgbss {
687 u8 *wpa_ie;
688 u8 *rsn_ie;
689 u8 *wps_ie;
690 u8 *fils_ind_ie;
691 bool security_mode;
692 struct wl_bss_vndr_ies ies; /* Common for STA, P2P GC, GO, AP, P2P Disc Interface */
693 } wl_cfgbss_t;
694
695 #ifdef WL11U
696 /* Max length of Interworking element */
697 #define IW_IES_MAX_BUF_LEN 8
698 #endif // endif
699
700 /* cfg driver profile */
701 struct wl_profile {
702 u32 mode;
703 s32 band;
704 u32 channel;
705 struct wlc_ssid ssid;
706 struct wl_security sec;
707 struct wl_ibss ibss;
708 u8 bssid[ETHER_ADDR_LEN];
709 u16 beacon_interval;
710 u8 dtim_period;
711 bool active;
712 u8 latest_bssid[ETHER_ADDR_LEN];
713 u32 channel_width;
714 #ifdef WL11U
715 u8 iw_ie[IW_IES_MAX_BUF_LEN];
716 u32 iw_ie_len;
717 #endif /* WL11U */
718 bool dpp_listen;
719 };
720
721 struct wl_wps_ie {
722 uint8 id; /* IE ID: 0xDD */
723 uint8 len; /* IE length */
724 uint8 OUI[3]; /* WiFi WPS specific OUI */
725 uint8 oui_type; /* Vendor specific OUI Type */
726 uint8 attrib[1]; /* variable length attributes */
727 } __attribute__ ((packed));
728 typedef struct wl_wps_ie wl_wps_ie_t;
729
730 struct wl_eap_msg {
731 uint16 attrib;
732 uint16 len;
733 uint8 type;
734 } __attribute__ ((packed));
735 typedef struct wl_eap_msg wl_eap_msg_t;
736
737 struct wl_eap_exp {
738 uint8 OUI[3];
739 uint32 oui_type;
740 uint8 opcode;
741 u8 flags;
742 u8 data[1];
743 } __attribute__ ((packed));
744 typedef struct wl_eap_exp wl_eap_exp_t;
745
746 struct net_info {
747 struct net_device *ndev;
748 struct wireless_dev *wdev;
749 struct wl_profile profile;
750 wl_iftype_t iftype;
751 s32 roam_off;
752 unsigned long sme_state;
753 bool pm_restore;
754 bool pm_block;
755 s32 pm;
756 s32 bssidx;
757 wl_cfgbss_t bss;
758 u8 ifidx;
759 #ifdef WL_SAE
760 unsigned long mgmt_txstatus;
761 size_t mgmt_txid;
762 struct completion mgmt_tx_cpl;
763 #endif /* WL_SAE */
764 struct list_head list; /* list of all net_info structure */
765 };
766 #ifdef WL_SAE
767 #define WL_WSEC_MAX_SAE_PASSWORD_LEN 128
768 #define WL_WSEC_MIN_SAE_PASSWORD_LEN 8
769 /**
770 * struct brcmf_wsec_sae_pwd_le - firmware SAE password material.
771 *
772 * @key_len: number of octets in key materials.
773 * @key: SAE password material.
774 */
775 struct wl_wsec_sae_pwd_le {
776 u16 key_len;
777 u8 key[WL_WSEC_MAX_SAE_PASSWORD_LEN];
778 };
779
780 #endif // endif
781 #ifdef WL_BCNRECV
782 /* PERIODIC Beacon receive for detecting FakeAPs */
783 typedef struct wl_bcnrecv_result {
784 uint8 SSID[DOT11_MAX_SSID_LEN]; /**< SSID String */
785 struct ether_addr BSSID; /**< Network BSSID */
786 uint8 channel; /**< Channel */
787 uint16 beacon_interval;
788 uint32 timestamp[2]; /**< Beacon Timestamp */
789 uint64 system_time;
790 } wl_bcnrecv_result_t;
791
792 typedef struct wl_bcnrecv_info {
793 uint bcnrecv_state; /* TO know the fakeap state */
794 } wl_bcnrecv_info_t;
795
796 typedef enum wl_bcnrecv_state {
797 BEACON_RECV_IDLE = 0,
798 BEACON_RECV_STARTED,
799 BEACON_RECV_STOPPED,
800 BEACON_RECV_SUSPENDED
801 } wl_bcnrecv_state_t;
802
803 typedef enum wl_bcnrecv_reason {
804 WL_BCNRECV_INVALID = 0,
805 WL_BCNRECV_USER_TRIGGER,
806 WL_BCNRECV_SUSPEND,
807 WL_BCNRECV_SCANBUSY,
808 WL_BCNRECV_CONCURRENCY,
809 WL_BCNRECV_LISTENBUSY,
810 WL_BCNRECV_ROAMABORT,
811 WL_BCNRECV_HANG
812 } wl_bcnrecv_reason_t;
813
814 typedef enum wl_bcnrecv_status {
815 WL_BCNRECV_STARTED = 0,
816 WL_BCNRECV_STOPPED,
817 WL_BCNRECV_ABORTED,
818 WL_BCNRECV_SUSPENDED,
819 WL_BCNRECV_MAX
820 } wl_bcnrecv_status_t;
821
822 typedef enum wl_bcnrecv_attr_type {
823 BCNRECV_ATTR_STATUS = 1,
824 BCNRECV_ATTR_REASON,
825 BCNRECV_ATTR_BCNINFO
826 } wl_bcnrecv_attr_type_t;
827 #endif /* WL_BCNRECV */
828 #ifdef WL_CHAN_UTIL
829 #define CU_ATTR_PERCENTAGE 1
830 #define CU_ATTR_HDR_LEN 30
831 #endif /* WL_CHAN_UTIL */
832
833 /* association inform */
834 #define MAX_REQ_LINE 1024u
835 struct wl_connect_info {
836 u8 req_ie[MAX_REQ_LINE];
837 u32 req_ie_len;
838 u8 resp_ie[MAX_REQ_LINE];
839 u32 resp_ie_len;
840 };
841 #define WL_MAX_FILS_KEY_LEN 64
842
843 struct wl_fils_info {
844 u8 fils_kek[WL_MAX_FILS_KEY_LEN];
845 u32 fils_kek_len;
846 u8 fils_pmk[WL_MAX_FILS_KEY_LEN];
847 u32 fils_pmk_len;
848 u8 fils_pmkid[WL_MAX_FILS_KEY_LEN];
849 u16 fils_erp_next_seq_num;
850 bool fils_roam_disabled;
851 u32 fils_bcn_timeout_cache;
852 };
853
854 /* firmware /nvram downloading controller */
855 struct wl_fw_ctrl {
856 const struct firmware *fw_entry;
857 unsigned long status;
858 u32 ptr;
859 s8 fw_name[WL_FILE_NAME_MAX];
860 s8 nvram_name[WL_FILE_NAME_MAX];
861 };
862
863 /* assoc ie length */
864 struct wl_assoc_ielen {
865 u32 req_len;
866 u32 resp_len;
867 };
868
869 #define MIN_PMKID_LIST_V3_FW_MAJOR 13
870 #define MIN_PMKID_LIST_V3_FW_MINOR 0
871
872 #define MIN_PMKID_LIST_V2_FW_MAJOR 12
873 #define MIN_PMKID_LIST_V2_FW_MINOR 0
874
875 #define MIN_ESCAN_PARAM_V2_FW_MAJOR 14
876 #define MIN_ESCAN_PARAM_V2_FW_MINOR 0
877
878 /* wpa2 pmk list */
879 struct wl_pmk_list {
880 pmkid_list_v3_t pmkids;
881 pmkid_v3_t foo[MAXPMKID - 1];
882 };
883
884 #define KEY_PERM_PMK 0xFFFFFFFF
885
886 #ifdef DHD_MAX_IFS
887 #define WL_MAX_IFS DHD_MAX_IFS
888 #else
889 #define WL_MAX_IFS 16
890 #endif // endif
891
892 #define MAC_RAND_BYTES 3
893 #define ESCAN_BUF_SIZE (64 * 1024)
894
895 struct escan_info {
896 u32 escan_state;
897 #ifdef STATIC_WL_PRIV_STRUCT
898 #ifndef CONFIG_DHD_USE_STATIC_BUF
899 #error STATIC_WL_PRIV_STRUCT should be used with CONFIG_DHD_USE_STATIC_BUF
900 #endif /* CONFIG_DHD_USE_STATIC_BUF */
901 #ifdef DUAL_ESCAN_RESULT_BUFFER
902 u8 *escan_buf[2];
903 #else
904 u8 *escan_buf;
905 #endif /* DUAL_ESCAN_RESULT_BUFFER */
906 #else
907 #ifdef DUAL_ESCAN_RESULT_BUFFER
908 u8 escan_buf[2][ESCAN_BUF_SIZE];
909 #else
910 u8 escan_buf[ESCAN_BUF_SIZE];
911 #endif /* DUAL_ESCAN_RESULT_BUFFER */
912 #endif /* STATIC_WL_PRIV_STRUCT */
913 #ifdef DUAL_ESCAN_RESULT_BUFFER
914 u8 cur_sync_id;
915 u8 escan_type[2];
916 #endif /* DUAL_ESCAN_RESULT_BUFFER */
917 struct wiphy *wiphy;
918 struct net_device *ndev;
919 };
920
921 #ifdef ESCAN_BUF_OVERFLOW_MGMT
922 #define BUF_OVERFLOW_MGMT_COUNT 3
923 typedef struct {
924 int RSSI;
925 int length;
926 struct ether_addr BSSID;
927 } removal_element_t;
928 #endif /* ESCAN_BUF_OVERFLOW_MGMT */
929
930 struct afx_hdl {
931 wl_af_params_t *pending_tx_act_frm;
932 struct ether_addr tx_dst_addr;
933 struct net_device *dev;
934 struct work_struct work;
935 s32 bssidx;
936 u32 retry;
937 s32 peer_chan;
938 s32 peer_listen_chan; /* search channel: configured by upper layer */
939 s32 my_listen_chan; /* listen chanel: extract it from prb req or gon req */
940 bool is_listen;
941 bool ack_recv;
942 bool is_active;
943 };
944
945 struct parsed_ies {
946 const wpa_ie_fixed_t *wps_ie;
947 u32 wps_ie_len;
948 const wpa_ie_fixed_t *wpa_ie;
949 u32 wpa_ie_len;
950 const bcm_tlv_t *wpa2_ie;
951 u32 wpa2_ie_len;
952 const bcm_tlv_t *fils_ind_ie;
953 u32 fils_ind_ie_len;
954 };
955
956 #ifdef P2P_LISTEN_OFFLOADING
957 typedef struct {
958 uint16 period; /* listen offload period */
959 uint16 interval; /* listen offload interval */
960 uint16 count; /* listen offload count */
961 uint16 pad; /* pad for 32bit align */
962 } wl_p2plo_listen_t;
963 #endif /* P2P_LISTEN_OFFLOADING */
964
965 #ifdef WLFBT
966 #define FBT_KEYLEN 32
967 #endif // endif
968 #define MAX_EVENT_BUF_NUM 16
969 typedef struct wl_eventmsg_buf {
970 u16 num;
971 struct {
972 u16 type;
973 bool set;
974 } event [MAX_EVENT_BUF_NUM];
975 } wl_eventmsg_buf_t;
976
977 typedef struct wl_if_event_info {
978 bool valid;
979 int ifidx;
980 int bssidx;
981 uint8 mac[ETHER_ADDR_LEN];
982 char name[IFNAMSIZ+1];
983 uint8 role;
984 } wl_if_event_info;
985
986 #ifdef SUPPORT_AP_RADIO_PWRSAVE
987 typedef struct ap_rps_info {
988 bool enable;
989 int sta_assoc_check;
990 int pps;
991 int quiet_time;
992 int level;
993 } ap_rps_info_t;
994 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
995
996 #ifdef SUPPORT_RSSI_SUM_REPORT
997 #define RSSILOG_FLAG_FEATURE_SW 0x1
998 #define RSSILOG_FLAG_REPORT_READY 0x2
999 typedef struct rssilog_set_param {
1000 uint8 enable;
1001 uint8 rssi_threshold;
1002 uint8 time_threshold;
1003 uint8 pad;
1004 } rssilog_set_param_t;
1005
1006 typedef struct rssilog_get_param {
1007 uint8 report_count;
1008 uint8 enable;
1009 uint8 rssi_threshold;
1010 uint8 time_threshold;
1011 } rssilog_get_param_t;
1012
1013 typedef struct rssi_ant_param {
1014 struct ether_addr ea;
1015 chanspec_t chanspec;
1016 } rssi_ant_param_t;
1017
1018 typedef struct wl_rssi_ant_mimo {
1019 uint32 version;
1020 uint32 count;
1021 int8 rssi_ant[WL_RSSI_ANT_MAX];
1022 int8 rssi_sum;
1023 int8 PAD[3];
1024 } wl_rssi_ant_mimo_t;
1025 #endif /* SUPPORT_RSSI_SUM_REPORT */
1026
1027 /* MBO-OCE prune event reason codes */
1028 #if defined(WL_MBO) || defined(WL_OCE)
1029 typedef enum wl_prune_evt_reason {
1030 WIFI_PRUNE_UNSPECIFIED = 0, /* Unspecified event reason code */
1031 WIFI_PRUNE_ASSOC_RETRY_DELAY = 1, /* MBO assoc retry delay */
1032 WIFI_PRUNE_RSSI_ASSOC_REJ = 2 /* OCE RSSI-based assoc rejection */
1033 } wl_prune_evt_reason_t;
1034 #endif /* WL_MBO || WL_OCE */
1035
1036 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
1037 #define GET_BSS_INFO_LEN 90
1038 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
1039
1040 #ifdef WL_MBO
1041 typedef struct wl_event_mbo wl_event_mbo_t;
1042 typedef struct wl_event_mbo_cell_nw_switch wl_event_mbo_cell_nw_switch_t;
1043 typedef struct wl_btm_event_type_data wl_btm_event_type_data_t;
1044 #endif /* WL_MBO */
1045
1046 #if defined(WL_MBO) || defined(WL_OCE)
1047 typedef struct wl_bssid_prune_evt_info wl_bssid_pruned_evt_info_t;
1048 #endif /* WL_MBO || WL_OCE */
1049
1050 #ifdef WL_NAN
1051 #define NAN_MAX_NDI 1u
1052 typedef struct wl_ndi_data
1053 {
1054 u8 ifname[IFNAMSIZ];
1055 u8 in_use;
1056 u8 created;
1057 struct net_device *nan_ndev;
1058 } wl_ndi_data_t;
1059 typedef struct wl_nancfg
1060 {
1061 wl_nan_ver_t version;
1062 wl_ndi_data_t ndi[NAN_MAX_NDI];
1063 struct mutex nan_sync;
1064 uint8 svc_inst_id_mask[NAN_SVC_INST_SIZE];
1065 uint8 inst_id_start;
1066 /* wait queue and condition variable for nan event */
1067 bool nan_event_recvd;
1068 wait_queue_head_t nan_event_wait;
1069 nan_stop_reason_code_t disable_reason;
1070 bool mac_rand;
1071 int range_type;
1072 uint8 max_ndp_count; /* Max no. of NDPs */
1073 nan_ndp_peer_t *nan_ndp_peer_info;
1074 } wl_nancfg_t;
1075
1076 #ifdef WL_NANP2P
1077 #define WL_CFG_P2P_DISC_BIT 0x1u
1078 #define WL_CFG_NAN_DISC_BIT 0x2u
1079 #define WL_NANP2P_CONC_SUPPORT (WL_CFG_P2P_DISC_BIT | WL_CFG_NAN_DISC_BIT)
1080 #endif /* WL_NAN2P */
1081 #endif /* WL_NAN */
1082
1083 #ifdef WL_IFACE_MGMT
1084 #define WL_IFACE_NOT_PRESENT -1
1085
1086 typedef enum iface_conc_policy {
1087 WL_IF_POLICY_DEFAULT = 0,
1088 WL_IF_POLICY_FCFS = 1,
1089 WL_IF_POLICY_LP = 2,
1090 WL_IF_POLICY_ROLE_PRIORITY = 3,
1091 WL_IF_POLICY_CUSTOM = 4,
1092 WL_IF_POLICY_INVALID
1093 } iface_conc_policy_t;
1094
1095 typedef struct iface_mgmt_data {
1096 uint8 policy;
1097 uint8 priority[WL_IF_TYPE_MAX];
1098 } iface_mgmt_data_t;
1099 #endif /* WL_IFACE_MGMT */
1100
1101 #ifdef WL_WPS_SYNC
1102 #define EAP_PACKET 0
1103 #define EAP_EXPANDED_TYPE 254
1104 #define EAP_EXP_OPCODE_OFFSET 7
1105 #define EAP_EXP_FRAGMENT_LEN_OFFSET 2
1106 #define EAP_EXP_FLAGS_FRAGMENTED_DATA 2
1107 #define EAP_EXP_FLAGS_MORE_DATA 1
1108 #define EAPOL_EAP_HDR_LEN 5
1109 #define EAP_EXP_HDR_MIN_LENGTH (EAPOL_EAP_HDR_LEN + EAP_EXP_OPCODE_OFFSET)
1110 #define EAP_ATTRIB_MSGTYPE 0x1022
1111 #define EAP_WSC_UPNP 0
1112 #define EAP_WSC_START 1
1113 #define EAP_WSC_ACK 2
1114 #define EAP_WSC_NACK 3
1115 #define EAP_WSC_MSG 4
1116 #define EAP_WSC_DONE 5
1117 #define EAP_WSC_MSG_M8 12
1118 #define EAP_CODE_FAILURE 4
1119 #define WL_WPS_REAUTH_TIMEOUT 10000
1120
1121 struct wl_eap_header {
1122 unsigned char code; /* EAP code */
1123 unsigned char id; /* Current request ID */
1124 unsigned short length; /* Length including header */
1125 unsigned char type; /* EAP type (optional) */
1126 unsigned char data[1]; /* Type data (optional) */
1127 } __attribute__ ((packed));
1128 typedef struct wl_eap_header wl_eap_header_t;
1129
1130 typedef enum wl_wps_state {
1131 WPS_STATE_IDLE = 0,
1132 WPS_STATE_STARTED,
1133 WPS_STATE_M8_SENT,
1134 WPS_STATE_M8_RECVD,
1135 WPS_STATE_EAP_FAIL,
1136 WPS_STATE_REAUTH_WAIT,
1137 WPS_STATE_LINKUP,
1138 WPS_STATE_LINKDOWN,
1139 WPS_STATE_DISCONNECT,
1140 WPS_STATE_DISCONNECT_CLIENT,
1141 WPS_STATE_CONNECT_FAIL,
1142 WPS_STATE_AUTHORIZE,
1143 WPS_STATE_DONE,
1144 WPS_STATE_INVALID
1145 } wl_wps_state_t;
1146
1147 #define WPS_MAX_SESSIONS 2
1148 typedef struct wl_wps_session {
1149 bool in_use;
1150 timer_list_compat_t timer;
1151 struct net_device *ndev;
1152 wl_wps_state_t state;
1153 u16 mode;
1154 u8 peer_mac[ETHER_ADDR_LEN];
1155 } wl_wps_session_t;
1156 #endif /* WL_WPS_SYNC */
1157
1158 #ifndef WL_STATIC_IFNAME_PREFIX
1159 #define WL_STATIC_IFNAME_PREFIX "wlan%d"
1160 #endif /* WL_STATIC_IFNAME */
1161 #define STATIC_INAME_STRING_LEN 6
1162 #ifndef DHD_NUM_STATIC_IFACES
1163 #define DHD_NUM_STATIC_IFACES 2
1164 #endif // endif
1165
1166 typedef struct buf_data {
1167 u32 ver; /* version of struct */
1168 u32 len; /* Total len */
1169 /* size of each buffer in case of split buffers (0 - single buffer). */
1170 u32 buf_threshold;
1171 const void *data_buf[1]; /* array of user space buffer pointers. */
1172 } buf_data_t;
1173
1174 /* private data of cfg80211 interface */
1175 struct bcm_cfg80211 {
1176 struct wireless_dev *wdev; /* representing cfg cfg80211 device */
1177
1178 struct wireless_dev *p2p_wdev; /* representing cfg cfg80211 device for P2P */
1179 struct net_device *p2p_net; /* reference to p2p0 interface */
1180
1181 struct wl_conf *conf;
1182 struct cfg80211_scan_request *scan_request; /* scan request object */
1183 EVENT_HANDLER evt_handler[WLC_E_LAST];
1184 struct list_head eq_list; /* used for event queue */
1185 struct list_head net_list; /* used for struct net_info */
1186 spinlock_t net_list_sync; /* to protect scan status (and others if needed) */
1187 spinlock_t eq_lock; /* for event queue synchronization */
1188 spinlock_t cfgdrv_lock; /* to protect scan status (and others if needed) */
1189 struct completion act_frm_scan;
1190 struct completion iface_disable;
1191 struct completion wait_next_af;
1192 struct mutex usr_sync; /* maily for up/down synchronization */
1193 struct mutex if_sync; /* maily for iface op synchronization */
1194 struct mutex scan_sync; /* scan sync from different scan contexts */
1195 struct wl_scan_results *bss_list;
1196 struct wl_scan_results *scan_results;
1197
1198 /* scan request object for internal purpose */
1199 struct wl_scan_req *scan_req_int;
1200 /* information element object for internal purpose */
1201 #if defined(STATIC_WL_PRIV_STRUCT)
1202 struct wl_ie *ie;
1203 #else
1204 struct wl_ie ie;
1205 #endif // endif
1206
1207 /* association information container */
1208 #if defined(STATIC_WL_PRIV_STRUCT)
1209 struct wl_connect_info *conn_info;
1210 #else
1211 struct wl_connect_info conn_info;
1212 #endif // endif
1213 #ifdef DEBUGFS_CFG80211
1214 struct dentry *debugfs;
1215 #endif /* DEBUGFS_CFG80211 */
1216 struct wl_pmk_list *pmk_list; /* wpa2 pmk list */
1217 tsk_ctl_t event_tsk; /* task of main event handler thread */
1218 void *pub;
1219 u32 iface_cnt;
1220 u32 channel; /* current channel */
1221 u32 af_sent_channel; /* channel action frame is sent */
1222 /* next af subtype to cancel the remained dwell time in rx process */
1223 u8 next_af_subtype;
1224 #ifdef WL_CFG80211_SYNC_GON
1225 ulong af_tx_sent_jiffies;
1226 #endif /* WL_CFG80211_SYNC_GON */
1227 struct escan_info escan_info; /* escan information */
1228 bool active_scan; /* current scan mode */
1229 bool ibss_starter; /* indicates this sta is ibss starter */
1230 bool link_up; /* link/connection up flag */
1231
1232 /* indicate whether chip to support power save mode */
1233 bool pwr_save;
1234 bool roam_on; /* on/off switch for self-roaming */
1235 bool scan_tried; /* indicates if first scan attempted */
1236 #if defined(BCMSDIO) || defined(BCMPCIE)
1237 bool wlfc_on;
1238 #endif // endif
1239 bool vsdb_mode;
1240 #define WL_ROAM_OFF_ON_CONCURRENT 0x0001
1241 #define WL_ROAM_REVERT_STATUS 0x0002
1242 u32 roam_flags;
1243 u8 *ioctl_buf; /* ioctl buffer */
1244 struct mutex ioctl_buf_sync;
1245 u8 *escan_ioctl_buf;
1246 u8 *extra_buf; /* maily to grab assoc information */
1247 struct dentry *debugfsdir;
1248 struct rfkill *rfkill;
1249 bool rf_blocked;
1250 struct ieee80211_channel remain_on_chan;
1251 enum nl80211_channel_type remain_on_chan_type;
1252 u64 send_action_id;
1253 u64 last_roc_id;
1254 wait_queue_head_t netif_change_event;
1255 wl_if_event_info if_event_info;
1256 struct completion send_af_done;
1257 struct afx_hdl *afx_hdl;
1258 struct p2p_info *p2p;
1259 bool p2p_supported;
1260 void *btcoex_info;
1261 timer_list_compat_t scan_timeout; /* Timer for catch scan event timeout */
1262 #ifdef WL_CFG80211_GON_COLLISION
1263 u8 block_gon_req_tx_count;
1264 u8 block_gon_req_rx_count;
1265 #endif /* WL_CFG80211_GON_COLLISION */
1266 #if defined(P2P_IE_MISSING_FIX)
1267 bool p2p_prb_noti;
1268 #endif // endif
1269 s32(*state_notifier) (struct bcm_cfg80211 *cfg,
1270 struct net_info *_net_info, enum wl_status state, bool set);
1271 unsigned long interrested_state;
1272 wlc_ssid_t hostapd_ssid;
1273 #ifdef WL11U
1274 bool wl11u;
1275 #endif /* WL11U */
1276 bool sched_scan_running; /* scheduled scan req status */
1277 struct cfg80211_sched_scan_request *sched_scan_req; /* scheduled scan req */
1278 #ifdef WL_HOST_BAND_MGMT
1279 u8 curr_band;
1280 #endif /* WL_HOST_BAND_MGMT */
1281 bool scan_suppressed;
1282 #ifdef OEM_ANDROID
1283 timer_list_compat_t scan_supp_timer;
1284 struct work_struct wlan_work;
1285 #endif /* OEM_ANDROID */
1286 struct mutex event_sync; /* maily for up/down synchronization */
1287 bool disable_roam_event;
1288 struct delayed_work pm_enable_work;
1289 #ifdef OEM_ANDROID
1290 struct workqueue_struct *event_workq; /* workqueue for event */
1291 #else
1292 bool event_workq_init;
1293 #endif /* OEM_ANDROID */
1294 struct work_struct event_work; /* work item for event */
1295 struct mutex pm_sync; /* mainly for pm work synchronization */
1296
1297 vndr_ie_setbuf_t *ibss_vsie; /* keep the VSIE for IBSS */
1298 int ibss_vsie_len;
1299 #ifdef WLAIBSS
1300 u32 aibss_txfail_pid;
1301 u32 aibss_txfail_seq;
1302 #endif /* WLAIBSS */
1303 #ifdef WL_RELMCAST
1304 u32 rmc_event_pid;
1305 u32 rmc_event_seq;
1306 #endif /* WL_RELMCAST */
1307 #ifdef WLAIBSS_MCHAN
1308 struct ether_addr ibss_if_addr;
1309 bcm_struct_cfgdev *ibss_cfgdev; /* For AIBSS */
1310 #endif /* WLAIBSS_MCHAN */
1311 bool bss_pending_op; /* indicate where there is a pending IF operation */
1312 #ifdef WLFBT
1313 uint8 fbt_key[FBT_KEYLEN];
1314 #endif // endif
1315 int roam_offload;
1316 #ifdef WL_NAN
1317 bool nan_enable;
1318 nan_svc_inst_t nan_inst_ctrl[NAN_ID_CTRL_SIZE];
1319 struct ether_addr initiator_ndi;
1320 uint8 nan_dp_state;
1321 bool nan_init_state; /* nan initialization state */
1322 wait_queue_head_t ndp_if_change_event;
1323 uint8 support_5g;
1324 u8 nan_nmi_mac[ETH_ALEN];
1325 u8 nan_dp_mask;
1326 wl_nancfg_t nancfg;
1327 #ifdef WL_NAN_DISC_CACHE
1328 int nan_disc_count;
1329 nan_disc_result_cache *nan_disc_cache;
1330 nan_svc_info_t svc_info[NAN_MAX_SVC_INST];
1331 nan_ranging_inst_t nan_ranging_info[NAN_MAX_RANGING_INST];
1332 #endif /* WL_NAN_DISC_CACHE */
1333 #ifdef WL_NANP2P
1334 uint8 conc_disc;
1335 bool nan_p2p_supported;
1336 #endif /* WL_NANP2P */
1337 #endif /* WL_NAN */
1338 #ifdef WL_IFACE_MGMT
1339 iface_mgmt_data_t iface_data;
1340 #endif /* WL_IFACE_MGMT */
1341 #ifdef WL_CFG80211_P2P_DEV_IF
1342 bool down_disc_if;
1343 #endif /* WL_CFG80211_P2P_DEV_IF */
1344 #ifdef P2PLISTEN_AP_SAMECHN
1345 bool p2p_resp_apchn_status;
1346 #endif /* P2PLISTEN_AP_SAMECHN */
1347 struct wl_wsec_key wep_key;
1348 #ifdef WLTDLS
1349 u8 *tdls_mgmt_frame;
1350 u32 tdls_mgmt_frame_len;
1351 s32 tdls_mgmt_freq;
1352 #endif /* WLTDLS */
1353 bool need_wait_afrx;
1354 #ifdef QOS_MAP_SET
1355 uint8 *up_table; /* user priority table, size is UP_TABLE_MAX */
1356 #endif /* QOS_MAP_SET */
1357 struct ether_addr last_roamed_addr;
1358 bool rcc_enabled; /* flag for Roam channel cache feature */
1359 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
1360 char bss_info[GET_BSS_INFO_LEN];
1361 wl_event_msg_t event_auth_assoc;
1362 u32 assoc_reject_status;
1363 u32 roam_count;
1364 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
1365 u16 ap_oper_channel;
1366 #if defined(SUPPORT_RANDOM_MAC_SCAN)
1367 bool random_mac_enabled;
1368 #endif /* SUPPORT_RANDOM_MAC_SCAN */
1369 #ifdef DHD_LOSSLESS_ROAMING
1370 timer_list_compat_t roam_timeout; /* Timer for catch roam timeout */
1371 #endif // endif
1372 #ifndef DUAL_ESCAN_RESULT_BUFFER
1373 uint16 escan_sync_id_cntr;
1374 #endif // endif
1375 #ifdef WLTDLS
1376 uint8 tdls_supported;
1377 struct mutex tdls_sync; /* protect tdls config operations */
1378 #endif /* WLTDLS */
1379 #ifdef MFP
1380 const uint8 *bip_pos;
1381 int mfp_mode;
1382 #endif /* MFP */
1383 #ifdef WES_SUPPORT
1384 #ifdef CUSTOMER_SCAN_TIMEOUT_SETTING
1385 int custom_scan_channel_time;
1386 int custom_scan_unassoc_time;
1387 int custom_scan_passive_time;
1388 int custom_scan_home_time;
1389 int custom_scan_home_away_time;
1390 #endif /* CUSTOMER_SCAN_TIMEOUT_SETTING */
1391 #endif /* WES_SUPPORT */
1392 uint8 vif_count; /* Virtual Interface count */
1393 #ifdef WBTEXT
1394 struct list_head wbtext_bssid_list;
1395 #endif /* WBTEXT */
1396 #ifdef SUPPORT_AP_RADIO_PWRSAVE
1397 ap_rps_info_t ap_rps_info;
1398 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
1399 u16 vif_macaddr_mask;
1400 osl_t *osh;
1401 struct list_head vndr_oui_list;
1402 spinlock_t vndr_oui_sync; /* to protect vndr_oui_list */
1403 bool rssi_sum_report;
1404 int rssi; /* previous RSSI (backup) of get_station */
1405 uint64 scan_enq_time;
1406 uint64 scan_deq_time;
1407 uint64 scan_hdlr_cmplt_time;
1408 uint64 scan_cmplt_time;
1409 uint64 wl_evt_deq_time;
1410 uint64 wl_evt_hdlr_entry_time;
1411 uint64 wl_evt_hdlr_exit_time;
1412 #ifdef WL_WPS_SYNC
1413 wl_wps_session_t wps_session[WPS_MAX_SESSIONS];
1414 spinlock_t wps_sync; /* to protect wps states (and others if needed) */
1415 #endif /* WL_WPS_SYNC */
1416 struct wl_fils_info fils_info;
1417 #ifdef WL_BAM
1418 wl_bad_ap_mngr_t bad_ap_mngr;
1419 #endif /* WL_BAM */
1420 #ifdef BIGDATA_SOFTAP
1421 struct wl_ap_sta_info *ap_sta_info;
1422 #endif /* BIGDATA_SOFTAP */
1423 uint8 scanmac_enabled;
1424 #ifdef WL_BCNRECV
1425 /* structure used for fake ap detection info */
1426 struct mutex bcn_sync; /* mainly for bcn resume/suspend synchronization */
1427 wl_bcnrecv_info_t bcnrecv_info;
1428 #endif /* WL_BCNRECV */
1429 struct net_device *static_ndev[DHD_MAX_STATIC_IFS];
1430 uint8 static_ndev_state[DHD_MAX_STATIC_IFS];
1431 bool hal_started;
1432 wl_wlc_version_t wlc_ver;
1433 bool scan_params_v2;
1434 #ifdef DHD_BANDSTEER
1435 void *dhd_bandsteer_cntx;
1436 bool p2p_bs;
1437 bool ap_bs;
1438 #endif /* DHD_BANDSTEER */
1439 #ifdef ENABLE_HOGSQS
1440 struct delayed_work hogsqs_eventwork; /* hog detection event work */
1441 #endif // endif
1442 #if !defined(DISABLE_11H) && defined(DHD_NOSCAN_DURING_CSA)
1443 bool in_csa;
1444 timer_list_compat_t csa_timeout; /* Timer for csa timeout */
1445 #endif // endif
1446 };
1447 #define WL_STATIC_IFIDX (DHD_MAX_IFS + DHD_MAX_STATIC_IFS - 1)
1448 enum static_ndev_states {
1449 NDEV_STATE_NONE,
1450 NDEV_STATE_OS_IF_CREATED,
1451 NDEV_STATE_FW_IF_CREATED,
1452 NDEV_STATE_FW_IF_FAILED,
1453 NDEV_STATE_FW_IF_DELETED
1454 };
1455 #ifdef WL_IFACE_MGMT
1456 #define IS_CFG80211_STATIC_IF_ACTIVE(cfg) \
1457 ((cfg && cfg->static_ndev && \
1458 (cfg->static_ndev_state & NDEV_STATE_FW_IF_CREATED)) ? true : false)
1459 #endif // endif
1460 #ifdef WL_SAE
1461 typedef struct wl_sae_key_info {
1462 uint8 peer_mac[ETHER_ADDR_LEN];
1463 uint16 pmk_len;
1464 uint16 pmkid_len;
1465 const uint8 *pmk;
1466 const uint8 *pmkid;
1467 } wl_sae_key_info_t;
1468 #endif /* WL_SAE */
1469
1470 typedef enum wl_concurrency_mode {
1471 CONCURRENCY_MODE_NONE = 0,
1472 CONCURRENCY_SCC_MODE,
1473 CONCURRENCY_VSDB_MODE,
1474 CONCURRENCY_RSDB_MODE
1475 } wl_concurrency_mode_t;
1476
1477 s32 wl_iftype_to_mode(wl_iftype_t iftype);
1478
1479 #define BCM_LIST_FOR_EACH_ENTRY_SAFE(pos, next, head, member) \
1480 list_for_each_entry_safe((pos), (next), (head), member)
1481 extern int ioctl_version;
1482
next_bss(struct wl_scan_results * list,wl_bss_info_t * bss)1483 static inline wl_bss_info_t *next_bss(struct wl_scan_results *list, wl_bss_info_t *bss)
1484 {
1485 return bss = bss ?
1486 (wl_bss_info_t *)((uintptr) bss + dtoh32(bss->length)) : list->bss_info;
1487 }
1488
1489 static inline void
wl_probe_wdev_all(struct bcm_cfg80211 * cfg)1490 wl_probe_wdev_all(struct bcm_cfg80211 *cfg)
1491 {
1492 struct net_info *_net_info, *next;
1493 unsigned long int flags;
1494 int idx = 0;
1495 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1496 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1497 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next,
1498 &cfg->net_list, list) {
1499 GCC_DIAGNOSTIC_POP();
1500 WL_INFORM_MEM(("wl_probe_wdev_all: net_list[%d] bssidx: %d\n",
1501 idx++, _net_info->bssidx));
1502 }
1503 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1504 return;
1505 }
1506
1507 static inline struct net_info *
wl_get_netinfo_by_fw_idx(struct bcm_cfg80211 * cfg,s32 bssidx,u8 ifidx)1508 wl_get_netinfo_by_fw_idx(struct bcm_cfg80211 *cfg, s32 bssidx, u8 ifidx)
1509 {
1510 struct net_info *_net_info, *next, *info = NULL;
1511 unsigned long int flags;
1512
1513 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1514 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1515 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1516 GCC_DIAGNOSTIC_POP();
1517 if ((bssidx >= 0) && (_net_info->bssidx == bssidx) &&
1518 (_net_info->ifidx == ifidx)) {
1519 info = _net_info;
1520 break;
1521 }
1522 }
1523 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1524 return info;
1525 }
1526
1527 static inline void
wl_dealloc_netinfo_by_wdev(struct bcm_cfg80211 * cfg,struct wireless_dev * wdev)1528 wl_dealloc_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev)
1529 {
1530 struct net_info *_net_info, *next;
1531 unsigned long int flags;
1532
1533 #ifdef DHD_IFDEBUG
1534 WL_INFORM_MEM(("dealloc_netinfo enter wdev=%p \n", OSL_OBFUSCATE_BUF(wdev)));
1535 #endif // endif
1536 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1537 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1538 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1539 GCC_DIAGNOSTIC_POP();
1540 if (wdev && (_net_info->wdev == wdev)) {
1541 wl_cfgbss_t *bss = &_net_info->bss;
1542
1543 if (bss->wpa_ie) {
1544 MFREE(cfg->osh, bss->wpa_ie, bss->wpa_ie[1]
1545 + WPA_RSN_IE_TAG_FIXED_LEN);
1546 bss->wpa_ie = NULL;
1547 }
1548
1549 if (bss->rsn_ie) {
1550 MFREE(cfg->osh, bss->rsn_ie,
1551 bss->rsn_ie[1] + WPA_RSN_IE_TAG_FIXED_LEN);
1552 bss->rsn_ie = NULL;
1553 }
1554
1555 if (bss->wps_ie) {
1556 MFREE(cfg->osh, bss->wps_ie, bss->wps_ie[1] + 2);
1557 bss->wps_ie = NULL;
1558 }
1559 list_del(&_net_info->list);
1560 cfg->iface_cnt--;
1561 MFREE(cfg->osh, _net_info, sizeof(struct net_info));
1562 }
1563 }
1564 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1565 #ifdef DHD_IFDEBUG
1566 WL_INFORM_MEM(("dealloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt));
1567 #endif // endif
1568 }
1569
1570 static inline s32
wl_alloc_netinfo(struct bcm_cfg80211 * cfg,struct net_device * ndev,struct wireless_dev * wdev,wl_iftype_t iftype,bool pm_block,u8 bssidx,u8 ifidx)1571 wl_alloc_netinfo(struct bcm_cfg80211 *cfg, struct net_device *ndev,
1572 struct wireless_dev * wdev, wl_iftype_t iftype, bool pm_block, u8 bssidx, u8 ifidx)
1573 {
1574 struct net_info *_net_info;
1575 s32 err = 0;
1576 unsigned long int flags;
1577 #ifdef DHD_IFDEBUG
1578 WL_INFORM_MEM(("alloc_netinfo enter bssidx=%d wdev=%p\n",
1579 bssidx, OSL_OBFUSCATE_BUF(wdev)));
1580 #endif // endif
1581 /* Check whether there is any duplicate entry for the
1582 * same bssidx && ifidx.
1583 */
1584 if ((_net_info = wl_get_netinfo_by_fw_idx(cfg, bssidx, ifidx))) {
1585 /* We have a duplicate entry for the same bssidx
1586 * already present which shouldn't have been the case.
1587 * Attempt recovery.
1588 */
1589 WL_ERR(("Duplicate entry for bssidx=%d ifidx=%d present."
1590 " Can't add new entry\n", bssidx, ifidx));
1591 wl_probe_wdev_all(cfg);
1592 #ifdef DHD_DEBUG
1593 ASSERT(0);
1594 #endif /* DHD_DEBUG */
1595 return -EINVAL;
1596 }
1597 if (cfg->iface_cnt == IFACE_MAX_CNT)
1598 return -ENOMEM;
1599 _net_info = (struct net_info *)MALLOCZ(cfg->osh, sizeof(struct net_info));
1600 if (!_net_info)
1601 err = -ENOMEM;
1602 else {
1603 _net_info->iftype = iftype;
1604 _net_info->ndev = ndev;
1605 _net_info->wdev = wdev;
1606 _net_info->pm_restore = 0;
1607 _net_info->pm = 0;
1608 _net_info->pm_block = pm_block;
1609 _net_info->roam_off = WL_INVALID;
1610 _net_info->bssidx = bssidx;
1611 _net_info->ifidx = ifidx;
1612 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1613 cfg->iface_cnt++;
1614 list_add(&_net_info->list, &cfg->net_list);
1615 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1616 #ifdef WL_SAE
1617 init_completion(&_net_info->mgmt_tx_cpl);
1618 #endif /* WL_SAE */
1619 }
1620 #ifdef DHD_IFDEBUG
1621 WL_DBG(("alloc_netinfo exit iface_cnt=%d \n", cfg->iface_cnt));
1622 #endif // endif
1623 return err;
1624 }
1625
1626 static inline void
wl_delete_all_netinfo(struct bcm_cfg80211 * cfg)1627 wl_delete_all_netinfo(struct bcm_cfg80211 *cfg)
1628 {
1629 struct net_info *_net_info, *next;
1630 unsigned long int flags;
1631
1632 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1633 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1634 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1635 wl_cfgbss_t *bss = &_net_info->bss;
1636 GCC_DIAGNOSTIC_POP();
1637
1638 if (bss->wpa_ie) {
1639 MFREE(cfg->osh, bss->wpa_ie, bss->wpa_ie[1]
1640 + WPA_RSN_IE_TAG_FIXED_LEN);
1641 bss->wpa_ie = NULL;
1642 }
1643
1644 if (bss->rsn_ie) {
1645 MFREE(cfg->osh, bss->rsn_ie, bss->rsn_ie[1]
1646 + WPA_RSN_IE_TAG_FIXED_LEN);
1647 bss->rsn_ie = NULL;
1648 }
1649
1650 if (bss->wps_ie) {
1651 MFREE(cfg->osh, bss->wps_ie, bss->wps_ie[1] + 2);
1652 bss->wps_ie = NULL;
1653 }
1654
1655 if (bss->fils_ind_ie) {
1656 MFREE(cfg->osh, bss->fils_ind_ie, bss->fils_ind_ie[1]
1657 + FILS_INDICATION_IE_TAG_FIXED_LEN);
1658 bss->fils_ind_ie = NULL;
1659 }
1660 list_del(&_net_info->list);
1661 if (_net_info->wdev) {
1662 MFREE(cfg->osh, _net_info->wdev, sizeof(struct wireless_dev));
1663 }
1664 MFREE(cfg->osh, _net_info, sizeof(struct net_info));
1665 }
1666 cfg->iface_cnt = 0;
1667 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1668 }
1669 static inline u32
wl_get_status_all(struct bcm_cfg80211 * cfg,s32 status)1670 wl_get_status_all(struct bcm_cfg80211 *cfg, s32 status)
1671
1672 {
1673 struct net_info *_net_info, *next;
1674 u32 cnt = 0;
1675 unsigned long int flags;
1676
1677 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1678 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1679 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1680 GCC_DIAGNOSTIC_POP();
1681 if (_net_info->ndev &&
1682 test_bit(status, &_net_info->sme_state))
1683 cnt++;
1684 }
1685 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1686 return cnt;
1687 }
1688 static inline void
wl_set_status_all(struct bcm_cfg80211 * cfg,s32 status,u32 op)1689 wl_set_status_all(struct bcm_cfg80211 *cfg, s32 status, u32 op)
1690 {
1691 struct net_info *_net_info, *next;
1692 unsigned long int flags;
1693
1694 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1695 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1696 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1697 GCC_DIAGNOSTIC_POP();
1698 switch (op) {
1699 case 1:
1700 break; /* set all status is not allowed */
1701 case 2:
1702 /*
1703 * Release the spinlock before calling notifier. Else there
1704 * will be nested calls
1705 */
1706 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1707 clear_bit(status, &_net_info->sme_state);
1708 if (cfg->state_notifier &&
1709 test_bit(status, &(cfg->interrested_state)))
1710 cfg->state_notifier(cfg, _net_info, status, false);
1711 return;
1712 case 4:
1713 break; /* change all status is not allowed */
1714 default:
1715 break; /* unknown operation */
1716 }
1717 }
1718 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1719 }
1720 static inline void
wl_set_status_by_netdev(struct bcm_cfg80211 * cfg,s32 status,struct net_device * ndev,u32 op)1721 wl_set_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status,
1722 struct net_device *ndev, u32 op)
1723 {
1724
1725 struct net_info *_net_info, *next;
1726 unsigned long int flags;
1727
1728 if (status >= BITS_PER_LONG) {
1729 /* max value for shift operation is
1730 * (BITS_PER_LONG -1) for unsigned long.
1731 * if status crosses BIT_PER_LONG, the variable
1732 * sme_state should be correspondingly updated.
1733 */
1734 ASSERT(0);
1735 return;
1736 }
1737
1738 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1739 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1740 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1741 if (ndev && (_net_info->ndev == ndev)) {
1742 GCC_DIAGNOSTIC_POP();
1743 switch (op) {
1744 case 1:
1745 /*
1746 * Release the spinlock before calling notifier. Else there
1747 * will be nested calls
1748 */
1749 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1750 set_bit(status, &_net_info->sme_state);
1751 if (cfg->state_notifier &&
1752 test_bit(status, &(cfg->interrested_state)))
1753 cfg->state_notifier(cfg, _net_info, status, true);
1754 return;
1755 case 2:
1756 /*
1757 * Release the spinlock before calling notifier. Else there
1758 * will be nested calls
1759 */
1760 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1761 clear_bit(status, &_net_info->sme_state);
1762 if (cfg->state_notifier &&
1763 test_bit(status, &(cfg->interrested_state)))
1764 cfg->state_notifier(cfg, _net_info, status, false);
1765 return;
1766 case 4:
1767 change_bit(status, &_net_info->sme_state);
1768 break;
1769 }
1770 }
1771
1772 }
1773 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1774
1775 }
1776
1777 static inline wl_cfgbss_t *
wl_get_cfgbss_by_wdev(struct bcm_cfg80211 * cfg,struct wireless_dev * wdev)1778 wl_get_cfgbss_by_wdev(struct bcm_cfg80211 *cfg,
1779 struct wireless_dev *wdev)
1780 {
1781 struct net_info *_net_info, *next;
1782 wl_cfgbss_t *bss = NULL;
1783 unsigned long int flags;
1784
1785 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1786 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1787 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1788 GCC_DIAGNOSTIC_POP();
1789 if (wdev && (_net_info->wdev == wdev)) {
1790 bss = &_net_info->bss;
1791 break;
1792 }
1793 }
1794
1795 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1796 return bss;
1797 }
1798
1799 static inline u32
wl_get_status_by_netdev(struct bcm_cfg80211 * cfg,s32 status,struct net_device * ndev)1800 wl_get_status_by_netdev(struct bcm_cfg80211 *cfg, s32 status,
1801 struct net_device *ndev)
1802 {
1803 struct net_info *_net_info, *next;
1804 u32 stat = 0;
1805 unsigned long int flags;
1806
1807 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1808 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1809 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1810 GCC_DIAGNOSTIC_POP();
1811 if (ndev && (_net_info->ndev == ndev)) {
1812 stat = test_bit(status, &_net_info->sme_state);
1813 break;
1814 }
1815 }
1816 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1817 return stat;
1818 }
1819
1820 static inline s32
wl_get_mode_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev)1821 wl_get_mode_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev)
1822 {
1823 struct net_info *_net_info, *next;
1824 s32 mode = -1;
1825 unsigned long int flags;
1826
1827 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1828 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1829 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1830 GCC_DIAGNOSTIC_POP();
1831 if (_net_info->ndev && (_net_info->ndev == ndev)) {
1832 mode = wl_iftype_to_mode(_net_info->iftype);
1833 break;
1834 }
1835 }
1836 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1837 return mode;
1838 }
1839
1840 static inline s32
wl_get_bssidx_by_wdev(struct bcm_cfg80211 * cfg,struct wireless_dev * wdev)1841 wl_get_bssidx_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev)
1842 {
1843 struct net_info *_net_info, *next;
1844 s32 bssidx = -1;
1845 unsigned long int flags;
1846
1847 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1848 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1849 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1850 GCC_DIAGNOSTIC_POP();
1851 if (_net_info->wdev && (_net_info->wdev == wdev)) {
1852 bssidx = _net_info->bssidx;
1853 break;
1854 }
1855 }
1856 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1857 return bssidx;
1858 }
1859
1860 static inline struct wireless_dev *
wl_get_wdev_by_fw_idx(struct bcm_cfg80211 * cfg,s32 bssidx,s32 ifidx)1861 wl_get_wdev_by_fw_idx(struct bcm_cfg80211 *cfg, s32 bssidx, s32 ifidx)
1862 {
1863 struct net_info *_net_info, *next;
1864 struct wireless_dev *wdev = NULL;
1865 unsigned long int flags;
1866
1867 if (bssidx < 0)
1868 return NULL;
1869 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1870 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1871 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1872 GCC_DIAGNOSTIC_POP();
1873 if ((_net_info->bssidx == bssidx) && (_net_info->ifidx == ifidx)) {
1874 wdev = _net_info->wdev;
1875 break;
1876 }
1877 }
1878 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1879 return wdev;
1880 }
1881
1882 static inline struct wl_profile *
wl_get_profile_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev)1883 wl_get_profile_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev)
1884 {
1885 struct net_info *_net_info, *next;
1886 struct wl_profile *prof = NULL;
1887 unsigned long int flags;
1888
1889 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1890 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1891 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1892 GCC_DIAGNOSTIC_POP();
1893 if (ndev && (_net_info->ndev == ndev)) {
1894 prof = &_net_info->profile;
1895 break;
1896 }
1897 }
1898 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1899 return prof;
1900 }
1901 static inline struct net_info *
wl_get_netinfo_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev)1902 wl_get_netinfo_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev)
1903 {
1904 struct net_info *_net_info, *next, *info = NULL;
1905 unsigned long int flags;
1906
1907 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1908 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1909 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1910 GCC_DIAGNOSTIC_POP();
1911 if (ndev && (_net_info->ndev == ndev)) {
1912 info = _net_info;
1913 break;
1914 }
1915 }
1916 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1917 return info;
1918 }
1919
1920 static inline struct net_info *
wl_get_netinfo_by_wdev(struct bcm_cfg80211 * cfg,struct wireless_dev * wdev)1921 wl_get_netinfo_by_wdev(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev)
1922 {
1923 struct net_info *_net_info, *next, *info = NULL;
1924 unsigned long int flags;
1925
1926 WL_CFG_NET_LIST_SYNC_LOCK(&cfg->net_list_sync, flags);
1927 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1928 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1929 GCC_DIAGNOSTIC_POP();
1930 if (wdev && (_net_info->wdev == wdev)) {
1931 info = _net_info;
1932 break;
1933 }
1934 }
1935 WL_CFG_NET_LIST_SYNC_UNLOCK(&cfg->net_list_sync, flags);
1936 return info;
1937 }
1938
1939 static inline u32
wl_get_chanwidth_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev)1940 wl_get_chanwidth_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev)
1941 {
1942 struct net_info *_net_info, *next;
1943 unsigned long int flags;
1944 u32 info = 0;
1945 spin_lock_irqsave(&cfg->net_list_sync, flags);
1946 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1947 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1948 GCC_DIAGNOSTIC_POP();
1949 if (ndev && (_net_info->ndev == ndev)) {
1950 info = _net_info->profile.channel_width;
1951 break;
1952 }
1953 }
1954 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
1955 return info;
1956 }
1957
1958 static inline void
wl_set_chanwidth_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev,u32 chanwidth)1959 wl_set_chanwidth_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, u32 chanwidth)
1960 {
1961 struct net_info *_net_info, *next;
1962 unsigned long int flags;
1963 spin_lock_irqsave(&cfg->net_list_sync, flags);
1964 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1965 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1966 GCC_DIAGNOSTIC_POP();
1967 if (ndev && (_net_info->ndev == ndev))
1968 _net_info->profile.channel_width = chanwidth;
1969 }
1970 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
1971 }
1972
1973 static inline struct wireless_dev *
wl_get_wdev_by_dpp_listen(struct bcm_cfg80211 * cfg)1974 wl_get_wdev_by_dpp_listen(struct bcm_cfg80211 *cfg)
1975 {
1976 struct wireless_dev *wdev = NULL;
1977 struct net_info *_net_info, *next;
1978 unsigned long int flags;
1979 spin_lock_irqsave(&cfg->net_list_sync, flags);
1980 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1981 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
1982 GCC_DIAGNOSTIC_POP();
1983 if (_net_info->profile.dpp_listen) {
1984 wdev = _net_info->wdev;
1985 break;
1986 }
1987 }
1988 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
1989 return wdev;
1990 }
1991
1992 static inline void
wl_set_dpp_listen_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev,bool dpp_listen)1993 wl_set_dpp_listen_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, bool dpp_listen)
1994 {
1995 struct net_info *_net_info, *next;
1996 unsigned long int flags;
1997 spin_lock_irqsave(&cfg->net_list_sync, flags);
1998 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
1999 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
2000 GCC_DIAGNOSTIC_POP();
2001 if (ndev && (_net_info->ndev == ndev))
2002 _net_info->profile.dpp_listen = dpp_listen;
2003 }
2004 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
2005 }
2006
2007 static inline char *
wl_iftype_to_str(int wl_iftype)2008 wl_iftype_to_str(int wl_iftype)
2009 {
2010 switch (wl_iftype) {
2011 case (WL_IF_TYPE_STA):
2012 return "WL_IF_TYPE_STA";
2013 case (WL_IF_TYPE_AP):
2014 return "WL_IF_TYPE_AP";
2015 case (WL_IF_TYPE_AWDL):
2016 return "WL_IF_TYPE_AWDL";
2017 case (WL_IF_TYPE_NAN_NMI):
2018 return "WL_IF_TYPE_NAN_NMI";
2019 case (WL_IF_TYPE_NAN):
2020 return "WL_IF_TYPE_NAN";
2021 case (WL_IF_TYPE_P2P_GO):
2022 return "WL_IF_TYPE_P2P_GO";
2023 case (WL_IF_TYPE_P2P_GC):
2024 return "WL_IF_TYPE_P2P_GC";
2025 case (WL_IF_TYPE_P2P_DISC):
2026 return "WL_IF_TYPE_P2P_DISC";
2027 case (WL_IF_TYPE_IBSS):
2028 return "WL_IF_TYPE_IBSS";
2029 case (WL_IF_TYPE_MONITOR):
2030 return "WL_IF_TYPE_MONITOR";
2031 case (WL_IF_TYPE_AIBSS):
2032 return "WL_IF_TYPE_AIBSS";
2033 default:
2034 return "WL_IF_TYPE_UNKNOWN";
2035 }
2036 }
2037
2038 #define is_discovery_iface(iface) (((iface == WL_IF_TYPE_P2P_DISC) || \
2039 (iface == WL_IF_TYPE_NAN_NMI)) ? 1 : 0)
2040 #define is_p2p_group_iface(wdev) (((wdev->iftype == NL80211_IFTYPE_P2P_GO) || \
2041 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)) ? 1 : 0)
2042 #define bcmcfg_to_wiphy(cfg) (cfg->wdev->wiphy)
2043 #define bcmcfg_to_prmry_ndev(cfg) (cfg->wdev->netdev)
2044 #define bcmcfg_to_prmry_wdev(cfg) (cfg->wdev)
2045 #define bcmcfg_to_p2p_wdev(cfg) (cfg->p2p_wdev)
2046 #define ndev_to_wl(n) (wdev_to_wl(n->ieee80211_ptr))
2047 #define ndev_to_wdev(ndev) (ndev->ieee80211_ptr)
2048 #define wdev_to_ndev(wdev) (wdev->netdev)
2049
2050 #ifdef WL_BLOCK_P2P_SCAN_ON_STA
2051 #define IS_P2P_IFACE(wdev) (wdev && \
2052 ((wdev->iftype == NL80211_IFTYPE_P2P_DEVICE) || \
2053 (wdev->iftype == NL80211_IFTYPE_P2P_GO) || \
2054 (wdev->iftype == NL80211_IFTYPE_P2P_CLIENT)))
2055 #endif /* WL_BLOCK_P2P_SCAN_ON_STA */
2056
2057 #define IS_STA_IFACE(wdev) (wdev && \
2058 (wdev->iftype == NL80211_IFTYPE_STATION))
2059
2060 #define IS_AP_IFACE(wdev) (wdev && \
2061 (wdev->iftype == NL80211_IFTYPE_AP))
2062
2063 #if defined(WL_ENABLE_P2P_IF)
2064 #define ndev_to_wlc_ndev(ndev, cfg) ((ndev == cfg->p2p_net) ? \
2065 bcmcfg_to_prmry_ndev(cfg) : ndev)
2066 #else
2067 #define ndev_to_wlc_ndev(ndev, cfg) (ndev)
2068 #endif /* WL_ENABLE_P2P_IF */
2069
2070 #define wdev_to_wlc_ndev(wdev, cfg) \
2071 (wdev_to_ndev(wdev) ? \
2072 wdev_to_ndev(wdev) : bcmcfg_to_prmry_ndev(cfg))
2073 #if defined(WL_CFG80211_P2P_DEV_IF)
2074 #define cfgdev_to_wlc_ndev(cfgdev, cfg) wdev_to_wlc_ndev(cfgdev, cfg)
2075 #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_wdev(cfg)
2076 #elif defined(WL_ENABLE_P2P_IF)
2077 #define cfgdev_to_wlc_ndev(cfgdev, cfg) ndev_to_wlc_ndev(cfgdev, cfg)
2078 #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) bcmcfg_to_prmry_ndev(cfg)
2079 #else
2080 #define cfgdev_to_wlc_ndev(cfgdev, cfg) (cfgdev)
2081 #define bcmcfg_to_prmry_cfgdev(cfgdev, cfg) (cfgdev)
2082 #endif /* WL_CFG80211_P2P_DEV_IF */
2083
2084 #if defined(WL_CFG80211_P2P_DEV_IF)
2085 #define cfgdev_to_wdev(cfgdev) (cfgdev)
2086 #define ndev_to_cfgdev(ndev) ndev_to_wdev(ndev)
2087 #define cfgdev_to_ndev(cfgdev) (cfgdev ? (cfgdev->netdev) : NULL)
2088 #define wdev_to_cfgdev(cfgdev) (cfgdev)
2089 #define discover_cfgdev(cfgdev, cfg) (cfgdev->iftype == NL80211_IFTYPE_P2P_DEVICE)
2090 #else
2091 #define cfgdev_to_wdev(cfgdev) (cfgdev->ieee80211_ptr)
2092 #define wdev_to_cfgdev(cfgdev) cfgdev ? (cfgdev->netdev) : NULL
2093 #define ndev_to_cfgdev(ndev) (ndev)
2094 #define cfgdev_to_ndev(cfgdev) (cfgdev)
2095 #define discover_cfgdev(cfgdev, cfg) (cfgdev == cfg->p2p_net)
2096 #endif /* WL_CFG80211_P2P_DEV_IF */
2097
2098 #if defined(WL_CFG80211_P2P_DEV_IF)
2099 #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \
2100 (cfg->scan_request->wdev == cfg->p2p_wdev)) ? true : false)
2101 #elif defined(WL_ENABLE_P2P_IF)
2102 #define scan_req_match(cfg) (((cfg) && (cfg->scan_request) && \
2103 (cfg->scan_request->dev == cfg->p2p_net)) ? true : false)
2104 #else
2105 #define scan_req_match(cfg) (((cfg) && p2p_is_on(cfg) && p2p_scan(cfg)) ? \
2106 true : false)
2107 #endif /* WL_CFG80211_P2P_DEV_IF */
2108
2109 #define PRINT_WDEV_INFO(cfgdev) \
2110 { \
2111 struct wireless_dev *wdev = cfgdev_to_wdev(cfgdev); \
2112 struct net_device *netdev = wdev ? wdev->netdev : NULL; \
2113 WL_DBG(("wdev_ptr:%p ndev_ptr:%p ifname:%s iftype:%d\n", OSL_OBFUSCATE_BUF(wdev), \
2114 OSL_OBFUSCATE_BUF(netdev), \
2115 netdev ? netdev->name : "NULL (non-ndev device)", \
2116 wdev ? wdev->iftype : 0xff)); \
2117 }
2118
2119 #if (LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0))
2120 #define scan_req_iftype(req) (req->dev->ieee80211_ptr->iftype)
2121 #else
2122 #define scan_req_iftype(req) (req->wdev->iftype)
2123 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 6, 0) */
2124
2125 #define wl_to_sr(w) (w->scan_req_int)
2126 #if defined(STATIC_WL_PRIV_STRUCT)
2127 #define wl_to_ie(w) (w->ie)
2128 #define wl_to_conn(w) (w->conn_info)
2129 #else
2130 #define wl_to_ie(w) (&w->ie)
2131 #define wl_to_conn(w) (&w->conn_info)
2132 #endif // endif
2133 #define wl_to_fils_info(w) (&w->fils_info)
2134 #define wiphy_from_scan(w) (w->escan_info.wiphy)
2135 #define wl_get_drv_status_all(cfg, stat) \
2136 (wl_get_status_all(cfg, WL_STATUS_ ## stat))
2137 #define wl_get_drv_status(cfg, stat, ndev) \
2138 (wl_get_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev))
2139 #define wl_set_drv_status(cfg, stat, ndev) \
2140 (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 1))
2141 #define wl_clr_drv_status(cfg, stat, ndev) \
2142 (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 2))
2143 #define wl_clr_drv_status_all(cfg, stat) \
2144 (wl_set_status_all(cfg, WL_STATUS_ ## stat, 2))
2145 #define wl_chg_drv_status(cfg, stat, ndev) \
2146 (wl_set_status_by_netdev(cfg, WL_STATUS_ ## stat, ndev, 4))
2147
2148 #define for_each_bss(list, bss, __i) \
2149 for (__i = 0; __i < list->count && __i < WL_AP_MAX; __i++, bss = next_bss(list, bss))
2150
2151 #define for_each_ndev(cfg, iter, next) \
2152 list_for_each_entry_safe(iter, next, &cfg->net_list, list)
2153
2154 /* In case of WPS from wpa_supplicant, pairwise siute and group suite is 0.
2155 * In addtion to that, wpa_version is WPA_VERSION_1
2156 */
2157 #define is_wps_conn(_sme) \
2158 ((wl_cfgp2p_find_wpsie(_sme->ie, _sme->ie_len) != NULL) && \
2159 (!_sme->crypto.n_ciphers_pairwise) && \
2160 (!_sme->crypto.cipher_group))
2161
2162 #ifdef WLFBT
2163 #if defined(WLAN_AKM_SUITE_FT_8021X) && defined(WLAN_AKM_SUITE_FT_PSK)
2164 #define IS_AKM_SUITE_FT(sec) (sec->wpa_auth == WLAN_AKM_SUITE_FT_8021X || \
2165 sec->wpa_auth == WLAN_AKM_SUITE_FT_PSK)
2166 #elif defined(WLAN_AKM_SUITE_FT_8021X)
2167 #define IS_AKM_SUITE_FT(sec) (sec->wpa_auth == WLAN_AKM_SUITE_FT_8021X)
2168 #elif defined(WLAN_AKM_SUITE_FT_PSK)
2169 #define IS_AKM_SUITE_FT(sec) (sec->wpa_auth == WLAN_AKM_SUITE_FT_PSK)
2170 #else
2171 #define IS_AKM_SUITE_FT(sec) ({BCM_REFERENCE(sec); FALSE;})
2172 #endif /* WLAN_AKM_SUITE_FT_8021X && WLAN_AKM_SUITE_FT_PSK */
2173 #else
2174 #define IS_AKM_SUITE_FT(sec) ({BCM_REFERENCE(sec); FALSE;})
2175 #endif /* WLFBT */
2176
2177 #define IS_AKM_SUITE_CCKM(sec) ({BCM_REFERENCE(sec); FALSE;})
2178
2179 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0))
2180 #define STA_INFO_BIT(info) (1ul << NL80211_STA_ ## info)
2181 #ifdef strnicmp
2182 #undef strnicmp
2183 #endif /* strnicmp */
2184 #define strnicmp(str1, str2, len) strncasecmp((str1), (str2), (len))
2185 #else
2186 #define STA_INFO_BIT(info) (STATION_ ## info)
2187 #endif /* (LINUX_VERSION_CODE >= KERNEL_VERSION(4, 0, 0)) */
2188
2189 extern s32 wl_cfg80211_attach(struct net_device *ndev, void *context);
2190 extern void wl_cfg80211_detach(struct bcm_cfg80211 *cfg);
2191
2192 extern void wl_cfg80211_event(struct net_device *ndev, const wl_event_msg_t *e,
2193 void *data);
2194 extern s32 wl_cfg80211_handle_critical_events(struct bcm_cfg80211 *cfg,
2195 const wl_event_msg_t * e);
2196
2197 void wl_cfg80211_set_parent_dev(void *dev);
2198 struct device *wl_cfg80211_get_parent_dev(void);
2199 struct bcm_cfg80211 *wl_cfg80211_get_bcmcfg(void);
2200 void wl_cfg80211_set_bcmcfg(struct bcm_cfg80211 *cfg);
2201
2202 /* clear IEs */
2203 extern s32 wl_cfg80211_clear_mgmt_vndr_ies(struct bcm_cfg80211 *cfg);
2204 extern s32 wl_cfg80211_clear_per_bss_ies(struct bcm_cfg80211 *cfg, struct wireless_dev *wdev);
2205 extern void wl_cfg80211_clear_p2p_disc_ies(struct bcm_cfg80211 *cfg);
2206 #ifdef WL_STATIC_IF
2207 extern int32 wl_cfg80211_update_iflist_info(struct bcm_cfg80211 *cfg, struct net_device *ndev,
2208 int ifidx, uint8 *addr, int bssidx, char *name, int if_state);
2209 extern int get_iface_num(const char *name, struct bcm_cfg80211 *cfg);
2210 extern bool is_static_iface(struct bcm_cfg80211 *cfg, struct net_device *net);
2211 extern int static_if_ndev_get_state(struct bcm_cfg80211 *cfg, struct net_device *net);
2212 extern bool is_static_iface_name(const char *name, struct bcm_cfg80211 *cfg);
2213 #endif /* WL_STATIC_IF */
2214 extern s32 wl_cfg80211_up(struct net_device *net);
2215 extern s32 wl_cfg80211_down(struct net_device *net);
2216 extern void wl_cfg80211_sta_ifdown(struct net_device *net);
2217 extern s32 wl_cfg80211_notify_ifadd(struct net_device * dev, int ifidx, char *name, uint8 *mac,
2218 uint8 bssidx, uint8 role);
2219 extern s32 wl_cfg80211_notify_ifdel(struct net_device * dev, int ifidx, char *name, uint8 *mac,
2220 uint8 bssidx);
2221 extern s32 wl_cfg80211_notify_ifchange(struct net_device * dev, int ifidx, char *name, uint8 *mac,
2222 uint8 bssidx);
2223 extern struct net_device* wl_cfg80211_allocate_if(struct bcm_cfg80211 *cfg, int ifidx,
2224 const char *name, uint8 *mac, uint8 bssidx, const char *dngl_name);
2225 extern int wl_cfg80211_register_if(struct bcm_cfg80211 *cfg,
2226 int ifidx, struct net_device* ndev, bool rtnl_lock_reqd);
2227 extern int wl_cfg80211_remove_if(struct bcm_cfg80211 *cfg,
2228 int ifidx, struct net_device* ndev, bool rtnl_lock_reqd);
2229 extern void wl_cfg80211_cleanup_if(struct net_device *dev);
2230 extern bool wl_cfg80211_is_concurrent_mode(struct net_device * dev);
2231 extern void wl_cfg80211_disassoc(struct net_device *ndev, uint32 reason);
2232 extern void wl_cfg80211_del_all_sta(struct net_device *ndev, uint32 reason);
2233 extern void* wl_cfg80211_get_dhdp(struct net_device * dev);
2234 extern bool wl_cfg80211_is_p2p_active(struct net_device * dev);
2235 extern bool wl_cfg80211_is_roam_offload(struct net_device * dev);
2236 extern bool wl_cfg80211_is_event_from_connected_bssid(struct net_device * dev,
2237 const wl_event_msg_t *e, int ifidx);
2238 extern void wl_cfg80211_dbg_level(u32 level);
2239 extern s32 wl_cfg80211_get_p2p_dev_addr(struct net_device *net, struct ether_addr *p2pdev_addr);
2240 extern s32 wl_cfg80211_set_p2p_noa(struct net_device *net, char* buf, int len);
2241 extern s32 wl_cfg80211_get_p2p_noa(struct net_device *net, char* buf, int len);
2242 extern s32 wl_cfg80211_set_wps_p2p_ie(struct net_device *net, char *buf, int len,
2243 enum wl_management_type type);
2244 extern s32 wl_cfg80211_set_p2p_ps(struct net_device *net, char* buf, int len);
2245 extern s32 wl_cfg80211_set_p2p_ecsa(struct net_device *net, char* buf, int len);
2246 extern s32 wl_cfg80211_increase_p2p_bw(struct net_device *net, char* buf, int len);
2247 extern bool wl_cfg80211_check_vif_in_use(struct net_device *ndev);
2248 #ifdef P2PLISTEN_AP_SAMECHN
2249 extern s32 wl_cfg80211_set_p2p_resp_ap_chn(struct net_device *net, s32 enable);
2250 #endif /* P2PLISTEN_AP_SAMECHN */
2251
2252 /* btcoex functions */
2253 void* wl_cfg80211_btcoex_init(struct net_device *ndev);
2254 void wl_cfg80211_btcoex_deinit(void);
2255
2256 extern chanspec_t wl_chspec_from_legacy(chanspec_t legacy_chspec);
2257 extern chanspec_t wl_chspec_driver_to_host(chanspec_t chanspec);
2258
2259 #ifdef WL_SUPPORT_AUTO_CHANNEL
2260 #define CHANSPEC_BUF_SIZE 1024
2261 #define CHAN_SEL_IOCTL_DELAY 300
2262 #define CHAN_SEL_RETRY_COUNT 15
2263 #define CHANNEL_IS_RADAR(channel) (((channel & WL_CHAN_RADAR) || \
2264 (channel & WL_CHAN_PASSIVE)) ? true : false)
2265 #define CHANNEL_IS_2G(channel) (((channel >= 1) && (channel <= 14)) ? \
2266 true : false)
2267 #define CHANNEL_IS_5G(channel) (((channel >= 36) && (channel <= 165)) ? \
2268 true : false)
2269 extern s32 wl_cfg80211_get_best_channels(struct net_device *dev, char* command,
2270 int total_len);
2271 #endif /* WL_SUPPORT_AUTO_CHANNEL */
2272 extern int wl_cfg80211_ether_atoe(const char *a, struct ether_addr *n);
2273 extern int wl_cfg80211_hang(struct net_device *dev, u16 reason);
2274 extern s32 wl_mode_to_nl80211_iftype(s32 mode);
2275 int wl_cfg80211_do_driver_init(struct net_device *net);
2276 void wl_cfg80211_enable_trace(bool set, u32 level);
2277 extern s32 wl_update_wiphybands(struct bcm_cfg80211 *cfg, bool notify);
2278 extern s32 wl_cfg80211_if_is_group_owner(void);
2279 extern chanspec_t wl_chspec_host_to_driver(chanspec_t chanspec);
2280 extern chanspec_t wl_ch_host_to_driver(u16 channel);
2281 extern s32 wl_set_tx_power(struct net_device *dev,
2282 enum nl80211_tx_power_setting type, s32 dbm);
2283 extern s32 wl_get_tx_power(struct net_device *dev, s32 *dbm);
2284 extern s32 wl_add_remove_eventmsg(struct net_device *ndev, u16 event, bool add);
2285 extern s32 wl_add_remove_eventextmsg(struct net_device *ndev, u16 event, bool add);
2286 extern void wl_stop_wait_next_action_frame(struct bcm_cfg80211 *cfg, struct net_device *ndev,
2287 u8 bsscfgidx);
2288 #ifdef WL_HOST_BAND_MGMT
2289 extern s32 wl_cfg80211_set_band(struct net_device *ndev, int band);
2290 #endif /* WL_HOST_BAND_MGMT */
2291 extern void wl_cfg80211_add_to_eventbuffer(wl_eventmsg_buf_t *ev, u16 event, bool set);
2292 extern s32 wl_cfg80211_apply_eventbuffer(struct net_device *ndev,
2293 struct bcm_cfg80211 *cfg, wl_eventmsg_buf_t *ev);
2294 extern void get_primary_mac(struct bcm_cfg80211 *cfg, struct ether_addr *mac);
2295 extern void wl_cfg80211_update_power_mode(struct net_device *dev);
2296 extern void wl_terminate_event_handler(struct net_device *dev);
2297 #if defined(DHD_ENABLE_BIGDATA_LOGGING)
2298 extern s32 wl_cfg80211_get_bss_info(struct net_device *dev, char* cmd, int total_len);
2299 extern s32 wl_cfg80211_get_connect_failed_status(struct net_device *dev, char* cmd, int total_len);
2300 #endif /* DHD_ENABLE_BIGDATA_LOGGING */
2301 extern struct bcm_cfg80211 *wl_get_cfg(struct net_device *ndev);
2302 extern s32 wl_cfg80211_set_if_band(struct net_device *ndev, int band);
2303 extern s32 wl_cfg80211_set_country_code(struct net_device *dev, char *country_code,
2304 bool notify, bool user_enforced, int revinfo);
2305 extern bool wl_cfg80211_is_hal_started(struct bcm_cfg80211 *cfg);
2306 #ifdef WL_WIPSEVT
2307 extern int wl_cfg80211_wips_event(uint16 misdeauth, char* bssid);
2308 #endif /* WL_WIPSEVT */
2309
2310 #define SCAN_BUF_CNT 2
2311 #define SCAN_BUF_NEXT 1
2312 #define WL_SCANTYPE_LEGACY 0x1
2313 #define WL_SCANTYPE_P2P 0x2
2314 #ifdef DUAL_ESCAN_RESULT_BUFFER
2315 #define wl_escan_set_sync_id(a, b) ((a) = (b)->escan_info.cur_sync_id)
2316 #define wl_escan_set_type(a, b) ((a)->escan_info.escan_type\
2317 [((a)->escan_info.cur_sync_id)%SCAN_BUF_CNT] = (b))
wl_escan_get_buf(struct bcm_cfg80211 * cfg,bool aborted)2318 static inline wl_scan_results_t *wl_escan_get_buf(struct bcm_cfg80211 *cfg, bool aborted)
2319 {
2320 u8 index;
2321 if (aborted) {
2322 if (cfg->escan_info.escan_type[0] == cfg->escan_info.escan_type[1])
2323 index = (cfg->escan_info.cur_sync_id + 1)%SCAN_BUF_CNT;
2324 else
2325 index = (cfg->escan_info.cur_sync_id)%SCAN_BUF_CNT;
2326 }
2327 else
2328 index = (cfg->escan_info.cur_sync_id)%SCAN_BUF_CNT;
2329
2330 return (wl_scan_results_t *)cfg->escan_info.escan_buf[index];
2331 }
wl_escan_check_sync_id(s32 status,u16 result_id,u16 wl_id)2332 static inline int wl_escan_check_sync_id(s32 status, u16 result_id, u16 wl_id)
2333 {
2334 if (result_id != wl_id) {
2335 WL_ERR(("ESCAN sync id mismatch :status :%d "
2336 "cur_sync_id:%d coming sync_id:%d\n",
2337 status, wl_id, result_id));
2338 return -1;
2339 }
2340 else
2341 return 0;
2342 }
wl_escan_print_sync_id(s32 status,u16 result_id,u16 wl_id)2343 static inline void wl_escan_print_sync_id(s32 status, u16 result_id, u16 wl_id)
2344 {
2345 if (result_id != wl_id) {
2346 WL_ERR(("ESCAN sync id mismatch :status :%d "
2347 "cur_sync_id:%d coming sync_id:%d\n",
2348 status, wl_id, result_id));
2349 }
2350 }
2351 #define wl_escan_increment_sync_id(a, b) ((a)->escan_info.cur_sync_id += b)
2352 #define wl_escan_init_sync_id(a) ((a)->escan_info.cur_sync_id = 0)
2353 #else
2354 #define wl_escan_set_sync_id(a, b) ((a) = htod16((b)->escan_sync_id_cntr++))
2355 #define wl_escan_set_type(a, b)
2356 #define wl_escan_get_buf(a, b) ((wl_scan_results_t *) (a)->escan_info.escan_buf)
2357 #define wl_escan_check_sync_id(a, b, c) 0
2358 #define wl_escan_print_sync_id(a, b, c)
2359 #define wl_escan_increment_sync_id(a, b)
2360 #define wl_escan_init_sync_id(a)
2361 #endif /* DUAL_ESCAN_RESULT_BUFFER */
2362 extern void wl_cfg80211_ibss_vsie_set_buffer(struct net_device *dev, vndr_ie_setbuf_t *ibss_vsie,
2363 int ibss_vsie_len);
2364 extern s32 wl_cfg80211_ibss_vsie_delete(struct net_device *dev);
2365 #ifdef WLAIBSS
2366 extern void wl_cfg80211_set_txfail_pid(struct net_device *dev, int pid);
2367 #endif /* WLAIBSS */
2368 #ifdef WL_RELMCAST
2369 extern void wl_cfg80211_set_rmc_pid(struct net_device *dev, int pid);
2370 #endif /* WL_RELMCAST */
2371 extern int wl_cfg80211_set_mgmt_vndr_ies(struct bcm_cfg80211 *cfg,
2372 bcm_struct_cfgdev *cfgdev, s32 bssidx, s32 pktflag,
2373 const u8 *vndr_ie, u32 vndr_ie_len);
2374
2375 #ifdef WLFBT
2376 extern int wl_cfg80211_get_fbt_key(struct net_device *dev, uint8 *key, int total_len);
2377 #endif // endif
2378
2379 /* Action frame specific functions */
2380 extern u8 wl_get_action_category(void *frame, u32 frame_len);
2381 extern int wl_get_public_action(void *frame, u32 frame_len, u8 *ret_action);
2382
2383 #ifdef WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST
2384 struct net_device *wl_cfg80211_get_remain_on_channel_ndev(struct bcm_cfg80211 *cfg);
2385 #endif /* WL_CFG80211_VSDB_PRIORITIZE_SCAN_REQUEST */
2386
2387 #ifdef WL_SUPPORT_ACS
2388 #define ACS_MSRMNT_DELAY 1000 /* dump_obss delay in ms */
2389 #define IOCTL_RETRY_COUNT 5
2390 #define CHAN_NOISE_DUMMY -80
2391 #define OBSS_TOKEN_IDX 15
2392 #define IBSS_TOKEN_IDX 15
2393 #define TX_TOKEN_IDX 14
2394 #define CTG_TOKEN_IDX 13
2395 #define PKT_TOKEN_IDX 15
2396 #define IDLE_TOKEN_IDX 12
2397 #endif /* WL_SUPPORT_ACS */
2398
2399 #ifdef BCMWAPI_WPI
2400 #define is_wapi(cipher) (cipher == WLAN_CIPHER_SUITE_SMS4) ? 1 : 0
2401 #endif /* BCMWAPI_WPI */
2402
2403 extern int wl_cfg80211_get_ioctl_version(void);
2404 extern int wl_cfg80211_enable_roam_offload(struct net_device *dev, int enable);
2405 extern s32 wl_cfg80211_dfs_ap_move(struct net_device *ndev, char *data,
2406 char *command, int total_len);
2407 #ifdef WBTEXT
2408 extern s32 wl_cfg80211_wbtext_set_default(struct net_device *ndev);
2409 extern s32 wl_cfg80211_wbtext_config(struct net_device *ndev, char *data,
2410 char *command, int total_len);
2411 extern int wl_cfg80211_wbtext_weight_config(struct net_device *ndev, char *data,
2412 char *command, int total_len);
2413 extern int wl_cfg80211_wbtext_table_config(struct net_device *ndev, char *data,
2414 char *command, int total_len);
2415 extern s32 wl_cfg80211_wbtext_delta_config(struct net_device *ndev, char *data,
2416 char *command, int total_len);
2417 #endif /* WBTEXT */
2418 extern s32 wl_cfg80211_get_chanspecs_2g(struct net_device *ndev,
2419 void *buf, s32 buflen);
2420 extern s32 wl_cfg80211_get_chanspecs_5g(struct net_device *ndev,
2421 void *buf, s32 buflen);
2422
2423 #if defined(SAVE_CONNECTION_WHEN_CC_UPDATE)
2424 extern bool wl_update_ap_chandef(struct net_device *ndev);
2425 extern bool wl_check_valid_channel_in_country(struct net_device *ndev, char *ccode, int forced);
2426 #endif // endif
2427
2428 extern s32 wl_cfg80211_bss_up(struct bcm_cfg80211 *cfg,
2429 struct net_device *ndev, s32 bsscfg_idx, s32 up);
2430 extern bool wl_cfg80211_bss_isup(struct net_device *ndev, int bsscfg_idx);
2431
2432 struct net_device *wl_cfg80211_post_ifcreate(struct net_device *ndev,
2433 wl_if_event_info *event, u8 *addr, const char *name, bool rtnl_lock_reqd);
2434 extern s32 wl_cfg80211_post_ifdel(struct net_device *ndev, bool rtnl_lock_reqd, s32 ifidx);
2435 #if defined(PKT_FILTER_SUPPORT) && defined(APSTA_BLOCK_ARP_DURING_DHCP)
2436 extern void wl_cfg80211_block_arp(struct net_device *dev, int enable);
2437 #endif /* PKT_FILTER_SUPPORT && APSTA_BLOCK_ARP_DURING_DHCP */
2438
2439 #ifdef WLTDLS
2440 extern s32 wl_cfg80211_tdls_config(struct bcm_cfg80211 *cfg,
2441 enum wl_tdls_config state, bool tdls_mode);
2442 extern s32 wl_tdls_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
2443 const wl_event_msg_t *e, void *data);
2444 #endif /* WLTDLS */
2445
2446 #ifdef WL_NAN
2447 extern int wl_cfgvendor_send_nan_event(struct wiphy * wiphy,
2448 struct net_device *dev, int event_id,
2449 nan_event_data_t *nan_event_data);
2450 extern int wl_cfgnan_init(struct bcm_cfg80211 *cfg);
2451 extern int wl_cfgnan_deinit(struct bcm_cfg80211 *cfg, uint8 busstate);
2452 extern bool wl_cfgnan_check_state(struct bcm_cfg80211 *cfg);
2453 #ifdef RTT_SUPPORT
2454 extern s32 wl_cfgvendor_send_as_rtt_legacy_event(struct wiphy *wiphy,
2455 struct net_device *dev, wl_nan_ev_rng_rpt_ind_t *range_res,
2456 uint32 status);
2457 #endif /* RTT_SUPPORT */
2458 #ifdef WL_NANP2P
2459 extern int wl_cfg80211_set_iface_conc_disc(struct net_device *ndev,
2460 uint8 arg_val);
2461 extern uint8 wl_cfg80211_get_iface_conc_disc(struct net_device *ndev);
2462 #endif /* WL_NANP2P */
2463 #endif /* WL_NAN */
2464
2465 #ifdef WL_CFG80211_P2P_DEV_IF
2466 extern void wl_cfg80211_del_p2p_wdev(struct net_device *dev);
2467 #endif /* WL_CFG80211_P2P_DEV_IF */
2468 #if defined(WL_SUPPORT_AUTO_CHANNEL)
2469 extern int wl_cfg80211_set_spect(struct net_device *dev, int spect);
2470 extern int wl_cfg80211_get_sta_channel(struct bcm_cfg80211 *cfg);
2471 #endif /* WL_SUPPORT_AUTO_CHANNEL */
2472 #ifdef WL_CFG80211_SYNC_GON
2473 #define WL_DRV_STATUS_SENDING_AF_FRM_EXT(cfg) \
2474 (wl_get_drv_status_all(cfg, SENDING_ACT_FRM) || \
2475 wl_get_drv_status_all(cfg, WAITING_NEXT_ACT_FRM_LISTEN))
2476 #else
2477 #define WL_DRV_STATUS_SENDING_AF_FRM_EXT(cfg) wl_get_drv_status_all(cfg, SENDING_ACT_FRM)
2478 #endif /* WL_CFG80211_SYNC_GON */
2479
2480 #ifdef P2P_LISTEN_OFFLOADING
2481 extern s32 wl_cfg80211_p2plo_deinit(struct bcm_cfg80211 *cfg);
2482 #endif /* P2P_LISTEN_OFFLOADING */
2483
2484 /* Function to flush the FW log buffer content */
2485 extern void wl_flush_fw_log_buffer(struct net_device *dev, uint32 logset_mask);
2486
2487 #define RETURN_EIO_IF_NOT_UP(wlpriv) \
2488 do { \
2489 struct net_device *checkSysUpNDev = bcmcfg_to_prmry_ndev(wlpriv); \
2490 if (unlikely(!wl_get_drv_status(wlpriv, READY, checkSysUpNDev))) { \
2491 WL_INFORM(("device is not ready\n")); \
2492 return -EIO; \
2493 } \
2494 } while (0)
2495
2496 #ifdef QOS_MAP_SET
2497 extern uint8 *wl_get_up_table(void);
2498 #endif /* QOS_MAP_SET */
2499
2500 #define P2PO_COOKIE 65535
2501 u64 wl_cfg80211_get_new_roc_id(struct bcm_cfg80211 *cfg);
2502
2503 #ifdef SUPPORT_AP_HIGHER_BEACONRATE
2504 int wl_set_ap_beacon_rate(struct net_device *dev, int val, char *ifname);
2505 int wl_get_ap_basic_rate(struct net_device *dev, char* command, char *ifname, int total_len);
2506 #endif /* SUPPORT_AP_HIGHER_BEACONRATE */
2507 #ifdef SUPPORT_AP_RADIO_PWRSAVE
2508 int wl_get_ap_rps(struct net_device *dev, char* command, char *ifname, int total_len);
2509 int wl_set_ap_rps(struct net_device *dev, bool enable, char *ifname);
2510 int wl_update_ap_rps_params(struct net_device *dev, ap_rps_info_t* rps, char *ifname);
2511 void wl_cfg80211_init_ap_rps(struct bcm_cfg80211 *cfg);
2512 #endif /* SUPPORT_AP_RADIO_PWRSAVE */
2513 #ifdef SUPPORT_RSSI_SUM_REPORT
2514 int wl_get_rssi_logging(struct net_device *dev, void *param);
2515 int wl_set_rssi_logging(struct net_device *dev, void *param);
2516 int wl_get_rssi_per_ant(struct net_device *dev, char *ifname, char *peer_mac, void *param);
2517 #endif /* SUPPORT_RSSI_SUM_REPORT */
2518 int wl_cfg80211_iface_count(struct net_device *dev);
2519 struct net_device* wl_get_ap_netdev(struct bcm_cfg80211 *cfg, char *ifname);
2520 void wl_cfg80211_cleanup_virtual_ifaces(struct bcm_cfg80211 *cfg, bool rtnl_lock_reqd);
2521 #ifdef WL_IFACE_MGMT
2522 extern int wl_cfg80211_set_iface_policy(struct net_device *ndev, char *arg, int len);
2523 extern uint8 wl_cfg80211_get_iface_policy(struct net_device *ndev);
2524 extern s32 wl_cfg80211_handle_if_role_conflict(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype);
2525 s32 wl_cfg80211_data_if_mgmt(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype);
2526 s32 wl_cfg80211_disc_if_mgmt(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype,
2527 bool *disable_nan, bool *disable_p2p);
2528 s32 wl_cfg80211_handle_discovery_config(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype);
2529 wl_iftype_t wl_cfg80211_get_sec_iface(struct bcm_cfg80211 *cfg);
2530 bool wl_cfg80211_is_associated_discovery(struct bcm_cfg80211 *cfg, wl_iftype_t new_wl_iftype);
2531 #endif /* WL_IFACE_MGMT */
2532 struct wireless_dev * wl_cfg80211_add_if(struct bcm_cfg80211 *cfg, struct net_device *primary_ndev,
2533 wl_iftype_t wl_iftype, const char *name, u8 *mac);
2534 extern s32 wl_cfg80211_del_if(struct bcm_cfg80211 *cfg, struct net_device *primary_ndev,
2535 struct wireless_dev *wdev, char *name);
2536 s32 _wl_cfg80211_del_if(struct bcm_cfg80211 *cfg, struct net_device *primary_ndev,
2537 struct wireless_dev *wdev, char *ifname);
2538 s32 wl_cfg80211_delete_iface(struct bcm_cfg80211 *cfg, wl_iftype_t sec_data_if_type);
2539 s32 wl_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev, bool enabled, s32 timeout);
2540
2541 #ifdef WL_STATIC_IF
2542 extern struct net_device *wl_cfg80211_register_static_if(struct bcm_cfg80211 *cfg,
2543 u16 iftype, char *ifname, int ifidx);
2544 extern void wl_cfg80211_unregister_static_if(struct bcm_cfg80211 * cfg);
2545 extern s32 wl_cfg80211_static_if_open(struct net_device *net);
2546 extern s32 wl_cfg80211_static_if_close(struct net_device *net);
2547 extern struct net_device * wl_cfg80211_post_static_ifcreate(struct bcm_cfg80211 *cfg,
2548 wl_if_event_info *event, u8 *addr, s32 iface_type, const char *iface_name);
2549 extern s32 wl_cfg80211_post_static_ifdel(struct bcm_cfg80211 *cfg, struct net_device *ndev);
2550 #endif /* WL_STATIC_IF */
2551 extern struct wireless_dev *wl_cfg80211_get_wdev_from_ifname(struct bcm_cfg80211 *cfg,
2552 const char *name);
2553 struct net_device* wl_get_netdev_by_name(struct bcm_cfg80211 *cfg, char *ifname);
2554 extern s32 wl_get_vif_macaddr(struct bcm_cfg80211 *cfg, u16 wl_iftype, u8 *mac_addr);
2555 extern s32 wl_release_vif_macaddr(struct bcm_cfg80211 *cfg, u8 *mac_addr, u16 wl_iftype);
2556 extern int wl_cfg80211_ifstats_counters(struct net_device *dev, wl_if_stats_t *if_stats);
2557 extern s32 wl_cfg80211_set_dbg_verbose(struct net_device *ndev, u32 level);
2558 extern s32 wl_cfg80211_set_transition_mode(struct net_device *ndev, u32 transition_disabled);
2559 extern int wl_cfg80211_deinit_p2p_discovery(struct bcm_cfg80211 * cfg);
2560 extern int wl_cfg80211_set_frameburst(struct bcm_cfg80211 *cfg, bool enable);
2561 extern int wl_cfg80211_determine_p2p_rsdb_mode(struct bcm_cfg80211 *cfg);
2562 extern uint8 wl_cfg80211_get_bus_state(struct bcm_cfg80211 *cfg);
2563 #ifdef WL_WPS_SYNC
2564 void wl_handle_wps_states(struct net_device *ndev, u8 *dump_data, u16 len, bool direction);
2565 #endif /* WL_WPS_SYNC */
2566 extern int wl_features_set(u8 *array, uint8 len, u32 ftidx);
2567 extern void *wl_read_prof(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 item);
2568 extern s32 wl_cfg80211_sup_event_handler(struct bcm_cfg80211 *cfg, bcm_struct_cfgdev *cfgdev,
2569 const wl_event_msg_t *event, void *data);
2570 extern s32 wl_inform_bss(struct bcm_cfg80211 *cfg);
2571 extern void wl_cfg80211_cancel_scan(struct bcm_cfg80211 *cfg);
2572 extern s32 wl_notify_escan_complete(struct bcm_cfg80211 *cfg,
2573 struct net_device *ndev, bool aborted, bool fw_abort);
2574 #ifdef CUSTOMER_HW4_DEBUG
2575 extern void wl_scan_timeout_dbg_clear(void);
2576 #endif /* CUSTOMER_HW4_DEBUG */
2577 extern s32 cfg80211_to_wl_iftype(uint16 type, uint16 *role, uint16 *mode);
2578 extern s32 wl_cfg80211_net_attach(struct net_device *primary_ndev);
2579 extern void wl_print_verinfo(struct bcm_cfg80211 *cfg);
2580 extern const u8 *wl_find_attribute(const u8 *buf, u16 len, u16 element_id);
2581 extern int wl_cfg80211_get_concurrency_mode(struct bcm_cfg80211 *cfg);
2582 #if defined(WL_DISABLE_HE_SOFTAP) || defined(WL_DISABLE_HE_P2P)
2583 int wl_cfg80211_set_he_mode(struct net_device *dev, struct bcm_cfg80211 *cfg,
2584 s32 bssidx, u32 interface_type, bool set);
2585 #define WL_HE_FEATURES_HE_AP 0x8
2586 #define WL_HE_FEATURES_HE_P2P 0x20
2587 #endif /* WL_DISABLE_HE_SOFTAP || WL_DISABLE_HE_P2P */
2588 extern s32 wl_cfg80211_config_suspend_events(struct net_device *ndev, bool enable);
2589 #ifdef WL11U
2590 extern bcm_tlv_t *
2591 wl_cfg80211_find_interworking_ie(const u8 *parse, u32 len);
2592 extern s32
2593 wl_cfg80211_add_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bssidx, s32 pktflag,
2594 uint8 ie_id, uint8 *data, uint8 data_len);
2595 extern s32
2596 wl_cfg80211_clear_iw_ie(struct bcm_cfg80211 *cfg, struct net_device *ndev, s32 bssidx);
2597
2598 static inline void
wl_get_iwdata_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev,u8 * iw_ie,u32 * iw_ie_len)2599 wl_get_iwdata_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, u8 *iw_ie,
2600 u32 *iw_ie_len)
2601 {
2602 struct net_info *_net_info, *next;
2603 unsigned long int flags;
2604
2605 spin_lock_irqsave(&cfg->net_list_sync, flags);
2606 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
2607 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
2608 GCC_DIAGNOSTIC_POP();
2609 if (ndev && (_net_info->ndev == ndev)) {
2610 *iw_ie_len = _net_info->profile.iw_ie_len;
2611 memcpy(iw_ie, _net_info->profile.iw_ie, _net_info->profile.iw_ie_len);
2612 break;
2613 }
2614 }
2615 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
2616 }
2617
2618 static inline void
wl_set_iwdata_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev,u8 * iw_ie,u32 iw_ie_len)2619 wl_set_iwdata_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev, u8 *iw_ie, u32 iw_ie_len)
2620 {
2621 struct net_info *_net_info, *next;
2622 unsigned long int flags;
2623
2624 spin_lock_irqsave(&cfg->net_list_sync, flags);
2625 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
2626 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
2627 GCC_DIAGNOSTIC_POP();
2628 if (ndev && (_net_info->ndev == ndev)) {
2629 _net_info->profile.iw_ie_len = iw_ie_len;
2630 memcpy(_net_info->profile.iw_ie, iw_ie, _net_info->profile.iw_ie_len);
2631 }
2632 }
2633 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
2634 }
2635
2636 static inline void
wl_clear_iwdata_by_netdev(struct bcm_cfg80211 * cfg,struct net_device * ndev)2637 wl_clear_iwdata_by_netdev(struct bcm_cfg80211 *cfg, struct net_device *ndev)
2638 {
2639 struct net_info *_net_info, *next;
2640 unsigned long int flags;
2641
2642 spin_lock_irqsave(&cfg->net_list_sync, flags);
2643 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
2644 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next, &cfg->net_list, list) {
2645 GCC_DIAGNOSTIC_POP();
2646 if (ndev && (_net_info->ndev == ndev)) {
2647 _net_info->profile.iw_ie_len = 0;
2648 memset(_net_info->profile.iw_ie, 0, IW_IES_MAX_BUF_LEN);
2649 }
2650 }
2651 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
2652 }
2653
2654 static inline void
wl_clear_iwdata(struct bcm_cfg80211 * cfg)2655 wl_clear_iwdata(struct bcm_cfg80211 *cfg)
2656 {
2657 struct net_info *_net_info, *next;
2658 unsigned long int flags;
2659 spin_lock_irqsave(&cfg->net_list_sync, flags);
2660 GCC_DIAGNOSTIC_PUSH_SUPPRESS_CAST();
2661 BCM_LIST_FOR_EACH_ENTRY_SAFE(_net_info, next,
2662 &cfg->net_list, list) {
2663 GCC_DIAGNOSTIC_POP();
2664 if (_net_info->profile.iw_ie_len) {
2665 _net_info->profile.iw_ie_len = 0;
2666 memset(_net_info->profile.iw_ie, 0, IW_IES_MAX_BUF_LEN);
2667 }
2668 }
2669 spin_unlock_irqrestore(&cfg->net_list_sync, flags);
2670 return;
2671 }
2672 #endif /* WL11U */
2673 #endif /* _wl_cfg80211_h_ */
2674