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