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