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_AKM_SAE 8
60#define RSN_CAP_LEN 2
61#define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
62#define RSN_CAP_MFPR_MASK BIT(6)
63#define RSN_CAP_MFPC_MASK BIT(7)
64#define RSN_PMKID_COUNT_LEN 2
65
66#define VNDR_IE_CMD_LEN 4
67
68
69#define VNDR_IE_COUNT_OFFSET 4
70#define VNDR_IE_PKTFLAG_OFFSET 8
71#define VNDR_IE_VSIE_OFFSET 12
72#define VNDR_IE_HDR_SIZE 12
73#define VNDR_IE_PARSE_LIMIT 5
74
75#define DOT11_MGMT_HDR_LEN 24
76#define DOT11_BCN_PRB_FIXED_LEN 12
77
78#define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
79#define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
80#define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
81
82#define BRCMF_SCAN_CHANNEL_TIME 40
83#define BRCMF_SCAN_UNASSOC_TIME 40
84#define BRCMF_SCAN_PASSIVE_TIME 120
85
86#define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
87
88#define BRCMF_PS_MAX_TIMEOUT_MS 2000
89
90#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
91 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
92
93static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
94{
95 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
96 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
97 vif->sme_state);
98 return false;
99 }
100 return true;
101}
102
103#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
104#define RATETAB_ENT(_rateid, _flags) \
105 { \
106 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
107 .hw_value = (_rateid), \
108 .flags = (_flags), \
109 }
110
111static struct ieee80211_rate __wl_rates[] = {
112 RATETAB_ENT(BRCM_RATE_1M, 0),
113 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
114 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
115 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
116 RATETAB_ENT(BRCM_RATE_6M, 0),
117 RATETAB_ENT(BRCM_RATE_9M, 0),
118 RATETAB_ENT(BRCM_RATE_12M, 0),
119 RATETAB_ENT(BRCM_RATE_18M, 0),
120 RATETAB_ENT(BRCM_RATE_24M, 0),
121 RATETAB_ENT(BRCM_RATE_36M, 0),
122 RATETAB_ENT(BRCM_RATE_48M, 0),
123 RATETAB_ENT(BRCM_RATE_54M, 0),
124};
125
126#define wl_g_rates (__wl_rates + 0)
127#define wl_g_rates_size ARRAY_SIZE(__wl_rates)
128#define wl_a_rates (__wl_rates + 4)
129#define wl_a_rates_size (wl_g_rates_size - 4)
130
131#define CHAN2G(_channel, _freq) { \
132 .band = NL80211_BAND_2GHZ, \
133 .center_freq = (_freq), \
134 .hw_value = (_channel), \
135 .max_antenna_gain = 0, \
136 .max_power = 30, \
137}
138
139#define CHAN5G(_channel) { \
140 .band = NL80211_BAND_5GHZ, \
141 .center_freq = 5000 + (5 * (_channel)), \
142 .hw_value = (_channel), \
143 .max_antenna_gain = 0, \
144 .max_power = 30, \
145}
146
147static struct ieee80211_channel __wl_2ghz_channels[] = {
148 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
149 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
150 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
151 CHAN2G(13, 2472), CHAN2G(14, 2484)
152};
153
154static struct ieee80211_channel __wl_5ghz_channels[] = {
155 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
156 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
157 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
158 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
159 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
160 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
161};
162
163
164
165
166static const struct ieee80211_supported_band __wl_band_2ghz = {
167 .band = NL80211_BAND_2GHZ,
168 .bitrates = wl_g_rates,
169 .n_bitrates = wl_g_rates_size,
170};
171
172static const struct ieee80211_supported_band __wl_band_5ghz = {
173 .band = NL80211_BAND_5GHZ,
174 .bitrates = wl_a_rates,
175 .n_bitrates = wl_a_rates_size,
176};
177
178
179
180
181
182
183
184
185static const struct ieee80211_regdomain brcmf_regdom = {
186 .n_reg_rules = 4,
187 .alpha2 = "99",
188 .reg_rules = {
189
190 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
191
192
193
194
195 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
196
197 REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
198
199 REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
200};
201
202
203
204
205
206
207
208static const u32 brcmf_cipher_suites[] = {
209 WLAN_CIPHER_SUITE_WEP40,
210 WLAN_CIPHER_SUITE_WEP104,
211 WLAN_CIPHER_SUITE_TKIP,
212 WLAN_CIPHER_SUITE_CCMP,
213
214 WLAN_CIPHER_SUITE_AES_CMAC
215};
216
217
218struct brcmf_vs_tlv {
219 u8 id;
220 u8 len;
221 u8 oui[3];
222 u8 oui_type;
223};
224
225struct parsed_vndr_ie_info {
226 u8 *ie_ptr;
227 u32 ie_len;
228 struct brcmf_vs_tlv vndrie;
229};
230
231struct parsed_vndr_ies {
232 u32 count;
233 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
234};
235
236static u8 nl80211_band_to_fwil(enum nl80211_band band)
237{
238 switch (band) {
239 case NL80211_BAND_2GHZ:
240 return WLC_BAND_2G;
241 case NL80211_BAND_5GHZ:
242 return WLC_BAND_5G;
243 default:
244 WARN_ON(1);
245 break;
246 }
247 return 0;
248}
249
250static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
251 struct cfg80211_chan_def *ch)
252{
253 struct brcmu_chan ch_inf;
254 s32 primary_offset;
255
256 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
257 ch->chan->center_freq, ch->center_freq1, ch->width);
258 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
259 primary_offset = ch->chan->center_freq - ch->center_freq1;
260 switch (ch->width) {
261 case NL80211_CHAN_WIDTH_20:
262 case NL80211_CHAN_WIDTH_20_NOHT:
263 ch_inf.bw = BRCMU_CHAN_BW_20;
264 WARN_ON(primary_offset != 0);
265 break;
266 case NL80211_CHAN_WIDTH_40:
267 ch_inf.bw = BRCMU_CHAN_BW_40;
268 if (primary_offset > 0)
269 ch_inf.sb = BRCMU_CHAN_SB_U;
270 else
271 ch_inf.sb = BRCMU_CHAN_SB_L;
272 break;
273 case NL80211_CHAN_WIDTH_80:
274 ch_inf.bw = BRCMU_CHAN_BW_80;
275 if (primary_offset == -30)
276 ch_inf.sb = BRCMU_CHAN_SB_LL;
277 else if (primary_offset == -10)
278 ch_inf.sb = BRCMU_CHAN_SB_LU;
279 else if (primary_offset == 10)
280 ch_inf.sb = BRCMU_CHAN_SB_UL;
281 else
282 ch_inf.sb = BRCMU_CHAN_SB_UU;
283 break;
284 case NL80211_CHAN_WIDTH_160:
285 ch_inf.bw = BRCMU_CHAN_BW_160;
286 if (primary_offset == -70)
287 ch_inf.sb = BRCMU_CHAN_SB_LLL;
288 else if (primary_offset == -50)
289 ch_inf.sb = BRCMU_CHAN_SB_LLU;
290 else if (primary_offset == -30)
291 ch_inf.sb = BRCMU_CHAN_SB_LUL;
292 else if (primary_offset == -10)
293 ch_inf.sb = BRCMU_CHAN_SB_LUU;
294 else if (primary_offset == 10)
295 ch_inf.sb = BRCMU_CHAN_SB_ULL;
296 else if (primary_offset == 30)
297 ch_inf.sb = BRCMU_CHAN_SB_ULU;
298 else if (primary_offset == 50)
299 ch_inf.sb = BRCMU_CHAN_SB_UUL;
300 else
301 ch_inf.sb = BRCMU_CHAN_SB_UUU;
302 break;
303 case NL80211_CHAN_WIDTH_80P80:
304 case NL80211_CHAN_WIDTH_5:
305 case NL80211_CHAN_WIDTH_10:
306 default:
307 WARN_ON_ONCE(1);
308 }
309 switch (ch->chan->band) {
310 case NL80211_BAND_2GHZ:
311 ch_inf.band = BRCMU_CHAN_BAND_2G;
312 break;
313 case NL80211_BAND_5GHZ:
314 ch_inf.band = BRCMU_CHAN_BAND_5G;
315 break;
316 case NL80211_BAND_60GHZ:
317 default:
318 WARN_ON_ONCE(1);
319 }
320 d11inf->encchspec(&ch_inf);
321
322 brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
323 return ch_inf.chspec;
324}
325
326u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
327 struct ieee80211_channel *ch)
328{
329 struct brcmu_chan ch_inf;
330
331 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
332 ch_inf.bw = BRCMU_CHAN_BW_20;
333 d11inf->encchspec(&ch_inf);
334
335 return ch_inf.chspec;
336}
337
338
339
340
341
342static const struct brcmf_tlv *
343brcmf_parse_tlvs(const void *buf, int buflen, uint key)
344{
345 const struct brcmf_tlv *elt = buf;
346 int totlen = buflen;
347
348
349 while (totlen >= TLV_HDR_LEN) {
350 int len = elt->len;
351
352
353 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
354 return elt;
355
356 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
357 totlen -= (len + TLV_HDR_LEN);
358 }
359
360 return NULL;
361}
362
363
364
365
366static bool
367brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
368 const u8 *oui, u32 oui_len, u8 type)
369{
370
371 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
372 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
373 type == ie[TLV_BODY_OFF + oui_len]) {
374 return true;
375 }
376
377 if (tlvs == NULL)
378 return false;
379
380 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
381
382 *tlvs_len -= (int)(ie - *tlvs);
383
384 *tlvs = ie;
385
386 return false;
387}
388
389static struct brcmf_vs_tlv *
390brcmf_find_wpaie(const u8 *parse, u32 len)
391{
392 const struct brcmf_tlv *ie;
393
394 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
395 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
396 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
397 return (struct brcmf_vs_tlv *)ie;
398 }
399 return NULL;
400}
401
402static struct brcmf_vs_tlv *
403brcmf_find_wpsie(const u8 *parse, u32 len)
404{
405 const struct brcmf_tlv *ie;
406
407 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
408 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
409 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
410 return (struct brcmf_vs_tlv *)ie;
411 }
412 return NULL;
413}
414
415static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
416 struct brcmf_cfg80211_vif *vif,
417 enum nl80211_iftype new_type)
418{
419 struct brcmf_cfg80211_vif *pos;
420 bool check_combos = false;
421 int ret = 0;
422 struct iface_combination_params params = {
423 .num_different_channels = 1,
424 };
425
426 list_for_each_entry(pos, &cfg->vif_list, list)
427 if (pos == vif) {
428 params.iftype_num[new_type]++;
429 } else {
430
431 check_combos = true;
432 params.iftype_num[pos->wdev.iftype]++;
433 }
434
435 if (check_combos)
436 ret = cfg80211_check_combinations(cfg->wiphy, ¶ms);
437
438 return ret;
439}
440
441static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
442 enum nl80211_iftype new_type)
443{
444 struct brcmf_cfg80211_vif *pos;
445 struct iface_combination_params params = {
446 .num_different_channels = 1,
447 };
448
449 list_for_each_entry(pos, &cfg->vif_list, list)
450 params.iftype_num[pos->wdev.iftype]++;
451
452 params.iftype_num[new_type]++;
453 return cfg80211_check_combinations(cfg->wiphy, ¶ms);
454}
455
456static void convert_key_from_CPU(struct brcmf_wsec_key *key,
457 struct brcmf_wsec_key_le *key_le)
458{
459 key_le->index = cpu_to_le32(key->index);
460 key_le->len = cpu_to_le32(key->len);
461 key_le->algo = cpu_to_le32(key->algo);
462 key_le->flags = cpu_to_le32(key->flags);
463 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
464 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
465 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
466 memcpy(key_le->data, key->data, sizeof(key->data));
467 memcpy(key_le->ea, key->ea, sizeof(key->ea));
468}
469
470static int
471send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
472{
473 struct brcmf_pub *drvr = ifp->drvr;
474 int err;
475 struct brcmf_wsec_key_le key_le;
476
477 convert_key_from_CPU(key, &key_le);
478
479 brcmf_netdev_wait_pend8021x(ifp);
480
481 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
482 sizeof(key_le));
483
484 if (err)
485 bphy_err(drvr, "wsec_key error (%d)\n", err);
486 return err;
487}
488
489static void
490brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
491{
492 struct brcmf_cfg80211_vif *vif;
493 struct brcmf_if *ifp;
494
495 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
496 ifp = vif->ifp;
497
498 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
499 (wdev->iftype == NL80211_IFTYPE_AP) ||
500 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
501 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
502 ADDR_DIRECT);
503 else
504 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
505 ADDR_INDIRECT);
506}
507
508static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
509{
510 int bsscfgidx;
511
512 for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
513
514 if (bsscfgidx == 1)
515 continue;
516 if (!drvr->iflist[bsscfgidx])
517 return bsscfgidx;
518 }
519
520 return -ENOMEM;
521}
522
523static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
524{
525 struct brcmf_pub *drvr = ifp->drvr;
526 struct brcmf_mbss_ssid_le mbss_ssid_le;
527 int bsscfgidx;
528 int err;
529
530 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
531 bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
532 if (bsscfgidx < 0)
533 return bsscfgidx;
534
535 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
536 mbss_ssid_le.SSID_len = cpu_to_le32(5);
537 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
538
539 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
540 sizeof(mbss_ssid_le));
541 if (err < 0)
542 bphy_err(drvr, "setting ssid failed %d\n", err);
543
544 return err;
545}
546
547
548
549
550
551
552
553
554static
555struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
556 struct vif_params *params)
557{
558 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
559 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
560 struct brcmf_pub *drvr = cfg->pub;
561 struct brcmf_cfg80211_vif *vif;
562 int err;
563
564 if (brcmf_cfg80211_vif_event_armed(cfg))
565 return ERR_PTR(-EBUSY);
566
567 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
568
569 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
570 if (IS_ERR(vif))
571 return (struct wireless_dev *)vif;
572
573 brcmf_cfg80211_arm_vif_event(cfg, vif);
574
575 err = brcmf_cfg80211_request_ap_if(ifp);
576 if (err) {
577 brcmf_cfg80211_arm_vif_event(cfg, NULL);
578 goto fail;
579 }
580
581
582 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
583 BRCMF_VIF_EVENT_TIMEOUT);
584 brcmf_cfg80211_arm_vif_event(cfg, NULL);
585 if (!err) {
586 bphy_err(drvr, "timeout occurred\n");
587 err = -EIO;
588 goto fail;
589 }
590
591
592 ifp = vif->ifp;
593 if (!ifp) {
594 bphy_err(drvr, "no if pointer provided\n");
595 err = -ENOENT;
596 goto fail;
597 }
598
599 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
600 err = brcmf_net_attach(ifp, true);
601 if (err) {
602 bphy_err(drvr, "Registering netdevice failed\n");
603 free_netdev(ifp->ndev);
604 goto fail;
605 }
606
607 return &ifp->vif->wdev;
608
609fail:
610 brcmf_free_vif(vif);
611 return ERR_PTR(err);
612}
613
614static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
615{
616 enum nl80211_iftype iftype;
617
618 iftype = vif->wdev.iftype;
619 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
620}
621
622static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
623{
624 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
625}
626
627
628
629
630
631
632
633static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
634 const char *name)
635{
636 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
637 struct brcmf_cfg80211_vif *vif;
638 struct net_device *ndev;
639 struct brcmf_if *ifp;
640 int err;
641
642 if (cfg->pub->mon_if) {
643 err = -EEXIST;
644 goto err_out;
645 }
646
647 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
648 if (IS_ERR(vif)) {
649 err = PTR_ERR(vif);
650 goto err_out;
651 }
652
653 ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
654 if (!ndev) {
655 err = -ENOMEM;
656 goto err_free_vif;
657 }
658 ndev->type = ARPHRD_IEEE80211_RADIOTAP;
659 ndev->ieee80211_ptr = &vif->wdev;
660 ndev->needs_free_netdev = true;
661 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
662 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
663
664 ifp = netdev_priv(ndev);
665 ifp->vif = vif;
666 ifp->ndev = ndev;
667 ifp->drvr = cfg->pub;
668
669 vif->ifp = ifp;
670 vif->wdev.netdev = ndev;
671
672 err = brcmf_net_mon_attach(ifp);
673 if (err) {
674 brcmf_err("Failed to attach %s device\n", ndev->name);
675 free_netdev(ndev);
676 goto err_free_vif;
677 }
678
679 cfg->pub->mon_if = ifp;
680
681 return &vif->wdev;
682
683err_free_vif:
684 brcmf_free_vif(vif);
685err_out:
686 return ERR_PTR(err);
687}
688
689static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
690{
691 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
692 struct net_device *ndev = wdev->netdev;
693
694 ndev->netdev_ops->ndo_stop(ndev);
695
696 brcmf_net_detach(ndev, true);
697
698 cfg->pub->mon_if = NULL;
699
700 return 0;
701}
702
703static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
704 const char *name,
705 unsigned char name_assign_type,
706 enum nl80211_iftype type,
707 struct vif_params *params)
708{
709 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
710 struct brcmf_pub *drvr = cfg->pub;
711 struct wireless_dev *wdev;
712 int err;
713
714 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
715 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
716 if (err) {
717 bphy_err(drvr, "iface validation failed: err=%d\n", err);
718 return ERR_PTR(err);
719 }
720 switch (type) {
721 case NL80211_IFTYPE_ADHOC:
722 case NL80211_IFTYPE_STATION:
723 case NL80211_IFTYPE_AP_VLAN:
724 case NL80211_IFTYPE_WDS:
725 case NL80211_IFTYPE_MESH_POINT:
726 return ERR_PTR(-EOPNOTSUPP);
727 case NL80211_IFTYPE_MONITOR:
728 return brcmf_mon_add_vif(wiphy, name);
729 case NL80211_IFTYPE_AP:
730 wdev = brcmf_ap_add_vif(wiphy, name, params);
731 break;
732 case NL80211_IFTYPE_P2P_CLIENT:
733 case NL80211_IFTYPE_P2P_GO:
734 case NL80211_IFTYPE_P2P_DEVICE:
735 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
736 break;
737 case NL80211_IFTYPE_UNSPECIFIED:
738 default:
739 return ERR_PTR(-EINVAL);
740 }
741
742 if (IS_ERR(wdev))
743 bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
744 type, (int)PTR_ERR(wdev));
745 else
746 brcmf_cfg80211_update_proto_addr_mode(wdev);
747
748 return wdev;
749}
750
751static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
752{
753 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
754 brcmf_set_mpc(ifp, mpc);
755}
756
757void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
758{
759 struct brcmf_pub *drvr = ifp->drvr;
760 s32 err = 0;
761
762 if (check_vif_up(ifp->vif)) {
763 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
764 if (err) {
765 bphy_err(drvr, "fail to set mpc\n");
766 return;
767 }
768 brcmf_dbg(INFO, "MPC : %d\n", mpc);
769 }
770}
771
772s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
773 struct brcmf_if *ifp, bool aborted,
774 bool fw_abort)
775{
776 struct brcmf_pub *drvr = cfg->pub;
777 struct brcmf_scan_params_le params_le;
778 struct cfg80211_scan_request *scan_request;
779 u64 reqid;
780 u32 bucket;
781 s32 err = 0;
782
783 brcmf_dbg(SCAN, "Enter\n");
784
785
786
787 scan_request = cfg->scan_request;
788 cfg->scan_request = NULL;
789
790 if (timer_pending(&cfg->escan_timeout))
791 del_timer_sync(&cfg->escan_timeout);
792
793 if (fw_abort) {
794
795 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
796 memset(¶ms_le, 0, sizeof(params_le));
797 eth_broadcast_addr(params_le.bssid);
798 params_le.bss_type = DOT11_BSSTYPE_ANY;
799 params_le.scan_type = 0;
800 params_le.channel_num = cpu_to_le32(1);
801 params_le.nprobes = cpu_to_le32(1);
802 params_le.active_time = cpu_to_le32(-1);
803 params_le.passive_time = cpu_to_le32(-1);
804 params_le.home_time = cpu_to_le32(-1);
805
806 params_le.channel_list[0] = cpu_to_le16(-1);
807
808 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
809 ¶ms_le, sizeof(params_le));
810 if (err)
811 bphy_err(drvr, "Scan abort failed\n");
812 }
813
814 brcmf_scan_config_mpc(ifp, 1);
815
816
817
818
819
820 if (cfg->int_escan_map) {
821 brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
822 cfg->int_escan_map);
823 while (cfg->int_escan_map) {
824 bucket = __ffs(cfg->int_escan_map);
825 cfg->int_escan_map &= ~BIT(bucket);
826 reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
827 bucket);
828 if (!aborted) {
829 brcmf_dbg(SCAN, "report results: reqid=%llu\n",
830 reqid);
831 cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
832 reqid);
833 }
834 }
835 } else if (scan_request) {
836 struct cfg80211_scan_info info = {
837 .aborted = aborted,
838 };
839
840 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
841 aborted ? "Aborted" : "Done");
842 cfg80211_scan_done(scan_request, &info);
843 }
844 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
845 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
846
847 return err;
848}
849
850static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
851 struct wireless_dev *wdev)
852{
853 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
854 struct net_device *ndev = wdev->netdev;
855 struct brcmf_if *ifp = netdev_priv(ndev);
856 struct brcmf_pub *drvr = cfg->pub;
857 int ret;
858 int err;
859
860 brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
861
862 err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
863 if (err) {
864 bphy_err(drvr, "interface_remove failed %d\n", err);
865 goto err_unarm;
866 }
867
868
869 ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
870 BRCMF_VIF_EVENT_TIMEOUT);
871 if (!ret) {
872 bphy_err(drvr, "timeout occurred\n");
873 err = -EIO;
874 goto err_unarm;
875 }
876
877 brcmf_remove_interface(ifp, true);
878
879err_unarm:
880 brcmf_cfg80211_arm_vif_event(cfg, NULL);
881 return err;
882}
883
884static
885int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
886{
887 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
888 struct net_device *ndev = wdev->netdev;
889
890 if (ndev && ndev == cfg_to_ndev(cfg))
891 return -ENOTSUPP;
892
893
894 if (brcmf_cfg80211_vif_event_armed(cfg))
895 return -EBUSY;
896
897 if (ndev) {
898 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
899 cfg->escan_info.ifp == netdev_priv(ndev))
900 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
901 true, true);
902
903 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
904 }
905
906 switch (wdev->iftype) {
907 case NL80211_IFTYPE_ADHOC:
908 case NL80211_IFTYPE_STATION:
909 case NL80211_IFTYPE_AP_VLAN:
910 case NL80211_IFTYPE_WDS:
911 case NL80211_IFTYPE_MESH_POINT:
912 return -EOPNOTSUPP;
913 case NL80211_IFTYPE_MONITOR:
914 return brcmf_mon_del_vif(wiphy, wdev);
915 case NL80211_IFTYPE_AP:
916 return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
917 case NL80211_IFTYPE_P2P_CLIENT:
918 case NL80211_IFTYPE_P2P_GO:
919 case NL80211_IFTYPE_P2P_DEVICE:
920 return brcmf_p2p_del_vif(wiphy, wdev);
921 case NL80211_IFTYPE_UNSPECIFIED:
922 default:
923 return -EINVAL;
924 }
925 return -EOPNOTSUPP;
926}
927
928static s32
929brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
930 enum nl80211_iftype type,
931 struct vif_params *params)
932{
933 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
934 struct brcmf_if *ifp = netdev_priv(ndev);
935 struct brcmf_cfg80211_vif *vif = ifp->vif;
936 struct brcmf_pub *drvr = cfg->pub;
937 s32 infra = 0;
938 s32 ap = 0;
939 s32 err = 0;
940
941 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
942 type);
943
944
945
946
947
948
949
950
951
952 if ((type == NL80211_IFTYPE_STATION) &&
953 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
954 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
955 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
956 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
957
958
959
960
961
962
963
964
965
966
967
968
969 if (cfg->p2p.p2pdev_dynamically)
970 return -EOPNOTSUPP;
971 else
972 return 0;
973 }
974 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
975 if (err) {
976 bphy_err(drvr, "iface validation failed: err=%d\n", err);
977 return err;
978 }
979 switch (type) {
980 case NL80211_IFTYPE_MONITOR:
981 case NL80211_IFTYPE_WDS:
982 bphy_err(drvr, "type (%d) : currently we do not support this type\n",
983 type);
984 return -EOPNOTSUPP;
985 case NL80211_IFTYPE_ADHOC:
986 infra = 0;
987 break;
988 case NL80211_IFTYPE_STATION:
989 infra = 1;
990 break;
991 case NL80211_IFTYPE_AP:
992 case NL80211_IFTYPE_P2P_GO:
993 ap = 1;
994 break;
995 default:
996 err = -EINVAL;
997 goto done;
998 }
999
1000 if (ap) {
1001 if (type == NL80211_IFTYPE_P2P_GO) {
1002 brcmf_dbg(INFO, "IF Type = P2P GO\n");
1003 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
1004 }
1005 if (!err) {
1006 brcmf_dbg(INFO, "IF Type = AP\n");
1007 }
1008 } else {
1009 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
1010 if (err) {
1011 bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
1012 err = -EAGAIN;
1013 goto done;
1014 }
1015 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
1016 "Adhoc" : "Infra");
1017 }
1018 ndev->ieee80211_ptr->iftype = type;
1019
1020 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
1021
1022done:
1023 brcmf_dbg(TRACE, "Exit\n");
1024
1025 return err;
1026}
1027
1028static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1029 struct brcmf_scan_params_le *params_le,
1030 struct cfg80211_scan_request *request)
1031{
1032 u32 n_ssids;
1033 u32 n_channels;
1034 s32 i;
1035 s32 offset;
1036 u16 chanspec;
1037 char *ptr;
1038 struct brcmf_ssid_le ssid_le;
1039
1040 eth_broadcast_addr(params_le->bssid);
1041 params_le->bss_type = DOT11_BSSTYPE_ANY;
1042 params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
1043 params_le->channel_num = 0;
1044 params_le->nprobes = cpu_to_le32(-1);
1045 params_le->active_time = cpu_to_le32(-1);
1046 params_le->passive_time = cpu_to_le32(-1);
1047 params_le->home_time = cpu_to_le32(-1);
1048 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
1049
1050 n_ssids = request->n_ssids;
1051 n_channels = request->n_channels;
1052
1053
1054 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1055 n_channels);
1056 if (n_channels > 0) {
1057 for (i = 0; i < n_channels; i++) {
1058 chanspec = channel_to_chanspec(&cfg->d11inf,
1059 request->channels[i]);
1060 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1061 request->channels[i]->hw_value, chanspec);
1062 params_le->channel_list[i] = cpu_to_le16(chanspec);
1063 }
1064 } else {
1065 brcmf_dbg(SCAN, "Scanning all channels\n");
1066 }
1067
1068 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1069 if (n_ssids > 0) {
1070 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
1071 n_channels * sizeof(u16);
1072 offset = roundup(offset, sizeof(u32));
1073 ptr = (char *)params_le + offset;
1074 for (i = 0; i < n_ssids; i++) {
1075 memset(&ssid_le, 0, sizeof(ssid_le));
1076 ssid_le.SSID_len =
1077 cpu_to_le32(request->ssids[i].ssid_len);
1078 memcpy(ssid_le.SSID, request->ssids[i].ssid,
1079 request->ssids[i].ssid_len);
1080 if (!ssid_le.SSID_len)
1081 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1082 else
1083 brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n",
1084 i, ssid_le.SSID, ssid_le.SSID_len);
1085 memcpy(ptr, &ssid_le, sizeof(ssid_le));
1086 ptr += sizeof(ssid_le);
1087 }
1088 } else {
1089 brcmf_dbg(SCAN, "Performing passive scan\n");
1090 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
1091 }
1092
1093 params_le->channel_num =
1094 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1095 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1096}
1097
1098static s32
1099brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1100 struct cfg80211_scan_request *request)
1101{
1102 struct brcmf_pub *drvr = cfg->pub;
1103 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1104 offsetof(struct brcmf_escan_params_le, params_le);
1105 struct brcmf_escan_params_le *params;
1106 s32 err = 0;
1107
1108 brcmf_dbg(SCAN, "E-SCAN START\n");
1109
1110 if (request != NULL) {
1111
1112 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1113
1114
1115 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1116 }
1117
1118 params = kzalloc(params_size, GFP_KERNEL);
1119 if (!params) {
1120 err = -ENOMEM;
1121 goto exit;
1122 }
1123 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1124 brcmf_escan_prep(cfg, ¶ms->params_le, request);
1125 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1126 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1127 params->sync_id = cpu_to_le16(0x1234);
1128
1129 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1130 if (err) {
1131 if (err == -EBUSY)
1132 brcmf_dbg(INFO, "system busy : escan canceled\n");
1133 else
1134 bphy_err(drvr, "error (%d)\n", err);
1135 }
1136
1137 kfree(params);
1138exit:
1139 return err;
1140}
1141
1142static s32
1143brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1144{
1145 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1146 s32 err;
1147 struct brcmf_scan_results *results;
1148 struct escan_info *escan = &cfg->escan_info;
1149
1150 brcmf_dbg(SCAN, "Enter\n");
1151 escan->ifp = ifp;
1152 escan->wiphy = cfg->wiphy;
1153 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1154
1155 brcmf_scan_config_mpc(ifp, 0);
1156 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1157 results->version = 0;
1158 results->count = 0;
1159 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1160
1161 err = escan->run(cfg, ifp, request);
1162 if (err)
1163 brcmf_scan_config_mpc(ifp, 1);
1164 return err;
1165}
1166
1167static s32
1168brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1169{
1170 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1171 struct brcmf_pub *drvr = cfg->pub;
1172 struct brcmf_cfg80211_vif *vif;
1173 s32 err = 0;
1174
1175 brcmf_dbg(TRACE, "Enter\n");
1176 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1177 if (!check_vif_up(vif))
1178 return -EIO;
1179
1180 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1181 bphy_err(drvr, "Scanning already: status (%lu)\n",
1182 cfg->scan_status);
1183 return -EAGAIN;
1184 }
1185 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1186 bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
1187 cfg->scan_status);
1188 return -EAGAIN;
1189 }
1190 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1191 bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
1192 cfg->scan_status);
1193 return -EAGAIN;
1194 }
1195 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1196 bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
1197 return -EAGAIN;
1198 }
1199
1200
1201 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1202 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1203
1204 brcmf_dbg(SCAN, "START ESCAN\n");
1205
1206 cfg->scan_request = request;
1207 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1208
1209 cfg->escan_info.run = brcmf_run_escan;
1210 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1211 if (err)
1212 goto scan_out;
1213
1214 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1215 request->ie, request->ie_len);
1216 if (err)
1217 goto scan_out;
1218
1219 err = brcmf_do_escan(vif->ifp, request);
1220 if (err)
1221 goto scan_out;
1222
1223
1224 mod_timer(&cfg->escan_timeout,
1225 jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1226
1227 return 0;
1228
1229scan_out:
1230 bphy_err(drvr, "scan error (%d)\n", err);
1231 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1232 cfg->scan_request = NULL;
1233 return err;
1234}
1235
1236static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1237{
1238 struct brcmf_if *ifp = netdev_priv(ndev);
1239 struct brcmf_pub *drvr = ifp->drvr;
1240 s32 err = 0;
1241
1242 err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
1243 if (err)
1244 bphy_err(drvr, "Error (%d)\n", err);
1245
1246 return err;
1247}
1248
1249static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1250{
1251 struct brcmf_if *ifp = netdev_priv(ndev);
1252 struct brcmf_pub *drvr = ifp->drvr;
1253 s32 err = 0;
1254
1255 err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
1256 frag_threshold);
1257 if (err)
1258 bphy_err(drvr, "Error (%d)\n", err);
1259
1260 return err;
1261}
1262
1263static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1264{
1265 struct brcmf_if *ifp = netdev_priv(ndev);
1266 struct brcmf_pub *drvr = ifp->drvr;
1267 s32 err = 0;
1268 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1269
1270 err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
1271 if (err) {
1272 bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
1273 return err;
1274 }
1275 return err;
1276}
1277
1278static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1279{
1280 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1281 struct net_device *ndev = cfg_to_ndev(cfg);
1282 struct brcmf_if *ifp = netdev_priv(ndev);
1283 s32 err = 0;
1284
1285 brcmf_dbg(TRACE, "Enter\n");
1286 if (!check_vif_up(ifp->vif))
1287 return -EIO;
1288
1289 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1290 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1291 cfg->conf->rts_threshold = wiphy->rts_threshold;
1292 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1293 if (!err)
1294 goto done;
1295 }
1296 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1297 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1298 cfg->conf->frag_threshold = wiphy->frag_threshold;
1299 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1300 if (!err)
1301 goto done;
1302 }
1303 if (changed & WIPHY_PARAM_RETRY_LONG
1304 && (cfg->conf->retry_long != wiphy->retry_long)) {
1305 cfg->conf->retry_long = wiphy->retry_long;
1306 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1307 if (!err)
1308 goto done;
1309 }
1310 if (changed & WIPHY_PARAM_RETRY_SHORT
1311 && (cfg->conf->retry_short != wiphy->retry_short)) {
1312 cfg->conf->retry_short = wiphy->retry_short;
1313 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1314 if (!err)
1315 goto done;
1316 }
1317
1318done:
1319 brcmf_dbg(TRACE, "Exit\n");
1320 return err;
1321}
1322
1323static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1324{
1325 memset(prof, 0, sizeof(*prof));
1326}
1327
1328static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1329{
1330 u16 reason;
1331
1332 switch (e->event_code) {
1333 case BRCMF_E_DEAUTH:
1334 case BRCMF_E_DEAUTH_IND:
1335 case BRCMF_E_DISASSOC_IND:
1336 reason = e->reason;
1337 break;
1338 case BRCMF_E_LINK:
1339 default:
1340 reason = 0;
1341 break;
1342 }
1343 return reason;
1344}
1345
1346static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1347{
1348 struct brcmf_pub *drvr = ifp->drvr;
1349 struct brcmf_wsec_pmk_le pmk;
1350 int i, err;
1351
1352
1353 pmk.key_len = cpu_to_le16(pmk_len << 1);
1354 pmk.flags = cpu_to_le16(BRCMF_WSEC_PASSPHRASE);
1355 for (i = 0; i < pmk_len; i++)
1356 snprintf(&pmk.key[2 * i], 3, "%02x", pmk_data[i]);
1357
1358
1359 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1360 &pmk, sizeof(pmk));
1361 if (err < 0)
1362 bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
1363 pmk_len);
1364
1365 return err;
1366}
1367
1368static int brcmf_set_sae_password(struct brcmf_if *ifp, const u8 *pwd_data,
1369 u16 pwd_len)
1370{
1371 struct brcmf_pub *drvr = ifp->drvr;
1372 struct brcmf_wsec_sae_pwd_le sae_pwd;
1373 int err;
1374
1375 if (pwd_len > BRCMF_WSEC_MAX_SAE_PASSWORD_LEN) {
1376 bphy_err(drvr, "sae_password must be less than %d\n",
1377 BRCMF_WSEC_MAX_SAE_PASSWORD_LEN);
1378 return -EINVAL;
1379 }
1380
1381 sae_pwd.key_len = cpu_to_le16(pwd_len);
1382 memcpy(sae_pwd.key, pwd_data, pwd_len);
1383
1384 err = brcmf_fil_iovar_data_set(ifp, "sae_password", &sae_pwd,
1385 sizeof(sae_pwd));
1386 if (err < 0)
1387 bphy_err(drvr, "failed to set SAE password in firmware (len=%u)\n",
1388 pwd_len);
1389
1390 return err;
1391}
1392
1393static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
1394 bool locally_generated)
1395{
1396 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1397 struct brcmf_pub *drvr = cfg->pub;
1398 bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP;
1399 s32 err = 0;
1400
1401 brcmf_dbg(TRACE, "Enter\n");
1402
1403 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1404 if (bus_up) {
1405 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n");
1406 err = brcmf_fil_cmd_data_set(vif->ifp,
1407 BRCMF_C_DISASSOC, NULL, 0);
1408 if (err)
1409 bphy_err(drvr, "WLC_DISASSOC failed (%d)\n",
1410 err);
1411 }
1412
1413 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1414 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1415 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1416 locally_generated, GFP_KERNEL);
1417 }
1418 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1419 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1420 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1421 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1422 if (bus_up)
1423 brcmf_set_pmk(vif->ifp, NULL, 0);
1424 vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1425 }
1426 brcmf_dbg(TRACE, "Exit\n");
1427}
1428
1429static s32
1430brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1431 struct cfg80211_ibss_params *params)
1432{
1433 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1434 struct brcmf_if *ifp = netdev_priv(ndev);
1435 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1436 struct brcmf_pub *drvr = cfg->pub;
1437 struct brcmf_join_params join_params;
1438 size_t join_params_size = 0;
1439 s32 err = 0;
1440 s32 wsec = 0;
1441 s32 bcnprd;
1442 u16 chanspec;
1443 u32 ssid_len;
1444
1445 brcmf_dbg(TRACE, "Enter\n");
1446 if (!check_vif_up(ifp->vif))
1447 return -EIO;
1448
1449 if (params->ssid)
1450 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1451 else {
1452 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1453 return -EOPNOTSUPP;
1454 }
1455
1456 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1457
1458 if (params->bssid)
1459 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1460 else
1461 brcmf_dbg(CONN, "No BSSID specified\n");
1462
1463 if (params->chandef.chan)
1464 brcmf_dbg(CONN, "channel: %d\n",
1465 params->chandef.chan->center_freq);
1466 else
1467 brcmf_dbg(CONN, "no channel specified\n");
1468
1469 if (params->channel_fixed)
1470 brcmf_dbg(CONN, "fixed channel required\n");
1471 else
1472 brcmf_dbg(CONN, "no fixed channel required\n");
1473
1474 if (params->ie && params->ie_len)
1475 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1476 else
1477 brcmf_dbg(CONN, "no ie specified\n");
1478
1479 if (params->beacon_interval)
1480 brcmf_dbg(CONN, "beacon interval: %d\n",
1481 params->beacon_interval);
1482 else
1483 brcmf_dbg(CONN, "no beacon interval specified\n");
1484
1485 if (params->basic_rates)
1486 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1487 else
1488 brcmf_dbg(CONN, "no basic rates specified\n");
1489
1490 if (params->privacy)
1491 brcmf_dbg(CONN, "privacy required\n");
1492 else
1493 brcmf_dbg(CONN, "no privacy required\n");
1494
1495
1496 if (params->privacy)
1497 wsec |= WEP_ENABLED;
1498
1499 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1500 if (err) {
1501 bphy_err(drvr, "wsec failed (%d)\n", err);
1502 goto done;
1503 }
1504
1505
1506 if (params->beacon_interval)
1507 bcnprd = params->beacon_interval;
1508 else
1509 bcnprd = 100;
1510
1511 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1512 if (err) {
1513 bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
1514 goto done;
1515 }
1516
1517
1518 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1519
1520
1521 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1522 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1523 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1524 join_params_size = sizeof(join_params.ssid_le);
1525
1526
1527 if (params->bssid) {
1528 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1529 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1530 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1531 } else {
1532 eth_broadcast_addr(join_params.params_le.bssid);
1533 eth_zero_addr(profile->bssid);
1534 }
1535
1536
1537 if (params->chandef.chan) {
1538 u32 target_channel;
1539
1540 cfg->channel =
1541 ieee80211_frequency_to_channel(
1542 params->chandef.chan->center_freq);
1543 if (params->channel_fixed) {
1544
1545 chanspec = chandef_to_chanspec(&cfg->d11inf,
1546 ¶ms->chandef);
1547 join_params.params_le.chanspec_list[0] =
1548 cpu_to_le16(chanspec);
1549 join_params.params_le.chanspec_num = cpu_to_le32(1);
1550 join_params_size += sizeof(join_params.params_le);
1551 }
1552
1553
1554 target_channel = cfg->channel;
1555 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1556 target_channel);
1557 if (err) {
1558 bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
1559 goto done;
1560 }
1561 } else
1562 cfg->channel = 0;
1563
1564 cfg->ibss_starter = false;
1565
1566
1567 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1568 &join_params, join_params_size);
1569 if (err) {
1570 bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
1571 goto done;
1572 }
1573
1574done:
1575 if (err)
1576 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1577 brcmf_dbg(TRACE, "Exit\n");
1578 return err;
1579}
1580
1581static s32
1582brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1583{
1584 struct brcmf_if *ifp = netdev_priv(ndev);
1585
1586 brcmf_dbg(TRACE, "Enter\n");
1587 if (!check_vif_up(ifp->vif)) {
1588
1589
1590
1591
1592 return 0;
1593 }
1594
1595 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
1596 brcmf_net_setcarrier(ifp, false);
1597
1598 brcmf_dbg(TRACE, "Exit\n");
1599
1600 return 0;
1601}
1602
1603static s32 brcmf_set_wpa_version(struct net_device *ndev,
1604 struct cfg80211_connect_params *sme)
1605{
1606 struct brcmf_if *ifp = netdev_priv(ndev);
1607 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1608 struct brcmf_pub *drvr = ifp->drvr;
1609 struct brcmf_cfg80211_security *sec;
1610 s32 val = 0;
1611 s32 err = 0;
1612
1613 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1614 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1615 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1616 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1617 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3)
1618 val = WPA3_AUTH_SAE_PSK;
1619 else
1620 val = WPA_AUTH_DISABLED;
1621 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1622 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
1623 if (err) {
1624 bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
1625 return err;
1626 }
1627 sec = &profile->sec;
1628 sec->wpa_versions = sme->crypto.wpa_versions;
1629 return err;
1630}
1631
1632static s32 brcmf_set_auth_type(struct net_device *ndev,
1633 struct cfg80211_connect_params *sme)
1634{
1635 struct brcmf_if *ifp = netdev_priv(ndev);
1636 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1637 struct brcmf_pub *drvr = ifp->drvr;
1638 struct brcmf_cfg80211_security *sec;
1639 s32 val = 0;
1640 s32 err = 0;
1641
1642 switch (sme->auth_type) {
1643 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1644 val = 0;
1645 brcmf_dbg(CONN, "open system\n");
1646 break;
1647 case NL80211_AUTHTYPE_SHARED_KEY:
1648 val = 1;
1649 brcmf_dbg(CONN, "shared key\n");
1650 break;
1651 case NL80211_AUTHTYPE_SAE:
1652 val = 3;
1653 brcmf_dbg(CONN, "SAE authentication\n");
1654 break;
1655 default:
1656 val = 2;
1657 brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
1658 break;
1659 }
1660
1661 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1662 if (err) {
1663 bphy_err(drvr, "set auth failed (%d)\n", err);
1664 return err;
1665 }
1666 sec = &profile->sec;
1667 sec->auth_type = sme->auth_type;
1668 return err;
1669}
1670
1671static s32
1672brcmf_set_wsec_mode(struct net_device *ndev,
1673 struct cfg80211_connect_params *sme)
1674{
1675 struct brcmf_if *ifp = netdev_priv(ndev);
1676 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1677 struct brcmf_pub *drvr = ifp->drvr;
1678 struct brcmf_cfg80211_security *sec;
1679 s32 pval = 0;
1680 s32 gval = 0;
1681 s32 wsec;
1682 s32 err = 0;
1683
1684 if (sme->crypto.n_ciphers_pairwise) {
1685 switch (sme->crypto.ciphers_pairwise[0]) {
1686 case WLAN_CIPHER_SUITE_WEP40:
1687 case WLAN_CIPHER_SUITE_WEP104:
1688 pval = WEP_ENABLED;
1689 break;
1690 case WLAN_CIPHER_SUITE_TKIP:
1691 pval = TKIP_ENABLED;
1692 break;
1693 case WLAN_CIPHER_SUITE_CCMP:
1694 pval = AES_ENABLED;
1695 break;
1696 case WLAN_CIPHER_SUITE_AES_CMAC:
1697 pval = AES_ENABLED;
1698 break;
1699 default:
1700 bphy_err(drvr, "invalid cipher pairwise (%d)\n",
1701 sme->crypto.ciphers_pairwise[0]);
1702 return -EINVAL;
1703 }
1704 }
1705 if (sme->crypto.cipher_group) {
1706 switch (sme->crypto.cipher_group) {
1707 case WLAN_CIPHER_SUITE_WEP40:
1708 case WLAN_CIPHER_SUITE_WEP104:
1709 gval = WEP_ENABLED;
1710 break;
1711 case WLAN_CIPHER_SUITE_TKIP:
1712 gval = TKIP_ENABLED;
1713 break;
1714 case WLAN_CIPHER_SUITE_CCMP:
1715 gval = AES_ENABLED;
1716 break;
1717 case WLAN_CIPHER_SUITE_AES_CMAC:
1718 gval = AES_ENABLED;
1719 break;
1720 default:
1721 bphy_err(drvr, "invalid cipher group (%d)\n",
1722 sme->crypto.cipher_group);
1723 return -EINVAL;
1724 }
1725 }
1726
1727 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1728
1729
1730 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1731 sme->privacy)
1732 pval = AES_ENABLED;
1733
1734 wsec = pval | gval;
1735 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1736 if (err) {
1737 bphy_err(drvr, "error (%d)\n", err);
1738 return err;
1739 }
1740
1741 sec = &profile->sec;
1742 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1743 sec->cipher_group = sme->crypto.cipher_group;
1744
1745 return err;
1746}
1747
1748static s32
1749brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1750{
1751 struct brcmf_if *ifp = netdev_priv(ndev);
1752 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1753 struct brcmf_pub *drvr = ifp->drvr;
1754 s32 val;
1755 s32 err;
1756 const struct brcmf_tlv *rsn_ie;
1757 const u8 *ie;
1758 u32 ie_len;
1759 u32 offset;
1760 u16 rsn_cap;
1761 u32 mfp;
1762 u16 count;
1763
1764 profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1765 profile->is_ft = false;
1766
1767 if (!sme->crypto.n_akm_suites)
1768 return 0;
1769
1770 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1771 if (err) {
1772 bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
1773 return err;
1774 }
1775 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1776 switch (sme->crypto.akm_suites[0]) {
1777 case WLAN_AKM_SUITE_8021X:
1778 val = WPA_AUTH_UNSPECIFIED;
1779 if (sme->want_1x)
1780 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1781 break;
1782 case WLAN_AKM_SUITE_PSK:
1783 val = WPA_AUTH_PSK;
1784 break;
1785 default:
1786 bphy_err(drvr, "invalid cipher group (%d)\n",
1787 sme->crypto.cipher_group);
1788 return -EINVAL;
1789 }
1790 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1791 switch (sme->crypto.akm_suites[0]) {
1792 case WLAN_AKM_SUITE_8021X:
1793 val = WPA2_AUTH_UNSPECIFIED;
1794 if (sme->want_1x)
1795 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1796 break;
1797 case WLAN_AKM_SUITE_8021X_SHA256:
1798 val = WPA2_AUTH_1X_SHA256;
1799 if (sme->want_1x)
1800 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1801 break;
1802 case WLAN_AKM_SUITE_PSK_SHA256:
1803 val = WPA2_AUTH_PSK_SHA256;
1804 break;
1805 case WLAN_AKM_SUITE_PSK:
1806 val = WPA2_AUTH_PSK;
1807 break;
1808 case WLAN_AKM_SUITE_FT_8021X:
1809 val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
1810 profile->is_ft = true;
1811 if (sme->want_1x)
1812 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
1813 break;
1814 case WLAN_AKM_SUITE_FT_PSK:
1815 val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
1816 profile->is_ft = true;
1817 break;
1818 default:
1819 bphy_err(drvr, "invalid cipher group (%d)\n",
1820 sme->crypto.cipher_group);
1821 return -EINVAL;
1822 }
1823 } else if (val & WPA3_AUTH_SAE_PSK) {
1824 switch (sme->crypto.akm_suites[0]) {
1825 case WLAN_AKM_SUITE_SAE:
1826 val = WPA3_AUTH_SAE_PSK;
1827 if (sme->crypto.sae_pwd) {
1828 brcmf_dbg(INFO, "using SAE offload\n");
1829 profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
1830 }
1831 break;
1832 default:
1833 bphy_err(drvr, "invalid cipher group (%d)\n",
1834 sme->crypto.cipher_group);
1835 return -EINVAL;
1836 }
1837 }
1838
1839 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
1840 brcmf_dbg(INFO, "using 1X offload\n");
1841
1842 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1843 goto skip_mfp_config;
1844
1845
1846
1847 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1848 WLAN_EID_RSN);
1849 if (!rsn_ie)
1850 goto skip_mfp_config;
1851 ie = (const u8 *)rsn_ie;
1852 ie_len = rsn_ie->len + TLV_HDR_LEN;
1853
1854 offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1855 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1856 goto skip_mfp_config;
1857
1858 count = ie[offset] + (ie[offset + 1] << 8);
1859 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1860 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1861 goto skip_mfp_config;
1862
1863 count = ie[offset] + (ie[offset + 1] << 8);
1864 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1865 if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1866 goto skip_mfp_config;
1867
1868 mfp = BRCMF_MFP_NONE;
1869 rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1870 if (rsn_cap & RSN_CAP_MFPR_MASK)
1871 mfp = BRCMF_MFP_REQUIRED;
1872 else if (rsn_cap & RSN_CAP_MFPC_MASK)
1873 mfp = BRCMF_MFP_CAPABLE;
1874 brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1875
1876skip_mfp_config:
1877 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1878 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1879 if (err) {
1880 bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
1881 return err;
1882 }
1883
1884 return err;
1885}
1886
1887static s32
1888brcmf_set_sharedkey(struct net_device *ndev,
1889 struct cfg80211_connect_params *sme)
1890{
1891 struct brcmf_if *ifp = netdev_priv(ndev);
1892 struct brcmf_pub *drvr = ifp->drvr;
1893 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1894 struct brcmf_cfg80211_security *sec;
1895 struct brcmf_wsec_key key;
1896 s32 val;
1897 s32 err = 0;
1898
1899 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1900
1901 if (sme->key_len == 0)
1902 return 0;
1903
1904 sec = &profile->sec;
1905 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1906 sec->wpa_versions, sec->cipher_pairwise);
1907
1908 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2 |
1909 NL80211_WPA_VERSION_3))
1910 return 0;
1911
1912 if (!(sec->cipher_pairwise &
1913 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1914 return 0;
1915
1916 memset(&key, 0, sizeof(key));
1917 key.len = (u32) sme->key_len;
1918 key.index = (u32) sme->key_idx;
1919 if (key.len > sizeof(key.data)) {
1920 bphy_err(drvr, "Too long key length (%u)\n", key.len);
1921 return -EINVAL;
1922 }
1923 memcpy(key.data, sme->key, key.len);
1924 key.flags = BRCMF_PRIMARY_KEY;
1925 switch (sec->cipher_pairwise) {
1926 case WLAN_CIPHER_SUITE_WEP40:
1927 key.algo = CRYPTO_ALGO_WEP1;
1928 break;
1929 case WLAN_CIPHER_SUITE_WEP104:
1930 key.algo = CRYPTO_ALGO_WEP128;
1931 break;
1932 default:
1933 bphy_err(drvr, "Invalid algorithm (%d)\n",
1934 sme->crypto.ciphers_pairwise[0]);
1935 return -EINVAL;
1936 }
1937
1938 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1939 key.len, key.index, key.algo);
1940 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1941 err = send_key_to_dongle(ifp, &key);
1942 if (err)
1943 return err;
1944
1945 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1946 brcmf_dbg(CONN, "set auth_type to shared key\n");
1947 val = WL_AUTH_SHARED_KEY;
1948 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
1949 if (err)
1950 bphy_err(drvr, "set auth failed (%d)\n", err);
1951 }
1952 return err;
1953}
1954
1955static
1956enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1957 enum nl80211_auth_type type)
1958{
1959 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1960 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1961 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1962 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1963 }
1964 return type;
1965}
1966
1967static void brcmf_set_join_pref(struct brcmf_if *ifp,
1968 struct cfg80211_bss_selection *bss_select)
1969{
1970 struct brcmf_pub *drvr = ifp->drvr;
1971 struct brcmf_join_pref_params join_pref_params[2];
1972 enum nl80211_band band;
1973 int err, i = 0;
1974
1975 join_pref_params[i].len = 2;
1976 join_pref_params[i].rssi_gain = 0;
1977
1978 if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
1979 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
1980
1981 switch (bss_select->behaviour) {
1982 case __NL80211_BSS_SELECT_ATTR_INVALID:
1983 brcmf_c_set_joinpref_default(ifp);
1984 return;
1985 case NL80211_BSS_SELECT_ATTR_BAND_PREF:
1986 join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
1987 band = bss_select->param.band_pref;
1988 join_pref_params[i].band = nl80211_band_to_fwil(band);
1989 i++;
1990 break;
1991 case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
1992 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
1993 band = bss_select->param.adjust.band;
1994 join_pref_params[i].band = nl80211_band_to_fwil(band);
1995 join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
1996 i++;
1997 break;
1998 case NL80211_BSS_SELECT_ATTR_RSSI:
1999 default:
2000 break;
2001 }
2002 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
2003 join_pref_params[i].len = 2;
2004 join_pref_params[i].rssi_gain = 0;
2005 join_pref_params[i].band = 0;
2006 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
2007 sizeof(join_pref_params));
2008 if (err)
2009 bphy_err(drvr, "Set join_pref error (%d)\n", err);
2010}
2011
2012static s32
2013brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
2014 struct cfg80211_connect_params *sme)
2015{
2016 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2017 struct brcmf_if *ifp = netdev_priv(ndev);
2018 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2019 struct ieee80211_channel *chan = sme->channel;
2020 struct brcmf_pub *drvr = ifp->drvr;
2021 struct brcmf_join_params join_params;
2022 size_t join_params_size;
2023 const struct brcmf_tlv *rsn_ie;
2024 const struct brcmf_vs_tlv *wpa_ie;
2025 const void *ie;
2026 u32 ie_len;
2027 struct brcmf_ext_join_params_le *ext_join_params;
2028 u16 chanspec;
2029 s32 err = 0;
2030 u32 ssid_len;
2031
2032 brcmf_dbg(TRACE, "Enter\n");
2033 if (!check_vif_up(ifp->vif))
2034 return -EIO;
2035
2036 if (!sme->ssid) {
2037 bphy_err(drvr, "Invalid ssid\n");
2038 return -EOPNOTSUPP;
2039 }
2040
2041 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
2042
2043 ie = NULL;
2044 ie_len = 0;
2045
2046 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
2047 if (wpa_ie) {
2048 ie = wpa_ie;
2049 ie_len = wpa_ie->len + TLV_HDR_LEN;
2050 } else {
2051
2052 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
2053 sme->ie_len,
2054 WLAN_EID_RSN);
2055 if (rsn_ie) {
2056 ie = rsn_ie;
2057 ie_len = rsn_ie->len + TLV_HDR_LEN;
2058 }
2059 }
2060 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
2061 }
2062
2063 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
2064 sme->ie, sme->ie_len);
2065 if (err)
2066 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
2067 else
2068 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
2069
2070 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2071
2072 if (chan) {
2073 cfg->channel =
2074 ieee80211_frequency_to_channel(chan->center_freq);
2075 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
2076 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
2077 cfg->channel, chan->center_freq, chanspec);
2078 } else {
2079 cfg->channel = 0;
2080 chanspec = 0;
2081 }
2082
2083 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
2084
2085 err = brcmf_set_wpa_version(ndev, sme);
2086 if (err) {
2087 bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
2088 goto done;
2089 }
2090
2091 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
2092 err = brcmf_set_auth_type(ndev, sme);
2093 if (err) {
2094 bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
2095 goto done;
2096 }
2097
2098 err = brcmf_set_wsec_mode(ndev, sme);
2099 if (err) {
2100 bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
2101 goto done;
2102 }
2103
2104 err = brcmf_set_key_mgmt(ndev, sme);
2105 if (err) {
2106 bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
2107 goto done;
2108 }
2109
2110 err = brcmf_set_sharedkey(ndev, sme);
2111 if (err) {
2112 bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
2113 goto done;
2114 }
2115
2116 if (sme->crypto.psk &&
2117 profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
2118 if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
2119 err = -EINVAL;
2120 goto done;
2121 }
2122 brcmf_dbg(INFO, "using PSK offload\n");
2123 profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
2124 }
2125
2126 if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
2127
2128 err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
2129 if (err < 0) {
2130 bphy_err(drvr, "failed to enable fw supplicant\n");
2131 goto done;
2132 }
2133 }
2134
2135 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
2136 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2137 BRCMF_WSEC_MAX_PSK_LEN);
2138 else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
2139
2140 err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
2141 if (err) {
2142 bphy_err(drvr, "failed to clean up user-space RSNE\n");
2143 goto done;
2144 }
2145 err = brcmf_set_sae_password(ifp, sme->crypto.sae_pwd,
2146 sme->crypto.sae_pwd_len);
2147 if (!err && sme->crypto.psk)
2148 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2149 BRCMF_WSEC_MAX_PSK_LEN);
2150 }
2151 if (err)
2152 goto done;
2153
2154
2155
2156
2157 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2158 offsetof(struct brcmf_assoc_params_le, chanspec_list);
2159 if (cfg->channel)
2160 join_params_size += sizeof(u16);
2161 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
2162 if (ext_join_params == NULL) {
2163 err = -ENOMEM;
2164 goto done;
2165 }
2166 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2167 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2168 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2169 if (ssid_len < IEEE80211_MAX_SSID_LEN)
2170 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2171 ext_join_params->ssid_le.SSID, ssid_len);
2172
2173
2174 ext_join_params->scan_le.scan_type = -1;
2175 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2176
2177 if (sme->bssid)
2178 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2179 else
2180 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2181
2182 if (cfg->channel) {
2183 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2184
2185 ext_join_params->assoc_le.chanspec_list[0] =
2186 cpu_to_le16(chanspec);
2187
2188
2189
2190
2191 ext_join_params->scan_le.active_time =
2192 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2193 ext_join_params->scan_le.passive_time =
2194 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2195
2196
2197
2198
2199 ext_join_params->scan_le.nprobes =
2200 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2201 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2202 } else {
2203 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2204 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2205 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2206 }
2207
2208 brcmf_set_join_pref(ifp, &sme->bss_select);
2209
2210 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2211 join_params_size);
2212 kfree(ext_join_params);
2213 if (!err)
2214
2215 goto done;
2216
2217
2218 memset(&join_params, 0, sizeof(join_params));
2219 join_params_size = sizeof(join_params.ssid_le);
2220
2221 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2222 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2223
2224 if (sme->bssid)
2225 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2226 else
2227 eth_broadcast_addr(join_params.params_le.bssid);
2228
2229 if (cfg->channel) {
2230 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2231 join_params.params_le.chanspec_num = cpu_to_le32(1);
2232 join_params_size += sizeof(join_params.params_le);
2233 }
2234 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2235 &join_params, join_params_size);
2236 if (err)
2237 bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
2238
2239done:
2240 if (err)
2241 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2242 brcmf_dbg(TRACE, "Exit\n");
2243 return err;
2244}
2245
2246static s32
2247brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2248 u16 reason_code)
2249{
2250 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2251 struct brcmf_if *ifp = netdev_priv(ndev);
2252 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2253 struct brcmf_pub *drvr = cfg->pub;
2254 struct brcmf_scb_val_le scbval;
2255 s32 err = 0;
2256
2257 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2258 if (!check_vif_up(ifp->vif))
2259 return -EIO;
2260
2261 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2262 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2263 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2264
2265 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2266 scbval.val = cpu_to_le32(reason_code);
2267 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2268 &scbval, sizeof(scbval));
2269 if (err)
2270 bphy_err(drvr, "error (%d)\n", err);
2271
2272 brcmf_dbg(TRACE, "Exit\n");
2273 return err;
2274}
2275
2276static s32
2277brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2278 enum nl80211_tx_power_setting type, s32 mbm)
2279{
2280 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2281 struct net_device *ndev = cfg_to_ndev(cfg);
2282 struct brcmf_if *ifp = netdev_priv(ndev);
2283 struct brcmf_pub *drvr = cfg->pub;
2284 s32 err;
2285 s32 disable;
2286 u32 qdbm = 127;
2287
2288 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2289 if (!check_vif_up(ifp->vif))
2290 return -EIO;
2291
2292 switch (type) {
2293 case NL80211_TX_POWER_AUTOMATIC:
2294 break;
2295 case NL80211_TX_POWER_LIMITED:
2296 case NL80211_TX_POWER_FIXED:
2297 if (mbm < 0) {
2298 bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
2299 err = -EINVAL;
2300 goto done;
2301 }
2302 qdbm = MBM_TO_DBM(4 * mbm);
2303 if (qdbm > 127)
2304 qdbm = 127;
2305 qdbm |= WL_TXPWR_OVERRIDE;
2306 break;
2307 default:
2308 bphy_err(drvr, "Unsupported type %d\n", type);
2309 err = -EINVAL;
2310 goto done;
2311 }
2312
2313 disable = WL_RADIO_SW_DISABLE << 16;
2314 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2315 if (err)
2316 bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
2317
2318 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2319 if (err)
2320 bphy_err(drvr, "qtxpower error (%d)\n", err);
2321
2322done:
2323 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2324 return err;
2325}
2326
2327static s32
2328brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2329 s32 *dbm)
2330{
2331 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2332 struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2333 struct brcmf_pub *drvr = cfg->pub;
2334 s32 qdbm = 0;
2335 s32 err;
2336
2337 brcmf_dbg(TRACE, "Enter\n");
2338 if (!check_vif_up(vif))
2339 return -EIO;
2340
2341 err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2342 if (err) {
2343 bphy_err(drvr, "error (%d)\n", err);
2344 goto done;
2345 }
2346 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2347
2348done:
2349 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2350 return err;
2351}
2352
2353static s32
2354brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2355 u8 key_idx, bool unicast, bool multicast)
2356{
2357 struct brcmf_if *ifp = netdev_priv(ndev);
2358 struct brcmf_pub *drvr = ifp->drvr;
2359 u32 index;
2360 u32 wsec;
2361 s32 err = 0;
2362
2363 brcmf_dbg(TRACE, "Enter\n");
2364 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2365 if (!check_vif_up(ifp->vif))
2366 return -EIO;
2367
2368 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2369 if (err) {
2370 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2371 goto done;
2372 }
2373
2374 if (wsec & WEP_ENABLED) {
2375
2376 index = key_idx;
2377 err = brcmf_fil_cmd_int_set(ifp,
2378 BRCMF_C_SET_KEY_PRIMARY, index);
2379 if (err)
2380 bphy_err(drvr, "error (%d)\n", err);
2381 }
2382done:
2383 brcmf_dbg(TRACE, "Exit\n");
2384 return err;
2385}
2386
2387static s32
2388brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2389 u8 key_idx, bool pairwise, const u8 *mac_addr)
2390{
2391 struct brcmf_if *ifp = netdev_priv(ndev);
2392 struct brcmf_wsec_key *key;
2393 s32 err;
2394
2395 brcmf_dbg(TRACE, "Enter\n");
2396 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2397
2398 if (!check_vif_up(ifp->vif))
2399 return -EIO;
2400
2401 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2402
2403 return -EINVAL;
2404 }
2405
2406 key = &ifp->vif->profile.key[key_idx];
2407
2408 if (key->algo == CRYPTO_ALGO_OFF) {
2409 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2410 return -EINVAL;
2411 }
2412
2413 memset(key, 0, sizeof(*key));
2414 key->index = (u32)key_idx;
2415 key->flags = BRCMF_PRIMARY_KEY;
2416
2417
2418 err = send_key_to_dongle(ifp, key);
2419
2420 brcmf_dbg(TRACE, "Exit\n");
2421 return err;
2422}
2423
2424static s32
2425brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2426 u8 key_idx, bool pairwise, const u8 *mac_addr,
2427 struct key_params *params)
2428{
2429 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2430 struct brcmf_if *ifp = netdev_priv(ndev);
2431 struct brcmf_pub *drvr = cfg->pub;
2432 struct brcmf_wsec_key *key;
2433 s32 val;
2434 s32 wsec;
2435 s32 err;
2436 u8 keybuf[8];
2437 bool ext_key;
2438
2439 brcmf_dbg(TRACE, "Enter\n");
2440 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2441 if (!check_vif_up(ifp->vif))
2442 return -EIO;
2443
2444 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2445
2446 bphy_err(drvr, "invalid key index (%d)\n", key_idx);
2447 return -EINVAL;
2448 }
2449
2450 if (params->key_len == 0)
2451 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2452 mac_addr);
2453
2454 if (params->key_len > sizeof(key->data)) {
2455 bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
2456 return -EINVAL;
2457 }
2458
2459 ext_key = false;
2460 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2461 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2462 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2463 ext_key = true;
2464 }
2465
2466 key = &ifp->vif->profile.key[key_idx];
2467 memset(key, 0, sizeof(*key));
2468 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2469 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2470 key->len = params->key_len;
2471 key->index = key_idx;
2472 memcpy(key->data, params->key, key->len);
2473 if (!ext_key)
2474 key->flags = BRCMF_PRIMARY_KEY;
2475
2476 if (params->seq && params->seq_len == 6) {
2477
2478 u8 *ivptr;
2479
2480 ivptr = (u8 *)params->seq;
2481 key->rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2482 (ivptr[3] << 8) | ivptr[2];
2483 key->rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2484 key->iv_initialized = true;
2485 }
2486
2487 switch (params->cipher) {
2488 case WLAN_CIPHER_SUITE_WEP40:
2489 key->algo = CRYPTO_ALGO_WEP1;
2490 val = WEP_ENABLED;
2491 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2492 break;
2493 case WLAN_CIPHER_SUITE_WEP104:
2494 key->algo = CRYPTO_ALGO_WEP128;
2495 val = WEP_ENABLED;
2496 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2497 break;
2498 case WLAN_CIPHER_SUITE_TKIP:
2499 if (!brcmf_is_apmode(ifp->vif)) {
2500 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2501 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2502 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2503 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2504 }
2505 key->algo = CRYPTO_ALGO_TKIP;
2506 val = TKIP_ENABLED;
2507 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2508 break;
2509 case WLAN_CIPHER_SUITE_AES_CMAC:
2510 key->algo = CRYPTO_ALGO_AES_CCM;
2511 val = AES_ENABLED;
2512 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2513 break;
2514 case WLAN_CIPHER_SUITE_CCMP:
2515 key->algo = CRYPTO_ALGO_AES_CCM;
2516 val = AES_ENABLED;
2517 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2518 break;
2519 default:
2520 bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
2521 err = -EINVAL;
2522 goto done;
2523 }
2524
2525 err = send_key_to_dongle(ifp, key);
2526 if (ext_key || err)
2527 goto done;
2528
2529 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2530 if (err) {
2531 bphy_err(drvr, "get wsec error (%d)\n", err);
2532 goto done;
2533 }
2534 wsec |= val;
2535 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2536 if (err) {
2537 bphy_err(drvr, "set wsec error (%d)\n", err);
2538 goto done;
2539 }
2540
2541done:
2542 brcmf_dbg(TRACE, "Exit\n");
2543 return err;
2544}
2545
2546static s32
2547brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2548 bool pairwise, const u8 *mac_addr, void *cookie,
2549 void (*callback)(void *cookie,
2550 struct key_params *params))
2551{
2552 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2553 struct key_params params;
2554 struct brcmf_if *ifp = netdev_priv(ndev);
2555 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2556 struct brcmf_pub *drvr = cfg->pub;
2557 struct brcmf_cfg80211_security *sec;
2558 s32 wsec;
2559 s32 err = 0;
2560
2561 brcmf_dbg(TRACE, "Enter\n");
2562 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2563 if (!check_vif_up(ifp->vif))
2564 return -EIO;
2565
2566 memset(¶ms, 0, sizeof(params));
2567
2568 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2569 if (err) {
2570 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2571
2572 err = -EAGAIN;
2573 goto done;
2574 }
2575 if (wsec & WEP_ENABLED) {
2576 sec = &profile->sec;
2577 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2578 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2579 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2580 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2581 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2582 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2583 }
2584 } else if (wsec & TKIP_ENABLED) {
2585 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2586 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2587 } else if (wsec & AES_ENABLED) {
2588 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2589 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2590 } else {
2591 bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
2592 err = -EINVAL;
2593 goto done;
2594 }
2595 callback(cookie, ¶ms);
2596
2597done:
2598 brcmf_dbg(TRACE, "Exit\n");
2599 return err;
2600}
2601
2602static s32
2603brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2604 struct net_device *ndev, u8 key_idx)
2605{
2606 struct brcmf_if *ifp = netdev_priv(ndev);
2607
2608 brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2609
2610 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2611 return 0;
2612
2613 brcmf_dbg(INFO, "Not supported\n");
2614
2615 return -EOPNOTSUPP;
2616}
2617
2618static void
2619brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2620{
2621 struct brcmf_pub *drvr = ifp->drvr;
2622 s32 err;
2623 u8 key_idx;
2624 struct brcmf_wsec_key *key;
2625 s32 wsec;
2626
2627 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2628 key = &ifp->vif->profile.key[key_idx];
2629 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2630 (key->algo == CRYPTO_ALGO_WEP128))
2631 break;
2632 }
2633 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2634 return;
2635
2636 err = send_key_to_dongle(ifp, key);
2637 if (err) {
2638 bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
2639 return;
2640 }
2641 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2642 if (err) {
2643 bphy_err(drvr, "get wsec error (%d)\n", err);
2644 return;
2645 }
2646 wsec |= WEP_ENABLED;
2647 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2648 if (err)
2649 bphy_err(drvr, "set wsec error (%d)\n", err);
2650}
2651
2652static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2653{
2654 struct nl80211_sta_flag_update *sfu;
2655
2656 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2657 si->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS);
2658 sfu = &si->sta_flags;
2659 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2660 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2661 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2662 BIT(NL80211_STA_FLAG_AUTHORIZED);
2663 if (fw_sta_flags & BRCMF_STA_WME)
2664 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2665 if (fw_sta_flags & BRCMF_STA_AUTHE)
2666 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2667 if (fw_sta_flags & BRCMF_STA_ASSOC)
2668 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2669 if (fw_sta_flags & BRCMF_STA_AUTHO)
2670 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2671}
2672
2673static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2674{
2675 struct brcmf_pub *drvr = ifp->drvr;
2676 struct {
2677 __le32 len;
2678 struct brcmf_bss_info_le bss_le;
2679 } *buf;
2680 u16 capability;
2681 int err;
2682
2683 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2684 if (!buf)
2685 return;
2686
2687 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2688 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2689 WL_BSS_INFO_MAX);
2690 if (err) {
2691 bphy_err(drvr, "Failed to get bss info (%d)\n", err);
2692 goto out_kfree;
2693 }
2694 si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
2695 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2696 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2697 capability = le16_to_cpu(buf->bss_le.capability);
2698 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2699 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2700 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2701 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2702 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2703 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2704
2705out_kfree:
2706 kfree(buf);
2707}
2708
2709static s32
2710brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2711 struct station_info *sinfo)
2712{
2713 struct brcmf_pub *drvr = ifp->drvr;
2714 struct brcmf_scb_val_le scbval;
2715 struct brcmf_pktcnt_le pktcnt;
2716 s32 err;
2717 u32 rate;
2718 u32 rssi;
2719
2720
2721 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2722 if (err < 0) {
2723 bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
2724 return err;
2725 }
2726 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2727 sinfo->txrate.legacy = rate * 5;
2728
2729 memset(&scbval, 0, sizeof(scbval));
2730 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2731 sizeof(scbval));
2732 if (err) {
2733 bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
2734 return err;
2735 }
2736 rssi = le32_to_cpu(scbval.val);
2737 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2738 sinfo->signal = rssi;
2739
2740 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2741 sizeof(pktcnt));
2742 if (err) {
2743 bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2744 return err;
2745 }
2746 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
2747 BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
2748 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
2749 BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2750 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2751 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2752 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2753 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
2754
2755 return 0;
2756}
2757
2758static s32
2759brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2760 const u8 *mac, struct station_info *sinfo)
2761{
2762 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2763 struct brcmf_if *ifp = netdev_priv(ndev);
2764 struct brcmf_pub *drvr = cfg->pub;
2765 struct brcmf_scb_val_le scb_val;
2766 s32 err = 0;
2767 struct brcmf_sta_info_le sta_info_le;
2768 u32 sta_flags;
2769 u32 is_tdls_peer;
2770 s32 total_rssi_avg = 0;
2771 s32 total_rssi = 0;
2772 s32 count_rssi = 0;
2773 int rssi;
2774 u32 i;
2775
2776 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2777 if (!check_vif_up(ifp->vif))
2778 return -EIO;
2779
2780 if (brcmf_is_ibssmode(ifp->vif))
2781 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2782
2783 memset(&sta_info_le, 0, sizeof(sta_info_le));
2784 memcpy(&sta_info_le, mac, ETH_ALEN);
2785 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2786 &sta_info_le,
2787 sizeof(sta_info_le));
2788 is_tdls_peer = !err;
2789 if (err) {
2790 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2791 &sta_info_le,
2792 sizeof(sta_info_le));
2793 if (err < 0) {
2794 bphy_err(drvr, "GET STA INFO failed, %d\n", err);
2795 goto done;
2796 }
2797 }
2798 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2799 sinfo->filled = BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
2800 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2801 sta_flags = le32_to_cpu(sta_info_le.flags);
2802 brcmf_convert_sta_flags(sta_flags, sinfo);
2803 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2804 if (is_tdls_peer)
2805 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2806 else
2807 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2808 if (sta_flags & BRCMF_STA_ASSOC) {
2809 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME);
2810 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2811 brcmf_fill_bss_param(ifp, sinfo);
2812 }
2813 if (sta_flags & BRCMF_STA_SCBSTATS) {
2814 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
2815 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2816 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
2817 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2818 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2819 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
2820 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2821 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2822 if (sinfo->tx_packets) {
2823 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
2824 sinfo->txrate.legacy =
2825 le32_to_cpu(sta_info_le.tx_rate) / 100;
2826 }
2827 if (sinfo->rx_packets) {
2828 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
2829 sinfo->rxrate.legacy =
2830 le32_to_cpu(sta_info_le.rx_rate) / 100;
2831 }
2832 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2833 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
2834 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2835 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
2836 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2837 }
2838 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2839 if (sta_info_le.rssi[i] == 0 ||
2840 sta_info_le.rx_lastpkt_rssi[i] == 0)
2841 continue;
2842 sinfo->chains |= BIT(count_rssi);
2843 sinfo->chain_signal[count_rssi] =
2844 sta_info_le.rx_lastpkt_rssi[i];
2845 sinfo->chain_signal_avg[count_rssi] =
2846 sta_info_le.rssi[i];
2847 total_rssi += sta_info_le.rx_lastpkt_rssi[i];
2848 total_rssi_avg += sta_info_le.rssi[i];
2849 count_rssi++;
2850 }
2851 if (count_rssi) {
2852 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2853 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
2854 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
2855 sinfo->filled |=
2856 BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
2857 sinfo->signal = total_rssi / count_rssi;
2858 sinfo->signal_avg = total_rssi_avg / count_rssi;
2859 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2860 &ifp->vif->sme_state)) {
2861 memset(&scb_val, 0, sizeof(scb_val));
2862 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2863 &scb_val, sizeof(scb_val));
2864 if (err) {
2865 bphy_err(drvr, "Could not get rssi (%d)\n",
2866 err);
2867 goto done;
2868 } else {
2869 rssi = le32_to_cpu(scb_val.val);
2870 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
2871 sinfo->signal = rssi;
2872 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2873 }
2874 }
2875 }
2876done:
2877 brcmf_dbg(TRACE, "Exit\n");
2878 return err;
2879}
2880
2881static int
2882brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2883 int idx, u8 *mac, struct station_info *sinfo)
2884{
2885 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2886 struct brcmf_if *ifp = netdev_priv(ndev);
2887 struct brcmf_pub *drvr = cfg->pub;
2888 s32 err;
2889
2890 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2891
2892 if (idx == 0) {
2893 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2894 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2895 &cfg->assoclist,
2896 sizeof(cfg->assoclist));
2897 if (err) {
2898
2899 if (err == -EBADE)
2900 bphy_info_once(drvr, "BRCMF_C_GET_ASSOCLIST unsupported\n");
2901 else
2902 bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST failed, err=%d\n",
2903 err);
2904
2905 cfg->assoclist.count = 0;
2906 return -EOPNOTSUPP;
2907 }
2908 }
2909 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2910 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2911 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2912 }
2913 return -ENOENT;
2914}
2915
2916static s32
2917brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2918 bool enabled, s32 timeout)
2919{
2920 s32 pm;
2921 s32 err = 0;
2922 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2923 struct brcmf_if *ifp = netdev_priv(ndev);
2924 struct brcmf_pub *drvr = cfg->pub;
2925
2926 brcmf_dbg(TRACE, "Enter\n");
2927
2928
2929
2930
2931
2932
2933
2934
2935 cfg->pwr_save = enabled;
2936 if (!check_vif_up(ifp->vif)) {
2937
2938 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2939 goto done;
2940 }
2941
2942 pm = enabled ? PM_FAST : PM_OFF;
2943
2944 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2945 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2946 pm = PM_OFF;
2947 }
2948 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2949
2950 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2951 if (err) {
2952 if (err == -ENODEV)
2953 bphy_err(drvr, "net_device is not ready yet\n");
2954 else
2955 bphy_err(drvr, "error (%d)\n", err);
2956 }
2957
2958 err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret",
2959 min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS));
2960 if (err)
2961 bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err);
2962
2963done:
2964 brcmf_dbg(TRACE, "Exit\n");
2965 return err;
2966}
2967
2968static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2969 struct brcmf_bss_info_le *bi)
2970{
2971 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2972 struct brcmf_pub *drvr = cfg->pub;
2973 struct cfg80211_bss *bss;
2974 enum nl80211_band band;
2975 struct brcmu_chan ch;
2976 u16 channel;
2977 u32 freq;
2978 u16 notify_capability;
2979 u16 notify_interval;
2980 u8 *notify_ie;
2981 size_t notify_ielen;
2982 struct cfg80211_inform_bss bss_data = {};
2983
2984 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2985 bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
2986 return -EINVAL;
2987 }
2988
2989 if (!bi->ctl_ch) {
2990 ch.chspec = le16_to_cpu(bi->chanspec);
2991 cfg->d11inf.decchspec(&ch);
2992 bi->ctl_ch = ch.control_ch_num;
2993 }
2994 channel = bi->ctl_ch;
2995
2996 if (channel <= CH_MAX_2G_CHANNEL)
2997 band = NL80211_BAND_2GHZ;
2998 else
2999 band = NL80211_BAND_5GHZ;
3000
3001 freq = ieee80211_channel_to_frequency(channel, band);
3002 bss_data.chan = ieee80211_get_channel(wiphy, freq);
3003 bss_data.scan_width = NL80211_BSS_CHAN_WIDTH_20;
3004 bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
3005
3006 notify_capability = le16_to_cpu(bi->capability);
3007 notify_interval = le16_to_cpu(bi->beacon_period);
3008 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3009 notify_ielen = le32_to_cpu(bi->ie_length);
3010 bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3011
3012 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
3013 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
3014 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
3015 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
3016 brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal);
3017
3018 bss = cfg80211_inform_bss_data(wiphy, &bss_data,
3019 CFG80211_BSS_FTYPE_UNKNOWN,
3020 (const u8 *)bi->BSSID,
3021 0, notify_capability,
3022 notify_interval, notify_ie,
3023 notify_ielen, GFP_KERNEL);
3024
3025 if (!bss)
3026 return -ENOMEM;
3027
3028 cfg80211_put_bss(wiphy, bss);
3029
3030 return 0;
3031}
3032
3033static struct brcmf_bss_info_le *
3034next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
3035{
3036 if (bss == NULL)
3037 return list->bss_info_le;
3038 return (struct brcmf_bss_info_le *)((unsigned long)bss +
3039 le32_to_cpu(bss->length));
3040}
3041
3042static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
3043{
3044 struct brcmf_pub *drvr = cfg->pub;
3045 struct brcmf_scan_results *bss_list;
3046 struct brcmf_bss_info_le *bi = NULL;
3047 s32 err = 0;
3048 int i;
3049
3050 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
3051 if (bss_list->count != 0 &&
3052 bss_list->version != BRCMF_BSS_INFO_VERSION) {
3053 bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
3054 bss_list->version);
3055 return -EOPNOTSUPP;
3056 }
3057 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
3058 for (i = 0; i < bss_list->count; i++) {
3059 bi = next_bss_le(bss_list, bi);
3060 err = brcmf_inform_single_bss(cfg, bi);
3061 if (err)
3062 break;
3063 }
3064 return err;
3065}
3066
3067static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
3068 struct net_device *ndev, const u8 *bssid)
3069{
3070 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3071 struct brcmf_pub *drvr = cfg->pub;
3072 struct ieee80211_channel *notify_channel;
3073 struct brcmf_bss_info_le *bi = NULL;
3074 struct ieee80211_supported_band *band;
3075 struct cfg80211_bss *bss;
3076 struct brcmu_chan ch;
3077 u8 *buf = NULL;
3078 s32 err = 0;
3079 u32 freq;
3080 u16 notify_capability;
3081 u16 notify_interval;
3082 u8 *notify_ie;
3083 size_t notify_ielen;
3084 s32 notify_signal;
3085
3086 brcmf_dbg(TRACE, "Enter\n");
3087
3088 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3089 if (buf == NULL) {
3090 err = -ENOMEM;
3091 goto CleanUp;
3092 }
3093
3094 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3095
3096 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
3097 buf, WL_BSS_INFO_MAX);
3098 if (err) {
3099 bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
3100 goto CleanUp;
3101 }
3102
3103 bi = (struct brcmf_bss_info_le *)(buf + 4);
3104
3105 ch.chspec = le16_to_cpu(bi->chanspec);
3106 cfg->d11inf.decchspec(&ch);
3107
3108 if (ch.band == BRCMU_CHAN_BAND_2G)
3109 band = wiphy->bands[NL80211_BAND_2GHZ];
3110 else
3111 band = wiphy->bands[NL80211_BAND_5GHZ];
3112
3113 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
3114 cfg->channel = freq;
3115 notify_channel = ieee80211_get_channel(wiphy, freq);
3116
3117 notify_capability = le16_to_cpu(bi->capability);
3118 notify_interval = le16_to_cpu(bi->beacon_period);
3119 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3120 notify_ielen = le32_to_cpu(bi->ie_length);
3121 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3122
3123 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
3124 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
3125 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
3126 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
3127
3128 bss = cfg80211_inform_bss(wiphy, notify_channel,
3129 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
3130 notify_capability, notify_interval,
3131 notify_ie, notify_ielen, notify_signal,
3132 GFP_KERNEL);
3133
3134 if (!bss) {
3135 err = -ENOMEM;
3136 goto CleanUp;
3137 }
3138
3139 cfg80211_put_bss(wiphy, bss);
3140
3141CleanUp:
3142
3143 kfree(buf);
3144
3145 brcmf_dbg(TRACE, "Exit\n");
3146
3147 return err;
3148}
3149
3150static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
3151 struct brcmf_if *ifp)
3152{
3153 struct brcmf_pub *drvr = cfg->pub;
3154 struct brcmf_bss_info_le *bi;
3155 const struct brcmf_tlv *tim;
3156 size_t ie_len;
3157 u8 *ie;
3158 s32 err = 0;
3159
3160 brcmf_dbg(TRACE, "Enter\n");
3161 if (brcmf_is_ibssmode(ifp->vif))
3162 return err;
3163
3164 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
3165 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3166 cfg->extra_buf, WL_EXTRA_BUF_MAX);
3167 if (err) {
3168 bphy_err(drvr, "Could not get bss info %d\n", err);
3169 goto update_bss_info_out;
3170 }
3171
3172 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
3173 err = brcmf_inform_single_bss(cfg, bi);
3174 if (err)
3175 goto update_bss_info_out;
3176
3177 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
3178 ie_len = le32_to_cpu(bi->ie_length);
3179
3180 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
3181 if (!tim) {
3182
3183
3184
3185
3186
3187 u32 var;
3188 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
3189 if (err) {
3190 bphy_err(drvr, "wl dtim_assoc failed (%d)\n", err);
3191 goto update_bss_info_out;
3192 }
3193 }
3194
3195update_bss_info_out:
3196 brcmf_dbg(TRACE, "Exit");
3197 return err;
3198}
3199
3200void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3201{
3202 struct escan_info *escan = &cfg->escan_info;
3203
3204 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3205 if (cfg->int_escan_map || cfg->scan_request) {
3206 escan->escan_state = WL_ESCAN_STATE_IDLE;
3207 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3208 }
3209 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3210 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3211}
3212
3213static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3214{
3215 struct brcmf_cfg80211_info *cfg =
3216 container_of(work, struct brcmf_cfg80211_info,
3217 escan_timeout_work);
3218
3219 brcmf_inform_bss(cfg);
3220 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3221}
3222
3223static void brcmf_escan_timeout(struct timer_list *t)
3224{
3225 struct brcmf_cfg80211_info *cfg =
3226 from_timer(cfg, t, escan_timeout);
3227 struct brcmf_pub *drvr = cfg->pub;
3228
3229 if (cfg->int_escan_map || cfg->scan_request) {
3230 bphy_err(drvr, "timer expired\n");
3231 schedule_work(&cfg->escan_timeout_work);
3232 }
3233}
3234
3235static s32
3236brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3237 struct brcmf_bss_info_le *bss,
3238 struct brcmf_bss_info_le *bss_info_le)
3239{
3240 struct brcmu_chan ch_bss, ch_bss_info_le;
3241
3242 ch_bss.chspec = le16_to_cpu(bss->chanspec);
3243 cfg->d11inf.decchspec(&ch_bss);
3244 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3245 cfg->d11inf.decchspec(&ch_bss_info_le);
3246
3247 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3248 ch_bss.band == ch_bss_info_le.band &&
3249 bss_info_le->SSID_len == bss->SSID_len &&
3250 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3251 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3252 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3253 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3254 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3255
3256
3257
3258
3259 if (bss_info_rssi > bss_rssi)
3260 bss->RSSI = bss_info_le->RSSI;
3261 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3262 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3263
3264
3265
3266 bss->RSSI = bss_info_le->RSSI;
3267 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3268 }
3269 return 1;
3270 }
3271 return 0;
3272}
3273
3274static s32
3275brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3276 const struct brcmf_event_msg *e, void *data)
3277{
3278 struct brcmf_pub *drvr = ifp->drvr;
3279 struct brcmf_cfg80211_info *cfg = drvr->config;
3280 s32 status;
3281 struct brcmf_escan_result_le *escan_result_le;
3282 u32 escan_buflen;
3283 struct brcmf_bss_info_le *bss_info_le;
3284 struct brcmf_bss_info_le *bss = NULL;
3285 u32 bi_length;
3286 struct brcmf_scan_results *list;
3287 u32 i;
3288 bool aborted;
3289
3290 status = e->status;
3291
3292 if (status == BRCMF_E_STATUS_ABORT)
3293 goto exit;
3294
3295 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3296 bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
3297 ifp->bsscfgidx);
3298 return -EPERM;
3299 }
3300
3301 if (status == BRCMF_E_STATUS_PARTIAL) {
3302 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3303 if (e->datalen < sizeof(*escan_result_le)) {
3304 bphy_err(drvr, "invalid event data length\n");
3305 goto exit;
3306 }
3307 escan_result_le = (struct brcmf_escan_result_le *) data;
3308 if (!escan_result_le) {
3309 bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
3310 goto exit;
3311 }
3312 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3313 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3314 escan_buflen > e->datalen ||
3315 escan_buflen < sizeof(*escan_result_le)) {
3316 bphy_err(drvr, "Invalid escan buffer length: %d\n",
3317 escan_buflen);
3318 goto exit;
3319 }
3320 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3321 bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
3322 escan_result_le->bss_count);
3323 goto exit;
3324 }
3325 bss_info_le = &escan_result_le->bss_info_le;
3326
3327 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3328 goto exit;
3329
3330 if (!cfg->int_escan_map && !cfg->scan_request) {
3331 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3332 goto exit;
3333 }
3334
3335 bi_length = le32_to_cpu(bss_info_le->length);
3336 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3337 bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
3338 bi_length);
3339 goto exit;
3340 }
3341
3342 if (!(cfg_to_wiphy(cfg)->interface_modes &
3343 BIT(NL80211_IFTYPE_ADHOC))) {
3344 if (le16_to_cpu(bss_info_le->capability) &
3345 WLAN_CAPABILITY_IBSS) {
3346 bphy_err(drvr, "Ignoring IBSS result\n");
3347 goto exit;
3348 }
3349 }
3350
3351 list = (struct brcmf_scan_results *)
3352 cfg->escan_info.escan_buf;
3353 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3354 bphy_err(drvr, "Buffer is too small: ignoring\n");
3355 goto exit;
3356 }
3357
3358 for (i = 0; i < list->count; i++) {
3359 bss = bss ? (struct brcmf_bss_info_le *)
3360 ((unsigned char *)bss +
3361 le32_to_cpu(bss->length)) : list->bss_info_le;
3362 if (brcmf_compare_update_same_bss(cfg, bss,
3363 bss_info_le))
3364 goto exit;
3365 }
3366 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3367 bi_length);
3368 list->version = le32_to_cpu(bss_info_le->version);
3369 list->buflen += bi_length;
3370 list->count++;
3371 } else {
3372 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3373 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3374 goto exit;
3375 if (cfg->int_escan_map || cfg->scan_request) {
3376 brcmf_inform_bss(cfg);
3377 aborted = status != BRCMF_E_STATUS_SUCCESS;
3378 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3379 } else
3380 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3381 status);
3382 }
3383exit:
3384 return 0;
3385}
3386
3387static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3388{
3389 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3390 brcmf_cfg80211_escan_handler);
3391 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3392
3393 timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3394 INIT_WORK(&cfg->escan_timeout_work,
3395 brcmf_cfg80211_escan_timeout_worker);
3396}
3397
3398static struct cfg80211_scan_request *
3399brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3400 struct cfg80211_scan_request *req;
3401 size_t req_size;
3402
3403 req_size = sizeof(*req) +
3404 n_netinfo * sizeof(req->