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