xref: /linux/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c (revision 7c6084d7fa4e61dd7824c34529277a814c7b3836)
1 // SPDX-License-Identifier: ISC
2 /*
3  * Copyright (c) 2010 Broadcom Corporation
4  */
5 
6 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
7 
8 #include <linux/kernel.h>
9 #include <linux/etherdevice.h>
10 #include <linux/module.h>
11 #include <linux/vmalloc.h>
12 #include <net/cfg80211.h>
13 #include <net/netlink.h>
14 #include <uapi/linux/if_arp.h>
15 
16 #include <brcmu_utils.h>
17 #include <defs.h>
18 #include <brcmu_wifi.h>
19 #include <brcm_hw_ids.h>
20 #include "core.h"
21 #include "debug.h"
22 #include "tracepoint.h"
23 #include "fwil_types.h"
24 #include "p2p.h"
25 #include "btcoex.h"
26 #include "pno.h"
27 #include "fwsignal.h"
28 #include "cfg80211.h"
29 #include "feature.h"
30 #include "fwil.h"
31 #include "proto.h"
32 #include "vendor.h"
33 #include "bus.h"
34 #include "common.h"
35 #include "fwvid.h"
36 
37 #define BRCMF_SCAN_IE_LEN_MAX		2048
38 
39 #define WPA_OUI				"\x00\x50\xF2"	/* WPA OUI */
40 #define WPA_OUI_TYPE			1
41 #define RSN_OUI				"\x00\x0F\xAC"	/* RSN OUI */
42 #define	WME_OUI_TYPE			2
43 #define WPS_OUI_TYPE			4
44 
45 #define VS_IE_FIXED_HDR_LEN		6
46 #define WPA_IE_VERSION_LEN		2
47 #define WPA_IE_MIN_OUI_LEN		4
48 #define WPA_IE_SUITE_COUNT_LEN		2
49 
50 #define WPA_CIPHER_NONE			0	/* None */
51 #define WPA_CIPHER_WEP_40		1	/* WEP (40-bit) */
52 #define WPA_CIPHER_TKIP			2	/* TKIP: default for WPA */
53 #define WPA_CIPHER_AES_CCM		4	/* AES (CCM) */
54 #define WPA_CIPHER_WEP_104		5	/* WEP (104-bit) */
55 
56 #define RSN_AKM_NONE			0	/* None (IBSS) */
57 #define RSN_AKM_UNSPECIFIED		1	/* Over 802.1x */
58 #define RSN_AKM_PSK			2	/* Pre-shared Key */
59 #define RSN_AKM_SHA256_1X		5	/* SHA256, 802.1X */
60 #define RSN_AKM_SHA256_PSK		6	/* SHA256, Pre-shared Key */
61 #define RSN_AKM_SAE			8	/* SAE */
62 #define RSN_CAP_LEN			2	/* Length of RSN capabilities */
63 #define RSN_CAP_PTK_REPLAY_CNTR_MASK	(BIT(2) | BIT(3))
64 #define RSN_CAP_MFPR_MASK		BIT(6)
65 #define RSN_CAP_MFPC_MASK		BIT(7)
66 #define RSN_PMKID_COUNT_LEN		2
67 
68 #define VNDR_IE_CMD_LEN			4	/* length of the set command
69 						 * string :"add", "del" (+ NUL)
70 						 */
71 #define VNDR_IE_COUNT_OFFSET		4
72 #define VNDR_IE_PKTFLAG_OFFSET		8
73 #define VNDR_IE_VSIE_OFFSET		12
74 #define VNDR_IE_HDR_SIZE		12
75 #define VNDR_IE_PARSE_LIMIT		5
76 
77 #define	DOT11_BCN_PRB_FIXED_LEN		12	/* beacon/probe fixed length */
78 
79 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS	320
80 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS	400
81 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS	20
82 
83 #define BRCMF_SCAN_CHANNEL_TIME		40
84 #define BRCMF_SCAN_UNASSOC_TIME		40
85 #define BRCMF_SCAN_PASSIVE_TIME		120
86 
87 #define BRCMF_ND_INFO_TIMEOUT		msecs_to_jiffies(2000)
88 
89 #define BRCMF_PS_MAX_TIMEOUT_MS		2000
90 
91 /* Dump obss definitions */
92 #define ACS_MSRMNT_DELAY		80
93 #define CHAN_NOISE_DUMMY		(-80)
94 #define OBSS_TOKEN_IDX			15
95 #define IBSS_TOKEN_IDX			15
96 #define TX_TOKEN_IDX			14
97 #define CTG_TOKEN_IDX			13
98 #define PKT_TOKEN_IDX			15
99 #define IDLE_TOKEN_IDX			12
100 
101 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
102 	(sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
103 
104 #define BRCMF_MAX_CHANSPEC_LIST \
105 	(BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1)
106 
107 struct brcmf_dump_survey {
108 	u32 obss;
109 	u32 ibss;
110 	u32 no_ctg;
111 	u32 no_pckt;
112 	u32 tx;
113 	u32 idle;
114 };
115 
116 struct cca_stats_n_flags {
117 	u32 msrmnt_time; /* Time for Measurement (msec) */
118 	u32 msrmnt_done; /* flag set when measurement complete */
119 	char buf[1];
120 };
121 
122 struct cca_msrmnt_query {
123 	u32 msrmnt_query;
124 	u32 time_req;
125 };
126 
127 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
128 {
129 	if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
130 		brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
131 			  vif->sme_state);
132 		return false;
133 	}
134 	return true;
135 }
136 
137 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
138 #define RATETAB_ENT(_rateid, _flags) \
139 	{                                                               \
140 		.bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
141 		.hw_value       = (_rateid),                            \
142 		.flags          = (_flags),                             \
143 	}
144 
145 static struct ieee80211_rate __wl_rates[] = {
146 	RATETAB_ENT(BRCM_RATE_1M, 0),
147 	RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
148 	RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
149 	RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
150 	RATETAB_ENT(BRCM_RATE_6M, 0),
151 	RATETAB_ENT(BRCM_RATE_9M, 0),
152 	RATETAB_ENT(BRCM_RATE_12M, 0),
153 	RATETAB_ENT(BRCM_RATE_18M, 0),
154 	RATETAB_ENT(BRCM_RATE_24M, 0),
155 	RATETAB_ENT(BRCM_RATE_36M, 0),
156 	RATETAB_ENT(BRCM_RATE_48M, 0),
157 	RATETAB_ENT(BRCM_RATE_54M, 0),
158 };
159 
160 #define wl_g_rates		(__wl_rates + 0)
161 #define wl_g_rates_size		ARRAY_SIZE(__wl_rates)
162 #define wl_a_rates		(__wl_rates + 4)
163 #define wl_a_rates_size		(wl_g_rates_size - 4)
164 
165 #define CHAN2G(_channel, _freq) {				\
166 	.band			= NL80211_BAND_2GHZ,		\
167 	.center_freq		= (_freq),			\
168 	.hw_value		= (_channel),			\
169 	.max_antenna_gain	= 0,				\
170 	.max_power		= 30,				\
171 }
172 
173 #define CHAN5G(_channel) {					\
174 	.band			= NL80211_BAND_5GHZ,		\
175 	.center_freq		= 5000 + (5 * (_channel)),	\
176 	.hw_value		= (_channel),			\
177 	.max_antenna_gain	= 0,				\
178 	.max_power		= 30,				\
179 }
180 
181 static struct ieee80211_channel __wl_2ghz_channels[] = {
182 	CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
183 	CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
184 	CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
185 	CHAN2G(13, 2472), CHAN2G(14, 2484)
186 };
187 
188 static struct ieee80211_channel __wl_5ghz_channels[] = {
189 	CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
190 	CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
191 	CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
192 	CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
193 	CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
194 	CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
195 };
196 
197 /* Band templates duplicated per wiphy. The channel info
198  * above is added to the band during setup.
199  */
200 static const struct ieee80211_supported_band __wl_band_2ghz = {
201 	.band = NL80211_BAND_2GHZ,
202 	.bitrates = wl_g_rates,
203 	.n_bitrates = wl_g_rates_size,
204 };
205 
206 static const struct ieee80211_supported_band __wl_band_5ghz = {
207 	.band = NL80211_BAND_5GHZ,
208 	.bitrates = wl_a_rates,
209 	.n_bitrates = wl_a_rates_size,
210 };
211 
212 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
213  * By default world regulatory domain defined in reg.c puts the flags
214  * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
215  * With respect to these flags, wpa_supplicant doesn't * start p2p
216  * operations on 5GHz channels. All the changes in world regulatory
217  * domain are to be done here.
218  */
219 static const struct ieee80211_regdomain brcmf_regdom = {
220 	.n_reg_rules = 4,
221 	.alpha2 =  "99",
222 	.reg_rules = {
223 		/* IEEE 802.11b/g, channels 1..11 */
224 		REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
225 		/* If any */
226 		/* IEEE 802.11 channel 14 - Only JP enables
227 		 * this and for 802.11b only
228 		 */
229 		REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
230 		/* IEEE 802.11a, channel 36..64 */
231 		REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
232 		/* IEEE 802.11a, channel 100..165 */
233 		REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
234 };
235 
236 /* Note: brcmf_cipher_suites is an array of int defining which cipher suites
237  * are supported. A pointer to this array and the number of entries is passed
238  * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
239  * So the cipher suite AES_CMAC has to be the last one in the array, and when
240  * device does not support MFP then the number of suites will be decreased by 1
241  */
242 static const u32 brcmf_cipher_suites[] = {
243 	WLAN_CIPHER_SUITE_WEP40,
244 	WLAN_CIPHER_SUITE_WEP104,
245 	WLAN_CIPHER_SUITE_TKIP,
246 	WLAN_CIPHER_SUITE_CCMP,
247 	/* Keep as last entry: */
248 	WLAN_CIPHER_SUITE_AES_CMAC
249 };
250 
251 /* Vendor specific ie. id = 221, oui and type defines exact ie */
252 struct brcmf_vs_tlv {
253 	u8 id;
254 	u8 len;
255 	u8 oui[3];
256 	u8 oui_type;
257 };
258 
259 struct parsed_vndr_ie_info {
260 	u8 *ie_ptr;
261 	u32 ie_len;	/* total length including id & length field */
262 	struct brcmf_vs_tlv vndrie;
263 };
264 
265 struct parsed_vndr_ies {
266 	u32 count;
267 	struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
268 };
269 
270 #define WL_INTERFACE_CREATE_VER_1		1
271 #define WL_INTERFACE_CREATE_VER_2		2
272 #define WL_INTERFACE_CREATE_VER_3		3
273 #define WL_INTERFACE_CREATE_VER_MAX		WL_INTERFACE_CREATE_VER_3
274 
275 #define WL_INTERFACE_MAC_DONT_USE	0x0
276 #define WL_INTERFACE_MAC_USE		0x2
277 
278 #define WL_INTERFACE_CREATE_STA		0x0
279 #define WL_INTERFACE_CREATE_AP		0x1
280 
281 struct wl_interface_create_v1 {
282 	u16	ver;			/* structure version */
283 	u32	flags;			/* flags for operation */
284 	u8	mac_addr[ETH_ALEN];	/* MAC address */
285 	u32	wlc_index;		/* optional for wlc index */
286 };
287 
288 struct wl_interface_create_v2 {
289 	u16	ver;			/* structure version */
290 	u8	pad1[2];
291 	u32	flags;			/* flags for operation */
292 	u8	mac_addr[ETH_ALEN];	/* MAC address */
293 	u8	iftype;			/* type of interface created */
294 	u8	pad2;
295 	u32	wlc_index;		/* optional for wlc index */
296 };
297 
298 struct wl_interface_create_v3 {
299 	u16 ver;			/* structure version */
300 	u16 len;			/* length of structure + data */
301 	u16 fixed_len;			/* length of structure */
302 	u8 iftype;			/* type of interface created */
303 	u8 wlc_index;			/* optional for wlc index */
304 	u32 flags;			/* flags for operation */
305 	u8 mac_addr[ETH_ALEN];		/* MAC address */
306 	u8 bssid[ETH_ALEN];		/* optional for BSSID */
307 	u8 if_index;			/* interface index request */
308 	u8 pad[3];
309 	u8 data[];			/* Optional for specific data */
310 };
311 
312 static u8 nl80211_band_to_fwil(enum nl80211_band band)
313 {
314 	switch (band) {
315 	case NL80211_BAND_2GHZ:
316 		return WLC_BAND_2G;
317 	case NL80211_BAND_5GHZ:
318 		return WLC_BAND_5G;
319 	default:
320 		WARN_ON(1);
321 		break;
322 	}
323 	return 0;
324 }
325 
326 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
327 			       struct cfg80211_chan_def *ch)
328 {
329 	struct brcmu_chan ch_inf;
330 	s32 primary_offset;
331 
332 	brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
333 		  ch->chan->center_freq, ch->center_freq1, ch->width);
334 	ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
335 	primary_offset = ch->chan->center_freq - ch->center_freq1;
336 	switch (ch->width) {
337 	case NL80211_CHAN_WIDTH_20:
338 	case NL80211_CHAN_WIDTH_20_NOHT:
339 		ch_inf.bw = BRCMU_CHAN_BW_20;
340 		WARN_ON(primary_offset != 0);
341 		break;
342 	case NL80211_CHAN_WIDTH_40:
343 		ch_inf.bw = BRCMU_CHAN_BW_40;
344 		if (primary_offset > 0)
345 			ch_inf.sb = BRCMU_CHAN_SB_U;
346 		else
347 			ch_inf.sb = BRCMU_CHAN_SB_L;
348 		break;
349 	case NL80211_CHAN_WIDTH_80:
350 		ch_inf.bw = BRCMU_CHAN_BW_80;
351 		if (primary_offset == -30)
352 			ch_inf.sb = BRCMU_CHAN_SB_LL;
353 		else if (primary_offset == -10)
354 			ch_inf.sb = BRCMU_CHAN_SB_LU;
355 		else if (primary_offset == 10)
356 			ch_inf.sb = BRCMU_CHAN_SB_UL;
357 		else
358 			ch_inf.sb = BRCMU_CHAN_SB_UU;
359 		break;
360 	case NL80211_CHAN_WIDTH_160:
361 		ch_inf.bw = BRCMU_CHAN_BW_160;
362 		if (primary_offset == -70)
363 			ch_inf.sb = BRCMU_CHAN_SB_LLL;
364 		else if (primary_offset == -50)
365 			ch_inf.sb = BRCMU_CHAN_SB_LLU;
366 		else if (primary_offset == -30)
367 			ch_inf.sb = BRCMU_CHAN_SB_LUL;
368 		else if (primary_offset == -10)
369 			ch_inf.sb = BRCMU_CHAN_SB_LUU;
370 		else if (primary_offset == 10)
371 			ch_inf.sb = BRCMU_CHAN_SB_ULL;
372 		else if (primary_offset == 30)
373 			ch_inf.sb = BRCMU_CHAN_SB_ULU;
374 		else if (primary_offset == 50)
375 			ch_inf.sb = BRCMU_CHAN_SB_UUL;
376 		else
377 			ch_inf.sb = BRCMU_CHAN_SB_UUU;
378 		break;
379 	case NL80211_CHAN_WIDTH_80P80:
380 	case NL80211_CHAN_WIDTH_5:
381 	case NL80211_CHAN_WIDTH_10:
382 	default:
383 		WARN_ON_ONCE(1);
384 	}
385 	switch (ch->chan->band) {
386 	case NL80211_BAND_2GHZ:
387 		ch_inf.band = BRCMU_CHAN_BAND_2G;
388 		break;
389 	case NL80211_BAND_5GHZ:
390 		ch_inf.band = BRCMU_CHAN_BAND_5G;
391 		break;
392 	case NL80211_BAND_60GHZ:
393 	default:
394 		WARN_ON_ONCE(1);
395 	}
396 	d11inf->encchspec(&ch_inf);
397 
398 	brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
399 	return ch_inf.chspec;
400 }
401 
402 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
403 			struct ieee80211_channel *ch)
404 {
405 	struct brcmu_chan ch_inf;
406 
407 	ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
408 	ch_inf.bw = BRCMU_CHAN_BW_20;
409 	d11inf->encchspec(&ch_inf);
410 
411 	return ch_inf.chspec;
412 }
413 
414 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
415  * triples, returning a pointer to the substring whose first element
416  * matches tag
417  */
418 static const struct brcmf_tlv *
419 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
420 {
421 	const struct brcmf_tlv *elt = buf;
422 	int totlen = buflen;
423 
424 	/* find tagged parameter */
425 	while (totlen >= TLV_HDR_LEN) {
426 		int len = elt->len;
427 
428 		/* validate remaining totlen */
429 		if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
430 			return elt;
431 
432 		elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
433 		totlen -= (len + TLV_HDR_LEN);
434 	}
435 
436 	return NULL;
437 }
438 
439 /* Is any of the tlvs the expected entry? If
440  * not update the tlvs buffer pointer/length.
441  */
442 static bool
443 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
444 		 const u8 *oui, u32 oui_len, u8 type)
445 {
446 	/* If the contents match the OUI and the type */
447 	if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
448 	    !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
449 	    type == ie[TLV_BODY_OFF + oui_len]) {
450 		return true;
451 	}
452 
453 	if (tlvs == NULL)
454 		return false;
455 	/* point to the next ie */
456 	ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
457 	/* calculate the length of the rest of the buffer */
458 	*tlvs_len -= (int)(ie - *tlvs);
459 	/* update the pointer to the start of the buffer */
460 	*tlvs = ie;
461 
462 	return false;
463 }
464 
465 static struct brcmf_vs_tlv *
466 brcmf_find_wpaie(const u8 *parse, u32 len)
467 {
468 	const struct brcmf_tlv *ie;
469 
470 	while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
471 		if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
472 				     WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
473 			return (struct brcmf_vs_tlv *)ie;
474 	}
475 	return NULL;
476 }
477 
478 static struct brcmf_vs_tlv *
479 brcmf_find_wpsie(const u8 *parse, u32 len)
480 {
481 	const struct brcmf_tlv *ie;
482 
483 	while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
484 		if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
485 				     WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
486 			return (struct brcmf_vs_tlv *)ie;
487 	}
488 	return NULL;
489 }
490 
491 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
492 				     struct brcmf_cfg80211_vif *vif,
493 				     enum nl80211_iftype new_type)
494 {
495 	struct brcmf_cfg80211_vif *pos;
496 	bool check_combos = false;
497 	int ret = 0;
498 	struct iface_combination_params params = {
499 		.num_different_channels = 1,
500 	};
501 
502 	list_for_each_entry(pos, &cfg->vif_list, list)
503 		if (pos == vif) {
504 			params.iftype_num[new_type]++;
505 		} else {
506 			/* concurrent interfaces so need check combinations */
507 			check_combos = true;
508 			params.iftype_num[pos->wdev.iftype]++;
509 		}
510 
511 	if (check_combos)
512 		ret = cfg80211_check_combinations(cfg->wiphy, &params);
513 
514 	return ret;
515 }
516 
517 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
518 				  enum nl80211_iftype new_type)
519 {
520 	struct brcmf_cfg80211_vif *pos;
521 	struct iface_combination_params params = {
522 		.num_different_channels = 1,
523 	};
524 
525 	list_for_each_entry(pos, &cfg->vif_list, list)
526 		params.iftype_num[pos->wdev.iftype]++;
527 
528 	params.iftype_num[new_type]++;
529 	return cfg80211_check_combinations(cfg->wiphy, &params);
530 }
531 
532 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
533 				 struct brcmf_wsec_key_le *key_le)
534 {
535 	key_le->index = cpu_to_le32(key->index);
536 	key_le->len = cpu_to_le32(key->len);
537 	key_le->algo = cpu_to_le32(key->algo);
538 	key_le->flags = cpu_to_le32(key->flags);
539 	key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
540 	key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
541 	key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
542 	memcpy(key_le->data, key->data, sizeof(key->data));
543 	memcpy(key_le->ea, key->ea, sizeof(key->ea));
544 }
545 
546 static int
547 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
548 {
549 	struct brcmf_pub *drvr = ifp->drvr;
550 	int err;
551 	struct brcmf_wsec_key_le key_le;
552 
553 	convert_key_from_CPU(key, &key_le);
554 
555 	brcmf_netdev_wait_pend8021x(ifp);
556 
557 	err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
558 					sizeof(key_le));
559 
560 	if (err)
561 		bphy_err(drvr, "wsec_key error (%d)\n", err);
562 	return err;
563 }
564 
565 static void
566 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
567 {
568 	struct brcmf_cfg80211_vif *vif;
569 	struct brcmf_if *ifp;
570 
571 	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
572 	ifp = vif->ifp;
573 
574 	if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
575 	    (wdev->iftype == NL80211_IFTYPE_AP) ||
576 	    (wdev->iftype == NL80211_IFTYPE_P2P_GO))
577 		brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
578 						ADDR_DIRECT);
579 	else
580 		brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
581 						ADDR_INDIRECT);
582 }
583 
584 static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
585 {
586 	int bsscfgidx;
587 
588 	for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
589 		/* bsscfgidx 1 is reserved for legacy P2P */
590 		if (bsscfgidx == 1)
591 			continue;
592 		if (!drvr->iflist[bsscfgidx])
593 			return bsscfgidx;
594 	}
595 
596 	return -ENOMEM;
597 }
598 
599 static void brcmf_set_vif_sta_macaddr(struct brcmf_if *ifp, u8 *mac_addr)
600 {
601 	u8 mac_idx = ifp->drvr->sta_mac_idx;
602 
603 	/* set difference MAC address with locally administered bit */
604 	memcpy(mac_addr, ifp->mac_addr, ETH_ALEN);
605 	mac_addr[0] |= 0x02;
606 	mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
607 	mac_idx++;
608 	mac_idx = mac_idx % 2;
609 	ifp->drvr->sta_mac_idx = mac_idx;
610 }
611 
612 static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
613 {
614 	struct wl_interface_create_v1 iface_v1;
615 	struct wl_interface_create_v2 iface_v2;
616 	struct wl_interface_create_v3 iface_v3;
617 	u32 iface_create_ver;
618 	int err;
619 
620 	/* interface_create version 1 */
621 	memset(&iface_v1, 0, sizeof(iface_v1));
622 	iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
623 	iface_v1.flags = WL_INTERFACE_CREATE_STA |
624 			 WL_INTERFACE_MAC_USE;
625 	if (!is_zero_ether_addr(macaddr))
626 		memcpy(iface_v1.mac_addr, macaddr, ETH_ALEN);
627 	else
628 		brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
629 
630 	err = brcmf_fil_iovar_data_get(ifp, "interface_create",
631 				       &iface_v1,
632 				       sizeof(iface_v1));
633 	if (err) {
634 		brcmf_info("failed to create interface(v1), err=%d\n",
635 			   err);
636 	} else {
637 		brcmf_dbg(INFO, "interface created(v1)\n");
638 		return 0;
639 	}
640 
641 	/* interface_create version 2 */
642 	memset(&iface_v2, 0, sizeof(iface_v2));
643 	iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
644 	iface_v2.flags = WL_INTERFACE_MAC_USE;
645 	iface_v2.iftype = WL_INTERFACE_CREATE_STA;
646 	if (!is_zero_ether_addr(macaddr))
647 		memcpy(iface_v2.mac_addr, macaddr, ETH_ALEN);
648 	else
649 		brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
650 
651 	err = brcmf_fil_iovar_data_get(ifp, "interface_create",
652 				       &iface_v2,
653 				       sizeof(iface_v2));
654 	if (err) {
655 		brcmf_info("failed to create interface(v2), err=%d\n",
656 			   err);
657 	} else {
658 		brcmf_dbg(INFO, "interface created(v2)\n");
659 		return 0;
660 	}
661 
662 	/* interface_create version 3+ */
663 	/* get supported version from firmware side */
664 	iface_create_ver = 0;
665 	err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
666 					 &iface_create_ver);
667 	if (err) {
668 		brcmf_err("fail to get supported version, err=%d\n", err);
669 		return -EOPNOTSUPP;
670 	}
671 
672 	switch (iface_create_ver) {
673 	case WL_INTERFACE_CREATE_VER_3:
674 		memset(&iface_v3, 0, sizeof(iface_v3));
675 		iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
676 		iface_v3.flags = WL_INTERFACE_MAC_USE;
677 		iface_v3.iftype = WL_INTERFACE_CREATE_STA;
678 		if (!is_zero_ether_addr(macaddr))
679 			memcpy(iface_v3.mac_addr, macaddr, ETH_ALEN);
680 		else
681 			brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
682 
683 		err = brcmf_fil_iovar_data_get(ifp, "interface_create",
684 					       &iface_v3,
685 					       sizeof(iface_v3));
686 
687 		if (!err)
688 			brcmf_dbg(INFO, "interface created(v3)\n");
689 		break;
690 	default:
691 		brcmf_err("not support interface create(v%d)\n",
692 			  iface_create_ver);
693 		err = -EOPNOTSUPP;
694 		break;
695 	}
696 
697 	if (err) {
698 		brcmf_info("station interface creation failed (%d)\n",
699 			   err);
700 		return -EIO;
701 	}
702 
703 	return 0;
704 }
705 
706 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
707 {
708 	struct wl_interface_create_v1 iface_v1;
709 	struct wl_interface_create_v2 iface_v2;
710 	struct wl_interface_create_v3 iface_v3;
711 	u32 iface_create_ver;
712 	struct brcmf_pub *drvr = ifp->drvr;
713 	struct brcmf_mbss_ssid_le mbss_ssid_le;
714 	int bsscfgidx;
715 	int err;
716 
717 	/* interface_create version 1 */
718 	memset(&iface_v1, 0, sizeof(iface_v1));
719 	iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
720 	iface_v1.flags = WL_INTERFACE_CREATE_AP |
721 			 WL_INTERFACE_MAC_USE;
722 
723 	brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
724 
725 	err = brcmf_fil_iovar_data_get(ifp, "interface_create",
726 				       &iface_v1,
727 				       sizeof(iface_v1));
728 	if (err) {
729 		brcmf_info("failed to create interface(v1), err=%d\n",
730 			   err);
731 	} else {
732 		brcmf_dbg(INFO, "interface created(v1)\n");
733 		return 0;
734 	}
735 
736 	/* interface_create version 2 */
737 	memset(&iface_v2, 0, sizeof(iface_v2));
738 	iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
739 	iface_v2.flags = WL_INTERFACE_MAC_USE;
740 	iface_v2.iftype = WL_INTERFACE_CREATE_AP;
741 
742 	brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
743 
744 	err = brcmf_fil_iovar_data_get(ifp, "interface_create",
745 				       &iface_v2,
746 				       sizeof(iface_v2));
747 	if (err) {
748 		brcmf_info("failed to create interface(v2), err=%d\n",
749 			   err);
750 	} else {
751 		brcmf_dbg(INFO, "interface created(v2)\n");
752 		return 0;
753 	}
754 
755 	/* interface_create version 3+ */
756 	/* get supported version from firmware side */
757 	iface_create_ver = 0;
758 	err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
759 					 &iface_create_ver);
760 	if (err) {
761 		brcmf_err("fail to get supported version, err=%d\n", err);
762 		return -EOPNOTSUPP;
763 	}
764 
765 	switch (iface_create_ver) {
766 	case WL_INTERFACE_CREATE_VER_3:
767 		memset(&iface_v3, 0, sizeof(iface_v3));
768 		iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
769 		iface_v3.flags = WL_INTERFACE_MAC_USE;
770 		iface_v3.iftype = WL_INTERFACE_CREATE_AP;
771 		brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
772 
773 		err = brcmf_fil_iovar_data_get(ifp, "interface_create",
774 					       &iface_v3,
775 					       sizeof(iface_v3));
776 
777 		if (!err)
778 			brcmf_dbg(INFO, "interface created(v3)\n");
779 		break;
780 	default:
781 		brcmf_err("not support interface create(v%d)\n",
782 			  iface_create_ver);
783 		err = -EOPNOTSUPP;
784 		break;
785 	}
786 
787 	if (err) {
788 		brcmf_info("Does not support interface_create (%d)\n",
789 			   err);
790 		memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
791 		bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
792 		if (bsscfgidx < 0)
793 			return bsscfgidx;
794 
795 		mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
796 		mbss_ssid_le.SSID_len = cpu_to_le32(5);
797 		sprintf(mbss_ssid_le.SSID, "ssid%d", bsscfgidx);
798 
799 		err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
800 						sizeof(mbss_ssid_le));
801 
802 		if (err < 0)
803 			bphy_err(drvr, "setting ssid failed %d\n", err);
804 	}
805 
806 	return err;
807 }
808 
809 /**
810  * brcmf_apsta_add_vif() - create a new AP or STA virtual interface
811  *
812  * @wiphy: wiphy device of new interface.
813  * @name: name of the new interface.
814  * @params: contains mac address for AP or STA device.
815  * @type: interface type.
816  *
817  * Return: pointer to new vif on success, ERR_PTR(-errno) if not
818  */
819 static
820 struct wireless_dev *brcmf_apsta_add_vif(struct wiphy *wiphy, const char *name,
821 					 struct vif_params *params,
822 					 enum nl80211_iftype type)
823 {
824 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
825 	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
826 	struct brcmf_pub *drvr = cfg->pub;
827 	struct brcmf_cfg80211_vif *vif;
828 	int err;
829 
830 	if (type != NL80211_IFTYPE_STATION && type != NL80211_IFTYPE_AP)
831 		return ERR_PTR(-EINVAL);
832 
833 	if (brcmf_cfg80211_vif_event_armed(cfg))
834 		return ERR_PTR(-EBUSY);
835 
836 	brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
837 
838 	vif = brcmf_alloc_vif(cfg, type);
839 	if (IS_ERR(vif))
840 		return (struct wireless_dev *)vif;
841 
842 	brcmf_cfg80211_arm_vif_event(cfg, vif);
843 
844 	if (type == NL80211_IFTYPE_STATION)
845 		err = brcmf_cfg80211_request_sta_if(ifp, params->macaddr);
846 	else
847 		err = brcmf_cfg80211_request_ap_if(ifp);
848 	if (err) {
849 		brcmf_cfg80211_arm_vif_event(cfg, NULL);
850 		goto fail;
851 	}
852 
853 	/* wait for firmware event */
854 	err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
855 					    BRCMF_VIF_EVENT_TIMEOUT);
856 	brcmf_cfg80211_arm_vif_event(cfg, NULL);
857 	if (!err) {
858 		bphy_err(drvr, "timeout occurred\n");
859 		err = -EIO;
860 		goto fail;
861 	}
862 
863 	/* interface created in firmware */
864 	ifp = vif->ifp;
865 	if (!ifp) {
866 		bphy_err(drvr, "no if pointer provided\n");
867 		err = -ENOENT;
868 		goto fail;
869 	}
870 
871 	strscpy(ifp->ndev->name, name, sizeof(ifp->ndev->name));
872 	err = brcmf_net_attach(ifp, true);
873 	if (err) {
874 		bphy_err(drvr, "Registering netdevice failed\n");
875 		free_netdev(ifp->ndev);
876 		goto fail;
877 	}
878 
879 	return &ifp->vif->wdev;
880 
881 fail:
882 	brcmf_free_vif(vif);
883 	return ERR_PTR(err);
884 }
885 
886 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
887 {
888 	enum nl80211_iftype iftype;
889 
890 	iftype = vif->wdev.iftype;
891 	return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
892 }
893 
894 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
895 {
896 	return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
897 }
898 
899 /**
900  * brcmf_mon_add_vif() - create monitor mode virtual interface
901  *
902  * @wiphy: wiphy device of new interface.
903  * @name: name of the new interface.
904  *
905  * Return: pointer to new vif on success, ERR_PTR(-errno) if not
906  */
907 static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
908 					      const char *name)
909 {
910 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
911 	struct brcmf_cfg80211_vif *vif;
912 	struct net_device *ndev;
913 	struct brcmf_if *ifp;
914 	int err;
915 
916 	if (cfg->pub->mon_if) {
917 		err = -EEXIST;
918 		goto err_out;
919 	}
920 
921 	vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
922 	if (IS_ERR(vif)) {
923 		err = PTR_ERR(vif);
924 		goto err_out;
925 	}
926 
927 	ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
928 	if (!ndev) {
929 		err = -ENOMEM;
930 		goto err_free_vif;
931 	}
932 	ndev->type = ARPHRD_IEEE80211_RADIOTAP;
933 	ndev->ieee80211_ptr = &vif->wdev;
934 	ndev->needs_free_netdev = true;
935 	ndev->priv_destructor = brcmf_cfg80211_free_vif;
936 	SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
937 
938 	ifp = netdev_priv(ndev);
939 	ifp->vif = vif;
940 	ifp->ndev = ndev;
941 	ifp->drvr = cfg->pub;
942 
943 	vif->ifp = ifp;
944 	vif->wdev.netdev = ndev;
945 
946 	err = brcmf_net_mon_attach(ifp);
947 	if (err) {
948 		brcmf_err("Failed to attach %s device\n", ndev->name);
949 		free_netdev(ndev);
950 		goto err_free_vif;
951 	}
952 
953 	cfg->pub->mon_if = ifp;
954 
955 	return &vif->wdev;
956 
957 err_free_vif:
958 	brcmf_free_vif(vif);
959 err_out:
960 	return ERR_PTR(err);
961 }
962 
963 static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
964 {
965 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
966 	struct net_device *ndev = wdev->netdev;
967 
968 	ndev->netdev_ops->ndo_stop(ndev);
969 
970 	brcmf_net_detach(ndev, true);
971 
972 	cfg->pub->mon_if = NULL;
973 
974 	return 0;
975 }
976 
977 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
978 						     const char *name,
979 						     unsigned char name_assign_type,
980 						     enum nl80211_iftype type,
981 						     struct vif_params *params)
982 {
983 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
984 	struct brcmf_pub *drvr = cfg->pub;
985 	struct wireless_dev *wdev;
986 	int err;
987 
988 	brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
989 	err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
990 	if (err) {
991 		bphy_err(drvr, "iface validation failed: err=%d\n", err);
992 		return ERR_PTR(err);
993 	}
994 	switch (type) {
995 	case NL80211_IFTYPE_ADHOC:
996 	case NL80211_IFTYPE_AP_VLAN:
997 	case NL80211_IFTYPE_WDS:
998 	case NL80211_IFTYPE_MESH_POINT:
999 		return ERR_PTR(-EOPNOTSUPP);
1000 	case NL80211_IFTYPE_MONITOR:
1001 		return brcmf_mon_add_vif(wiphy, name);
1002 	case NL80211_IFTYPE_STATION:
1003 	case NL80211_IFTYPE_AP:
1004 		wdev = brcmf_apsta_add_vif(wiphy, name, params, type);
1005 		break;
1006 	case NL80211_IFTYPE_P2P_CLIENT:
1007 	case NL80211_IFTYPE_P2P_GO:
1008 	case NL80211_IFTYPE_P2P_DEVICE:
1009 		wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
1010 		break;
1011 	case NL80211_IFTYPE_UNSPECIFIED:
1012 	default:
1013 		return ERR_PTR(-EINVAL);
1014 	}
1015 
1016 	if (IS_ERR(wdev))
1017 		bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
1018 			 type, (int)PTR_ERR(wdev));
1019 	else
1020 		brcmf_cfg80211_update_proto_addr_mode(wdev);
1021 
1022 	return wdev;
1023 }
1024 
1025 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
1026 {
1027 	if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
1028 		brcmf_set_mpc(ifp, mpc);
1029 }
1030 
1031 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
1032 {
1033 	struct brcmf_pub *drvr = ifp->drvr;
1034 	s32 err = 0;
1035 
1036 	if (check_vif_up(ifp->vif)) {
1037 		err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
1038 		if (err) {
1039 			bphy_err(drvr, "fail to set mpc\n");
1040 			return;
1041 		}
1042 		brcmf_dbg(INFO, "MPC : %d\n", mpc);
1043 	}
1044 }
1045 
1046 bool brcmf_is_apmode_operating(struct wiphy *wiphy)
1047 {
1048 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1049 	struct brcmf_cfg80211_vif *vif;
1050 	bool ret = false;
1051 
1052 	list_for_each_entry(vif, &cfg->vif_list, list) {
1053 		if (brcmf_is_apmode(vif) &&
1054 		    test_bit(BRCMF_VIF_STATUS_AP_CREATED, &vif->sme_state))
1055 			ret = true;
1056 	}
1057 
1058 	return ret;
1059 }
1060 
1061 static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le,
1062 				       struct brcmf_scan_params_le *params_le)
1063 {
1064 	size_t params_size;
1065 	u32 ch;
1066 	int n_channels, n_ssids;
1067 
1068 	memcpy(&params_le->ssid_le, &params_v2_le->ssid_le,
1069 	       sizeof(params_le->ssid_le));
1070 	memcpy(&params_le->bssid, &params_v2_le->bssid,
1071 	       sizeof(params_le->bssid));
1072 
1073 	params_le->bss_type = params_v2_le->bss_type;
1074 	params_le->scan_type = le32_to_cpu(params_v2_le->scan_type);
1075 	params_le->nprobes = params_v2_le->nprobes;
1076 	params_le->active_time = params_v2_le->active_time;
1077 	params_le->passive_time = params_v2_le->passive_time;
1078 	params_le->home_time = params_v2_le->home_time;
1079 	params_le->channel_num = params_v2_le->channel_num;
1080 
1081 	ch = le32_to_cpu(params_v2_le->channel_num);
1082 	n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK;
1083 	n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT;
1084 
1085 	params_size = sizeof(u16) * n_channels;
1086 	if (n_ssids > 0) {
1087 		params_size = roundup(params_size, sizeof(u32));
1088 		params_size += sizeof(struct brcmf_ssid_le) * n_ssids;
1089 	}
1090 
1091 	memcpy(&params_le->channel_list[0],
1092 	       &params_v2_le->channel_list[0], params_size);
1093 }
1094 
1095 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1096 			     struct brcmf_scan_params_v2_le *params_le,
1097 			     struct cfg80211_scan_request *request)
1098 {
1099 	u32 n_ssids;
1100 	u32 n_channels;
1101 	s32 i;
1102 	s32 offset;
1103 	u16 chanspec;
1104 	char *ptr;
1105 	int length;
1106 	struct brcmf_ssid_le ssid_le;
1107 
1108 	eth_broadcast_addr(params_le->bssid);
1109 
1110 	length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1111 
1112 	params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V2);
1113 	params_le->bss_type = DOT11_BSSTYPE_ANY;
1114 	params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_ACTIVE);
1115 	params_le->channel_num = 0;
1116 	params_le->nprobes = cpu_to_le32(-1);
1117 	params_le->active_time = cpu_to_le32(-1);
1118 	params_le->passive_time = cpu_to_le32(-1);
1119 	params_le->home_time = cpu_to_le32(-1);
1120 	memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
1121 
1122 	/* Scan abort */
1123 	if (!request) {
1124 		length += sizeof(u16);
1125 		params_le->channel_num = cpu_to_le32(1);
1126 		params_le->channel_list[0] = cpu_to_le16(-1);
1127 		params_le->length = cpu_to_le16(length);
1128 		return;
1129 	}
1130 
1131 	n_ssids = request->n_ssids;
1132 	n_channels = request->n_channels;
1133 
1134 	/* Copy channel array if applicable */
1135 	brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1136 		  n_channels);
1137 	if (n_channels > 0) {
1138 		length += roundup(sizeof(u16) * n_channels, sizeof(u32));
1139 		for (i = 0; i < n_channels; i++) {
1140 			chanspec = channel_to_chanspec(&cfg->d11inf,
1141 						       request->channels[i]);
1142 			brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1143 				  request->channels[i]->hw_value, chanspec);
1144 			params_le->channel_list[i] = cpu_to_le16(chanspec);
1145 		}
1146 	} else {
1147 		brcmf_dbg(SCAN, "Scanning all channels\n");
1148 	}
1149 
1150 	/* Copy ssid array if applicable */
1151 	brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1152 	if (n_ssids > 0) {
1153 		offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) +
1154 				n_channels * sizeof(u16);
1155 		offset = roundup(offset, sizeof(u32));
1156 		length += sizeof(ssid_le) * n_ssids;
1157 		ptr = (char *)params_le + offset;
1158 		for (i = 0; i < n_ssids; i++) {
1159 			memset(&ssid_le, 0, sizeof(ssid_le));
1160 			ssid_le.SSID_len =
1161 					cpu_to_le32(request->ssids[i].ssid_len);
1162 			memcpy(ssid_le.SSID, request->ssids[i].ssid,
1163 			       request->ssids[i].ssid_len);
1164 			if (!ssid_le.SSID_len)
1165 				brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1166 			else
1167 				brcmf_dbg(SCAN, "%d: scan for  %.32s size=%d\n",
1168 					  i, ssid_le.SSID, ssid_le.SSID_len);
1169 			memcpy(ptr, &ssid_le, sizeof(ssid_le));
1170 			ptr += sizeof(ssid_le);
1171 		}
1172 	} else {
1173 		brcmf_dbg(SCAN, "Performing passive scan\n");
1174 		params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_PASSIVE);
1175 	}
1176 	params_le->length = cpu_to_le16(length);
1177 	/* Adding mask to channel numbers */
1178 	params_le->channel_num =
1179 		cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1180 			(n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1181 }
1182 
1183 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
1184 				struct brcmf_if *ifp, bool aborted,
1185 				bool fw_abort)
1186 {
1187 	struct brcmf_pub *drvr = cfg->pub;
1188 	struct brcmf_scan_params_v2_le params_v2_le;
1189 	struct cfg80211_scan_request *scan_request;
1190 	u64 reqid;
1191 	u32 bucket;
1192 	s32 err = 0;
1193 
1194 	brcmf_dbg(SCAN, "Enter\n");
1195 
1196 	/* clear scan request, because the FW abort can cause a second call */
1197 	/* to this functon and might cause a double cfg80211_scan_done      */
1198 	scan_request = cfg->scan_request;
1199 	cfg->scan_request = NULL;
1200 
1201 	timer_delete_sync(&cfg->escan_timeout);
1202 
1203 	if (fw_abort) {
1204 		/* Do a scan abort to stop the driver's scan engine */
1205 		brcmf_dbg(SCAN, "ABORT scan in firmware\n");
1206 
1207 		brcmf_escan_prep(cfg, &params_v2_le, NULL);
1208 
1209 		/* E-Scan (or anyother type) can be aborted by SCAN */
1210 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1211 			err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1212 						     &params_v2_le,
1213 						     sizeof(params_v2_le));
1214 		} else {
1215 			struct brcmf_scan_params_le params_le;
1216 
1217 			brcmf_scan_params_v2_to_v1(&params_v2_le, &params_le);
1218 			err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1219 						     &params_le,
1220 						     sizeof(params_le));
1221 		}
1222 
1223 		if (err)
1224 			bphy_err(drvr, "Scan abort failed\n");
1225 	}
1226 
1227 	brcmf_scan_config_mpc(ifp, 1);
1228 
1229 	/*
1230 	 * e-scan can be initiated internally
1231 	 * which takes precedence.
1232 	 */
1233 	if (cfg->int_escan_map) {
1234 		brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
1235 			  cfg->int_escan_map);
1236 		while (cfg->int_escan_map) {
1237 			bucket = __ffs(cfg->int_escan_map);
1238 			cfg->int_escan_map &= ~BIT(bucket);
1239 			reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
1240 							       bucket);
1241 			if (!aborted) {
1242 				brcmf_dbg(SCAN, "report results: reqid=%llu\n",
1243 					  reqid);
1244 				cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
1245 							    reqid);
1246 			}
1247 		}
1248 	} else if (scan_request) {
1249 		struct cfg80211_scan_info info = {
1250 			.aborted = aborted,
1251 		};
1252 
1253 		brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
1254 			  aborted ? "Aborted" : "Done");
1255 		cfg80211_scan_done(scan_request, &info);
1256 	}
1257 	if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
1258 		brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
1259 
1260 	return err;
1261 }
1262 
1263 static int brcmf_cfg80211_del_apsta_iface(struct wiphy *wiphy,
1264 					  struct wireless_dev *wdev)
1265 {
1266 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1267 	struct net_device *ndev = wdev->netdev;
1268 	struct brcmf_if *ifp = netdev_priv(ndev);
1269 	struct brcmf_pub *drvr = cfg->pub;
1270 	int ret;
1271 	int err;
1272 
1273 	brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
1274 
1275 	err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
1276 	if (err) {
1277 		bphy_err(drvr, "interface_remove failed %d\n", err);
1278 		goto err_unarm;
1279 	}
1280 
1281 	/* wait for firmware event */
1282 	ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
1283 					    BRCMF_VIF_EVENT_TIMEOUT);
1284 	if (!ret) {
1285 		bphy_err(drvr, "timeout occurred\n");
1286 		err = -EIO;
1287 		goto err_unarm;
1288 	}
1289 
1290 	brcmf_remove_interface(ifp, true);
1291 
1292 err_unarm:
1293 	brcmf_cfg80211_arm_vif_event(cfg, NULL);
1294 	return err;
1295 }
1296 
1297 static
1298 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
1299 {
1300 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1301 	struct net_device *ndev = wdev->netdev;
1302 
1303 	if (ndev && ndev == cfg_to_ndev(cfg))
1304 		return -ENOTSUPP;
1305 
1306 	/* vif event pending in firmware */
1307 	if (brcmf_cfg80211_vif_event_armed(cfg))
1308 		return -EBUSY;
1309 
1310 	if (ndev) {
1311 		if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
1312 		    cfg->escan_info.ifp == netdev_priv(ndev))
1313 			brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
1314 						    true, true);
1315 
1316 		brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
1317 	}
1318 
1319 	switch (wdev->iftype) {
1320 	case NL80211_IFTYPE_ADHOC:
1321 	case NL80211_IFTYPE_AP_VLAN:
1322 	case NL80211_IFTYPE_WDS:
1323 	case NL80211_IFTYPE_MESH_POINT:
1324 		return -EOPNOTSUPP;
1325 	case NL80211_IFTYPE_MONITOR:
1326 		return brcmf_mon_del_vif(wiphy, wdev);
1327 	case NL80211_IFTYPE_STATION:
1328 	case NL80211_IFTYPE_AP:
1329 		return brcmf_cfg80211_del_apsta_iface(wiphy, wdev);
1330 	case NL80211_IFTYPE_P2P_CLIENT:
1331 	case NL80211_IFTYPE_P2P_GO:
1332 	case NL80211_IFTYPE_P2P_DEVICE:
1333 		return brcmf_p2p_del_vif(wiphy, wdev);
1334 	case NL80211_IFTYPE_UNSPECIFIED:
1335 	default:
1336 		return -EINVAL;
1337 	}
1338 	return -EOPNOTSUPP;
1339 }
1340 
1341 static s32
1342 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1343 			 enum nl80211_iftype type,
1344 			 struct vif_params *params)
1345 {
1346 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1347 	struct brcmf_if *ifp = netdev_priv(ndev);
1348 	struct brcmf_cfg80211_vif *vif = ifp->vif;
1349 	struct brcmf_pub *drvr = cfg->pub;
1350 	s32 infra = 0;
1351 	s32 ap = 0;
1352 	s32 err = 0;
1353 
1354 	brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
1355 		  type);
1356 
1357 	/* WAR: There are a number of p2p interface related problems which
1358 	 * need to be handled initially (before doing the validate).
1359 	 * wpa_supplicant tends to do iface changes on p2p device/client/go
1360 	 * which are not always possible/allowed. However we need to return
1361 	 * OK otherwise the wpa_supplicant wont start. The situation differs
1362 	 * on configuration and setup (p2pon=1 module param). The first check
1363 	 * is to see if the request is a change to station for p2p iface.
1364 	 */
1365 	if ((type == NL80211_IFTYPE_STATION) &&
1366 	    ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
1367 	     (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
1368 	     (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
1369 		brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
1370 		/* Now depending on whether module param p2pon=1 was used the
1371 		 * response needs to be either 0 or EOPNOTSUPP. The reason is
1372 		 * that if p2pon=1 is used, but a newer supplicant is used then
1373 		 * we should return an error, as this combination wont work.
1374 		 * In other situations 0 is returned and supplicant will start
1375 		 * normally. It will give a trace in cfg80211, but it is the
1376 		 * only way to get it working. Unfortunately this will result
1377 		 * in situation where we wont support new supplicant in
1378 		 * combination with module param p2pon=1, but that is the way
1379 		 * it is. If the user tries this then unloading of driver might
1380 		 * fail/lock.
1381 		 */
1382 		if (cfg->p2p.p2pdev_dynamically)
1383 			return -EOPNOTSUPP;
1384 		else
1385 			return 0;
1386 	}
1387 	err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
1388 	if (err) {
1389 		bphy_err(drvr, "iface validation failed: err=%d\n", err);
1390 		return err;
1391 	}
1392 	switch (type) {
1393 	case NL80211_IFTYPE_MONITOR:
1394 	case NL80211_IFTYPE_WDS:
1395 		bphy_err(drvr, "type (%d) : currently we do not support this type\n",
1396 			 type);
1397 		return -EOPNOTSUPP;
1398 	case NL80211_IFTYPE_ADHOC:
1399 		infra = 0;
1400 		break;
1401 	case NL80211_IFTYPE_STATION:
1402 		infra = 1;
1403 		break;
1404 	case NL80211_IFTYPE_AP:
1405 	case NL80211_IFTYPE_P2P_GO:
1406 		ap = 1;
1407 		break;
1408 	default:
1409 		err = -EINVAL;
1410 		goto done;
1411 	}
1412 
1413 	if (ap) {
1414 		if (type == NL80211_IFTYPE_P2P_GO) {
1415 			brcmf_dbg(INFO, "IF Type = P2P GO\n");
1416 			err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
1417 		}
1418 		if (!err) {
1419 			brcmf_dbg(INFO, "IF Type = AP\n");
1420 		}
1421 	} else {
1422 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
1423 		if (err) {
1424 			bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
1425 			err = -EAGAIN;
1426 			goto done;
1427 		}
1428 		brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
1429 			  "Adhoc" : "Infra");
1430 	}
1431 	ndev->ieee80211_ptr->iftype = type;
1432 
1433 	brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
1434 
1435 done:
1436 	brcmf_dbg(TRACE, "Exit\n");
1437 
1438 	return err;
1439 }
1440 
1441 static s32
1442 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1443 		struct cfg80211_scan_request *request)
1444 {
1445 	struct brcmf_pub *drvr = cfg->pub;
1446 	s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1447 			  offsetof(struct brcmf_escan_params_le, params_v2_le);
1448 	struct brcmf_escan_params_le *params;
1449 	s32 err = 0;
1450 
1451 	brcmf_dbg(SCAN, "E-SCAN START\n");
1452 
1453 	if (request != NULL) {
1454 		/* Allocate space for populating ssids in struct */
1455 		params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1456 
1457 		/* Allocate space for populating ssids in struct */
1458 		params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1459 	}
1460 
1461 	params = kzalloc(params_size, GFP_KERNEL);
1462 	if (!params) {
1463 		err = -ENOMEM;
1464 		goto exit;
1465 	}
1466 	BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1467 	brcmf_escan_prep(cfg, &params->params_v2_le, request);
1468 
1469 	params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V2);
1470 
1471 	if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1472 		struct brcmf_escan_params_le *params_v1;
1473 
1474 		params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1475 		params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE;
1476 		params_v1 = kzalloc(params_size, GFP_KERNEL);
1477 		if (!params_v1) {
1478 			err = -ENOMEM;
1479 			goto exit_params;
1480 		}
1481 		params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1482 		brcmf_scan_params_v2_to_v1(&params->params_v2_le, &params_v1->params_le);
1483 		kfree(params);
1484 		params = params_v1;
1485 	}
1486 
1487 	params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1488 	params->sync_id = cpu_to_le16(0x1234);
1489 
1490 	err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1491 	if (err) {
1492 		if (err == -EBUSY)
1493 			brcmf_dbg(INFO, "system busy : escan canceled\n");
1494 		else
1495 			bphy_err(drvr, "error (%d)\n", err);
1496 	}
1497 
1498 exit_params:
1499 	kfree(params);
1500 exit:
1501 	return err;
1502 }
1503 
1504 static s32
1505 brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1506 {
1507 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1508 	s32 err;
1509 	struct brcmf_scan_results *results;
1510 	struct escan_info *escan = &cfg->escan_info;
1511 
1512 	brcmf_dbg(SCAN, "Enter\n");
1513 	escan->ifp = ifp;
1514 	escan->wiphy = cfg->wiphy;
1515 	escan->escan_state = WL_ESCAN_STATE_SCANNING;
1516 
1517 	brcmf_scan_config_mpc(ifp, 0);
1518 	results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1519 	results->version = 0;
1520 	results->count = 0;
1521 	results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1522 
1523 	err = escan->run(cfg, ifp, request);
1524 	if (err)
1525 		brcmf_scan_config_mpc(ifp, 1);
1526 	return err;
1527 }
1528 
1529 static s32
1530 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1531 {
1532 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1533 	struct brcmf_pub *drvr = cfg->pub;
1534 	struct brcmf_cfg80211_vif *vif;
1535 	s32 err = 0;
1536 
1537 	brcmf_dbg(TRACE, "Enter\n");
1538 	vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1539 	if (!check_vif_up(vif))
1540 		return -EIO;
1541 
1542 	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1543 		bphy_err(drvr, "Scanning already: status (%lu)\n",
1544 			 cfg->scan_status);
1545 		return -EAGAIN;
1546 	}
1547 	if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1548 		bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
1549 			 cfg->scan_status);
1550 		return -EAGAIN;
1551 	}
1552 	if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1553 		bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
1554 			 cfg->scan_status);
1555 		return -EAGAIN;
1556 	}
1557 	if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1558 		bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
1559 		return -EAGAIN;
1560 	}
1561 
1562 	brcmf_dbg(SCAN, "START ESCAN\n");
1563 
1564 	cfg->scan_request = request;
1565 	set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1566 
1567 	cfg->escan_info.run = brcmf_run_escan;
1568 	err = brcmf_p2p_scan_prep(wiphy, request, vif);
1569 	if (err)
1570 		goto scan_out;
1571 
1572 	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1573 				    request->ie, request->ie_len);
1574 	if (err)
1575 		goto scan_out;
1576 
1577 	/* If scan req comes for p2p0, send it over primary I/F */
1578 	if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1579 		vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1580 
1581 	err = brcmf_do_escan(vif->ifp, request);
1582 	if (err)
1583 		goto scan_out;
1584 
1585 	/* Arm scan timeout timer */
1586 	mod_timer(&cfg->escan_timeout,
1587 		  jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1588 
1589 	return 0;
1590 
1591 scan_out:
1592 	bphy_err(drvr, "scan error (%d)\n", err);
1593 	clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1594 	cfg->scan_request = NULL;
1595 	return err;
1596 }
1597 
1598 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1599 {
1600 	struct brcmf_if *ifp = netdev_priv(ndev);
1601 	struct brcmf_pub *drvr = ifp->drvr;
1602 	s32 err = 0;
1603 
1604 	err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
1605 	if (err)
1606 		bphy_err(drvr, "Error (%d)\n", err);
1607 
1608 	return err;
1609 }
1610 
1611 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1612 {
1613 	struct brcmf_if *ifp = netdev_priv(ndev);
1614 	struct brcmf_pub *drvr = ifp->drvr;
1615 	s32 err = 0;
1616 
1617 	err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
1618 				      frag_threshold);
1619 	if (err)
1620 		bphy_err(drvr, "Error (%d)\n", err);
1621 
1622 	return err;
1623 }
1624 
1625 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1626 {
1627 	struct brcmf_if *ifp = netdev_priv(ndev);
1628 	struct brcmf_pub *drvr = ifp->drvr;
1629 	s32 err = 0;
1630 	u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1631 
1632 	err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
1633 	if (err) {
1634 		bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
1635 		return err;
1636 	}
1637 	return err;
1638 }
1639 
1640 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
1641 					   u32 changed)
1642 {
1643 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1644 	struct net_device *ndev = cfg_to_ndev(cfg);
1645 	struct brcmf_if *ifp = netdev_priv(ndev);
1646 	s32 err = 0;
1647 
1648 	brcmf_dbg(TRACE, "Enter\n");
1649 	if (!check_vif_up(ifp->vif))
1650 		return -EIO;
1651 
1652 	if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1653 	    (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1654 		cfg->conf->rts_threshold = wiphy->rts_threshold;
1655 		err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1656 		if (!err)
1657 			goto done;
1658 	}
1659 	if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1660 	    (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1661 		cfg->conf->frag_threshold = wiphy->frag_threshold;
1662 		err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1663 		if (!err)
1664 			goto done;
1665 	}
1666 	if (changed & WIPHY_PARAM_RETRY_LONG
1667 	    && (cfg->conf->retry_long != wiphy->retry_long)) {
1668 		cfg->conf->retry_long = wiphy->retry_long;
1669 		err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1670 		if (!err)
1671 			goto done;
1672 	}
1673 	if (changed & WIPHY_PARAM_RETRY_SHORT
1674 	    && (cfg->conf->retry_short != wiphy->retry_short)) {
1675 		cfg->conf->retry_short = wiphy->retry_short;
1676 		err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1677 		if (!err)
1678 			goto done;
1679 	}
1680 
1681 done:
1682 	brcmf_dbg(TRACE, "Exit\n");
1683 	return err;
1684 }
1685 
1686 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1687 {
1688 	memset(prof, 0, sizeof(*prof));
1689 }
1690 
1691 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1692 {
1693 	u16 reason;
1694 
1695 	switch (e->event_code) {
1696 	case BRCMF_E_DEAUTH:
1697 	case BRCMF_E_DEAUTH_IND:
1698 	case BRCMF_E_DISASSOC_IND:
1699 		reason = e->reason;
1700 		break;
1701 	case BRCMF_E_LINK:
1702 	default:
1703 		reason = 0;
1704 		break;
1705 	}
1706 	return reason;
1707 }
1708 
1709 int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 flags)
1710 {
1711 	struct brcmf_pub *drvr = ifp->drvr;
1712 	struct brcmf_wsec_pmk_le pmk;
1713 	int err;
1714 
1715 	if (key_len > sizeof(pmk.key)) {
1716 		bphy_err(drvr, "key must be less than %zu bytes\n",
1717 			 sizeof(pmk.key));
1718 		return -EINVAL;
1719 	}
1720 
1721 	memset(&pmk, 0, sizeof(pmk));
1722 
1723 	/* pass key material directly */
1724 	pmk.key_len = cpu_to_le16(key_len);
1725 	pmk.flags = cpu_to_le16(flags);
1726 	memcpy(pmk.key, key, key_len);
1727 
1728 	/* store key material in firmware */
1729 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1730 				     &pmk, sizeof(pmk));
1731 	if (err < 0)
1732 		bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
1733 			 key_len);
1734 
1735 	return err;
1736 }
1737 BRCMF_EXPORT_SYMBOL_GPL(brcmf_set_wsec);
1738 
1739 static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1740 {
1741 	return brcmf_set_wsec(ifp, pmk_data, pmk_len, 0);
1742 }
1743 
1744 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
1745 			    bool locally_generated)
1746 {
1747 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1748 	struct brcmf_pub *drvr = cfg->pub;
1749 	bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP;
1750 	s32 err = 0;
1751 
1752 	brcmf_dbg(TRACE, "Enter\n");
1753 
1754 	if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1755 		if (bus_up) {
1756 			brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n");
1757 			err = brcmf_fil_cmd_data_set(vif->ifp,
1758 						     BRCMF_C_DISASSOC, NULL, 0);
1759 			if (err)
1760 				bphy_err(drvr, "WLC_DISASSOC failed (%d)\n",
1761 					 err);
1762 		}
1763 
1764 		if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1765 		    (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1766 			cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1767 					      locally_generated, GFP_KERNEL);
1768 	}
1769 	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1770 	clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
1771 	clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
1772 	clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1773 	brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1774 	if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1775 		if (bus_up)
1776 			brcmf_set_pmk(vif->ifp, NULL, 0);
1777 		vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1778 	}
1779 	brcmf_dbg(TRACE, "Exit\n");
1780 }
1781 
1782 static s32
1783 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1784 		      struct cfg80211_ibss_params *params)
1785 {
1786 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1787 	struct brcmf_if *ifp = netdev_priv(ndev);
1788 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1789 	struct brcmf_pub *drvr = cfg->pub;
1790 	struct brcmf_join_params join_params;
1791 	size_t join_params_size = 0;
1792 	s32 err = 0;
1793 	s32 wsec = 0;
1794 	s32 bcnprd;
1795 	u16 chanspec;
1796 	u32 ssid_len;
1797 
1798 	brcmf_dbg(TRACE, "Enter\n");
1799 	if (!check_vif_up(ifp->vif))
1800 		return -EIO;
1801 
1802 	if (params->ssid)
1803 		brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1804 	else {
1805 		brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1806 		return -EOPNOTSUPP;
1807 	}
1808 
1809 	set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1810 
1811 	if (params->bssid)
1812 		brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1813 	else
1814 		brcmf_dbg(CONN, "No BSSID specified\n");
1815 
1816 	if (params->chandef.chan)
1817 		brcmf_dbg(CONN, "channel: %d\n",
1818 			  params->chandef.chan->center_freq);
1819 	else
1820 		brcmf_dbg(CONN, "no channel specified\n");
1821 
1822 	if (params->channel_fixed)
1823 		brcmf_dbg(CONN, "fixed channel required\n");
1824 	else
1825 		brcmf_dbg(CONN, "no fixed channel required\n");
1826 
1827 	if (params->ie && params->ie_len)
1828 		brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1829 	else
1830 		brcmf_dbg(CONN, "no ie specified\n");
1831 
1832 	if (params->beacon_interval)
1833 		brcmf_dbg(CONN, "beacon interval: %d\n",
1834 			  params->beacon_interval);
1835 	else
1836 		brcmf_dbg(CONN, "no beacon interval specified\n");
1837 
1838 	if (params->basic_rates)
1839 		brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1840 	else
1841 		brcmf_dbg(CONN, "no basic rates specified\n");
1842 
1843 	if (params->privacy)
1844 		brcmf_dbg(CONN, "privacy required\n");
1845 	else
1846 		brcmf_dbg(CONN, "no privacy required\n");
1847 
1848 	/* Configure Privacy for starter */
1849 	if (params->privacy)
1850 		wsec |= WEP_ENABLED;
1851 
1852 	err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1853 	if (err) {
1854 		bphy_err(drvr, "wsec failed (%d)\n", err);
1855 		goto done;
1856 	}
1857 
1858 	/* Configure Beacon Interval for starter */
1859 	if (params->beacon_interval)
1860 		bcnprd = params->beacon_interval;
1861 	else
1862 		bcnprd = 100;
1863 
1864 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1865 	if (err) {
1866 		bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
1867 		goto done;
1868 	}
1869 
1870 	/* Configure required join parameter */
1871 	memset(&join_params, 0, sizeof(struct brcmf_join_params));
1872 
1873 	/* SSID */
1874 	ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1875 	memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1876 	join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1877 	join_params_size = sizeof(join_params.ssid_le);
1878 
1879 	/* BSSID */
1880 	if (params->bssid) {
1881 		memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1882 		join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1883 		memcpy(profile->bssid, params->bssid, ETH_ALEN);
1884 	} else {
1885 		eth_broadcast_addr(join_params.params_le.bssid);
1886 		eth_zero_addr(profile->bssid);
1887 	}
1888 
1889 	/* Channel */
1890 	if (params->chandef.chan) {
1891 		u32 target_channel;
1892 
1893 		cfg->channel =
1894 			ieee80211_frequency_to_channel(
1895 				params->chandef.chan->center_freq);
1896 		if (params->channel_fixed) {
1897 			/* adding chanspec */
1898 			chanspec = chandef_to_chanspec(&cfg->d11inf,
1899 						       &params->chandef);
1900 			join_params.params_le.chanspec_list[0] =
1901 				cpu_to_le16(chanspec);
1902 			join_params.params_le.chanspec_num = cpu_to_le32(1);
1903 			join_params_size += sizeof(join_params.params_le);
1904 		}
1905 
1906 		/* set channel for starter */
1907 		target_channel = cfg->channel;
1908 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1909 					    target_channel);
1910 		if (err) {
1911 			bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
1912 			goto done;
1913 		}
1914 	} else
1915 		cfg->channel = 0;
1916 
1917 	cfg->ibss_starter = false;
1918 
1919 
1920 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1921 				     &join_params, join_params_size);
1922 	if (err) {
1923 		bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
1924 		goto done;
1925 	}
1926 
1927 done:
1928 	if (err)
1929 		clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1930 	brcmf_dbg(TRACE, "Exit\n");
1931 	return err;
1932 }
1933 
1934 static s32
1935 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1936 {
1937 	struct brcmf_if *ifp = netdev_priv(ndev);
1938 
1939 	brcmf_dbg(TRACE, "Enter\n");
1940 	if (!check_vif_up(ifp->vif)) {
1941 		/* When driver is being unloaded, it can end up here. If an
1942 		 * error is returned then later on a debug trace in the wireless
1943 		 * core module will be printed. To avoid this 0 is returned.
1944 		 */
1945 		return 0;
1946 	}
1947 
1948 	brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
1949 	brcmf_net_setcarrier(ifp, false);
1950 
1951 	brcmf_dbg(TRACE, "Exit\n");
1952 
1953 	return 0;
1954 }
1955 
1956 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1957 				 struct cfg80211_connect_params *sme)
1958 {
1959 	struct brcmf_if *ifp = netdev_priv(ndev);
1960 	struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1961 	struct brcmf_pub *drvr = ifp->drvr;
1962 	struct brcmf_cfg80211_security *sec;
1963 	s32 val;
1964 	s32 err;
1965 
1966 	if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
1967 		val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1968 	} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
1969 		if (drvr->bus_if->fwvid == BRCMF_FWVENDOR_CYW &&
1970 		    sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_SAE)
1971 			val = WPA3_AUTH_SAE_PSK;
1972 		else
1973 			val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1974 	} else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3) {
1975 		val = WPA3_AUTH_SAE_PSK;
1976 	} else {
1977 		val = WPA_AUTH_DISABLED;
1978 	}
1979 	brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1980 	err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
1981 	if (err) {
1982 		bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
1983 		return err;
1984 	}
1985 	sec = &profile->sec;
1986 	sec->wpa_versions = sme->crypto.wpa_versions;
1987 	return err;
1988 }
1989 
1990 static s32 brcmf_set_auth_type(struct net_device *ndev,
1991 			       struct cfg80211_connect_params *sme)
1992 {
1993 	struct brcmf_if *ifp = netdev_priv(ndev);
1994 	struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1995 	struct brcmf_pub *drvr = ifp->drvr;
1996 	struct brcmf_cfg80211_security *sec;
1997 	s32 val = 0;
1998 	s32 err = 0;
1999 
2000 	switch (sme->auth_type) {
2001 	case NL80211_AUTHTYPE_OPEN_SYSTEM:
2002 		val = 0;
2003 		brcmf_dbg(CONN, "open system\n");
2004 		break;
2005 	case NL80211_AUTHTYPE_SHARED_KEY:
2006 		val = 1;
2007 		brcmf_dbg(CONN, "shared key\n");
2008 		break;
2009 	case NL80211_AUTHTYPE_SAE:
2010 		val = 3;
2011 		brcmf_dbg(CONN, "SAE authentication\n");
2012 		break;
2013 	default:
2014 		val = 2;
2015 		brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
2016 		break;
2017 	}
2018 
2019 	err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
2020 	if (err) {
2021 		bphy_err(drvr, "set auth failed (%d)\n", err);
2022 		return err;
2023 	}
2024 	sec = &profile->sec;
2025 	sec->auth_type = sme->auth_type;
2026 	return err;
2027 }
2028 
2029 static s32
2030 brcmf_set_wsec_mode(struct net_device *ndev,
2031 		    struct cfg80211_connect_params *sme)
2032 {
2033 	struct brcmf_if *ifp = netdev_priv(ndev);
2034 	struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2035 	struct brcmf_pub *drvr = ifp->drvr;
2036 	struct brcmf_cfg80211_security *sec;
2037 	s32 pval = 0;
2038 	s32 gval = 0;
2039 	s32 wsec;
2040 	s32 err = 0;
2041 
2042 	if (sme->crypto.n_ciphers_pairwise) {
2043 		switch (sme->crypto.ciphers_pairwise[0]) {
2044 		case WLAN_CIPHER_SUITE_WEP40:
2045 		case WLAN_CIPHER_SUITE_WEP104:
2046 			pval = WEP_ENABLED;
2047 			break;
2048 		case WLAN_CIPHER_SUITE_TKIP:
2049 			pval = TKIP_ENABLED;
2050 			break;
2051 		case WLAN_CIPHER_SUITE_CCMP:
2052 			pval = AES_ENABLED;
2053 			break;
2054 		case WLAN_CIPHER_SUITE_AES_CMAC:
2055 			pval = AES_ENABLED;
2056 			break;
2057 		default:
2058 			bphy_err(drvr, "invalid cipher pairwise (%d)\n",
2059 				 sme->crypto.ciphers_pairwise[0]);
2060 			return -EINVAL;
2061 		}
2062 	}
2063 	if (sme->crypto.cipher_group) {
2064 		switch (sme->crypto.cipher_group) {
2065 		case WLAN_CIPHER_SUITE_WEP40:
2066 		case WLAN_CIPHER_SUITE_WEP104:
2067 			gval = WEP_ENABLED;
2068 			break;
2069 		case WLAN_CIPHER_SUITE_TKIP:
2070 			gval = TKIP_ENABLED;
2071 			break;
2072 		case WLAN_CIPHER_SUITE_CCMP:
2073 			gval = AES_ENABLED;
2074 			break;
2075 		case WLAN_CIPHER_SUITE_AES_CMAC:
2076 			gval = AES_ENABLED;
2077 			break;
2078 		default:
2079 			bphy_err(drvr, "invalid cipher group (%d)\n",
2080 				 sme->crypto.cipher_group);
2081 			return -EINVAL;
2082 		}
2083 	}
2084 
2085 	brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
2086 	/* In case of privacy, but no security and WPS then simulate */
2087 	/* setting AES. WPS-2.0 allows no security                   */
2088 	if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
2089 	    sme->privacy)
2090 		pval = AES_ENABLED;
2091 
2092 	wsec = pval | gval;
2093 	err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2094 	if (err) {
2095 		bphy_err(drvr, "error (%d)\n", err);
2096 		return err;
2097 	}
2098 
2099 	sec = &profile->sec;
2100 	sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
2101 	sec->cipher_group = sme->crypto.cipher_group;
2102 
2103 	return err;
2104 }
2105 
2106 static s32
2107 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
2108 {
2109 	struct brcmf_if *ifp = netdev_priv(ndev);
2110 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2111 	struct brcmf_pub *drvr = ifp->drvr;
2112 	s32 val;
2113 	s32 err;
2114 	const struct brcmf_tlv *rsn_ie;
2115 	const u8 *ie;
2116 	u32 ie_len;
2117 	u32 offset;
2118 	u16 rsn_cap;
2119 	u32 mfp;
2120 	u16 count;
2121 
2122 	profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
2123 	profile->is_ft = false;
2124 
2125 	if (!sme->crypto.n_akm_suites)
2126 		return 0;
2127 
2128 	err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
2129 				       "wpa_auth", &val);
2130 	if (err) {
2131 		bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
2132 		return err;
2133 	}
2134 	if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
2135 		switch (sme->crypto.akm_suites[0]) {
2136 		case WLAN_AKM_SUITE_8021X:
2137 			val = WPA_AUTH_UNSPECIFIED;
2138 			if (sme->want_1x)
2139 				profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2140 			break;
2141 		case WLAN_AKM_SUITE_PSK:
2142 			val = WPA_AUTH_PSK;
2143 			break;
2144 		default:
2145 			bphy_err(drvr, "invalid akm suite (%d)\n",
2146 				 sme->crypto.akm_suites[0]);
2147 			return -EINVAL;
2148 		}
2149 	} else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
2150 		switch (sme->crypto.akm_suites[0]) {
2151 		case WLAN_AKM_SUITE_8021X:
2152 			val = WPA2_AUTH_UNSPECIFIED;
2153 			if (sme->want_1x)
2154 				profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2155 			break;
2156 		case WLAN_AKM_SUITE_8021X_SHA256:
2157 			val = WPA2_AUTH_1X_SHA256;
2158 			if (sme->want_1x)
2159 				profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2160 			break;
2161 		case WLAN_AKM_SUITE_PSK_SHA256:
2162 			val = WPA2_AUTH_PSK_SHA256;
2163 			break;
2164 		case WLAN_AKM_SUITE_PSK:
2165 			val = WPA2_AUTH_PSK;
2166 			break;
2167 		case WLAN_AKM_SUITE_FT_8021X:
2168 			val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
2169 			profile->is_ft = true;
2170 			if (sme->want_1x)
2171 				profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2172 			break;
2173 		case WLAN_AKM_SUITE_FT_PSK:
2174 			val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
2175 			profile->is_ft = true;
2176 			break;
2177 		default:
2178 			bphy_err(drvr, "invalid akm suite (%d)\n",
2179 				 sme->crypto.akm_suites[0]);
2180 			return -EINVAL;
2181 		}
2182 	} else if (val & WPA3_AUTH_SAE_PSK) {
2183 		switch (sme->crypto.akm_suites[0]) {
2184 		case WLAN_AKM_SUITE_SAE:
2185 			val = WPA3_AUTH_SAE_PSK;
2186 			break;
2187 		case WLAN_AKM_SUITE_FT_OVER_SAE:
2188 			val = WPA3_AUTH_SAE_PSK | WPA2_AUTH_FT;
2189 			profile->is_ft = true;
2190 			break;
2191 		default:
2192 			bphy_err(drvr, "invalid akm suite (%d)\n",
2193 				 sme->crypto.akm_suites[0]);
2194 			return -EINVAL;
2195 		}
2196 		if (sme->crypto.sae_pwd) {
2197 			profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
2198 		}
2199 	}
2200 
2201 	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
2202 		brcmf_dbg(INFO, "using 1X offload\n");
2203 	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE)
2204 		brcmf_dbg(INFO, "using SAE offload\n");
2205 
2206 	if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2207 		goto skip_mfp_config;
2208 	/* The MFP mode (1 or 2) needs to be determined, parse IEs. The
2209 	 * IE will not be verified, just a quick search for MFP config
2210 	 */
2211 	rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
2212 				  WLAN_EID_RSN);
2213 	if (!rsn_ie)
2214 		goto skip_mfp_config;
2215 	ie = (const u8 *)rsn_ie;
2216 	ie_len = rsn_ie->len + TLV_HDR_LEN;
2217 	/* Skip unicast suite */
2218 	offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
2219 	if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
2220 		goto skip_mfp_config;
2221 	/* Skip multicast suite */
2222 	count = ie[offset] + (ie[offset + 1] << 8);
2223 	offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
2224 	if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
2225 		goto skip_mfp_config;
2226 	/* Skip auth key management suite(s) */
2227 	count = ie[offset] + (ie[offset + 1] << 8);
2228 	offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
2229 	if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
2230 		goto skip_mfp_config;
2231 	/* Ready to read capabilities */
2232 	mfp = BRCMF_MFP_NONE;
2233 	rsn_cap = ie[offset] + (ie[offset + 1] << 8);
2234 	if (rsn_cap & RSN_CAP_MFPR_MASK)
2235 		mfp = BRCMF_MFP_REQUIRED;
2236 	else if (rsn_cap & RSN_CAP_MFPC_MASK)
2237 		mfp = BRCMF_MFP_CAPABLE;
2238 	brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
2239 
2240 skip_mfp_config:
2241 	brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
2242 	err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
2243 	if (err) {
2244 		bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
2245 		return err;
2246 	}
2247 
2248 	return err;
2249 }
2250 
2251 static s32
2252 brcmf_set_sharedkey(struct net_device *ndev,
2253 		    struct cfg80211_connect_params *sme)
2254 {
2255 	struct brcmf_if *ifp = netdev_priv(ndev);
2256 	struct brcmf_pub *drvr = ifp->drvr;
2257 	struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2258 	struct brcmf_cfg80211_security *sec;
2259 	struct brcmf_wsec_key key;
2260 	s32 val;
2261 	s32 err = 0;
2262 
2263 	brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
2264 
2265 	if (sme->key_len == 0)
2266 		return 0;
2267 
2268 	sec = &profile->sec;
2269 	brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
2270 		  sec->wpa_versions, sec->cipher_pairwise);
2271 
2272 	if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2 |
2273 				 NL80211_WPA_VERSION_3))
2274 		return 0;
2275 
2276 	if (!(sec->cipher_pairwise &
2277 	    (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
2278 		return 0;
2279 
2280 	memset(&key, 0, sizeof(key));
2281 	key.len = (u32) sme->key_len;
2282 	key.index = (u32) sme->key_idx;
2283 	if (key.len > sizeof(key.data)) {
2284 		bphy_err(drvr, "Too long key length (%u)\n", key.len);
2285 		return -EINVAL;
2286 	}
2287 	memcpy(key.data, sme->key, key.len);
2288 	key.flags = BRCMF_PRIMARY_KEY;
2289 	switch (sec->cipher_pairwise) {
2290 	case WLAN_CIPHER_SUITE_WEP40:
2291 		key.algo = CRYPTO_ALGO_WEP1;
2292 		break;
2293 	case WLAN_CIPHER_SUITE_WEP104:
2294 		key.algo = CRYPTO_ALGO_WEP128;
2295 		break;
2296 	default:
2297 		bphy_err(drvr, "Invalid algorithm (%d)\n",
2298 			 sme->crypto.ciphers_pairwise[0]);
2299 		return -EINVAL;
2300 	}
2301 	/* Set the new key/index */
2302 	brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
2303 		  key.len, key.index, key.algo);
2304 	brcmf_dbg(CONN, "key \"%s\"\n", key.data);
2305 	err = send_key_to_dongle(ifp, &key);
2306 	if (err)
2307 		return err;
2308 
2309 	if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
2310 		brcmf_dbg(CONN, "set auth_type to shared key\n");
2311 		val = WL_AUTH_SHARED_KEY;	/* shared key */
2312 		err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
2313 		if (err)
2314 			bphy_err(drvr, "set auth failed (%d)\n", err);
2315 	}
2316 	return err;
2317 }
2318 
2319 static
2320 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
2321 					   enum nl80211_auth_type type)
2322 {
2323 	if (type == NL80211_AUTHTYPE_AUTOMATIC &&
2324 	    brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
2325 		brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
2326 		type = NL80211_AUTHTYPE_OPEN_SYSTEM;
2327 	}
2328 	return type;
2329 }
2330 
2331 static void brcmf_set_join_pref(struct brcmf_if *ifp,
2332 				struct cfg80211_bss_selection *bss_select)
2333 {
2334 	struct brcmf_pub *drvr = ifp->drvr;
2335 	struct brcmf_join_pref_params join_pref_params[2];
2336 	enum nl80211_band band;
2337 	int err, i = 0;
2338 
2339 	join_pref_params[i].len = 2;
2340 	join_pref_params[i].rssi_gain = 0;
2341 
2342 	if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
2343 		brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
2344 
2345 	switch (bss_select->behaviour) {
2346 	case __NL80211_BSS_SELECT_ATTR_INVALID:
2347 		brcmf_c_set_joinpref_default(ifp);
2348 		return;
2349 	case NL80211_BSS_SELECT_ATTR_BAND_PREF:
2350 		join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
2351 		band = bss_select->param.band_pref;
2352 		join_pref_params[i].band = nl80211_band_to_fwil(band);
2353 		i++;
2354 		break;
2355 	case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
2356 		join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
2357 		band = bss_select->param.adjust.band;
2358 		join_pref_params[i].band = nl80211_band_to_fwil(band);
2359 		join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
2360 		i++;
2361 		break;
2362 	case NL80211_BSS_SELECT_ATTR_RSSI:
2363 	default:
2364 		break;
2365 	}
2366 	join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
2367 	join_pref_params[i].len = 2;
2368 	join_pref_params[i].rssi_gain = 0;
2369 	join_pref_params[i].band = 0;
2370 	err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
2371 				       sizeof(join_pref_params));
2372 	if (err)
2373 		bphy_err(drvr, "Set join_pref error (%d)\n", err);
2374 }
2375 
2376 static s32
2377 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
2378 		       struct cfg80211_connect_params *sme)
2379 {
2380 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2381 	struct brcmf_if *ifp = netdev_priv(ndev);
2382 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2383 	struct ieee80211_channel *chan = sme->channel;
2384 	struct brcmf_pub *drvr = ifp->drvr;
2385 	struct brcmf_join_params join_params;
2386 	size_t join_params_size;
2387 	const struct brcmf_tlv *rsn_ie;
2388 	const struct brcmf_vs_tlv *wpa_ie;
2389 	const void *ie;
2390 	u32 ie_len;
2391 	struct brcmf_ext_join_params_le *ext_join_params;
2392 	u16 chanspec;
2393 	s32 err = 0;
2394 	u32 ssid_len;
2395 
2396 	brcmf_dbg(TRACE, "Enter\n");
2397 	if (!check_vif_up(ifp->vif))
2398 		return -EIO;
2399 
2400 	if (!sme->ssid) {
2401 		bphy_err(drvr, "Invalid ssid\n");
2402 		return -EOPNOTSUPP;
2403 	}
2404 
2405 	if (sme->channel_hint)
2406 		chan = sme->channel_hint;
2407 
2408 	if (sme->bssid_hint)
2409 		sme->bssid = sme->bssid_hint;
2410 
2411 	if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
2412 		/* A normal (non P2P) connection request setup. */
2413 		ie = NULL;
2414 		ie_len = 0;
2415 		/* find the WPA_IE */
2416 		wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
2417 		if (wpa_ie) {
2418 			ie = wpa_ie;
2419 			ie_len = wpa_ie->len + TLV_HDR_LEN;
2420 		} else {
2421 			/* find the RSN_IE */
2422 			rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
2423 						  sme->ie_len,
2424 						  WLAN_EID_RSN);
2425 			if (rsn_ie) {
2426 				ie = rsn_ie;
2427 				ie_len = rsn_ie->len + TLV_HDR_LEN;
2428 			}
2429 		}
2430 		brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
2431 	}
2432 
2433 	err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
2434 				    sme->ie, sme->ie_len);
2435 	if (err)
2436 		bphy_err(drvr, "Set Assoc REQ IE Failed\n");
2437 	else
2438 		brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
2439 
2440 	set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2441 
2442 	if (chan) {
2443 		cfg->channel =
2444 			ieee80211_frequency_to_channel(chan->center_freq);
2445 		chanspec = channel_to_chanspec(&cfg->d11inf, chan);
2446 		brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
2447 			  cfg->channel, chan->center_freq, chanspec);
2448 	} else {
2449 		cfg->channel = 0;
2450 		chanspec = 0;
2451 	}
2452 
2453 	brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
2454 
2455 	err = brcmf_set_wpa_version(ndev, sme);
2456 	if (err) {
2457 		bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
2458 		goto done;
2459 	}
2460 
2461 	sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
2462 	err = brcmf_set_auth_type(ndev, sme);
2463 	if (err) {
2464 		bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
2465 		goto done;
2466 	}
2467 
2468 	err = brcmf_set_wsec_mode(ndev, sme);
2469 	if (err) {
2470 		bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
2471 		goto done;
2472 	}
2473 
2474 	err = brcmf_set_key_mgmt(ndev, sme);
2475 	if (err) {
2476 		bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
2477 		goto done;
2478 	}
2479 
2480 	err = brcmf_set_sharedkey(ndev, sme);
2481 	if (err) {
2482 		bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
2483 		goto done;
2484 	}
2485 
2486 	if (sme->crypto.psk &&
2487 	    profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
2488 		if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
2489 			err = -EINVAL;
2490 			goto done;
2491 		}
2492 		brcmf_dbg(INFO, "using PSK offload\n");
2493 		profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
2494 	}
2495 
2496 	if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
2497 		/* enable firmware supplicant for this interface */
2498 		err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
2499 		if (err < 0) {
2500 			bphy_err(drvr, "failed to enable fw supplicant\n");
2501 			goto done;
2502 		}
2503 	}
2504 
2505 	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
2506 		err = brcmf_set_pmk(ifp, sme->crypto.psk,
2507 				    BRCMF_WSEC_MAX_PSK_LEN);
2508 	else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
2509 		/* clean up user-space RSNE */
2510 		err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
2511 		if (err) {
2512 			bphy_err(drvr, "failed to clean up user-space RSNE\n");
2513 			goto done;
2514 		}
2515 		err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
2516 		if (!err && sme->crypto.psk)
2517 			err = brcmf_set_pmk(ifp, sme->crypto.psk,
2518 					    BRCMF_WSEC_MAX_PSK_LEN);
2519 	}
2520 	if (err)
2521 		goto done;
2522 
2523 	/* Join with specific BSSID and cached SSID
2524 	 * If SSID is zero join based on BSSID only
2525 	 */
2526 	join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2527 		offsetof(struct brcmf_assoc_params_le, chanspec_list);
2528 	if (cfg->channel)
2529 		join_params_size += sizeof(u16);
2530 	ext_join_params = kzalloc_obj(*ext_join_params);
2531 	if (ext_join_params == NULL) {
2532 		err = -ENOMEM;
2533 		goto done;
2534 	}
2535 	ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2536 	ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2537 	memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2538 	if (ssid_len < IEEE80211_MAX_SSID_LEN)
2539 		brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2540 			  ext_join_params->ssid_le.SSID, ssid_len);
2541 
2542 	/* Set up join scan parameters */
2543 	ext_join_params->scan_le.scan_type = -1;
2544 	ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2545 
2546 	if (sme->bssid)
2547 		memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2548 	else
2549 		eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2550 
2551 	if (cfg->channel) {
2552 		ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2553 
2554 		ext_join_params->assoc_le.chanspec_list[0] =
2555 			cpu_to_le16(chanspec);
2556 		/* Increase dwell time to receive probe response or detect
2557 		 * beacon from target AP at a noisy air only during connect
2558 		 * command.
2559 		 */
2560 		ext_join_params->scan_le.active_time =
2561 			cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2562 		ext_join_params->scan_le.passive_time =
2563 			cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2564 		/* To sync with presence period of VSDB GO send probe request
2565 		 * more frequently. Probe request will be stopped when it gets
2566 		 * probe response from target AP/GO.
2567 		 */
2568 		ext_join_params->scan_le.nprobes =
2569 			cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2570 				    BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2571 	} else {
2572 		ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2573 		ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2574 		ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2575 	}
2576 
2577 	brcmf_set_join_pref(ifp, &sme->bss_select);
2578 
2579 	err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2580 					 join_params_size);
2581 	kfree(ext_join_params);
2582 	if (!err)
2583 		/* This is it. join command worked, we are done */
2584 		goto done;
2585 
2586 	/* join command failed, fallback to set ssid */
2587 	memset(&join_params, 0, sizeof(join_params));
2588 	join_params_size = sizeof(join_params.ssid_le);
2589 
2590 	memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2591 	join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2592 
2593 	if (sme->bssid)
2594 		memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2595 	else
2596 		eth_broadcast_addr(join_params.params_le.bssid);
2597 
2598 	if (cfg->channel) {
2599 		join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2600 		join_params.params_le.chanspec_num = cpu_to_le32(1);
2601 		join_params_size += sizeof(join_params.params_le);
2602 	}
2603 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2604 				     &join_params, join_params_size);
2605 	if (err)
2606 		bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
2607 
2608 done:
2609 	if (err)
2610 		clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2611 	brcmf_dbg(TRACE, "Exit\n");
2612 	return err;
2613 }
2614 
2615 static s32
2616 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2617 		       u16 reason_code)
2618 {
2619 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2620 	struct brcmf_if *ifp = netdev_priv(ndev);
2621 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2622 	struct brcmf_pub *drvr = cfg->pub;
2623 	struct brcmf_scb_val_le scbval;
2624 	s32 err = 0;
2625 
2626 	brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2627 	if (!check_vif_up(ifp->vif))
2628 		return -EIO;
2629 
2630 	clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2631 	clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2632 	clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &ifp->vif->sme_state);
2633 	clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &ifp->vif->sme_state);
2634 	cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2635 
2636 	memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2637 	scbval.val = cpu_to_le32(reason_code);
2638 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2639 				     &scbval, sizeof(scbval));
2640 	if (err)
2641 		bphy_err(drvr, "error (%d)\n", err);
2642 
2643 	brcmf_dbg(TRACE, "Exit\n");
2644 	return err;
2645 }
2646 
2647 static s32
2648 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2649 			    int radio_idx, enum nl80211_tx_power_setting type,
2650 			    s32 mbm)
2651 {
2652 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2653 	struct net_device *ndev = cfg_to_ndev(cfg);
2654 	struct brcmf_if *ifp = netdev_priv(ndev);
2655 	struct brcmf_pub *drvr = cfg->pub;
2656 	s32 err;
2657 	s32 disable;
2658 	u32 qdbm = 127;
2659 
2660 	brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2661 	if (!check_vif_up(ifp->vif))
2662 		return -EIO;
2663 
2664 	switch (type) {
2665 	case NL80211_TX_POWER_AUTOMATIC:
2666 		break;
2667 	case NL80211_TX_POWER_LIMITED:
2668 	case NL80211_TX_POWER_FIXED:
2669 		if (mbm < 0) {
2670 			bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
2671 			err = -EINVAL;
2672 			goto done;
2673 		}
2674 		qdbm =  MBM_TO_DBM(4 * mbm);
2675 		if (qdbm > 127)
2676 			qdbm = 127;
2677 		qdbm |= WL_TXPWR_OVERRIDE;
2678 		break;
2679 	default:
2680 		bphy_err(drvr, "Unsupported type %d\n", type);
2681 		err = -EINVAL;
2682 		goto done;
2683 	}
2684 	/* Make sure radio is off or on as far as software is concerned */
2685 	disable = WL_RADIO_SW_DISABLE << 16;
2686 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2687 	if (err)
2688 		bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
2689 
2690 	err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2691 	if (err)
2692 		bphy_err(drvr, "qtxpower error (%d)\n", err);
2693 
2694 done:
2695 	brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2696 	return err;
2697 }
2698 
2699 static s32
2700 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2701 			    int radio_idx, unsigned int link_id, s32 *dbm)
2702 {
2703 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2704 	struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2705 	struct brcmf_pub *drvr = cfg->pub;
2706 	s32 qdbm;
2707 	s32 err;
2708 
2709 	brcmf_dbg(TRACE, "Enter\n");
2710 	if (!check_vif_up(vif))
2711 		return -EIO;
2712 
2713 	err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2714 	if (err) {
2715 		bphy_err(drvr, "error (%d)\n", err);
2716 		goto done;
2717 	}
2718 	*dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2719 
2720 done:
2721 	brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2722 	return err;
2723 }
2724 
2725 static s32
2726 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2727 				  int link_id, u8 key_idx, bool unicast,
2728 				  bool multicast)
2729 {
2730 	struct brcmf_if *ifp = netdev_priv(ndev);
2731 	struct brcmf_pub *drvr = ifp->drvr;
2732 	u32 index;
2733 	u32 wsec;
2734 	s32 err = 0;
2735 
2736 	brcmf_dbg(TRACE, "Enter\n");
2737 	brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2738 	if (!check_vif_up(ifp->vif))
2739 		return -EIO;
2740 
2741 	err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2742 	if (err) {
2743 		bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2744 		goto done;
2745 	}
2746 
2747 	if (wsec & WEP_ENABLED) {
2748 		/* Just select a new current key */
2749 		index = key_idx;
2750 		err = brcmf_fil_cmd_int_set(ifp,
2751 					    BRCMF_C_SET_KEY_PRIMARY, index);
2752 		if (err)
2753 			bphy_err(drvr, "error (%d)\n", err);
2754 	}
2755 done:
2756 	brcmf_dbg(TRACE, "Exit\n");
2757 	return err;
2758 }
2759 
2760 static s32
2761 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct wireless_dev *wdev,
2762 		       int link_id, u8 key_idx, bool pairwise,
2763 		       const u8 *mac_addr)
2764 {
2765 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
2766 	struct brcmf_wsec_key *key;
2767 	s32 err;
2768 
2769 	brcmf_dbg(TRACE, "Enter\n");
2770 	brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2771 
2772 	if (!check_vif_up(ifp->vif))
2773 		return -EIO;
2774 
2775 	if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2776 		/* we ignore this key index in this case */
2777 		return -EINVAL;
2778 	}
2779 
2780 	key = &ifp->vif->profile.key[key_idx];
2781 
2782 	if (key->algo == CRYPTO_ALGO_OFF) {
2783 		brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2784 		return -EINVAL;
2785 	}
2786 
2787 	memset(key, 0, sizeof(*key));
2788 	key->index = (u32)key_idx;
2789 	key->flags = BRCMF_PRIMARY_KEY;
2790 
2791 	/* Clear the key/index */
2792 	err = send_key_to_dongle(ifp, key);
2793 
2794 	brcmf_dbg(TRACE, "Exit\n");
2795 	return err;
2796 }
2797 
2798 static s32
2799 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct wireless_dev *wdev,
2800 		       int link_id, u8 key_idx, bool pairwise,
2801 		       const u8 *mac_addr, struct key_params *params)
2802 {
2803 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2804 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
2805 	struct brcmf_pub *drvr = cfg->pub;
2806 	struct brcmf_wsec_key *key;
2807 	s32 val;
2808 	s32 wsec;
2809 	s32 err;
2810 	u8 keybuf[8];
2811 	bool ext_key;
2812 
2813 	brcmf_dbg(TRACE, "Enter\n");
2814 	brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2815 	if (!check_vif_up(ifp->vif))
2816 		return -EIO;
2817 
2818 	if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2819 		/* we ignore this key index in this case */
2820 		bphy_err(drvr, "invalid key index (%d)\n", key_idx);
2821 		return -EINVAL;
2822 	}
2823 
2824 	if (params->key_len == 0)
2825 		return brcmf_cfg80211_del_key(wiphy, wdev, -1, key_idx,
2826 					      pairwise, mac_addr);
2827 
2828 	if (params->key_len > sizeof(key->data)) {
2829 		bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
2830 		return -EINVAL;
2831 	}
2832 
2833 	ext_key = false;
2834 	if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2835 	    (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2836 		brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2837 		ext_key = true;
2838 	}
2839 
2840 	key = &ifp->vif->profile.key[key_idx];
2841 	memset(key, 0, sizeof(*key));
2842 	if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2843 		memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2844 	key->len = params->key_len;
2845 	key->index = key_idx;
2846 	memcpy(key->data, params->key, key->len);
2847 	if (!ext_key)
2848 		key->flags = BRCMF_PRIMARY_KEY;
2849 
2850 	if (params->seq && params->seq_len == 6) {
2851 		/* rx iv */
2852 		u8 *ivptr;
2853 
2854 		ivptr = (u8 *)params->seq;
2855 		key->rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2856 			(ivptr[3] << 8) | ivptr[2];
2857 		key->rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2858 		key->iv_initialized = true;
2859 	}
2860 
2861 	switch (params->cipher) {
2862 	case WLAN_CIPHER_SUITE_WEP40:
2863 		key->algo = CRYPTO_ALGO_WEP1;
2864 		val = WEP_ENABLED;
2865 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2866 		break;
2867 	case WLAN_CIPHER_SUITE_WEP104:
2868 		key->algo = CRYPTO_ALGO_WEP128;
2869 		val = WEP_ENABLED;
2870 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2871 		break;
2872 	case WLAN_CIPHER_SUITE_TKIP:
2873 		if (!brcmf_is_apmode(ifp->vif)) {
2874 			brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2875 			memcpy(keybuf, &key->data[24], sizeof(keybuf));
2876 			memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2877 			memcpy(&key->data[16], keybuf, sizeof(keybuf));
2878 		}
2879 		key->algo = CRYPTO_ALGO_TKIP;
2880 		val = TKIP_ENABLED;
2881 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2882 		break;
2883 	case WLAN_CIPHER_SUITE_AES_CMAC:
2884 		key->algo = CRYPTO_ALGO_AES_CCM;
2885 		val = AES_ENABLED;
2886 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2887 		break;
2888 	case WLAN_CIPHER_SUITE_CCMP:
2889 		key->algo = CRYPTO_ALGO_AES_CCM;
2890 		val = AES_ENABLED;
2891 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2892 		break;
2893 	default:
2894 		bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
2895 		err = -EINVAL;
2896 		goto done;
2897 	}
2898 
2899 	err = send_key_to_dongle(ifp, key);
2900 	if (ext_key || err)
2901 		goto done;
2902 
2903 	err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2904 	if (err) {
2905 		bphy_err(drvr, "get wsec error (%d)\n", err);
2906 		goto done;
2907 	}
2908 	wsec |= val;
2909 	err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2910 	if (err) {
2911 		bphy_err(drvr, "set wsec error (%d)\n", err);
2912 		goto done;
2913 	}
2914 
2915 done:
2916 	brcmf_dbg(TRACE, "Exit\n");
2917 	return err;
2918 }
2919 
2920 static s32
2921 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct wireless_dev *wdev,
2922 		       int link_id, u8 key_idx, bool pairwise,
2923 		       const u8 *mac_addr, void *cookie,
2924 		       void (*callback)(void *cookie,
2925 					struct key_params *params))
2926 {
2927 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2928 	struct key_params params;
2929 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
2930 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2931 	struct brcmf_pub *drvr = cfg->pub;
2932 	struct brcmf_cfg80211_security *sec;
2933 	s32 wsec;
2934 	s32 err = 0;
2935 
2936 	brcmf_dbg(TRACE, "Enter\n");
2937 	brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2938 	if (!check_vif_up(ifp->vif))
2939 		return -EIO;
2940 
2941 	memset(&params, 0, sizeof(params));
2942 
2943 	err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2944 	if (err) {
2945 		bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2946 		/* Ignore this error, may happen during DISASSOC */
2947 		err = -EAGAIN;
2948 		goto done;
2949 	}
2950 	if (wsec & WEP_ENABLED) {
2951 		sec = &profile->sec;
2952 		if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2953 			params.cipher = WLAN_CIPHER_SUITE_WEP40;
2954 			brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2955 		} else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2956 			params.cipher = WLAN_CIPHER_SUITE_WEP104;
2957 			brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2958 		}
2959 	} else if (wsec & TKIP_ENABLED) {
2960 		params.cipher = WLAN_CIPHER_SUITE_TKIP;
2961 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2962 	} else if (wsec & AES_ENABLED) {
2963 		params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2964 		brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2965 	} else  {
2966 		bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
2967 		err = -EINVAL;
2968 		goto done;
2969 	}
2970 	callback(cookie, &params);
2971 
2972 done:
2973 	brcmf_dbg(TRACE, "Exit\n");
2974 	return err;
2975 }
2976 
2977 static s32
2978 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2979 				       struct wireless_dev *wdev, int link_id,
2980 				       u8 key_idx)
2981 {
2982 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
2983 
2984 	brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2985 
2986 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2987 		return 0;
2988 
2989 	brcmf_dbg(INFO, "Not supported\n");
2990 
2991 	return -EOPNOTSUPP;
2992 }
2993 
2994 static void
2995 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2996 {
2997 	struct brcmf_pub *drvr = ifp->drvr;
2998 	s32 err;
2999 	u8 key_idx;
3000 	struct brcmf_wsec_key *key;
3001 	s32 wsec;
3002 
3003 	for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
3004 		key = &ifp->vif->profile.key[key_idx];
3005 		if ((key->algo == CRYPTO_ALGO_WEP1) ||
3006 		    (key->algo == CRYPTO_ALGO_WEP128))
3007 			break;
3008 	}
3009 	if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
3010 		return;
3011 
3012 	err = send_key_to_dongle(ifp, key);
3013 	if (err) {
3014 		bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
3015 		return;
3016 	}
3017 	err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
3018 	if (err) {
3019 		bphy_err(drvr, "get wsec error (%d)\n", err);
3020 		return;
3021 	}
3022 	wsec |= WEP_ENABLED;
3023 	err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3024 	if (err)
3025 		bphy_err(drvr, "set wsec error (%d)\n", err);
3026 }
3027 
3028 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
3029 {
3030 	struct nl80211_sta_flag_update *sfu;
3031 
3032 	brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
3033 	si->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS);
3034 	sfu = &si->sta_flags;
3035 	sfu->mask = BIT(NL80211_STA_FLAG_WME) |
3036 		    BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3037 		    BIT(NL80211_STA_FLAG_ASSOCIATED) |
3038 		    BIT(NL80211_STA_FLAG_AUTHORIZED);
3039 	if (fw_sta_flags & BRCMF_STA_WME)
3040 		sfu->set |= BIT(NL80211_STA_FLAG_WME);
3041 	if (fw_sta_flags & BRCMF_STA_AUTHE)
3042 		sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
3043 	if (fw_sta_flags & BRCMF_STA_ASSOC)
3044 		sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
3045 	if (fw_sta_flags & BRCMF_STA_AUTHO)
3046 		sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
3047 }
3048 
3049 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
3050 {
3051 	struct brcmf_pub *drvr = ifp->drvr;
3052 	struct {
3053 		__le32 len;
3054 		struct brcmf_bss_info_le bss_le;
3055 	} *buf;
3056 	u16 capability;
3057 	int err;
3058 
3059 	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3060 	if (!buf)
3061 		return;
3062 
3063 	buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
3064 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
3065 				     WL_BSS_INFO_MAX);
3066 	if (err) {
3067 		bphy_err(drvr, "Failed to get bss info (%d)\n", err);
3068 		goto out_kfree;
3069 	}
3070 	si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
3071 	si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
3072 	si->bss_param.dtim_period = buf->bss_le.dtim_period;
3073 	capability = le16_to_cpu(buf->bss_le.capability);
3074 	if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
3075 		si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
3076 	if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3077 		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
3078 	if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
3079 		si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
3080 
3081 out_kfree:
3082 	kfree(buf);
3083 }
3084 
3085 static s32
3086 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
3087 				struct station_info *sinfo)
3088 {
3089 	struct brcmf_pub *drvr = ifp->drvr;
3090 	struct brcmf_scb_val_le scbval;
3091 	struct brcmf_pktcnt_le pktcnt;
3092 	s32 err;
3093 	u32 rate;
3094 	u32 rssi;
3095 
3096 	/* Get the current tx rate */
3097 	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
3098 	if (err < 0) {
3099 		bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
3100 		return err;
3101 	}
3102 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
3103 	sinfo->txrate.legacy = rate * 5;
3104 
3105 	memset(&scbval, 0, sizeof(scbval));
3106 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
3107 				     sizeof(scbval));
3108 	if (err) {
3109 		bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
3110 		return err;
3111 	}
3112 	rssi = le32_to_cpu(scbval.val);
3113 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3114 	sinfo->signal = rssi;
3115 
3116 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
3117 				     sizeof(pktcnt));
3118 	if (err) {
3119 		bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
3120 		return err;
3121 	}
3122 	sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
3123 			 BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
3124 			 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
3125 			 BIT_ULL(NL80211_STA_INFO_TX_FAILED);
3126 	sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
3127 	sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
3128 	sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
3129 	sinfo->tx_failed  = le32_to_cpu(pktcnt.tx_bad_pkt);
3130 
3131 	return 0;
3132 }
3133 
3134 static s32
3135 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct wireless_dev *wdev,
3136 			   const u8 *mac, struct station_info *sinfo)
3137 {
3138 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3139 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3140 	struct brcmf_pub *drvr = cfg->pub;
3141 	struct brcmf_scb_val_le scb_val;
3142 	s32 err = 0;
3143 	struct brcmf_sta_info_le sta_info_le;
3144 	u32 sta_flags;
3145 	u32 is_tdls_peer;
3146 	s32 total_rssi_avg = 0;
3147 	s32 total_rssi = 0;
3148 	s32 count_rssi = 0;
3149 	int rssi;
3150 	u32 i;
3151 
3152 	brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
3153 	if (!check_vif_up(ifp->vif))
3154 		return -EIO;
3155 
3156 	if (brcmf_is_ibssmode(ifp->vif))
3157 		return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
3158 
3159 	memset(&sta_info_le, 0, sizeof(sta_info_le));
3160 	memcpy(&sta_info_le, mac, ETH_ALEN);
3161 	err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
3162 				       &sta_info_le,
3163 				       sizeof(sta_info_le));
3164 	is_tdls_peer = !err;
3165 	if (err) {
3166 		err = brcmf_fil_iovar_data_get(ifp, "sta_info",
3167 					       &sta_info_le,
3168 					       sizeof(sta_info_le));
3169 		if (err < 0) {
3170 			bphy_err(drvr, "GET STA INFO failed, %d\n", err);
3171 			goto done;
3172 		}
3173 	}
3174 	brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
3175 	sinfo->filled = BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
3176 	sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
3177 	sta_flags = le32_to_cpu(sta_info_le.flags);
3178 	brcmf_convert_sta_flags(sta_flags, sinfo);
3179 	sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
3180 	if (is_tdls_peer)
3181 		sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
3182 	else
3183 		sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3184 	if (sta_flags & BRCMF_STA_ASSOC) {
3185 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME);
3186 		sinfo->connected_time = le32_to_cpu(sta_info_le.in);
3187 		brcmf_fill_bss_param(ifp, sinfo);
3188 	}
3189 	if (sta_flags & BRCMF_STA_SCBSTATS) {
3190 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
3191 		sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
3192 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
3193 		sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
3194 		sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
3195 		sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
3196 		sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
3197 		sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
3198 		if (sinfo->tx_packets) {
3199 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
3200 			sinfo->txrate.legacy =
3201 				le32_to_cpu(sta_info_le.tx_rate) / 100;
3202 		}
3203 		if (sinfo->rx_packets) {
3204 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
3205 			sinfo->rxrate.legacy =
3206 				le32_to_cpu(sta_info_le.rx_rate) / 100;
3207 		}
3208 		if (le16_to_cpu(sta_info_le.ver) >= 4) {
3209 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
3210 			sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
3211 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
3212 			sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
3213 		}
3214 		for (i = 0; i < BRCMF_ANT_MAX; i++) {
3215 			if (sta_info_le.rssi[i] == 0 ||
3216 			    sta_info_le.rx_lastpkt_rssi[i] == 0)
3217 				continue;
3218 			sinfo->chains |= BIT(count_rssi);
3219 			sinfo->chain_signal[count_rssi] =
3220 				sta_info_le.rx_lastpkt_rssi[i];
3221 			sinfo->chain_signal_avg[count_rssi] =
3222 				sta_info_le.rssi[i];
3223 			total_rssi += sta_info_le.rx_lastpkt_rssi[i];
3224 			total_rssi_avg += sta_info_le.rssi[i];
3225 			count_rssi++;
3226 		}
3227 		if (count_rssi) {
3228 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3229 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
3230 			sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
3231 			sinfo->filled |=
3232 				BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
3233 			sinfo->signal = total_rssi / count_rssi;
3234 			sinfo->signal_avg = total_rssi_avg / count_rssi;
3235 		} else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
3236 			&ifp->vif->sme_state)) {
3237 			memset(&scb_val, 0, sizeof(scb_val));
3238 			err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
3239 						     &scb_val, sizeof(scb_val));
3240 			if (err) {
3241 				bphy_err(drvr, "Could not get rssi (%d)\n",
3242 					 err);
3243 				goto done;
3244 			} else {
3245 				rssi = le32_to_cpu(scb_val.val);
3246 				sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3247 				sinfo->signal = rssi;
3248 				brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
3249 			}
3250 		}
3251 	}
3252 done:
3253 	brcmf_dbg(TRACE, "Exit\n");
3254 	return err;
3255 }
3256 
3257 static int
3258 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct wireless_dev *wdev,
3259 			    int idx, u8 *mac, struct station_info *sinfo)
3260 {
3261 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3262 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
3263 	struct brcmf_pub *drvr = cfg->pub;
3264 	s32 err;
3265 
3266 	brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
3267 
3268 	if (idx == 0) {
3269 		cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
3270 		err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
3271 					     &cfg->assoclist,
3272 					     sizeof(cfg->assoclist));
3273 		if (err) {
3274 			/* GET_ASSOCLIST unsupported by firmware of older chips */
3275 			if (err == -EBADE)
3276 				bphy_info_once(drvr, "BRCMF_C_GET_ASSOCLIST unsupported\n");
3277 			else
3278 				bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST failed, err=%d\n",
3279 					 err);
3280 
3281 			cfg->assoclist.count = 0;
3282 			return -EOPNOTSUPP;
3283 		}
3284 	}
3285 	if (idx < le32_to_cpu(cfg->assoclist.count)) {
3286 		memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
3287 		return brcmf_cfg80211_get_station(wiphy, wdev,
3288 						  mac, sinfo);
3289 	}
3290 	return -ENOENT;
3291 }
3292 
3293 static s32
3294 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
3295 			   bool enabled, s32 timeout)
3296 {
3297 	s32 pm;
3298 	s32 err = 0;
3299 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3300 	struct brcmf_if *ifp = netdev_priv(ndev);
3301 	struct brcmf_pub *drvr = cfg->pub;
3302 
3303 	brcmf_dbg(TRACE, "Enter\n");
3304 
3305 	/*
3306 	 * Powersave enable/disable request is coming from the
3307 	 * cfg80211 even before the interface is up. In that
3308 	 * scenario, driver will be storing the power save
3309 	 * preference in cfg struct to apply this to
3310 	 * FW later while initializing the dongle
3311 	 */
3312 	cfg->pwr_save = enabled;
3313 	if (!check_vif_up(ifp->vif)) {
3314 
3315 		brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
3316 		goto done;
3317 	}
3318 
3319 	pm = enabled ? PM_FAST : PM_OFF;
3320 	/* Do not enable the power save after assoc if it is a p2p interface */
3321 	if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
3322 		brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
3323 		pm = PM_OFF;
3324 	}
3325 	brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
3326 
3327 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
3328 	if (err) {
3329 		if (err == -ENODEV)
3330 			bphy_err(drvr, "net_device is not ready yet\n");
3331 		else
3332 			bphy_err(drvr, "error (%d)\n", err);
3333 	}
3334 
3335 	err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret",
3336 				min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS));
3337 	if (err)
3338 		bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err);
3339 
3340 done:
3341 	brcmf_dbg(TRACE, "Exit\n");
3342 	return err;
3343 }
3344 
3345 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
3346 				   struct brcmf_bss_info_le *bi)
3347 {
3348 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
3349 	struct brcmf_pub *drvr = cfg->pub;
3350 	struct cfg80211_bss *bss;
3351 	enum nl80211_band band;
3352 	struct brcmu_chan ch;
3353 	u16 channel;
3354 	u32 freq;
3355 	u16 notify_capability;
3356 	u16 notify_interval;
3357 	u8 *notify_ie;
3358 	size_t notify_ielen;
3359 	struct cfg80211_inform_bss bss_data = {};
3360 
3361 	if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
3362 		bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
3363 		return -EINVAL;
3364 	}
3365 
3366 	if (!bi->ctl_ch) {
3367 		ch.chspec = le16_to_cpu(bi->chanspec);
3368 		cfg->d11inf.decchspec(&ch);
3369 		bi->ctl_ch = ch.control_ch_num;
3370 	}
3371 	channel = bi->ctl_ch;
3372 
3373 	if (channel <= CH_MAX_2G_CHANNEL)
3374 		band = NL80211_BAND_2GHZ;
3375 	else
3376 		band = NL80211_BAND_5GHZ;
3377 
3378 	freq = ieee80211_channel_to_frequency(channel, band);
3379 	bss_data.chan = ieee80211_get_channel(wiphy, freq);
3380 	bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
3381 
3382 	notify_capability = le16_to_cpu(bi->capability);
3383 	notify_interval = le16_to_cpu(bi->beacon_period);
3384 	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3385 	notify_ielen = le32_to_cpu(bi->ie_length);
3386 	bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3387 
3388 	brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
3389 	brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
3390 	brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
3391 	brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
3392 	brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal);
3393 
3394 	bss = cfg80211_inform_bss_data(wiphy, &bss_data,
3395 				       CFG80211_BSS_FTYPE_UNKNOWN,
3396 				       (const u8 *)bi->BSSID,
3397 				       0, notify_capability,
3398 				       notify_interval, notify_ie,
3399 				       notify_ielen, GFP_KERNEL);
3400 
3401 	if (!bss)
3402 		return -ENOMEM;
3403 
3404 	cfg80211_put_bss(wiphy, bss);
3405 
3406 	return 0;
3407 }
3408 
3409 static struct brcmf_bss_info_le *
3410 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
3411 {
3412 	if (bss == NULL)
3413 		return list->bss_info_le;
3414 	return (struct brcmf_bss_info_le *)((unsigned long)bss +
3415 					    le32_to_cpu(bss->length));
3416 }
3417 
3418 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
3419 {
3420 	struct brcmf_pub *drvr = cfg->pub;
3421 	struct brcmf_scan_results *bss_list;
3422 	struct brcmf_bss_info_le *bi = NULL;	/* must be initialized */
3423 	s32 err = 0;
3424 	int i;
3425 
3426 	bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
3427 	if (bss_list->count != 0 &&
3428 	    bss_list->version != BRCMF_BSS_INFO_VERSION) {
3429 		bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
3430 			 bss_list->version);
3431 		return -EOPNOTSUPP;
3432 	}
3433 	brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
3434 	for (i = 0; i < bss_list->count; i++) {
3435 		bi = next_bss_le(bss_list, bi);
3436 		err = brcmf_inform_single_bss(cfg, bi);
3437 		if (err)
3438 			break;
3439 	}
3440 	return err;
3441 }
3442 
3443 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
3444 			     struct net_device *ndev, const u8 *bssid)
3445 {
3446 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
3447 	struct brcmf_pub *drvr = cfg->pub;
3448 	struct ieee80211_channel *notify_channel;
3449 	struct brcmf_bss_info_le *bi = NULL;
3450 	struct ieee80211_supported_band *band;
3451 	struct cfg80211_bss *bss;
3452 	struct brcmu_chan ch;
3453 	u8 *buf = NULL;
3454 	s32 err = 0;
3455 	u32 freq;
3456 	u16 notify_capability;
3457 	u16 notify_interval;
3458 	u8 *notify_ie;
3459 	size_t notify_ielen;
3460 	s32 notify_signal;
3461 
3462 	brcmf_dbg(TRACE, "Enter\n");
3463 
3464 	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3465 	if (buf == NULL) {
3466 		err = -ENOMEM;
3467 		goto CleanUp;
3468 	}
3469 
3470 	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3471 
3472 	err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
3473 				     buf, WL_BSS_INFO_MAX);
3474 	if (err) {
3475 		bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
3476 		goto CleanUp;
3477 	}
3478 
3479 	bi = (struct brcmf_bss_info_le *)(buf + 4);
3480 
3481 	ch.chspec = le16_to_cpu(bi->chanspec);
3482 	cfg->d11inf.decchspec(&ch);
3483 
3484 	if (ch.band == BRCMU_CHAN_BAND_2G)
3485 		band = wiphy->bands[NL80211_BAND_2GHZ];
3486 	else
3487 		band = wiphy->bands[NL80211_BAND_5GHZ];
3488 
3489 	freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
3490 	cfg->channel = freq;
3491 	notify_channel = ieee80211_get_channel(wiphy, freq);
3492 
3493 	notify_capability = le16_to_cpu(bi->capability);
3494 	notify_interval = le16_to_cpu(bi->beacon_period);
3495 	notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3496 	notify_ielen = le32_to_cpu(bi->ie_length);
3497 	notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3498 
3499 	brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
3500 	brcmf_dbg(CONN, "capability: %X\n", notify_capability);
3501 	brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
3502 	brcmf_dbg(CONN, "signal: %d\n", notify_signal);
3503 
3504 	bss = cfg80211_inform_bss(wiphy, notify_channel,
3505 				  CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
3506 				  notify_capability, notify_interval,
3507 				  notify_ie, notify_ielen, notify_signal,
3508 				  GFP_KERNEL);
3509 
3510 	if (!bss) {
3511 		err = -ENOMEM;
3512 		goto CleanUp;
3513 	}
3514 
3515 	cfg80211_put_bss(wiphy, bss);
3516 
3517 CleanUp:
3518 
3519 	kfree(buf);
3520 
3521 	brcmf_dbg(TRACE, "Exit\n");
3522 
3523 	return err;
3524 }
3525 
3526 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
3527 				 struct brcmf_if *ifp)
3528 {
3529 	struct brcmf_pub *drvr = cfg->pub;
3530 	struct brcmf_bss_info_le *bi = NULL;
3531 	s32 err = 0;
3532 
3533 	brcmf_dbg(TRACE, "Enter\n");
3534 	if (brcmf_is_ibssmode(ifp->vif))
3535 		return err;
3536 
3537 	*(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
3538 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3539 				     cfg->extra_buf, WL_EXTRA_BUF_MAX);
3540 	if (err) {
3541 		bphy_err(drvr, "Could not get bss info %d\n", err);
3542 		goto update_bss_info_out;
3543 	}
3544 	bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
3545 	err = brcmf_inform_single_bss(cfg, bi);
3546 
3547 update_bss_info_out:
3548 	brcmf_dbg(TRACE, "Exit");
3549 	return err;
3550 }
3551 
3552 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3553 {
3554 	struct escan_info *escan = &cfg->escan_info;
3555 
3556 	set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3557 	if (cfg->int_escan_map || cfg->scan_request) {
3558 		escan->escan_state = WL_ESCAN_STATE_IDLE;
3559 		brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3560 	}
3561 	clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3562 	clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3563 }
3564 
3565 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3566 {
3567 	struct brcmf_cfg80211_info *cfg =
3568 			container_of(work, struct brcmf_cfg80211_info,
3569 				     escan_timeout_work);
3570 
3571 	brcmf_inform_bss(cfg);
3572 	brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3573 }
3574 
3575 static void brcmf_escan_timeout(struct timer_list *t)
3576 {
3577 	struct brcmf_cfg80211_info *cfg =
3578 			timer_container_of(cfg, t, escan_timeout);
3579 	struct brcmf_pub *drvr = cfg->pub;
3580 
3581 	if (cfg->int_escan_map || cfg->scan_request) {
3582 		bphy_err(drvr, "timer expired\n");
3583 		schedule_work(&cfg->escan_timeout_work);
3584 	}
3585 }
3586 
3587 static s32
3588 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3589 			      struct brcmf_bss_info_le *bss,
3590 			      struct brcmf_bss_info_le *bss_info_le)
3591 {
3592 	struct brcmu_chan ch_bss, ch_bss_info_le;
3593 
3594 	ch_bss.chspec = le16_to_cpu(bss->chanspec);
3595 	cfg->d11inf.decchspec(&ch_bss);
3596 	ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3597 	cfg->d11inf.decchspec(&ch_bss_info_le);
3598 
3599 	if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3600 		ch_bss.band == ch_bss_info_le.band &&
3601 		bss_info_le->SSID_len == bss->SSID_len &&
3602 		!memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3603 		if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3604 			(bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3605 			s16 bss_rssi = le16_to_cpu(bss->RSSI);
3606 			s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3607 
3608 			/* preserve max RSSI if the measurements are
3609 			* both on-channel or both off-channel
3610 			*/
3611 			if (bss_info_rssi > bss_rssi)
3612 				bss->RSSI = bss_info_le->RSSI;
3613 		} else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3614 			(bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3615 			/* preserve the on-channel rssi measurement
3616 			* if the new measurement is off channel
3617 			*/
3618 			bss->RSSI = bss_info_le->RSSI;
3619 			bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3620 		}
3621 		return 1;
3622 	}
3623 	return 0;
3624 }
3625 
3626 static s32
3627 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3628 			     const struct brcmf_event_msg *e, void *data)
3629 {
3630 	struct brcmf_pub *drvr = ifp->drvr;
3631 	struct brcmf_cfg80211_info *cfg = drvr->config;
3632 	s32 status;
3633 	struct brcmf_escan_result_le *escan_result_le;
3634 	u32 escan_buflen;
3635 	struct brcmf_bss_info_le *bss_info_le;
3636 	struct brcmf_bss_info_le *bss = NULL;
3637 	u32 bi_length;
3638 	struct brcmf_scan_results *list;
3639 	u32 i;
3640 	bool aborted;
3641 
3642 	status = e->status;
3643 
3644 	if (status == BRCMF_E_STATUS_ABORT)
3645 		goto exit;
3646 
3647 	if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3648 		bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
3649 			 ifp->bsscfgidx);
3650 		return -EPERM;
3651 	}
3652 
3653 	if (status == BRCMF_E_STATUS_PARTIAL) {
3654 		brcmf_dbg(SCAN, "ESCAN Partial result\n");
3655 		if (e->datalen < sizeof(*escan_result_le)) {
3656 			bphy_err(drvr, "invalid event data length\n");
3657 			goto exit;
3658 		}
3659 		escan_result_le = (struct brcmf_escan_result_le *) data;
3660 		if (!escan_result_le) {
3661 			bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
3662 			goto exit;
3663 		}
3664 		escan_buflen = le32_to_cpu(escan_result_le->buflen);
3665 		if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3666 		    escan_buflen > e->datalen ||
3667 		    escan_buflen < sizeof(*escan_result_le)) {
3668 			bphy_err(drvr, "Invalid escan buffer length: %d\n",
3669 				 escan_buflen);
3670 			goto exit;
3671 		}
3672 		if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3673 			bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
3674 				 escan_result_le->bss_count);
3675 			goto exit;
3676 		}
3677 		bss_info_le = &escan_result_le->bss_info_le;
3678 
3679 		if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3680 			goto exit;
3681 
3682 		if (!cfg->int_escan_map && !cfg->scan_request) {
3683 			brcmf_dbg(SCAN, "result without cfg80211 request\n");
3684 			goto exit;
3685 		}
3686 
3687 		bi_length = le32_to_cpu(bss_info_le->length);
3688 		if (bi_length != escan_buflen -	WL_ESCAN_RESULTS_FIXED_SIZE) {
3689 			bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
3690 				 bi_length);
3691 			goto exit;
3692 		}
3693 
3694 		if (!(cfg_to_wiphy(cfg)->interface_modes &
3695 					BIT(NL80211_IFTYPE_ADHOC))) {
3696 			if (le16_to_cpu(bss_info_le->capability) &
3697 						WLAN_CAPABILITY_IBSS) {
3698 				bphy_err(drvr, "Ignoring IBSS result\n");
3699 				goto exit;
3700 			}
3701 		}
3702 
3703 		list = (struct brcmf_scan_results *)
3704 				cfg->escan_info.escan_buf;
3705 		if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3706 			bphy_err(drvr, "Buffer is too small: ignoring\n");
3707 			goto exit;
3708 		}
3709 
3710 		for (i = 0; i < list->count; i++) {
3711 			bss = bss ? (struct brcmf_bss_info_le *)
3712 				((unsigned char *)bss +
3713 				le32_to_cpu(bss->length)) : list->bss_info_le;
3714 			if (brcmf_compare_update_same_bss(cfg, bss,
3715 							  bss_info_le))
3716 				goto exit;
3717 		}
3718 		memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3719 		       bi_length);
3720 		list->version = le32_to_cpu(bss_info_le->version);
3721 		list->buflen += bi_length;
3722 		list->count++;
3723 	} else {
3724 		cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3725 		if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3726 			goto exit;
3727 		if (cfg->int_escan_map || cfg->scan_request) {
3728 			brcmf_inform_bss(cfg);
3729 			aborted = status != BRCMF_E_STATUS_SUCCESS;
3730 			brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3731 		} else
3732 			brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3733 				  status);
3734 	}
3735 exit:
3736 	return 0;
3737 }
3738 
3739 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3740 {
3741 	brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3742 			    brcmf_cfg80211_escan_handler);
3743 	cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3744 	/* Init scan_timeout timer */
3745 	timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3746 	INIT_WORK(&cfg->escan_timeout_work,
3747 		  brcmf_cfg80211_escan_timeout_worker);
3748 }
3749 
3750 static struct cfg80211_scan_request *
3751 brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3752 	struct cfg80211_scan_request *req;
3753 	size_t req_size;
3754 
3755 	req_size = sizeof(*req) +
3756 		   n_netinfo * sizeof(req->channels[0]) +
3757 		   n_netinfo * sizeof(*req->ssids);
3758 
3759 	req = kzalloc(req_size, GFP_KERNEL);
3760 	if (req) {
3761 		req->wiphy = wiphy;
3762 		req->ssids = (void *)(&req->channels[0]) +
3763 			     n_netinfo * sizeof(req->channels[0]);
3764 	}
3765 	return req;
3766 }
3767 
3768 static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3769 					 u8 *ssid, u8 ssid_len, u8 channel)
3770 {
3771 	struct ieee80211_channel *chan;
3772 	enum nl80211_band band;
3773 	int freq, i;
3774 
3775 	if (channel <= CH_MAX_2G_CHANNEL)
3776 		band = NL80211_BAND_2GHZ;
3777 	else
3778 		band = NL80211_BAND_5GHZ;
3779 
3780 	freq = ieee80211_channel_to_frequency(channel, band);
3781 	if (!freq)
3782 		return -EINVAL;
3783 
3784 	chan = ieee80211_get_channel(req->wiphy, freq);
3785 	if (!chan)
3786 		return -EINVAL;
3787 
3788 	for (i = 0; i < req->n_channels; i++) {
3789 		if (req->channels[i] == chan)
3790 			break;
3791 	}
3792 	if (i == req->n_channels) {
3793 		req->n_channels++;
3794 		req->channels[i] = chan;
3795 	}
3796 
3797 	for (i = 0; i < req->n_ssids; i++) {
3798 		if (req->ssids[i].ssid_len == ssid_len &&
3799 		    !memcmp(req->ssids[i].ssid, ssid, ssid_len))
3800 			break;
3801 	}
3802 	if (i == req->n_ssids) {
3803 		memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3804 		req->ssids[req->n_ssids++].ssid_len = ssid_len;
3805 	}
3806 	return 0;
3807 }
3808 
3809 static int brcmf_start_internal_escan(struct brcmf_if *ifp, u32 fwmap,
3810 				      struct cfg80211_scan_request *request)
3811 {
3812 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3813 	int err;
3814 
3815 	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3816 		if (cfg->int_escan_map)
3817 			brcmf_dbg(SCAN, "aborting internal scan: map=%u\n",
3818 				  cfg->int_escan_map);
3819 		/* Abort any on-going scan */
3820 		brcmf_abort_scanning(cfg);
3821 	}
3822 
3823 	brcmf_dbg(SCAN, "start internal scan: map=%u\n", fwmap);
3824 	set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3825 	cfg->escan_info.run = brcmf_run_escan;
3826 	err = brcmf_do_escan(ifp, request);
3827 	if (err) {
3828 		clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3829 		return err;
3830 	}
3831 	cfg->int_escan_map = fwmap;
3832 	return 0;
3833 }
3834 
3835 static struct brcmf_pno_net_info_le *
3836 brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3837 {
3838 	struct brcmf_pno_scanresults_v2_le *pfn_v2;
3839 	struct brcmf_pno_net_info_le *netinfo;
3840 
3841 	switch (pfn_v1->version) {
3842 	default:
3843 		WARN_ON(1);
3844 		fallthrough;
3845 	case cpu_to_le32(1):
3846 		netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3847 		break;
3848 	case cpu_to_le32(2):
3849 		pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3850 		netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3851 		break;
3852 	}
3853 
3854 	return netinfo;
3855 }
3856 
3857 /* PFN result doesn't have all the info which are required by the supplicant
3858  * (For e.g IEs) Do a target Escan so that sched scan results are reported
3859  * via wl_inform_single_bss in the required format. Escan does require the
3860  * scan request in the form of cfg80211_scan_request. For timebeing, create
3861  * cfg80211_scan_request one out of the received PNO event.
3862  */
3863 static s32
3864 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3865 				const struct brcmf_event_msg *e, void *data)
3866 {
3867 	struct brcmf_pub *drvr = ifp->drvr;
3868 	struct brcmf_cfg80211_info *cfg = drvr->config;
3869 	struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3870 	struct cfg80211_scan_request *request = NULL;
3871 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
3872 	int i, err = 0;
3873 	struct brcmf_pno_scanresults_le *pfn_result;
3874 	u32 bucket_map;
3875 	u32 result_count;
3876 	u32 status;
3877 	u32 datalen;
3878 
3879 	brcmf_dbg(SCAN, "Enter\n");
3880 
3881 	if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3882 		brcmf_dbg(SCAN, "Event data too small. Ignore\n");
3883 		return 0;
3884 	}
3885 
3886 	if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3887 		brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3888 		return 0;
3889 	}
3890 
3891 	pfn_result = (struct brcmf_pno_scanresults_le *)data;
3892 	result_count = le32_to_cpu(pfn_result->count);
3893 	status = le32_to_cpu(pfn_result->status);
3894 
3895 	/* PFN event is limited to fit 512 bytes so we may get
3896 	 * multiple NET_FOUND events. For now place a warning here.
3897 	 */
3898 	WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3899 	brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3900 	if (!result_count) {
3901 		bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n");
3902 		goto out_err;
3903 	}
3904 
3905 	netinfo_start = brcmf_get_netinfo_array(pfn_result);
3906 	datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3907 	if (datalen < result_count * sizeof(*netinfo)) {
3908 		bphy_err(drvr, "insufficient event data\n");
3909 		goto out_err;
3910 	}
3911 
3912 	request = brcmf_alloc_internal_escan_request(wiphy,
3913 						     result_count);
3914 	if (!request) {
3915 		err = -ENOMEM;
3916 		goto out_err;
3917 	}
3918 
3919 	bucket_map = 0;
3920 	for (i = 0; i < result_count; i++) {
3921 		netinfo = &netinfo_start[i];
3922 
3923 		if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3924 			netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3925 		brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3926 			  netinfo->SSID, netinfo->channel);
3927 		bucket_map |= brcmf_pno_get_bucket_map(cfg->pno, netinfo);
3928 		err = brcmf_internal_escan_add_info(request,
3929 						    netinfo->SSID,
3930 						    netinfo->SSID_len,
3931 						    netinfo->channel);
3932 		if (err)
3933 			goto out_err;
3934 	}
3935 
3936 	if (!bucket_map)
3937 		goto free_req;
3938 
3939 	err = brcmf_start_internal_escan(ifp, bucket_map, request);
3940 	if (!err)
3941 		goto free_req;
3942 
3943 out_err:
3944 	cfg80211_sched_scan_stopped(wiphy, 0);
3945 free_req:
3946 	kfree(request);
3947 	return err;
3948 }
3949 
3950 static int
3951 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3952 				struct net_device *ndev,
3953 				struct cfg80211_sched_scan_request *req)
3954 {
3955 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3956 	struct brcmf_if *ifp = netdev_priv(ndev);
3957 	struct brcmf_pub *drvr = cfg->pub;
3958 
3959 	brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
3960 		  req->n_match_sets, req->n_ssids);
3961 
3962 	if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3963 		bphy_err(drvr, "Scanning suppressed: status=%lu\n",
3964 			 cfg->scan_status);
3965 		return -EAGAIN;
3966 	}
3967 
3968 	if (req->n_match_sets <= 0) {
3969 		brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3970 			  req->n_match_sets);
3971 		return -EINVAL;
3972 	}
3973 
3974 	return brcmf_pno_start_sched_scan(ifp, req);
3975 }
3976 
3977 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3978 					  struct net_device *ndev, u64 reqid)
3979 {
3980 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3981 	struct brcmf_if *ifp = netdev_priv(ndev);
3982 
3983 	brcmf_dbg(SCAN, "enter\n");
3984 	brcmf_pno_stop_sched_scan(ifp, reqid);
3985 	if (cfg->int_escan_map)
3986 		brcmf_notify_escan_complete(cfg, ifp, true, true);
3987 	return 0;
3988 }
3989 
3990 static __always_inline void brcmf_delay(u32 ms)
3991 {
3992 	if (ms < 1000 / HZ) {
3993 		cond_resched();
3994 		mdelay(ms);
3995 	} else {
3996 		msleep(ms);
3997 	}
3998 }
3999 
4000 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
4001 				     u8 *pattern, u32 patternsize, u8 *mask,
4002 				     u32 packet_offset)
4003 {
4004 	struct brcmf_fil_wowl_pattern_le *filter;
4005 	u32 masksize;
4006 	u32 patternoffset;
4007 	u8 *buf;
4008 	u32 bufsize;
4009 	s32 ret;
4010 
4011 	masksize = (patternsize + 7) / 8;
4012 	patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
4013 
4014 	bufsize = sizeof(*filter) + patternsize + masksize;
4015 	buf = kzalloc(bufsize, GFP_KERNEL);
4016 	if (!buf)
4017 		return -ENOMEM;
4018 	filter = (struct brcmf_fil_wowl_pattern_le *)buf;
4019 
4020 	memcpy(filter->cmd, cmd, 4);
4021 	filter->masksize = cpu_to_le32(masksize);
4022 	filter->offset = cpu_to_le32(packet_offset);
4023 	filter->patternoffset = cpu_to_le32(patternoffset);
4024 	filter->patternsize = cpu_to_le32(patternsize);
4025 	filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
4026 
4027 	if ((mask) && (masksize))
4028 		memcpy(buf + sizeof(*filter), mask, masksize);
4029 	if ((pattern) && (patternsize))
4030 		memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
4031 
4032 	ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
4033 
4034 	kfree(buf);
4035 	return ret;
4036 }
4037 
4038 static s32
4039 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
4040 		      void *data)
4041 {
4042 	struct brcmf_pub *drvr = ifp->drvr;
4043 	struct brcmf_cfg80211_info *cfg = drvr->config;
4044 	struct brcmf_pno_scanresults_le *pfn_result;
4045 	struct brcmf_pno_net_info_le *netinfo;
4046 
4047 	brcmf_dbg(SCAN, "Enter\n");
4048 
4049 	if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
4050 		brcmf_dbg(SCAN, "Event data too small. Ignore\n");
4051 		return 0;
4052 	}
4053 
4054 	pfn_result = (struct brcmf_pno_scanresults_le *)data;
4055 
4056 	if (e->event_code == BRCMF_E_PFN_NET_LOST) {
4057 		brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
4058 		return 0;
4059 	}
4060 
4061 	if (le32_to_cpu(pfn_result->count) < 1) {
4062 		bphy_err(drvr, "Invalid result count, expected 1 (%d)\n",
4063 			 le32_to_cpu(pfn_result->count));
4064 		return -EINVAL;
4065 	}
4066 
4067 	netinfo = brcmf_get_netinfo_array(pfn_result);
4068 	if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
4069 		netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
4070 	memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
4071 	cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
4072 	cfg->wowl.nd->n_channels = 1;
4073 	cfg->wowl.nd->channels[0] =
4074 		ieee80211_channel_to_frequency(netinfo->channel,
4075 			netinfo->channel <= CH_MAX_2G_CHANNEL ?
4076 					NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
4077 	cfg->wowl.nd_info->n_matches = 1;
4078 	cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
4079 
4080 	/* Inform (the resume task) that the net detect information was recvd */
4081 	cfg->wowl.nd_data_completed = true;
4082 	wake_up(&cfg->wowl.nd_data_wait);
4083 
4084 	return 0;
4085 }
4086 
4087 #ifdef CONFIG_PM
4088 
4089 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
4090 {
4091 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4092 	struct brcmf_pub *drvr = cfg->pub;
4093 	struct brcmf_wowl_wakeind_le wake_ind_le;
4094 	struct cfg80211_wowlan_wakeup wakeup_data;
4095 	struct cfg80211_wowlan_wakeup *wakeup;
4096 	u32 wakeind;
4097 	s32 err;
4098 	long time_left;
4099 
4100 	err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
4101 				       sizeof(wake_ind_le));
4102 	if (err) {
4103 		bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err);
4104 		return;
4105 	}
4106 
4107 	wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
4108 	if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
4109 		       BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
4110 		       BRCMF_WOWL_PFN_FOUND)) {
4111 		wakeup = &wakeup_data;
4112 		memset(&wakeup_data, 0, sizeof(wakeup_data));
4113 		wakeup_data.pattern_idx = -1;
4114 
4115 		if (wakeind & BRCMF_WOWL_MAGIC) {
4116 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
4117 			wakeup_data.magic_pkt = true;
4118 		}
4119 		if (wakeind & BRCMF_WOWL_DIS) {
4120 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
4121 			wakeup_data.disconnect = true;
4122 		}
4123 		if (wakeind & BRCMF_WOWL_BCN) {
4124 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
4125 			wakeup_data.disconnect = true;
4126 		}
4127 		if (wakeind & BRCMF_WOWL_RETR) {
4128 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
4129 			wakeup_data.disconnect = true;
4130 		}
4131 		if (wakeind & BRCMF_WOWL_NET) {
4132 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
4133 			/* For now always map to pattern 0, no API to get
4134 			 * correct information available at the moment.
4135 			 */
4136 			wakeup_data.pattern_idx = 0;
4137 		}
4138 		if (wakeind & BRCMF_WOWL_PFN_FOUND) {
4139 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
4140 			time_left = wait_event_timeout(cfg->wowl.nd_data_wait,
4141 						       cfg->wowl.nd_data_completed,
4142 						       BRCMF_ND_INFO_TIMEOUT);
4143 			if (!time_left)
4144 				bphy_err(drvr, "No result for wowl net detect\n");
4145 			else
4146 				wakeup_data.net_detect = cfg->wowl.nd_info;
4147 		}
4148 		if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
4149 			brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
4150 			wakeup_data.gtk_rekey_failure = true;
4151 		}
4152 	} else {
4153 		wakeup = NULL;
4154 	}
4155 	cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
4156 }
4157 
4158 #else
4159 
4160 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
4161 {
4162 }
4163 
4164 #endif /* CONFIG_PM */
4165 
4166 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
4167 {
4168 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4169 	struct net_device *ndev = cfg_to_ndev(cfg);
4170 	struct brcmf_if *ifp = netdev_priv(ndev);
4171 
4172 	brcmf_dbg(TRACE, "Enter\n");
4173 
4174 	if (cfg->wowl.active) {
4175 		brcmf_report_wowl_wakeind(wiphy, ifp);
4176 		brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
4177 		brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
4178 		if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
4179 			brcmf_configure_arp_nd_offload(ifp, true);
4180 		brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
4181 				      cfg->wowl.pre_pmmode);
4182 		cfg->wowl.active = false;
4183 		if (cfg->wowl.nd_enabled) {
4184 			brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
4185 			brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
4186 			brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4187 					    brcmf_notify_sched_scan_results);
4188 			cfg->wowl.nd_enabled = false;
4189 		}
4190 	}
4191 	return 0;
4192 }
4193 
4194 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
4195 				 struct brcmf_if *ifp,
4196 				 struct cfg80211_wowlan *wowl)
4197 {
4198 	u32 wowl_config;
4199 	struct brcmf_wowl_wakeind_le wowl_wakeind;
4200 	u32 i;
4201 
4202 	brcmf_dbg(TRACE, "Suspend, wowl config.\n");
4203 
4204 	if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
4205 		brcmf_configure_arp_nd_offload(ifp, false);
4206 	brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
4207 	brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
4208 
4209 	wowl_config = 0;
4210 	if (wowl->disconnect)
4211 		wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
4212 	if (wowl->magic_pkt)
4213 		wowl_config |= BRCMF_WOWL_MAGIC;
4214 	if ((wowl->patterns) && (wowl->n_patterns)) {
4215 		wowl_config |= BRCMF_WOWL_NET;
4216 		for (i = 0; i < wowl->n_patterns; i++) {
4217 			brcmf_config_wowl_pattern(ifp, "add",
4218 				(u8 *)wowl->patterns[i].pattern,
4219 				wowl->patterns[i].pattern_len,
4220 				(u8 *)wowl->patterns[i].mask,
4221 				wowl->patterns[i].pkt_offset);
4222 		}
4223 	}
4224 	if (wowl->nd_config) {
4225 		brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
4226 						wowl->nd_config);
4227 		wowl_config |= BRCMF_WOWL_PFN_FOUND;
4228 
4229 		cfg->wowl.nd_data_completed = false;
4230 		cfg->wowl.nd_enabled = true;
4231 		/* Now reroute the event for PFN to the wowl function. */
4232 		brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
4233 		brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4234 				    brcmf_wowl_nd_results);
4235 	}
4236 	if (wowl->gtk_rekey_failure)
4237 		wowl_config |= BRCMF_WOWL_GTK_FAILURE;
4238 	if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4239 		wowl_config |= BRCMF_WOWL_UNASSOC;
4240 
4241 	memcpy(&wowl_wakeind, "clear", 6);
4242 	brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
4243 				 sizeof(wowl_wakeind));
4244 	brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
4245 	brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
4246 	brcmf_bus_wowl_config(cfg->pub->bus_if, true);
4247 	cfg->wowl.active = true;
4248 }
4249 
4250 static int brcmf_keepalive_start(struct brcmf_if *ifp, unsigned int interval)
4251 {
4252 	struct brcmf_mkeep_alive_pkt_le kalive = {0};
4253 	int ret = 0;
4254 
4255 	/* Configure Null function/data keepalive */
4256 	kalive.version = cpu_to_le16(1);
4257 	kalive.period_msec = cpu_to_le32(interval * MSEC_PER_SEC);
4258 	kalive.len_bytes = cpu_to_le16(0);
4259 	kalive.keep_alive_id = 0;
4260 
4261 	ret = brcmf_fil_iovar_data_set(ifp, "mkeep_alive", &kalive, sizeof(kalive));
4262 	if (ret)
4263 		brcmf_err("keep-alive packet config failed, ret=%d\n", ret);
4264 
4265 	return ret;
4266 }
4267 
4268 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
4269 				  struct cfg80211_wowlan *wowl)
4270 {
4271 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4272 	struct net_device *ndev = cfg_to_ndev(cfg);
4273 	struct brcmf_if *ifp = netdev_priv(ndev);
4274 	struct brcmf_cfg80211_vif *vif;
4275 
4276 	brcmf_dbg(TRACE, "Enter\n");
4277 
4278 	/* if the primary net_device is not READY there is nothing
4279 	 * we can do but pray resume goes smoothly.
4280 	 */
4281 	if (!check_vif_up(ifp->vif))
4282 		goto exit;
4283 
4284 	/* Stop scheduled scan */
4285 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
4286 		brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
4287 
4288 	/* end any scanning */
4289 	if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
4290 		brcmf_abort_scanning(cfg);
4291 
4292 	if (wowl == NULL) {
4293 		brcmf_bus_wowl_config(cfg->pub->bus_if, false);
4294 		list_for_each_entry(vif, &cfg->vif_list, list) {
4295 			if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
4296 				continue;
4297 			/* While going to suspend if associated with AP
4298 			 * disassociate from AP to save power while system is
4299 			 * in suspended state
4300 			 */
4301 			brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true);
4302 			/* Make sure WPA_Supplicant receives all the event
4303 			 * generated due to DISASSOC call to the fw to keep
4304 			 * the state fw and WPA_Supplicant state consistent
4305 			 */
4306 			brcmf_delay(500);
4307 		}
4308 		/* Configure MPC */
4309 		brcmf_set_mpc(ifp, 1);
4310 
4311 	} else {
4312 		/* Configure WOWL parameters */
4313 		brcmf_configure_wowl(cfg, ifp, wowl);
4314 
4315 		/* Prevent disassociation due to inactivity with keep-alive */
4316 		brcmf_keepalive_start(ifp, 30);
4317 	}
4318 
4319 exit:
4320 	brcmf_dbg(TRACE, "Exit\n");
4321 	/* clear any scanning activity */
4322 	cfg->scan_status = 0;
4323 	return 0;
4324 }
4325 
4326 static s32
4327 brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,
4328 		  bool alive)
4329 {
4330 	struct brcmf_pmk_op_v3_le *pmk_op;
4331 	int length = offsetof(struct brcmf_pmk_op_v3_le, pmk);
4332 	int ret;
4333 
4334 	pmk_op = kzalloc_obj(*pmk_op);
4335 	if (!pmk_op)
4336 		return -ENOMEM;
4337 
4338 	pmk_op->version = cpu_to_le16(BRCMF_PMKSA_VER_3);
4339 
4340 	if (!pmksa) {
4341 		/* Flush operation, operate on entire list */
4342 		pmk_op->count = cpu_to_le16(0);
4343 	} else {
4344 		/* Single PMK operation */
4345 		pmk_op->count = cpu_to_le16(1);
4346 		length += sizeof(struct brcmf_pmksa_v3);
4347 		if (pmksa->bssid)
4348 			memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN);
4349 		if (pmksa->pmkid) {
4350 			memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4351 			pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN;
4352 		}
4353 		if (pmksa->ssid && pmksa->ssid_len) {
4354 			memcpy(pmk_op->pmk[0].ssid.SSID, pmksa->ssid, pmksa->ssid_len);
4355 			pmk_op->pmk[0].ssid.SSID_len = pmksa->ssid_len;
4356 		}
4357 		pmk_op->pmk[0].time_left = cpu_to_le32(alive ? BRCMF_PMKSA_NO_EXPIRY : 0);
4358 	}
4359 
4360 	pmk_op->length = cpu_to_le16(length);
4361 
4362 	ret = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_op, sizeof(*pmk_op));
4363 	kfree(pmk_op);
4364 	return ret;
4365 }
4366 
4367 static __used s32
4368 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
4369 {
4370 	struct brcmf_pmk_list_le *pmk_list;
4371 	int i;
4372 	u32 npmk;
4373 
4374 	pmk_list = &cfg->pmk_list;
4375 	npmk = le32_to_cpu(pmk_list->npmk);
4376 
4377 	brcmf_dbg(CONN, "No of elements %d\n", npmk);
4378 	for (i = 0; i < npmk; i++)
4379 		brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
4380 
4381 	return brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
4382 			sizeof(*pmk_list));
4383 }
4384 
4385 static s32
4386 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4387 			 struct cfg80211_pmksa *pmksa)
4388 {
4389 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4390 	struct brcmf_if *ifp = netdev_priv(ndev);
4391 	struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4392 	struct brcmf_pub *drvr = cfg->pub;
4393 	s32 err;
4394 	u32 npmk, i;
4395 
4396 	brcmf_dbg(TRACE, "Enter\n");
4397 	if (!check_vif_up(ifp->vif))
4398 		return -EIO;
4399 
4400 	brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmksa->bssid);
4401 	brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmksa->pmkid);
4402 
4403 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4404 		return brcmf_pmksa_v3_op(ifp, pmksa, true);
4405 
4406 	/* TODO: implement PMKID_V2 */
4407 
4408 	npmk = le32_to_cpu(cfg->pmk_list.npmk);
4409 	for (i = 0; i < npmk; i++)
4410 		if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4411 			break;
4412 	if (i < BRCMF_MAXPMKID) {
4413 		memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
4414 		memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4415 		if (i == npmk) {
4416 			npmk++;
4417 			cfg->pmk_list.npmk = cpu_to_le32(npmk);
4418 		}
4419 	} else {
4420 		bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk);
4421 		return -EINVAL;
4422 	}
4423 
4424 	err = brcmf_update_pmklist(cfg, ifp);
4425 
4426 	brcmf_dbg(TRACE, "Exit\n");
4427 	return err;
4428 }
4429 
4430 static s32
4431 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4432 			 struct cfg80211_pmksa *pmksa)
4433 {
4434 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4435 	struct brcmf_if *ifp = netdev_priv(ndev);
4436 	struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4437 	struct brcmf_pub *drvr = cfg->pub;
4438 	s32 err;
4439 	u32 npmk, i;
4440 
4441 	brcmf_dbg(TRACE, "Enter\n");
4442 	if (!check_vif_up(ifp->vif))
4443 		return -EIO;
4444 
4445 	brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
4446 
4447 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4448 		return brcmf_pmksa_v3_op(ifp, pmksa, false);
4449 
4450 	/* TODO: implement PMKID_V2 */
4451 
4452 	npmk = le32_to_cpu(cfg->pmk_list.npmk);
4453 	for (i = 0; i < npmk; i++)
4454 		if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4455 			break;
4456 
4457 	if ((npmk > 0) && (i < npmk)) {
4458 		for (; i < (npmk - 1); i++) {
4459 			memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
4460 			memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
4461 			       WLAN_PMKID_LEN);
4462 		}
4463 		memset(&pmk[i], 0, sizeof(*pmk));
4464 		cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
4465 	} else {
4466 		bphy_err(drvr, "Cache entry not found\n");
4467 		return -EINVAL;
4468 	}
4469 
4470 	err = brcmf_update_pmklist(cfg, ifp);
4471 
4472 	brcmf_dbg(TRACE, "Exit\n");
4473 	return err;
4474 
4475 }
4476 
4477 static s32
4478 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
4479 {
4480 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4481 	struct brcmf_if *ifp = netdev_priv(ndev);
4482 	s32 err;
4483 
4484 	brcmf_dbg(TRACE, "Enter\n");
4485 	if (!check_vif_up(ifp->vif))
4486 		return -EIO;
4487 
4488 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4489 		return brcmf_pmksa_v3_op(ifp, NULL, false);
4490 
4491 	/* TODO: implement PMKID_V2 */
4492 
4493 	memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
4494 	err = brcmf_update_pmklist(cfg, ifp);
4495 
4496 	brcmf_dbg(TRACE, "Exit\n");
4497 	return err;
4498 
4499 }
4500 
4501 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
4502 {
4503 	struct brcmf_pub *drvr = ifp->drvr;
4504 	s32 err;
4505 	s32 wpa_val;
4506 
4507 	/* set auth */
4508 	err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
4509 	if (err < 0) {
4510 		bphy_err(drvr, "auth error %d\n", err);
4511 		return err;
4512 	}
4513 	/* set wsec */
4514 	err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
4515 	if (err < 0) {
4516 		bphy_err(drvr, "wsec error %d\n", err);
4517 		return err;
4518 	}
4519 	/* set upper-layer auth */
4520 	if (brcmf_is_ibssmode(ifp->vif))
4521 		wpa_val = WPA_AUTH_NONE;
4522 	else
4523 		wpa_val = WPA_AUTH_DISABLED;
4524 	err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
4525 	if (err < 0) {
4526 		bphy_err(drvr, "wpa_auth error %d\n", err);
4527 		return err;
4528 	}
4529 
4530 	return 0;
4531 }
4532 
4533 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
4534 {
4535 	if (is_rsn_ie)
4536 		return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
4537 
4538 	return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
4539 }
4540 
4541 static s32
4542 brcmf_configure_wpaie(struct brcmf_if *ifp,
4543 		      const struct brcmf_vs_tlv *wpa_ie,
4544 		      bool is_rsn_ie)
4545 {
4546 	struct brcmf_pub *drvr = ifp->drvr;
4547 	u32 auth = 0; /* d11 open authentication */
4548 	u16 count;
4549 	s32 err = 0;
4550 	s32 len;
4551 	u32 i;
4552 	u32 wsec;
4553 	u32 pval = 0;
4554 	u32 gval = 0;
4555 	u32 wpa_auth = 0;
4556 	u32 offset;
4557 	u8 *data;
4558 	u16 rsn_cap;
4559 	u32 wme_bss_disable;
4560 	u32 mfp;
4561 
4562 	brcmf_dbg(TRACE, "Enter\n");
4563 	if (wpa_ie == NULL)
4564 		goto exit;
4565 
4566 	len = wpa_ie->len + TLV_HDR_LEN;
4567 	data = (u8 *)wpa_ie;
4568 	offset = TLV_HDR_LEN;
4569 	if (!is_rsn_ie)
4570 		offset += VS_IE_FIXED_HDR_LEN;
4571 	else
4572 		offset += WPA_IE_VERSION_LEN;
4573 
4574 	/* check for multicast cipher suite */
4575 	if (offset + WPA_IE_MIN_OUI_LEN > len) {
4576 		err = -EINVAL;
4577 		bphy_err(drvr, "no multicast cipher suite\n");
4578 		goto exit;
4579 	}
4580 
4581 	if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4582 		err = -EINVAL;
4583 		bphy_err(drvr, "invalid OUI\n");
4584 		goto exit;
4585 	}
4586 	offset += TLV_OUI_LEN;
4587 
4588 	/* pick up multicast cipher */
4589 	switch (data[offset]) {
4590 	case WPA_CIPHER_NONE:
4591 		gval = 0;
4592 		break;
4593 	case WPA_CIPHER_WEP_40:
4594 	case WPA_CIPHER_WEP_104:
4595 		gval = WEP_ENABLED;
4596 		break;
4597 	case WPA_CIPHER_TKIP:
4598 		gval = TKIP_ENABLED;
4599 		break;
4600 	case WPA_CIPHER_AES_CCM:
4601 		gval = AES_ENABLED;
4602 		break;
4603 	default:
4604 		err = -EINVAL;
4605 		bphy_err(drvr, "Invalid multi cast cipher info\n");
4606 		goto exit;
4607 	}
4608 
4609 	offset++;
4610 	/* walk thru unicast cipher list and pick up what we recognize */
4611 	count = data[offset] + (data[offset + 1] << 8);
4612 	offset += WPA_IE_SUITE_COUNT_LEN;
4613 	/* Check for unicast suite(s) */
4614 	if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4615 		err = -EINVAL;
4616 		bphy_err(drvr, "no unicast cipher suite\n");
4617 		goto exit;
4618 	}
4619 	for (i = 0; i < count; i++) {
4620 		if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4621 			err = -EINVAL;
4622 			bphy_err(drvr, "invalid OUI\n");
4623 			goto exit;
4624 		}
4625 		offset += TLV_OUI_LEN;
4626 		switch (data[offset]) {
4627 		case WPA_CIPHER_NONE:
4628 			break;
4629 		case WPA_CIPHER_WEP_40:
4630 		case WPA_CIPHER_WEP_104:
4631 			pval |= WEP_ENABLED;
4632 			break;
4633 		case WPA_CIPHER_TKIP:
4634 			pval |= TKIP_ENABLED;
4635 			break;
4636 		case WPA_CIPHER_AES_CCM:
4637 			pval |= AES_ENABLED;
4638 			break;
4639 		default:
4640 			bphy_err(drvr, "Invalid unicast security info\n");
4641 		}
4642 		offset++;
4643 	}
4644 	/* walk thru auth management suite list and pick up what we recognize */
4645 	count = data[offset] + (data[offset + 1] << 8);
4646 	offset += WPA_IE_SUITE_COUNT_LEN;
4647 	/* Check for auth key management suite(s) */
4648 	if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4649 		err = -EINVAL;
4650 		bphy_err(drvr, "no auth key mgmt suite\n");
4651 		goto exit;
4652 	}
4653 	for (i = 0; i < count; i++) {
4654 		if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4655 			err = -EINVAL;
4656 			bphy_err(drvr, "invalid OUI\n");
4657 			goto exit;
4658 		}
4659 		offset += TLV_OUI_LEN;
4660 		switch (data[offset]) {
4661 		case RSN_AKM_NONE:
4662 			brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
4663 			wpa_auth |= WPA_AUTH_NONE;
4664 			break;
4665 		case RSN_AKM_UNSPECIFIED:
4666 			brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
4667 			is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
4668 				    (wpa_auth |= WPA_AUTH_UNSPECIFIED);
4669 			break;
4670 		case RSN_AKM_PSK:
4671 			brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
4672 			is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
4673 				    (wpa_auth |= WPA_AUTH_PSK);
4674 			break;
4675 		case RSN_AKM_SHA256_PSK:
4676 			brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4677 			wpa_auth |= WPA2_AUTH_PSK_SHA256;
4678 			break;
4679 		case RSN_AKM_SHA256_1X:
4680 			brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4681 			wpa_auth |= WPA2_AUTH_1X_SHA256;
4682 			break;
4683 		case RSN_AKM_SAE:
4684 			brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
4685 			wpa_auth |= WPA3_AUTH_SAE_PSK;
4686 			break;
4687 		default:
4688 			bphy_err(drvr, "Invalid key mgmt info\n");
4689 		}
4690 		offset++;
4691 	}
4692 
4693 	mfp = BRCMF_MFP_NONE;
4694 	if (is_rsn_ie) {
4695 		wme_bss_disable = 1;
4696 		if ((offset + RSN_CAP_LEN) <= len) {
4697 			rsn_cap = data[offset] + (data[offset + 1] << 8);
4698 			if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4699 				wme_bss_disable = 0;
4700 			if (rsn_cap & RSN_CAP_MFPR_MASK) {
4701 				brcmf_dbg(TRACE, "MFP Required\n");
4702 				mfp = BRCMF_MFP_REQUIRED;
4703 				/* Firmware only supports mfp required in
4704 				 * combination with WPA2_AUTH_PSK_SHA256,
4705 				 * WPA2_AUTH_1X_SHA256, or WPA3_AUTH_SAE_PSK.
4706 				 */
4707 				if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4708 						  WPA2_AUTH_1X_SHA256 |
4709 						  WPA3_AUTH_SAE_PSK))) {
4710 					err = -EINVAL;
4711 					goto exit;
4712 				}
4713 				/* Firmware has requirement that WPA2_AUTH_PSK/
4714 				 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4715 				 * is to be included in the rsn ie.
4716 				 */
4717 				if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4718 					wpa_auth |= WPA2_AUTH_PSK;
4719 				else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4720 					wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4721 			} else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4722 				brcmf_dbg(TRACE, "MFP Capable\n");
4723 				mfp = BRCMF_MFP_CAPABLE;
4724 			}
4725 		}
4726 		offset += RSN_CAP_LEN;
4727 		/* set wme_bss_disable to sync RSN Capabilities */
4728 		err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4729 					       wme_bss_disable);
4730 		if (err < 0) {
4731 			bphy_err(drvr, "wme_bss_disable error %d\n", err);
4732 			goto exit;
4733 		}
4734 
4735 		/* Skip PMKID cnt as it is know to be 0 for AP. */
4736 		offset += RSN_PMKID_COUNT_LEN;
4737 
4738 		/* See if there is BIP wpa suite left for MFP */
4739 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4740 		    ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4741 			err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4742 							&data[offset],
4743 							WPA_IE_MIN_OUI_LEN);
4744 			if (err < 0) {
4745 				bphy_err(drvr, "bip error %d\n", err);
4746 				goto exit;
4747 			}
4748 		}
4749 	}
4750 	/* FOR WPS , set SES_OW_ENABLED */
4751 	wsec = (pval | gval | SES_OW_ENABLED);
4752 
4753 	/* set auth */
4754 	err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4755 	if (err < 0) {
4756 		bphy_err(drvr, "auth error %d\n", err);
4757 		goto exit;
4758 	}
4759 	/* set wsec */
4760 	err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4761 	if (err < 0) {
4762 		bphy_err(drvr, "wsec error %d\n", err);
4763 		goto exit;
4764 	}
4765 	/* Configure MFP, this needs to go after wsec otherwise the wsec command
4766 	 * will overwrite the values set by MFP
4767 	 */
4768 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4769 		err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4770 		if (err < 0) {
4771 			bphy_err(drvr, "mfp error %d\n", err);
4772 			goto exit;
4773 		}
4774 	}
4775 	/* set upper-layer auth */
4776 	err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4777 	if (err < 0) {
4778 		bphy_err(drvr, "wpa_auth error %d\n", err);
4779 		goto exit;
4780 	}
4781 
4782 exit:
4783 	return err;
4784 }
4785 
4786 static s32
4787 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4788 		     struct parsed_vndr_ies *vndr_ies)
4789 {
4790 	struct brcmf_vs_tlv *vndrie;
4791 	struct brcmf_tlv *ie;
4792 	struct parsed_vndr_ie_info *parsed_info;
4793 	s32 remaining_len;
4794 
4795 	remaining_len = (s32)vndr_ie_len;
4796 	memset(vndr_ies, 0, sizeof(*vndr_ies));
4797 
4798 	ie = (struct brcmf_tlv *)vndr_ie_buf;
4799 	while (ie) {
4800 		if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4801 			goto next;
4802 		vndrie = (struct brcmf_vs_tlv *)ie;
4803 		/* len should be bigger than OUI length + one */
4804 		if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4805 			brcmf_err("invalid vndr ie. length is too small %d\n",
4806 				  vndrie->len);
4807 			goto next;
4808 		}
4809 		/* if wpa or wme ie, do not add ie */
4810 		if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4811 		    ((vndrie->oui_type == WPA_OUI_TYPE) ||
4812 		    (vndrie->oui_type == WME_OUI_TYPE))) {
4813 			brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4814 			goto next;
4815 		}
4816 
4817 		parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4818 
4819 		/* save vndr ie information */
4820 		parsed_info->ie_ptr = (char *)vndrie;
4821 		parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4822 		memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4823 
4824 		vndr_ies->count++;
4825 
4826 		brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n",
4827 			  parsed_info->vndrie.oui,
4828 			  parsed_info->vndrie.oui_type);
4829 
4830 		if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4831 			break;
4832 next:
4833 		remaining_len -= (ie->len + TLV_HDR_LEN);
4834 		if (remaining_len <= TLV_HDR_LEN)
4835 			ie = NULL;
4836 		else
4837 			ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4838 				TLV_HDR_LEN);
4839 	}
4840 	return 0;
4841 }
4842 
4843 static u32
4844 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4845 {
4846 	strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN);
4847 
4848 	put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4849 
4850 	put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4851 
4852 	memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4853 
4854 	return ie_len + VNDR_IE_HDR_SIZE;
4855 }
4856 
4857 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4858 			  const u8 *vndr_ie_buf, u32 vndr_ie_len)
4859 {
4860 	struct brcmf_pub *drvr;
4861 	struct brcmf_if *ifp;
4862 	struct vif_saved_ie *saved_ie;
4863 	s32 err = 0;
4864 	u8  *iovar_ie_buf;
4865 	u8  *curr_ie_buf;
4866 	u8  *mgmt_ie_buf = NULL;
4867 	int mgmt_ie_buf_len;
4868 	u32 *mgmt_ie_len;
4869 	u32 del_add_ie_buf_len = 0;
4870 	u32 total_ie_buf_len = 0;
4871 	u32 parsed_ie_buf_len = 0;
4872 	struct parsed_vndr_ies old_vndr_ies;
4873 	struct parsed_vndr_ies new_vndr_ies;
4874 	struct parsed_vndr_ie_info *vndrie_info;
4875 	s32 i;
4876 	u8 *ptr;
4877 	int remained_buf_len;
4878 
4879 	if (!vif)
4880 		return -ENODEV;
4881 	ifp = vif->ifp;
4882 	drvr = ifp->drvr;
4883 	saved_ie = &vif->saved_ie;
4884 
4885 	brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4886 		  pktflag);
4887 	iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4888 	if (!iovar_ie_buf)
4889 		return -ENOMEM;
4890 	curr_ie_buf = iovar_ie_buf;
4891 	switch (pktflag) {
4892 	case BRCMF_VNDR_IE_PRBREQ_FLAG:
4893 		mgmt_ie_buf = saved_ie->probe_req_ie;
4894 		mgmt_ie_len = &saved_ie->probe_req_ie_len;
4895 		mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4896 		break;
4897 	case BRCMF_VNDR_IE_PRBRSP_FLAG:
4898 		mgmt_ie_buf = saved_ie->probe_res_ie;
4899 		mgmt_ie_len = &saved_ie->probe_res_ie_len;
4900 		mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4901 		break;
4902 	case BRCMF_VNDR_IE_BEACON_FLAG:
4903 		mgmt_ie_buf = saved_ie->beacon_ie;
4904 		mgmt_ie_len = &saved_ie->beacon_ie_len;
4905 		mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4906 		break;
4907 	case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4908 		mgmt_ie_buf = saved_ie->assoc_req_ie;
4909 		mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4910 		mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4911 		break;
4912 	case BRCMF_VNDR_IE_ASSOCRSP_FLAG:
4913 		mgmt_ie_buf = saved_ie->assoc_res_ie;
4914 		mgmt_ie_len = &saved_ie->assoc_res_ie_len;
4915 		mgmt_ie_buf_len = sizeof(saved_ie->assoc_res_ie);
4916 		break;
4917 	default:
4918 		err = -EPERM;
4919 		bphy_err(drvr, "not suitable type\n");
4920 		goto exit;
4921 	}
4922 
4923 	if (vndr_ie_len > mgmt_ie_buf_len) {
4924 		err = -ENOMEM;
4925 		bphy_err(drvr, "extra IE size too big\n");
4926 		goto exit;
4927 	}
4928 
4929 	/* parse and save new vndr_ie in curr_ie_buff before comparing it */
4930 	if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4931 		ptr = curr_ie_buf;
4932 		brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4933 		for (i = 0; i < new_vndr_ies.count; i++) {
4934 			vndrie_info = &new_vndr_ies.ie_info[i];
4935 			memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4936 			       vndrie_info->ie_len);
4937 			parsed_ie_buf_len += vndrie_info->ie_len;
4938 		}
4939 	}
4940 
4941 	if (mgmt_ie_buf && *mgmt_ie_len) {
4942 		if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4943 		    (memcmp(mgmt_ie_buf, curr_ie_buf,
4944 			    parsed_ie_buf_len) == 0)) {
4945 			brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4946 			goto exit;
4947 		}
4948 
4949 		/* parse old vndr_ie */
4950 		brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4951 
4952 		/* make a command to delete old ie */
4953 		for (i = 0; i < old_vndr_ies.count; i++) {
4954 			vndrie_info = &old_vndr_ies.ie_info[i];
4955 
4956 			brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n",
4957 				  vndrie_info->vndrie.id,
4958 				  vndrie_info->vndrie.len,
4959 				  vndrie_info->vndrie.oui);
4960 
4961 			del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4962 							   vndrie_info->ie_ptr,
4963 							   vndrie_info->ie_len,
4964 							   "del");
4965 			curr_ie_buf += del_add_ie_buf_len;
4966 			total_ie_buf_len += del_add_ie_buf_len;
4967 		}
4968 	}
4969 
4970 	*mgmt_ie_len = 0;
4971 	/* Add if there is any extra IE */
4972 	if (mgmt_ie_buf && parsed_ie_buf_len) {
4973 		ptr = mgmt_ie_buf;
4974 
4975 		remained_buf_len = mgmt_ie_buf_len;
4976 
4977 		/* make a command to add new ie */
4978 		for (i = 0; i < new_vndr_ies.count; i++) {
4979 			vndrie_info = &new_vndr_ies.ie_info[i];
4980 
4981 			/* verify remained buf size before copy data */
4982 			if (remained_buf_len < (vndrie_info->vndrie.len +
4983 							VNDR_IE_VSIE_OFFSET)) {
4984 				bphy_err(drvr, "no space in mgmt_ie_buf: len left %d",
4985 					 remained_buf_len);
4986 				break;
4987 			}
4988 			remained_buf_len -= (vndrie_info->ie_len +
4989 					     VNDR_IE_VSIE_OFFSET);
4990 
4991 			brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n",
4992 				  vndrie_info->vndrie.id,
4993 				  vndrie_info->vndrie.len,
4994 				  vndrie_info->vndrie.oui);
4995 
4996 			del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4997 							   vndrie_info->ie_ptr,
4998 							   vndrie_info->ie_len,
4999 							   "add");
5000 
5001 			/* save the parsed IE in wl struct */
5002 			memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
5003 			       vndrie_info->ie_len);
5004 			*mgmt_ie_len += vndrie_info->ie_len;
5005 
5006 			curr_ie_buf += del_add_ie_buf_len;
5007 			total_ie_buf_len += del_add_ie_buf_len;
5008 		}
5009 	}
5010 	if (total_ie_buf_len) {
5011 		err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
5012 						 total_ie_buf_len);
5013 		if (err)
5014 			bphy_err(drvr, "vndr ie set error : %d\n", err);
5015 	}
5016 
5017 exit:
5018 	kfree(iovar_ie_buf);
5019 	return err;
5020 }
5021 
5022 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
5023 {
5024 	static const s32 pktflags[] = {
5025 		BRCMF_VNDR_IE_PRBRSP_FLAG,
5026 		BRCMF_VNDR_IE_BEACON_FLAG
5027 	};
5028 	int i;
5029 
5030 	if (vif->wdev.iftype == NL80211_IFTYPE_AP)
5031 		brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG, NULL, 0);
5032 	else
5033 		brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, NULL, 0);
5034 
5035 	for (i = 0; i < ARRAY_SIZE(pktflags); i++)
5036 		brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
5037 
5038 	memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
5039 	return 0;
5040 }
5041 
5042 static s32
5043 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
5044 			struct cfg80211_beacon_data *beacon)
5045 {
5046 	struct brcmf_pub *drvr = vif->ifp->drvr;
5047 	s32 err;
5048 
5049 	/* Set Beacon IEs to FW */
5050 	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
5051 				    beacon->tail, beacon->tail_len);
5052 	if (err) {
5053 		bphy_err(drvr, "Set Beacon IE Failed\n");
5054 		return err;
5055 	}
5056 	brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
5057 
5058 	/* Set Probe Response IEs to FW */
5059 	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
5060 				    beacon->proberesp_ies,
5061 				    beacon->proberesp_ies_len);
5062 	if (err)
5063 		bphy_err(drvr, "Set Probe Resp IE Failed\n");
5064 	else
5065 		brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
5066 
5067 	/* Set Assoc Response IEs to FW */
5068 	err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG,
5069 				    beacon->assocresp_ies,
5070 				    beacon->assocresp_ies_len);
5071 	if (err)
5072 		brcmf_err("Set Assoc Resp IE Failed\n");
5073 	else
5074 		brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc Resp\n");
5075 
5076 	return err;
5077 }
5078 
5079 static s32
5080 brcmf_parse_configure_security(struct brcmf_if *ifp,
5081 			       struct cfg80211_ap_settings *settings,
5082 			       enum nl80211_iftype dev_role)
5083 {
5084 	const struct brcmf_tlv *rsn_ie;
5085 	const struct brcmf_vs_tlv *wpa_ie;
5086 	s32 err = 0;
5087 
5088 	/* find the RSN_IE */
5089 	rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
5090 				  settings->beacon.tail_len, WLAN_EID_RSN);
5091 
5092 	/* find the WPA_IE */
5093 	wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
5094 				  settings->beacon.tail_len);
5095 
5096 	if (wpa_ie || rsn_ie) {
5097 		brcmf_dbg(TRACE, "WPA(2) IE is found\n");
5098 		if (wpa_ie) {
5099 			/* WPA IE */
5100 			err = brcmf_configure_wpaie(ifp, wpa_ie, false);
5101 			if (err < 0)
5102 				return err;
5103 		} else {
5104 			struct brcmf_vs_tlv *tmp_ie;
5105 
5106 			tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
5107 
5108 			/* RSN IE */
5109 			err = brcmf_configure_wpaie(ifp, tmp_ie, true);
5110 			if (err < 0)
5111 				return err;
5112 		}
5113 	} else {
5114 		brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
5115 		brcmf_configure_opensecurity(ifp);
5116 	}
5117 
5118 	return err;
5119 }
5120 
5121 static s32
5122 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
5123 			struct cfg80211_ap_settings *settings)
5124 {
5125 	s32 ie_offset;
5126 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5127 	struct brcmf_if *ifp = netdev_priv(ndev);
5128 	struct brcmf_pub *drvr = cfg->pub;
5129 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5130 	struct cfg80211_crypto_settings *crypto = &settings->crypto;
5131 	const struct brcmf_tlv *ssid_ie;
5132 	const struct brcmf_tlv *country_ie;
5133 	struct brcmf_ssid_le ssid_le;
5134 	s32 err = -EPERM;
5135 	struct brcmf_join_params join_params;
5136 	enum nl80211_iftype dev_role;
5137 	struct brcmf_fil_bss_enable_le bss_enable;
5138 	u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
5139 	bool mbss;
5140 	int is_11d;
5141 	bool supports_11d;
5142 	bool closednet;
5143 
5144 	brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
5145 		  settings->chandef.chan->hw_value,
5146 		  settings->chandef.center_freq1, settings->chandef.width,
5147 		  settings->beacon_interval, settings->dtim_period);
5148 	brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
5149 		  settings->ssid, settings->ssid_len, settings->auth_type,
5150 		  settings->inactivity_timeout);
5151 	dev_role = ifp->vif->wdev.iftype;
5152 	mbss = ifp->vif->mbss;
5153 
5154 	/* store current 11d setting */
5155 	if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
5156 				  &ifp->vif->is_11d)) {
5157 		is_11d = supports_11d = false;
5158 	} else {
5159 		country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
5160 					      settings->beacon.tail_len,
5161 					      WLAN_EID_COUNTRY);
5162 		is_11d = country_ie ? 1 : 0;
5163 		supports_11d = true;
5164 	}
5165 
5166 	memset(&ssid_le, 0, sizeof(ssid_le));
5167 	if (settings->ssid == NULL || settings->ssid_len == 0) {
5168 		ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
5169 		ssid_ie = brcmf_parse_tlvs(
5170 				(u8 *)&settings->beacon.head[ie_offset],
5171 				settings->beacon.head_len - ie_offset,
5172 				WLAN_EID_SSID);
5173 		if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
5174 			return -EINVAL;
5175 
5176 		memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
5177 		ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
5178 		brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
5179 	} else {
5180 		memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
5181 		ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
5182 	}
5183 
5184 	if (!mbss) {
5185 		brcmf_set_mpc(ifp, 0);
5186 		brcmf_configure_arp_nd_offload(ifp, false);
5187 	}
5188 
5189 	/* Parameters shared by all radio interfaces */
5190 	if (!mbss) {
5191 		if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
5192 			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
5193 						    is_11d);
5194 			if (err < 0) {
5195 				bphy_err(drvr, "Regulatory Set Error, %d\n",
5196 					 err);
5197 				goto exit;
5198 			}
5199 		}
5200 		if (settings->beacon_interval) {
5201 			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
5202 						    settings->beacon_interval);
5203 			if (err < 0) {
5204 				bphy_err(drvr, "Beacon Interval Set Error, %d\n",
5205 					 err);
5206 				goto exit;
5207 			}
5208 		}
5209 		if (settings->dtim_period) {
5210 			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
5211 						    settings->dtim_period);
5212 			if (err < 0) {
5213 				bphy_err(drvr, "DTIM Interval Set Error, %d\n",
5214 					 err);
5215 				goto exit;
5216 			}
5217 		}
5218 
5219 		if ((dev_role == NL80211_IFTYPE_AP) &&
5220 		    ((ifp->ifidx == 0) ||
5221 		     (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB) &&
5222 		      !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)))) {
5223 			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5224 			if (err < 0) {
5225 				bphy_err(drvr, "BRCMF_C_DOWN error %d\n",
5226 					 err);
5227 				goto exit;
5228 			}
5229 			brcmf_fil_iovar_int_set(ifp, "apsta", 0);
5230 		}
5231 
5232 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
5233 		if (err < 0) {
5234 			bphy_err(drvr, "SET INFRA error %d\n", err);
5235 			goto exit;
5236 		}
5237 	} else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
5238 		/* Multiple-BSS should use same 11d configuration */
5239 		err = -EINVAL;
5240 		goto exit;
5241 	}
5242 
5243 	/* Interface specific setup */
5244 	if (dev_role == NL80211_IFTYPE_AP) {
5245 		if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
5246 			brcmf_fil_iovar_int_set(ifp, "mbss", 1);
5247 
5248 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
5249 		if (err < 0) {
5250 			bphy_err(drvr, "setting AP mode failed %d\n",
5251 				 err);
5252 			goto exit;
5253 		}
5254 		if (!mbss) {
5255 			/* Firmware 10.x requires setting channel after enabling
5256 			 * AP and before bringing interface up.
5257 			 */
5258 			err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
5259 			if (err < 0) {
5260 				bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
5261 					 chanspec, err);
5262 				goto exit;
5263 			}
5264 		}
5265 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
5266 		if (err < 0) {
5267 			bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
5268 			goto exit;
5269 		}
5270 
5271 		if (crypto->psk) {
5272 			brcmf_dbg(INFO, "using PSK offload\n");
5273 			profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_PSK);
5274 			err = brcmf_set_pmk(ifp, crypto->psk,
5275 					    BRCMF_WSEC_MAX_PSK_LEN);
5276 			if (err < 0)
5277 				goto exit;
5278 		}
5279 		if (crypto->sae_pwd) {
5280 			brcmf_dbg(INFO, "using SAE offload\n");
5281 			profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_SAE);
5282 			err = brcmf_fwvid_set_sae_password(ifp, crypto);
5283 			if (err < 0)
5284 				goto exit;
5285 		}
5286 		if (profile->use_fwauth == 0)
5287 			profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
5288 
5289 		err = brcmf_parse_configure_security(ifp, settings,
5290 						     NL80211_IFTYPE_AP);
5291 		if (err < 0) {
5292 			bphy_err(drvr, "brcmf_parse_configure_security error\n");
5293 			goto exit;
5294 		}
5295 
5296 		/* On DOWN the firmware removes the WEP keys, reconfigure
5297 		 * them if they were set.
5298 		 */
5299 		brcmf_cfg80211_reconfigure_wep(ifp);
5300 
5301 		memset(&join_params, 0, sizeof(join_params));
5302 		/* join parameters starts with ssid */
5303 		memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
5304 		/* create softap */
5305 		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
5306 					     &join_params, sizeof(join_params));
5307 		if (err < 0) {
5308 			bphy_err(drvr, "SET SSID error (%d)\n", err);
5309 			goto exit;
5310 		}
5311 
5312 		closednet =
5313 			(settings->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
5314 		err = brcmf_fil_iovar_int_set(ifp, "closednet",	closednet);
5315 		if (err) {
5316 			bphy_err(drvr, "%s closednet error (%d)\n",
5317 				 (closednet ? "enabled" : "disabled"),
5318 				 err);
5319 			goto exit;
5320 		}
5321 
5322 		brcmf_dbg(TRACE, "AP mode configuration complete\n");
5323 	} else if (dev_role == NL80211_IFTYPE_P2P_GO) {
5324 		err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
5325 		if (err < 0) {
5326 			bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
5327 				 chanspec, err);
5328 			goto exit;
5329 		}
5330 
5331 		err = brcmf_parse_configure_security(ifp, settings,
5332 						     NL80211_IFTYPE_P2P_GO);
5333 		if (err < 0) {
5334 			brcmf_err("brcmf_parse_configure_security error\n");
5335 			goto exit;
5336 		}
5337 
5338 		err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
5339 						sizeof(ssid_le));
5340 		if (err < 0) {
5341 			bphy_err(drvr, "setting ssid failed %d\n", err);
5342 			goto exit;
5343 		}
5344 		bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
5345 		bss_enable.enable = cpu_to_le32(1);
5346 		err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
5347 					       sizeof(bss_enable));
5348 		if (err < 0) {
5349 			bphy_err(drvr, "bss_enable config failed %d\n", err);
5350 			goto exit;
5351 		}
5352 
5353 		brcmf_dbg(TRACE, "GO mode configuration complete\n");
5354 	} else {
5355 		WARN_ON(1);
5356 	}
5357 
5358 	brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
5359 	set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
5360 	brcmf_net_setcarrier(ifp, true);
5361 
5362 exit:
5363 	if ((err) && (!mbss)) {
5364 		brcmf_set_mpc(ifp, 1);
5365 		brcmf_configure_arp_nd_offload(ifp, true);
5366 	}
5367 	return err;
5368 }
5369 
5370 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
5371 				  unsigned int link_id)
5372 {
5373 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5374 	struct brcmf_if *ifp = netdev_priv(ndev);
5375 	struct brcmf_pub *drvr = cfg->pub;
5376 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5377 	s32 err;
5378 	struct brcmf_fil_bss_enable_le bss_enable;
5379 	struct brcmf_join_params join_params;
5380 
5381 	brcmf_dbg(TRACE, "Enter\n");
5382 
5383 	if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
5384 		/* Due to most likely deauths outstanding we sleep */
5385 		/* first to make sure they get processed by fw. */
5386 		msleep(400);
5387 
5388 		if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
5389 			struct cfg80211_crypto_settings crypto = {};
5390 
5391 			if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
5392 				brcmf_set_pmk(ifp, NULL, 0);
5393 			if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE))
5394 				brcmf_fwvid_set_sae_password(ifp, &crypto);
5395 			profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
5396 		}
5397 
5398 		if (ifp->vif->mbss) {
5399 			err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5400 			return err;
5401 		}
5402 
5403 		/* First BSS doesn't get a full reset */
5404 		if (ifp->bsscfgidx == 0)
5405 			brcmf_fil_iovar_int_set(ifp, "closednet", 0);
5406 
5407 		memset(&join_params, 0, sizeof(join_params));
5408 		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
5409 					     &join_params, sizeof(join_params));
5410 		if (err < 0)
5411 			bphy_err(drvr, "SET SSID error (%d)\n", err);
5412 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5413 		if (err < 0)
5414 			bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
5415 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
5416 		if (err < 0)
5417 			bphy_err(drvr, "setting AP mode failed %d\n", err);
5418 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
5419 			brcmf_fil_iovar_int_set(ifp, "mbss", 0);
5420 		brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
5421 				      ifp->vif->is_11d);
5422 		/* Bring device back up so it can be used again */
5423 		err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
5424 		if (err < 0)
5425 			bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
5426 
5427 		brcmf_vif_clear_mgmt_ies(ifp->vif);
5428 	} else {
5429 		bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
5430 		bss_enable.enable = cpu_to_le32(0);
5431 		err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
5432 					       sizeof(bss_enable));
5433 		if (err < 0)
5434 			bphy_err(drvr, "bss_enable config failed %d\n", err);
5435 	}
5436 	brcmf_set_mpc(ifp, 1);
5437 	clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
5438 	brcmf_configure_arp_nd_offload(ifp, true);
5439 	brcmf_net_setcarrier(ifp, false);
5440 
5441 	return err;
5442 }
5443 
5444 static s32
5445 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
5446 			     struct cfg80211_ap_update *info)
5447 {
5448 	struct brcmf_if *ifp = netdev_priv(ndev);
5449 
5450 	brcmf_dbg(TRACE, "Enter\n");
5451 
5452 	return brcmf_config_ap_mgmt_ie(ifp->vif, &info->beacon);
5453 }
5454 
5455 static int
5456 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct wireless_dev *wdev,
5457 			   struct station_del_parameters *params)
5458 {
5459 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5460 	struct brcmf_pub *drvr = cfg->pub;
5461 	struct brcmf_scb_val_le scbval;
5462 	struct net_device *ndev = wdev->netdev;
5463 	struct brcmf_if *ifp = netdev_priv(ndev);
5464 	s32 err;
5465 
5466 	if (!params->mac)
5467 		return -EFAULT;
5468 
5469 	brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
5470 
5471 	if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
5472 		ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
5473 	if (!check_vif_up(ifp->vif))
5474 		return -EIO;
5475 
5476 	memcpy(&scbval.ea, params->mac, ETH_ALEN);
5477 	scbval.val = cpu_to_le32(params->reason_code);
5478 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
5479 				     &scbval, sizeof(scbval));
5480 	if (err)
5481 		bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
5482 			 err);
5483 
5484 	brcmf_dbg(TRACE, "Exit\n");
5485 	return err;
5486 }
5487 
5488 static int
5489 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct wireless_dev *wdev,
5490 			      const u8 *mac, struct station_parameters *params)
5491 {
5492 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5493 	struct brcmf_pub *drvr = cfg->pub;
5494 	struct brcmf_if *ifp = netdev_priv(wdev->netdev);
5495 	s32 err;
5496 
5497 	brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
5498 		  params->sta_flags_mask, params->sta_flags_set);
5499 
5500 	/* Ignore all 00 MAC */
5501 	if (is_zero_ether_addr(mac))
5502 		return 0;
5503 
5504 	if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5505 		return 0;
5506 
5507 	if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
5508 		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
5509 					     (void *)mac, ETH_ALEN);
5510 	else
5511 		err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
5512 					     (void *)mac, ETH_ALEN);
5513 	if (err < 0)
5514 		bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
5515 
5516 	return err;
5517 }
5518 
5519 static void
5520 brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
5521 					       struct wireless_dev *wdev,
5522 					       struct mgmt_frame_regs *upd)
5523 {
5524 	struct brcmf_cfg80211_vif *vif;
5525 
5526 	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5527 
5528 	vif->mgmt_rx_reg = upd->interface_stypes;
5529 }
5530 
5531 
5532 int
5533 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
5534 		       struct cfg80211_mgmt_tx_params *params, u64 *cookie)
5535 {
5536 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5537 	struct ieee80211_channel *chan = params->chan;
5538 	struct brcmf_pub *drvr = cfg->pub;
5539 	const u8 *buf = params->buf;
5540 	size_t len = params->len;
5541 	const struct ieee80211_mgmt *mgmt;
5542 	struct brcmf_cfg80211_vif *vif;
5543 	s32 err = 0;
5544 	s32 ie_offset;
5545 	s32 ie_len;
5546 	struct brcmf_fil_action_frame_le *action_frame;
5547 	struct brcmf_fil_af_params_le *af_params;
5548 	bool ack;
5549 	__le32 hw_ch;
5550 
5551 	brcmf_dbg(TRACE, "Enter\n");
5552 
5553 	*cookie = 0;
5554 
5555 	mgmt = (const struct ieee80211_mgmt *)buf;
5556 
5557 	if (!ieee80211_is_mgmt(mgmt->frame_control)) {
5558 		bphy_err(drvr, "Driver only allows MGMT packet type\n");
5559 		return -EPERM;
5560 	}
5561 
5562 	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5563 
5564 	if (ieee80211_is_probe_resp(mgmt->frame_control)) {
5565 		/* Right now the only reason to get a probe response */
5566 		/* is for p2p listen response or for p2p GO from     */
5567 		/* wpa_supplicant. Unfortunately the probe is send   */
5568 		/* on primary ndev, while dongle wants it on the p2p */
5569 		/* vif. Since this is only reason for a probe        */
5570 		/* response to be sent, the vif is taken from cfg.   */
5571 		/* If ever desired to send proberesp for non p2p     */
5572 		/* response then data should be checked for          */
5573 		/* "DIRECT-". Note in future supplicant will take    */
5574 		/* dedicated p2p wdev to do this and then this 'hack'*/
5575 		/* is not needed anymore.                            */
5576 		ie_offset =  DOT11_MGMT_HDR_LEN +
5577 			     DOT11_BCN_PRB_FIXED_LEN;
5578 		ie_len = len - ie_offset;
5579 		if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
5580 			vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5581 		err = brcmf_vif_set_mgmt_ie(vif,
5582 					    BRCMF_VNDR_IE_PRBRSP_FLAG,
5583 					    &buf[ie_offset],
5584 					    ie_len);
5585 		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
5586 					GFP_KERNEL);
5587 	} else if (ieee80211_is_action(mgmt->frame_control)) {
5588 		if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
5589 			bphy_err(drvr, "invalid action frame length\n");
5590 			err = -EINVAL;
5591 			goto exit;
5592 		}
5593 		af_params = kzalloc_obj(*af_params);
5594 		if (af_params == NULL) {
5595 			bphy_err(drvr, "unable to allocate frame\n");
5596 			err = -ENOMEM;
5597 			goto exit;
5598 		}
5599 		action_frame = &af_params->action_frame;
5600 		/* Add the packet Id */
5601 		action_frame->packet_id = cpu_to_le32(*cookie);
5602 		/* Add BSSID */
5603 		memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
5604 		memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
5605 		/* Add the length exepted for 802.11 header  */
5606 		action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
5607 		/* Add the channel. Use the one specified as parameter if any or
5608 		 * the current one (got from the firmware) otherwise
5609 		 */
5610 		if (chan) {
5611 			hw_ch = cpu_to_le32(chan->hw_value);
5612 		} else {
5613 			err = brcmf_fil_cmd_data_get(vif->ifp,
5614 						     BRCMF_C_GET_CHANNEL,
5615 						     &hw_ch, sizeof(hw_ch));
5616 			if (err) {
5617 				bphy_err(drvr,
5618 					 "unable to get current hw channel\n");
5619 				goto free;
5620 			}
5621 		}
5622 		af_params->channel = hw_ch;
5623 
5624 		af_params->dwell_time = cpu_to_le32(params->wait);
5625 		memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
5626 		       le16_to_cpu(action_frame->len));
5627 
5628 		brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, channel=%d\n",
5629 			  *cookie, le16_to_cpu(action_frame->len),
5630 			  le32_to_cpu(af_params->channel));
5631 
5632 		ack = brcmf_p2p_send_action_frame(vif->ifp, af_params);
5633 
5634 		cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
5635 					GFP_KERNEL);
5636 free:
5637 		kfree(af_params);
5638 	} else {
5639 		brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
5640 		brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
5641 	}
5642 
5643 exit:
5644 	return err;
5645 }
5646 BRCMF_EXPORT_SYMBOL_GPL(brcmf_cfg80211_mgmt_tx);
5647 
5648 static int brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
5649 						    struct net_device *ndev,
5650 						    s32 rssi_low, s32 rssi_high)
5651 {
5652 	struct brcmf_cfg80211_vif *vif;
5653 	struct brcmf_if *ifp;
5654 	int err = 0;
5655 
5656 	brcmf_dbg(TRACE, "low=%d high=%d", rssi_low, rssi_high);
5657 
5658 	ifp = netdev_priv(ndev);
5659 	vif = ifp->vif;
5660 
5661 	if (rssi_low != vif->cqm_rssi_low || rssi_high != vif->cqm_rssi_high) {
5662 		/* The firmware will send an event when the RSSI is less than or
5663 		 * equal to a configured level and the previous RSSI event was
5664 		 * less than or equal to a different level. Set a third level
5665 		 * so that we also detect the transition from rssi <= rssi_high
5666 		 * to rssi > rssi_high.
5667 		 */
5668 		struct brcmf_rssi_event_le config = {
5669 			.rate_limit_msec = cpu_to_le32(0),
5670 			.rssi_level_num = 3,
5671 			.rssi_levels = {
5672 				clamp_val(rssi_low, S8_MIN, S8_MAX - 2),
5673 				clamp_val(rssi_high, S8_MIN + 1, S8_MAX - 1),
5674 				S8_MAX,
5675 			},
5676 		};
5677 
5678 		err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &config,
5679 					       sizeof(config));
5680 		if (err) {
5681 			err = -EINVAL;
5682 		} else {
5683 			vif->cqm_rssi_low = rssi_low;
5684 			vif->cqm_rssi_high = rssi_high;
5685 		}
5686 	}
5687 
5688 	return err;
5689 }
5690 
5691 static int
5692 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
5693 					struct wireless_dev *wdev,
5694 					u64 cookie)
5695 {
5696 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5697 	struct brcmf_pub *drvr = cfg->pub;
5698 	struct brcmf_cfg80211_vif *vif;
5699 	int err = 0;
5700 
5701 	brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
5702 
5703 	vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5704 	if (vif == NULL) {
5705 		bphy_err(drvr, "No p2p device available for probe response\n");
5706 		err = -ENODEV;
5707 		goto exit;
5708 	}
5709 	brcmf_p2p_cancel_remain_on_channel(vif->ifp);
5710 exit:
5711 	return err;
5712 }
5713 
5714 static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
5715 				      struct wireless_dev *wdev,
5716 				      unsigned int link_id,
5717 				      struct cfg80211_chan_def *chandef)
5718 {
5719 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5720 	struct net_device *ndev = wdev->netdev;
5721 	struct brcmf_pub *drvr = cfg->pub;
5722 	struct brcmu_chan ch;
5723 	enum nl80211_band band = 0;
5724 	enum nl80211_chan_width width = 0;
5725 	u32 chanspec;
5726 	int freq, err;
5727 
5728 	if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP)
5729 		return -ENODEV;
5730 
5731 	err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec);
5732 	if (err) {
5733 		bphy_err(drvr, "chanspec failed (%d)\n", err);
5734 		return err;
5735 	}
5736 
5737 	ch.chspec = chanspec;
5738 	cfg->d11inf.decchspec(&ch);
5739 
5740 	switch (ch.band) {
5741 	case BRCMU_CHAN_BAND_2G:
5742 		band = NL80211_BAND_2GHZ;
5743 		break;
5744 	case BRCMU_CHAN_BAND_5G:
5745 		band = NL80211_BAND_5GHZ;
5746 		break;
5747 	}
5748 
5749 	switch (ch.bw) {
5750 	case BRCMU_CHAN_BW_80:
5751 		width = NL80211_CHAN_WIDTH_80;
5752 		break;
5753 	case BRCMU_CHAN_BW_40:
5754 		width = NL80211_CHAN_WIDTH_40;
5755 		break;
5756 	case BRCMU_CHAN_BW_20:
5757 		width = NL80211_CHAN_WIDTH_20;
5758 		break;
5759 	case BRCMU_CHAN_BW_80P80:
5760 		width = NL80211_CHAN_WIDTH_80P80;
5761 		break;
5762 	case BRCMU_CHAN_BW_160:
5763 		width = NL80211_CHAN_WIDTH_160;
5764 		break;
5765 	}
5766 
5767 	freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
5768 	chandef->chan = ieee80211_get_channel(wiphy, freq);
5769 	chandef->width = width;
5770 	chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
5771 	chandef->center_freq2 = 0;
5772 
5773 	return 0;
5774 }
5775 
5776 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
5777 					   struct wireless_dev *wdev,
5778 					   enum nl80211_crit_proto_id proto,
5779 					   u16 duration)
5780 {
5781 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5782 	struct brcmf_cfg80211_vif *vif;
5783 
5784 	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5785 
5786 	/* only DHCP support for now */
5787 	if (proto != NL80211_CRIT_PROTO_DHCP)
5788 		return -EINVAL;
5789 
5790 	/* suppress and abort scanning */
5791 	set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5792 	brcmf_abort_scanning(cfg);
5793 
5794 	return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
5795 }
5796 
5797 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
5798 					   struct wireless_dev *wdev)
5799 {
5800 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5801 	struct brcmf_cfg80211_vif *vif;
5802 
5803 	vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5804 
5805 	brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
5806 	clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5807 }
5808 
5809 static s32
5810 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
5811 			     const struct brcmf_event_msg *e, void *data)
5812 {
5813 	switch (e->reason) {
5814 	case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5815 		brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5816 		break;
5817 	case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5818 		brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5819 		brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5820 		break;
5821 	case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5822 		brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5823 		brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5824 		break;
5825 	}
5826 
5827 	return 0;
5828 }
5829 
5830 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5831 {
5832 	int ret;
5833 
5834 	switch (oper) {
5835 	case NL80211_TDLS_DISCOVERY_REQ:
5836 		ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5837 		break;
5838 	case NL80211_TDLS_SETUP:
5839 		ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5840 		break;
5841 	case NL80211_TDLS_TEARDOWN:
5842 		ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5843 		break;
5844 	default:
5845 		brcmf_err("unsupported operation: %d\n", oper);
5846 		ret = -EOPNOTSUPP;
5847 	}
5848 	return ret;
5849 }
5850 
5851 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5852 				    struct net_device *ndev, const u8 *peer,
5853 				    enum nl80211_tdls_operation oper)
5854 {
5855 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5856 	struct brcmf_pub *drvr = cfg->pub;
5857 	struct brcmf_if *ifp;
5858 	struct brcmf_tdls_iovar_le info;
5859 	int ret = 0;
5860 
5861 	ret = brcmf_convert_nl80211_tdls_oper(oper);
5862 	if (ret < 0)
5863 		return ret;
5864 
5865 	ifp = netdev_priv(ndev);
5866 	memset(&info, 0, sizeof(info));
5867 	info.mode = (u8)ret;
5868 	if (peer)
5869 		memcpy(info.ea, peer, ETH_ALEN);
5870 
5871 	ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5872 				       &info, sizeof(info));
5873 	if (ret < 0)
5874 		bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
5875 
5876 	return ret;
5877 }
5878 
5879 static int
5880 brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
5881 				  struct net_device *ndev,
5882 				  struct cfg80211_connect_params *sme,
5883 				  u32 changed)
5884 {
5885 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5886 	struct brcmf_pub *drvr = cfg->pub;
5887 	struct brcmf_if *ifp;
5888 	int err;
5889 
5890 	if (!(changed & UPDATE_ASSOC_IES))
5891 		return 0;
5892 
5893 	ifp = netdev_priv(ndev);
5894 	err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
5895 				    sme->ie, sme->ie_len);
5896 	if (err)
5897 		bphy_err(drvr, "Set Assoc REQ IE Failed\n");
5898 	else
5899 		brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
5900 
5901 	return err;
5902 }
5903 
5904 #ifdef CONFIG_PM
5905 static int
5906 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5907 			      struct cfg80211_gtk_rekey_data *gtk)
5908 {
5909 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5910 	struct brcmf_pub *drvr = cfg->pub;
5911 	struct brcmf_if *ifp = netdev_priv(ndev);
5912 	struct brcmf_gtk_keyinfo_le gtk_le;
5913 	int ret;
5914 
5915 	brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5916 
5917 	memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5918 	memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5919 	memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5920 	       sizeof(gtk_le.replay_counter));
5921 
5922 	ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", &gtk_le,
5923 				       sizeof(gtk_le));
5924 	if (ret < 0)
5925 		bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
5926 
5927 	return ret;
5928 }
5929 #endif
5930 
5931 static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
5932 				  const struct cfg80211_pmk_conf *conf)
5933 {
5934 	struct brcmf_if *ifp;
5935 
5936 	brcmf_dbg(TRACE, "enter\n");
5937 
5938 	/* expect using firmware supplicant for 1X */
5939 	ifp = netdev_priv(dev);
5940 	if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5941 		return -EINVAL;
5942 
5943 	if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
5944 		return -ERANGE;
5945 
5946 	return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
5947 }
5948 
5949 static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
5950 				  const u8 *aa)
5951 {
5952 	struct brcmf_if *ifp;
5953 
5954 	brcmf_dbg(TRACE, "enter\n");
5955 	ifp = netdev_priv(dev);
5956 	if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5957 		return -EINVAL;
5958 
5959 	return brcmf_set_pmk(ifp, NULL, 0);
5960 }
5961 
5962 static int brcmf_cfg80211_change_bss(struct wiphy *wiphy, struct net_device *dev,
5963 				     struct bss_parameters *params)
5964 {
5965 	struct brcmf_if *ifp = netdev_priv(dev);
5966 	int ret = 0;
5967 
5968 	/* In AP mode, the "ap_isolate" value represents
5969 	 *  0 = allow low-level bridging of frames between associated stations
5970 	 *  1 = restrict low-level bridging of frames to isolate associated stations
5971 	 * -1 = do not change existing setting
5972 	 */
5973 	if (params->ap_isolate >= 0) {
5974 		ret = brcmf_fil_iovar_int_set(ifp, "ap_isolate", params->ap_isolate);
5975 		if (ret < 0)
5976 			brcmf_err("ap_isolate iovar failed: ret=%d\n", ret);
5977 	}
5978 
5979 	return ret;
5980 }
5981 
5982 static struct cfg80211_ops brcmf_cfg80211_ops = {
5983 	.add_virtual_intf = brcmf_cfg80211_add_iface,
5984 	.del_virtual_intf = brcmf_cfg80211_del_iface,
5985 	.change_virtual_intf = brcmf_cfg80211_change_iface,
5986 	.scan = brcmf_cfg80211_scan,
5987 	.set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5988 	.join_ibss = brcmf_cfg80211_join_ibss,
5989 	.leave_ibss = brcmf_cfg80211_leave_ibss,
5990 	.get_station = brcmf_cfg80211_get_station,
5991 	.dump_station = brcmf_cfg80211_dump_station,
5992 	.set_tx_power = brcmf_cfg80211_set_tx_power,
5993 	.get_tx_power = brcmf_cfg80211_get_tx_power,
5994 	.add_key = brcmf_cfg80211_add_key,
5995 	.del_key = brcmf_cfg80211_del_key,
5996 	.get_key = brcmf_cfg80211_get_key,
5997 	.set_default_key = brcmf_cfg80211_config_default_key,
5998 	.set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5999 	.set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
6000 	.connect = brcmf_cfg80211_connect,
6001 	.disconnect = brcmf_cfg80211_disconnect,
6002 	.suspend = brcmf_cfg80211_suspend,
6003 	.resume = brcmf_cfg80211_resume,
6004 	.set_pmksa = brcmf_cfg80211_set_pmksa,
6005 	.del_pmksa = brcmf_cfg80211_del_pmksa,
6006 	.flush_pmksa = brcmf_cfg80211_flush_pmksa,
6007 	.start_ap = brcmf_cfg80211_start_ap,
6008 	.stop_ap = brcmf_cfg80211_stop_ap,
6009 	.change_beacon = brcmf_cfg80211_change_beacon,
6010 	.del_station = brcmf_cfg80211_del_station,
6011 	.change_station = brcmf_cfg80211_change_station,
6012 	.sched_scan_start = brcmf_cfg80211_sched_scan_start,
6013 	.sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
6014 	.update_mgmt_frame_registrations =
6015 		brcmf_cfg80211_update_mgmt_frame_registrations,
6016 	.mgmt_tx = brcmf_cfg80211_mgmt_tx,
6017 	.set_cqm_rssi_range_config = brcmf_cfg80211_set_cqm_rssi_range_config,
6018 	.remain_on_channel = brcmf_p2p_remain_on_channel,
6019 	.cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
6020 	.get_channel = brcmf_cfg80211_get_channel,
6021 	.start_p2p_device = brcmf_p2p_start_device,
6022 	.stop_p2p_device = brcmf_p2p_stop_device,
6023 	.crit_proto_start = brcmf_cfg80211_crit_proto_start,
6024 	.crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
6025 	.tdls_oper = brcmf_cfg80211_tdls_oper,
6026 	.update_connect_params = brcmf_cfg80211_update_conn_params,
6027 	.set_pmk = brcmf_cfg80211_set_pmk,
6028 	.del_pmk = brcmf_cfg80211_del_pmk,
6029 	.change_bss = brcmf_cfg80211_change_bss,
6030 };
6031 
6032 struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
6033 {
6034 	struct cfg80211_ops *ops;
6035 
6036 	ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
6037 		       GFP_KERNEL);
6038 
6039 	if (ops && settings->roamoff)
6040 		ops->update_connect_params = NULL;
6041 
6042 	return ops;
6043 }
6044 
6045 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
6046 					   enum nl80211_iftype type)
6047 {
6048 	struct brcmf_cfg80211_vif *vif_walk;
6049 	struct brcmf_cfg80211_vif *vif;
6050 	bool mbss;
6051 	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6052 
6053 	brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
6054 		  sizeof(*vif));
6055 	vif = kzalloc_obj(*vif);
6056 	if (!vif)
6057 		return ERR_PTR(-ENOMEM);
6058 
6059 	vif->wdev.wiphy = cfg->wiphy;
6060 	vif->wdev.iftype = type;
6061 	init_completion(&vif->mgmt_tx);
6062 
6063 	brcmf_init_prof(&vif->profile);
6064 
6065 	if (type == NL80211_IFTYPE_AP &&
6066 	    brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
6067 		mbss = false;
6068 		list_for_each_entry(vif_walk, &cfg->vif_list, list) {
6069 			if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
6070 				mbss = true;
6071 				break;
6072 			}
6073 		}
6074 		vif->mbss = mbss;
6075 	}
6076 
6077 	list_add_tail(&vif->list, &cfg->vif_list);
6078 	return vif;
6079 }
6080 
6081 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
6082 {
6083 	list_del(&vif->list);
6084 	kfree(vif);
6085 }
6086 
6087 void brcmf_cfg80211_free_vif(struct net_device *ndev)
6088 {
6089 	struct brcmf_cfg80211_vif *vif;
6090 	struct brcmf_if *ifp;
6091 
6092 	ifp = netdev_priv(ndev);
6093 	vif = ifp->vif;
6094 
6095 	if (vif)
6096 		brcmf_free_vif(vif);
6097 }
6098 
6099 static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
6100 			    const struct brcmf_event_msg *e)
6101 {
6102 	u32 event = e->event_code;
6103 	u32 status = e->status;
6104 
6105 	if ((vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK ||
6106 	     vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_SAE) &&
6107 	    event == BRCMF_E_PSK_SUP &&
6108 	    status == BRCMF_E_STATUS_FWSUP_COMPLETED)
6109 		set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6110 	if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
6111 		brcmf_dbg(CONN, "Processing set ssid\n");
6112 		memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
6113 		if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK &&
6114 		    vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_SAE)
6115 			return true;
6116 
6117 		set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6118 	}
6119 
6120 	if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
6121 	    test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
6122 		clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6123 		clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6124 		return true;
6125 	}
6126 	return false;
6127 }
6128 
6129 static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif,
6130 			    const struct brcmf_event_msg *e)
6131 {
6132 	u32 event = e->event_code;
6133 	u16 flags = e->flags;
6134 
6135 	if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
6136 	    (event == BRCMF_E_DISASSOC_IND) ||
6137 	    ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
6138 		brcmf_dbg(CONN, "Processing link down\n");
6139 		clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6140 		clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6141 		return true;
6142 	}
6143 	return false;
6144 }
6145 
6146 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
6147 			       const struct brcmf_event_msg *e)
6148 {
6149 	u32 event = e->event_code;
6150 	u32 status = e->status;
6151 
6152 	if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
6153 		brcmf_dbg(CONN, "Processing Link %s & no network found\n",
6154 			  e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
6155 		return true;
6156 	}
6157 
6158 	if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
6159 		brcmf_dbg(CONN, "Processing connecting & no network found\n");
6160 		return true;
6161 	}
6162 
6163 	if (event == BRCMF_E_PSK_SUP &&
6164 	    status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
6165 		brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
6166 			  status);
6167 		return true;
6168 	}
6169 
6170 	return false;
6171 }
6172 
6173 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
6174 {
6175 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6176 
6177 	kfree(conn_info->req_ie);
6178 	conn_info->req_ie = NULL;
6179 	conn_info->req_ie_len = 0;
6180 	kfree(conn_info->resp_ie);
6181 	conn_info->resp_ie = NULL;
6182 	conn_info->resp_ie_len = 0;
6183 }
6184 
6185 u8 brcmf_map_prio_to_prec(void *config, u8 prio)
6186 {
6187 	struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
6188 
6189 	if (!cfg)
6190 		return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
6191 		       (prio ^ 2) : prio;
6192 
6193 	/* For those AC(s) with ACM flag set to 1, convert its 4-level priority
6194 	 * to an 8-level precedence which is the same as BE's
6195 	 */
6196 	if (prio > PRIO_8021D_EE &&
6197 	    cfg->ac_priority[prio] == cfg->ac_priority[PRIO_8021D_BE])
6198 		return cfg->ac_priority[prio] * 2;
6199 
6200 	/* Conversion of 4-level priority to 8-level precedence */
6201 	if (prio == PRIO_8021D_BE || prio == PRIO_8021D_BK ||
6202 	    prio == PRIO_8021D_CL || prio == PRIO_8021D_VO)
6203 		return cfg->ac_priority[prio] * 2;
6204 	else
6205 		return cfg->ac_priority[prio] * 2 + 1;
6206 }
6207 
6208 u8 brcmf_map_prio_to_aci(void *config, u8 prio)
6209 {
6210 	/* Prio here refers to the 802.1d priority in range of 0 to 7.
6211 	 * ACI here refers to the WLAN AC Index in range of 0 to 3.
6212 	 * This function will return ACI corresponding to input prio.
6213 	 */
6214 	struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
6215 
6216 	if (cfg)
6217 		return cfg->ac_priority[prio];
6218 
6219 	return prio;
6220 }
6221 
6222 static void brcmf_init_wmm_prio(u8 *priority)
6223 {
6224 	/* Initialize AC priority array to default
6225 	 * 802.1d priority as per following table:
6226 	 * 802.1d prio 0,3 maps to BE
6227 	 * 802.1d prio 1,2 maps to BK
6228 	 * 802.1d prio 4,5 maps to VI
6229 	 * 802.1d prio 6,7 maps to VO
6230 	 */
6231 	priority[0] = BRCMF_FWS_FIFO_AC_BE;
6232 	priority[3] = BRCMF_FWS_FIFO_AC_BE;
6233 	priority[1] = BRCMF_FWS_FIFO_AC_BK;
6234 	priority[2] = BRCMF_FWS_FIFO_AC_BK;
6235 	priority[4] = BRCMF_FWS_FIFO_AC_VI;
6236 	priority[5] = BRCMF_FWS_FIFO_AC_VI;
6237 	priority[6] = BRCMF_FWS_FIFO_AC_VO;
6238 	priority[7] = BRCMF_FWS_FIFO_AC_VO;
6239 }
6240 
6241 static void brcmf_wifi_prioritize_acparams(const
6242 	struct brcmf_cfg80211_edcf_acparam *acp, u8 *priority)
6243 {
6244 	u8 aci;
6245 	u8 aifsn;
6246 	u8 ecwmin;
6247 	u8 ecwmax;
6248 	u8 acm;
6249 	u8 ranking_basis[EDCF_AC_COUNT];
6250 	u8 aci_prio[EDCF_AC_COUNT]; /* AC_BE, AC_BK, AC_VI, AC_VO */
6251 	u8 index;
6252 
6253 	for (aci = 0; aci < EDCF_AC_COUNT; aci++, acp++) {
6254 		aifsn  = acp->ACI & EDCF_AIFSN_MASK;
6255 		acm = (acp->ACI & EDCF_ACM_MASK) ? 1 : 0;
6256 		ecwmin = acp->ECW & EDCF_ECWMIN_MASK;
6257 		ecwmax = (acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT;
6258 		brcmf_dbg(CONN, "ACI %d aifsn %d acm %d ecwmin %d ecwmax %d\n",
6259 			  aci, aifsn, acm, ecwmin, ecwmax);
6260 		/* Default AC_VO will be the lowest ranking value */
6261 		ranking_basis[aci] = aifsn + ecwmin + ecwmax;
6262 		/* Initialise priority starting at 0 (AC_BE) */
6263 		aci_prio[aci] = 0;
6264 
6265 		/* If ACM is set, STA can't use this AC as per 802.11.
6266 		 * Change the ranking to BE
6267 		 */
6268 		if (aci != AC_BE && aci != AC_BK && acm == 1)
6269 			ranking_basis[aci] = ranking_basis[AC_BE];
6270 	}
6271 
6272 	/* Ranking method which works for AC priority
6273 	 * swapping when values for cwmin, cwmax and aifsn are varied
6274 	 * Compare each aci_prio against each other aci_prio
6275 	 */
6276 	for (aci = 0; aci < EDCF_AC_COUNT; aci++) {
6277 		for (index = 0; index < EDCF_AC_COUNT; index++) {
6278 			if (index != aci) {
6279 				/* Smaller ranking value has higher priority,
6280 				 * so increment priority for each ACI which has
6281 				 * a higher ranking value
6282 				 */
6283 				if (ranking_basis[aci] < ranking_basis[index])
6284 					aci_prio[aci]++;
6285 			}
6286 		}
6287 	}
6288 
6289 	/* By now, aci_prio[] will be in range of 0 to 3.
6290 	 * Use ACI prio to get the new priority value for
6291 	 * each 802.1d traffic type, in this range.
6292 	 */
6293 	if (!(aci_prio[AC_BE] == aci_prio[AC_BK] &&
6294 	      aci_prio[AC_BK] == aci_prio[AC_VI] &&
6295 	      aci_prio[AC_VI] == aci_prio[AC_VO])) {
6296 		/* 802.1d 0,3 maps to BE */
6297 		priority[0] = aci_prio[AC_BE];
6298 		priority[3] = aci_prio[AC_BE];
6299 
6300 		/* 802.1d 1,2 maps to BK */
6301 		priority[1] = aci_prio[AC_BK];
6302 		priority[2] = aci_prio[AC_BK];
6303 
6304 		/* 802.1d 4,5 maps to VO */
6305 		priority[4] = aci_prio[AC_VI];
6306 		priority[5] = aci_prio[AC_VI];
6307 
6308 		/* 802.1d 6,7 maps to VO */
6309 		priority[6] = aci_prio[AC_VO];
6310 		priority[7] = aci_prio[AC_VO];
6311 	} else {
6312 		/* Initialize to default priority */
6313 		brcmf_init_wmm_prio(priority);
6314 	}
6315 
6316 	brcmf_dbg(CONN, "Adj prio BE 0->%d, BK 1->%d, BK 2->%d, BE 3->%d\n",
6317 		  priority[0], priority[1], priority[2], priority[3]);
6318 
6319 	brcmf_dbg(CONN, "Adj prio VI 4->%d, VI 5->%d, VO 6->%d, VO 7->%d\n",
6320 		  priority[4], priority[5], priority[6], priority[7]);
6321 }
6322 
6323 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
6324 			       struct brcmf_if *ifp)
6325 {
6326 	struct brcmf_pub *drvr = cfg->pub;
6327 	struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
6328 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6329 	struct brcmf_cfg80211_edcf_acparam edcf_acparam_info[EDCF_AC_COUNT];
6330 	u32 req_len;
6331 	u32 resp_len;
6332 	s32 err = 0;
6333 
6334 	brcmf_clear_assoc_ies(cfg);
6335 
6336 	err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
6337 				       cfg->extra_buf, WL_ASSOC_INFO_MAX);
6338 	if (err) {
6339 		bphy_err(drvr, "could not get assoc info (%d)\n", err);
6340 		return err;
6341 	}
6342 	assoc_info =
6343 		(struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
6344 	req_len = le32_to_cpu(assoc_info->req_len);
6345 	resp_len = le32_to_cpu(assoc_info->resp_len);
6346 	if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) {
6347 		bphy_err(drvr, "invalid lengths in assoc info: req %u resp %u\n",
6348 			 req_len, resp_len);
6349 		return -EINVAL;
6350 	}
6351 	if (req_len) {
6352 		err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
6353 					       cfg->extra_buf,
6354 					       WL_ASSOC_INFO_MAX);
6355 		if (err) {
6356 			bphy_err(drvr, "could not get assoc req (%d)\n", err);
6357 			return err;
6358 		}
6359 		conn_info->req_ie_len = req_len;
6360 		conn_info->req_ie =
6361 		    kmemdup(cfg->extra_buf, conn_info->req_ie_len,
6362 			    GFP_KERNEL);
6363 		if (!conn_info->req_ie)
6364 			conn_info->req_ie_len = 0;
6365 	} else {
6366 		conn_info->req_ie_len = 0;
6367 		conn_info->req_ie = NULL;
6368 	}
6369 	if (resp_len) {
6370 		err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
6371 					       cfg->extra_buf,
6372 					       WL_ASSOC_INFO_MAX);
6373 		if (err) {
6374 			bphy_err(drvr, "could not get assoc resp (%d)\n", err);
6375 			return err;
6376 		}
6377 		conn_info->resp_ie_len = resp_len;
6378 		conn_info->resp_ie =
6379 		    kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
6380 			    GFP_KERNEL);
6381 		if (!conn_info->resp_ie)
6382 			conn_info->resp_ie_len = 0;
6383 
6384 		err = brcmf_fil_iovar_data_get(ifp, "wme_ac_sta",
6385 					       edcf_acparam_info,
6386 					       sizeof(edcf_acparam_info));
6387 		if (err) {
6388 			brcmf_err("could not get wme_ac_sta (%d)\n", err);
6389 			return err;
6390 		}
6391 
6392 		brcmf_wifi_prioritize_acparams(edcf_acparam_info,
6393 					       cfg->ac_priority);
6394 	} else {
6395 		conn_info->resp_ie_len = 0;
6396 		conn_info->resp_ie = NULL;
6397 	}
6398 	brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
6399 		  conn_info->req_ie_len, conn_info->resp_ie_len);
6400 
6401 	return err;
6402 }
6403 
6404 static s32
6405 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
6406 		       struct net_device *ndev,
6407 		       const struct brcmf_event_msg *e)
6408 {
6409 	struct brcmf_if *ifp = netdev_priv(ndev);
6410 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6411 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6412 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
6413 	struct ieee80211_channel *notify_channel = NULL;
6414 	struct ieee80211_supported_band *band;
6415 	struct brcmf_bss_info_le *bi;
6416 	struct brcmu_chan ch;
6417 	struct cfg80211_roam_info roam_info = {};
6418 	u32 freq;
6419 	s32 err = 0;
6420 	u8 *buf;
6421 
6422 	brcmf_dbg(TRACE, "Enter\n");
6423 
6424 	brcmf_get_assoc_ies(cfg, ifp);
6425 	memcpy(profile->bssid, e->addr, ETH_ALEN);
6426 	brcmf_update_bss_info(cfg, ifp);
6427 
6428 	buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
6429 	if (buf == NULL) {
6430 		err = -ENOMEM;
6431 		goto done;
6432 	}
6433 
6434 	/* data sent to dongle has to be little endian */
6435 	*(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
6436 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
6437 				     buf, WL_BSS_INFO_MAX);
6438 
6439 	if (err)
6440 		goto done;
6441 
6442 	bi = (struct brcmf_bss_info_le *)(buf + 4);
6443 	ch.chspec = le16_to_cpu(bi->chanspec);
6444 	cfg->d11inf.decchspec(&ch);
6445 
6446 	if (ch.band == BRCMU_CHAN_BAND_2G)
6447 		band = wiphy->bands[NL80211_BAND_2GHZ];
6448 	else
6449 		band = wiphy->bands[NL80211_BAND_5GHZ];
6450 
6451 	freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
6452 	notify_channel = ieee80211_get_channel(wiphy, freq);
6453 
6454 done:
6455 	kfree(buf);
6456 
6457 	roam_info.links[0].channel = notify_channel;
6458 	roam_info.links[0].bssid = profile->bssid;
6459 	roam_info.req_ie = conn_info->req_ie;
6460 	roam_info.req_ie_len = conn_info->req_ie_len;
6461 	roam_info.resp_ie = conn_info->resp_ie;
6462 	roam_info.resp_ie_len = conn_info->resp_ie_len;
6463 
6464 	cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
6465 	brcmf_dbg(CONN, "Report roaming result\n");
6466 
6467 	if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
6468 		cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL);
6469 		brcmf_dbg(CONN, "Report port authorized\n");
6470 	}
6471 
6472 	set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
6473 	brcmf_dbg(TRACE, "Exit\n");
6474 	return err;
6475 }
6476 
6477 static s32
6478 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
6479 		       struct net_device *ndev, const struct brcmf_event_msg *e,
6480 		       bool completed)
6481 {
6482 	struct brcmf_if *ifp = netdev_priv(ndev);
6483 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6484 	struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6485 	struct cfg80211_connect_resp_params conn_params;
6486 
6487 	brcmf_dbg(TRACE, "Enter\n");
6488 
6489 	if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6490 			       &ifp->vif->sme_state)) {
6491 		memset(&conn_params, 0, sizeof(conn_params));
6492 		if (completed) {
6493 			brcmf_get_assoc_ies(cfg, ifp);
6494 			brcmf_update_bss_info(cfg, ifp);
6495 			set_bit(BRCMF_VIF_STATUS_CONNECTED,
6496 				&ifp->vif->sme_state);
6497 			conn_params.status = WLAN_STATUS_SUCCESS;
6498 		} else {
6499 			clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS,
6500 				  &ifp->vif->sme_state);
6501 			clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS,
6502 				  &ifp->vif->sme_state);
6503 			conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
6504 		}
6505 		conn_params.links[0].bssid = profile->bssid;
6506 		conn_params.req_ie = conn_info->req_ie;
6507 		conn_params.req_ie_len = conn_info->req_ie_len;
6508 		conn_params.resp_ie = conn_info->resp_ie;
6509 		conn_params.resp_ie_len = conn_info->resp_ie_len;
6510 		cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
6511 		brcmf_dbg(CONN, "Report connect result - connection %s\n",
6512 			  completed ? "succeeded" : "failed");
6513 	}
6514 	brcmf_dbg(TRACE, "Exit\n");
6515 	return 0;
6516 }
6517 
6518 static s32
6519 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
6520 			       struct net_device *ndev,
6521 			       const struct brcmf_event_msg *e, void *data)
6522 {
6523 	struct brcmf_pub *drvr = cfg->pub;
6524 	static int generation;
6525 	u32 event = e->event_code;
6526 	u32 reason = e->reason;
6527 	struct station_info *sinfo;
6528 
6529 	brcmf_dbg(CONN, "event %s (%u), reason %d\n",
6530 		  brcmf_fweh_event_name(event), event, reason);
6531 	if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
6532 	    ndev != cfg_to_ndev(cfg)) {
6533 		brcmf_dbg(CONN, "AP mode link down\n");
6534 		complete(&cfg->vif_disabled);
6535 		return 0;
6536 	}
6537 
6538 	if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
6539 	    (reason == BRCMF_E_STATUS_SUCCESS)) {
6540 		if (!data) {
6541 			bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
6542 			return -EINVAL;
6543 		}
6544 
6545 		sinfo = kzalloc_obj(*sinfo);
6546 		if (!sinfo)
6547 			return -ENOMEM;
6548 
6549 		sinfo->assoc_req_ies = data;
6550 		sinfo->assoc_req_ies_len = e->datalen;
6551 		generation++;
6552 		sinfo->generation = generation;
6553 		cfg80211_new_sta(ndev->ieee80211_ptr, e->addr, sinfo,
6554 				 GFP_KERNEL);
6555 
6556 		kfree(sinfo);
6557 	} else if ((event == BRCMF_E_DISASSOC_IND) ||
6558 		   (event == BRCMF_E_DEAUTH_IND) ||
6559 		   (event == BRCMF_E_DEAUTH)) {
6560 		cfg80211_del_sta(ndev->ieee80211_ptr, e->addr, GFP_KERNEL);
6561 	}
6562 	return 0;
6563 }
6564 
6565 static s32
6566 brcmf_notify_connect_status(struct brcmf_if *ifp,
6567 			    const struct brcmf_event_msg *e, void *data)
6568 {
6569 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6570 	struct net_device *ndev = ifp->ndev;
6571 	struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6572 	struct ieee80211_channel *chan;
6573 	s32 err = 0;
6574 
6575 	if ((e->event_code == BRCMF_E_DEAUTH) ||
6576 	    (e->event_code == BRCMF_E_DEAUTH_IND) ||
6577 	    (e->event_code == BRCMF_E_DISASSOC_IND) ||
6578 	    ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
6579 		brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
6580 	}
6581 
6582 	if (brcmf_is_apmode(ifp->vif)) {
6583 		err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
6584 	} else if (brcmf_is_linkup(ifp->vif, e)) {
6585 		brcmf_dbg(CONN, "Linkup\n");
6586 		if (brcmf_is_ibssmode(ifp->vif)) {
6587 			brcmf_inform_ibss(cfg, ndev, e->addr);
6588 			chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
6589 			memcpy(profile->bssid, e->addr, ETH_ALEN);
6590 			cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
6591 			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6592 				  &ifp->vif->sme_state);
6593 			set_bit(BRCMF_VIF_STATUS_CONNECTED,
6594 				&ifp->vif->sme_state);
6595 		} else
6596 			brcmf_bss_connect_done(cfg, ndev, e, true);
6597 		brcmf_net_setcarrier(ifp, true);
6598 	} else if (brcmf_is_linkdown(ifp->vif, e)) {
6599 		brcmf_dbg(CONN, "Linkdown\n");
6600 		if (!brcmf_is_ibssmode(ifp->vif) &&
6601 		    (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6602 			      &ifp->vif->sme_state) ||
6603 		     test_bit(BRCMF_VIF_STATUS_CONNECTING,
6604 			      &ifp->vif->sme_state))) {
6605 			if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6606 				     &ifp->vif->sme_state) &&
6607 			    memcmp(profile->bssid, e->addr, ETH_ALEN))
6608 				return err;
6609 
6610 			brcmf_bss_connect_done(cfg, ndev, e, false);
6611 			brcmf_link_down(ifp->vif,
6612 					brcmf_map_fw_linkdown_reason(e),
6613 					e->event_code &
6614 					(BRCMF_E_DEAUTH_IND |
6615 					BRCMF_E_DISASSOC_IND)
6616 					? false : true);
6617 			brcmf_init_prof(ndev_to_prof(ndev));
6618 			if (ndev != cfg_to_ndev(cfg))
6619 				complete(&cfg->vif_disabled);
6620 			brcmf_net_setcarrier(ifp, false);
6621 		}
6622 	} else if (brcmf_is_nonetwork(cfg, e)) {
6623 		if (brcmf_is_ibssmode(ifp->vif))
6624 			clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6625 				  &ifp->vif->sme_state);
6626 		else
6627 			brcmf_bss_connect_done(cfg, ndev, e, false);
6628 	}
6629 
6630 	return err;
6631 }
6632 
6633 static s32
6634 brcmf_notify_roaming_status(struct brcmf_if *ifp,
6635 			    const struct brcmf_event_msg *e, void *data)
6636 {
6637 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6638 	u32 event = e->event_code;
6639 	u32 status = e->status;
6640 
6641 	if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
6642 		if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6643 			     &ifp->vif->sme_state)) {
6644 			brcmf_bss_roaming_done(cfg, ifp->ndev, e);
6645 		} else {
6646 			brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
6647 			brcmf_net_setcarrier(ifp, true);
6648 		}
6649 	}
6650 
6651 	return 0;
6652 }
6653 
6654 static s32
6655 brcmf_notify_mic_status(struct brcmf_if *ifp,
6656 			const struct brcmf_event_msg *e, void *data)
6657 {
6658 	u16 flags = e->flags;
6659 	enum nl80211_key_type key_type;
6660 
6661 	if (flags & BRCMF_EVENT_MSG_GROUP)
6662 		key_type = NL80211_KEYTYPE_GROUP;
6663 	else
6664 		key_type = NL80211_KEYTYPE_PAIRWISE;
6665 
6666 	cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
6667 				     NULL, GFP_KERNEL);
6668 
6669 	return 0;
6670 }
6671 
6672 static s32 brcmf_notify_rssi(struct brcmf_if *ifp,
6673 			     const struct brcmf_event_msg *e, void *data)
6674 {
6675 	struct brcmf_cfg80211_vif *vif = ifp->vif;
6676 	struct brcmf_rssi_be *info = data;
6677 	s32 rssi, snr = 0, noise = 0;
6678 	s32 low, high, last;
6679 
6680 	if (e->datalen >= sizeof(*info)) {
6681 		rssi = be32_to_cpu(info->rssi);
6682 		snr = be32_to_cpu(info->snr);
6683 		noise = be32_to_cpu(info->noise);
6684 	} else if (e->datalen >= sizeof(rssi)) {
6685 		rssi = be32_to_cpu(*(__be32 *)data);
6686 	} else {
6687 		brcmf_err("insufficient RSSI event data\n");
6688 		return 0;
6689 	}
6690 
6691 	low = vif->cqm_rssi_low;
6692 	high = vif->cqm_rssi_high;
6693 	last = vif->cqm_rssi_last;
6694 
6695 	brcmf_dbg(TRACE, "rssi=%d snr=%d noise=%d low=%d high=%d last=%d\n",
6696 		  rssi, snr, noise, low, high, last);
6697 
6698 	vif->cqm_rssi_last = rssi;
6699 
6700 	if (rssi <= low || rssi == 0) {
6701 		brcmf_dbg(INFO, "LOW rssi=%d\n", rssi);
6702 		cfg80211_cqm_rssi_notify(ifp->ndev,
6703 					 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
6704 					 rssi, GFP_KERNEL);
6705 	} else if (rssi > high) {
6706 		brcmf_dbg(INFO, "HIGH rssi=%d\n", rssi);
6707 		cfg80211_cqm_rssi_notify(ifp->ndev,
6708 					 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
6709 					 rssi, GFP_KERNEL);
6710 	}
6711 
6712 	return 0;
6713 }
6714 
6715 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
6716 				  const struct brcmf_event_msg *e, void *data)
6717 {
6718 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6719 	struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
6720 	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6721 	struct brcmf_cfg80211_vif *vif;
6722 
6723 	brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
6724 		  ifevent->action, ifevent->flags, ifevent->ifidx,
6725 		  ifevent->bsscfgidx);
6726 
6727 	spin_lock(&event->vif_event_lock);
6728 	event->action = ifevent->action;
6729 	vif = event->vif;
6730 
6731 	switch (ifevent->action) {
6732 	case BRCMF_E_IF_ADD:
6733 		/* waiting process may have timed out */
6734 		if (!cfg->vif_event.vif) {
6735 			spin_unlock(&event->vif_event_lock);
6736 			return -EBADF;
6737 		}
6738 
6739 		ifp->vif = vif;
6740 		vif->ifp = ifp;
6741 		if (ifp->ndev) {
6742 			vif->wdev.netdev = ifp->ndev;
6743 			ifp->ndev->ieee80211_ptr = &vif->wdev;
6744 			SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
6745 		}
6746 		spin_unlock(&event->vif_event_lock);
6747 		wake_up(&event->vif_wq);
6748 		return 0;
6749 
6750 	case BRCMF_E_IF_DEL:
6751 		spin_unlock(&event->vif_event_lock);
6752 		/* event may not be upon user request */
6753 		if (brcmf_cfg80211_vif_event_armed(cfg))
6754 			wake_up(&event->vif_wq);
6755 		return 0;
6756 
6757 	case BRCMF_E_IF_CHANGE:
6758 		spin_unlock(&event->vif_event_lock);
6759 		wake_up(&event->vif_wq);
6760 		return 0;
6761 
6762 	default:
6763 		spin_unlock(&event->vif_event_lock);
6764 		break;
6765 	}
6766 	return -EINVAL;
6767 }
6768 
6769 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
6770 {
6771 	conf->frag_threshold = (u32)-1;
6772 	conf->rts_threshold = (u32)-1;
6773 	conf->retry_short = (u32)-1;
6774 	conf->retry_long = (u32)-1;
6775 }
6776 
6777 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
6778 {
6779 	brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
6780 			    brcmf_notify_connect_status);
6781 	brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
6782 			    brcmf_notify_connect_status);
6783 	brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
6784 			    brcmf_notify_connect_status);
6785 	brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
6786 			    brcmf_notify_connect_status);
6787 	brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
6788 			    brcmf_notify_connect_status);
6789 	brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
6790 			    brcmf_notify_connect_status);
6791 	brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
6792 			    brcmf_notify_roaming_status);
6793 	brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
6794 			    brcmf_notify_mic_status);
6795 	brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
6796 			    brcmf_notify_connect_status);
6797 	brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
6798 			    brcmf_notify_sched_scan_results);
6799 	brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
6800 			    brcmf_notify_vif_event);
6801 	brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
6802 			    brcmf_p2p_notify_rx_mgmt_p2p_probereq);
6803 	brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
6804 			    brcmf_p2p_notify_listen_complete);
6805 	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
6806 			    brcmf_p2p_notify_action_frame_rx);
6807 	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
6808 			    brcmf_p2p_notify_action_tx_complete);
6809 	brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
6810 			    brcmf_p2p_notify_action_tx_complete);
6811 	brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
6812 			    brcmf_notify_connect_status);
6813 	brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
6814 
6815 	brcmf_fwvid_register_event_handlers(cfg->pub);
6816 }
6817 
6818 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
6819 {
6820 	kfree(cfg->conf);
6821 	cfg->conf = NULL;
6822 	kfree(cfg->extra_buf);
6823 	cfg->extra_buf = NULL;
6824 	kfree(cfg->wowl.nd);
6825 	cfg->wowl.nd = NULL;
6826 	kfree(cfg->wowl.nd_info);
6827 	cfg->wowl.nd_info = NULL;
6828 	kfree(cfg->escan_info.escan_buf);
6829 	cfg->escan_info.escan_buf = NULL;
6830 }
6831 
6832 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
6833 {
6834 	cfg->conf = kzalloc_obj(*cfg->conf);
6835 	if (!cfg->conf)
6836 		goto init_priv_mem_out;
6837 	cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
6838 	if (!cfg->extra_buf)
6839 		goto init_priv_mem_out;
6840 	cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
6841 	if (!cfg->wowl.nd)
6842 		goto init_priv_mem_out;
6843 	cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
6844 				    sizeof(struct cfg80211_wowlan_nd_match *),
6845 				    GFP_KERNEL);
6846 	if (!cfg->wowl.nd_info)
6847 		goto init_priv_mem_out;
6848 	cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
6849 	if (!cfg->escan_info.escan_buf)
6850 		goto init_priv_mem_out;
6851 
6852 	return 0;
6853 
6854 init_priv_mem_out:
6855 	brcmf_deinit_priv_mem(cfg);
6856 
6857 	return -ENOMEM;
6858 }
6859 
6860 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
6861 {
6862 	s32 err = 0;
6863 
6864 	cfg->scan_request = NULL;
6865 	cfg->pwr_save = true;
6866 	cfg->dongle_up = false;		/* dongle is not up yet */
6867 	err = brcmf_init_priv_mem(cfg);
6868 	if (err)
6869 		return err;
6870 	brcmf_register_event_handlers(cfg);
6871 	mutex_init(&cfg->usr_sync);
6872 	brcmf_init_escan(cfg);
6873 	brcmf_init_conf(cfg->conf);
6874 	brcmf_init_wmm_prio(cfg->ac_priority);
6875 	init_completion(&cfg->vif_disabled);
6876 	return err;
6877 }
6878 
6879 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
6880 {
6881 	cfg->dongle_up = false;	/* dongle down */
6882 	brcmf_abort_scanning(cfg);
6883 	brcmf_deinit_priv_mem(cfg);
6884 	brcmf_clear_assoc_ies(cfg);
6885 }
6886 
6887 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
6888 {
6889 	init_waitqueue_head(&event->vif_wq);
6890 	spin_lock_init(&event->vif_event_lock);
6891 }
6892 
6893 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
6894 {
6895 	struct brcmf_pub *drvr = ifp->drvr;
6896 	s32 err;
6897 	u32 bcn_timeout;
6898 	__le32 roamtrigger[2];
6899 	__le32 roam_delta[2];
6900 
6901 	/* Configure beacon timeout value based upon roaming setting */
6902 	if (ifp->drvr->settings->roamoff)
6903 		bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
6904 	else
6905 		bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
6906 	err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
6907 	if (err) {
6908 		bphy_err(drvr, "bcn_timeout error (%d)\n", err);
6909 		goto roam_setup_done;
6910 	}
6911 
6912 	/* Enable/Disable built-in roaming to allow supplicant to take care of
6913 	 * roaming.
6914 	 */
6915 	brcmf_dbg(INFO, "Internal Roaming = %s\n",
6916 		  ifp->drvr->settings->roamoff ? "Off" : "On");
6917 	err = brcmf_fil_iovar_int_set(ifp, "roam_off",
6918 				      ifp->drvr->settings->roamoff);
6919 	if (err) {
6920 		bphy_err(drvr, "roam_off error (%d)\n", err);
6921 		goto roam_setup_done;
6922 	}
6923 
6924 	roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
6925 	roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
6926 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
6927 				     (void *)roamtrigger, sizeof(roamtrigger));
6928 	if (err)
6929 		bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
6930 
6931 	roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
6932 	roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
6933 	err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
6934 				     (void *)roam_delta, sizeof(roam_delta));
6935 	if (err)
6936 		bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
6937 
6938 	return 0;
6939 
6940 roam_setup_done:
6941 	return err;
6942 }
6943 
6944 static s32
6945 brcmf_dongle_scantime(struct brcmf_if *ifp)
6946 {
6947 	struct brcmf_pub *drvr = ifp->drvr;
6948 	s32 err = 0;
6949 
6950 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
6951 				    BRCMF_SCAN_CHANNEL_TIME);
6952 	if (err) {
6953 		bphy_err(drvr, "Scan assoc time error (%d)\n", err);
6954 		goto dongle_scantime_out;
6955 	}
6956 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
6957 				    BRCMF_SCAN_UNASSOC_TIME);
6958 	if (err) {
6959 		bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
6960 		goto dongle_scantime_out;
6961 	}
6962 
6963 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
6964 				    BRCMF_SCAN_PASSIVE_TIME);
6965 	if (err) {
6966 		bphy_err(drvr, "Scan passive time error (%d)\n", err);
6967 		goto dongle_scantime_out;
6968 	}
6969 
6970 dongle_scantime_out:
6971 	return err;
6972 }
6973 
6974 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
6975 					   struct brcmu_chan *ch)
6976 {
6977 	u32 ht40_flag;
6978 
6979 	ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
6980 	if (ch->sb == BRCMU_CHAN_SB_U) {
6981 		if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6982 			channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6983 		channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
6984 	} else {
6985 		/* It should be one of
6986 		 * IEEE80211_CHAN_NO_HT40 or
6987 		 * IEEE80211_CHAN_NO_HT40PLUS
6988 		 */
6989 		channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6990 		if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6991 			channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
6992 	}
6993 }
6994 
6995 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
6996 				    u32 bw_cap[])
6997 {
6998 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
6999 	struct brcmf_pub *drvr = cfg->pub;
7000 	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
7001 	struct ieee80211_supported_band *band;
7002 	struct ieee80211_channel *channel;
7003 	struct brcmf_chanspec_list *list;
7004 	struct brcmu_chan ch;
7005 	int err;
7006 	u8 *pbuf;
7007 	u32 i, j;
7008 	u32 total;
7009 	u32 chaninfo;
7010 
7011 	pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
7012 
7013 	if (pbuf == NULL)
7014 		return -ENOMEM;
7015 
7016 	list = (struct brcmf_chanspec_list *)pbuf;
7017 
7018 	err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
7019 				       BRCMF_DCMD_MEDLEN);
7020 	if (err) {
7021 		bphy_err(drvr, "get chanspecs error (%d)\n", err);
7022 		goto fail_pbuf;
7023 	}
7024 
7025 	band = wiphy->bands[NL80211_BAND_2GHZ];
7026 	if (band)
7027 		for (i = 0; i < band->n_channels; i++)
7028 			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
7029 	band = wiphy->bands[NL80211_BAND_5GHZ];
7030 	if (band)
7031 		for (i = 0; i < band->n_channels; i++)
7032 			band->channels[i].flags = IEEE80211_CHAN_DISABLED;
7033 
7034 	total = le32_to_cpu(list->count);
7035 	if (total > BRCMF_MAX_CHANSPEC_LIST) {
7036 		bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
7037 			 total);
7038 		err = -EINVAL;
7039 		goto fail_pbuf;
7040 	}
7041 
7042 	for (i = 0; i < total; i++) {
7043 		ch.chspec = (u16)le32_to_cpu(list->element[i]);
7044 		cfg->d11inf.decchspec(&ch);
7045 
7046 		if (ch.band == BRCMU_CHAN_BAND_2G) {
7047 			band = wiphy->bands[NL80211_BAND_2GHZ];
7048 		} else if (ch.band == BRCMU_CHAN_BAND_5G) {
7049 			band = wiphy->bands[NL80211_BAND_5GHZ];
7050 		} else {
7051 			bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
7052 				 ch.chspec);
7053 			continue;
7054 		}
7055 		if (!band)
7056 			continue;
7057 		if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
7058 		    ch.bw == BRCMU_CHAN_BW_40)
7059 			continue;
7060 		if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
7061 		    ch.bw == BRCMU_CHAN_BW_80)
7062 			continue;
7063 
7064 		channel = NULL;
7065 		for (j = 0; j < band->n_channels; j++) {
7066 			if (band->channels[j].hw_value == ch.control_ch_num) {
7067 				channel = &band->channels[j];
7068 				break;
7069 			}
7070 		}
7071 		if (!channel) {
7072 			/* It seems firmware supports some channel we never
7073 			 * considered. Something new in IEEE standard?
7074 			 */
7075 			bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
7076 				 ch.control_ch_num);
7077 			continue;
7078 		}
7079 
7080 		if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
7081 			continue;
7082 
7083 		/* assuming the chanspecs order is HT20,
7084 		 * HT40 upper, HT40 lower, and VHT80.
7085 		 */
7086 		switch (ch.bw) {
7087 		case BRCMU_CHAN_BW_160:
7088 			channel->flags &= ~IEEE80211_CHAN_NO_160MHZ;
7089 			break;
7090 		case BRCMU_CHAN_BW_80:
7091 			channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
7092 			break;
7093 		case BRCMU_CHAN_BW_40:
7094 			brcmf_update_bw40_channel_flag(channel, &ch);
7095 			break;
7096 		default:
7097 			wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n",
7098 				   ch.bw);
7099 			fallthrough;
7100 		case BRCMU_CHAN_BW_20:
7101 			/* enable the channel and disable other bandwidths
7102 			 * for now as mentioned order assure they are enabled
7103 			 * for subsequent chanspecs.
7104 			 */
7105 			channel->flags = IEEE80211_CHAN_NO_HT40 |
7106 					 IEEE80211_CHAN_NO_80MHZ |
7107 					 IEEE80211_CHAN_NO_160MHZ;
7108 			ch.bw = BRCMU_CHAN_BW_20;
7109 			cfg->d11inf.encchspec(&ch);
7110 			chaninfo = ch.chspec;
7111 			err = brcmf_fil_bsscfg_int_query(ifp, "per_chan_info",
7112 							 &chaninfo);
7113 			if (!err) {
7114 				if (chaninfo & WL_CHAN_RADAR)
7115 					channel->flags |=
7116 						(IEEE80211_CHAN_RADAR |
7117 						 IEEE80211_CHAN_NO_IR);
7118 				if (chaninfo & WL_CHAN_PASSIVE)
7119 					channel->flags |=
7120 						IEEE80211_CHAN_NO_IR;
7121 			}
7122 		}
7123 	}
7124 
7125 fail_pbuf:
7126 	kfree(pbuf);
7127 	return err;
7128 }
7129 
7130 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
7131 {
7132 	struct brcmf_pub *drvr = cfg->pub;
7133 	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
7134 	struct ieee80211_supported_band *band;
7135 	struct brcmf_fil_bwcap_le band_bwcap;
7136 	struct brcmf_chanspec_list *list;
7137 	u8 *pbuf;
7138 	u32 val;
7139 	int err;
7140 	struct brcmu_chan ch;
7141 	u32 num_chan;
7142 	int i, j;
7143 
7144 	/* verify support for bw_cap command */
7145 	val = WLC_BAND_5G;
7146 	err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &val);
7147 
7148 	if (!err) {
7149 		/* only set 2G bandwidth using bw_cap command */
7150 		band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
7151 		band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
7152 		err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
7153 					       sizeof(band_bwcap));
7154 	} else {
7155 		brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
7156 		val = WLC_N_BW_40ALL;
7157 		err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
7158 	}
7159 
7160 	if (!err) {
7161 		/* update channel info in 2G band */
7162 		pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
7163 
7164 		if (pbuf == NULL)
7165 			return -ENOMEM;
7166 
7167 		ch.band = BRCMU_CHAN_BAND_2G;
7168 		ch.bw = BRCMU_CHAN_BW_40;
7169 		ch.sb = BRCMU_CHAN_SB_NONE;
7170 		ch.chnum = 0;
7171 		cfg->d11inf.encchspec(&ch);
7172 
7173 		/* pass encoded chanspec in query */
7174 		*(__le16 *)pbuf = cpu_to_le16(ch.chspec);
7175 
7176 		err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
7177 					       BRCMF_DCMD_MEDLEN);
7178 		if (err) {
7179 			bphy_err(drvr, "get chanspecs error (%d)\n", err);
7180 			kfree(pbuf);
7181 			return err;
7182 		}
7183 
7184 		band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
7185 		list = (struct brcmf_chanspec_list *)pbuf;
7186 		num_chan = le32_to_cpu(list->count);
7187 		if (num_chan > BRCMF_MAX_CHANSPEC_LIST) {
7188 			bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
7189 				 num_chan);
7190 			kfree(pbuf);
7191 			return -EINVAL;
7192 		}
7193 
7194 		for (i = 0; i < num_chan; i++) {
7195 			ch.chspec = (u16)le32_to_cpu(list->element[i]);
7196 			cfg->d11inf.decchspec(&ch);
7197 			if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
7198 				continue;
7199 			if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
7200 				continue;
7201 			for (j = 0; j < band->n_channels; j++) {
7202 				if (band->channels[j].hw_value == ch.control_ch_num)
7203 					break;
7204 			}
7205 			if (WARN_ON(j == band->n_channels))
7206 				continue;
7207 
7208 			brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
7209 		}
7210 		kfree(pbuf);
7211 	}
7212 	return err;
7213 }
7214 
7215 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
7216 {
7217 	struct brcmf_pub *drvr = ifp->drvr;
7218 	u32 band, mimo_bwcap;
7219 	int err;
7220 
7221 	band = WLC_BAND_2G;
7222 	err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
7223 	if (!err) {
7224 		bw_cap[NL80211_BAND_2GHZ] = band;
7225 		band = WLC_BAND_5G;
7226 		err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
7227 		if (!err) {
7228 			bw_cap[NL80211_BAND_5GHZ] = band;
7229 			return;
7230 		}
7231 		WARN_ON(1);
7232 		return;
7233 	}
7234 	brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
7235 	err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
7236 	if (err)
7237 		/* assume 20MHz if firmware does not give a clue */
7238 		mimo_bwcap = WLC_N_BW_20ALL;
7239 
7240 	switch (mimo_bwcap) {
7241 	case WLC_N_BW_40ALL:
7242 		bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
7243 		fallthrough;
7244 	case WLC_N_BW_20IN2G_40IN5G:
7245 		bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
7246 		fallthrough;
7247 	case WLC_N_BW_20ALL:
7248 		bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
7249 		bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
7250 		break;
7251 	default:
7252 		bphy_err(drvr, "invalid mimo_bw_cap value\n");
7253 	}
7254 }
7255 
7256 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
7257 				u32 bw_cap[2], u32 nchain)
7258 {
7259 	band->ht_cap.ht_supported = true;
7260 	if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
7261 		band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
7262 		band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7263 	}
7264 	band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
7265 	band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
7266 	band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
7267 	band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
7268 	memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
7269 	band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
7270 }
7271 
7272 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7273 {
7274 	u16 mcs_map;
7275 	int i;
7276 
7277 	for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7278 		mcs_map = (mcs_map << 2) | supp;
7279 
7280 	return cpu_to_le16(mcs_map);
7281 }
7282 
7283 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7284 				 u32 bw_cap[2], u32 nchain, u32 txstreams,
7285 				 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7286 {
7287 	__le16 mcs_map;
7288 
7289 	/* not allowed in 2.4G band */
7290 	if (band->band == NL80211_BAND_2GHZ)
7291 		return;
7292 
7293 	band->vht_cap.vht_supported = true;
7294 	/* 80MHz is mandatory */
7295 	band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
7296 	if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
7297 		band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
7298 		band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
7299 	}
7300 	/* all support 256-QAM */
7301 	mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7302 	band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7303 	band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
7304 
7305 	/* Beamforming support information */
7306 	if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
7307 		band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
7308 	if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
7309 		band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
7310 	if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
7311 		band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
7312 	if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
7313 		band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
7314 
7315 	if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
7316 		band->vht_cap.cap |=
7317 			(2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7318 		band->vht_cap.cap |= ((txstreams - 1) <<
7319 				IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7320 		band->vht_cap.cap |=
7321 			IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
7322 	}
7323 }
7324 
7325 static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
7326 {
7327 	struct brcmf_pub *drvr = cfg->pub;
7328 	struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
7329 	struct wiphy *wiphy = cfg_to_wiphy(cfg);
7330 	u32 nmode;
7331 	u32 vhtmode = 0;
7332 	u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
7333 	u32 rxchain;
7334 	u32 nchain;
7335 	int err;
7336 	s32 i;
7337 	struct ieee80211_supported_band *band;
7338 	u32 txstreams = 0;
7339 	u32 txbf_bfe_cap = 0;
7340 	u32 txbf_bfr_cap = 0;
7341 
7342 	(void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7343 	err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
7344 	if (err) {
7345 		bphy_err(drvr, "nmode error (%d)\n", err);
7346 	} else {
7347 		brcmf_get_bwcap(ifp, bw_cap);
7348 	}
7349 	brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
7350 		  nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
7351 		  bw_cap[NL80211_BAND_5GHZ]);
7352 
7353 	err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
7354 	if (err) {
7355 		/* rxchain unsupported by firmware of older chips */
7356 		if (err == -EBADE)
7357 			bphy_info_once(drvr, "rxchain unsupported\n");
7358 		else
7359 			bphy_err(drvr, "rxchain error (%d)\n", err);
7360 
7361 		nchain = 1;
7362 	} else {
7363 		for (nchain = 0; rxchain; nchain++)
7364 			rxchain = rxchain & (rxchain - 1);
7365 	}
7366 	brcmf_dbg(INFO, "nchain=%d\n", nchain);
7367 
7368 	err = brcmf_construct_chaninfo(cfg, bw_cap);
7369 	if (err) {
7370 		bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
7371 		return err;
7372 	}
7373 
7374 	if (vhtmode) {
7375 		(void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
7376 		(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
7377 					      &txbf_bfe_cap);
7378 		(void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
7379 					      &txbf_bfr_cap);
7380 	}
7381 
7382 	for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
7383 		band = wiphy->bands[i];
7384 		if (band == NULL)
7385 			continue;
7386 
7387 		if (nmode)
7388 			brcmf_update_ht_cap(band, bw_cap, nchain);
7389 		if (vhtmode)
7390 			brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7391 					     txbf_bfe_cap, txbf_bfr_cap);
7392 	}
7393 
7394 	return 0;
7395 }
7396 
7397 static const struct ieee80211_txrx_stypes
7398 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
7399 	[NL80211_IFTYPE_STATION] = {
7400 		.tx = 0xffff,
7401 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7402 		      BIT(IEEE80211_STYPE_AUTH >> 4) |
7403 		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7404 	},
7405 	[NL80211_IFTYPE_P2P_CLIENT] = {
7406 		.tx = 0xffff,
7407 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7408 		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7409 	},
7410 	[NL80211_IFTYPE_P2P_GO] = {
7411 		.tx = 0xffff,
7412 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
7413 		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
7414 		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
7415 		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
7416 		      BIT(IEEE80211_STYPE_AUTH >> 4) |
7417 		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
7418 		      BIT(IEEE80211_STYPE_ACTION >> 4)
7419 	},
7420 	[NL80211_IFTYPE_P2P_DEVICE] = {
7421 		.tx = 0xffff,
7422 		.rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7423 		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7424 	},
7425 	[NL80211_IFTYPE_AP] = {
7426 		.tx = 0xffff,
7427 		.rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
7428 		      BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
7429 		      BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
7430 		      BIT(IEEE80211_STYPE_DISASSOC >> 4) |
7431 		      BIT(IEEE80211_STYPE_AUTH >> 4) |
7432 		      BIT(IEEE80211_STYPE_DEAUTH >> 4) |
7433 		      BIT(IEEE80211_STYPE_ACTION >> 4)
7434 	}
7435 };
7436 
7437 /**
7438  * brcmf_setup_ifmodes() - determine interface modes and combinations.
7439  *
7440  * @wiphy: wiphy object.
7441  * @ifp: interface object needed for feat module api.
7442  *
7443  * The interface modes and combinations are determined dynamically here
7444  * based on firmware functionality.
7445  *
7446  * no p2p and no mbss:
7447  *
7448  *	#STA <= 1, #AP <= 1, channels = 1, 2 total
7449  *
7450  * no p2p and mbss:
7451  *
7452  *	#STA <= 1, #AP <= 1, channels = 1, 2 total
7453  *	#AP <= 4, matching BI, channels = 1, 4 total
7454  *
7455  * no p2p and rsdb:
7456  *	#STA <= 1, #AP <= 2, channels = 2, 4 total
7457  *
7458  * p2p, no mchan, and mbss:
7459  *
7460  *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
7461  *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
7462  *	#AP <= 4, matching BI, channels = 1, 4 total
7463  *
7464  * p2p, mchan, and mbss:
7465  *
7466  *	#STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
7467  *	#STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
7468  *	#AP <= 4, matching BI, channels = 1, 4 total
7469  *
7470  * p2p, rsdb, and no mbss:
7471  *	#STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
7472  *	 channels = 2, 4 total
7473  *
7474  * Return: 0 on success, negative errno on failure
7475  */
7476 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
7477 {
7478 	struct ieee80211_iface_combination *combo = NULL;
7479 	struct ieee80211_iface_limit *c0_limits = NULL;
7480 	struct ieee80211_iface_limit *p2p_limits = NULL;
7481 	struct ieee80211_iface_limit *mbss_limits = NULL;
7482 	bool mon_flag, mbss, p2p, rsdb, mchan;
7483 	int i, c, n_combos, n_limits;
7484 
7485 	mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
7486 	mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
7487 	p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
7488 	rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
7489 	mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
7490 
7491 	n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
7492 	combo = kzalloc_objs(*combo, n_combos);
7493 	if (!combo)
7494 		goto err;
7495 
7496 	wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
7497 				 BIT(NL80211_IFTYPE_ADHOC) |
7498 				 BIT(NL80211_IFTYPE_AP);
7499 	if (mon_flag)
7500 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7501 	if (p2p)
7502 		wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
7503 					  BIT(NL80211_IFTYPE_P2P_GO) |
7504 					  BIT(NL80211_IFTYPE_P2P_DEVICE);
7505 
7506 	c = 0;
7507 	i = 0;
7508 	n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
7509 	c0_limits = kzalloc_objs(*c0_limits, n_limits);
7510 	if (!c0_limits)
7511 		goto err;
7512 
7513 	combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
7514 	c0_limits[i].max = 1 + (p2p && mchan);
7515 	c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7516 	if (mon_flag) {
7517 		c0_limits[i].max = 1;
7518 		c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7519 	}
7520 	if (p2p) {
7521 		c0_limits[i].max = 1;
7522 		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7523 		c0_limits[i].max = 1 + rsdb;
7524 		c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
7525 				       BIT(NL80211_IFTYPE_P2P_GO);
7526 	}
7527 	if (p2p && rsdb) {
7528 		c0_limits[i].max = 2;
7529 		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7530 		combo[c].max_interfaces = 4;
7531 	} else if (p2p) {
7532 		combo[c].max_interfaces = i;
7533 	} else if (rsdb) {
7534 		c0_limits[i].max = 2;
7535 		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7536 		combo[c].max_interfaces = 3;
7537 	} else {
7538 		c0_limits[i].max = 1;
7539 		c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7540 		combo[c].max_interfaces = i;
7541 	}
7542 	combo[c].n_limits = i;
7543 	combo[c].limits = c0_limits;
7544 
7545 	if (p2p && !rsdb) {
7546 		c++;
7547 		i = 0;
7548 		p2p_limits = kzalloc_objs(*p2p_limits, 4);
7549 		if (!p2p_limits)
7550 			goto err;
7551 		p2p_limits[i].max = 1;
7552 		p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7553 		p2p_limits[i].max = 1;
7554 		p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7555 		p2p_limits[i].max = 1;
7556 		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
7557 		p2p_limits[i].max = 1;
7558 		p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7559 		combo[c].num_different_channels = 1;
7560 		combo[c].max_interfaces = i;
7561 		combo[c].n_limits = i;
7562 		combo[c].limits = p2p_limits;
7563 	}
7564 
7565 	if (mbss) {
7566 		c++;
7567 		i = 0;
7568 		n_limits = 1 + mon_flag;
7569 		mbss_limits = kzalloc_objs(*mbss_limits, n_limits);
7570 		if (!mbss_limits)
7571 			goto err;
7572 		mbss_limits[i].max = 4;
7573 		mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7574 		if (mon_flag) {
7575 			mbss_limits[i].max = 1;
7576 			mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7577 		}
7578 		combo[c].beacon_int_infra_match = true;
7579 		combo[c].num_different_channels = 1;
7580 		combo[c].max_interfaces = 4 + mon_flag;
7581 		combo[c].n_limits = i;
7582 		combo[c].limits = mbss_limits;
7583 	}
7584 
7585 	wiphy->n_iface_combinations = n_combos;
7586 	wiphy->iface_combinations = combo;
7587 	return 0;
7588 
7589 err:
7590 	kfree(c0_limits);
7591 	kfree(p2p_limits);
7592 	kfree(mbss_limits);
7593 	kfree(combo);
7594 	return -ENOMEM;
7595 }
7596 
7597 #ifdef CONFIG_PM
7598 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
7599 	.flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
7600 	.n_patterns = BRCMF_WOWL_MAXPATTERNS,
7601 	.pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
7602 	.pattern_min_len = 1,
7603 	.max_pkt_offset = 1500,
7604 };
7605 #endif
7606 
7607 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
7608 {
7609 #ifdef CONFIG_PM
7610 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
7611 	struct brcmf_pub *drvr = cfg->pub;
7612 	struct wiphy_wowlan_support *wowl;
7613 
7614 	wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
7615 		       GFP_KERNEL);
7616 	if (!wowl) {
7617 		bphy_err(drvr, "only support basic wowlan features\n");
7618 		wiphy->wowlan = &brcmf_wowlan_support;
7619 		return;
7620 	}
7621 
7622 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7623 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
7624 			wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
7625 			wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
7626 			init_waitqueue_head(&cfg->wowl.nd_data_wait);
7627 		}
7628 	}
7629 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
7630 		wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
7631 		wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
7632 	}
7633 
7634 	wiphy->wowlan = wowl;
7635 #endif
7636 }
7637 
7638 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
7639 {
7640 	struct brcmf_pub *drvr = ifp->drvr;
7641 	const struct ieee80211_iface_combination *combo;
7642 	struct ieee80211_supported_band *band;
7643 	u16 max_interfaces = 0;
7644 	bool gscan;
7645 	__le32 bandlist[3];
7646 	u32 n_bands;
7647 	int err, i;
7648 
7649 	wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
7650 	wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
7651 	wiphy->max_num_pmkids = BRCMF_MAXPMKID;
7652 
7653 	err = brcmf_setup_ifmodes(wiphy, ifp);
7654 	if (err)
7655 		return err;
7656 
7657 	for (i = 0, combo = wiphy->iface_combinations;
7658 	     i < wiphy->n_iface_combinations; i++, combo++) {
7659 		max_interfaces = max(max_interfaces, combo->max_interfaces);
7660 	}
7661 
7662 	for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
7663 	     i++) {
7664 		u8 *addr = drvr->addresses[i].addr;
7665 
7666 		memcpy(addr, drvr->mac, ETH_ALEN);
7667 		if (i) {
7668 			addr[0] |= BIT(1);
7669 			addr[ETH_ALEN - 1] ^= i;
7670 		}
7671 	}
7672 	wiphy->addresses = drvr->addresses;
7673 	wiphy->n_addresses = i;
7674 
7675 	wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7676 	wiphy->cipher_suites = brcmf_cipher_suites;
7677 	wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
7678 	if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
7679 		wiphy->n_cipher_suites--;
7680 	wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
7681 				    BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
7682 				    BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
7683 
7684 	wiphy->bss_param_support = WIPHY_BSS_PARAM_AP_ISOLATE;
7685 
7686 	wiphy->flags |= WIPHY_FLAG_NETNS_OK |
7687 			WIPHY_FLAG_PS_ON_BY_DEFAULT |
7688 			WIPHY_FLAG_HAVE_AP_SME |
7689 			WIPHY_FLAG_OFFCHAN_TX |
7690 			WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
7691 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
7692 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7693 	if (!ifp->drvr->settings->roamoff)
7694 		wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7695 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
7696 		wiphy_ext_feature_set(wiphy,
7697 				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
7698 		wiphy_ext_feature_set(wiphy,
7699 				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
7700 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7701 			wiphy_ext_feature_set(wiphy,
7702 					      NL80211_EXT_FEATURE_SAE_OFFLOAD);
7703 	}
7704 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH)) {
7705 		wiphy_ext_feature_set(wiphy,
7706 				      NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
7707 		if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7708 			wiphy_ext_feature_set(wiphy,
7709 					      NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
7710 	}
7711 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT))
7712 		wiphy->features |= NL80211_FEATURE_SAE;
7713 	wiphy->mgmt_stypes = brcmf_txrx_stypes;
7714 	wiphy->max_remain_on_channel_duration = 5000;
7715 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7716 		gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
7717 		brcmf_pno_wiphy_params(wiphy, gscan);
7718 	}
7719 	/* vendor commands/events support */
7720 	wiphy->vendor_commands = brcmf_vendor_cmds;
7721 	wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
7722 
7723 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
7724 		brcmf_wiphy_wowl_params(wiphy, ifp);
7725 	err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
7726 				     sizeof(bandlist));
7727 	if (err) {
7728 		bphy_err(drvr, "could not obtain band info: err=%d\n", err);
7729 		return err;
7730 	}
7731 	/* first entry in bandlist is number of bands */
7732 	n_bands = le32_to_cpu(bandlist[0]);
7733 	for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
7734 		if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
7735 			band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
7736 				       GFP_KERNEL);
7737 			if (!band)
7738 				return -ENOMEM;
7739 
7740 			band->channels = kmemdup(&__wl_2ghz_channels,
7741 						 sizeof(__wl_2ghz_channels),
7742 						 GFP_KERNEL);
7743 			if (!band->channels) {
7744 				kfree(band);
7745 				return -ENOMEM;
7746 			}
7747 
7748 			band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
7749 			wiphy->bands[NL80211_BAND_2GHZ] = band;
7750 		}
7751 		if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
7752 			band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
7753 				       GFP_KERNEL);
7754 			if (!band)
7755 				return -ENOMEM;
7756 
7757 			band->channels = kmemdup(&__wl_5ghz_channels,
7758 						 sizeof(__wl_5ghz_channels),
7759 						 GFP_KERNEL);
7760 			if (!band->channels) {
7761 				kfree(band);
7762 				return -ENOMEM;
7763 			}
7764 
7765 			band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
7766 			wiphy->bands[NL80211_BAND_5GHZ] = band;
7767 		}
7768 	}
7769 
7770 	if (wiphy->bands[NL80211_BAND_5GHZ] &&
7771 	    brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H))
7772 		wiphy_ext_feature_set(wiphy,
7773 				      NL80211_EXT_FEATURE_DFS_OFFLOAD);
7774 
7775 	wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
7776 
7777 	wiphy_read_of_freq_limits(wiphy);
7778 
7779 	return 0;
7780 }
7781 
7782 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
7783 {
7784 	struct brcmf_pub *drvr = cfg->pub;
7785 	struct net_device *ndev;
7786 	struct wireless_dev *wdev;
7787 	struct brcmf_if *ifp;
7788 	s32 power_mode;
7789 	s32 err = 0;
7790 
7791 	if (cfg->dongle_up)
7792 		return err;
7793 
7794 	ndev = cfg_to_ndev(cfg);
7795 	wdev = ndev->ieee80211_ptr;
7796 	ifp = netdev_priv(ndev);
7797 
7798 	/* make sure RF is ready for work */
7799 	brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
7800 
7801 	brcmf_dongle_scantime(ifp);
7802 
7803 	power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
7804 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
7805 	if (err)
7806 		goto default_conf_out;
7807 	brcmf_dbg(INFO, "power save set to %s\n",
7808 		  (power_mode ? "enabled" : "disabled"));
7809 
7810 	err = brcmf_dongle_roam(ifp);
7811 	if (err)
7812 		goto default_conf_out;
7813 	err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
7814 					  NULL);
7815 	if (err)
7816 		goto default_conf_out;
7817 
7818 	brcmf_configure_arp_nd_offload(ifp, true);
7819 
7820 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
7821 	if (err) {
7822 		bphy_err(drvr, "failed to set frameburst mode\n");
7823 		goto default_conf_out;
7824 	}
7825 
7826 	cfg->dongle_up = true;
7827 default_conf_out:
7828 
7829 	return err;
7830 
7831 }
7832 
7833 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
7834 {
7835 	set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7836 
7837 	return brcmf_config_dongle(ifp->drvr->config);
7838 }
7839 
7840 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
7841 {
7842 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7843 
7844 	/*
7845 	 * While going down, if associated with AP disassociate
7846 	 * from AP to save power
7847 	 */
7848 	if (check_vif_up(ifp->vif)) {
7849 		brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
7850 
7851 		/* Make sure WPA_Supplicant receives all the event
7852 		   generated due to DISASSOC call to the fw to keep
7853 		   the state fw and WPA_Supplicant state consistent
7854 		 */
7855 		brcmf_delay(500);
7856 	}
7857 
7858 	brcmf_abort_scanning(cfg);
7859 	clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7860 
7861 	return 0;
7862 }
7863 
7864 s32 brcmf_cfg80211_up(struct net_device *ndev)
7865 {
7866 	struct brcmf_if *ifp = netdev_priv(ndev);
7867 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7868 	s32 err = 0;
7869 
7870 	mutex_lock(&cfg->usr_sync);
7871 	err = __brcmf_cfg80211_up(ifp);
7872 	mutex_unlock(&cfg->usr_sync);
7873 
7874 	return err;
7875 }
7876 
7877 s32 brcmf_cfg80211_down(struct net_device *ndev)
7878 {
7879 	struct brcmf_if *ifp = netdev_priv(ndev);
7880 	struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7881 	s32 err = 0;
7882 
7883 	mutex_lock(&cfg->usr_sync);
7884 	err = __brcmf_cfg80211_down(ifp);
7885 	mutex_unlock(&cfg->usr_sync);
7886 
7887 	return err;
7888 }
7889 
7890 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
7891 			     unsigned long state)
7892 {
7893 	struct brcmf_cfg80211_vif *vif;
7894 
7895 	list_for_each_entry(vif, &cfg->vif_list, list) {
7896 		if (test_bit(state, &vif->sme_state))
7897 			return true;
7898 	}
7899 	return false;
7900 }
7901 
7902 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
7903 				    u8 action)
7904 {
7905 	u8 evt_action;
7906 
7907 	spin_lock(&event->vif_event_lock);
7908 	evt_action = event->action;
7909 	spin_unlock(&event->vif_event_lock);
7910 	return evt_action == action;
7911 }
7912 
7913 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
7914 				  struct brcmf_cfg80211_vif *vif)
7915 {
7916 	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7917 
7918 	spin_lock(&event->vif_event_lock);
7919 	event->vif = vif;
7920 	event->action = 0;
7921 	spin_unlock(&event->vif_event_lock);
7922 }
7923 
7924 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
7925 {
7926 	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7927 	bool armed;
7928 
7929 	spin_lock(&event->vif_event_lock);
7930 	armed = event->vif != NULL;
7931 	spin_unlock(&event->vif_event_lock);
7932 
7933 	return armed;
7934 }
7935 
7936 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
7937 				  u8 action, ulong timeout)
7938 {
7939 	struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7940 
7941 	return wait_event_timeout(event->vif_wq,
7942 				  vif_event_equals(event, action), timeout);
7943 }
7944 
7945 static bool brmcf_use_iso3166_ccode_fallback(struct brcmf_pub *drvr)
7946 {
7947 	if (drvr->settings->trivial_ccode_map)
7948 		return true;
7949 
7950 	switch (drvr->bus_if->chip) {
7951 	case BRCM_CC_43430_CHIP_ID:
7952 	case BRCM_CC_4345_CHIP_ID:
7953 	case BRCM_CC_4356_CHIP_ID:
7954 	case BRCM_CC_43602_CHIP_ID:
7955 		return true;
7956 	default:
7957 		return false;
7958 	}
7959 }
7960 
7961 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
7962 					struct brcmf_fil_country_le *ccreq)
7963 {
7964 	struct brcmfmac_pd_cc *country_codes;
7965 	struct brcmfmac_pd_cc_entry *cc;
7966 	s32 found_index;
7967 	int i;
7968 
7969 	if ((alpha2[0] == ccreq->country_abbrev[0]) &&
7970 	    (alpha2[1] == ccreq->country_abbrev[1])) {
7971 		brcmf_dbg(TRACE, "Country code already set\n");
7972 		return -EAGAIN;
7973 	}
7974 
7975 	country_codes = drvr->settings->country_codes;
7976 	if (!country_codes) {
7977 		if (brmcf_use_iso3166_ccode_fallback(drvr)) {
7978 			brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n");
7979 			memset(ccreq, 0, sizeof(*ccreq));
7980 			ccreq->country_abbrev[0] = alpha2[0];
7981 			ccreq->country_abbrev[1] = alpha2[1];
7982 			ccreq->ccode[0] = alpha2[0];
7983 			ccreq->ccode[1] = alpha2[1];
7984 			return 0;
7985 		}
7986 
7987 		brcmf_dbg(TRACE, "No country codes configured for device\n");
7988 		return -EINVAL;
7989 	}
7990 
7991 	found_index = -1;
7992 	for (i = 0; i < country_codes->table_size; i++) {
7993 		cc = &country_codes->table[i];
7994 		if ((cc->iso3166[0] == '\0') && (found_index == -1))
7995 			found_index = i;
7996 		if ((cc->iso3166[0] == alpha2[0]) &&
7997 		    (cc->iso3166[1] == alpha2[1])) {
7998 			found_index = i;
7999 			break;
8000 		}
8001 	}
8002 	if (found_index == -1) {
8003 		brcmf_dbg(TRACE, "No country code match found\n");
8004 		return -EINVAL;
8005 	}
8006 	memset(ccreq, 0, sizeof(*ccreq));
8007 	ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
8008 	memcpy(ccreq->ccode, country_codes->table[found_index].cc,
8009 	       BRCMF_COUNTRY_BUF_SZ);
8010 	ccreq->country_abbrev[0] = alpha2[0];
8011 	ccreq->country_abbrev[1] = alpha2[1];
8012 	ccreq->country_abbrev[2] = 0;
8013 
8014 	return 0;
8015 }
8016 
8017 static int
8018 brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey)
8019 {
8020 	int i;
8021 	char *token;
8022 	char delim[] = "\n ";
8023 	unsigned long val;
8024 	int err = 0;
8025 
8026 	token = strsep(&buf, delim);
8027 	while (token) {
8028 		if (!strcmp(token, "OBSS")) {
8029 			for (i = 0; i < OBSS_TOKEN_IDX; i++)
8030 				token = strsep(&buf, delim);
8031 			err = kstrtoul(token, 10, &val);
8032 			if (err)
8033 				break;
8034 			survey->obss = val;
8035 		}
8036 
8037 		if (!strcmp(token, "IBSS")) {
8038 			for (i = 0; i < IBSS_TOKEN_IDX; i++)
8039 				token = strsep(&buf, delim);
8040 			err = kstrtoul(token, 10, &val);
8041 			if (err)
8042 				break;
8043 			survey->ibss = val;
8044 		}
8045 
8046 		if (!strcmp(token, "TXDur")) {
8047 			for (i = 0; i < TX_TOKEN_IDX; i++)
8048 				token = strsep(&buf, delim);
8049 			err = kstrtoul(token, 10, &val);
8050 			if (err)
8051 				break;
8052 			survey->tx = val;
8053 		}
8054 
8055 		if (!strcmp(token, "Category")) {
8056 			for (i = 0; i < CTG_TOKEN_IDX; i++)
8057 				token = strsep(&buf, delim);
8058 			err = kstrtoul(token, 10, &val);
8059 			if (err)
8060 				break;
8061 			survey->no_ctg = val;
8062 		}
8063 
8064 		if (!strcmp(token, "Packet")) {
8065 			for (i = 0; i < PKT_TOKEN_IDX; i++)
8066 				token = strsep(&buf, delim);
8067 			err = kstrtoul(token, 10, &val);
8068 			if (err)
8069 				break;
8070 			survey->no_pckt = val;
8071 		}
8072 
8073 		if (!strcmp(token, "Opp(time):")) {
8074 			for (i = 0; i < IDLE_TOKEN_IDX; i++)
8075 				token = strsep(&buf, delim);
8076 			err = kstrtoul(token, 10, &val);
8077 			if (err)
8078 				break;
8079 			survey->idle = val;
8080 		}
8081 
8082 		token = strsep(&buf, delim);
8083 	}
8084 
8085 	return err;
8086 }
8087 
8088 static int
8089 brcmf_dump_obss(struct brcmf_if *ifp, struct cca_msrmnt_query req,
8090 		struct brcmf_dump_survey *survey)
8091 {
8092 	struct cca_stats_n_flags *results;
8093 	char *buf;
8094 	int err;
8095 
8096 	buf = kzalloc(sizeof(char) * BRCMF_DCMD_MEDLEN, GFP_KERNEL);
8097 	if (!buf)
8098 		return -ENOMEM;
8099 
8100 	memcpy(buf, &req, sizeof(struct cca_msrmnt_query));
8101 	err = brcmf_fil_iovar_data_get(ifp, "dump_obss",
8102 				       buf, BRCMF_DCMD_MEDLEN);
8103 	if (err) {
8104 		brcmf_err("dump_obss error (%d)\n", err);
8105 		err = -EINVAL;
8106 		goto exit;
8107 	}
8108 	results = (struct cca_stats_n_flags *)(buf);
8109 
8110 	if (req.msrmnt_query)
8111 		brcmf_parse_dump_obss(results->buf, survey);
8112 
8113 exit:
8114 	kfree(buf);
8115 	return err;
8116 }
8117 
8118 static s32
8119 brcmf_set_channel(struct brcmf_cfg80211_info *cfg, struct ieee80211_channel *chan)
8120 {
8121 	u16 chspec = 0;
8122 	int err = 0;
8123 	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
8124 
8125 	if (chan->flags & IEEE80211_CHAN_DISABLED)
8126 		return -EINVAL;
8127 
8128 	/* set_channel */
8129 	chspec = channel_to_chanspec(&cfg->d11inf, chan);
8130 	if (chspec != INVCHANSPEC) {
8131 		err = brcmf_fil_iovar_int_set(ifp, "chanspec", chspec);
8132 		if (err) {
8133 			brcmf_err("set chanspec 0x%04x fail, reason %d\n", chspec, err);
8134 			err = -EINVAL;
8135 		}
8136 	} else {
8137 		brcmf_err("failed to convert host chanspec to fw chanspec\n");
8138 		err = -EINVAL;
8139 	}
8140 
8141 	return err;
8142 }
8143 
8144 static int
8145 brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
8146 			   int idx, struct survey_info *info)
8147 {
8148 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
8149 	struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
8150 	struct brcmf_dump_survey survey = {};
8151 	struct ieee80211_supported_band *band;
8152 	enum nl80211_band band_id;
8153 	struct cca_msrmnt_query req;
8154 	u32 noise;
8155 	int err;
8156 
8157 	brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx);
8158 
8159 	/* Do not run survey when VIF in CONNECTING / CONNECTED states */
8160 	if ((test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) ||
8161 	    (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))) {
8162 		return -EBUSY;
8163 	}
8164 
8165 	for (band_id = 0; band_id < NUM_NL80211_BANDS; band_id++) {
8166 		band = wiphy->bands[band_id];
8167 		if (!band)
8168 			continue;
8169 		if (idx >= band->n_channels) {
8170 			idx -= band->n_channels;
8171 			continue;
8172 		}
8173 
8174 		info->channel = &band->channels[idx];
8175 		break;
8176 	}
8177 	if (band_id == NUM_NL80211_BANDS)
8178 		return -ENOENT;
8179 
8180 	/* Setting current channel to the requested channel */
8181 	info->filled = 0;
8182 	if (brcmf_set_channel(cfg, info->channel))
8183 		return 0;
8184 
8185 	/* Disable mpc */
8186 	brcmf_set_mpc(ifp, 0);
8187 
8188 	/* Set interface up, explicitly. */
8189 	err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
8190 	if (err) {
8191 		brcmf_err("set interface up failed, err = %d\n", err);
8192 		goto exit;
8193 	}
8194 
8195 	/* Get noise value */
8196 	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
8197 	if (err) {
8198 		brcmf_err("Get Phy Noise failed, use dummy value\n");
8199 		noise = CHAN_NOISE_DUMMY;
8200 	}
8201 
8202 	/* Start Measurement for obss stats on current channel */
8203 	req.msrmnt_query = 0;
8204 	req.time_req = ACS_MSRMNT_DELAY;
8205 	err = brcmf_dump_obss(ifp, req, &survey);
8206 	if (err)
8207 		goto exit;
8208 
8209 	/* Add 10 ms for IOVAR completion */
8210 	msleep(ACS_MSRMNT_DELAY + 10);
8211 
8212 	/* Issue IOVAR to collect measurement results */
8213 	req.msrmnt_query = 1;
8214 	err = brcmf_dump_obss(ifp, req, &survey);
8215 	if (err)
8216 		goto exit;
8217 
8218 	info->noise = noise;
8219 	info->time = ACS_MSRMNT_DELAY;
8220 	info->time_busy = ACS_MSRMNT_DELAY - survey.idle;
8221 	info->time_rx = survey.obss + survey.ibss + survey.no_ctg +
8222 		survey.no_pckt;
8223 	info->time_tx = survey.tx;
8224 	info->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME |
8225 		SURVEY_INFO_TIME_BUSY | SURVEY_INFO_TIME_RX |
8226 		SURVEY_INFO_TIME_TX;
8227 
8228 	brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n",
8229 		  ieee80211_frequency_to_channel(info->channel->center_freq),
8230 		  ACS_MSRMNT_DELAY);
8231 	brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
8232 		  info->noise, info->time_busy, info->time_rx, info->time_tx);
8233 
8234 exit:
8235 	if (!brcmf_is_apmode(ifp->vif))
8236 		brcmf_set_mpc(ifp, 1);
8237 	return err;
8238 }
8239 
8240 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
8241 					struct regulatory_request *req)
8242 {
8243 	struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
8244 	struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
8245 	struct brcmf_pub *drvr = cfg->pub;
8246 	struct brcmf_fil_country_le ccreq;
8247 	s32 err;
8248 	int i;
8249 
8250 	/* The country code gets set to "00" by default at boot, ignore */
8251 	if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
8252 		return;
8253 
8254 	/* ignore non-ISO3166 country codes */
8255 	for (i = 0; i < 2; i++)
8256 		if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
8257 			bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
8258 				 req->alpha2[0], req->alpha2[1]);
8259 			return;
8260 		}
8261 
8262 	brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
8263 		  req->alpha2[0], req->alpha2[1]);
8264 
8265 	err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
8266 	if (err) {
8267 		bphy_err(drvr, "Country code iovar returned err = %d\n", err);
8268 		return;
8269 	}
8270 
8271 	err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
8272 	if (err)
8273 		return;
8274 
8275 	err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
8276 	if (err) {
8277 		bphy_err(drvr, "Firmware rejected country setting\n");
8278 		return;
8279 	}
8280 	brcmf_setup_wiphybands(cfg);
8281 }
8282 
8283 static void brcmf_free_wiphy(struct wiphy *wiphy)
8284 {
8285 	int i;
8286 
8287 	if (!wiphy)
8288 		return;
8289 
8290 	if (wiphy->iface_combinations) {
8291 		for (i = 0; i < wiphy->n_iface_combinations; i++)
8292 			kfree(wiphy->iface_combinations[i].limits);
8293 	}
8294 	kfree(wiphy->iface_combinations);
8295 	if (wiphy->bands[NL80211_BAND_2GHZ]) {
8296 		kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
8297 		kfree(wiphy->bands[NL80211_BAND_2GHZ]);
8298 	}
8299 	if (wiphy->bands[NL80211_BAND_5GHZ]) {
8300 		kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
8301 		kfree(wiphy->bands[NL80211_BAND_5GHZ]);
8302 	}
8303 #if IS_ENABLED(CONFIG_PM)
8304 	if (wiphy->wowlan != &brcmf_wowlan_support)
8305 		kfree(wiphy->wowlan);
8306 #endif
8307 }
8308 
8309 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
8310 						  struct cfg80211_ops *ops,
8311 						  bool p2pdev_forced)
8312 {
8313 	struct wiphy *wiphy = drvr->wiphy;
8314 	struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
8315 	struct brcmf_cfg80211_info *cfg;
8316 	struct brcmf_cfg80211_vif *vif;
8317 	struct brcmf_if *ifp;
8318 	s32 err = 0;
8319 	s32 io_type;
8320 	u16 *cap = NULL;
8321 
8322 	if (!ndev) {
8323 		bphy_err(drvr, "ndev is invalid\n");
8324 		return NULL;
8325 	}
8326 
8327 	cfg = kzalloc_obj(*cfg);
8328 	if (!cfg) {
8329 		bphy_err(drvr, "Could not allocate wiphy device\n");
8330 		return NULL;
8331 	}
8332 
8333 	cfg->wiphy = wiphy;
8334 	cfg->pub = drvr;
8335 	init_vif_event(&cfg->vif_event);
8336 	INIT_LIST_HEAD(&cfg->vif_list);
8337 
8338 	vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
8339 	if (IS_ERR(vif))
8340 		goto wiphy_out;
8341 
8342 	ifp = netdev_priv(ndev);
8343 	vif->ifp = ifp;
8344 	vif->wdev.netdev = ndev;
8345 	ndev->ieee80211_ptr = &vif->wdev;
8346 	SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
8347 
8348 	err = wl_init_priv(cfg);
8349 	if (err) {
8350 		bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
8351 		brcmf_free_vif(vif);
8352 		goto wiphy_out;
8353 	}
8354 	ifp->vif = vif;
8355 
8356 	/* determine d11 io type before wiphy setup */
8357 	err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
8358 	if (err) {
8359 		bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
8360 		goto priv_out;
8361 	}
8362 	cfg->d11inf.io_type = (u8)io_type;
8363 	brcmu_d11_attach(&cfg->d11inf);
8364 
8365 	/* regulatory notifier below needs access to cfg so
8366 	 * assign it now.
8367 	 */
8368 	drvr->config = cfg;
8369 
8370 	err = brcmf_setup_wiphy(wiphy, ifp);
8371 	if (err < 0)
8372 		goto priv_out;
8373 
8374 	brcmf_dbg(INFO, "Registering custom regulatory\n");
8375 	wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
8376 	wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
8377 	wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
8378 
8379 	/* firmware defaults to 40MHz disabled in 2G band. We signal
8380 	 * cfg80211 here that we do and have it decide we can enable
8381 	 * it. But first check if device does support 2G operation.
8382 	 */
8383 	if (wiphy->bands[NL80211_BAND_2GHZ]) {
8384 		cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
8385 		*cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8386 	}
8387 #ifdef CONFIG_PM
8388 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
8389 		ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
8390 #endif
8391 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DUMP_OBSS))
8392 		ops->dump_survey = brcmf_cfg80211_dump_survey;
8393 
8394 	err = wiphy_register(wiphy);
8395 	if (err < 0) {
8396 		bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
8397 		goto priv_out;
8398 	}
8399 
8400 	err = brcmf_setup_wiphybands(cfg);
8401 	if (err) {
8402 		bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
8403 		goto wiphy_unreg_out;
8404 	}
8405 
8406 	/* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
8407 	 * setup 40MHz in 2GHz band and enable OBSS scanning.
8408 	 */
8409 	if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
8410 		err = brcmf_enable_bw40_2g(cfg);
8411 		if (!err)
8412 			err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
8413 						      BRCMF_OBSS_COEX_AUTO);
8414 		else
8415 			*cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8416 	}
8417 
8418 	err = brcmf_fweh_activate_events(ifp);
8419 	if (err) {
8420 		bphy_err(drvr, "FWEH activation failed (%d)\n", err);
8421 		goto wiphy_unreg_out;
8422 	}
8423 
8424 	err = brcmf_p2p_attach(cfg, p2pdev_forced);
8425 	if (err) {
8426 		bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
8427 		goto wiphy_unreg_out;
8428 	}
8429 	err = brcmf_btcoex_attach(cfg);
8430 	if (err) {
8431 		bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
8432 		brcmf_p2p_detach(&cfg->p2p);
8433 		goto wiphy_unreg_out;
8434 	}
8435 	err = brcmf_pno_attach(cfg);
8436 	if (err) {
8437 		bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
8438 		brcmf_btcoex_detach(cfg);
8439 		brcmf_p2p_detach(&cfg->p2p);
8440 		goto wiphy_unreg_out;
8441 	}
8442 
8443 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
8444 		err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
8445 		if (err) {
8446 			brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
8447 			wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
8448 		} else {
8449 			brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
8450 					    brcmf_notify_tdls_peer_event);
8451 		}
8452 	}
8453 
8454 	/* (re-) activate FWEH event handling */
8455 	err = brcmf_fweh_activate_events(ifp);
8456 	if (err) {
8457 		bphy_err(drvr, "FWEH activation failed (%d)\n", err);
8458 		goto detach;
8459 	}
8460 
8461 	/* Fill in some of the advertised nl80211 supported features */
8462 	if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
8463 		wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
8464 #ifdef CONFIG_PM
8465 		if (wiphy->wowlan &&
8466 		    wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
8467 			wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
8468 #endif
8469 	}
8470 
8471 	return cfg;
8472 
8473 detach:
8474 	brcmf_pno_detach(cfg);
8475 	brcmf_btcoex_detach(cfg);
8476 	brcmf_p2p_detach(&cfg->p2p);
8477 wiphy_unreg_out:
8478 	wiphy_unregister(cfg->wiphy);
8479 priv_out:
8480 	wl_deinit_priv(cfg);
8481 	brcmf_free_vif(vif);
8482 	ifp->vif = NULL;
8483 wiphy_out:
8484 	brcmf_free_wiphy(wiphy);
8485 	kfree(cfg);
8486 	return NULL;
8487 }
8488 
8489 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
8490 {
8491 	if (!cfg)
8492 		return;
8493 
8494 	brcmf_pno_detach(cfg);
8495 	brcmf_btcoex_detach(cfg);
8496 	wiphy_unregister(cfg->wiphy);
8497 	wl_deinit_priv(cfg);
8498 	cancel_work_sync(&cfg->escan_timeout_work);
8499 	brcmf_free_wiphy(cfg->wiphy);
8500 	kfree(cfg);
8501 }
8502