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