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