2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
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>
26 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
31 #include "tracepoint.h"
32 #include "fwil_types.h"
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
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
59 #define WPS_OUI_TYPE 4
61 #define VS_IE_FIXED_HDR_LEN 6
62 #define WPA_IE_VERSION_LEN 2
63 #define WPA_IE_MIN_OUI_LEN 4
64 #define WPA_IE_SUITE_COUNT_LEN 2
66 #define WPA_CIPHER_NONE 0 /* None */
67 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
72 #define RSN_AKM_NONE 0 /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74 #define RSN_AKM_PSK 2 /* Pre-shared Key */
75 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
81 #define VNDR_IE_COUNT_OFFSET 4
82 #define VNDR_IE_PKTFLAG_OFFSET 8
83 #define VNDR_IE_VSIE_OFFSET 12
84 #define VNDR_IE_HDR_SIZE 12
85 #define VNDR_IE_PARSE_LIMIT 5
87 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
91 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
92 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
97 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
99 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
100 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
107 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
108 #define RATETAB_ENT(_rateid, _flags) \
110 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
111 .hw_value = (_rateid), \
115 static struct ieee80211_rate __wl_rates[] = {
116 RATETAB_ENT(BRCM_RATE_1M, 0),
117 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
118 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATETAB_ENT(BRCM_RATE_6M, 0),
121 RATETAB_ENT(BRCM_RATE_9M, 0),
122 RATETAB_ENT(BRCM_RATE_12M, 0),
123 RATETAB_ENT(BRCM_RATE_18M, 0),
124 RATETAB_ENT(BRCM_RATE_24M, 0),
125 RATETAB_ENT(BRCM_RATE_36M, 0),
126 RATETAB_ENT(BRCM_RATE_48M, 0),
127 RATETAB_ENT(BRCM_RATE_54M, 0),
130 #define wl_g_rates (__wl_rates + 0)
131 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
132 #define wl_a_rates (__wl_rates + 4)
133 #define wl_a_rates_size (wl_g_rates_size - 4)
135 #define CHAN2G(_channel, _freq) { \
136 .band = IEEE80211_BAND_2GHZ, \
137 .center_freq = (_freq), \
138 .hw_value = (_channel), \
139 .flags = IEEE80211_CHAN_DISABLED, \
140 .max_antenna_gain = 0, \
144 #define CHAN5G(_channel) { \
145 .band = IEEE80211_BAND_5GHZ, \
146 .center_freq = 5000 + (5 * (_channel)), \
147 .hw_value = (_channel), \
148 .flags = IEEE80211_CHAN_DISABLED, \
149 .max_antenna_gain = 0, \
153 static struct ieee80211_channel __wl_2ghz_channels[] = {
154 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
155 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
156 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
157 CHAN2G(13, 2472), CHAN2G(14, 2484)
160 static struct ieee80211_channel __wl_5ghz_channels[] = {
161 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
162 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
163 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
164 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
165 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
166 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
169 /* Band templates duplicated per wiphy. The channel info
170 * above is added to the band during setup.
172 static const struct ieee80211_supported_band __wl_band_2ghz = {
173 .band = IEEE80211_BAND_2GHZ,
174 .bitrates = wl_g_rates,
175 .n_bitrates = wl_g_rates_size,
178 static const struct ieee80211_supported_band __wl_band_5ghz = {
179 .band = IEEE80211_BAND_5GHZ,
180 .bitrates = wl_a_rates,
181 .n_bitrates = wl_a_rates_size,
184 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
185 * By default world regulatory domain defined in reg.c puts the flags
186 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
187 * With respect to these flags, wpa_supplicant doesn't * start p2p
188 * operations on 5GHz channels. All the changes in world regulatory
189 * domain are to be done here.
191 static const struct ieee80211_regdomain brcmf_regdom = {
195 /* IEEE 802.11b/g, channels 1..11 */
196 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
198 /* IEEE 802.11 channel 14 - Only JP enables
199 * this and for 802.11b only
201 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
202 /* IEEE 802.11a, channel 36..64 */
203 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
204 /* IEEE 802.11a, channel 100..165 */
205 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
208 static const u32 __wl_cipher_suites[] = {
209 WLAN_CIPHER_SUITE_WEP40,
210 WLAN_CIPHER_SUITE_WEP104,
211 WLAN_CIPHER_SUITE_TKIP,
212 WLAN_CIPHER_SUITE_CCMP,
213 WLAN_CIPHER_SUITE_AES_CMAC,
216 /* Vendor specific ie. id = 221, oui and type defines exact ie */
217 struct brcmf_vs_tlv {
224 struct parsed_vndr_ie_info {
226 u32 ie_len; /* total length including id & length field */
227 struct brcmf_vs_tlv vndrie;
230 struct parsed_vndr_ies {
232 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
235 static int brcmf_roamoff;
236 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
237 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
239 /* Quarter dBm units to mW
240 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
241 * Table is offset so the last entry is largest mW value that fits in
245 #define QDBM_OFFSET 153 /* Offset for first entry */
246 #define QDBM_TABLE_LEN 40 /* Table size */
248 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
249 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
251 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
253 /* Largest mW value that will round down to the last table entry,
254 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
255 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
256 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
258 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
260 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
261 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
262 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
263 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
264 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
265 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
266 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
269 static u16 brcmf_qdbm_to_mw(u8 qdbm)
272 int idx = qdbm - QDBM_OFFSET;
274 if (idx >= QDBM_TABLE_LEN)
275 /* clamp to max u16 mW value */
278 /* scale the qdBm index up to the range of the table 0-40
279 * where an offset of 40 qdBm equals a factor of 10 mW.
286 /* return the mW value scaled down to the correct factor of 10,
287 * adding in factor/2 to get proper rounding.
289 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
292 static u8 brcmf_mw_to_qdbm(u16 mw)
299 /* handle boundary case */
303 offset = QDBM_OFFSET;
305 /* move mw into the range of the table */
306 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
311 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
312 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
313 nqdBm_to_mW_map[qdbm]) / 2;
314 if (mw_uint < boundary)
323 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
324 struct cfg80211_chan_def *ch)
326 struct brcmu_chan ch_inf;
329 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
330 ch->chan->center_freq, ch->center_freq1, ch->width);
331 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
332 primary_offset = ch->center_freq1 - ch->chan->center_freq;
334 case NL80211_CHAN_WIDTH_20:
335 case NL80211_CHAN_WIDTH_20_NOHT:
336 ch_inf.bw = BRCMU_CHAN_BW_20;
337 WARN_ON(primary_offset != 0);
339 case NL80211_CHAN_WIDTH_40:
340 ch_inf.bw = BRCMU_CHAN_BW_40;
341 if (primary_offset < 0)
342 ch_inf.sb = BRCMU_CHAN_SB_U;
344 ch_inf.sb = BRCMU_CHAN_SB_L;
346 case NL80211_CHAN_WIDTH_80:
347 ch_inf.bw = BRCMU_CHAN_BW_80;
348 if (primary_offset < 0) {
349 if (primary_offset < -CH_10MHZ_APART)
350 ch_inf.sb = BRCMU_CHAN_SB_UU;
352 ch_inf.sb = BRCMU_CHAN_SB_UL;
354 if (primary_offset > CH_10MHZ_APART)
355 ch_inf.sb = BRCMU_CHAN_SB_LL;
357 ch_inf.sb = BRCMU_CHAN_SB_LU;
360 case NL80211_CHAN_WIDTH_80P80:
361 case NL80211_CHAN_WIDTH_160:
362 case NL80211_CHAN_WIDTH_5:
363 case NL80211_CHAN_WIDTH_10:
367 switch (ch->chan->band) {
368 case IEEE80211_BAND_2GHZ:
369 ch_inf.band = BRCMU_CHAN_BAND_2G;
371 case IEEE80211_BAND_5GHZ:
372 ch_inf.band = BRCMU_CHAN_BAND_5G;
374 case IEEE80211_BAND_60GHZ:
378 d11inf->encchspec(&ch_inf);
380 return ch_inf.chspec;
383 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
384 struct ieee80211_channel *ch)
386 struct brcmu_chan ch_inf;
388 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
389 ch_inf.bw = BRCMU_CHAN_BW_20;
390 d11inf->encchspec(&ch_inf);
392 return ch_inf.chspec;
395 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
396 * triples, returning a pointer to the substring whose first element
399 const struct brcmf_tlv *
400 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
402 const struct brcmf_tlv *elt = buf;
405 /* find tagged parameter */
406 while (totlen >= TLV_HDR_LEN) {
409 /* validate remaining totlen */
410 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
413 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
414 totlen -= (len + TLV_HDR_LEN);
420 /* Is any of the tlvs the expected entry? If
421 * not update the tlvs buffer pointer/length.
424 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
425 const u8 *oui, u32 oui_len, u8 type)
427 /* If the contents match the OUI and the type */
428 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
429 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
430 type == ie[TLV_BODY_OFF + oui_len]) {
436 /* point to the next ie */
437 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
438 /* calculate the length of the rest of the buffer */
439 *tlvs_len -= (int)(ie - *tlvs);
440 /* update the pointer to the start of the buffer */
446 static struct brcmf_vs_tlv *
447 brcmf_find_wpaie(const u8 *parse, u32 len)
449 const struct brcmf_tlv *ie;
451 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
452 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
453 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
454 return (struct brcmf_vs_tlv *)ie;
459 static struct brcmf_vs_tlv *
460 brcmf_find_wpsie(const u8 *parse, u32 len)
462 const struct brcmf_tlv *ie;
464 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
465 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
466 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
467 return (struct brcmf_vs_tlv *)ie;
473 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
474 struct brcmf_wsec_key_le *key_le)
476 key_le->index = cpu_to_le32(key->index);
477 key_le->len = cpu_to_le32(key->len);
478 key_le->algo = cpu_to_le32(key->algo);
479 key_le->flags = cpu_to_le32(key->flags);
480 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
481 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
482 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
483 memcpy(key_le->data, key->data, sizeof(key->data));
484 memcpy(key_le->ea, key->ea, sizeof(key->ea));
488 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
491 struct brcmf_wsec_key_le key_le;
493 convert_key_from_CPU(key, &key_le);
495 brcmf_netdev_wait_pend8021x(ifp);
497 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
501 brcmf_err("wsec_key error (%d)\n", err);
506 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
512 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
516 /* Try to set and enable ARP offload feature, this may fail, then it */
517 /* is simply not supported and err 0 will be returned */
518 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
520 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
524 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
526 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
530 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
538 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
540 struct brcmf_cfg80211_vif *vif;
541 struct brcmf_if *ifp;
543 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
546 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
547 (wdev->iftype == NL80211_IFTYPE_AP) ||
548 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
549 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
552 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
556 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
558 struct brcmf_mbss_ssid_le mbss_ssid_le;
562 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
563 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
567 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
568 mbss_ssid_le.SSID_len = cpu_to_le32(5);
569 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
571 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
572 sizeof(mbss_ssid_le));
574 brcmf_err("setting ssid failed %d\n", err);
580 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
582 * @wiphy: wiphy device of new interface.
583 * @name: name of the new interface.
585 * @params: contains mac address for AP device.
588 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
589 u32 *flags, struct vif_params *params)
591 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
592 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
593 struct brcmf_cfg80211_vif *vif;
596 if (brcmf_cfg80211_vif_event_armed(cfg))
597 return ERR_PTR(-EBUSY);
599 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
601 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
603 return (struct wireless_dev *)vif;
605 brcmf_cfg80211_arm_vif_event(cfg, vif);
607 err = brcmf_cfg80211_request_ap_if(ifp);
609 brcmf_cfg80211_arm_vif_event(cfg, NULL);
613 /* wait for firmware event */
614 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
615 msecs_to_jiffies(1500));
616 brcmf_cfg80211_arm_vif_event(cfg, NULL);
618 brcmf_err("timeout occurred\n");
623 /* interface created in firmware */
626 brcmf_err("no if pointer provided\n");
631 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
632 err = brcmf_net_attach(ifp, true);
634 brcmf_err("Registering netdevice failed\n");
638 return &ifp->vif->wdev;
645 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
647 enum nl80211_iftype iftype;
649 iftype = vif->wdev.iftype;
650 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
653 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
655 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
658 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
660 unsigned char name_assign_type,
661 enum nl80211_iftype type,
663 struct vif_params *params)
665 struct wireless_dev *wdev;
667 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
669 case NL80211_IFTYPE_ADHOC:
670 case NL80211_IFTYPE_STATION:
671 case NL80211_IFTYPE_AP_VLAN:
672 case NL80211_IFTYPE_WDS:
673 case NL80211_IFTYPE_MONITOR:
674 case NL80211_IFTYPE_MESH_POINT:
675 return ERR_PTR(-EOPNOTSUPP);
676 case NL80211_IFTYPE_AP:
677 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
679 brcmf_cfg80211_update_proto_addr_mode(wdev);
681 case NL80211_IFTYPE_P2P_CLIENT:
682 case NL80211_IFTYPE_P2P_GO:
683 case NL80211_IFTYPE_P2P_DEVICE:
684 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
686 brcmf_cfg80211_update_proto_addr_mode(wdev);
688 case NL80211_IFTYPE_UNSPECIFIED:
690 return ERR_PTR(-EINVAL);
694 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
696 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
697 brcmf_set_mpc(ifp, mpc);
700 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
704 if (check_vif_up(ifp->vif)) {
705 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
707 brcmf_err("fail to set mpc\n");
710 brcmf_dbg(INFO, "MPC : %d\n", mpc);
714 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
715 struct brcmf_if *ifp, bool aborted,
718 struct brcmf_scan_params_le params_le;
719 struct cfg80211_scan_request *scan_request;
722 brcmf_dbg(SCAN, "Enter\n");
724 /* clear scan request, because the FW abort can cause a second call */
725 /* to this functon and might cause a double cfg80211_scan_done */
726 scan_request = cfg->scan_request;
727 cfg->scan_request = NULL;
729 if (timer_pending(&cfg->escan_timeout))
730 del_timer_sync(&cfg->escan_timeout);
733 /* Do a scan abort to stop the driver's scan engine */
734 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
735 memset(¶ms_le, 0, sizeof(params_le));
736 eth_broadcast_addr(params_le.bssid);
737 params_le.bss_type = DOT11_BSSTYPE_ANY;
738 params_le.scan_type = 0;
739 params_le.channel_num = cpu_to_le32(1);
740 params_le.nprobes = cpu_to_le32(1);
741 params_le.active_time = cpu_to_le32(-1);
742 params_le.passive_time = cpu_to_le32(-1);
743 params_le.home_time = cpu_to_le32(-1);
744 /* Scan is aborted by setting channel_list[0] to -1 */
745 params_le.channel_list[0] = cpu_to_le16(-1);
746 /* E-Scan (or anyother type) can be aborted by SCAN */
747 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
748 ¶ms_le, sizeof(params_le));
750 brcmf_err("Scan abort failed\n");
753 brcmf_scan_config_mpc(ifp, 1);
756 * e-scan can be initiated by scheduled scan
757 * which takes precedence.
759 if (cfg->sched_escan) {
760 brcmf_dbg(SCAN, "scheduled scan completed\n");
761 cfg->sched_escan = false;
763 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
764 } else if (scan_request) {
765 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
766 aborted ? "Aborted" : "Done");
767 cfg80211_scan_done(scan_request, aborted);
769 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
770 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
776 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
778 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
779 struct net_device *ndev = wdev->netdev;
781 /* vif event pending in firmware */
782 if (brcmf_cfg80211_vif_event_armed(cfg))
786 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
787 cfg->escan_info.ifp == netdev_priv(ndev))
788 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
791 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
794 switch (wdev->iftype) {
795 case NL80211_IFTYPE_ADHOC:
796 case NL80211_IFTYPE_STATION:
797 case NL80211_IFTYPE_AP:
798 case NL80211_IFTYPE_AP_VLAN:
799 case NL80211_IFTYPE_WDS:
800 case NL80211_IFTYPE_MONITOR:
801 case NL80211_IFTYPE_MESH_POINT:
803 case NL80211_IFTYPE_P2P_CLIENT:
804 case NL80211_IFTYPE_P2P_GO:
805 case NL80211_IFTYPE_P2P_DEVICE:
806 return brcmf_p2p_del_vif(wiphy, wdev);
807 case NL80211_IFTYPE_UNSPECIFIED:
815 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
816 enum nl80211_iftype type, u32 *flags,
817 struct vif_params *params)
819 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
820 struct brcmf_if *ifp = netdev_priv(ndev);
821 struct brcmf_cfg80211_vif *vif = ifp->vif;
826 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
829 case NL80211_IFTYPE_MONITOR:
830 case NL80211_IFTYPE_WDS:
831 brcmf_err("type (%d) : currently we do not support this type\n",
834 case NL80211_IFTYPE_ADHOC:
837 case NL80211_IFTYPE_STATION:
838 /* Ignore change for p2p IF. Unclear why supplicant does this */
839 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
840 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
841 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
842 /* WAR: It is unexpected to get a change of VIF for P2P
843 * IF, but it happens. The request can not be handled
844 * but returning EPERM causes a crash. Returning 0
845 * without setting ieee80211_ptr->iftype causes trace
846 * (WARN_ON) but it works with wpa_supplicant
852 case NL80211_IFTYPE_AP:
853 case NL80211_IFTYPE_P2P_GO:
862 if (type == NL80211_IFTYPE_P2P_GO) {
863 brcmf_dbg(INFO, "IF Type = P2P GO\n");
864 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
867 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
868 brcmf_dbg(INFO, "IF Type = AP\n");
871 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
873 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
877 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
880 ndev->ieee80211_ptr->iftype = type;
882 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
885 brcmf_dbg(TRACE, "Exit\n");
890 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
891 struct brcmf_scan_params_le *params_le,
892 struct cfg80211_scan_request *request)
900 struct brcmf_ssid_le ssid_le;
902 eth_broadcast_addr(params_le->bssid);
903 params_le->bss_type = DOT11_BSSTYPE_ANY;
904 params_le->scan_type = 0;
905 params_le->channel_num = 0;
906 params_le->nprobes = cpu_to_le32(-1);
907 params_le->active_time = cpu_to_le32(-1);
908 params_le->passive_time = cpu_to_le32(-1);
909 params_le->home_time = cpu_to_le32(-1);
910 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
912 /* if request is null exit so it will be all channel broadcast scan */
916 n_ssids = request->n_ssids;
917 n_channels = request->n_channels;
918 /* Copy channel array if applicable */
919 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
921 if (n_channels > 0) {
922 for (i = 0; i < n_channels; i++) {
923 chanspec = channel_to_chanspec(&cfg->d11inf,
924 request->channels[i]);
925 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
926 request->channels[i]->hw_value, chanspec);
927 params_le->channel_list[i] = cpu_to_le16(chanspec);
930 brcmf_dbg(SCAN, "Scanning all channels\n");
932 /* Copy ssid array if applicable */
933 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
935 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
936 n_channels * sizeof(u16);
937 offset = roundup(offset, sizeof(u32));
938 ptr = (char *)params_le + offset;
939 for (i = 0; i < n_ssids; i++) {
940 memset(&ssid_le, 0, sizeof(ssid_le));
942 cpu_to_le32(request->ssids[i].ssid_len);
943 memcpy(ssid_le.SSID, request->ssids[i].ssid,
944 request->ssids[i].ssid_len);
945 if (!ssid_le.SSID_len)
946 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
948 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
949 i, ssid_le.SSID, ssid_le.SSID_len);
950 memcpy(ptr, &ssid_le, sizeof(ssid_le));
951 ptr += sizeof(ssid_le);
954 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
955 if ((request->ssids) && request->ssids->ssid_len) {
956 brcmf_dbg(SCAN, "SSID %s len=%d\n",
957 params_le->ssid_le.SSID,
958 request->ssids->ssid_len);
959 params_le->ssid_le.SSID_len =
960 cpu_to_le32(request->ssids->ssid_len);
961 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
962 request->ssids->ssid_len);
965 /* Adding mask to channel numbers */
966 params_le->channel_num =
967 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
968 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
972 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
973 struct cfg80211_scan_request *request, u16 action)
975 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
976 offsetof(struct brcmf_escan_params_le, params_le);
977 struct brcmf_escan_params_le *params;
980 brcmf_dbg(SCAN, "E-SCAN START\n");
982 if (request != NULL) {
983 /* Allocate space for populating ssids in struct */
984 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
986 /* Allocate space for populating ssids in struct */
987 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
990 params = kzalloc(params_size, GFP_KERNEL);
995 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
996 brcmf_escan_prep(cfg, ¶ms->params_le, request);
997 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
998 params->action = cpu_to_le16(action);
999 params->sync_id = cpu_to_le16(0x1234);
1001 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1004 brcmf_dbg(INFO, "system busy : escan canceled\n");
1006 brcmf_err("error (%d)\n", err);
1015 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1016 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1020 struct brcmf_scan_results *results;
1021 struct escan_info *escan = &cfg->escan_info;
1023 brcmf_dbg(SCAN, "Enter\n");
1025 escan->wiphy = wiphy;
1026 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1027 passive_scan = cfg->active_scan ? 0 : 1;
1028 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1031 brcmf_err("error (%d)\n", err);
1034 brcmf_scan_config_mpc(ifp, 0);
1035 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1036 results->version = 0;
1038 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1040 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
1042 brcmf_scan_config_mpc(ifp, 1);
1047 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1048 struct cfg80211_scan_request *request,
1049 struct cfg80211_ssid *this_ssid)
1051 struct brcmf_if *ifp = vif->ifp;
1052 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1053 struct cfg80211_ssid *ssids;
1054 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
1061 brcmf_dbg(SCAN, "START ESCAN\n");
1063 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1064 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1067 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1068 brcmf_err("Scanning being aborted: status (%lu)\n",
1072 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1073 brcmf_err("Scanning suppressed: status (%lu)\n",
1077 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1078 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1082 /* If scan req comes for p2p0, send it over primary I/F */
1083 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1084 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1089 ssids = request->ssids;
1093 /* we don't do escan in ibss */
1097 cfg->scan_request = request;
1098 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1100 cfg->escan_info.run = brcmf_run_escan;
1101 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1105 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1109 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1110 ssids->ssid, ssids->ssid_len);
1111 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1112 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1113 sr->ssid_le.SSID_len = cpu_to_le32(0);
1116 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1117 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1120 brcmf_dbg(SCAN, "Broadcast scan\n");
1122 passive_scan = cfg->active_scan ? 0 : 1;
1123 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1126 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1129 brcmf_scan_config_mpc(ifp, 0);
1130 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1131 &sr->ssid_le, sizeof(sr->ssid_le));
1134 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1137 brcmf_err("WLC_SCAN error (%d)\n", err);
1139 brcmf_scan_config_mpc(ifp, 1);
1144 /* Arm scan timeout timer */
1145 mod_timer(&cfg->escan_timeout, jiffies +
1146 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1151 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1152 cfg->scan_request = NULL;
1157 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1159 struct brcmf_cfg80211_vif *vif;
1162 brcmf_dbg(TRACE, "Enter\n");
1163 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1164 if (!check_vif_up(vif))
1167 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1170 brcmf_err("scan error (%d)\n", err);
1172 brcmf_dbg(TRACE, "Exit\n");
1176 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1180 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1183 brcmf_err("Error (%d)\n", err);
1188 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1192 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1195 brcmf_err("Error (%d)\n", err);
1200 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1203 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1205 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1207 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1213 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1215 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1216 struct net_device *ndev = cfg_to_ndev(cfg);
1217 struct brcmf_if *ifp = netdev_priv(ndev);
1220 brcmf_dbg(TRACE, "Enter\n");
1221 if (!check_vif_up(ifp->vif))
1224 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1225 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1226 cfg->conf->rts_threshold = wiphy->rts_threshold;
1227 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1231 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1232 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1233 cfg->conf->frag_threshold = wiphy->frag_threshold;
1234 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1238 if (changed & WIPHY_PARAM_RETRY_LONG
1239 && (cfg->conf->retry_long != wiphy->retry_long)) {
1240 cfg->conf->retry_long = wiphy->retry_long;
1241 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1245 if (changed & WIPHY_PARAM_RETRY_SHORT
1246 && (cfg->conf->retry_short != wiphy->retry_short)) {
1247 cfg->conf->retry_short = wiphy->retry_short;
1248 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1254 brcmf_dbg(TRACE, "Exit\n");
1258 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1260 memset(prof, 0, sizeof(*prof));
1263 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1267 switch (e->event_code) {
1268 case BRCMF_E_DEAUTH:
1269 case BRCMF_E_DEAUTH_IND:
1270 case BRCMF_E_DISASSOC_IND:
1281 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1283 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1286 brcmf_dbg(TRACE, "Enter\n");
1288 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1289 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1290 err = brcmf_fil_cmd_data_set(vif->ifp,
1291 BRCMF_C_DISASSOC, NULL, 0);
1293 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1295 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1296 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1300 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1301 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1302 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1303 brcmf_dbg(TRACE, "Exit\n");
1307 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1308 struct cfg80211_ibss_params *params)
1310 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1311 struct brcmf_if *ifp = netdev_priv(ndev);
1312 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1313 struct brcmf_join_params join_params;
1314 size_t join_params_size = 0;
1320 brcmf_dbg(TRACE, "Enter\n");
1321 if (!check_vif_up(ifp->vif))
1325 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1327 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1331 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1334 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1336 brcmf_dbg(CONN, "No BSSID specified\n");
1338 if (params->chandef.chan)
1339 brcmf_dbg(CONN, "channel: %d\n",
1340 params->chandef.chan->center_freq);
1342 brcmf_dbg(CONN, "no channel specified\n");
1344 if (params->channel_fixed)
1345 brcmf_dbg(CONN, "fixed channel required\n");
1347 brcmf_dbg(CONN, "no fixed channel required\n");
1349 if (params->ie && params->ie_len)
1350 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1352 brcmf_dbg(CONN, "no ie specified\n");
1354 if (params->beacon_interval)
1355 brcmf_dbg(CONN, "beacon interval: %d\n",
1356 params->beacon_interval);
1358 brcmf_dbg(CONN, "no beacon interval specified\n");
1360 if (params->basic_rates)
1361 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1363 brcmf_dbg(CONN, "no basic rates specified\n");
1365 if (params->privacy)
1366 brcmf_dbg(CONN, "privacy required\n");
1368 brcmf_dbg(CONN, "no privacy required\n");
1370 /* Configure Privacy for starter */
1371 if (params->privacy)
1372 wsec |= WEP_ENABLED;
1374 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1376 brcmf_err("wsec failed (%d)\n", err);
1380 /* Configure Beacon Interval for starter */
1381 if (params->beacon_interval)
1382 bcnprd = params->beacon_interval;
1386 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1388 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1392 /* Configure required join parameter */
1393 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1396 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1397 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1398 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1399 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1400 join_params_size = sizeof(join_params.ssid_le);
1403 if (params->bssid) {
1404 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1405 join_params_size = sizeof(join_params.ssid_le) +
1406 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1407 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1409 eth_broadcast_addr(join_params.params_le.bssid);
1410 eth_zero_addr(profile->bssid);
1414 if (params->chandef.chan) {
1418 ieee80211_frequency_to_channel(
1419 params->chandef.chan->center_freq);
1420 if (params->channel_fixed) {
1421 /* adding chanspec */
1422 chanspec = chandef_to_chanspec(&cfg->d11inf,
1424 join_params.params_le.chanspec_list[0] =
1425 cpu_to_le16(chanspec);
1426 join_params.params_le.chanspec_num = cpu_to_le32(1);
1427 join_params_size += sizeof(join_params.params_le);
1430 /* set channel for starter */
1431 target_channel = cfg->channel;
1432 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1435 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1441 cfg->ibss_starter = false;
1444 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1445 &join_params, join_params_size);
1447 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1453 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1454 brcmf_dbg(TRACE, "Exit\n");
1459 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1461 struct brcmf_if *ifp = netdev_priv(ndev);
1463 brcmf_dbg(TRACE, "Enter\n");
1464 if (!check_vif_up(ifp->vif))
1467 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1469 brcmf_dbg(TRACE, "Exit\n");
1474 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1475 struct cfg80211_connect_params *sme)
1477 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1478 struct brcmf_cfg80211_security *sec;
1482 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1483 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1484 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1485 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1487 val = WPA_AUTH_DISABLED;
1488 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1489 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1491 brcmf_err("set wpa_auth failed (%d)\n", err);
1494 sec = &profile->sec;
1495 sec->wpa_versions = sme->crypto.wpa_versions;
1499 static s32 brcmf_set_auth_type(struct net_device *ndev,
1500 struct cfg80211_connect_params *sme)
1502 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1503 struct brcmf_cfg80211_security *sec;
1507 switch (sme->auth_type) {
1508 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1510 brcmf_dbg(CONN, "open system\n");
1512 case NL80211_AUTHTYPE_SHARED_KEY:
1514 brcmf_dbg(CONN, "shared key\n");
1516 case NL80211_AUTHTYPE_AUTOMATIC:
1518 brcmf_dbg(CONN, "automatic\n");
1520 case NL80211_AUTHTYPE_NETWORK_EAP:
1521 brcmf_dbg(CONN, "network eap\n");
1524 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1528 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1530 brcmf_err("set auth failed (%d)\n", err);
1533 sec = &profile->sec;
1534 sec->auth_type = sme->auth_type;
1539 brcmf_set_wsec_mode(struct net_device *ndev,
1540 struct cfg80211_connect_params *sme, bool mfp)
1542 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1543 struct brcmf_cfg80211_security *sec;
1549 if (sme->crypto.n_ciphers_pairwise) {
1550 switch (sme->crypto.ciphers_pairwise[0]) {
1551 case WLAN_CIPHER_SUITE_WEP40:
1552 case WLAN_CIPHER_SUITE_WEP104:
1555 case WLAN_CIPHER_SUITE_TKIP:
1556 pval = TKIP_ENABLED;
1558 case WLAN_CIPHER_SUITE_CCMP:
1561 case WLAN_CIPHER_SUITE_AES_CMAC:
1565 brcmf_err("invalid cipher pairwise (%d)\n",
1566 sme->crypto.ciphers_pairwise[0]);
1570 if (sme->crypto.cipher_group) {
1571 switch (sme->crypto.cipher_group) {
1572 case WLAN_CIPHER_SUITE_WEP40:
1573 case WLAN_CIPHER_SUITE_WEP104:
1576 case WLAN_CIPHER_SUITE_TKIP:
1577 gval = TKIP_ENABLED;
1579 case WLAN_CIPHER_SUITE_CCMP:
1582 case WLAN_CIPHER_SUITE_AES_CMAC:
1586 brcmf_err("invalid cipher group (%d)\n",
1587 sme->crypto.cipher_group);
1592 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1593 /* In case of privacy, but no security and WPS then simulate */
1594 /* setting AES. WPS-2.0 allows no security */
1595 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1600 wsec = pval | gval | MFP_CAPABLE;
1603 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1605 brcmf_err("error (%d)\n", err);
1609 sec = &profile->sec;
1610 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1611 sec->cipher_group = sme->crypto.cipher_group;
1617 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1619 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1620 struct brcmf_cfg80211_security *sec;
1624 if (sme->crypto.n_akm_suites) {
1625 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1628 brcmf_err("could not get wpa_auth (%d)\n", err);
1631 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1632 switch (sme->crypto.akm_suites[0]) {
1633 case WLAN_AKM_SUITE_8021X:
1634 val = WPA_AUTH_UNSPECIFIED;
1636 case WLAN_AKM_SUITE_PSK:
1640 brcmf_err("invalid cipher group (%d)\n",
1641 sme->crypto.cipher_group);
1644 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1645 switch (sme->crypto.akm_suites[0]) {
1646 case WLAN_AKM_SUITE_8021X:
1647 val = WPA2_AUTH_UNSPECIFIED;
1649 case WLAN_AKM_SUITE_PSK:
1650 val = WPA2_AUTH_PSK;
1653 brcmf_err("invalid cipher group (%d)\n",
1654 sme->crypto.cipher_group);
1659 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1660 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1663 brcmf_err("could not set wpa_auth (%d)\n", err);
1667 sec = &profile->sec;
1668 sec->wpa_auth = sme->crypto.akm_suites[0];
1674 brcmf_set_sharedkey(struct net_device *ndev,
1675 struct cfg80211_connect_params *sme)
1677 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1678 struct brcmf_cfg80211_security *sec;
1679 struct brcmf_wsec_key key;
1683 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1685 if (sme->key_len == 0)
1688 sec = &profile->sec;
1689 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1690 sec->wpa_versions, sec->cipher_pairwise);
1692 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1695 if (!(sec->cipher_pairwise &
1696 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1699 memset(&key, 0, sizeof(key));
1700 key.len = (u32) sme->key_len;
1701 key.index = (u32) sme->key_idx;
1702 if (key.len > sizeof(key.data)) {
1703 brcmf_err("Too long key length (%u)\n", key.len);
1706 memcpy(key.data, sme->key, key.len);
1707 key.flags = BRCMF_PRIMARY_KEY;
1708 switch (sec->cipher_pairwise) {
1709 case WLAN_CIPHER_SUITE_WEP40:
1710 key.algo = CRYPTO_ALGO_WEP1;
1712 case WLAN_CIPHER_SUITE_WEP104:
1713 key.algo = CRYPTO_ALGO_WEP128;
1716 brcmf_err("Invalid algorithm (%d)\n",
1717 sme->crypto.ciphers_pairwise[0]);
1720 /* Set the new key/index */
1721 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1722 key.len, key.index, key.algo);
1723 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1724 err = send_key_to_dongle(netdev_priv(ndev), &key);
1728 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1729 brcmf_dbg(CONN, "set auth_type to shared key\n");
1730 val = WL_AUTH_SHARED_KEY; /* shared key */
1731 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1733 brcmf_err("set auth failed (%d)\n", err);
1739 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1740 enum nl80211_auth_type type)
1742 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1743 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1744 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1745 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1751 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1752 struct cfg80211_connect_params *sme)
1754 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1755 struct brcmf_if *ifp = netdev_priv(ndev);
1756 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1757 struct ieee80211_channel *chan = sme->channel;
1758 struct brcmf_join_params join_params;
1759 size_t join_params_size;
1760 const struct brcmf_tlv *rsn_ie;
1761 const struct brcmf_vs_tlv *wpa_ie;
1764 struct brcmf_ext_join_params_le *ext_join_params;
1768 brcmf_dbg(TRACE, "Enter\n");
1769 if (!check_vif_up(ifp->vif))
1773 brcmf_err("Invalid ssid\n");
1777 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1778 /* A normal (non P2P) connection request setup. */
1781 /* find the WPA_IE */
1782 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1785 ie_len = wpa_ie->len + TLV_HDR_LEN;
1787 /* find the RSN_IE */
1788 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1793 ie_len = rsn_ie->len + TLV_HDR_LEN;
1796 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1799 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1800 sme->ie, sme->ie_len);
1802 brcmf_err("Set Assoc REQ IE Failed\n");
1804 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1806 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1810 ieee80211_frequency_to_channel(chan->center_freq);
1811 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1812 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1813 cfg->channel, chan->center_freq, chanspec);
1819 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1821 err = brcmf_set_wpa_version(ndev, sme);
1823 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1827 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1828 err = brcmf_set_auth_type(ndev, sme);
1830 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1834 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1836 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1840 err = brcmf_set_key_mgmt(ndev, sme);
1842 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1846 err = brcmf_set_sharedkey(ndev, sme);
1848 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1852 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1853 (u32)sme->ssid_len);
1854 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1855 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1856 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1857 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1858 profile->ssid.SSID_len);
1861 /* Join with specific BSSID and cached SSID
1862 * If SSID is zero join based on BSSID only
1864 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1865 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1867 join_params_size += sizeof(u16);
1868 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1869 if (ext_join_params == NULL) {
1873 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1874 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1875 profile->ssid.SSID_len);
1877 /* Set up join scan parameters */
1878 ext_join_params->scan_le.scan_type = -1;
1879 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1882 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1884 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1887 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1889 ext_join_params->assoc_le.chanspec_list[0] =
1890 cpu_to_le16(chanspec);
1891 /* Increase dwell time to receive probe response or detect
1892 * beacon from target AP at a noisy air only during connect
1895 ext_join_params->scan_le.active_time =
1896 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1897 ext_join_params->scan_le.passive_time =
1898 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1899 /* To sync with presence period of VSDB GO send probe request
1900 * more frequently. Probe request will be stopped when it gets
1901 * probe response from target AP/GO.
1903 ext_join_params->scan_le.nprobes =
1904 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1905 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1907 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1908 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1909 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1912 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1914 kfree(ext_join_params);
1916 /* This is it. join command worked, we are done */
1919 /* join command failed, fallback to set ssid */
1920 memset(&join_params, 0, sizeof(join_params));
1921 join_params_size = sizeof(join_params.ssid_le);
1923 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1924 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1927 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1929 eth_broadcast_addr(join_params.params_le.bssid);
1932 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1933 join_params.params_le.chanspec_num = cpu_to_le32(1);
1934 join_params_size += sizeof(join_params.params_le);
1936 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1937 &join_params, join_params_size);
1939 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1943 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1944 brcmf_dbg(TRACE, "Exit\n");
1949 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1952 struct brcmf_if *ifp = netdev_priv(ndev);
1953 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1954 struct brcmf_scb_val_le scbval;
1957 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1958 if (!check_vif_up(ifp->vif))
1961 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1962 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1963 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1965 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1966 scbval.val = cpu_to_le32(reason_code);
1967 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1968 &scbval, sizeof(scbval));
1970 brcmf_err("error (%d)\n", err);
1972 brcmf_dbg(TRACE, "Exit\n");
1977 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1978 enum nl80211_tx_power_setting type, s32 mbm)
1981 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1982 struct net_device *ndev = cfg_to_ndev(cfg);
1983 struct brcmf_if *ifp = netdev_priv(ndev);
1987 s32 dbm = MBM_TO_DBM(mbm);
1989 brcmf_dbg(TRACE, "Enter\n");
1990 if (!check_vif_up(ifp->vif))
1994 case NL80211_TX_POWER_AUTOMATIC:
1996 case NL80211_TX_POWER_LIMITED:
1997 case NL80211_TX_POWER_FIXED:
1999 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2005 /* Make sure radio is off or on as far as software is concerned */
2006 disable = WL_RADIO_SW_DISABLE << 16;
2007 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2009 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2014 txpwrmw = (u16) dbm;
2015 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
2016 (s32)brcmf_mw_to_qdbm(txpwrmw));
2018 brcmf_err("qtxpower error (%d)\n", err);
2019 cfg->conf->tx_power = dbm;
2022 brcmf_dbg(TRACE, "Exit\n");
2026 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
2027 struct wireless_dev *wdev,
2030 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2031 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2036 brcmf_dbg(TRACE, "Enter\n");
2037 if (!check_vif_up(ifp->vif))
2040 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
2042 brcmf_err("error (%d)\n", err);
2046 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2047 *dbm = (s32) brcmf_qdbm_to_mw(result);
2050 brcmf_dbg(TRACE, "Exit\n");
2055 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2056 u8 key_idx, bool unicast, bool multicast)
2058 struct brcmf_if *ifp = netdev_priv(ndev);
2063 brcmf_dbg(TRACE, "Enter\n");
2064 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2065 if (!check_vif_up(ifp->vif))
2068 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2070 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2074 if (wsec & WEP_ENABLED) {
2075 /* Just select a new current key */
2077 err = brcmf_fil_cmd_int_set(ifp,
2078 BRCMF_C_SET_KEY_PRIMARY, index);
2080 brcmf_err("error (%d)\n", err);
2083 brcmf_dbg(TRACE, "Exit\n");
2088 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2089 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2091 struct brcmf_if *ifp = netdev_priv(ndev);
2092 struct brcmf_wsec_key key;
2096 memset(&key, 0, sizeof(key));
2097 key.index = (u32) key_idx;
2098 /* Instead of bcast for ea address for default wep keys,
2099 driver needs it to be Null */
2100 if (!is_multicast_ether_addr(mac_addr))
2101 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2102 key.len = (u32) params->key_len;
2103 /* check for key index change */
2106 err = send_key_to_dongle(ifp, &key);
2108 brcmf_err("key delete error (%d)\n", err);
2110 if (key.len > sizeof(key.data)) {
2111 brcmf_err("Invalid key length (%d)\n", key.len);
2115 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2116 memcpy(key.data, params->key, key.len);
2118 if (!brcmf_is_apmode(ifp->vif) &&
2119 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2120 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2121 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2122 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2123 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2126 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2127 if (params->seq && params->seq_len == 6) {
2130 ivptr = (u8 *) params->seq;
2131 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2132 (ivptr[3] << 8) | ivptr[2];
2133 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2134 key.iv_initialized = true;
2137 switch (params->cipher) {
2138 case WLAN_CIPHER_SUITE_WEP40:
2139 key.algo = CRYPTO_ALGO_WEP1;
2140 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2142 case WLAN_CIPHER_SUITE_WEP104:
2143 key.algo = CRYPTO_ALGO_WEP128;
2144 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2146 case WLAN_CIPHER_SUITE_TKIP:
2147 key.algo = CRYPTO_ALGO_TKIP;
2148 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2150 case WLAN_CIPHER_SUITE_AES_CMAC:
2151 key.algo = CRYPTO_ALGO_AES_CCM;
2152 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2154 case WLAN_CIPHER_SUITE_CCMP:
2155 key.algo = CRYPTO_ALGO_AES_CCM;
2156 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2159 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2162 err = send_key_to_dongle(ifp, &key);
2164 brcmf_err("wsec_key error (%d)\n", err);
2170 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2171 u8 key_idx, bool pairwise, const u8 *mac_addr,
2172 struct key_params *params)
2174 struct brcmf_if *ifp = netdev_priv(ndev);
2175 struct brcmf_wsec_key *key;
2181 brcmf_dbg(TRACE, "Enter\n");
2182 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2183 if (!check_vif_up(ifp->vif))
2186 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2187 /* we ignore this key index in this case */
2188 brcmf_err("invalid key index (%d)\n", key_idx);
2193 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2194 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2195 brcmf_dbg(TRACE, "Exit");
2196 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2199 key = &ifp->vif->profile.key[key_idx];
2200 memset(key, 0, sizeof(*key));
2202 if (params->key_len > sizeof(key->data)) {
2203 brcmf_err("Too long key length (%u)\n", params->key_len);
2207 key->len = params->key_len;
2208 key->index = key_idx;
2210 memcpy(key->data, params->key, key->len);
2212 key->flags = BRCMF_PRIMARY_KEY;
2213 switch (params->cipher) {
2214 case WLAN_CIPHER_SUITE_WEP40:
2215 key->algo = CRYPTO_ALGO_WEP1;
2217 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2219 case WLAN_CIPHER_SUITE_WEP104:
2220 key->algo = CRYPTO_ALGO_WEP128;
2222 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2224 case WLAN_CIPHER_SUITE_TKIP:
2225 if (!brcmf_is_apmode(ifp->vif)) {
2226 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2227 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2228 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2229 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2231 key->algo = CRYPTO_ALGO_TKIP;
2233 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2235 case WLAN_CIPHER_SUITE_AES_CMAC:
2236 key->algo = CRYPTO_ALGO_AES_CCM;
2238 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2240 case WLAN_CIPHER_SUITE_CCMP:
2241 key->algo = CRYPTO_ALGO_AES_CCM;
2243 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2246 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2251 err = send_key_to_dongle(ifp, key);
2255 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2257 brcmf_err("get wsec error (%d)\n", err);
2261 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2263 brcmf_err("set wsec error (%d)\n", err);
2268 brcmf_dbg(TRACE, "Exit\n");
2273 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2274 u8 key_idx, bool pairwise, const u8 *mac_addr)
2276 struct brcmf_if *ifp = netdev_priv(ndev);
2277 struct brcmf_wsec_key key;
2280 brcmf_dbg(TRACE, "Enter\n");
2281 if (!check_vif_up(ifp->vif))
2284 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2285 /* we ignore this key index in this case */
2289 memset(&key, 0, sizeof(key));
2291 key.index = (u32) key_idx;
2292 key.flags = BRCMF_PRIMARY_KEY;
2293 key.algo = CRYPTO_ALGO_OFF;
2295 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2297 /* Set the new key/index */
2298 err = send_key_to_dongle(ifp, &key);
2300 brcmf_dbg(TRACE, "Exit\n");
2305 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2306 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2307 void (*callback) (void *cookie, struct key_params * params))
2309 struct key_params params;
2310 struct brcmf_if *ifp = netdev_priv(ndev);
2311 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2312 struct brcmf_cfg80211_security *sec;
2316 brcmf_dbg(TRACE, "Enter\n");
2317 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2318 if (!check_vif_up(ifp->vif))
2321 memset(¶ms, 0, sizeof(params));
2323 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2325 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2326 /* Ignore this error, may happen during DISASSOC */
2330 if (wsec & WEP_ENABLED) {
2331 sec = &profile->sec;
2332 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2333 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2334 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2335 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2336 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2337 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2339 } else if (wsec & TKIP_ENABLED) {
2340 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2341 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2342 } else if (wsec & AES_ENABLED) {
2343 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2344 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2346 brcmf_err("Invalid algo (0x%x)\n", wsec);
2350 callback(cookie, ¶ms);
2353 brcmf_dbg(TRACE, "Exit\n");
2358 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2359 struct net_device *ndev, u8 key_idx)
2361 brcmf_dbg(INFO, "Not supported\n");
2367 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2371 struct brcmf_wsec_key *key;
2374 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2375 key = &ifp->vif->profile.key[key_idx];
2376 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2377 (key->algo == CRYPTO_ALGO_WEP128))
2380 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2383 err = send_key_to_dongle(ifp, key);
2385 brcmf_err("Setting WEP key failed (%d)\n", err);
2388 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2390 brcmf_err("get wsec error (%d)\n", err);
2393 wsec |= WEP_ENABLED;
2394 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2396 brcmf_err("set wsec error (%d)\n", err);
2399 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2401 struct nl80211_sta_flag_update *sfu;
2403 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2404 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2405 sfu = &si->sta_flags;
2406 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2407 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2408 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2409 BIT(NL80211_STA_FLAG_AUTHORIZED);
2410 if (fw_sta_flags & BRCMF_STA_WME)
2411 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2412 if (fw_sta_flags & BRCMF_STA_AUTHE)
2413 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2414 if (fw_sta_flags & BRCMF_STA_ASSOC)
2415 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2416 if (fw_sta_flags & BRCMF_STA_AUTHO)
2417 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2420 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2424 struct brcmf_bss_info_le bss_le;
2429 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2433 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2434 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2437 brcmf_err("Failed to get bss info (%d)\n", err);
2440 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2441 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2442 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2443 capability = le16_to_cpu(buf->bss_le.capability);
2444 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2445 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2446 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2447 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2448 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2449 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2453 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2454 const u8 *mac, struct station_info *sinfo)
2456 struct brcmf_if *ifp = netdev_priv(ndev);
2458 struct brcmf_sta_info_le sta_info_le;
2462 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2463 if (!check_vif_up(ifp->vif))
2466 memset(&sta_info_le, 0, sizeof(sta_info_le));
2467 memcpy(&sta_info_le, mac, ETH_ALEN);
2468 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2470 sizeof(sta_info_le));
2471 is_tdls_peer = !err;
2473 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2475 sizeof(sta_info_le));
2477 brcmf_err("GET STA INFO failed, %d\n", err);
2481 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2482 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2483 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2484 sta_flags = le32_to_cpu(sta_info_le.flags);
2485 brcmf_convert_sta_flags(sta_flags, sinfo);
2486 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2488 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2490 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2491 if (sta_flags & BRCMF_STA_ASSOC) {
2492 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2493 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2494 brcmf_fill_bss_param(ifp, sinfo);
2496 if (sta_flags & BRCMF_STA_SCBSTATS) {
2497 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2498 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2499 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2500 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2501 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2502 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2503 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2504 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2505 if (sinfo->tx_packets) {
2506 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2507 sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
2508 sinfo->txrate.legacy /= 100;
2510 if (sinfo->rx_packets) {
2511 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2512 sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
2513 sinfo->rxrate.legacy /= 100;
2515 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2516 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2517 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2518 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2519 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2523 brcmf_dbg(TRACE, "Exit\n");
2528 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2529 bool enabled, s32 timeout)
2533 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2534 struct brcmf_if *ifp = netdev_priv(ndev);
2536 brcmf_dbg(TRACE, "Enter\n");
2539 * Powersave enable/disable request is coming from the
2540 * cfg80211 even before the interface is up. In that
2541 * scenario, driver will be storing the power save
2542 * preference in cfg struct to apply this to
2543 * FW later while initializing the dongle
2545 cfg->pwr_save = enabled;
2546 if (!check_vif_up(ifp->vif)) {
2548 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2552 pm = enabled ? PM_FAST : PM_OFF;
2553 /* Do not enable the power save after assoc if it is a p2p interface */
2554 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2555 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2558 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2560 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2563 brcmf_err("net_device is not ready yet\n");
2565 brcmf_err("error (%d)\n", err);
2568 brcmf_dbg(TRACE, "Exit\n");
2572 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2573 struct brcmf_bss_info_le *bi)
2575 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2576 struct ieee80211_channel *notify_channel;
2577 struct cfg80211_bss *bss;
2578 struct ieee80211_supported_band *band;
2579 struct brcmu_chan ch;
2582 u16 notify_capability;
2583 u16 notify_interval;
2585 size_t notify_ielen;
2588 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2589 brcmf_err("Bss info is larger than buffer. Discarding\n");
2594 ch.chspec = le16_to_cpu(bi->chanspec);
2595 cfg->d11inf.decchspec(&ch);
2596 bi->ctl_ch = ch.chnum;
2598 channel = bi->ctl_ch;
2600 if (channel <= CH_MAX_2G_CHANNEL)
2601 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2603 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2605 freq = ieee80211_channel_to_frequency(channel, band->band);
2606 notify_channel = ieee80211_get_channel(wiphy, freq);
2608 notify_capability = le16_to_cpu(bi->capability);
2609 notify_interval = le16_to_cpu(bi->beacon_period);
2610 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2611 notify_ielen = le32_to_cpu(bi->ie_length);
2612 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2614 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2615 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2616 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2617 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2618 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2620 bss = cfg80211_inform_bss(wiphy, notify_channel,
2621 CFG80211_BSS_FTYPE_UNKNOWN,
2622 (const u8 *)bi->BSSID,
2623 0, notify_capability,
2624 notify_interval, notify_ie,
2625 notify_ielen, notify_signal,
2631 cfg80211_put_bss(wiphy, bss);
2636 static struct brcmf_bss_info_le *
2637 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2640 return list->bss_info_le;
2641 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2642 le32_to_cpu(bss->length));
2645 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2647 struct brcmf_scan_results *bss_list;
2648 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2652 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2653 if (bss_list->count != 0 &&
2654 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2655 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2659 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2660 for (i = 0; i < bss_list->count; i++) {
2661 bi = next_bss_le(bss_list, bi);
2662 err = brcmf_inform_single_bss(cfg, bi);
2669 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2670 struct net_device *ndev, const u8 *bssid)
2672 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2673 struct ieee80211_channel *notify_channel;
2674 struct brcmf_bss_info_le *bi = NULL;
2675 struct ieee80211_supported_band *band;
2676 struct cfg80211_bss *bss;
2677 struct brcmu_chan ch;
2681 u16 notify_capability;
2682 u16 notify_interval;
2684 size_t notify_ielen;
2687 brcmf_dbg(TRACE, "Enter\n");
2689 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2695 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2697 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2698 buf, WL_BSS_INFO_MAX);
2700 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2704 bi = (struct brcmf_bss_info_le *)(buf + 4);
2706 ch.chspec = le16_to_cpu(bi->chanspec);
2707 cfg->d11inf.decchspec(&ch);
2709 if (ch.band == BRCMU_CHAN_BAND_2G)
2710 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2712 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2714 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2715 notify_channel = ieee80211_get_channel(wiphy, freq);
2717 notify_capability = le16_to_cpu(bi->capability);
2718 notify_interval = le16_to_cpu(bi->beacon_period);
2719 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2720 notify_ielen = le32_to_cpu(bi->ie_length);
2721 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2723 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2724 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2725 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2726 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2728 bss = cfg80211_inform_bss(wiphy, notify_channel,
2729 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2730 notify_capability, notify_interval,
2731 notify_ie, notify_ielen, notify_signal,
2739 cfg80211_put_bss(wiphy, bss);
2745 brcmf_dbg(TRACE, "Exit\n");
2750 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2751 struct brcmf_if *ifp)
2753 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2754 struct brcmf_bss_info_le *bi;
2755 struct brcmf_ssid *ssid;
2756 const struct brcmf_tlv *tim;
2757 u16 beacon_interval;
2763 brcmf_dbg(TRACE, "Enter\n");
2764 if (brcmf_is_ibssmode(ifp->vif))
2767 ssid = &profile->ssid;
2769 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2770 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2771 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2773 brcmf_err("Could not get bss info %d\n", err);
2774 goto update_bss_info_out;
2777 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2778 err = brcmf_inform_single_bss(cfg, bi);
2780 goto update_bss_info_out;
2782 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2783 ie_len = le32_to_cpu(bi->ie_length);
2784 beacon_interval = le16_to_cpu(bi->beacon_period);
2786 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2788 dtim_period = tim->data[1];
2791 * active scan was done so we could not get dtim
2792 * information out of probe response.
2793 * so we speficially query dtim information to dongle.
2796 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2798 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2799 goto update_bss_info_out;
2801 dtim_period = (u8)var;
2804 update_bss_info_out:
2805 brcmf_dbg(TRACE, "Exit");
2809 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2811 struct escan_info *escan = &cfg->escan_info;
2813 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2814 if (cfg->scan_request) {
2815 escan->escan_state = WL_ESCAN_STATE_IDLE;
2816 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2818 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2819 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2822 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2824 struct brcmf_cfg80211_info *cfg =
2825 container_of(work, struct brcmf_cfg80211_info,
2826 escan_timeout_work);
2828 brcmf_inform_bss(cfg);
2829 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2832 static void brcmf_escan_timeout(unsigned long data)
2834 struct brcmf_cfg80211_info *cfg =
2835 (struct brcmf_cfg80211_info *)data;
2837 if (cfg->scan_request) {
2838 brcmf_err("timer expired\n");
2839 schedule_work(&cfg->escan_timeout_work);
2844 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2845 struct brcmf_bss_info_le *bss,
2846 struct brcmf_bss_info_le *bss_info_le)
2848 struct brcmu_chan ch_bss, ch_bss_info_le;
2850 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2851 cfg->d11inf.decchspec(&ch_bss);
2852 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2853 cfg->d11inf.decchspec(&ch_bss_info_le);
2855 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2856 ch_bss.band == ch_bss_info_le.band &&
2857 bss_info_le->SSID_len == bss->SSID_len &&
2858 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2859 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2860 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2861 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2862 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2864 /* preserve max RSSI if the measurements are
2865 * both on-channel or both off-channel
2867 if (bss_info_rssi > bss_rssi)
2868 bss->RSSI = bss_info_le->RSSI;
2869 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2870 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2871 /* preserve the on-channel rssi measurement
2872 * if the new measurement is off channel
2874 bss->RSSI = bss_info_le->RSSI;
2875 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2883 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2884 const struct brcmf_event_msg *e, void *data)
2886 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2888 struct brcmf_escan_result_le *escan_result_le;
2889 struct brcmf_bss_info_le *bss_info_le;
2890 struct brcmf_bss_info_le *bss = NULL;
2892 struct brcmf_scan_results *list;
2898 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2899 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2903 if (status == BRCMF_E_STATUS_PARTIAL) {
2904 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2905 escan_result_le = (struct brcmf_escan_result_le *) data;
2906 if (!escan_result_le) {
2907 brcmf_err("Invalid escan result (NULL pointer)\n");
2910 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2911 brcmf_err("Invalid bss_count %d: ignoring\n",
2912 escan_result_le->bss_count);
2915 bss_info_le = &escan_result_le->bss_info_le;
2917 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2920 if (!cfg->scan_request) {
2921 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2925 bi_length = le32_to_cpu(bss_info_le->length);
2926 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2927 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2928 brcmf_err("Invalid bss_info length %d: ignoring\n",
2933 if (!(cfg_to_wiphy(cfg)->interface_modes &
2934 BIT(NL80211_IFTYPE_ADHOC))) {
2935 if (le16_to_cpu(bss_info_le->capability) &
2936 WLAN_CAPABILITY_IBSS) {
2937 brcmf_err("Ignoring IBSS result\n");
2942 list = (struct brcmf_scan_results *)
2943 cfg->escan_info.escan_buf;
2944 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2945 brcmf_err("Buffer is too small: ignoring\n");
2949 for (i = 0; i < list->count; i++) {
2950 bss = bss ? (struct brcmf_bss_info_le *)
2951 ((unsigned char *)bss +
2952 le32_to_cpu(bss->length)) : list->bss_info_le;
2953 if (brcmf_compare_update_same_bss(cfg, bss,
2957 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2958 bss_info_le, bi_length);
2959 list->version = le32_to_cpu(bss_info_le->version);
2960 list->buflen += bi_length;
2963 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2964 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2966 if (cfg->scan_request) {
2967 brcmf_inform_bss(cfg);
2968 aborted = status != BRCMF_E_STATUS_SUCCESS;
2969 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
2971 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2978 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2980 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2981 brcmf_cfg80211_escan_handler);
2982 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2983 /* Init scan_timeout timer */
2984 init_timer(&cfg->escan_timeout);
2985 cfg->escan_timeout.data = (unsigned long) cfg;
2986 cfg->escan_timeout.function = brcmf_escan_timeout;
2987 INIT_WORK(&cfg->escan_timeout_work,
2988 brcmf_cfg80211_escan_timeout_worker);
2991 static __always_inline void brcmf_delay(u32 ms)
2993 if (ms < 1000 / HZ) {
3001 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3002 u8 *pattern, u32 patternsize, u8 *mask,
3005 struct brcmf_fil_wowl_pattern_le *filter;
3012 masksize = (patternsize + 7) / 8;
3013 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3015 bufsize = sizeof(*filter) + patternsize + masksize;
3016 buf = kzalloc(bufsize, GFP_KERNEL);
3019 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3021 memcpy(filter->cmd, cmd, 4);
3022 filter->masksize = cpu_to_le32(masksize);
3023 filter->offset = cpu_to_le32(packet_offset);
3024 filter->patternoffset = cpu_to_le32(patternoffset);
3025 filter->patternsize = cpu_to_le32(patternsize);
3026 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3028 if ((mask) && (masksize))
3029 memcpy(buf + sizeof(*filter), mask, masksize);
3030 if ((pattern) && (patternsize))
3031 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3033 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3039 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3041 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3042 struct net_device *ndev = cfg_to_ndev(cfg);
3043 struct brcmf_if *ifp = netdev_priv(ndev);
3045 brcmf_dbg(TRACE, "Enter\n");
3047 if (cfg->wowl_enabled) {
3048 brcmf_configure_arp_offload(ifp, true);
3049 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3050 cfg->pre_wowl_pmmode);
3051 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3052 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3053 cfg->wowl_enabled = false;
3058 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3059 struct brcmf_if *ifp,
3060 struct cfg80211_wowlan *wowl)
3065 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3067 brcmf_configure_arp_offload(ifp, false);
3068 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
3069 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3072 if (wowl->disconnect)
3073 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3074 if (wowl->magic_pkt)
3075 wowl_config |= BRCMF_WOWL_MAGIC;
3076 if ((wowl->patterns) && (wowl->n_patterns)) {
3077 wowl_config |= BRCMF_WOWL_NET;
3078 for (i = 0; i < wowl->n_patterns; i++) {
3079 brcmf_config_wowl_pattern(ifp, "add",
3080 (u8 *)wowl->patterns[i].pattern,
3081 wowl->patterns[i].pattern_len,
3082 (u8 *)wowl->patterns[i].mask,
3083 wowl->patterns[i].pkt_offset);
3086 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3087 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3088 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3089 cfg->wowl_enabled = true;
3092 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3093 struct cfg80211_wowlan *wowl)
3095 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3096 struct net_device *ndev = cfg_to_ndev(cfg);
3097 struct brcmf_if *ifp = netdev_priv(ndev);
3098 struct brcmf_cfg80211_vif *vif;
3100 brcmf_dbg(TRACE, "Enter\n");
3102 /* if the primary net_device is not READY there is nothing
3103 * we can do but pray resume goes smoothly.
3105 if (!check_vif_up(ifp->vif))
3108 /* end any scanning */
3109 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3110 brcmf_abort_scanning(cfg);
3113 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3114 list_for_each_entry(vif, &cfg->vif_list, list) {
3115 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3117 /* While going to suspend if associated with AP
3118 * disassociate from AP to save power while system is
3119 * in suspended state
3121 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3122 /* Make sure WPA_Supplicant receives all the event
3123 * generated due to DISASSOC call to the fw to keep
3124 * the state fw and WPA_Supplicant state consistent
3129 brcmf_set_mpc(ifp, 1);
3132 /* Configure WOWL paramaters */
3133 brcmf_configure_wowl(cfg, ifp, wowl);
3137 brcmf_dbg(TRACE, "Exit\n");
3138 /* clear any scanning activity */
3139 cfg->scan_status = 0;
3144 brcmf_update_pmklist(struct net_device *ndev,
3145 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3150 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3152 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
3153 for (i = 0; i < pmkid_len; i++) {
3154 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
3155 &pmk_list->pmkids.pmkid[i].BSSID);
3156 for (j = 0; j < WLAN_PMKID_LEN; j++)
3157 brcmf_dbg(CONN, "%02x\n",
3158 pmk_list->pmkids.pmkid[i].PMKID[j]);
3162 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
3163 (char *)pmk_list, sizeof(*pmk_list));
3169 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3170 struct cfg80211_pmksa *pmksa)
3172 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3173 struct brcmf_if *ifp = netdev_priv(ndev);
3174 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3178 brcmf_dbg(TRACE, "Enter\n");
3179 if (!check_vif_up(ifp->vif))
3182 pmkid_len = le32_to_cpu(pmkids->npmkid);
3183 for (i = 0; i < pmkid_len; i++)
3184 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3186 if (i < WL_NUM_PMKIDS_MAX) {
3187 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3188 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3189 if (i == pmkid_len) {
3191 pmkids->npmkid = cpu_to_le32(pmkid_len);
3196 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3197 pmkids->pmkid[pmkid_len].BSSID);
3198 for (i = 0; i < WLAN_PMKID_LEN; i++)
3199 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3201 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3203 brcmf_dbg(TRACE, "Exit\n");
3208 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3209 struct cfg80211_pmksa *pmksa)
3211 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3212 struct brcmf_if *ifp = netdev_priv(ndev);
3213 struct pmkid_list pmkid;
3217 brcmf_dbg(TRACE, "Enter\n");
3218 if (!check_vif_up(ifp->vif))
3221 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3222 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3224 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3225 &pmkid.pmkid[0].BSSID);
3226 for (i = 0; i < WLAN_PMKID_LEN; i++)
3227 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
3229 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3230 for (i = 0; i < pmkid_len; i++)
3232 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3237 && (i < pmkid_len)) {
3238 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3239 sizeof(struct pmkid));
3240 for (; i < (pmkid_len - 1); i++) {
3241 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3242 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3244 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3245 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3248 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3252 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3254 brcmf_dbg(TRACE, "Exit\n");
3260 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3262 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3263 struct brcmf_if *ifp = netdev_priv(ndev);
3266 brcmf_dbg(TRACE, "Enter\n");
3267 if (!check_vif_up(ifp->vif))
3270 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3271 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3273 brcmf_dbg(TRACE, "Exit\n");
3279 * PFN result doesn't have all the info which are
3280 * required by the supplicant
3281 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3282 * via wl_inform_single_bss in the required format. Escan does require the
3283 * scan request in the form of cfg80211_scan_request. For timebeing, create
3284 * cfg80211_scan_request one out of the received PNO event.
3287 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3288 const struct brcmf_event_msg *e, void *data)
3290 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3291 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3292 struct cfg80211_scan_request *request = NULL;
3293 struct cfg80211_ssid *ssid = NULL;
3294 struct ieee80211_channel *channel = NULL;
3295 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3297 int channel_req = 0;
3299 struct brcmf_pno_scanresults_le *pfn_result;
3303 brcmf_dbg(SCAN, "Enter\n");
3305 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3306 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3310 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3311 result_count = le32_to_cpu(pfn_result->count);
3312 status = le32_to_cpu(pfn_result->status);
3315 * PFN event is limited to fit 512 bytes so we may get
3316 * multiple NET_FOUND events. For now place a warning here.
3318 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3319 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3320 if (result_count > 0) {
3323 request = kzalloc(sizeof(*request), GFP_KERNEL);
3324 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3325 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3326 if (!request || !ssid || !channel) {
3331 request->wiphy = wiphy;
3332 data += sizeof(struct brcmf_pno_scanresults_le);
3333 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3335 for (i = 0; i < result_count; i++) {
3336 netinfo = &netinfo_start[i];
3338 brcmf_err("Invalid netinfo ptr. index: %d\n",
3344 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3345 netinfo->SSID, netinfo->channel);
3346 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3347 ssid[i].ssid_len = netinfo->SSID_len;
3350 channel_req = netinfo->channel;
3351 if (channel_req <= CH_MAX_2G_CHANNEL)
3352 band = NL80211_BAND_2GHZ;
3354 band = NL80211_BAND_5GHZ;
3355 channel[i].center_freq =
3356 ieee80211_channel_to_frequency(channel_req,
3358 channel[i].band = band;
3359 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3360 request->channels[i] = &channel[i];
3361 request->n_channels++;
3364 /* assign parsed ssid array */
3365 if (request->n_ssids)
3366 request->ssids = &ssid[0];
3368 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3369 /* Abort any on-going scan */
3370 brcmf_abort_scanning(cfg);
3373 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3374 cfg->escan_info.run = brcmf_run_escan;
3375 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3377 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3380 cfg->sched_escan = true;
3381 cfg->scan_request = request;
3383 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3396 cfg80211_sched_scan_stopped(wiphy);
3400 static int brcmf_dev_pno_clean(struct net_device *ndev)
3405 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3408 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3412 brcmf_err("failed code %d\n", ret);
3417 static int brcmf_dev_pno_config(struct net_device *ndev)
3419 struct brcmf_pno_param_le pfn_param;
3421 memset(&pfn_param, 0, sizeof(pfn_param));
3422 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3424 /* set extra pno params */
3425 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3426 pfn_param.repeat = BRCMF_PNO_REPEAT;
3427 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3429 /* set up pno scan fr */
3430 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3432 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3433 &pfn_param, sizeof(pfn_param));
3437 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3438 struct net_device *ndev,
3439 struct cfg80211_sched_scan_request *request)
3441 struct brcmf_if *ifp = netdev_priv(ndev);
3442 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3443 struct brcmf_pno_net_param_le pfn;
3447 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3448 request->n_match_sets, request->n_ssids);
3449 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3450 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3453 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3454 brcmf_err("Scanning suppressed: status (%lu)\n",
3459 if (!request->n_ssids || !request->n_match_sets) {
3460 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3465 if (request->n_ssids > 0) {
3466 for (i = 0; i < request->n_ssids; i++) {
3467 /* Active scan req for ssids */
3468 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3469 request->ssids[i].ssid);
3472 * match_set ssids is a supert set of n_ssid list,
3473 * so we need not add these set seperately.
3478 if (request->n_match_sets > 0) {
3479 /* clean up everything */
3480 ret = brcmf_dev_pno_clean(ndev);
3482 brcmf_err("failed error=%d\n", ret);
3487 ret = brcmf_dev_pno_config(ndev);
3489 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3493 /* configure each match set */
3494 for (i = 0; i < request->n_match_sets; i++) {
3495 struct cfg80211_ssid *ssid;
3498 ssid = &request->match_sets[i].ssid;
3499 ssid_len = ssid->ssid_len;
3502 brcmf_err("skip broadcast ssid\n");
3505 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3506 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3507 pfn.wsec = cpu_to_le32(0);
3508 pfn.infra = cpu_to_le32(1);
3509 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3510 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3511 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3512 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3514 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3515 ret == 0 ? "set" : "failed", ssid->ssid);
3517 /* Enable the PNO */
3518 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3519 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3529 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3530 struct net_device *ndev)
3532 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3534 brcmf_dbg(SCAN, "enter\n");
3535 brcmf_dev_pno_clean(ndev);
3536 if (cfg->sched_escan)
3537 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3541 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3546 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3548 brcmf_err("auth error %d\n", err);
3552 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3554 brcmf_err("wsec error %d\n", err);
3557 /* set upper-layer auth */
3558 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3560 brcmf_err("wpa_auth error %d\n", err);
3567 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3570 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3572 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3576 brcmf_configure_wpaie(struct brcmf_if *ifp,
3577 const struct brcmf_vs_tlv *wpa_ie,
3580 u32 auth = 0; /* d11 open authentication */
3592 u32 wme_bss_disable;
3594 brcmf_dbg(TRACE, "Enter\n");
3598 len = wpa_ie->len + TLV_HDR_LEN;
3599 data = (u8 *)wpa_ie;
3600 offset = TLV_HDR_LEN;
3602 offset += VS_IE_FIXED_HDR_LEN;
3604 offset += WPA_IE_VERSION_LEN;
3606 /* check for multicast cipher suite */
3607 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3609 brcmf_err("no multicast cipher suite\n");
3613 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3615 brcmf_err("ivalid OUI\n");
3618 offset += TLV_OUI_LEN;
3620 /* pick up multicast cipher */
3621 switch (data[offset]) {
3622 case WPA_CIPHER_NONE:
3625 case WPA_CIPHER_WEP_40:
3626 case WPA_CIPHER_WEP_104:
3629 case WPA_CIPHER_TKIP:
3630 gval = TKIP_ENABLED;
3632 case WPA_CIPHER_AES_CCM:
3637 brcmf_err("Invalid multi cast cipher info\n");
3642 /* walk thru unicast cipher list and pick up what we recognize */
3643 count = data[offset] + (data[offset + 1] << 8);
3644 offset += WPA_IE_SUITE_COUNT_LEN;
3645 /* Check for unicast suite(s) */
3646 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3648 brcmf_err("no unicast cipher suite\n");
3651 for (i = 0; i < count; i++) {
3652 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3654 brcmf_err("ivalid OUI\n");
3657 offset += TLV_OUI_LEN;
3658 switch (data[offset]) {
3659 case WPA_CIPHER_NONE:
3661 case WPA_CIPHER_WEP_40:
3662 case WPA_CIPHER_WEP_104:
3663 pval |= WEP_ENABLED;
3665 case WPA_CIPHER_TKIP:
3666 pval |= TKIP_ENABLED;
3668 case WPA_CIPHER_AES_CCM:
3669 pval |= AES_ENABLED;
3672 brcmf_err("Ivalid unicast security info\n");
3676 /* walk thru auth management suite list and pick up what we recognize */
3677 count = data[offset] + (data[offset + 1] << 8);
3678 offset += WPA_IE_SUITE_COUNT_LEN;
3679 /* Check for auth key management suite(s) */
3680 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3682 brcmf_err("no auth key mgmt suite\n");
3685 for (i = 0; i < count; i++) {
3686 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3688 brcmf_err("ivalid OUI\n");
3691 offset += TLV_OUI_LEN;
3692 switch (data[offset]) {
3694 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3695 wpa_auth |= WPA_AUTH_NONE;
3697 case RSN_AKM_UNSPECIFIED:
3698 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3699 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3700 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3703 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3704 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3705 (wpa_auth |= WPA_AUTH_PSK);
3708 brcmf_err("Ivalid key mgmt info\n");
3714 wme_bss_disable = 1;
3715 if ((offset + RSN_CAP_LEN) <= len) {
3716 rsn_cap = data[offset] + (data[offset + 1] << 8);
3717 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3718 wme_bss_disable = 0;
3720 /* set wme_bss_disable to sync RSN Capabilities */
3721 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3724 brcmf_err("wme_bss_disable error %d\n", err);
3728 /* FOR WPS , set SES_OW_ENABLED */
3729 wsec = (pval | gval | SES_OW_ENABLED);
3732 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3734 brcmf_err("auth error %d\n", err);
3738 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3740 brcmf_err("wsec error %d\n", err);
3743 /* set upper-layer auth */
3744 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3746 brcmf_err("wpa_auth error %d\n", err);
3755 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3756 struct parsed_vndr_ies *vndr_ies)
3758 struct brcmf_vs_tlv *vndrie;
3759 struct brcmf_tlv *ie;
3760 struct parsed_vndr_ie_info *parsed_info;
3763 remaining_len = (s32)vndr_ie_len;
3764 memset(vndr_ies, 0, sizeof(*vndr_ies));
3766 ie = (struct brcmf_tlv *)vndr_ie_buf;
3768 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3770 vndrie = (struct brcmf_vs_tlv *)ie;
3771 /* len should be bigger than OUI length + one */
3772 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3773 brcmf_err("invalid vndr ie. length is too small %d\n",
3777 /* if wpa or wme ie, do not add ie */
3778 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3779 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3780 (vndrie->oui_type == WME_OUI_TYPE))) {
3781 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3785 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3787 /* save vndr ie information */
3788 parsed_info->ie_ptr = (char *)vndrie;
3789 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3790 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3794 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3795 parsed_info->vndrie.oui[0],
3796 parsed_info->vndrie.oui[1],
3797 parsed_info->vndrie.oui[2],
3798 parsed_info->vndrie.oui_type);
3800 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3803 remaining_len -= (ie->len + TLV_HDR_LEN);
3804 if (remaining_len <= TLV_HDR_LEN)
3807 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3814 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3817 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3818 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3820 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3822 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3824 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3826 return ie_len + VNDR_IE_HDR_SIZE;
3829 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3830 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3832 struct brcmf_if *ifp;
3833 struct vif_saved_ie *saved_ie;
3837 u8 *mgmt_ie_buf = NULL;
3838 int mgmt_ie_buf_len;
3840 u32 del_add_ie_buf_len = 0;
3841 u32 total_ie_buf_len = 0;
3842 u32 parsed_ie_buf_len = 0;
3843 struct parsed_vndr_ies old_vndr_ies;
3844 struct parsed_vndr_ies new_vndr_ies;
3845 struct parsed_vndr_ie_info *vndrie_info;
3848 int remained_buf_len;
3853 saved_ie = &vif->saved_ie;
3855 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3856 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3859 curr_ie_buf = iovar_ie_buf;
3861 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3862 mgmt_ie_buf = saved_ie->probe_req_ie;
3863 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3864 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3866 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3867 mgmt_ie_buf = saved_ie->probe_res_ie;
3868 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3869 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3871 case BRCMF_VNDR_IE_BEACON_FLAG:
3872 mgmt_ie_buf = saved_ie->beacon_ie;
3873 mgmt_ie_len = &saved_ie->beacon_ie_len;
3874 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3876 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3877 mgmt_ie_buf = saved_ie->assoc_req_ie;
3878 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3879 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3883 brcmf_err("not suitable type\n");
3887 if (vndr_ie_len > mgmt_ie_buf_len) {
3889 brcmf_err("extra IE size too big\n");
3893 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3894 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3896 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3897 for (i = 0; i < new_vndr_ies.count; i++) {
3898 vndrie_info = &new_vndr_ies.ie_info[i];
3899 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3900 vndrie_info->ie_len);
3901 parsed_ie_buf_len += vndrie_info->ie_len;
3905 if (mgmt_ie_buf && *mgmt_ie_len) {
3906 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3907 (memcmp(mgmt_ie_buf, curr_ie_buf,
3908 parsed_ie_buf_len) == 0)) {
3909 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3913 /* parse old vndr_ie */
3914 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3916 /* make a command to delete old ie */
3917 for (i = 0; i < old_vndr_ies.count; i++) {
3918 vndrie_info = &old_vndr_ies.ie_info[i];
3920 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3921 vndrie_info->vndrie.id,
3922 vndrie_info->vndrie.len,
3923 vndrie_info->vndrie.oui[0],
3924 vndrie_info->vndrie.oui[1],
3925 vndrie_info->vndrie.oui[2]);
3927 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3928 vndrie_info->ie_ptr,
3929 vndrie_info->ie_len,
3931 curr_ie_buf += del_add_ie_buf_len;
3932 total_ie_buf_len += del_add_ie_buf_len;
3937 /* Add if there is any extra IE */
3938 if (mgmt_ie_buf && parsed_ie_buf_len) {
3941 remained_buf_len = mgmt_ie_buf_len;
3943 /* make a command to add new ie */
3944 for (i = 0; i < new_vndr_ies.count; i++) {
3945 vndrie_info = &new_vndr_ies.ie_info[i];
3947 /* verify remained buf size before copy data */
3948 if (remained_buf_len < (vndrie_info->vndrie.len +
3949 VNDR_IE_VSIE_OFFSET)) {
3950 brcmf_err("no space in mgmt_ie_buf: len left %d",
3954 remained_buf_len -= (vndrie_info->ie_len +
3955 VNDR_IE_VSIE_OFFSET);
3957 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3958 vndrie_info->vndrie.id,
3959 vndrie_info->vndrie.len,
3960 vndrie_info->vndrie.oui[0],
3961 vndrie_info->vndrie.oui[1],
3962 vndrie_info->vndrie.oui[2]);
3964 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3965 vndrie_info->ie_ptr,
3966 vndrie_info->ie_len,
3969 /* save the parsed IE in wl struct */
3970 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3971 vndrie_info->ie_len);
3972 *mgmt_ie_len += vndrie_info->ie_len;
3974 curr_ie_buf += del_add_ie_buf_len;
3975 total_ie_buf_len += del_add_ie_buf_len;
3978 if (total_ie_buf_len) {
3979 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3982 brcmf_err("vndr ie set error : %d\n", err);
3986 kfree(iovar_ie_buf);
3990 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3993 BRCMF_VNDR_IE_PRBREQ_FLAG,
3994 BRCMF_VNDR_IE_PRBRSP_FLAG,
3995 BRCMF_VNDR_IE_BEACON_FLAG
3999 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4000 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4002 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4007 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4008 struct cfg80211_beacon_data *beacon)
4012 /* Set Beacon IEs to FW */
4013 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4014 beacon->tail, beacon->tail_len);
4016 brcmf_err("Set Beacon IE Failed\n");
4019 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4021 /* Set Probe Response IEs to FW */
4022 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4023 beacon->proberesp_ies,
4024 beacon->proberesp_ies_len);
4026 brcmf_err("Set Probe Resp IE Failed\n");
4028 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4034 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4035 struct cfg80211_ap_settings *settings)
4038 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4039 struct brcmf_if *ifp = netdev_priv(ndev);
4040 const struct brcmf_tlv *ssid_ie;
4041 const struct brcmf_tlv *country_ie;
4042 struct brcmf_ssid_le ssid_le;
4044 const struct brcmf_tlv *rsn_ie;
4045 const struct brcmf_vs_tlv *wpa_ie;
4046 struct brcmf_join_params join_params;
4047 enum nl80211_iftype dev_role;
4048 struct brcmf_fil_bss_enable_le bss_enable;
4053 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4054 settings->chandef.chan->hw_value,
4055 settings->chandef.center_freq1, settings->chandef.width,
4056 settings->beacon_interval, settings->dtim_period);
4057 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4058 settings->ssid, settings->ssid_len, settings->auth_type,
4059 settings->inactivity_timeout);
4060 dev_role = ifp->vif->wdev.iftype;
4061 mbss = ifp->vif->mbss;
4063 /* store current 11d setting */
4064 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4065 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4066 settings->beacon.tail_len,
4068 is_11d = country_ie ? 1 : 0;
4070 memset(&ssid_le, 0, sizeof(ssid_le));
4071 if (settings->ssid == NULL || settings->ssid_len == 0) {
4072 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4073 ssid_ie = brcmf_parse_tlvs(
4074 (u8 *)&settings->beacon.head[ie_offset],
4075 settings->beacon.head_len - ie_offset,
4080 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4081 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4082 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4084 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4085 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4089 brcmf_set_mpc(ifp, 0);
4090 brcmf_configure_arp_offload(ifp, false);
4093 /* find the RSN_IE */
4094 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4095 settings->beacon.tail_len, WLAN_EID_RSN);
4097 /* find the WPA_IE */
4098 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4099 settings->beacon.tail_len);
4101 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4102 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4103 if (wpa_ie != NULL) {
4105 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4109 struct brcmf_vs_tlv *tmp_ie;
4111 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4114 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4119 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4120 brcmf_configure_opensecurity(ifp);
4123 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4126 chanspec = chandef_to_chanspec(&cfg->d11inf,
4127 &settings->chandef);
4128 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4130 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4135 if (is_11d != ifp->vif->is_11d) {
4136 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4139 brcmf_err("Regulatory Set Error, %d\n", err);
4143 if (settings->beacon_interval) {
4144 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4145 settings->beacon_interval);
4147 brcmf_err("Beacon Interval Set Error, %d\n",
4152 if (settings->dtim_period) {
4153 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4154 settings->dtim_period);
4156 brcmf_err("DTIM Interval Set Error, %d\n", err);
4161 if (dev_role == NL80211_IFTYPE_AP) {
4162 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4164 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4167 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4170 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4172 brcmf_err("SET INFRA error %d\n", err);
4175 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4176 /* Multiple-BSS should use same 11d configuration */
4180 if (dev_role == NL80211_IFTYPE_AP) {
4181 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4182 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4184 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4186 brcmf_err("setting AP mode failed %d\n", err);
4189 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4191 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4194 /* On DOWN the firmware removes the WEP keys, reconfigure
4195 * them if they were set.
4197 brcmf_cfg80211_reconfigure_wep(ifp);
4199 memset(&join_params, 0, sizeof(join_params));
4200 /* join parameters starts with ssid */
4201 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4203 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4204 &join_params, sizeof(join_params));
4206 brcmf_err("SET SSID error (%d)\n", err);
4209 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4211 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4214 brcmf_err("setting ssid failed %d\n", err);
4217 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4218 bss_enable.enable = cpu_to_le32(1);
4219 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4220 sizeof(bss_enable));
4222 brcmf_err("bss_enable config failed %d\n", err);
4226 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4228 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4229 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4232 if ((err) && (!mbss)) {
4233 brcmf_set_mpc(ifp, 1);
4234 brcmf_configure_arp_offload(ifp, true);
4239 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4241 struct brcmf_if *ifp = netdev_priv(ndev);
4243 struct brcmf_fil_bss_enable_le bss_enable;
4244 struct brcmf_join_params join_params;
4246 brcmf_dbg(TRACE, "Enter\n");
4248 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4249 /* Due to most likely deauths outstanding we sleep */
4250 /* first to make sure they get processed by fw. */
4253 if (ifp->vif->mbss) {
4254 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4258 memset(&join_params, 0, sizeof(join_params));
4259 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4260 &join_params, sizeof(join_params));
4262 brcmf_err("SET SSID error (%d)\n", err);
4263 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4265 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4266 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4268 brcmf_err("setting AP mode failed %d\n", err);
4269 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4271 brcmf_err("setting INFRA mode failed %d\n", err);
4272 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4273 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4274 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4277 brcmf_err("restoring REGULATORY setting failed %d\n",
4279 /* Bring device back up so it can be used again */
4280 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4282 brcmf_err("BRCMF_C_UP error %d\n", err);
4284 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4285 bss_enable.enable = cpu_to_le32(0);
4286 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4287 sizeof(bss_enable));
4289 brcmf_err("bss_enable config failed %d\n", err);
4291 brcmf_set_mpc(ifp, 1);
4292 brcmf_configure_arp_offload(ifp, true);
4293 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4294 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4300 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4301 struct cfg80211_beacon_data *info)
4303 struct brcmf_if *ifp = netdev_priv(ndev);
4306 brcmf_dbg(TRACE, "Enter\n");
4308 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4314 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4315 struct station_del_parameters *params)
4317 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4318 struct brcmf_scb_val_le scbval;
4319 struct brcmf_if *ifp = netdev_priv(ndev);
4325 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4327 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4328 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4329 if (!check_vif_up(ifp->vif))
4332 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4333 scbval.val = cpu_to_le32(params->reason_code);
4334 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4335 &scbval, sizeof(scbval));
4337 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4339 brcmf_dbg(TRACE, "Exit\n");
4344 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4345 const u8 *mac, struct station_parameters *params)
4347 struct brcmf_if *ifp = netdev_priv(ndev);
4350 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4351 params->sta_flags_mask, params->sta_flags_set);
4353 /* Ignore all 00 MAC */
4354 if (is_zero_ether_addr(mac))
4357 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4360 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4361 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4362 (void *)mac, ETH_ALEN);
4364 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4365 (void *)mac, ETH_ALEN);
4367 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4373 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4374 struct wireless_dev *wdev,
4375 u16 frame_type, bool reg)
4377 struct brcmf_cfg80211_vif *vif;
4380 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4382 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4383 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4385 vif->mgmt_rx_reg |= BIT(mgmt_type);
4387 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4392 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4393 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4395 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4396 struct ieee80211_channel *chan = params->chan;
4397 const u8 *buf = params->buf;
4398 size_t len = params->len;
4399 const struct ieee80211_mgmt *mgmt;
4400 struct brcmf_cfg80211_vif *vif;
4404 struct brcmf_fil_action_frame_le *action_frame;
4405 struct brcmf_fil_af_params_le *af_params;
4410 brcmf_dbg(TRACE, "Enter\n");
4414 mgmt = (const struct ieee80211_mgmt *)buf;
4416 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4417 brcmf_err("Driver only allows MGMT packet type\n");
4421 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4423 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4424 /* Right now the only reason to get a probe response */
4425 /* is for p2p listen response or for p2p GO from */
4426 /* wpa_supplicant. Unfortunately the probe is send */
4427 /* on primary ndev, while dongle wants it on the p2p */
4428 /* vif. Since this is only reason for a probe */
4429 /* response to be sent, the vif is taken from cfg. */
4430 /* If ever desired to send proberesp for non p2p */
4431 /* response then data should be checked for */
4432 /* "DIRECT-". Note in future supplicant will take */
4433 /* dedicated p2p wdev to do this and then this 'hack'*/
4434 /* is not needed anymore. */
4435 ie_offset = DOT11_MGMT_HDR_LEN +
4436 DOT11_BCN_PRB_FIXED_LEN;
4437 ie_len = len - ie_offset;
4438 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4439 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4440 err = brcmf_vif_set_mgmt_ie(vif,
4441 BRCMF_VNDR_IE_PRBRSP_FLAG,
4444 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4446 } else if (ieee80211_is_action(mgmt->frame_control)) {
4447 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4448 if (af_params == NULL) {
4449 brcmf_err("unable to allocate frame\n");
4453 action_frame = &af_params->action_frame;
4454 /* Add the packet Id */
4455 action_frame->packet_id = cpu_to_le32(*cookie);
4457 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4458 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4459 /* Add the length exepted for 802.11 header */
4460 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4461 /* Add the channel. Use the one specified as parameter if any or
4462 * the current one (got from the firmware) otherwise
4465 freq = chan->center_freq;
4467 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4469 chan_nr = ieee80211_frequency_to_channel(freq);
4470 af_params->channel = cpu_to_le32(chan_nr);
4472 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4473 le16_to_cpu(action_frame->len));
4475 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4476 *cookie, le16_to_cpu(action_frame->len), freq);
4478 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4481 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4485 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4486 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4495 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4496 struct wireless_dev *wdev,
4499 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4500 struct brcmf_cfg80211_vif *vif;
4503 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4505 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4507 brcmf_err("No p2p device available for probe response\n");
4511 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4516 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4517 struct wireless_dev *wdev,
4518 enum nl80211_crit_proto_id proto,
4521 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4522 struct brcmf_cfg80211_vif *vif;
4524 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4526 /* only DHCP support for now */
4527 if (proto != NL80211_CRIT_PROTO_DHCP)
4530 /* suppress and abort scanning */
4531 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4532 brcmf_abort_scanning(cfg);
4534 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4537 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4538 struct wireless_dev *wdev)
4540 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4541 struct brcmf_cfg80211_vif *vif;
4543 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4545 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4546 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4550 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4551 const struct brcmf_event_msg *e, void *data)
4553 switch (e->reason) {
4554 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4555 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4557 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4558 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4559 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4561 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4562 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4563 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4570 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4575 case NL80211_TDLS_DISCOVERY_REQ:
4576 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4578 case NL80211_TDLS_SETUP:
4579 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4581 case NL80211_TDLS_TEARDOWN:
4582 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4585 brcmf_err("unsupported operation: %d\n", oper);
4591 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4592 struct net_device *ndev, const u8 *peer,
4593 enum nl80211_tdls_operation oper)
4595 struct brcmf_if *ifp;
4596 struct brcmf_tdls_iovar_le info;
4599 ret = brcmf_convert_nl80211_tdls_oper(oper);
4603 ifp = netdev_priv(ndev);
4604 memset(&info, 0, sizeof(info));
4605 info.mode = (u8)ret;
4607 memcpy(info.ea, peer, ETH_ALEN);
4609 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4610 &info, sizeof(info));
4612 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4617 static struct cfg80211_ops wl_cfg80211_ops = {
4618 .add_virtual_intf = brcmf_cfg80211_add_iface,
4619 .del_virtual_intf = brcmf_cfg80211_del_iface,
4620 .change_virtual_intf = brcmf_cfg80211_change_iface,
4621 .scan = brcmf_cfg80211_scan,
4622 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4623 .join_ibss = brcmf_cfg80211_join_ibss,
4624 .leave_ibss = brcmf_cfg80211_leave_ibss,
4625 .get_station = brcmf_cfg80211_get_station,
4626 .set_tx_power = brcmf_cfg80211_set_tx_power,
4627 .get_tx_power = brcmf_cfg80211_get_tx_power,
4628 .add_key = brcmf_cfg80211_add_key,
4629 .del_key = brcmf_cfg80211_del_key,
4630 .get_key = brcmf_cfg80211_get_key,
4631 .set_default_key = brcmf_cfg80211_config_default_key,
4632 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4633 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4634 .connect = brcmf_cfg80211_connect,
4635 .disconnect = brcmf_cfg80211_disconnect,
4636 .suspend = brcmf_cfg80211_suspend,
4637 .resume = brcmf_cfg80211_resume,
4638 .set_pmksa = brcmf_cfg80211_set_pmksa,
4639 .del_pmksa = brcmf_cfg80211_del_pmksa,
4640 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4641 .start_ap = brcmf_cfg80211_start_ap,
4642 .stop_ap = brcmf_cfg80211_stop_ap,
4643 .change_beacon = brcmf_cfg80211_change_beacon,
4644 .del_station = brcmf_cfg80211_del_station,
4645 .change_station = brcmf_cfg80211_change_station,
4646 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4647 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4648 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4649 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4650 .remain_on_channel = brcmf_p2p_remain_on_channel,
4651 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4652 .start_p2p_device = brcmf_p2p_start_device,
4653 .stop_p2p_device = brcmf_p2p_stop_device,
4654 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4655 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4656 .tdls_oper = brcmf_cfg80211_tdls_oper,
4659 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4660 enum nl80211_iftype type,
4663 struct brcmf_cfg80211_vif *vif_walk;
4664 struct brcmf_cfg80211_vif *vif;
4667 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4669 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4671 return ERR_PTR(-ENOMEM);
4673 vif->wdev.wiphy = cfg->wiphy;
4674 vif->wdev.iftype = type;
4676 vif->pm_block = pm_block;
4679 brcmf_init_prof(&vif->profile);
4681 if (type == NL80211_IFTYPE_AP) {
4683 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4684 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4692 list_add_tail(&vif->list, &cfg->vif_list);
4696 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4698 list_del(&vif->list);
4702 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4704 struct brcmf_cfg80211_vif *vif;
4705 struct brcmf_if *ifp;
4707 ifp = netdev_priv(ndev);
4710 brcmf_free_vif(vif);
4714 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4716 u32 event = e->event_code;
4717 u32 status = e->status;
4719 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4720 brcmf_dbg(CONN, "Processing set ssid\n");
4727 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4729 u32 event = e->event_code;
4730 u16 flags = e->flags;
4732 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4733 (event == BRCMF_E_DISASSOC_IND) ||
4734 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4735 brcmf_dbg(CONN, "Processing link down\n");
4741 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4742 const struct brcmf_event_msg *e)
4744 u32 event = e->event_code;
4745 u32 status = e->status;
4747 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4748 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4749 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4753 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4754 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4761 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4763 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4765 kfree(conn_info->req_ie);
4766 conn_info->req_ie = NULL;
4767 conn_info->req_ie_len = 0;
4768 kfree(conn_info->resp_ie);
4769 conn_info->resp_ie = NULL;
4770 conn_info->resp_ie_len = 0;
4773 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4774 struct brcmf_if *ifp)
4776 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4777 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4782 brcmf_clear_assoc_ies(cfg);
4784 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4785 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4787 brcmf_err("could not get assoc info (%d)\n", err);
4791 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4792 req_len = le32_to_cpu(assoc_info->req_len);
4793 resp_len = le32_to_cpu(assoc_info->resp_len);
4795 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4799 brcmf_err("could not get assoc req (%d)\n", err);
4802 conn_info->req_ie_len = req_len;
4804 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4807 conn_info->req_ie_len = 0;
4808 conn_info->req_ie = NULL;
4811 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4815 brcmf_err("could not get assoc resp (%d)\n", err);
4818 conn_info->resp_ie_len = resp_len;
4819 conn_info->resp_ie =
4820 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4823 conn_info->resp_ie_len = 0;
4824 conn_info->resp_ie = NULL;
4826 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4827 conn_info->req_ie_len, conn_info->resp_ie_len);
4833 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4834 struct net_device *ndev,
4835 const struct brcmf_event_msg *e)
4837 struct brcmf_if *ifp = netdev_priv(ndev);
4838 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4839 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4840 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4841 struct ieee80211_channel *notify_channel = NULL;
4842 struct ieee80211_supported_band *band;
4843 struct brcmf_bss_info_le *bi;
4844 struct brcmu_chan ch;
4849 brcmf_dbg(TRACE, "Enter\n");
4851 brcmf_get_assoc_ies(cfg, ifp);
4852 memcpy(profile->bssid, e->addr, ETH_ALEN);
4853 brcmf_update_bss_info(cfg, ifp);
4855 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4861 /* data sent to dongle has to be little endian */
4862 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4863 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4864 buf, WL_BSS_INFO_MAX);
4869 bi = (struct brcmf_bss_info_le *)(buf + 4);
4870 ch.chspec = le16_to_cpu(bi->chanspec);
4871 cfg->d11inf.decchspec(&ch);
4873 if (ch.band == BRCMU_CHAN_BAND_2G)
4874 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4876 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4878 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4879 notify_channel = ieee80211_get_channel(wiphy, freq);
4883 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4884 conn_info->req_ie, conn_info->req_ie_len,
4885 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4886 brcmf_dbg(CONN, "Report roaming result\n");
4888 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4889 brcmf_dbg(TRACE, "Exit\n");
4894 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4895 struct net_device *ndev, const struct brcmf_event_msg *e,
4898 struct brcmf_if *ifp = netdev_priv(ndev);
4899 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4900 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4902 brcmf_dbg(TRACE, "Enter\n");
4904 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4905 &ifp->vif->sme_state)) {
4907 brcmf_get_assoc_ies(cfg, ifp);
4908 memcpy(profile->bssid, e->addr, ETH_ALEN);
4909 brcmf_update_bss_info(cfg, ifp);
4910 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4911 &ifp->vif->sme_state);
4913 cfg80211_connect_result(ndev,
4914 (u8 *)profile->bssid,
4916 conn_info->req_ie_len,
4918 conn_info->resp_ie_len,
4919 completed ? WLAN_STATUS_SUCCESS :
4920 WLAN_STATUS_AUTH_TIMEOUT,
4922 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4923 completed ? "succeeded" : "failed");
4925 brcmf_dbg(TRACE, "Exit\n");
4930 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4931 struct net_device *ndev,
4932 const struct brcmf_event_msg *e, void *data)
4934 struct brcmf_if *ifp = netdev_priv(ndev);
4935 static int generation;
4936 u32 event = e->event_code;
4937 u32 reason = e->reason;
4938 struct station_info sinfo;
4940 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4941 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4942 ndev != cfg_to_ndev(cfg)) {
4943 brcmf_dbg(CONN, "AP mode link down\n");
4944 complete(&cfg->vif_disabled);
4946 brcmf_remove_interface(ifp->drvr, ifp->bssidx);
4950 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4951 (reason == BRCMF_E_STATUS_SUCCESS)) {
4952 memset(&sinfo, 0, sizeof(sinfo));
4954 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4957 sinfo.assoc_req_ies = data;
4958 sinfo.assoc_req_ies_len = e->datalen;
4960 sinfo.generation = generation;
4961 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4962 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4963 (event == BRCMF_E_DEAUTH_IND) ||
4964 (event == BRCMF_E_DEAUTH)) {
4965 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4971 brcmf_notify_connect_status(struct brcmf_if *ifp,
4972 const struct brcmf_event_msg *e, void *data)
4974 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4975 struct net_device *ndev = ifp->ndev;
4976 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4977 struct ieee80211_channel *chan;
4980 if ((e->event_code == BRCMF_E_DEAUTH) ||
4981 (e->event_code == BRCMF_E_DEAUTH_IND) ||
4982 (e->event_code == BRCMF_E_DISASSOC_IND) ||
4983 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
4984 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4987 if (brcmf_is_apmode(ifp->vif)) {
4988 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4989 } else if (brcmf_is_linkup(e)) {
4990 brcmf_dbg(CONN, "Linkup\n");
4991 if (brcmf_is_ibssmode(ifp->vif)) {
4992 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4993 memcpy(profile->bssid, e->addr, ETH_ALEN);
4994 wl_inform_ibss(cfg, ndev, e->addr);
4995 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4996 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4997 &ifp->vif->sme_state);
4998 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4999 &ifp->vif->sme_state);
5001 brcmf_bss_connect_done(cfg, ndev, e, true);
5002 } else if (brcmf_is_linkdown(e)) {
5003 brcmf_dbg(CONN, "Linkdown\n");
5004 if (!brcmf_is_ibssmode(ifp->vif)) {
5005 brcmf_bss_connect_done(cfg, ndev, e, false);
5007 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
5008 brcmf_init_prof(ndev_to_prof(ndev));
5009 if (ndev != cfg_to_ndev(cfg))
5010 complete(&cfg->vif_disabled);
5011 } else if (brcmf_is_nonetwork(cfg, e)) {
5012 if (brcmf_is_ibssmode(ifp->vif))
5013 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5014 &ifp->vif->sme_state);
5016 brcmf_bss_connect_done(cfg, ndev, e, false);
5023 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5024 const struct brcmf_event_msg *e, void *data)
5026 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5027 u32 event = e->event_code;
5028 u32 status = e->status;
5030 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5031 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5032 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5034 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5041 brcmf_notify_mic_status(struct brcmf_if *ifp,
5042 const struct brcmf_event_msg *e, void *data)
5044 u16 flags = e->flags;
5045 enum nl80211_key_type key_type;
5047 if (flags & BRCMF_EVENT_MSG_GROUP)
5048 key_type = NL80211_KEYTYPE_GROUP;
5050 key_type = NL80211_KEYTYPE_PAIRWISE;
5052 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5058 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5059 const struct brcmf_event_msg *e, void *data)
5061 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5062 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5063 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5064 struct brcmf_cfg80211_vif *vif;
5066 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
5067 ifevent->action, ifevent->flags, ifevent->ifidx,
5070 mutex_lock(&event->vif_event_lock);
5071 event->action = ifevent->action;
5074 switch (ifevent->action) {
5075 case BRCMF_E_IF_ADD:
5076 /* waiting process may have timed out */
5077 if (!cfg->vif_event.vif) {
5078 mutex_unlock(&event->vif_event_lock);
5085 vif->wdev.netdev = ifp->ndev;
5086 ifp->ndev->ieee80211_ptr = &vif->wdev;
5087 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5089 mutex_unlock(&event->vif_event_lock);
5090 wake_up(&event->vif_wq);
5093 case BRCMF_E_IF_DEL:
5094 mutex_unlock(&event->vif_event_lock);
5095 /* event may not be upon user request */
5096 if (brcmf_cfg80211_vif_event_armed(cfg))
5097 wake_up(&event->vif_wq);
5100 case BRCMF_E_IF_CHANGE:
5101 mutex_unlock(&event->vif_event_lock);
5102 wake_up(&event->vif_wq);
5106 mutex_unlock(&event->vif_event_lock);
5112 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5114 conf->frag_threshold = (u32)-1;
5115 conf->rts_threshold = (u32)-1;
5116 conf->retry_short = (u32)-1;
5117 conf->retry_long = (u32)-1;
5118 conf->tx_power = -1;
5121 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5123 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5124 brcmf_notify_connect_status);
5125 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5126 brcmf_notify_connect_status);
5127 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5128 brcmf_notify_connect_status);
5129 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5130 brcmf_notify_connect_status);
5131 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5132 brcmf_notify_connect_status);
5133 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5134 brcmf_notify_connect_status);
5135 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5136 brcmf_notify_roaming_status);
5137 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5138 brcmf_notify_mic_status);
5139 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5140 brcmf_notify_connect_status);
5141 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5142 brcmf_notify_sched_scan_results);
5143 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5144 brcmf_notify_vif_event);
5145 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5146 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5147 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5148 brcmf_p2p_notify_listen_complete);
5149 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5150 brcmf_p2p_notify_action_frame_rx);
5151 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5152 brcmf_p2p_notify_action_tx_complete);
5153 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5154 brcmf_p2p_notify_action_tx_complete);
5157 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5161 kfree(cfg->escan_ioctl_buf);
5162 cfg->escan_ioctl_buf = NULL;
5163 kfree(cfg->extra_buf);
5164 cfg->extra_buf = NULL;
5165 kfree(cfg->pmk_list);
5166 cfg->pmk_list = NULL;
5169 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5171 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5173 goto init_priv_mem_out;
5174 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5175 if (!cfg->escan_ioctl_buf)
5176 goto init_priv_mem_out;
5177 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5178 if (!cfg->extra_buf)
5179 goto init_priv_mem_out;
5180 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
5182 goto init_priv_mem_out;
5187 brcmf_deinit_priv_mem(cfg);
5192 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5196 cfg->scan_request = NULL;
5197 cfg->pwr_save = true;
5198 cfg->active_scan = true; /* we do active scan per default */
5199 cfg->dongle_up = false; /* dongle is not up yet */
5200 err = brcmf_init_priv_mem(cfg);
5203 brcmf_register_event_handlers(cfg);
5204 mutex_init(&cfg->usr_sync);
5205 brcmf_init_escan(cfg);
5206 brcmf_init_conf(cfg->conf);
5207 init_completion(&cfg->vif_disabled);
5211 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5213 cfg->dongle_up = false; /* dongle down */
5214 brcmf_abort_scanning(cfg);
5215 brcmf_deinit_priv_mem(cfg);
5218 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5220 init_waitqueue_head(&event->vif_wq);
5221 mutex_init(&event->vif_event_lock);
5225 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5228 __le32 roamtrigger[2];
5229 __le32 roam_delta[2];
5232 * Setup timeout if Beacons are lost and roam is
5233 * off to report link down
5235 if (brcmf_roamoff) {
5236 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5238 brcmf_err("bcn_timeout error (%d)\n", err);
5239 goto dongle_rom_out;
5244 * Enable/Disable built-in roaming to allow supplicant
5245 * to take care of roaming
5247 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5248 brcmf_roamoff ? "Off" : "On");
5249 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5251 brcmf_err("roam_off error (%d)\n", err);
5252 goto dongle_rom_out;
5255 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5256 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5257 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5258 (void *)roamtrigger, sizeof(roamtrigger));
5260 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5261 goto dongle_rom_out;
5264 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5265 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5266 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5267 (void *)roam_delta, sizeof(roam_delta));
5269 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5270 goto dongle_rom_out;
5278 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5279 s32 scan_unassoc_time, s32 scan_passive_time)
5283 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5286 if (err == -EOPNOTSUPP)
5287 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5289 brcmf_err("Scan assoc time error (%d)\n", err);
5290 goto dongle_scantime_out;
5292 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5295 if (err == -EOPNOTSUPP)
5296 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5298 brcmf_err("Scan unassoc time error (%d)\n", err);
5299 goto dongle_scantime_out;
5302 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5305 if (err == -EOPNOTSUPP)
5306 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5308 brcmf_err("Scan passive time error (%d)\n", err);
5309 goto dongle_scantime_out;
5312 dongle_scantime_out:
5316 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5317 struct brcmu_chan *ch)
5321 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5322 if (ch->sb == BRCMU_CHAN_SB_U) {
5323 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5324 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5325 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5327 /* It should be one of
5328 * IEEE80211_CHAN_NO_HT40 or
5329 * IEEE80211_CHAN_NO_HT40PLUS
5331 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5332 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5333 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5337 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5340 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5341 struct ieee80211_supported_band *band;
5342 struct ieee80211_channel *channel;
5343 struct wiphy *wiphy;
5344 struct brcmf_chanspec_list *list;
5345 struct brcmu_chan ch;
5353 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5358 list = (struct brcmf_chanspec_list *)pbuf;
5360 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5363 brcmf_err("get chanspecs error (%d)\n", err);
5367 wiphy = cfg_to_wiphy(cfg);
5368 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5370 for (i = 0; i < band->n_channels; i++)
5371 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5372 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5374 for (i = 0; i < band->n_channels; i++)
5375 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5377 total = le32_to_cpu(list->count);
5378 for (i = 0; i < total; i++) {
5379 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5380 cfg->d11inf.decchspec(&ch);
5382 if (ch.band == BRCMU_CHAN_BAND_2G) {
5383 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5384 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5385 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5387 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5392 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5393 ch.bw == BRCMU_CHAN_BW_40)
5395 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5396 ch.bw == BRCMU_CHAN_BW_80)
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) {
5407 channel[index].center_freq =
5408 ieee80211_channel_to_frequency(ch.chnum, band->band);
5409 channel[index].hw_value = ch.chnum;
5411 /* assuming the chanspecs order is HT20,
5412 * HT40 upper, HT40 lower, and VHT80.
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);
5419 /* enable the channel and disable other bandwidths
5420 * for now as mentioned order assure they are enabled
5421 * for subsequent chanspecs.
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",
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;
5447 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5449 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5450 struct ieee80211_supported_band *band;
5451 struct brcmf_fil_bwcap_le band_bwcap;
5452 struct brcmf_chanspec_list *list;
5456 struct brcmu_chan ch;
5460 /* verify support for bw_cap command */
5462 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5465 /* only set 2G bandwidth using bw_cap command */
5466 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5467 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5468 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5469 sizeof(band_bwcap));
5471 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5472 val = WLC_N_BW_40ALL;
5473 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5477 /* update channel info in 2G band */
5478 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5483 ch.band = BRCMU_CHAN_BAND_2G;
5484 ch.bw = BRCMU_CHAN_BW_40;
5485 ch.sb = BRCMU_CHAN_SB_NONE;
5487 cfg->d11inf.encchspec(&ch);
5489 /* pass encoded chanspec in query */
5490 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5492 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5495 brcmf_err("get chanspecs error (%d)\n", err);
5500 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5501 list = (struct brcmf_chanspec_list *)pbuf;
5502 num_chan = le32_to_cpu(list->count);
5503 for (i = 0; i < num_chan; i++) {
5504 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5505 cfg->d11inf.decchspec(&ch);
5506 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5508 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5510 for (j = 0; j < band->n_channels; j++) {
5511 if (band->channels[j].hw_value == ch.chnum)
5514 if (WARN_ON(j == band->n_channels))
5517 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5524 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5526 u32 band, mimo_bwcap;
5530 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5532 bw_cap[IEEE80211_BAND_2GHZ] = band;
5534 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5536 bw_cap[IEEE80211_BAND_5GHZ] = band;
5542 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5544 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5546 /* assume 20MHz if firmware does not give a clue */
5547 mimo_bwcap = WLC_N_BW_20ALL;
5549 switch (mimo_bwcap) {
5550 case WLC_N_BW_40ALL:
5551 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5553 case WLC_N_BW_20IN2G_40IN5G:
5554 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5556 case WLC_N_BW_20ALL:
5557 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5558 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5561 brcmf_err("invalid mimo_bw_cap value\n");
5565 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5566 u32 bw_cap[2], u32 nchain)
5568 band->ht_cap.ht_supported = true;
5569 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5570 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5571 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5573 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5574 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5575 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5576 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5577 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5578 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5581 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5586 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5587 mcs_map = (mcs_map << 2) | supp;
5589 return cpu_to_le16(mcs_map);
5592 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5593 u32 bw_cap[2], u32 nchain)
5597 /* not allowed in 2.4G band */
5598 if (band->band == IEEE80211_BAND_2GHZ)
5601 band->vht_cap.vht_supported = true;
5602 /* 80MHz is mandatory */
5603 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5604 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5605 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5606 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5608 /* all support 256-QAM */
5609 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5610 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5611 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5614 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5616 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5617 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5620 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5625 struct ieee80211_supported_band *band;
5627 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5628 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5630 brcmf_err("nmode error (%d)\n", err);
5632 brcmf_get_bwcap(ifp, bw_cap);
5634 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5635 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5636 bw_cap[IEEE80211_BAND_5GHZ]);
5638 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5640 brcmf_err("rxchain error (%d)\n", err);
5643 for (nchain = 0; rxchain; nchain++)
5644 rxchain = rxchain & (rxchain - 1);
5646 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5648 err = brcmf_construct_chaninfo(cfg, bw_cap);
5650 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5654 wiphy = cfg_to_wiphy(cfg);
5655 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5656 band = wiphy->bands[i];
5661 brcmf_update_ht_cap(band, bw_cap, nchain);
5663 brcmf_update_vht_cap(band, bw_cap, nchain);
5669 static const struct ieee80211_txrx_stypes
5670 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5671 [NL80211_IFTYPE_STATION] = {
5673 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5674 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5676 [NL80211_IFTYPE_P2P_CLIENT] = {
5678 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5679 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5681 [NL80211_IFTYPE_P2P_GO] = {
5683 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5684 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5685 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5686 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5687 BIT(IEEE80211_STYPE_AUTH >> 4) |
5688 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5689 BIT(IEEE80211_STYPE_ACTION >> 4)
5691 [NL80211_IFTYPE_P2P_DEVICE] = {
5693 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5694 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5698 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5700 struct ieee80211_iface_combination *combo = NULL;
5701 struct ieee80211_iface_limit *limits = NULL;
5702 int i = 0, max_iface_cnt;
5704 combo = kzalloc(sizeof(*combo), GFP_KERNEL);
5708 limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
5712 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5713 BIT(NL80211_IFTYPE_ADHOC) |
5714 BIT(NL80211_IFTYPE_AP);
5716 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5717 combo->num_different_channels = 2;
5719 combo->num_different_channels = 1;
5721 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
5723 limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5725 limits[i++].types = BIT(NL80211_IFTYPE_AP);
5729 limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
5730 BIT(NL80211_IFTYPE_AP);
5734 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
5735 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5736 BIT(NL80211_IFTYPE_P2P_GO) |
5737 BIT(NL80211_IFTYPE_P2P_DEVICE);
5739 limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5740 BIT(NL80211_IFTYPE_P2P_GO);
5742 limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5745 combo->max_interfaces = max_iface_cnt;
5746 combo->limits = limits;
5747 combo->n_limits = i;
5749 wiphy->iface_combinations = combo;
5750 wiphy->n_iface_combinations = 1;
5759 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5761 /* scheduled scan settings */
5762 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5763 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5764 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5765 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5769 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5770 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5771 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5772 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5773 .pattern_min_len = 1,
5774 .max_pkt_offset = 1500,
5778 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5782 wiphy->wowlan = &brcmf_wowlan_support;
5786 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5788 struct ieee80211_supported_band *band;
5793 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5794 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5795 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5797 err = brcmf_setup_ifmodes(wiphy, ifp);
5801 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5802 wiphy->cipher_suites = __wl_cipher_suites;
5803 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5804 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5805 WIPHY_FLAG_OFFCHAN_TX |
5806 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5807 WIPHY_FLAG_SUPPORTS_TDLS;
5809 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5810 wiphy->mgmt_stypes = brcmf_txrx_stypes;
5811 wiphy->max_remain_on_channel_duration = 5000;
5812 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
5813 brcmf_wiphy_pno_params(wiphy);
5815 /* vendor commands/events support */
5816 wiphy->vendor_commands = brcmf_vendor_cmds;
5817 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5819 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
5820 brcmf_wiphy_wowl_params(wiphy);
5822 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
5825 brcmf_err("could not obtain band info: err=%d\n", err);
5828 /* first entry in bandlist is number of bands */
5829 n_bands = le32_to_cpu(bandlist[0]);
5830 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
5831 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
5832 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5837 band->channels = kmemdup(&__wl_2ghz_channels,
5838 sizeof(__wl_2ghz_channels),
5840 if (!band->channels) {
5845 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
5846 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5848 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
5849 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
5854 band->channels = kmemdup(&__wl_5ghz_channels,
5855 sizeof(__wl_5ghz_channels),
5857 if (!band->channels) {
5862 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
5863 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
5866 err = brcmf_setup_wiphybands(wiphy);
5870 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5872 struct net_device *ndev;
5873 struct wireless_dev *wdev;
5874 struct brcmf_if *ifp;
5881 ndev = cfg_to_ndev(cfg);
5882 wdev = ndev->ieee80211_ptr;
5883 ifp = netdev_priv(ndev);
5885 /* make sure RF is ready for work */
5886 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5888 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5889 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5891 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5892 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5894 goto default_conf_out;
5895 brcmf_dbg(INFO, "power save set to %s\n",
5896 (power_mode ? "enabled" : "disabled"));
5898 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5900 goto default_conf_out;
5901 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5904 goto default_conf_out;
5906 brcmf_configure_arp_offload(ifp, true);
5908 cfg->dongle_up = true;
5915 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5917 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5919 return brcmf_config_dongle(ifp->drvr->config);
5922 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5924 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5927 * While going down, if associated with AP disassociate
5928 * from AP to save power
5930 if (check_vif_up(ifp->vif)) {
5931 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
5933 /* Make sure WPA_Supplicant receives all the event
5934 generated due to DISASSOC call to the fw to keep
5935 the state fw and WPA_Supplicant state consistent
5940 brcmf_abort_scanning(cfg);
5941 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5946 s32 brcmf_cfg80211_up(struct net_device *ndev)
5948 struct brcmf_if *ifp = netdev_priv(ndev);
5949 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5952 mutex_lock(&cfg->usr_sync);
5953 err = __brcmf_cfg80211_up(ifp);
5954 mutex_unlock(&cfg->usr_sync);
5959 s32 brcmf_cfg80211_down(struct net_device *ndev)
5961 struct brcmf_if *ifp = netdev_priv(ndev);
5962 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5965 mutex_lock(&cfg->usr_sync);
5966 err = __brcmf_cfg80211_down(ifp);
5967 mutex_unlock(&cfg->usr_sync);
5972 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5974 struct wireless_dev *wdev = &ifp->vif->wdev;
5976 return wdev->iftype;
5979 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
5980 unsigned long state)
5982 struct brcmf_cfg80211_vif *vif;
5984 list_for_each_entry(vif, &cfg->vif_list, list) {
5985 if (test_bit(state, &vif->sme_state))
5991 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5996 mutex_lock(&event->vif_event_lock);
5997 evt_action = event->action;
5998 mutex_unlock(&event->vif_event_lock);
5999 return evt_action == action;
6002 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6003 struct brcmf_cfg80211_vif *vif)
6005 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6007 mutex_lock(&event->vif_event_lock);
6010 mutex_unlock(&event->vif_event_lock);
6013 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6015 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6018 mutex_lock(&event->vif_event_lock);
6019 armed = event->vif != NULL;
6020 mutex_unlock(&event->vif_event_lock);
6024 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6025 u8 action, ulong timeout)
6027 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6029 return wait_event_timeout(event->vif_wq,
6030 vif_event_equals(event, action), timeout);
6033 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6034 struct regulatory_request *req)
6036 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6037 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6038 struct brcmf_fil_country_le ccreq;
6041 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6042 req->alpha2[0], req->alpha2[1]);
6044 /* ignore non-ISO3166 country codes */
6045 for (i = 0; i < sizeof(req->alpha2); i++)
6046 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6047 brcmf_err("not a ISO3166 code\n");
6050 memset(&ccreq, 0, sizeof(ccreq));
6051 ccreq.rev = cpu_to_le32(-1);
6052 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6053 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6054 brcmf_err("firmware rejected country setting\n");
6057 brcmf_setup_wiphybands(wiphy);
6060 static void brcmf_free_wiphy(struct wiphy *wiphy)
6065 if (wiphy->iface_combinations)
6066 kfree(wiphy->iface_combinations->limits);
6067 kfree(wiphy->iface_combinations);
6068 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6069 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6070 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6072 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6073 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6074 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6079 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6080 struct device *busdev)
6082 struct net_device *ndev = drvr->iflist[0]->ndev;
6083 struct brcmf_cfg80211_info *cfg;
6084 struct wiphy *wiphy;
6085 struct brcmf_cfg80211_vif *vif;
6086 struct brcmf_if *ifp;
6092 brcmf_err("ndev is invalid\n");
6096 ifp = netdev_priv(ndev);
6097 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6099 brcmf_err("Could not allocate wiphy device\n");
6102 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6103 set_wiphy_dev(wiphy, busdev);
6105 cfg = wiphy_priv(wiphy);
6108 init_vif_event(&cfg->vif_event);
6109 INIT_LIST_HEAD(&cfg->vif_list);
6111 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6116 vif->wdev.netdev = ndev;
6117 ndev->ieee80211_ptr = &vif->wdev;
6118 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6120 err = wl_init_priv(cfg);
6122 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6123 brcmf_free_vif(vif);
6128 /* determine d11 io type before wiphy setup */
6129 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6131 brcmf_err("Failed to get D11 version (%d)\n", err);
6134 cfg->d11inf.io_type = (u8)io_type;
6135 brcmu_d11_attach(&cfg->d11inf);
6137 err = brcmf_setup_wiphy(wiphy, ifp);
6141 brcmf_dbg(INFO, "Registering custom regulatory\n");
6142 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6143 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6144 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6146 /* firmware defaults to 40MHz disabled in 2G band. We signal
6147 * cfg80211 here that we do and have it decide we can enable
6148 * it. But first check if device does support 2G operation.
6150 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6151 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6152 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6154 err = wiphy_register(wiphy);
6156 brcmf_err("Could not register wiphy device (%d)\n", err);
6160 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6161 * setup 40MHz in 2GHz band and enable OBSS scanning.
6163 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6164 err = brcmf_enable_bw40_2g(cfg);
6166 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6167 BRCMF_OBSS_COEX_AUTO);
6169 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6172 err = brcmf_p2p_attach(cfg);
6174 brcmf_err("P2P initilisation failed (%d)\n", err);
6175 goto wiphy_unreg_out;
6177 err = brcmf_btcoex_attach(cfg);
6179 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6180 brcmf_p2p_detach(&cfg->p2p);
6181 goto wiphy_unreg_out;
6184 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6186 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6187 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6189 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6190 brcmf_notify_tdls_peer_event);
6196 wiphy_unregister(cfg->wiphy);
6198 wl_deinit_priv(cfg);
6199 brcmf_free_vif(vif);
6201 brcmf_free_wiphy(wiphy);
6205 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6210 brcmf_btcoex_detach(cfg);
6211 wiphy_unregister(cfg->wiphy);
6212 wl_deinit_priv(cfg);
6213 brcmf_free_wiphy(cfg->wiphy);