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