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