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