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