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