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