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