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