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