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"
44 #define BRCMF_SCAN_IE_LEN_MAX 2048
46 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
47 #define WPA_OUI_TYPE 1
48 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
49 #define WME_OUI_TYPE 2
50 #define WPS_OUI_TYPE 4
52 #define VS_IE_FIXED_HDR_LEN 6
53 #define WPA_IE_VERSION_LEN 2
54 #define WPA_IE_MIN_OUI_LEN 4
55 #define WPA_IE_SUITE_COUNT_LEN 2
57 #define WPA_CIPHER_NONE 0 /* None */
58 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
59 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
60 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
61 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
63 #define RSN_AKM_NONE 0 /* None (IBSS) */
64 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
65 #define RSN_AKM_PSK 2 /* Pre-shared Key */
66 #define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
67 #define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
68 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
69 #define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
70 #define RSN_CAP_MFPR_MASK BIT(6)
71 #define RSN_CAP_MFPC_MASK BIT(7)
72 #define RSN_PMKID_COUNT_LEN 2
74 #define VNDR_IE_CMD_LEN 4 /* length of the set command
75 * string :"add", "del" (+ NUL)
77 #define VNDR_IE_COUNT_OFFSET 4
78 #define VNDR_IE_PKTFLAG_OFFSET 8
79 #define VNDR_IE_VSIE_OFFSET 12
80 #define VNDR_IE_HDR_SIZE 12
81 #define VNDR_IE_PARSE_LIMIT 5
83 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
86 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
87 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
88 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
90 #define BRCMF_SCAN_CHANNEL_TIME 40
91 #define BRCMF_SCAN_UNASSOC_TIME 40
92 #define BRCMF_SCAN_PASSIVE_TIME 120
94 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
96 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
97 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
99 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
101 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
102 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
109 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
110 #define RATETAB_ENT(_rateid, _flags) \
112 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
113 .hw_value = (_rateid), \
117 static struct ieee80211_rate __wl_rates[] = {
118 RATETAB_ENT(BRCM_RATE_1M, 0),
119 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
121 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
122 RATETAB_ENT(BRCM_RATE_6M, 0),
123 RATETAB_ENT(BRCM_RATE_9M, 0),
124 RATETAB_ENT(BRCM_RATE_12M, 0),
125 RATETAB_ENT(BRCM_RATE_18M, 0),
126 RATETAB_ENT(BRCM_RATE_24M, 0),
127 RATETAB_ENT(BRCM_RATE_36M, 0),
128 RATETAB_ENT(BRCM_RATE_48M, 0),
129 RATETAB_ENT(BRCM_RATE_54M, 0),
132 #define wl_g_rates (__wl_rates + 0)
133 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
134 #define wl_a_rates (__wl_rates + 4)
135 #define wl_a_rates_size (wl_g_rates_size - 4)
137 #define CHAN2G(_channel, _freq) { \
138 .band = NL80211_BAND_2GHZ, \
139 .center_freq = (_freq), \
140 .hw_value = (_channel), \
141 .flags = IEEE80211_CHAN_DISABLED, \
142 .max_antenna_gain = 0, \
146 #define CHAN5G(_channel) { \
147 .band = NL80211_BAND_5GHZ, \
148 .center_freq = 5000 + (5 * (_channel)), \
149 .hw_value = (_channel), \
150 .flags = IEEE80211_CHAN_DISABLED, \
151 .max_antenna_gain = 0, \
155 static struct ieee80211_channel __wl_2ghz_channels[] = {
156 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
157 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
158 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
159 CHAN2G(13, 2472), CHAN2G(14, 2484)
162 static struct ieee80211_channel __wl_5ghz_channels[] = {
163 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
164 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
165 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
166 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
167 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
168 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
171 /* Band templates duplicated per wiphy. The channel info
172 * above is added to the band during setup.
174 static const struct ieee80211_supported_band __wl_band_2ghz = {
175 .band = NL80211_BAND_2GHZ,
176 .bitrates = wl_g_rates,
177 .n_bitrates = wl_g_rates_size,
180 static const struct ieee80211_supported_band __wl_band_5ghz = {
181 .band = NL80211_BAND_5GHZ,
182 .bitrates = wl_a_rates,
183 .n_bitrates = wl_a_rates_size,
186 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
187 * By default world regulatory domain defined in reg.c puts the flags
188 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
189 * With respect to these flags, wpa_supplicant doesn't * start p2p
190 * operations on 5GHz channels. All the changes in world regulatory
191 * domain are to be done here.
193 static const struct ieee80211_regdomain brcmf_regdom = {
197 /* IEEE 802.11b/g, channels 1..11 */
198 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
200 /* IEEE 802.11 channel 14 - Only JP enables
201 * this and for 802.11b only
203 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
204 /* IEEE 802.11a, channel 36..64 */
205 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
206 /* IEEE 802.11a, channel 100..165 */
207 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
210 /* Note: brcmf_cipher_suites is an array of int defining which cipher suites
211 * are supported. A pointer to this array and the number of entries is passed
212 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
213 * So the cipher suite AES_CMAC has to be the last one in the array, and when
214 * device does not support MFP then the number of suites will be decreased by 1
216 static const u32 brcmf_cipher_suites[] = {
217 WLAN_CIPHER_SUITE_WEP40,
218 WLAN_CIPHER_SUITE_WEP104,
219 WLAN_CIPHER_SUITE_TKIP,
220 WLAN_CIPHER_SUITE_CCMP,
221 /* Keep as last entry: */
222 WLAN_CIPHER_SUITE_AES_CMAC
225 /* Vendor specific ie. id = 221, oui and type defines exact ie */
226 struct brcmf_vs_tlv {
233 struct parsed_vndr_ie_info {
235 u32 ie_len; /* total length including id & length field */
236 struct brcmf_vs_tlv vndrie;
239 struct parsed_vndr_ies {
241 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
244 static u8 nl80211_band_to_fwil(enum nl80211_band band)
247 case NL80211_BAND_2GHZ:
249 case NL80211_BAND_5GHZ:
258 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
259 struct cfg80211_chan_def *ch)
261 struct brcmu_chan ch_inf;
264 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
265 ch->chan->center_freq, ch->center_freq1, ch->width);
266 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
267 primary_offset = ch->chan->center_freq - ch->center_freq1;
269 case NL80211_CHAN_WIDTH_20:
270 case NL80211_CHAN_WIDTH_20_NOHT:
271 ch_inf.bw = BRCMU_CHAN_BW_20;
272 WARN_ON(primary_offset != 0);
274 case NL80211_CHAN_WIDTH_40:
275 ch_inf.bw = BRCMU_CHAN_BW_40;
276 if (primary_offset > 0)
277 ch_inf.sb = BRCMU_CHAN_SB_U;
279 ch_inf.sb = BRCMU_CHAN_SB_L;
281 case NL80211_CHAN_WIDTH_80:
282 ch_inf.bw = BRCMU_CHAN_BW_80;
283 if (primary_offset == -30)
284 ch_inf.sb = BRCMU_CHAN_SB_LL;
285 else if (primary_offset == -10)
286 ch_inf.sb = BRCMU_CHAN_SB_LU;
287 else if (primary_offset == 10)
288 ch_inf.sb = BRCMU_CHAN_SB_UL;
290 ch_inf.sb = BRCMU_CHAN_SB_UU;
292 case NL80211_CHAN_WIDTH_80P80:
293 case NL80211_CHAN_WIDTH_160:
294 case NL80211_CHAN_WIDTH_5:
295 case NL80211_CHAN_WIDTH_10:
299 switch (ch->chan->band) {
300 case NL80211_BAND_2GHZ:
301 ch_inf.band = BRCMU_CHAN_BAND_2G;
303 case NL80211_BAND_5GHZ:
304 ch_inf.band = BRCMU_CHAN_BAND_5G;
306 case NL80211_BAND_60GHZ:
310 d11inf->encchspec(&ch_inf);
312 return ch_inf.chspec;
315 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
316 struct ieee80211_channel *ch)
318 struct brcmu_chan ch_inf;
320 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
321 ch_inf.bw = BRCMU_CHAN_BW_20;
322 d11inf->encchspec(&ch_inf);
324 return ch_inf.chspec;
327 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
328 * triples, returning a pointer to the substring whose first element
331 const struct brcmf_tlv *
332 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
334 const struct brcmf_tlv *elt = buf;
337 /* find tagged parameter */
338 while (totlen >= TLV_HDR_LEN) {
341 /* validate remaining totlen */
342 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
345 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
346 totlen -= (len + TLV_HDR_LEN);
352 /* Is any of the tlvs the expected entry? If
353 * not update the tlvs buffer pointer/length.
356 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
357 const u8 *oui, u32 oui_len, u8 type)
359 /* If the contents match the OUI and the type */
360 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
361 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
362 type == ie[TLV_BODY_OFF + oui_len]) {
368 /* point to the next ie */
369 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
370 /* calculate the length of the rest of the buffer */
371 *tlvs_len -= (int)(ie - *tlvs);
372 /* update the pointer to the start of the buffer */
378 static struct brcmf_vs_tlv *
379 brcmf_find_wpaie(const u8 *parse, u32 len)
381 const struct brcmf_tlv *ie;
383 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
384 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
385 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
386 return (struct brcmf_vs_tlv *)ie;
391 static struct brcmf_vs_tlv *
392 brcmf_find_wpsie(const u8 *parse, u32 len)
394 const struct brcmf_tlv *ie;
396 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
397 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
398 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
399 return (struct brcmf_vs_tlv *)ie;
404 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
405 struct brcmf_cfg80211_vif *vif,
406 enum nl80211_iftype new_type)
408 struct brcmf_cfg80211_vif *pos;
409 bool check_combos = false;
411 struct iface_combination_params params = {
412 .num_different_channels = 1,
415 list_for_each_entry(pos, &cfg->vif_list, list)
417 params.iftype_num[new_type]++;
419 /* concurrent interfaces so need check combinations */
421 params.iftype_num[pos->wdev.iftype]++;
425 ret = cfg80211_check_combinations(cfg->wiphy, ¶ms);
430 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
431 enum nl80211_iftype new_type)
433 struct brcmf_cfg80211_vif *pos;
434 struct iface_combination_params params = {
435 .num_different_channels = 1,
438 list_for_each_entry(pos, &cfg->vif_list, list)
439 params.iftype_num[pos->wdev.iftype]++;
441 params.iftype_num[new_type]++;
442 return cfg80211_check_combinations(cfg->wiphy, ¶ms);
445 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
446 struct brcmf_wsec_key_le *key_le)
448 key_le->index = cpu_to_le32(key->index);
449 key_le->len = cpu_to_le32(key->len);
450 key_le->algo = cpu_to_le32(key->algo);
451 key_le->flags = cpu_to_le32(key->flags);
452 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
453 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
454 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
455 memcpy(key_le->data, key->data, sizeof(key->data));
456 memcpy(key_le->ea, key->ea, sizeof(key->ea));
460 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
463 struct brcmf_wsec_key_le key_le;
465 convert_key_from_CPU(key, &key_le);
467 brcmf_netdev_wait_pend8021x(ifp);
469 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
473 brcmf_err("wsec_key error (%d)\n", err);
478 brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
484 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
488 /* Try to set and enable ARP offload feature, this may fail, then it */
489 /* is simply not supported and err 0 will be returned */
490 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
492 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
496 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
498 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
502 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
506 err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
508 brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
512 brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
519 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
521 struct brcmf_cfg80211_vif *vif;
522 struct brcmf_if *ifp;
524 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
527 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
528 (wdev->iftype == NL80211_IFTYPE_AP) ||
529 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
530 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
533 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
537 static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
541 for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
542 /* bsscfgidx 1 is reserved for legacy P2P */
545 if (!drvr->iflist[bsscfgidx])
552 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
554 struct brcmf_mbss_ssid_le mbss_ssid_le;
558 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
559 bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
563 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
564 mbss_ssid_le.SSID_len = cpu_to_le32(5);
565 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
567 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
568 sizeof(mbss_ssid_le));
570 brcmf_err("setting ssid failed %d\n", err);
576 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
578 * @wiphy: wiphy device of new interface.
579 * @name: name of the new interface.
581 * @params: contains mac address for AP device.
584 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
585 u32 *flags, struct vif_params *params)
587 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
588 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
589 struct brcmf_cfg80211_vif *vif;
592 if (brcmf_cfg80211_vif_event_armed(cfg))
593 return ERR_PTR(-EBUSY);
595 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
597 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP);
599 return (struct wireless_dev *)vif;
601 brcmf_cfg80211_arm_vif_event(cfg, vif);
603 err = brcmf_cfg80211_request_ap_if(ifp);
605 brcmf_cfg80211_arm_vif_event(cfg, NULL);
609 /* wait for firmware event */
610 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
611 BRCMF_VIF_EVENT_TIMEOUT);
612 brcmf_cfg80211_arm_vif_event(cfg, NULL);
614 brcmf_err("timeout occurred\n");
619 /* interface created in firmware */
622 brcmf_err("no if pointer provided\n");
627 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
628 err = brcmf_net_attach(ifp, true);
630 brcmf_err("Registering netdevice failed\n");
634 return &ifp->vif->wdev;
641 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
643 enum nl80211_iftype iftype;
645 iftype = vif->wdev.iftype;
646 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
649 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
651 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
654 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
656 unsigned char name_assign_type,
657 enum nl80211_iftype type,
659 struct vif_params *params)
661 struct wireless_dev *wdev;
664 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
665 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
667 brcmf_err("iface validation failed: err=%d\n", err);
671 case NL80211_IFTYPE_ADHOC:
672 case NL80211_IFTYPE_STATION:
673 case NL80211_IFTYPE_AP_VLAN:
674 case NL80211_IFTYPE_WDS:
675 case NL80211_IFTYPE_MONITOR:
676 case NL80211_IFTYPE_MESH_POINT:
677 return ERR_PTR(-EOPNOTSUPP);
678 case NL80211_IFTYPE_AP:
679 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
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 case NL80211_IFTYPE_UNSPECIFIED:
688 return ERR_PTR(-EINVAL);
692 brcmf_err("add iface %s type %d failed: err=%d\n",
693 name, type, (int)PTR_ERR(wdev));
695 brcmf_cfg80211_update_proto_addr_mode(wdev);
700 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
702 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
703 brcmf_set_mpc(ifp, mpc);
706 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
710 if (check_vif_up(ifp->vif)) {
711 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
713 brcmf_err("fail to set mpc\n");
716 brcmf_dbg(INFO, "MPC : %d\n", mpc);
720 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
721 struct brcmf_if *ifp, bool aborted,
724 struct brcmf_scan_params_le params_le;
725 struct cfg80211_scan_request *scan_request;
728 brcmf_dbg(SCAN, "Enter\n");
730 /* clear scan request, because the FW abort can cause a second call */
731 /* to this functon and might cause a double cfg80211_scan_done */
732 scan_request = cfg->scan_request;
733 cfg->scan_request = NULL;
735 if (timer_pending(&cfg->escan_timeout))
736 del_timer_sync(&cfg->escan_timeout);
739 /* Do a scan abort to stop the driver's scan engine */
740 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
741 memset(¶ms_le, 0, sizeof(params_le));
742 eth_broadcast_addr(params_le.bssid);
743 params_le.bss_type = DOT11_BSSTYPE_ANY;
744 params_le.scan_type = 0;
745 params_le.channel_num = cpu_to_le32(1);
746 params_le.nprobes = cpu_to_le32(1);
747 params_le.active_time = cpu_to_le32(-1);
748 params_le.passive_time = cpu_to_le32(-1);
749 params_le.home_time = cpu_to_le32(-1);
750 /* Scan is aborted by setting channel_list[0] to -1 */
751 params_le.channel_list[0] = cpu_to_le16(-1);
752 /* E-Scan (or anyother type) can be aborted by SCAN */
753 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
754 ¶ms_le, sizeof(params_le));
756 brcmf_err("Scan abort failed\n");
759 brcmf_scan_config_mpc(ifp, 1);
762 * e-scan can be initiated internally
763 * which takes precedence.
765 if (cfg->internal_escan) {
766 brcmf_dbg(SCAN, "scheduled scan completed\n");
767 cfg->internal_escan = false;
769 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
770 } else if (scan_request) {
771 struct cfg80211_scan_info info = {
775 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
776 aborted ? "Aborted" : "Done");
777 cfg80211_scan_done(scan_request, &info);
779 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
780 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
785 static int brcmf_cfg80211_del_ap_iface(struct wiphy *wiphy,
786 struct wireless_dev *wdev)
788 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
789 struct net_device *ndev = wdev->netdev;
790 struct brcmf_if *ifp = netdev_priv(ndev);
794 brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
796 err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
798 brcmf_err("interface_remove failed %d\n", err);
802 /* wait for firmware event */
803 ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
804 BRCMF_VIF_EVENT_TIMEOUT);
806 brcmf_err("timeout occurred\n");
811 brcmf_remove_interface(ifp, true);
814 brcmf_cfg80211_arm_vif_event(cfg, NULL);
819 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
821 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
822 struct net_device *ndev = wdev->netdev;
824 if (ndev && ndev == cfg_to_ndev(cfg))
827 /* vif event pending in firmware */
828 if (brcmf_cfg80211_vif_event_armed(cfg))
832 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
833 cfg->escan_info.ifp == netdev_priv(ndev))
834 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
837 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
840 switch (wdev->iftype) {
841 case NL80211_IFTYPE_ADHOC:
842 case NL80211_IFTYPE_STATION:
843 case NL80211_IFTYPE_AP_VLAN:
844 case NL80211_IFTYPE_WDS:
845 case NL80211_IFTYPE_MONITOR:
846 case NL80211_IFTYPE_MESH_POINT:
848 case NL80211_IFTYPE_AP:
849 return brcmf_cfg80211_del_ap_iface(wiphy, wdev);
850 case NL80211_IFTYPE_P2P_CLIENT:
851 case NL80211_IFTYPE_P2P_GO:
852 case NL80211_IFTYPE_P2P_DEVICE:
853 return brcmf_p2p_del_vif(wiphy, wdev);
854 case NL80211_IFTYPE_UNSPECIFIED:
862 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
863 enum nl80211_iftype type, u32 *flags,
864 struct vif_params *params)
866 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
867 struct brcmf_if *ifp = netdev_priv(ndev);
868 struct brcmf_cfg80211_vif *vif = ifp->vif;
873 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
876 /* WAR: There are a number of p2p interface related problems which
877 * need to be handled initially (before doing the validate).
878 * wpa_supplicant tends to do iface changes on p2p device/client/go
879 * which are not always possible/allowed. However we need to return
880 * OK otherwise the wpa_supplicant wont start. The situation differs
881 * on configuration and setup (p2pon=1 module param). The first check
882 * is to see if the request is a change to station for p2p iface.
884 if ((type == NL80211_IFTYPE_STATION) &&
885 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
886 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
887 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
888 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
889 /* Now depending on whether module param p2pon=1 was used the
890 * response needs to be either 0 or EOPNOTSUPP. The reason is
891 * that if p2pon=1 is used, but a newer supplicant is used then
892 * we should return an error, as this combination wont work.
893 * In other situations 0 is returned and supplicant will start
894 * normally. It will give a trace in cfg80211, but it is the
895 * only way to get it working. Unfortunately this will result
896 * in situation where we wont support new supplicant in
897 * combination with module param p2pon=1, but that is the way
898 * it is. If the user tries this then unloading of driver might
901 if (cfg->p2p.p2pdev_dynamically)
906 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
908 brcmf_err("iface validation failed: err=%d\n", err);
912 case NL80211_IFTYPE_MONITOR:
913 case NL80211_IFTYPE_WDS:
914 brcmf_err("type (%d) : currently we do not support this type\n",
917 case NL80211_IFTYPE_ADHOC:
920 case NL80211_IFTYPE_STATION:
923 case NL80211_IFTYPE_AP:
924 case NL80211_IFTYPE_P2P_GO:
933 if (type == NL80211_IFTYPE_P2P_GO) {
934 brcmf_dbg(INFO, "IF Type = P2P GO\n");
935 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
938 brcmf_dbg(INFO, "IF Type = AP\n");
941 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
943 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
947 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
950 ndev->ieee80211_ptr->iftype = type;
952 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
955 brcmf_dbg(TRACE, "Exit\n");
960 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
961 struct brcmf_scan_params_le *params_le,
962 struct cfg80211_scan_request *request)
970 struct brcmf_ssid_le ssid_le;
972 eth_broadcast_addr(params_le->bssid);
973 params_le->bss_type = DOT11_BSSTYPE_ANY;
974 params_le->scan_type = 0;
975 params_le->channel_num = 0;
976 params_le->nprobes = cpu_to_le32(-1);
977 params_le->active_time = cpu_to_le32(-1);
978 params_le->passive_time = cpu_to_le32(-1);
979 params_le->home_time = cpu_to_le32(-1);
980 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
982 /* if request is null exit so it will be all channel broadcast scan */
986 n_ssids = request->n_ssids;
987 n_channels = request->n_channels;
988 /* Copy channel array if applicable */
989 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
991 if (n_channels > 0) {
992 for (i = 0; i < n_channels; i++) {
993 chanspec = channel_to_chanspec(&cfg->d11inf,
994 request->channels[i]);
995 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
996 request->channels[i]->hw_value, chanspec);
997 params_le->channel_list[i] = cpu_to_le16(chanspec);
1000 brcmf_dbg(SCAN, "Scanning all channels\n");
1002 /* Copy ssid array if applicable */
1003 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1005 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
1006 n_channels * sizeof(u16);
1007 offset = roundup(offset, sizeof(u32));
1008 ptr = (char *)params_le + offset;
1009 for (i = 0; i < n_ssids; i++) {
1010 memset(&ssid_le, 0, sizeof(ssid_le));
1012 cpu_to_le32(request->ssids[i].ssid_len);
1013 memcpy(ssid_le.SSID, request->ssids[i].ssid,
1014 request->ssids[i].ssid_len);
1015 if (!ssid_le.SSID_len)
1016 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1018 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
1019 i, ssid_le.SSID, ssid_le.SSID_len);
1020 memcpy(ptr, &ssid_le, sizeof(ssid_le));
1021 ptr += sizeof(ssid_le);
1024 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
1025 if ((request->ssids) && request->ssids->ssid_len) {
1026 brcmf_dbg(SCAN, "SSID %s len=%d\n",
1027 params_le->ssid_le.SSID,
1028 request->ssids->ssid_len);
1029 params_le->ssid_le.SSID_len =
1030 cpu_to_le32(request->ssids->ssid_len);
1031 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
1032 request->ssids->ssid_len);
1035 /* Adding mask to channel numbers */
1036 params_le->channel_num =
1037 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1038 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1042 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1043 struct cfg80211_scan_request *request)
1045 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1046 offsetof(struct brcmf_escan_params_le, params_le);
1047 struct brcmf_escan_params_le *params;
1050 brcmf_dbg(SCAN, "E-SCAN START\n");
1052 if (request != NULL) {
1053 /* Allocate space for populating ssids in struct */
1054 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1056 /* Allocate space for populating ssids in struct */
1057 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1060 params = kzalloc(params_size, GFP_KERNEL);
1065 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1066 brcmf_escan_prep(cfg, ¶ms->params_le, request);
1067 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1068 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1069 params->sync_id = cpu_to_le16(0x1234);
1071 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1074 brcmf_dbg(INFO, "system busy : escan canceled\n");
1076 brcmf_err("error (%d)\n", err);
1085 brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1087 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1090 struct brcmf_scan_results *results;
1091 struct escan_info *escan = &cfg->escan_info;
1093 brcmf_dbg(SCAN, "Enter\n");
1095 escan->wiphy = cfg->wiphy;
1096 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1097 passive_scan = cfg->active_scan ? 0 : 1;
1098 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1101 brcmf_err("error (%d)\n", err);
1104 brcmf_scan_config_mpc(ifp, 0);
1105 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1106 results->version = 0;
1108 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1110 err = escan->run(cfg, ifp, request);
1112 brcmf_scan_config_mpc(ifp, 1);
1117 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1118 struct cfg80211_scan_request *request,
1119 struct cfg80211_ssid *this_ssid)
1121 struct brcmf_if *ifp = vif->ifp;
1122 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1123 struct cfg80211_ssid *ssids;
1128 struct brcmf_ssid_le ssid_le;
1131 brcmf_dbg(SCAN, "START ESCAN\n");
1133 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1134 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1137 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1138 brcmf_err("Scanning being aborted: status (%lu)\n",
1142 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1143 brcmf_err("Scanning suppressed: status (%lu)\n",
1147 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1148 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1152 /* If scan req comes for p2p0, send it over primary I/F */
1153 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1154 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1159 ssids = request->ssids;
1163 /* we don't do escan in ibss */
1167 cfg->scan_request = request;
1168 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1170 cfg->escan_info.run = brcmf_run_escan;
1171 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1175 err = brcmf_do_escan(vif->ifp, request);
1179 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1180 ssids->ssid, ssids->ssid_len);
1181 memset(&ssid_le, 0, sizeof(ssid_le));
1182 SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len);
1183 ssid_le.SSID_len = cpu_to_le32(0);
1186 memcpy(ssid_le.SSID, ssids->ssid, SSID_len);
1187 ssid_le.SSID_len = cpu_to_le32(SSID_len);
1190 brcmf_dbg(SCAN, "Broadcast scan\n");
1192 passive_scan = cfg->active_scan ? 0 : 1;
1193 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1196 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1199 brcmf_scan_config_mpc(ifp, 0);
1200 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le,
1204 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1207 brcmf_err("WLC_SCAN error (%d)\n", err);
1209 brcmf_scan_config_mpc(ifp, 1);
1214 /* Arm scan timeout timer */
1215 mod_timer(&cfg->escan_timeout, jiffies +
1216 BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1221 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1222 cfg->scan_request = NULL;
1227 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1229 struct brcmf_cfg80211_vif *vif;
1232 brcmf_dbg(TRACE, "Enter\n");
1233 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1234 if (!check_vif_up(vif))
1237 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1240 brcmf_err("scan error (%d)\n", err);
1242 brcmf_dbg(TRACE, "Exit\n");
1246 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1250 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1253 brcmf_err("Error (%d)\n", err);
1258 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1262 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1265 brcmf_err("Error (%d)\n", err);
1270 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1273 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1275 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1277 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1283 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1285 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1286 struct net_device *ndev = cfg_to_ndev(cfg);
1287 struct brcmf_if *ifp = netdev_priv(ndev);
1290 brcmf_dbg(TRACE, "Enter\n");
1291 if (!check_vif_up(ifp->vif))
1294 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1295 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1296 cfg->conf->rts_threshold = wiphy->rts_threshold;
1297 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1301 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1302 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1303 cfg->conf->frag_threshold = wiphy->frag_threshold;
1304 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1308 if (changed & WIPHY_PARAM_RETRY_LONG
1309 && (cfg->conf->retry_long != wiphy->retry_long)) {
1310 cfg->conf->retry_long = wiphy->retry_long;
1311 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1315 if (changed & WIPHY_PARAM_RETRY_SHORT
1316 && (cfg->conf->retry_short != wiphy->retry_short)) {
1317 cfg->conf->retry_short = wiphy->retry_short;
1318 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1324 brcmf_dbg(TRACE, "Exit\n");
1328 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1330 memset(prof, 0, sizeof(*prof));
1333 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1337 switch (e->event_code) {
1338 case BRCMF_E_DEAUTH:
1339 case BRCMF_E_DEAUTH_IND:
1340 case BRCMF_E_DISASSOC_IND:
1351 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1353 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1356 brcmf_dbg(TRACE, "Enter\n");
1358 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1359 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1360 err = brcmf_fil_cmd_data_set(vif->ifp,
1361 BRCMF_C_DISASSOC, NULL, 0);
1363 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1365 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1366 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1367 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1370 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1371 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1372 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1373 brcmf_dbg(TRACE, "Exit\n");
1377 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1378 struct cfg80211_ibss_params *params)
1380 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1381 struct brcmf_if *ifp = netdev_priv(ndev);
1382 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1383 struct brcmf_join_params join_params;
1384 size_t join_params_size = 0;
1391 brcmf_dbg(TRACE, "Enter\n");
1392 if (!check_vif_up(ifp->vif))
1396 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1398 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1402 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1405 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1407 brcmf_dbg(CONN, "No BSSID specified\n");
1409 if (params->chandef.chan)
1410 brcmf_dbg(CONN, "channel: %d\n",
1411 params->chandef.chan->center_freq);
1413 brcmf_dbg(CONN, "no channel specified\n");
1415 if (params->channel_fixed)
1416 brcmf_dbg(CONN, "fixed channel required\n");
1418 brcmf_dbg(CONN, "no fixed channel required\n");
1420 if (params->ie && params->ie_len)
1421 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1423 brcmf_dbg(CONN, "no ie specified\n");
1425 if (params->beacon_interval)
1426 brcmf_dbg(CONN, "beacon interval: %d\n",
1427 params->beacon_interval);
1429 brcmf_dbg(CONN, "no beacon interval specified\n");
1431 if (params->basic_rates)
1432 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1434 brcmf_dbg(CONN, "no basic rates specified\n");
1436 if (params->privacy)
1437 brcmf_dbg(CONN, "privacy required\n");
1439 brcmf_dbg(CONN, "no privacy required\n");
1441 /* Configure Privacy for starter */
1442 if (params->privacy)
1443 wsec |= WEP_ENABLED;
1445 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1447 brcmf_err("wsec failed (%d)\n", err);
1451 /* Configure Beacon Interval for starter */
1452 if (params->beacon_interval)
1453 bcnprd = params->beacon_interval;
1457 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1459 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1463 /* Configure required join parameter */
1464 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1467 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1468 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1469 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1470 join_params_size = sizeof(join_params.ssid_le);
1473 if (params->bssid) {
1474 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1475 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1476 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1478 eth_broadcast_addr(join_params.params_le.bssid);
1479 eth_zero_addr(profile->bssid);
1483 if (params->chandef.chan) {
1487 ieee80211_frequency_to_channel(
1488 params->chandef.chan->center_freq);
1489 if (params->channel_fixed) {
1490 /* adding chanspec */
1491 chanspec = chandef_to_chanspec(&cfg->d11inf,
1493 join_params.params_le.chanspec_list[0] =
1494 cpu_to_le16(chanspec);
1495 join_params.params_le.chanspec_num = cpu_to_le32(1);
1496 join_params_size += sizeof(join_params.params_le);
1499 /* set channel for starter */
1500 target_channel = cfg->channel;
1501 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1504 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1510 cfg->ibss_starter = false;
1513 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1514 &join_params, join_params_size);
1516 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1522 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1523 brcmf_dbg(TRACE, "Exit\n");
1528 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1530 struct brcmf_if *ifp = netdev_priv(ndev);
1532 brcmf_dbg(TRACE, "Enter\n");
1533 if (!check_vif_up(ifp->vif)) {
1534 /* When driver is being unloaded, it can end up here. If an
1535 * error is returned then later on a debug trace in the wireless
1536 * core module will be printed. To avoid this 0 is returned.
1541 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1542 brcmf_net_setcarrier(ifp, false);
1544 brcmf_dbg(TRACE, "Exit\n");
1549 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1550 struct cfg80211_connect_params *sme)
1552 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1553 struct brcmf_cfg80211_security *sec;
1557 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1558 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1559 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1560 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1562 val = WPA_AUTH_DISABLED;
1563 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1564 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1566 brcmf_err("set wpa_auth failed (%d)\n", err);
1569 sec = &profile->sec;
1570 sec->wpa_versions = sme->crypto.wpa_versions;
1574 static s32 brcmf_set_auth_type(struct net_device *ndev,
1575 struct cfg80211_connect_params *sme)
1577 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1578 struct brcmf_cfg80211_security *sec;
1582 switch (sme->auth_type) {
1583 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1585 brcmf_dbg(CONN, "open system\n");
1587 case NL80211_AUTHTYPE_SHARED_KEY:
1589 brcmf_dbg(CONN, "shared key\n");
1593 brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
1597 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1599 brcmf_err("set auth failed (%d)\n", err);
1602 sec = &profile->sec;
1603 sec->auth_type = sme->auth_type;
1608 brcmf_set_wsec_mode(struct net_device *ndev,
1609 struct cfg80211_connect_params *sme)
1611 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1612 struct brcmf_cfg80211_security *sec;
1618 if (sme->crypto.n_ciphers_pairwise) {
1619 switch (sme->crypto.ciphers_pairwise[0]) {
1620 case WLAN_CIPHER_SUITE_WEP40:
1621 case WLAN_CIPHER_SUITE_WEP104:
1624 case WLAN_CIPHER_SUITE_TKIP:
1625 pval = TKIP_ENABLED;
1627 case WLAN_CIPHER_SUITE_CCMP:
1630 case WLAN_CIPHER_SUITE_AES_CMAC:
1634 brcmf_err("invalid cipher pairwise (%d)\n",
1635 sme->crypto.ciphers_pairwise[0]);
1639 if (sme->crypto.cipher_group) {
1640 switch (sme->crypto.cipher_group) {
1641 case WLAN_CIPHER_SUITE_WEP40:
1642 case WLAN_CIPHER_SUITE_WEP104:
1645 case WLAN_CIPHER_SUITE_TKIP:
1646 gval = TKIP_ENABLED;
1648 case WLAN_CIPHER_SUITE_CCMP:
1651 case WLAN_CIPHER_SUITE_AES_CMAC:
1655 brcmf_err("invalid cipher group (%d)\n",
1656 sme->crypto.cipher_group);
1661 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1662 /* In case of privacy, but no security and WPS then simulate */
1663 /* setting AES. WPS-2.0 allows no security */
1664 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1669 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1671 brcmf_err("error (%d)\n", err);
1675 sec = &profile->sec;
1676 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1677 sec->cipher_group = sme->crypto.cipher_group;
1683 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1685 struct brcmf_if *ifp = netdev_priv(ndev);
1688 const struct brcmf_tlv *rsn_ie;
1696 if (!sme->crypto.n_akm_suites)
1699 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev), "wpa_auth", &val);
1701 brcmf_err("could not get wpa_auth (%d)\n", err);
1704 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1705 switch (sme->crypto.akm_suites[0]) {
1706 case WLAN_AKM_SUITE_8021X:
1707 val = WPA_AUTH_UNSPECIFIED;
1709 case WLAN_AKM_SUITE_PSK:
1713 brcmf_err("invalid cipher group (%d)\n",
1714 sme->crypto.cipher_group);
1717 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1718 switch (sme->crypto.akm_suites[0]) {
1719 case WLAN_AKM_SUITE_8021X:
1720 val = WPA2_AUTH_UNSPECIFIED;
1722 case WLAN_AKM_SUITE_8021X_SHA256:
1723 val = WPA2_AUTH_1X_SHA256;
1725 case WLAN_AKM_SUITE_PSK_SHA256:
1726 val = WPA2_AUTH_PSK_SHA256;
1728 case WLAN_AKM_SUITE_PSK:
1729 val = WPA2_AUTH_PSK;
1732 brcmf_err("invalid cipher group (%d)\n",
1733 sme->crypto.cipher_group);
1738 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
1739 goto skip_mfp_config;
1740 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
1741 * IE will not be verified, just a quick search for MFP config
1743 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
1746 goto skip_mfp_config;
1747 ie = (const u8 *)rsn_ie;
1748 ie_len = rsn_ie->len + TLV_HDR_LEN;
1749 /* Skip unicast suite */
1750 offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
1751 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1752 goto skip_mfp_config;
1753 /* Skip multicast suite */
1754 count = ie[offset] + (ie[offset + 1] << 8);
1755 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1756 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
1757 goto skip_mfp_config;
1758 /* Skip auth key management suite(s) */
1759 count = ie[offset] + (ie[offset + 1] << 8);
1760 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
1761 if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
1762 goto skip_mfp_config;
1763 /* Ready to read capabilities */
1764 mfp = BRCMF_MFP_NONE;
1765 rsn_cap = ie[offset] + (ie[offset + 1] << 8);
1766 if (rsn_cap & RSN_CAP_MFPR_MASK)
1767 mfp = BRCMF_MFP_REQUIRED;
1768 else if (rsn_cap & RSN_CAP_MFPC_MASK)
1769 mfp = BRCMF_MFP_CAPABLE;
1770 brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
1773 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1774 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1776 brcmf_err("could not set wpa_auth (%d)\n", err);
1784 brcmf_set_sharedkey(struct net_device *ndev,
1785 struct cfg80211_connect_params *sme)
1787 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1788 struct brcmf_cfg80211_security *sec;
1789 struct brcmf_wsec_key key;
1793 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1795 if (sme->key_len == 0)
1798 sec = &profile->sec;
1799 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1800 sec->wpa_versions, sec->cipher_pairwise);
1802 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1805 if (!(sec->cipher_pairwise &
1806 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1809 memset(&key, 0, sizeof(key));
1810 key.len = (u32) sme->key_len;
1811 key.index = (u32) sme->key_idx;
1812 if (key.len > sizeof(key.data)) {
1813 brcmf_err("Too long key length (%u)\n", key.len);
1816 memcpy(key.data, sme->key, key.len);
1817 key.flags = BRCMF_PRIMARY_KEY;
1818 switch (sec->cipher_pairwise) {
1819 case WLAN_CIPHER_SUITE_WEP40:
1820 key.algo = CRYPTO_ALGO_WEP1;
1822 case WLAN_CIPHER_SUITE_WEP104:
1823 key.algo = CRYPTO_ALGO_WEP128;
1826 brcmf_err("Invalid algorithm (%d)\n",
1827 sme->crypto.ciphers_pairwise[0]);
1830 /* Set the new key/index */
1831 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1832 key.len, key.index, key.algo);
1833 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1834 err = send_key_to_dongle(netdev_priv(ndev), &key);
1838 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1839 brcmf_dbg(CONN, "set auth_type to shared key\n");
1840 val = WL_AUTH_SHARED_KEY; /* shared key */
1841 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1843 brcmf_err("set auth failed (%d)\n", err);
1849 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1850 enum nl80211_auth_type type)
1852 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1853 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1854 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1855 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1860 static void brcmf_set_join_pref(struct brcmf_if *ifp,
1861 struct cfg80211_bss_selection *bss_select)
1863 struct brcmf_join_pref_params join_pref_params[2];
1864 enum nl80211_band band;
1867 join_pref_params[i].len = 2;
1868 join_pref_params[i].rssi_gain = 0;
1870 if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
1871 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
1873 switch (bss_select->behaviour) {
1874 case __NL80211_BSS_SELECT_ATTR_INVALID:
1875 brcmf_c_set_joinpref_default(ifp);
1877 case NL80211_BSS_SELECT_ATTR_BAND_PREF:
1878 join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
1879 band = bss_select->param.band_pref;
1880 join_pref_params[i].band = nl80211_band_to_fwil(band);
1883 case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
1884 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
1885 band = bss_select->param.adjust.band;
1886 join_pref_params[i].band = nl80211_band_to_fwil(band);
1887 join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
1890 case NL80211_BSS_SELECT_ATTR_RSSI:
1894 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
1895 join_pref_params[i].len = 2;
1896 join_pref_params[i].rssi_gain = 0;
1897 join_pref_params[i].band = 0;
1898 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
1899 sizeof(join_pref_params));
1901 brcmf_err("Set join_pref error (%d)\n", err);
1905 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1906 struct cfg80211_connect_params *sme)
1908 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1909 struct brcmf_if *ifp = netdev_priv(ndev);
1910 struct ieee80211_channel *chan = sme->channel;
1911 struct brcmf_join_params join_params;
1912 size_t join_params_size;
1913 const struct brcmf_tlv *rsn_ie;
1914 const struct brcmf_vs_tlv *wpa_ie;
1917 struct brcmf_ext_join_params_le *ext_join_params;
1922 brcmf_dbg(TRACE, "Enter\n");
1923 if (!check_vif_up(ifp->vif))
1927 brcmf_err("Invalid ssid\n");
1931 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1932 /* A normal (non P2P) connection request setup. */
1935 /* find the WPA_IE */
1936 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1939 ie_len = wpa_ie->len + TLV_HDR_LEN;
1941 /* find the RSN_IE */
1942 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1947 ie_len = rsn_ie->len + TLV_HDR_LEN;
1950 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1953 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1954 sme->ie, sme->ie_len);
1956 brcmf_err("Set Assoc REQ IE Failed\n");
1958 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1960 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1964 ieee80211_frequency_to_channel(chan->center_freq);
1965 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1966 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1967 cfg->channel, chan->center_freq, chanspec);
1973 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1975 err = brcmf_set_wpa_version(ndev, sme);
1977 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1981 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1982 err = brcmf_set_auth_type(ndev, sme);
1984 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1988 err = brcmf_set_wsec_mode(ndev, sme);
1990 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1994 err = brcmf_set_key_mgmt(ndev, sme);
1996 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
2000 err = brcmf_set_sharedkey(ndev, sme);
2002 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
2006 /* Join with specific BSSID and cached SSID
2007 * If SSID is zero join based on BSSID only
2009 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2010 offsetof(struct brcmf_assoc_params_le, chanspec_list);
2012 join_params_size += sizeof(u16);
2013 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
2014 if (ext_join_params == NULL) {
2018 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2019 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2020 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2021 if (ssid_len < IEEE80211_MAX_SSID_LEN)
2022 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2023 ext_join_params->ssid_le.SSID, ssid_len);
2025 /* Set up join scan parameters */
2026 ext_join_params->scan_le.scan_type = -1;
2027 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2030 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2032 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2035 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2037 ext_join_params->assoc_le.chanspec_list[0] =
2038 cpu_to_le16(chanspec);
2039 /* Increase dwell time to receive probe response or detect
2040 * beacon from target AP at a noisy air only during connect
2043 ext_join_params->scan_le.active_time =
2044 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2045 ext_join_params->scan_le.passive_time =
2046 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2047 /* To sync with presence period of VSDB GO send probe request
2048 * more frequently. Probe request will be stopped when it gets
2049 * probe response from target AP/GO.
2051 ext_join_params->scan_le.nprobes =
2052 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2053 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2055 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2056 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2057 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2060 brcmf_set_join_pref(ifp, &sme->bss_select);
2062 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2064 kfree(ext_join_params);
2066 /* This is it. join command worked, we are done */
2069 /* join command failed, fallback to set ssid */
2070 memset(&join_params, 0, sizeof(join_params));
2071 join_params_size = sizeof(join_params.ssid_le);
2073 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2074 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2077 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2079 eth_broadcast_addr(join_params.params_le.bssid);
2082 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2083 join_params.params_le.chanspec_num = cpu_to_le32(1);
2084 join_params_size += sizeof(join_params.params_le);
2086 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2087 &join_params, join_params_size);
2089 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
2093 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2094 brcmf_dbg(TRACE, "Exit\n");
2099 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2102 struct brcmf_if *ifp = netdev_priv(ndev);
2103 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2104 struct brcmf_scb_val_le scbval;
2107 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2108 if (!check_vif_up(ifp->vif))
2111 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2112 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2113 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2115 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2116 scbval.val = cpu_to_le32(reason_code);
2117 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2118 &scbval, sizeof(scbval));
2120 brcmf_err("error (%d)\n", err);
2122 brcmf_dbg(TRACE, "Exit\n");
2127 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2128 enum nl80211_tx_power_setting type, s32 mbm)
2130 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2131 struct net_device *ndev = cfg_to_ndev(cfg);
2132 struct brcmf_if *ifp = netdev_priv(ndev);
2137 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2138 if (!check_vif_up(ifp->vif))
2142 case NL80211_TX_POWER_AUTOMATIC:
2144 case NL80211_TX_POWER_LIMITED:
2145 case NL80211_TX_POWER_FIXED:
2147 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2151 qdbm = MBM_TO_DBM(4 * mbm);
2154 qdbm |= WL_TXPWR_OVERRIDE;
2157 brcmf_err("Unsupported type %d\n", type);
2161 /* Make sure radio is off or on as far as software is concerned */
2162 disable = WL_RADIO_SW_DISABLE << 16;
2163 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2165 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2167 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2169 brcmf_err("qtxpower error (%d)\n", err);
2172 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2177 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2180 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2181 struct net_device *ndev = cfg_to_ndev(cfg);
2182 struct brcmf_if *ifp = netdev_priv(ndev);
2186 brcmf_dbg(TRACE, "Enter\n");
2187 if (!check_vif_up(ifp->vif))
2190 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
2192 brcmf_err("error (%d)\n", err);
2195 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2198 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2203 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2204 u8 key_idx, bool unicast, bool multicast)
2206 struct brcmf_if *ifp = netdev_priv(ndev);
2211 brcmf_dbg(TRACE, "Enter\n");
2212 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2213 if (!check_vif_up(ifp->vif))
2216 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2218 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2222 if (wsec & WEP_ENABLED) {
2223 /* Just select a new current key */
2225 err = brcmf_fil_cmd_int_set(ifp,
2226 BRCMF_C_SET_KEY_PRIMARY, index);
2228 brcmf_err("error (%d)\n", err);
2231 brcmf_dbg(TRACE, "Exit\n");
2236 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2237 u8 key_idx, bool pairwise, const u8 *mac_addr)
2239 struct brcmf_if *ifp = netdev_priv(ndev);
2240 struct brcmf_wsec_key *key;
2243 brcmf_dbg(TRACE, "Enter\n");
2244 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2246 if (!check_vif_up(ifp->vif))
2249 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2250 /* we ignore this key index in this case */
2254 key = &ifp->vif->profile.key[key_idx];
2256 if (key->algo == CRYPTO_ALGO_OFF) {
2257 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2261 memset(key, 0, sizeof(*key));
2262 key->index = (u32)key_idx;
2263 key->flags = BRCMF_PRIMARY_KEY;
2265 /* Clear the key/index */
2266 err = send_key_to_dongle(ifp, key);
2268 brcmf_dbg(TRACE, "Exit\n");
2273 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2274 u8 key_idx, bool pairwise, const u8 *mac_addr,
2275 struct key_params *params)
2277 struct brcmf_if *ifp = netdev_priv(ndev);
2278 struct brcmf_wsec_key *key;
2285 brcmf_dbg(TRACE, "Enter\n");
2286 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2287 if (!check_vif_up(ifp->vif))
2290 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2291 /* we ignore this key index in this case */
2292 brcmf_err("invalid key index (%d)\n", key_idx);
2296 if (params->key_len == 0)
2297 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2300 if (params->key_len > sizeof(key->data)) {
2301 brcmf_err("Too long key length (%u)\n", params->key_len);
2306 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2307 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2308 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2312 key = &ifp->vif->profile.key[key_idx];
2313 memset(key, 0, sizeof(*key));
2314 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2315 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2316 key->len = params->key_len;
2317 key->index = key_idx;
2318 memcpy(key->data, params->key, key->len);
2320 key->flags = BRCMF_PRIMARY_KEY;
2322 switch (params->cipher) {
2323 case WLAN_CIPHER_SUITE_WEP40:
2324 key->algo = CRYPTO_ALGO_WEP1;
2326 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2328 case WLAN_CIPHER_SUITE_WEP104:
2329 key->algo = CRYPTO_ALGO_WEP128;
2331 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2333 case WLAN_CIPHER_SUITE_TKIP:
2334 if (!brcmf_is_apmode(ifp->vif)) {
2335 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2336 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2337 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2338 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2340 key->algo = CRYPTO_ALGO_TKIP;
2342 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2344 case WLAN_CIPHER_SUITE_AES_CMAC:
2345 key->algo = CRYPTO_ALGO_AES_CCM;
2347 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2349 case WLAN_CIPHER_SUITE_CCMP:
2350 key->algo = CRYPTO_ALGO_AES_CCM;
2352 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2355 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2360 err = send_key_to_dongle(ifp, key);
2364 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2366 brcmf_err("get wsec error (%d)\n", err);
2370 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2372 brcmf_err("set wsec error (%d)\n", err);
2377 brcmf_dbg(TRACE, "Exit\n");
2382 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev, u8 key_idx,
2383 bool pairwise, const u8 *mac_addr, void *cookie,
2384 void (*callback)(void *cookie,
2385 struct key_params *params))
2387 struct key_params params;
2388 struct brcmf_if *ifp = netdev_priv(ndev);
2389 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2390 struct brcmf_cfg80211_security *sec;
2394 brcmf_dbg(TRACE, "Enter\n");
2395 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2396 if (!check_vif_up(ifp->vif))
2399 memset(¶ms, 0, sizeof(params));
2401 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2403 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2404 /* Ignore this error, may happen during DISASSOC */
2408 if (wsec & WEP_ENABLED) {
2409 sec = &profile->sec;
2410 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2411 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2412 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2413 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2414 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2415 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2417 } else if (wsec & TKIP_ENABLED) {
2418 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2419 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2420 } else if (wsec & AES_ENABLED) {
2421 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2422 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2424 brcmf_err("Invalid algo (0x%x)\n", wsec);
2428 callback(cookie, ¶ms);
2431 brcmf_dbg(TRACE, "Exit\n");
2436 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2437 struct net_device *ndev, u8 key_idx)
2439 struct brcmf_if *ifp = netdev_priv(ndev);
2441 brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2443 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2446 brcmf_dbg(INFO, "Not supported\n");
2452 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2456 struct brcmf_wsec_key *key;
2459 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2460 key = &ifp->vif->profile.key[key_idx];
2461 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2462 (key->algo == CRYPTO_ALGO_WEP128))
2465 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2468 err = send_key_to_dongle(ifp, key);
2470 brcmf_err("Setting WEP key failed (%d)\n", err);
2473 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2475 brcmf_err("get wsec error (%d)\n", err);
2478 wsec |= WEP_ENABLED;
2479 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2481 brcmf_err("set wsec error (%d)\n", err);
2484 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2486 struct nl80211_sta_flag_update *sfu;
2488 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2489 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2490 sfu = &si->sta_flags;
2491 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2492 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2493 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2494 BIT(NL80211_STA_FLAG_AUTHORIZED);
2495 if (fw_sta_flags & BRCMF_STA_WME)
2496 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2497 if (fw_sta_flags & BRCMF_STA_AUTHE)
2498 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2499 if (fw_sta_flags & BRCMF_STA_ASSOC)
2500 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2501 if (fw_sta_flags & BRCMF_STA_AUTHO)
2502 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2505 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2509 struct brcmf_bss_info_le bss_le;
2514 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2518 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2519 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2522 brcmf_err("Failed to get bss info (%d)\n", err);
2525 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2526 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2527 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2528 capability = le16_to_cpu(buf->bss_le.capability);
2529 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2530 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2531 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2532 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2533 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2534 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2541 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2542 struct station_info *sinfo)
2544 struct brcmf_scb_val_le scbval;
2545 struct brcmf_pktcnt_le pktcnt;
2550 /* Get the current tx rate */
2551 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2553 brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err);
2556 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2557 sinfo->txrate.legacy = rate * 5;
2559 memset(&scbval, 0, sizeof(scbval));
2560 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2563 brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err);
2566 rssi = le32_to_cpu(scbval.val);
2567 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2568 sinfo->signal = rssi;
2570 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2573 brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2576 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
2577 BIT(NL80211_STA_INFO_RX_DROP_MISC) |
2578 BIT(NL80211_STA_INFO_TX_PACKETS) |
2579 BIT(NL80211_STA_INFO_TX_FAILED);
2580 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2581 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2582 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2583 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
2589 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2590 const u8 *mac, struct station_info *sinfo)
2592 struct brcmf_if *ifp = netdev_priv(ndev);
2593 struct brcmf_scb_val_le scb_val;
2595 struct brcmf_sta_info_le sta_info_le;
2603 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2604 if (!check_vif_up(ifp->vif))
2607 if (brcmf_is_ibssmode(ifp->vif))
2608 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2610 memset(&sta_info_le, 0, sizeof(sta_info_le));
2611 memcpy(&sta_info_le, mac, ETH_ALEN);
2612 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2614 sizeof(sta_info_le));
2615 is_tdls_peer = !err;
2617 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2619 sizeof(sta_info_le));
2621 brcmf_err("GET STA INFO failed, %d\n", err);
2625 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2626 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2627 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2628 sta_flags = le32_to_cpu(sta_info_le.flags);
2629 brcmf_convert_sta_flags(sta_flags, sinfo);
2630 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2632 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2634 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2635 if (sta_flags & BRCMF_STA_ASSOC) {
2636 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2637 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2638 brcmf_fill_bss_param(ifp, sinfo);
2640 if (sta_flags & BRCMF_STA_SCBSTATS) {
2641 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2642 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2643 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2644 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2645 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2646 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2647 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2648 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2649 if (sinfo->tx_packets) {
2650 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2651 sinfo->txrate.legacy =
2652 le32_to_cpu(sta_info_le.tx_rate) / 100;
2654 if (sinfo->rx_packets) {
2655 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2656 sinfo->rxrate.legacy =
2657 le32_to_cpu(sta_info_le.rx_rate) / 100;
2659 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2660 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2661 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2662 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2663 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2667 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2668 if (sta_info_le.rssi[i]) {
2669 sinfo->chain_signal_avg[count_rssi] =
2670 sta_info_le.rssi[i];
2671 sinfo->chain_signal[count_rssi] =
2672 sta_info_le.rssi[i];
2673 total_rssi += sta_info_le.rssi[i];
2678 sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2679 sinfo->chains = count_rssi;
2681 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2682 total_rssi /= count_rssi;
2683 sinfo->signal = total_rssi;
2684 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2685 &ifp->vif->sme_state)) {
2686 memset(&scb_val, 0, sizeof(scb_val));
2687 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2688 &scb_val, sizeof(scb_val));
2690 brcmf_err("Could not get rssi (%d)\n", err);
2693 rssi = le32_to_cpu(scb_val.val);
2694 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2695 sinfo->signal = rssi;
2696 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2701 brcmf_dbg(TRACE, "Exit\n");
2706 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2707 int idx, u8 *mac, struct station_info *sinfo)
2709 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2710 struct brcmf_if *ifp = netdev_priv(ndev);
2713 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2716 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2717 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2719 sizeof(cfg->assoclist));
2721 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2723 cfg->assoclist.count = 0;
2727 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2728 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2729 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2735 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2736 bool enabled, s32 timeout)
2740 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2741 struct brcmf_if *ifp = netdev_priv(ndev);
2743 brcmf_dbg(TRACE, "Enter\n");
2746 * Powersave enable/disable request is coming from the
2747 * cfg80211 even before the interface is up. In that
2748 * scenario, driver will be storing the power save
2749 * preference in cfg struct to apply this to
2750 * FW later while initializing the dongle
2752 cfg->pwr_save = enabled;
2753 if (!check_vif_up(ifp->vif)) {
2755 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2759 pm = enabled ? PM_FAST : PM_OFF;
2760 /* Do not enable the power save after assoc if it is a p2p interface */
2761 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2762 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2765 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2767 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2770 brcmf_err("net_device is not ready yet\n");
2772 brcmf_err("error (%d)\n", err);
2775 brcmf_dbg(TRACE, "Exit\n");
2779 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2780 struct brcmf_bss_info_le *bi)
2782 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2783 struct ieee80211_channel *notify_channel;
2784 struct cfg80211_bss *bss;
2785 struct ieee80211_supported_band *band;
2786 struct brcmu_chan ch;
2789 u16 notify_capability;
2790 u16 notify_interval;
2792 size_t notify_ielen;
2795 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2796 brcmf_err("Bss info is larger than buffer. Discarding\n");
2801 ch.chspec = le16_to_cpu(bi->chanspec);
2802 cfg->d11inf.decchspec(&ch);
2803 bi->ctl_ch = ch.control_ch_num;
2805 channel = bi->ctl_ch;
2807 if (channel <= CH_MAX_2G_CHANNEL)
2808 band = wiphy->bands[NL80211_BAND_2GHZ];
2810 band = wiphy->bands[NL80211_BAND_5GHZ];
2812 freq = ieee80211_channel_to_frequency(channel, band->band);
2813 notify_channel = ieee80211_get_channel(wiphy, freq);
2815 notify_capability = le16_to_cpu(bi->capability);
2816 notify_interval = le16_to_cpu(bi->beacon_period);
2817 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2818 notify_ielen = le32_to_cpu(bi->ie_length);
2819 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2821 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2822 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2823 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2824 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2825 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2827 bss = cfg80211_inform_bss(wiphy, notify_channel,
2828 CFG80211_BSS_FTYPE_UNKNOWN,
2829 (const u8 *)bi->BSSID,
2830 0, notify_capability,
2831 notify_interval, notify_ie,
2832 notify_ielen, notify_signal,
2838 cfg80211_put_bss(wiphy, bss);
2843 static struct brcmf_bss_info_le *
2844 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2847 return list->bss_info_le;
2848 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2849 le32_to_cpu(bss->length));
2852 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2854 struct brcmf_scan_results *bss_list;
2855 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2859 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2860 if (bss_list->count != 0 &&
2861 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2862 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2866 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2867 for (i = 0; i < bss_list->count; i++) {
2868 bi = next_bss_le(bss_list, bi);
2869 err = brcmf_inform_single_bss(cfg, bi);
2876 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
2877 struct net_device *ndev, const u8 *bssid)
2879 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2880 struct ieee80211_channel *notify_channel;
2881 struct brcmf_bss_info_le *bi = NULL;
2882 struct ieee80211_supported_band *band;
2883 struct cfg80211_bss *bss;
2884 struct brcmu_chan ch;
2888 u16 notify_capability;
2889 u16 notify_interval;
2891 size_t notify_ielen;
2894 brcmf_dbg(TRACE, "Enter\n");
2896 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2902 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2904 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2905 buf, WL_BSS_INFO_MAX);
2907 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2911 bi = (struct brcmf_bss_info_le *)(buf + 4);
2913 ch.chspec = le16_to_cpu(bi->chanspec);
2914 cfg->d11inf.decchspec(&ch);
2916 if (ch.band == BRCMU_CHAN_BAND_2G)
2917 band = wiphy->bands[NL80211_BAND_2GHZ];
2919 band = wiphy->bands[NL80211_BAND_5GHZ];
2921 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
2922 cfg->channel = freq;
2923 notify_channel = ieee80211_get_channel(wiphy, freq);
2925 notify_capability = le16_to_cpu(bi->capability);
2926 notify_interval = le16_to_cpu(bi->beacon_period);
2927 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2928 notify_ielen = le32_to_cpu(bi->ie_length);
2929 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2931 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
2932 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2933 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2934 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2936 bss = cfg80211_inform_bss(wiphy, notify_channel,
2937 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2938 notify_capability, notify_interval,
2939 notify_ie, notify_ielen, notify_signal,
2947 cfg80211_put_bss(wiphy, bss);
2953 brcmf_dbg(TRACE, "Exit\n");
2958 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2959 struct brcmf_if *ifp)
2961 struct brcmf_bss_info_le *bi;
2962 const struct brcmf_tlv *tim;
2963 u16 beacon_interval;
2969 brcmf_dbg(TRACE, "Enter\n");
2970 if (brcmf_is_ibssmode(ifp->vif))
2973 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2974 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2975 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2977 brcmf_err("Could not get bss info %d\n", err);
2978 goto update_bss_info_out;
2981 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2982 err = brcmf_inform_single_bss(cfg, bi);
2984 goto update_bss_info_out;
2986 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2987 ie_len = le32_to_cpu(bi->ie_length);
2988 beacon_interval = le16_to_cpu(bi->beacon_period);
2990 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2992 dtim_period = tim->data[1];
2995 * active scan was done so we could not get dtim
2996 * information out of probe response.
2997 * so we speficially query dtim information to dongle.
3000 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
3002 brcmf_err("wl dtim_assoc failed (%d)\n", err);
3003 goto update_bss_info_out;
3005 dtim_period = (u8)var;
3008 update_bss_info_out:
3009 brcmf_dbg(TRACE, "Exit");
3013 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3015 struct escan_info *escan = &cfg->escan_info;
3017 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3018 if (cfg->internal_escan || cfg->scan_request) {
3019 escan->escan_state = WL_ESCAN_STATE_IDLE;
3020 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3022 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3023 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3026 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3028 struct brcmf_cfg80211_info *cfg =
3029 container_of(work, struct brcmf_cfg80211_info,
3030 escan_timeout_work);
3032 brcmf_inform_bss(cfg);
3033 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3036 static void brcmf_escan_timeout(unsigned long data)
3038 struct brcmf_cfg80211_info *cfg =
3039 (struct brcmf_cfg80211_info *)data;
3041 if (cfg->internal_escan || cfg->scan_request) {
3042 brcmf_err("timer expired\n");
3043 schedule_work(&cfg->escan_timeout_work);
3048 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3049 struct brcmf_bss_info_le *bss,
3050 struct brcmf_bss_info_le *bss_info_le)
3052 struct brcmu_chan ch_bss, ch_bss_info_le;
3054 ch_bss.chspec = le16_to_cpu(bss->chanspec);
3055 cfg->d11inf.decchspec(&ch_bss);
3056 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3057 cfg->d11inf.decchspec(&ch_bss_info_le);
3059 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3060 ch_bss.band == ch_bss_info_le.band &&
3061 bss_info_le->SSID_len == bss->SSID_len &&
3062 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3063 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3064 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3065 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3066 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3068 /* preserve max RSSI if the measurements are
3069 * both on-channel or both off-channel
3071 if (bss_info_rssi > bss_rssi)
3072 bss->RSSI = bss_info_le->RSSI;
3073 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3074 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3075 /* preserve the on-channel rssi measurement
3076 * if the new measurement is off channel
3078 bss->RSSI = bss_info_le->RSSI;
3079 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3087 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3088 const struct brcmf_event_msg *e, void *data)
3090 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3092 struct brcmf_escan_result_le *escan_result_le;
3093 struct brcmf_bss_info_le *bss_info_le;
3094 struct brcmf_bss_info_le *bss = NULL;
3096 struct brcmf_scan_results *list;
3102 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3103 brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
3107 if (status == BRCMF_E_STATUS_PARTIAL) {
3108 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3109 escan_result_le = (struct brcmf_escan_result_le *) data;
3110 if (!escan_result_le) {
3111 brcmf_err("Invalid escan result (NULL pointer)\n");
3114 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3115 brcmf_err("Invalid bss_count %d: ignoring\n",
3116 escan_result_le->bss_count);
3119 bss_info_le = &escan_result_le->bss_info_le;
3121 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3124 if (!cfg->internal_escan && !cfg->scan_request) {
3125 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3129 bi_length = le32_to_cpu(bss_info_le->length);
3130 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3131 WL_ESCAN_RESULTS_FIXED_SIZE)) {
3132 brcmf_err("Invalid bss_info length %d: ignoring\n",
3137 if (!(cfg_to_wiphy(cfg)->interface_modes &
3138 BIT(NL80211_IFTYPE_ADHOC))) {
3139 if (le16_to_cpu(bss_info_le->capability) &
3140 WLAN_CAPABILITY_IBSS) {
3141 brcmf_err("Ignoring IBSS result\n");
3146 list = (struct brcmf_scan_results *)
3147 cfg->escan_info.escan_buf;
3148 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3149 brcmf_err("Buffer is too small: ignoring\n");
3153 for (i = 0; i < list->count; i++) {
3154 bss = bss ? (struct brcmf_bss_info_le *)
3155 ((unsigned char *)bss +
3156 le32_to_cpu(bss->length)) : list->bss_info_le;
3157 if (brcmf_compare_update_same_bss(cfg, bss,
3161 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3163 list->version = le32_to_cpu(bss_info_le->version);
3164 list->buflen += bi_length;
3167 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3168 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3170 if (cfg->internal_escan || cfg->scan_request) {
3171 brcmf_inform_bss(cfg);
3172 aborted = status != BRCMF_E_STATUS_SUCCESS;
3173 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3175 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3182 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3184 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3185 brcmf_cfg80211_escan_handler);
3186 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3187 /* Init scan_timeout timer */
3188 init_timer(&cfg->escan_timeout);
3189 cfg->escan_timeout.data = (unsigned long) cfg;
3190 cfg->escan_timeout.function = brcmf_escan_timeout;
3191 INIT_WORK(&cfg->escan_timeout_work,
3192 brcmf_cfg80211_escan_timeout_worker);
3195 static struct cfg80211_scan_request *
3196 brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3197 struct cfg80211_scan_request *req;
3200 req_size = sizeof(*req) +
3201 n_netinfo * sizeof(req->channels[0]) +
3202 n_netinfo * sizeof(*req->ssids);
3204 req = kzalloc(req_size, GFP_KERNEL);
3207 req->ssids = (void *)(&req->channels[0]) +
3208 n_netinfo * sizeof(req->channels[0]);
3213 static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3214 u8 *ssid, u8 ssid_len, u8 channel)
3216 struct ieee80211_channel *chan;
3217 enum nl80211_band band;
3220 if (channel <= CH_MAX_2G_CHANNEL)
3221 band = NL80211_BAND_2GHZ;
3223 band = NL80211_BAND_5GHZ;
3225 freq = ieee80211_channel_to_frequency(channel, band);
3229 chan = ieee80211_get_channel(req->wiphy, freq);
3233 req->channels[req->n_channels++] = chan;
3234 memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3235 req->ssids[req->n_ssids++].ssid_len = ssid_len;
3240 static int brcmf_start_internal_escan(struct brcmf_if *ifp,
3241 struct cfg80211_scan_request *request)
3243 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3246 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3247 /* Abort any on-going scan */
3248 brcmf_abort_scanning(cfg);
3251 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3252 cfg->escan_info.run = brcmf_run_escan;
3253 err = brcmf_do_escan(ifp, request);
3255 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3258 cfg->internal_escan = true;
3262 static struct brcmf_pno_net_info_le *
3263 brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3265 struct brcmf_pno_scanresults_v2_le *pfn_v2;
3266 struct brcmf_pno_net_info_le *netinfo;
3268 switch (pfn_v1->version) {
3272 case cpu_to_le32(1):
3273 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3275 case cpu_to_le32(2):
3276 pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3277 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3284 /* PFN result doesn't have all the info which are required by the supplicant
3285 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3286 * via wl_inform_single_bss in the required format. Escan does require the
3287 * scan request in the form of cfg80211_scan_request. For timebeing, create
3288 * cfg80211_scan_request one out of the received PNO event.
3291 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3292 const struct brcmf_event_msg *e, void *data)
3294 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3295 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3296 struct cfg80211_scan_request *request = NULL;
3297 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3299 struct brcmf_pno_scanresults_le *pfn_result;
3303 brcmf_dbg(SCAN, "Enter\n");
3305 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3306 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3310 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3311 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3315 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3316 result_count = le32_to_cpu(pfn_result->count);
3317 status = le32_to_cpu(pfn_result->status);
3319 /* PFN event is limited to fit 512 bytes so we may get
3320 * multiple NET_FOUND events. For now place a warning here.
3322 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3323 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3324 if (!result_count) {
3325 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3328 request = brcmf_alloc_internal_escan_request(wiphy,
3335 data += sizeof(struct brcmf_pno_scanresults_le);
3336 netinfo_start = brcmf_get_netinfo_array(pfn_result);
3338 for (i = 0; i < result_count; i++) {
3339 netinfo = &netinfo_start[i];
3341 brcmf_err("Invalid netinfo ptr. index: %d\n",
3347 brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3348 netinfo->SSID, netinfo->channel);
3349 err = brcmf_internal_escan_add_info(request,
3357 err = brcmf_start_internal_escan(ifp, request);
3362 cfg80211_sched_scan_stopped(wiphy);
3369 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3370 struct net_device *ndev,
3371 struct cfg80211_sched_scan_request *req)
3373 struct brcmf_if *ifp = netdev_priv(ndev);
3374 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3376 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3377 req->n_match_sets, req->n_ssids);
3379 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3380 brcmf_err("Scanning suppressed: status (%lu)\n",
3385 if (req->n_match_sets <= 0) {
3386 brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3391 return brcmf_pno_start_sched_scan(ifp, req);
3394 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3395 struct net_device *ndev)
3397 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3398 struct brcmf_if *ifp = netdev_priv(ndev);
3400 brcmf_dbg(SCAN, "enter\n");
3401 brcmf_pno_clean(ifp);
3402 if (cfg->internal_escan)
3403 brcmf_notify_escan_complete(cfg, ifp, true, true);
3407 static __always_inline void brcmf_delay(u32 ms)
3409 if (ms < 1000 / HZ) {
3417 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3418 u8 *pattern, u32 patternsize, u8 *mask,
3421 struct brcmf_fil_wowl_pattern_le *filter;
3428 masksize = (patternsize + 7) / 8;
3429 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3431 bufsize = sizeof(*filter) + patternsize + masksize;
3432 buf = kzalloc(bufsize, GFP_KERNEL);
3435 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3437 memcpy(filter->cmd, cmd, 4);
3438 filter->masksize = cpu_to_le32(masksize);
3439 filter->offset = cpu_to_le32(packet_offset);
3440 filter->patternoffset = cpu_to_le32(patternoffset);
3441 filter->patternsize = cpu_to_le32(patternsize);
3442 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3444 if ((mask) && (masksize))
3445 memcpy(buf + sizeof(*filter), mask, masksize);
3446 if ((pattern) && (patternsize))
3447 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3449 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3456 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3459 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3460 struct brcmf_pno_scanresults_le *pfn_result;
3461 struct brcmf_pno_net_info_le *netinfo;
3463 brcmf_dbg(SCAN, "Enter\n");
3465 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3466 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3470 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3472 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3473 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3477 if (le32_to_cpu(pfn_result->count) < 1) {
3478 brcmf_err("Invalid result count, expected 1 (%d)\n",
3479 le32_to_cpu(pfn_result->count));
3483 data += sizeof(struct brcmf_pno_scanresults_le);
3484 netinfo = (struct brcmf_pno_net_info_le *)data;
3485 memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3486 cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3487 cfg->wowl.nd->n_channels = 1;
3488 cfg->wowl.nd->channels[0] =
3489 ieee80211_channel_to_frequency(netinfo->channel,
3490 netinfo->channel <= CH_MAX_2G_CHANNEL ?
3491 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3492 cfg->wowl.nd_info->n_matches = 1;
3493 cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3495 /* Inform (the resume task) that the net detect information was recvd */
3496 cfg->wowl.nd_data_completed = true;
3497 wake_up(&cfg->wowl.nd_data_wait);
3504 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3506 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3507 struct brcmf_wowl_wakeind_le wake_ind_le;
3508 struct cfg80211_wowlan_wakeup wakeup_data;
3509 struct cfg80211_wowlan_wakeup *wakeup;
3514 err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3515 sizeof(wake_ind_le));
3517 brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
3521 wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3522 if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3523 BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3524 BRCMF_WOWL_PFN_FOUND)) {
3525 wakeup = &wakeup_data;
3526 memset(&wakeup_data, 0, sizeof(wakeup_data));
3527 wakeup_data.pattern_idx = -1;
3529 if (wakeind & BRCMF_WOWL_MAGIC) {
3530 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3531 wakeup_data.magic_pkt = true;
3533 if (wakeind & BRCMF_WOWL_DIS) {
3534 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3535 wakeup_data.disconnect = true;
3537 if (wakeind & BRCMF_WOWL_BCN) {
3538 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3539 wakeup_data.disconnect = true;
3541 if (wakeind & BRCMF_WOWL_RETR) {
3542 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3543 wakeup_data.disconnect = true;
3545 if (wakeind & BRCMF_WOWL_NET) {
3546 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3547 /* For now always map to pattern 0, no API to get
3548 * correct information available at the moment.
3550 wakeup_data.pattern_idx = 0;
3552 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3553 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3554 timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3555 cfg->wowl.nd_data_completed,
3556 BRCMF_ND_INFO_TIMEOUT);
3558 brcmf_err("No result for wowl net detect\n");
3560 wakeup_data.net_detect = cfg->wowl.nd_info;
3562 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3563 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3564 wakeup_data.gtk_rekey_failure = true;
3569 cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3574 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3578 #endif /* CONFIG_PM */
3580 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3582 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3583 struct net_device *ndev = cfg_to_ndev(cfg);
3584 struct brcmf_if *ifp = netdev_priv(ndev);
3586 brcmf_dbg(TRACE, "Enter\n");
3588 if (cfg->wowl.active) {
3589 brcmf_report_wowl_wakeind(wiphy, ifp);
3590 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3591 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3592 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3593 brcmf_configure_arp_nd_offload(ifp, true);
3594 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3595 cfg->wowl.pre_pmmode);
3596 cfg->wowl.active = false;
3597 if (cfg->wowl.nd_enabled) {
3598 brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev);
3599 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3600 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3601 brcmf_notify_sched_scan_results);
3602 cfg->wowl.nd_enabled = false;
3608 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3609 struct brcmf_if *ifp,
3610 struct cfg80211_wowlan *wowl)
3613 struct brcmf_wowl_wakeind_le wowl_wakeind;
3616 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3618 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3619 brcmf_configure_arp_nd_offload(ifp, false);
3620 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3621 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3624 if (wowl->disconnect)
3625 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3626 if (wowl->magic_pkt)
3627 wowl_config |= BRCMF_WOWL_MAGIC;
3628 if ((wowl->patterns) && (wowl->n_patterns)) {
3629 wowl_config |= BRCMF_WOWL_NET;
3630 for (i = 0; i < wowl->n_patterns; i++) {
3631 brcmf_config_wowl_pattern(ifp, "add",
3632 (u8 *)wowl->patterns[i].pattern,
3633 wowl->patterns[i].pattern_len,
3634 (u8 *)wowl->patterns[i].mask,
3635 wowl->patterns[i].pkt_offset);
3638 if (wowl->nd_config) {
3639 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3641 wowl_config |= BRCMF_WOWL_PFN_FOUND;
3643 cfg->wowl.nd_data_completed = false;
3644 cfg->wowl.nd_enabled = true;
3645 /* Now reroute the event for PFN to the wowl function. */
3646 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3647 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3648 brcmf_wowl_nd_results);
3650 if (wowl->gtk_rekey_failure)
3651 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3652 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3653 wowl_config |= BRCMF_WOWL_UNASSOC;
3655 memcpy(&wowl_wakeind, "clear", 6);
3656 brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
3657 sizeof(wowl_wakeind));
3658 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3659 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3660 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3661 cfg->wowl.active = true;
3664 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3665 struct cfg80211_wowlan *wowl)
3667 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3668 struct net_device *ndev = cfg_to_ndev(cfg);
3669 struct brcmf_if *ifp = netdev_priv(ndev);
3670 struct brcmf_cfg80211_vif *vif;
3672 brcmf_dbg(TRACE, "Enter\n");
3674 /* if the primary net_device is not READY there is nothing
3675 * we can do but pray resume goes smoothly.
3677 if (!check_vif_up(ifp->vif))
3680 /* Stop scheduled scan */
3681 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3682 brcmf_cfg80211_sched_scan_stop(wiphy, ndev);
3684 /* end any scanning */
3685 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3686 brcmf_abort_scanning(cfg);
3689 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3690 list_for_each_entry(vif, &cfg->vif_list, list) {
3691 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3693 /* While going to suspend if associated with AP
3694 * disassociate from AP to save power while system is
3695 * in suspended state
3697 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3698 /* Make sure WPA_Supplicant receives all the event
3699 * generated due to DISASSOC call to the fw to keep
3700 * the state fw and WPA_Supplicant state consistent
3705 brcmf_set_mpc(ifp, 1);
3708 /* Configure WOWL paramaters */
3709 brcmf_configure_wowl(cfg, ifp, wowl);
3713 brcmf_dbg(TRACE, "Exit\n");
3714 /* clear any scanning activity */
3715 cfg->scan_status = 0;
3720 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3722 struct brcmf_pmk_list_le *pmk_list;
3727 pmk_list = &cfg->pmk_list;
3728 npmk = le32_to_cpu(pmk_list->npmk);
3730 brcmf_dbg(CONN, "No of elements %d\n", npmk);
3731 for (i = 0; i < npmk; i++)
3732 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3734 err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3741 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3742 struct cfg80211_pmksa *pmksa)
3744 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3745 struct brcmf_if *ifp = netdev_priv(ndev);
3746 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3750 brcmf_dbg(TRACE, "Enter\n");
3751 if (!check_vif_up(ifp->vif))
3754 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3755 for (i = 0; i < npmk; i++)
3756 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3758 if (i < BRCMF_MAXPMKID) {
3759 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
3760 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
3763 cfg->pmk_list.npmk = cpu_to_le32(npmk);
3766 brcmf_err("Too many PMKSA entries cached %d\n", npmk);
3770 brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
3771 for (i = 0; i < WLAN_PMKID_LEN; i += 4)
3772 brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
3773 pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
3774 pmk[npmk].pmkid[i + 3]);
3776 err = brcmf_update_pmklist(cfg, ifp);
3778 brcmf_dbg(TRACE, "Exit\n");
3783 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3784 struct cfg80211_pmksa *pmksa)
3786 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3787 struct brcmf_if *ifp = netdev_priv(ndev);
3788 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3792 brcmf_dbg(TRACE, "Enter\n");
3793 if (!check_vif_up(ifp->vif))
3796 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
3798 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3799 for (i = 0; i < npmk; i++)
3800 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3803 if ((npmk > 0) && (i < npmk)) {
3804 for (; i < (npmk - 1); i++) {
3805 memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
3806 memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
3809 memset(&pmk[i], 0, sizeof(*pmk));
3810 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
3812 brcmf_err("Cache entry not found\n");
3816 err = brcmf_update_pmklist(cfg, ifp);
3818 brcmf_dbg(TRACE, "Exit\n");
3824 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3826 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3827 struct brcmf_if *ifp = netdev_priv(ndev);
3830 brcmf_dbg(TRACE, "Enter\n");
3831 if (!check_vif_up(ifp->vif))
3834 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
3835 err = brcmf_update_pmklist(cfg, ifp);
3837 brcmf_dbg(TRACE, "Exit\n");
3842 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3847 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3849 brcmf_err("auth error %d\n", err);
3853 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3855 brcmf_err("wsec error %d\n", err);
3858 /* set upper-layer auth */
3859 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3861 brcmf_err("wpa_auth error %d\n", err);
3868 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3871 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3873 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3877 brcmf_configure_wpaie(struct brcmf_if *ifp,
3878 const struct brcmf_vs_tlv *wpa_ie,
3881 u32 auth = 0; /* d11 open authentication */
3893 u32 wme_bss_disable;
3896 brcmf_dbg(TRACE, "Enter\n");
3900 len = wpa_ie->len + TLV_HDR_LEN;
3901 data = (u8 *)wpa_ie;
3902 offset = TLV_HDR_LEN;
3904 offset += VS_IE_FIXED_HDR_LEN;
3906 offset += WPA_IE_VERSION_LEN;
3908 /* check for multicast cipher suite */
3909 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3911 brcmf_err("no multicast cipher suite\n");
3915 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3917 brcmf_err("ivalid OUI\n");
3920 offset += TLV_OUI_LEN;
3922 /* pick up multicast cipher */
3923 switch (data[offset]) {
3924 case WPA_CIPHER_NONE:
3927 case WPA_CIPHER_WEP_40:
3928 case WPA_CIPHER_WEP_104:
3931 case WPA_CIPHER_TKIP:
3932 gval = TKIP_ENABLED;
3934 case WPA_CIPHER_AES_CCM:
3939 brcmf_err("Invalid multi cast cipher info\n");
3944 /* walk thru unicast cipher list and pick up what we recognize */
3945 count = data[offset] + (data[offset + 1] << 8);
3946 offset += WPA_IE_SUITE_COUNT_LEN;
3947 /* Check for unicast suite(s) */
3948 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3950 brcmf_err("no unicast cipher suite\n");
3953 for (i = 0; i < count; i++) {
3954 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3956 brcmf_err("ivalid OUI\n");
3959 offset += TLV_OUI_LEN;
3960 switch (data[offset]) {
3961 case WPA_CIPHER_NONE:
3963 case WPA_CIPHER_WEP_40:
3964 case WPA_CIPHER_WEP_104:
3965 pval |= WEP_ENABLED;
3967 case WPA_CIPHER_TKIP:
3968 pval |= TKIP_ENABLED;
3970 case WPA_CIPHER_AES_CCM:
3971 pval |= AES_ENABLED;
3974 brcmf_err("Ivalid unicast security info\n");
3978 /* walk thru auth management suite list and pick up what we recognize */
3979 count = data[offset] + (data[offset + 1] << 8);
3980 offset += WPA_IE_SUITE_COUNT_LEN;
3981 /* Check for auth key management suite(s) */
3982 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3984 brcmf_err("no auth key mgmt suite\n");
3987 for (i = 0; i < count; i++) {
3988 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3990 brcmf_err("ivalid OUI\n");
3993 offset += TLV_OUI_LEN;
3994 switch (data[offset]) {
3996 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3997 wpa_auth |= WPA_AUTH_NONE;
3999 case RSN_AKM_UNSPECIFIED:
4000 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
4001 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
4002 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
4005 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
4006 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
4007 (wpa_auth |= WPA_AUTH_PSK);
4009 case RSN_AKM_SHA256_PSK:
4010 brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4011 wpa_auth |= WPA2_AUTH_PSK_SHA256;
4013 case RSN_AKM_SHA256_1X:
4014 brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4015 wpa_auth |= WPA2_AUTH_1X_SHA256;
4018 brcmf_err("Ivalid key mgmt info\n");
4023 mfp = BRCMF_MFP_NONE;
4025 wme_bss_disable = 1;
4026 if ((offset + RSN_CAP_LEN) <= len) {
4027 rsn_cap = data[offset] + (data[offset + 1] << 8);
4028 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4029 wme_bss_disable = 0;
4030 if (rsn_cap & RSN_CAP_MFPR_MASK) {
4031 brcmf_dbg(TRACE, "MFP Required\n");
4032 mfp = BRCMF_MFP_REQUIRED;
4033 /* Firmware only supports mfp required in
4034 * combination with WPA2_AUTH_PSK_SHA256 or
4035 * WPA2_AUTH_1X_SHA256.
4037 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4038 WPA2_AUTH_1X_SHA256))) {
4042 /* Firmware has requirement that WPA2_AUTH_PSK/
4043 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4044 * is to be included in the rsn ie.
4046 if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4047 wpa_auth |= WPA2_AUTH_PSK;
4048 else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4049 wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4050 } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4051 brcmf_dbg(TRACE, "MFP Capable\n");
4052 mfp = BRCMF_MFP_CAPABLE;
4055 offset += RSN_CAP_LEN;
4056 /* set wme_bss_disable to sync RSN Capabilities */
4057 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4060 brcmf_err("wme_bss_disable error %d\n", err);
4064 /* Skip PMKID cnt as it is know to be 0 for AP. */
4065 offset += RSN_PMKID_COUNT_LEN;
4067 /* See if there is BIP wpa suite left for MFP */
4068 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4069 ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4070 err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4072 WPA_IE_MIN_OUI_LEN);
4074 brcmf_err("bip error %d\n", err);
4079 /* FOR WPS , set SES_OW_ENABLED */
4080 wsec = (pval | gval | SES_OW_ENABLED);
4083 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4085 brcmf_err("auth error %d\n", err);
4089 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4091 brcmf_err("wsec error %d\n", err);
4094 /* Configure MFP, this needs to go after wsec otherwise the wsec command
4095 * will overwrite the values set by MFP
4097 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4098 err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4100 brcmf_err("mfp error %d\n", err);
4104 /* set upper-layer auth */
4105 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4107 brcmf_err("wpa_auth error %d\n", err);
4116 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4117 struct parsed_vndr_ies *vndr_ies)
4119 struct brcmf_vs_tlv *vndrie;
4120 struct brcmf_tlv *ie;
4121 struct parsed_vndr_ie_info *parsed_info;
4124 remaining_len = (s32)vndr_ie_len;
4125 memset(vndr_ies, 0, sizeof(*vndr_ies));
4127 ie = (struct brcmf_tlv *)vndr_ie_buf;
4129 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4131 vndrie = (struct brcmf_vs_tlv *)ie;
4132 /* len should be bigger than OUI length + one */
4133 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4134 brcmf_err("invalid vndr ie. length is too small %d\n",
4138 /* if wpa or wme ie, do not add ie */
4139 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4140 ((vndrie->oui_type == WPA_OUI_TYPE) ||
4141 (vndrie->oui_type == WME_OUI_TYPE))) {
4142 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4146 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4148 /* save vndr ie information */
4149 parsed_info->ie_ptr = (char *)vndrie;
4150 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4151 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4155 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
4156 parsed_info->vndrie.oui[0],
4157 parsed_info->vndrie.oui[1],
4158 parsed_info->vndrie.oui[2],
4159 parsed_info->vndrie.oui_type);
4161 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4164 remaining_len -= (ie->len + TLV_HDR_LEN);
4165 if (remaining_len <= TLV_HDR_LEN)
4168 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4175 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4178 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
4179 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
4181 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4183 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4185 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4187 return ie_len + VNDR_IE_HDR_SIZE;
4190 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4191 const u8 *vndr_ie_buf, u32 vndr_ie_len)
4193 struct brcmf_if *ifp;
4194 struct vif_saved_ie *saved_ie;
4198 u8 *mgmt_ie_buf = NULL;
4199 int mgmt_ie_buf_len;
4201 u32 del_add_ie_buf_len = 0;
4202 u32 total_ie_buf_len = 0;
4203 u32 parsed_ie_buf_len = 0;
4204 struct parsed_vndr_ies old_vndr_ies;
4205 struct parsed_vndr_ies new_vndr_ies;
4206 struct parsed_vndr_ie_info *vndrie_info;
4209 int remained_buf_len;
4214 saved_ie = &vif->saved_ie;
4216 brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4218 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4221 curr_ie_buf = iovar_ie_buf;
4223 case BRCMF_VNDR_IE_PRBREQ_FLAG:
4224 mgmt_ie_buf = saved_ie->probe_req_ie;
4225 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4226 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4228 case BRCMF_VNDR_IE_PRBRSP_FLAG:
4229 mgmt_ie_buf = saved_ie->probe_res_ie;
4230 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4231 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4233 case BRCMF_VNDR_IE_BEACON_FLAG:
4234 mgmt_ie_buf = saved_ie->beacon_ie;
4235 mgmt_ie_len = &saved_ie->beacon_ie_len;
4236 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4238 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4239 mgmt_ie_buf = saved_ie->assoc_req_ie;
4240 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4241 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4245 brcmf_err("not suitable type\n");
4249 if (vndr_ie_len > mgmt_ie_buf_len) {
4251 brcmf_err("extra IE size too big\n");
4255 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4256 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4258 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4259 for (i = 0; i < new_vndr_ies.count; i++) {
4260 vndrie_info = &new_vndr_ies.ie_info[i];
4261 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4262 vndrie_info->ie_len);
4263 parsed_ie_buf_len += vndrie_info->ie_len;
4267 if (mgmt_ie_buf && *mgmt_ie_len) {
4268 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4269 (memcmp(mgmt_ie_buf, curr_ie_buf,
4270 parsed_ie_buf_len) == 0)) {
4271 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4275 /* parse old vndr_ie */
4276 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4278 /* make a command to delete old ie */
4279 for (i = 0; i < old_vndr_ies.count; i++) {
4280 vndrie_info = &old_vndr_ies.ie_info[i];
4282 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4283 vndrie_info->vndrie.id,
4284 vndrie_info->vndrie.len,
4285 vndrie_info->vndrie.oui[0],
4286 vndrie_info->vndrie.oui[1],
4287 vndrie_info->vndrie.oui[2]);
4289 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4290 vndrie_info->ie_ptr,
4291 vndrie_info->ie_len,
4293 curr_ie_buf += del_add_ie_buf_len;
4294 total_ie_buf_len += del_add_ie_buf_len;
4299 /* Add if there is any extra IE */
4300 if (mgmt_ie_buf && parsed_ie_buf_len) {
4303 remained_buf_len = mgmt_ie_buf_len;
4305 /* make a command to add new ie */
4306 for (i = 0; i < new_vndr_ies.count; i++) {
4307 vndrie_info = &new_vndr_ies.ie_info[i];
4309 /* verify remained buf size before copy data */
4310 if (remained_buf_len < (vndrie_info->vndrie.len +
4311 VNDR_IE_VSIE_OFFSET)) {
4312 brcmf_err("no space in mgmt_ie_buf: len left %d",
4316 remained_buf_len -= (vndrie_info->ie_len +
4317 VNDR_IE_VSIE_OFFSET);
4319 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4320 vndrie_info->vndrie.id,
4321 vndrie_info->vndrie.len,
4322 vndrie_info->vndrie.oui[0],
4323 vndrie_info->vndrie.oui[1],
4324 vndrie_info->vndrie.oui[2]);
4326 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4327 vndrie_info->ie_ptr,
4328 vndrie_info->ie_len,
4331 /* save the parsed IE in wl struct */
4332 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4333 vndrie_info->ie_len);
4334 *mgmt_ie_len += vndrie_info->ie_len;
4336 curr_ie_buf += del_add_ie_buf_len;
4337 total_ie_buf_len += del_add_ie_buf_len;
4340 if (total_ie_buf_len) {
4341 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4344 brcmf_err("vndr ie set error : %d\n", err);
4348 kfree(iovar_ie_buf);
4352 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4355 BRCMF_VNDR_IE_PRBREQ_FLAG,
4356 BRCMF_VNDR_IE_PRBRSP_FLAG,
4357 BRCMF_VNDR_IE_BEACON_FLAG
4361 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4362 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4364 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4369 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4370 struct cfg80211_beacon_data *beacon)
4374 /* Set Beacon IEs to FW */
4375 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4376 beacon->tail, beacon->tail_len);
4378 brcmf_err("Set Beacon IE Failed\n");
4381 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4383 /* Set Probe Response IEs to FW */
4384 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4385 beacon->proberesp_ies,
4386 beacon->proberesp_ies_len);
4388 brcmf_err("Set Probe Resp IE Failed\n");
4390 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4396 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4397 struct cfg80211_ap_settings *settings)
4400 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4401 struct brcmf_if *ifp = netdev_priv(ndev);
4402 const struct brcmf_tlv *ssid_ie;
4403 const struct brcmf_tlv *country_ie;
4404 struct brcmf_ssid_le ssid_le;
4406 const struct brcmf_tlv *rsn_ie;
4407 const struct brcmf_vs_tlv *wpa_ie;
4408 struct brcmf_join_params join_params;
4409 enum nl80211_iftype dev_role;
4410 struct brcmf_fil_bss_enable_le bss_enable;
4411 u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
4416 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4417 settings->chandef.chan->hw_value,
4418 settings->chandef.center_freq1, settings->chandef.width,
4419 settings->beacon_interval, settings->dtim_period);
4420 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4421 settings->ssid, settings->ssid_len, settings->auth_type,
4422 settings->inactivity_timeout);
4423 dev_role = ifp->vif->wdev.iftype;
4424 mbss = ifp->vif->mbss;
4426 /* store current 11d setting */
4427 if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
4428 &ifp->vif->is_11d)) {
4429 is_11d = supports_11d = false;
4431 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4432 settings->beacon.tail_len,
4434 is_11d = country_ie ? 1 : 0;
4435 supports_11d = true;
4438 memset(&ssid_le, 0, sizeof(ssid_le));
4439 if (settings->ssid == NULL || settings->ssid_len == 0) {
4440 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4441 ssid_ie = brcmf_parse_tlvs(
4442 (u8 *)&settings->beacon.head[ie_offset],
4443 settings->beacon.head_len - ie_offset,
4445 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4448 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4449 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4450 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4452 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4453 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4457 brcmf_set_mpc(ifp, 0);
4458 brcmf_configure_arp_nd_offload(ifp, false);
4461 /* find the RSN_IE */
4462 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4463 settings->beacon.tail_len, WLAN_EID_RSN);
4465 /* find the WPA_IE */
4466 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4467 settings->beacon.tail_len);
4469 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4470 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4471 if (wpa_ie != NULL) {
4473 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4477 struct brcmf_vs_tlv *tmp_ie;
4479 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4482 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4487 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4488 brcmf_configure_opensecurity(ifp);
4491 /* Parameters shared by all radio interfaces */
4493 if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
4494 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4497 brcmf_err("Regulatory Set Error, %d\n", err);
4501 if (settings->beacon_interval) {
4502 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4503 settings->beacon_interval);
4505 brcmf_err("Beacon Interval Set Error, %d\n",
4510 if (settings->dtim_period) {
4511 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4512 settings->dtim_period);
4514 brcmf_err("DTIM Interval Set Error, %d\n", err);
4519 if ((dev_role == NL80211_IFTYPE_AP) &&
4520 ((ifp->ifidx == 0) ||
4521 !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
4522 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4524 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4527 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4530 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4532 brcmf_err("SET INFRA error %d\n", err);
4535 } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
4536 /* Multiple-BSS should use same 11d configuration */
4541 /* Interface specific setup */
4542 if (dev_role == NL80211_IFTYPE_AP) {
4543 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4544 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4546 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4548 brcmf_err("setting AP mode failed %d\n", err);
4552 /* Firmware 10.x requires setting channel after enabling
4553 * AP and before bringing interface up.
4555 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4557 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4562 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4564 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4567 /* On DOWN the firmware removes the WEP keys, reconfigure
4568 * them if they were set.
4570 brcmf_cfg80211_reconfigure_wep(ifp);
4572 memset(&join_params, 0, sizeof(join_params));
4573 /* join parameters starts with ssid */
4574 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4576 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4577 &join_params, sizeof(join_params));
4579 brcmf_err("SET SSID error (%d)\n", err);
4583 if (settings->hidden_ssid) {
4584 err = brcmf_fil_iovar_int_set(ifp, "closednet", 1);
4586 brcmf_err("closednet error (%d)\n", err);
4591 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4592 } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
4593 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4595 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4599 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4602 brcmf_err("setting ssid failed %d\n", err);
4605 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4606 bss_enable.enable = cpu_to_le32(1);
4607 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4608 sizeof(bss_enable));
4610 brcmf_err("bss_enable config failed %d\n", err);
4614 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4619 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4620 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4621 brcmf_net_setcarrier(ifp, true);
4624 if ((err) && (!mbss)) {
4625 brcmf_set_mpc(ifp, 1);
4626 brcmf_configure_arp_nd_offload(ifp, true);
4631 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4633 struct brcmf_if *ifp = netdev_priv(ndev);
4635 struct brcmf_fil_bss_enable_le bss_enable;
4636 struct brcmf_join_params join_params;
4638 brcmf_dbg(TRACE, "Enter\n");
4640 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4641 /* Due to most likely deauths outstanding we sleep */
4642 /* first to make sure they get processed by fw. */
4645 if (ifp->vif->mbss) {
4646 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4650 /* First BSS doesn't get a full reset */
4651 if (ifp->bsscfgidx == 0)
4652 brcmf_fil_iovar_int_set(ifp, "closednet", 0);
4654 memset(&join_params, 0, sizeof(join_params));
4655 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4656 &join_params, sizeof(join_params));
4658 brcmf_err("SET SSID error (%d)\n", err);
4659 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4661 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4662 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4664 brcmf_err("setting AP mode failed %d\n", err);
4665 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4667 brcmf_err("setting INFRA mode failed %d\n", err);
4668 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4669 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4670 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4672 /* Bring device back up so it can be used again */
4673 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4675 brcmf_err("BRCMF_C_UP error %d\n", err);
4677 brcmf_vif_clear_mgmt_ies(ifp->vif);
4679 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4680 bss_enable.enable = cpu_to_le32(0);
4681 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4682 sizeof(bss_enable));
4684 brcmf_err("bss_enable config failed %d\n", err);
4686 brcmf_set_mpc(ifp, 1);
4687 brcmf_configure_arp_nd_offload(ifp, true);
4688 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4689 brcmf_net_setcarrier(ifp, false);
4695 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4696 struct cfg80211_beacon_data *info)
4698 struct brcmf_if *ifp = netdev_priv(ndev);
4701 brcmf_dbg(TRACE, "Enter\n");
4703 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4709 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4710 struct station_del_parameters *params)
4712 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4713 struct brcmf_scb_val_le scbval;
4714 struct brcmf_if *ifp = netdev_priv(ndev);
4720 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4722 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4723 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4724 if (!check_vif_up(ifp->vif))
4727 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4728 scbval.val = cpu_to_le32(params->reason_code);
4729 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4730 &scbval, sizeof(scbval));
4732 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4734 brcmf_dbg(TRACE, "Exit\n");
4739 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4740 const u8 *mac, struct station_parameters *params)
4742 struct brcmf_if *ifp = netdev_priv(ndev);
4745 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4746 params->sta_flags_mask, params->sta_flags_set);
4748 /* Ignore all 00 MAC */
4749 if (is_zero_ether_addr(mac))
4752 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4755 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4756 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4757 (void *)mac, ETH_ALEN);
4759 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4760 (void *)mac, ETH_ALEN);
4762 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4768 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4769 struct wireless_dev *wdev,
4770 u16 frame_type, bool reg)
4772 struct brcmf_cfg80211_vif *vif;
4775 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4777 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4778 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4780 vif->mgmt_rx_reg |= BIT(mgmt_type);
4782 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4787 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4788 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4790 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4791 struct ieee80211_channel *chan = params->chan;
4792 const u8 *buf = params->buf;
4793 size_t len = params->len;
4794 const struct ieee80211_mgmt *mgmt;
4795 struct brcmf_cfg80211_vif *vif;
4799 struct brcmf_fil_action_frame_le *action_frame;
4800 struct brcmf_fil_af_params_le *af_params;
4805 brcmf_dbg(TRACE, "Enter\n");
4809 mgmt = (const struct ieee80211_mgmt *)buf;
4811 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4812 brcmf_err("Driver only allows MGMT packet type\n");
4816 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4818 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4819 /* Right now the only reason to get a probe response */
4820 /* is for p2p listen response or for p2p GO from */
4821 /* wpa_supplicant. Unfortunately the probe is send */
4822 /* on primary ndev, while dongle wants it on the p2p */
4823 /* vif. Since this is only reason for a probe */
4824 /* response to be sent, the vif is taken from cfg. */
4825 /* If ever desired to send proberesp for non p2p */
4826 /* response then data should be checked for */
4827 /* "DIRECT-". Note in future supplicant will take */
4828 /* dedicated p2p wdev to do this and then this 'hack'*/
4829 /* is not needed anymore. */
4830 ie_offset = DOT11_MGMT_HDR_LEN +
4831 DOT11_BCN_PRB_FIXED_LEN;
4832 ie_len = len - ie_offset;
4833 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4834 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4835 err = brcmf_vif_set_mgmt_ie(vif,
4836 BRCMF_VNDR_IE_PRBRSP_FLAG,
4839 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4841 } else if (ieee80211_is_action(mgmt->frame_control)) {
4842 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4843 if (af_params == NULL) {
4844 brcmf_err("unable to allocate frame\n");
4848 action_frame = &af_params->action_frame;
4849 /* Add the packet Id */
4850 action_frame->packet_id = cpu_to_le32(*cookie);
4852 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4853 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4854 /* Add the length exepted for 802.11 header */
4855 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4856 /* Add the channel. Use the one specified as parameter if any or
4857 * the current one (got from the firmware) otherwise
4860 freq = chan->center_freq;
4862 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4864 chan_nr = ieee80211_frequency_to_channel(freq);
4865 af_params->channel = cpu_to_le32(chan_nr);
4867 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4868 le16_to_cpu(action_frame->len));
4870 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4871 *cookie, le16_to_cpu(action_frame->len), freq);
4873 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4876 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4880 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4881 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4890 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4891 struct wireless_dev *wdev,
4894 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4895 struct brcmf_cfg80211_vif *vif;
4898 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4900 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4902 brcmf_err("No p2p device available for probe response\n");
4906 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4911 static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
4912 struct wireless_dev *wdev,
4913 struct cfg80211_chan_def *chandef)
4915 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4916 struct net_device *ndev = wdev->netdev;
4917 struct brcmf_if *ifp;
4918 struct brcmu_chan ch;
4919 enum nl80211_band band = 0;
4920 enum nl80211_chan_width width = 0;
4926 ifp = netdev_priv(ndev);
4928 err = brcmf_fil_iovar_int_get(ifp, "chanspec", &chanspec);
4930 brcmf_err("chanspec failed (%d)\n", err);
4934 ch.chspec = chanspec;
4935 cfg->d11inf.decchspec(&ch);
4938 case BRCMU_CHAN_BAND_2G:
4939 band = NL80211_BAND_2GHZ;
4941 case BRCMU_CHAN_BAND_5G:
4942 band = NL80211_BAND_5GHZ;
4947 case BRCMU_CHAN_BW_80:
4948 width = NL80211_CHAN_WIDTH_80;
4950 case BRCMU_CHAN_BW_40:
4951 width = NL80211_CHAN_WIDTH_40;
4953 case BRCMU_CHAN_BW_20:
4954 width = NL80211_CHAN_WIDTH_20;
4956 case BRCMU_CHAN_BW_80P80:
4957 width = NL80211_CHAN_WIDTH_80P80;
4959 case BRCMU_CHAN_BW_160:
4960 width = NL80211_CHAN_WIDTH_160;
4964 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
4965 chandef->chan = ieee80211_get_channel(wiphy, freq);
4966 chandef->width = width;
4967 chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
4968 chandef->center_freq2 = 0;
4973 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4974 struct wireless_dev *wdev,
4975 enum nl80211_crit_proto_id proto,
4978 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4979 struct brcmf_cfg80211_vif *vif;
4981 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4983 /* only DHCP support for now */
4984 if (proto != NL80211_CRIT_PROTO_DHCP)
4987 /* suppress and abort scanning */
4988 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4989 brcmf_abort_scanning(cfg);
4991 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4994 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4995 struct wireless_dev *wdev)
4997 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4998 struct brcmf_cfg80211_vif *vif;
5000 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5002 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
5003 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5007 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
5008 const struct brcmf_event_msg *e, void *data)
5010 switch (e->reason) {
5011 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5012 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5014 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5015 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5016 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5018 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5019 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5020 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5027 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5032 case NL80211_TDLS_DISCOVERY_REQ:
5033 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5035 case NL80211_TDLS_SETUP:
5036 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5038 case NL80211_TDLS_TEARDOWN:
5039 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5042 brcmf_err("unsupported operation: %d\n", oper);
5048 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5049 struct net_device *ndev, const u8 *peer,
5050 enum nl80211_tdls_operation oper)
5052 struct brcmf_if *ifp;
5053 struct brcmf_tdls_iovar_le info;
5056 ret = brcmf_convert_nl80211_tdls_oper(oper);
5060 ifp = netdev_priv(ndev);
5061 memset(&info, 0, sizeof(info));
5062 info.mode = (u8)ret;
5064 memcpy(info.ea, peer, ETH_ALEN);
5066 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5067 &info, sizeof(info));
5069 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
5076 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5077 struct cfg80211_gtk_rekey_data *gtk)
5079 struct brcmf_if *ifp = netdev_priv(ndev);
5080 struct brcmf_gtk_keyinfo_le gtk_le;
5083 brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5085 memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5086 memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5087 memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5088 sizeof(gtk_le.replay_counter));
5090 ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
5093 brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
5099 static struct cfg80211_ops brcmf_cfg80211_ops = {
5100 .add_virtual_intf = brcmf_cfg80211_add_iface,
5101 .del_virtual_intf = brcmf_cfg80211_del_iface,
5102 .change_virtual_intf = brcmf_cfg80211_change_iface,
5103 .scan = brcmf_cfg80211_scan,
5104 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5105 .join_ibss = brcmf_cfg80211_join_ibss,
5106 .leave_ibss = brcmf_cfg80211_leave_ibss,
5107 .get_station = brcmf_cfg80211_get_station,
5108 .dump_station = brcmf_cfg80211_dump_station,
5109 .set_tx_power = brcmf_cfg80211_set_tx_power,
5110 .get_tx_power = brcmf_cfg80211_get_tx_power,
5111 .add_key = brcmf_cfg80211_add_key,
5112 .del_key = brcmf_cfg80211_del_key,
5113 .get_key = brcmf_cfg80211_get_key,
5114 .set_default_key = brcmf_cfg80211_config_default_key,
5115 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5116 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
5117 .connect = brcmf_cfg80211_connect,
5118 .disconnect = brcmf_cfg80211_disconnect,
5119 .suspend = brcmf_cfg80211_suspend,
5120 .resume = brcmf_cfg80211_resume,
5121 .set_pmksa = brcmf_cfg80211_set_pmksa,
5122 .del_pmksa = brcmf_cfg80211_del_pmksa,
5123 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
5124 .start_ap = brcmf_cfg80211_start_ap,
5125 .stop_ap = brcmf_cfg80211_stop_ap,
5126 .change_beacon = brcmf_cfg80211_change_beacon,
5127 .del_station = brcmf_cfg80211_del_station,
5128 .change_station = brcmf_cfg80211_change_station,
5129 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
5130 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
5131 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
5132 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
5133 .remain_on_channel = brcmf_p2p_remain_on_channel,
5134 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
5135 .get_channel = brcmf_cfg80211_get_channel,
5136 .start_p2p_device = brcmf_p2p_start_device,
5137 .stop_p2p_device = brcmf_p2p_stop_device,
5138 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
5139 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
5140 .tdls_oper = brcmf_cfg80211_tdls_oper,
5143 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
5144 enum nl80211_iftype type)
5146 struct brcmf_cfg80211_vif *vif_walk;
5147 struct brcmf_cfg80211_vif *vif;
5150 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
5152 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
5154 return ERR_PTR(-ENOMEM);
5156 vif->wdev.wiphy = cfg->wiphy;
5157 vif->wdev.iftype = type;
5159 brcmf_init_prof(&vif->profile);
5161 if (type == NL80211_IFTYPE_AP) {
5163 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
5164 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
5172 list_add_tail(&vif->list, &cfg->vif_list);
5176 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
5178 list_del(&vif->list);
5182 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
5184 struct brcmf_cfg80211_vif *vif;
5185 struct brcmf_if *ifp;
5187 ifp = netdev_priv(ndev);
5191 brcmf_free_vif(vif);
5195 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
5197 u32 event = e->event_code;
5198 u32 status = e->status;
5200 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
5201 brcmf_dbg(CONN, "Processing set ssid\n");
5208 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
5210 u32 event = e->event_code;
5211 u16 flags = e->flags;
5213 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
5214 (event == BRCMF_E_DISASSOC_IND) ||
5215 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
5216 brcmf_dbg(CONN, "Processing link down\n");
5222 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
5223 const struct brcmf_event_msg *e)
5225 u32 event = e->event_code;
5226 u32 status = e->status;
5228 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
5229 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
5230 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
5234 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
5235 brcmf_dbg(CONN, "Processing connecting & no network found\n");
5242 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
5244 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5246 kfree(conn_info->req_ie);
5247 conn_info->req_ie = NULL;
5248 conn_info->req_ie_len = 0;
5249 kfree(conn_info->resp_ie);
5250 conn_info->resp_ie = NULL;
5251 conn_info->resp_ie_len = 0;
5254 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
5255 struct brcmf_if *ifp)
5257 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
5258 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5263 brcmf_clear_assoc_ies(cfg);
5265 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5266 cfg->extra_buf, WL_ASSOC_INFO_MAX);
5268 brcmf_err("could not get assoc info (%d)\n", err);
5272 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5273 req_len = le32_to_cpu(assoc_info->req_len);
5274 resp_len = le32_to_cpu(assoc_info->resp_len);
5276 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5280 brcmf_err("could not get assoc req (%d)\n", err);
5283 conn_info->req_ie_len = req_len;
5285 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5288 conn_info->req_ie_len = 0;
5289 conn_info->req_ie = NULL;
5292 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5296 brcmf_err("could not get assoc resp (%d)\n", err);
5299 conn_info->resp_ie_len = resp_len;
5300 conn_info->resp_ie =
5301 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5304 conn_info->resp_ie_len = 0;
5305 conn_info->resp_ie = NULL;
5307 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5308 conn_info->req_ie_len, conn_info->resp_ie_len);
5314 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5315 struct net_device *ndev,
5316 const struct brcmf_event_msg *e)
5318 struct brcmf_if *ifp = netdev_priv(ndev);
5319 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5320 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5321 struct wiphy *wiphy = cfg_to_wiphy(cfg);
5322 struct ieee80211_channel *notify_channel = NULL;
5323 struct ieee80211_supported_band *band;
5324 struct brcmf_bss_info_le *bi;
5325 struct brcmu_chan ch;
5330 brcmf_dbg(TRACE, "Enter\n");
5332 brcmf_get_assoc_ies(cfg, ifp);
5333 memcpy(profile->bssid, e->addr, ETH_ALEN);
5334 brcmf_update_bss_info(cfg, ifp);
5336 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5342 /* data sent to dongle has to be little endian */
5343 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5344 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
5345 buf, WL_BSS_INFO_MAX);
5350 bi = (struct brcmf_bss_info_le *)(buf + 4);
5351 ch.chspec = le16_to_cpu(bi->chanspec);
5352 cfg->d11inf.decchspec(&ch);
5354 if (ch.band == BRCMU_CHAN_BAND_2G)
5355 band = wiphy->bands[NL80211_BAND_2GHZ];
5357 band = wiphy->bands[NL80211_BAND_5GHZ];
5359 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
5360 notify_channel = ieee80211_get_channel(wiphy, freq);
5364 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
5365 conn_info->req_ie, conn_info->req_ie_len,
5366 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
5367 brcmf_dbg(CONN, "Report roaming result\n");
5369 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
5370 brcmf_dbg(TRACE, "Exit\n");
5375 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
5376 struct net_device *ndev, const struct brcmf_event_msg *e,
5379 struct brcmf_if *ifp = netdev_priv(ndev);
5380 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5381 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5383 brcmf_dbg(TRACE, "Enter\n");
5385 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5386 &ifp->vif->sme_state)) {
5388 brcmf_get_assoc_ies(cfg, ifp);
5389 memcpy(profile->bssid, e->addr, ETH_ALEN);
5390 brcmf_update_bss_info(cfg, ifp);
5391 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5392 &ifp->vif->sme_state);
5394 cfg80211_connect_result(ndev,
5395 (u8 *)profile->bssid,
5397 conn_info->req_ie_len,
5399 conn_info->resp_ie_len,
5400 completed ? WLAN_STATUS_SUCCESS :
5401 WLAN_STATUS_AUTH_TIMEOUT,
5403 brcmf_dbg(CONN, "Report connect result - connection %s\n",
5404 completed ? "succeeded" : "failed");
5406 brcmf_dbg(TRACE, "Exit\n");
5411 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
5412 struct net_device *ndev,
5413 const struct brcmf_event_msg *e, void *data)
5415 static int generation;
5416 u32 event = e->event_code;
5417 u32 reason = e->reason;
5418 struct station_info sinfo;
5420 brcmf_dbg(CONN, "event %s (%u), reason %d\n",
5421 brcmf_fweh_event_name(event), event, reason);
5422 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5423 ndev != cfg_to_ndev(cfg)) {
5424 brcmf_dbg(CONN, "AP mode link down\n");
5425 complete(&cfg->vif_disabled);
5429 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5430 (reason == BRCMF_E_STATUS_SUCCESS)) {
5431 memset(&sinfo, 0, sizeof(sinfo));
5433 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5436 sinfo.assoc_req_ies = data;
5437 sinfo.assoc_req_ies_len = e->datalen;
5439 sinfo.generation = generation;
5440 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5441 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5442 (event == BRCMF_E_DEAUTH_IND) ||
5443 (event == BRCMF_E_DEAUTH)) {
5444 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5450 brcmf_notify_connect_status(struct brcmf_if *ifp,
5451 const struct brcmf_event_msg *e, void *data)
5453 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5454 struct net_device *ndev = ifp->ndev;
5455 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5456 struct ieee80211_channel *chan;
5459 if ((e->event_code == BRCMF_E_DEAUTH) ||
5460 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5461 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5462 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5463 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5466 if (brcmf_is_apmode(ifp->vif)) {
5467 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5468 } else if (brcmf_is_linkup(e)) {
5469 brcmf_dbg(CONN, "Linkup\n");
5470 if (brcmf_is_ibssmode(ifp->vif)) {
5471 brcmf_inform_ibss(cfg, ndev, e->addr);
5472 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5473 memcpy(profile->bssid, e->addr, ETH_ALEN);
5474 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5475 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5476 &ifp->vif->sme_state);
5477 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5478 &ifp->vif->sme_state);
5480 brcmf_bss_connect_done(cfg, ndev, e, true);
5481 brcmf_net_setcarrier(ifp, true);
5482 } else if (brcmf_is_linkdown(e)) {
5483 brcmf_dbg(CONN, "Linkdown\n");
5484 if (!brcmf_is_ibssmode(ifp->vif)) {
5485 brcmf_bss_connect_done(cfg, ndev, e, false);
5486 brcmf_link_down(ifp->vif,
5487 brcmf_map_fw_linkdown_reason(e));
5488 brcmf_init_prof(ndev_to_prof(ndev));
5489 if (ndev != cfg_to_ndev(cfg))
5490 complete(&cfg->vif_disabled);
5491 brcmf_net_setcarrier(ifp, false);
5493 } else if (brcmf_is_nonetwork(cfg, e)) {
5494 if (brcmf_is_ibssmode(ifp->vif))
5495 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5496 &ifp->vif->sme_state);
5498 brcmf_bss_connect_done(cfg, ndev, e, false);
5505 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5506 const struct brcmf_event_msg *e, void *data)
5508 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5509 u32 event = e->event_code;
5510 u32 status = e->status;
5512 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5513 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5514 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5516 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5523 brcmf_notify_mic_status(struct brcmf_if *ifp,
5524 const struct brcmf_event_msg *e, void *data)
5526 u16 flags = e->flags;
5527 enum nl80211_key_type key_type;
5529 if (flags & BRCMF_EVENT_MSG_GROUP)
5530 key_type = NL80211_KEYTYPE_GROUP;
5532 key_type = NL80211_KEYTYPE_PAIRWISE;
5534 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5540 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5541 const struct brcmf_event_msg *e, void *data)
5543 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5544 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5545 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5546 struct brcmf_cfg80211_vif *vif;
5548 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5549 ifevent->action, ifevent->flags, ifevent->ifidx,
5550 ifevent->bsscfgidx);
5552 spin_lock(&event->vif_event_lock);
5553 event->action = ifevent->action;
5556 switch (ifevent->action) {
5557 case BRCMF_E_IF_ADD:
5558 /* waiting process may have timed out */
5559 if (!cfg->vif_event.vif) {
5560 spin_unlock(&event->vif_event_lock);
5567 vif->wdev.netdev = ifp->ndev;
5568 ifp->ndev->ieee80211_ptr = &vif->wdev;
5569 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5571 spin_unlock(&event->vif_event_lock);
5572 wake_up(&event->vif_wq);
5575 case BRCMF_E_IF_DEL:
5576 spin_unlock(&event->vif_event_lock);
5577 /* event may not be upon user request */
5578 if (brcmf_cfg80211_vif_event_armed(cfg))
5579 wake_up(&event->vif_wq);
5582 case BRCMF_E_IF_CHANGE:
5583 spin_unlock(&event->vif_event_lock);
5584 wake_up(&event->vif_wq);
5588 spin_unlock(&event->vif_event_lock);
5594 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5596 conf->frag_threshold = (u32)-1;
5597 conf->rts_threshold = (u32)-1;
5598 conf->retry_short = (u32)-1;
5599 conf->retry_long = (u32)-1;
5602 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5604 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5605 brcmf_notify_connect_status);
5606 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5607 brcmf_notify_connect_status);
5608 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5609 brcmf_notify_connect_status);
5610 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5611 brcmf_notify_connect_status);
5612 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5613 brcmf_notify_connect_status);
5614 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5615 brcmf_notify_connect_status);
5616 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5617 brcmf_notify_roaming_status);
5618 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5619 brcmf_notify_mic_status);
5620 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5621 brcmf_notify_connect_status);
5622 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5623 brcmf_notify_sched_scan_results);
5624 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5625 brcmf_notify_vif_event);
5626 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5627 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5628 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5629 brcmf_p2p_notify_listen_complete);
5630 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5631 brcmf_p2p_notify_action_frame_rx);
5632 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5633 brcmf_p2p_notify_action_tx_complete);
5634 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5635 brcmf_p2p_notify_action_tx_complete);
5638 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5642 kfree(cfg->extra_buf);
5643 cfg->extra_buf = NULL;
5644 kfree(cfg->wowl.nd);
5645 cfg->wowl.nd = NULL;
5646 kfree(cfg->wowl.nd_info);
5647 cfg->wowl.nd_info = NULL;
5648 kfree(cfg->escan_info.escan_buf);
5649 cfg->escan_info.escan_buf = NULL;
5652 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5654 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5656 goto init_priv_mem_out;
5657 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5658 if (!cfg->extra_buf)
5659 goto init_priv_mem_out;
5660 cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
5662 goto init_priv_mem_out;
5663 cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
5664 sizeof(struct cfg80211_wowlan_nd_match *),
5666 if (!cfg->wowl.nd_info)
5667 goto init_priv_mem_out;
5668 cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
5669 if (!cfg->escan_info.escan_buf)
5670 goto init_priv_mem_out;
5675 brcmf_deinit_priv_mem(cfg);
5680 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5684 cfg->scan_request = NULL;
5685 cfg->pwr_save = true;
5686 cfg->active_scan = true; /* we do active scan per default */
5687 cfg->dongle_up = false; /* dongle is not up yet */
5688 err = brcmf_init_priv_mem(cfg);
5691 brcmf_register_event_handlers(cfg);
5692 mutex_init(&cfg->usr_sync);
5693 brcmf_init_escan(cfg);
5694 brcmf_init_conf(cfg->conf);
5695 init_completion(&cfg->vif_disabled);
5699 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5701 cfg->dongle_up = false; /* dongle down */
5702 brcmf_abort_scanning(cfg);
5703 brcmf_deinit_priv_mem(cfg);
5706 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5708 init_waitqueue_head(&event->vif_wq);
5709 spin_lock_init(&event->vif_event_lock);
5712 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
5716 __le32 roamtrigger[2];
5717 __le32 roam_delta[2];
5719 /* Configure beacon timeout value based upon roaming setting */
5720 if (ifp->drvr->settings->roamoff)
5721 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
5723 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
5724 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5726 brcmf_err("bcn_timeout error (%d)\n", err);
5727 goto roam_setup_done;
5730 /* Enable/Disable built-in roaming to allow supplicant to take care of
5733 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5734 ifp->drvr->settings->roamoff ? "Off" : "On");
5735 err = brcmf_fil_iovar_int_set(ifp, "roam_off",
5736 ifp->drvr->settings->roamoff);
5738 brcmf_err("roam_off error (%d)\n", err);
5739 goto roam_setup_done;
5742 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5743 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5744 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5745 (void *)roamtrigger, sizeof(roamtrigger));
5747 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5748 goto roam_setup_done;
5751 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5752 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5753 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5754 (void *)roam_delta, sizeof(roam_delta));
5756 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5757 goto roam_setup_done;
5765 brcmf_dongle_scantime(struct brcmf_if *ifp)
5769 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5770 BRCMF_SCAN_CHANNEL_TIME);
5772 brcmf_err("Scan assoc time error (%d)\n", err);
5773 goto dongle_scantime_out;
5775 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5776 BRCMF_SCAN_UNASSOC_TIME);
5778 brcmf_err("Scan unassoc time error (%d)\n", err);
5779 goto dongle_scantime_out;
5782 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5783 BRCMF_SCAN_PASSIVE_TIME);
5785 brcmf_err("Scan passive time error (%d)\n", err);
5786 goto dongle_scantime_out;
5789 dongle_scantime_out:
5793 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5794 struct brcmu_chan *ch)
5798 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5799 if (ch->sb == BRCMU_CHAN_SB_U) {
5800 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5801 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5802 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5804 /* It should be one of
5805 * IEEE80211_CHAN_NO_HT40 or
5806 * IEEE80211_CHAN_NO_HT40PLUS
5808 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5809 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5810 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5814 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5817 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5818 struct ieee80211_supported_band *band;
5819 struct ieee80211_channel *channel;
5820 struct wiphy *wiphy;
5821 struct brcmf_chanspec_list *list;
5822 struct brcmu_chan ch;
5830 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5835 list = (struct brcmf_chanspec_list *)pbuf;
5837 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5840 brcmf_err("get chanspecs error (%d)\n", err);
5844 wiphy = cfg_to_wiphy(cfg);
5845 band = wiphy->bands[NL80211_BAND_2GHZ];
5847 for (i = 0; i < band->n_channels; i++)
5848 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5849 band = wiphy->bands[NL80211_BAND_5GHZ];
5851 for (i = 0; i < band->n_channels; i++)
5852 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5854 total = le32_to_cpu(list->count);
5855 for (i = 0; i < total; i++) {
5856 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5857 cfg->d11inf.decchspec(&ch);
5859 if (ch.band == BRCMU_CHAN_BAND_2G) {
5860 band = wiphy->bands[NL80211_BAND_2GHZ];
5861 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5862 band = wiphy->bands[NL80211_BAND_5GHZ];
5864 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5869 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5870 ch.bw == BRCMU_CHAN_BW_40)
5872 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5873 ch.bw == BRCMU_CHAN_BW_80)
5876 channel = band->channels;
5877 index = band->n_channels;
5878 for (j = 0; j < band->n_channels; j++) {
5879 if (channel[j].hw_value == ch.control_ch_num) {
5884 channel[index].center_freq =
5885 ieee80211_channel_to_frequency(ch.control_ch_num,
5887 channel[index].hw_value = ch.control_ch_num;
5889 /* assuming the chanspecs order is HT20,
5890 * HT40 upper, HT40 lower, and VHT80.
5892 if (ch.bw == BRCMU_CHAN_BW_80) {
5893 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5894 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5895 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5897 /* enable the channel and disable other bandwidths
5898 * for now as mentioned order assure they are enabled
5899 * for subsequent chanspecs.
5901 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5902 IEEE80211_CHAN_NO_80MHZ;
5903 ch.bw = BRCMU_CHAN_BW_20;
5904 cfg->d11inf.encchspec(&ch);
5905 chaninfo = ch.chspec;
5906 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5909 if (chaninfo & WL_CHAN_RADAR)
5910 channel[index].flags |=
5911 (IEEE80211_CHAN_RADAR |
5912 IEEE80211_CHAN_NO_IR);
5913 if (chaninfo & WL_CHAN_PASSIVE)
5914 channel[index].flags |=
5915 IEEE80211_CHAN_NO_IR;
5925 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5927 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5928 struct ieee80211_supported_band *band;
5929 struct brcmf_fil_bwcap_le band_bwcap;
5930 struct brcmf_chanspec_list *list;
5934 struct brcmu_chan ch;
5938 /* verify support for bw_cap command */
5940 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5943 /* only set 2G bandwidth using bw_cap command */
5944 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5945 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5946 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5947 sizeof(band_bwcap));
5949 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5950 val = WLC_N_BW_40ALL;
5951 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5955 /* update channel info in 2G band */
5956 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5961 ch.band = BRCMU_CHAN_BAND_2G;
5962 ch.bw = BRCMU_CHAN_BW_40;
5963 ch.sb = BRCMU_CHAN_SB_NONE;
5965 cfg->d11inf.encchspec(&ch);
5967 /* pass encoded chanspec in query */
5968 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5970 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5973 brcmf_err("get chanspecs error (%d)\n", err);
5978 band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
5979 list = (struct brcmf_chanspec_list *)pbuf;
5980 num_chan = le32_to_cpu(list->count);
5981 for (i = 0; i < num_chan; i++) {
5982 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5983 cfg->d11inf.decchspec(&ch);
5984 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5986 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5988 for (j = 0; j < band->n_channels; j++) {
5989 if (band->channels[j].hw_value == ch.control_ch_num)
5992 if (WARN_ON(j == band->n_channels))
5995 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
6002 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
6004 u32 band, mimo_bwcap;
6008 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6010 bw_cap[NL80211_BAND_2GHZ] = band;
6012 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
6014 bw_cap[NL80211_BAND_5GHZ] = band;
6020 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
6022 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
6024 /* assume 20MHz if firmware does not give a clue */
6025 mimo_bwcap = WLC_N_BW_20ALL;
6027 switch (mimo_bwcap) {
6028 case WLC_N_BW_40ALL:
6029 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
6031 case WLC_N_BW_20IN2G_40IN5G:
6032 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
6034 case WLC_N_BW_20ALL:
6035 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
6036 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
6039 brcmf_err("invalid mimo_bw_cap value\n");
6043 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
6044 u32 bw_cap[2], u32 nchain)
6046 band->ht_cap.ht_supported = true;
6047 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
6048 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
6049 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6051 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
6052 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
6053 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
6054 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
6055 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
6056 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
6059 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
6064 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
6065 mcs_map = (mcs_map << 2) | supp;
6067 return cpu_to_le16(mcs_map);
6070 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
6071 u32 bw_cap[2], u32 nchain, u32 txstreams,
6072 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
6076 /* not allowed in 2.4G band */
6077 if (band->band == NL80211_BAND_2GHZ)
6080 band->vht_cap.vht_supported = true;
6081 /* 80MHz is mandatory */
6082 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
6083 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
6084 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
6085 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
6087 /* all support 256-QAM */
6088 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
6089 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
6090 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
6092 /* Beamforming support information */
6093 if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
6094 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
6095 if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
6096 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
6097 if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
6098 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
6099 if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
6100 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
6102 if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
6103 band->vht_cap.cap |=
6104 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
6105 band->vht_cap.cap |= ((txstreams - 1) <<
6106 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
6107 band->vht_cap.cap |=
6108 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
6112 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
6114 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6115 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6118 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
6123 struct ieee80211_supported_band *band;
6125 u32 txbf_bfe_cap = 0;
6126 u32 txbf_bfr_cap = 0;
6128 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
6129 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
6131 brcmf_err("nmode error (%d)\n", err);
6133 brcmf_get_bwcap(ifp, bw_cap);
6135 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
6136 nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
6137 bw_cap[NL80211_BAND_5GHZ]);
6139 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
6141 brcmf_err("rxchain error (%d)\n", err);
6144 for (nchain = 0; rxchain; nchain++)
6145 rxchain = rxchain & (rxchain - 1);
6147 brcmf_dbg(INFO, "nchain=%d\n", nchain);
6149 err = brcmf_construct_chaninfo(cfg, bw_cap);
6151 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
6156 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
6157 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
6159 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
6163 wiphy = cfg_to_wiphy(cfg);
6164 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
6165 band = wiphy->bands[i];
6170 brcmf_update_ht_cap(band, bw_cap, nchain);
6172 brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
6173 txbf_bfe_cap, txbf_bfr_cap);
6179 static const struct ieee80211_txrx_stypes
6180 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
6181 [NL80211_IFTYPE_STATION] = {
6183 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6184 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6186 [NL80211_IFTYPE_P2P_CLIENT] = {
6188 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6189 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6191 [NL80211_IFTYPE_P2P_GO] = {
6193 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
6194 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
6195 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
6196 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
6197 BIT(IEEE80211_STYPE_AUTH >> 4) |
6198 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
6199 BIT(IEEE80211_STYPE_ACTION >> 4)
6201 [NL80211_IFTYPE_P2P_DEVICE] = {
6203 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
6204 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
6209 * brcmf_setup_ifmodes() - determine interface modes and combinations.
6211 * @wiphy: wiphy object.
6212 * @ifp: interface object needed for feat module api.
6214 * The interface modes and combinations are determined dynamically here
6215 * based on firmware functionality.
6217 * no p2p and no mbss:
6219 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6223 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6224 * #AP <= 4, matching BI, channels = 1, 4 total
6226 * p2p, no mchan, and mbss:
6228 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
6229 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6230 * #AP <= 4, matching BI, channels = 1, 4 total
6232 * p2p, mchan, and mbss:
6234 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6235 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6236 * #AP <= 4, matching BI, channels = 1, 4 total
6238 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
6240 struct ieee80211_iface_combination *combo = NULL;
6241 struct ieee80211_iface_limit *c0_limits = NULL;
6242 struct ieee80211_iface_limit *p2p_limits = NULL;
6243 struct ieee80211_iface_limit *mbss_limits = NULL;
6247 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
6248 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
6250 n_combos = 1 + !!p2p + !!mbss;
6251 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
6255 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6256 BIT(NL80211_IFTYPE_ADHOC) |
6257 BIT(NL80211_IFTYPE_AP);
6261 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
6264 c0_limits[i].max = 1;
6265 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6267 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
6268 combo[c].num_different_channels = 2;
6269 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
6270 BIT(NL80211_IFTYPE_P2P_GO) |
6271 BIT(NL80211_IFTYPE_P2P_DEVICE);
6272 c0_limits[i].max = 1;
6273 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6274 c0_limits[i].max = 1;
6275 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
6276 BIT(NL80211_IFTYPE_P2P_GO);
6278 c0_limits[i].max = 1;
6279 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6281 combo[c].num_different_channels = 1;
6282 combo[c].max_interfaces = i;
6283 combo[c].n_limits = i;
6284 combo[c].limits = c0_limits;
6289 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
6292 p2p_limits[i].max = 1;
6293 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6294 p2p_limits[i].max = 1;
6295 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6296 p2p_limits[i].max = 1;
6297 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
6298 p2p_limits[i].max = 1;
6299 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6300 combo[c].num_different_channels = 1;
6301 combo[c].max_interfaces = i;
6302 combo[c].n_limits = i;
6303 combo[c].limits = p2p_limits;
6309 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
6312 mbss_limits[i].max = 4;
6313 mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6314 combo[c].beacon_int_infra_match = true;
6315 combo[c].num_different_channels = 1;
6316 combo[c].max_interfaces = 4;
6317 combo[c].n_limits = i;
6318 combo[c].limits = mbss_limits;
6321 wiphy->n_iface_combinations = n_combos;
6322 wiphy->iface_combinations = combo;
6333 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
6335 /* scheduled scan settings */
6336 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
6337 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6338 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6339 wiphy->max_sched_scan_plan_interval = BRCMF_PNO_SCHED_SCAN_MAX_PERIOD;
6340 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6344 static struct wiphy_wowlan_support brcmf_wowlan_support = {
6345 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
6346 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
6347 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
6348 .pattern_min_len = 1,
6349 .max_pkt_offset = 1500,
6353 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6356 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6358 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6359 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
6360 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
6361 init_waitqueue_head(&cfg->wowl.nd_data_wait);
6364 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
6365 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
6366 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
6369 wiphy->wowlan = &brcmf_wowlan_support;
6373 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6375 struct brcmf_pub *drvr = ifp->drvr;
6376 const struct ieee80211_iface_combination *combo;
6377 struct ieee80211_supported_band *band;
6378 u16 max_interfaces = 0;
6383 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
6384 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6385 wiphy->max_num_pmkids = BRCMF_MAXPMKID;
6387 err = brcmf_setup_ifmodes(wiphy, ifp);
6391 for (i = 0, combo = wiphy->iface_combinations;
6392 i < wiphy->n_iface_combinations; i++, combo++) {
6393 max_interfaces = max(max_interfaces, combo->max_interfaces);
6396 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
6398 u8 *addr = drvr->addresses[i].addr;
6400 memcpy(addr, drvr->mac, ETH_ALEN);
6403 addr[ETH_ALEN - 1] ^= i;
6406 wiphy->addresses = drvr->addresses;
6407 wiphy->n_addresses = i;
6409 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6410 wiphy->cipher_suites = brcmf_cipher_suites;
6411 wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
6412 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
6413 wiphy->n_cipher_suites--;
6414 wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
6415 BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
6416 BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
6418 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
6419 WIPHY_FLAG_OFFCHAN_TX |
6420 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6421 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
6422 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6423 if (!ifp->drvr->settings->roamoff)
6424 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6425 wiphy->mgmt_stypes = brcmf_txrx_stypes;
6426 wiphy->max_remain_on_channel_duration = 5000;
6427 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
6428 brcmf_wiphy_pno_params(wiphy);
6430 /* vendor commands/events support */
6431 wiphy->vendor_commands = brcmf_vendor_cmds;
6432 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
6434 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
6435 brcmf_wiphy_wowl_params(wiphy, ifp);
6436 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
6439 brcmf_err("could not obtain band info: err=%d\n", err);
6442 /* first entry in bandlist is number of bands */
6443 n_bands = le32_to_cpu(bandlist[0]);
6444 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
6445 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
6446 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
6451 band->channels = kmemdup(&__wl_2ghz_channels,
6452 sizeof(__wl_2ghz_channels),
6454 if (!band->channels) {
6459 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6460 wiphy->bands[NL80211_BAND_2GHZ] = band;
6462 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6463 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6468 band->channels = kmemdup(&__wl_5ghz_channels,
6469 sizeof(__wl_5ghz_channels),
6471 if (!band->channels) {
6476 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6477 wiphy->bands[NL80211_BAND_5GHZ] = band;
6480 err = brcmf_setup_wiphybands(wiphy);
6484 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6486 struct net_device *ndev;
6487 struct wireless_dev *wdev;
6488 struct brcmf_if *ifp;
6495 ndev = cfg_to_ndev(cfg);
6496 wdev = ndev->ieee80211_ptr;
6497 ifp = netdev_priv(ndev);
6499 /* make sure RF is ready for work */
6500 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6502 brcmf_dongle_scantime(ifp);
6504 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6505 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6507 goto default_conf_out;
6508 brcmf_dbg(INFO, "power save set to %s\n",
6509 (power_mode ? "enabled" : "disabled"));
6511 err = brcmf_dongle_roam(ifp);
6513 goto default_conf_out;
6514 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6517 goto default_conf_out;
6519 brcmf_configure_arp_nd_offload(ifp, true);
6521 cfg->dongle_up = true;
6528 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6530 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6532 return brcmf_config_dongle(ifp->drvr->config);
6535 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6537 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6540 * While going down, if associated with AP disassociate
6541 * from AP to save power
6543 if (check_vif_up(ifp->vif)) {
6544 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6546 /* Make sure WPA_Supplicant receives all the event
6547 generated due to DISASSOC call to the fw to keep
6548 the state fw and WPA_Supplicant state consistent
6553 brcmf_abort_scanning(cfg);
6554 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6559 s32 brcmf_cfg80211_up(struct net_device *ndev)
6561 struct brcmf_if *ifp = netdev_priv(ndev);
6562 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6565 mutex_lock(&cfg->usr_sync);
6566 err = __brcmf_cfg80211_up(ifp);
6567 mutex_unlock(&cfg->usr_sync);
6572 s32 brcmf_cfg80211_down(struct net_device *ndev)
6574 struct brcmf_if *ifp = netdev_priv(ndev);
6575 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6578 mutex_lock(&cfg->usr_sync);
6579 err = __brcmf_cfg80211_down(ifp);
6580 mutex_unlock(&cfg->usr_sync);
6585 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6587 struct wireless_dev *wdev = &ifp->vif->wdev;
6589 return wdev->iftype;
6592 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6593 unsigned long state)
6595 struct brcmf_cfg80211_vif *vif;
6597 list_for_each_entry(vif, &cfg->vif_list, list) {
6598 if (test_bit(state, &vif->sme_state))
6604 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6609 spin_lock(&event->vif_event_lock);
6610 evt_action = event->action;
6611 spin_unlock(&event->vif_event_lock);
6612 return evt_action == action;
6615 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6616 struct brcmf_cfg80211_vif *vif)
6618 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6620 spin_lock(&event->vif_event_lock);
6623 spin_unlock(&event->vif_event_lock);
6626 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6628 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6631 spin_lock(&event->vif_event_lock);
6632 armed = event->vif != NULL;
6633 spin_unlock(&event->vif_event_lock);
6638 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
6639 u8 action, ulong timeout)
6641 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6643 return wait_event_timeout(event->vif_wq,
6644 vif_event_equals(event, action), timeout);
6647 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6648 struct brcmf_fil_country_le *ccreq)
6650 struct brcmfmac_pd_cc *country_codes;
6651 struct brcmfmac_pd_cc_entry *cc;
6655 country_codes = drvr->settings->country_codes;
6656 if (!country_codes) {
6657 brcmf_dbg(TRACE, "No country codes configured for device\n");
6661 if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6662 (alpha2[1] == ccreq->country_abbrev[1])) {
6663 brcmf_dbg(TRACE, "Country code already set\n");
6668 for (i = 0; i < country_codes->table_size; i++) {
6669 cc = &country_codes->table[i];
6670 if ((cc->iso3166[0] == '\0') && (found_index == -1))
6672 if ((cc->iso3166[0] == alpha2[0]) &&
6673 (cc->iso3166[1] == alpha2[1])) {
6678 if (found_index == -1) {
6679 brcmf_dbg(TRACE, "No country code match found\n");
6682 memset(ccreq, 0, sizeof(*ccreq));
6683 ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6684 memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6685 BRCMF_COUNTRY_BUF_SZ);
6686 ccreq->country_abbrev[0] = alpha2[0];
6687 ccreq->country_abbrev[1] = alpha2[1];
6688 ccreq->country_abbrev[2] = 0;
6693 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6694 struct regulatory_request *req)
6696 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6697 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6698 struct brcmf_fil_country_le ccreq;
6702 /* ignore non-ISO3166 country codes */
6703 for (i = 0; i < sizeof(req->alpha2); i++)
6704 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6705 brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
6706 req->alpha2[0], req->alpha2[1]);
6710 brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6711 req->alpha2[0], req->alpha2[1]);
6713 err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6715 brcmf_err("Country code iovar returned err = %d\n", err);
6719 err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6723 err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6725 brcmf_err("Firmware rejected country setting\n");
6728 brcmf_setup_wiphybands(wiphy);
6731 static void brcmf_free_wiphy(struct wiphy *wiphy)
6738 if (wiphy->iface_combinations) {
6739 for (i = 0; i < wiphy->n_iface_combinations; i++)
6740 kfree(wiphy->iface_combinations[i].limits);
6742 kfree(wiphy->iface_combinations);
6743 if (wiphy->bands[NL80211_BAND_2GHZ]) {
6744 kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
6745 kfree(wiphy->bands[NL80211_BAND_2GHZ]);
6747 if (wiphy->bands[NL80211_BAND_5GHZ]) {
6748 kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
6749 kfree(wiphy->bands[NL80211_BAND_5GHZ]);
6754 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6755 struct device *busdev,
6758 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6759 struct brcmf_cfg80211_info *cfg;
6760 struct wiphy *wiphy;
6761 struct cfg80211_ops *ops;
6762 struct brcmf_cfg80211_vif *vif;
6763 struct brcmf_if *ifp;
6769 brcmf_err("ndev is invalid\n");
6773 ops = kmemdup(&brcmf_cfg80211_ops, sizeof(*ops), GFP_KERNEL);
6777 ifp = netdev_priv(ndev);
6779 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
6780 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
6782 wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
6784 brcmf_err("Could not allocate wiphy device\n");
6787 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6788 set_wiphy_dev(wiphy, busdev);
6790 cfg = wiphy_priv(wiphy);
6794 init_vif_event(&cfg->vif_event);
6795 INIT_LIST_HEAD(&cfg->vif_list);
6797 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
6802 vif->wdev.netdev = ndev;
6803 ndev->ieee80211_ptr = &vif->wdev;
6804 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6806 err = wl_init_priv(cfg);
6808 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6809 brcmf_free_vif(vif);
6814 /* determine d11 io type before wiphy setup */
6815 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6817 brcmf_err("Failed to get D11 version (%d)\n", err);
6820 cfg->d11inf.io_type = (u8)io_type;
6821 brcmu_d11_attach(&cfg->d11inf);
6823 err = brcmf_setup_wiphy(wiphy, ifp);
6827 brcmf_dbg(INFO, "Registering custom regulatory\n");
6828 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6829 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6830 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6832 /* firmware defaults to 40MHz disabled in 2G band. We signal
6833 * cfg80211 here that we do and have it decide we can enable
6834 * it. But first check if device does support 2G operation.
6836 if (wiphy->bands[NL80211_BAND_2GHZ]) {
6837 cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
6838 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6840 err = wiphy_register(wiphy);
6842 brcmf_err("Could not register wiphy device (%d)\n", err);
6846 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6847 * setup 40MHz in 2GHz band and enable OBSS scanning.
6849 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6850 err = brcmf_enable_bw40_2g(cfg);
6852 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6853 BRCMF_OBSS_COEX_AUTO);
6855 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6857 /* p2p might require that "if-events" get processed by fweh. So
6858 * activate the already registered event handlers now and activate
6859 * the rest when initialization has completed. drvr->config needs to
6860 * be assigned before activating events.
6863 err = brcmf_fweh_activate_events(ifp);
6865 brcmf_err("FWEH activation failed (%d)\n", err);
6866 goto wiphy_unreg_out;
6869 err = brcmf_p2p_attach(cfg, p2pdev_forced);
6871 brcmf_err("P2P initialisation failed (%d)\n", err);
6872 goto wiphy_unreg_out;
6874 err = brcmf_btcoex_attach(cfg);
6876 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6877 brcmf_p2p_detach(&cfg->p2p);
6878 goto wiphy_unreg_out;
6881 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
6882 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6884 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6885 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6887 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6888 brcmf_notify_tdls_peer_event);
6892 /* (re-) activate FWEH event handling */
6893 err = brcmf_fweh_activate_events(ifp);
6895 brcmf_err("FWEH activation failed (%d)\n", err);
6899 /* Fill in some of the advertised nl80211 supported features */
6900 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
6901 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
6903 if (wiphy->wowlan &&
6904 wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
6905 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6912 brcmf_btcoex_detach(cfg);
6913 brcmf_p2p_detach(&cfg->p2p);
6915 wiphy_unregister(cfg->wiphy);
6917 wl_deinit_priv(cfg);
6918 brcmf_free_vif(vif);
6921 brcmf_free_wiphy(wiphy);
6926 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6931 brcmf_btcoex_detach(cfg);
6932 wiphy_unregister(cfg->wiphy);
6934 wl_deinit_priv(cfg);
6935 brcmf_free_wiphy(cfg->wiphy);