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