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