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