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