2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <linux/module.h>
22 #include <linux/vmalloc.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
26 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
31 #include "tracepoint.h"
32 #include "fwil_types.h"
43 #define BRCMF_SCAN_IE_LEN_MAX 2048
44 #define BRCMF_PNO_VERSION 2
45 #define BRCMF_PNO_TIME 30
46 #define BRCMF_PNO_REPEAT 4
47 #define BRCMF_PNO_FREQ_EXPO_MAX 3
48 #define BRCMF_PNO_MAX_PFN_COUNT 16
49 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
50 #define BRCMF_PNO_HIDDEN_BIT 2
51 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
52 #define BRCMF_PNO_SCAN_COMPLETE 1
53 #define BRCMF_PNO_SCAN_INCOMPLETE 0
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
59 #define WPS_OUI_TYPE 4
61 #define VS_IE_FIXED_HDR_LEN 6
62 #define WPA_IE_VERSION_LEN 2
63 #define WPA_IE_MIN_OUI_LEN 4
64 #define WPA_IE_SUITE_COUNT_LEN 2
66 #define WPA_CIPHER_NONE 0 /* None */
67 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
72 #define RSN_AKM_NONE 0 /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74 #define RSN_AKM_PSK 2 /* Pre-shared Key */
75 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
81 #define VNDR_IE_COUNT_OFFSET 4
82 #define VNDR_IE_PKTFLAG_OFFSET 8
83 #define VNDR_IE_VSIE_OFFSET 12
84 #define VNDR_IE_HDR_SIZE 12
85 #define VNDR_IE_PARSE_LIMIT 5
87 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
91 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
92 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
97 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
99 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
100 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
107 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
108 #define RATETAB_ENT(_rateid, _flags) \
110 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
111 .hw_value = (_rateid), \
115 static struct ieee80211_rate __wl_rates[] = {
116 RATETAB_ENT(BRCM_RATE_1M, 0),
117 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
118 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATETAB_ENT(BRCM_RATE_6M, 0),
121 RATETAB_ENT(BRCM_RATE_9M, 0),
122 RATETAB_ENT(BRCM_RATE_12M, 0),
123 RATETAB_ENT(BRCM_RATE_18M, 0),
124 RATETAB_ENT(BRCM_RATE_24M, 0),
125 RATETAB_ENT(BRCM_RATE_36M, 0),
126 RATETAB_ENT(BRCM_RATE_48M, 0),
127 RATETAB_ENT(BRCM_RATE_54M, 0),
130 #define wl_g_rates (__wl_rates + 0)
131 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
132 #define wl_a_rates (__wl_rates + 4)
133 #define wl_a_rates_size (wl_g_rates_size - 4)
135 #define CHAN2G(_channel, _freq) { \
136 .band = IEEE80211_BAND_2GHZ, \
137 .center_freq = (_freq), \
138 .hw_value = (_channel), \
139 .flags = IEEE80211_CHAN_DISABLED, \
140 .max_antenna_gain = 0, \
144 #define CHAN5G(_channel) { \
145 .band = IEEE80211_BAND_5GHZ, \
146 .center_freq = 5000 + (5 * (_channel)), \
147 .hw_value = (_channel), \
148 .flags = IEEE80211_CHAN_DISABLED, \
149 .max_antenna_gain = 0, \
153 static struct ieee80211_channel __wl_2ghz_channels[] = {
154 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
155 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
156 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
157 CHAN2G(13, 2472), CHAN2G(14, 2484)
160 static struct ieee80211_channel __wl_5ghz_channels[] = {
161 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
162 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
163 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
164 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
165 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
166 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
169 /* Band templates duplicated per wiphy. The channel info
170 * above is added to the band during setup.
172 static const struct ieee80211_supported_band __wl_band_2ghz = {
173 .band = IEEE80211_BAND_2GHZ,
174 .bitrates = wl_g_rates,
175 .n_bitrates = wl_g_rates_size,
178 static const struct ieee80211_supported_band __wl_band_5ghz = {
179 .band = IEEE80211_BAND_5GHZ,
180 .bitrates = wl_a_rates,
181 .n_bitrates = wl_a_rates_size,
184 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
185 * By default world regulatory domain defined in reg.c puts the flags
186 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
187 * With respect to these flags, wpa_supplicant doesn't * start p2p
188 * operations on 5GHz channels. All the changes in world regulatory
189 * domain are to be done here.
191 static const struct ieee80211_regdomain brcmf_regdom = {
195 /* IEEE 802.11b/g, channels 1..11 */
196 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
198 /* IEEE 802.11 channel 14 - Only JP enables
199 * this and for 802.11b only
201 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
202 /* IEEE 802.11a, channel 36..64 */
203 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
204 /* IEEE 802.11a, channel 100..165 */
205 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
208 static const u32 __wl_cipher_suites[] = {
209 WLAN_CIPHER_SUITE_WEP40,
210 WLAN_CIPHER_SUITE_WEP104,
211 WLAN_CIPHER_SUITE_TKIP,
212 WLAN_CIPHER_SUITE_CCMP,
213 WLAN_CIPHER_SUITE_AES_CMAC,
216 /* Vendor specific ie. id = 221, oui and type defines exact ie */
217 struct brcmf_vs_tlv {
224 struct parsed_vndr_ie_info {
226 u32 ie_len; /* total length including id & length field */
227 struct brcmf_vs_tlv vndrie;
230 struct parsed_vndr_ies {
232 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
235 static int brcmf_roamoff;
236 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
237 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
240 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
241 struct cfg80211_chan_def *ch)
243 struct brcmu_chan ch_inf;
246 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
247 ch->chan->center_freq, ch->center_freq1, ch->width);
248 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
249 primary_offset = ch->center_freq1 - ch->chan->center_freq;
251 case NL80211_CHAN_WIDTH_20:
252 case NL80211_CHAN_WIDTH_20_NOHT:
253 ch_inf.bw = BRCMU_CHAN_BW_20;
254 WARN_ON(primary_offset != 0);
256 case NL80211_CHAN_WIDTH_40:
257 ch_inf.bw = BRCMU_CHAN_BW_40;
258 if (primary_offset < 0)
259 ch_inf.sb = BRCMU_CHAN_SB_U;
261 ch_inf.sb = BRCMU_CHAN_SB_L;
263 case NL80211_CHAN_WIDTH_80:
264 ch_inf.bw = BRCMU_CHAN_BW_80;
265 if (primary_offset < 0) {
266 if (primary_offset < -CH_10MHZ_APART)
267 ch_inf.sb = BRCMU_CHAN_SB_UU;
269 ch_inf.sb = BRCMU_CHAN_SB_UL;
271 if (primary_offset > CH_10MHZ_APART)
272 ch_inf.sb = BRCMU_CHAN_SB_LL;
274 ch_inf.sb = BRCMU_CHAN_SB_LU;
277 case NL80211_CHAN_WIDTH_80P80:
278 case NL80211_CHAN_WIDTH_160:
279 case NL80211_CHAN_WIDTH_5:
280 case NL80211_CHAN_WIDTH_10:
284 switch (ch->chan->band) {
285 case IEEE80211_BAND_2GHZ:
286 ch_inf.band = BRCMU_CHAN_BAND_2G;
288 case IEEE80211_BAND_5GHZ:
289 ch_inf.band = BRCMU_CHAN_BAND_5G;
291 case IEEE80211_BAND_60GHZ:
295 d11inf->encchspec(&ch_inf);
297 return ch_inf.chspec;
300 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
301 struct ieee80211_channel *ch)
303 struct brcmu_chan ch_inf;
305 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
306 ch_inf.bw = BRCMU_CHAN_BW_20;
307 d11inf->encchspec(&ch_inf);
309 return ch_inf.chspec;
312 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
313 * triples, returning a pointer to the substring whose first element
316 const struct brcmf_tlv *
317 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
319 const struct brcmf_tlv *elt = buf;
322 /* find tagged parameter */
323 while (totlen >= TLV_HDR_LEN) {
326 /* validate remaining totlen */
327 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
330 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
331 totlen -= (len + TLV_HDR_LEN);
337 /* Is any of the tlvs the expected entry? If
338 * not update the tlvs buffer pointer/length.
341 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
342 const u8 *oui, u32 oui_len, u8 type)
344 /* If the contents match the OUI and the type */
345 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
346 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
347 type == ie[TLV_BODY_OFF + oui_len]) {
353 /* point to the next ie */
354 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
355 /* calculate the length of the rest of the buffer */
356 *tlvs_len -= (int)(ie - *tlvs);
357 /* update the pointer to the start of the buffer */
363 static struct brcmf_vs_tlv *
364 brcmf_find_wpaie(const u8 *parse, u32 len)
366 const struct brcmf_tlv *ie;
368 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
369 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
370 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
371 return (struct brcmf_vs_tlv *)ie;
376 static struct brcmf_vs_tlv *
377 brcmf_find_wpsie(const u8 *parse, u32 len)
379 const struct brcmf_tlv *ie;
381 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
382 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
383 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
384 return (struct brcmf_vs_tlv *)ie;
389 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
390 struct brcmf_cfg80211_vif *vif,
391 enum nl80211_iftype new_type)
393 int iftype_num[NUM_NL80211_IFTYPES];
394 struct brcmf_cfg80211_vif *pos;
396 memset(&iftype_num[0], 0, sizeof(iftype_num));
397 list_for_each_entry(pos, &cfg->vif_list, list)
399 iftype_num[new_type]++;
401 iftype_num[pos->wdev.iftype]++;
403 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
406 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
407 enum nl80211_iftype new_type)
409 int iftype_num[NUM_NL80211_IFTYPES];
410 struct brcmf_cfg80211_vif *pos;
412 memset(&iftype_num[0], 0, sizeof(iftype_num));
413 list_for_each_entry(pos, &cfg->vif_list, list)
414 iftype_num[pos->wdev.iftype]++;
416 iftype_num[new_type]++;
417 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
420 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
421 struct brcmf_wsec_key_le *key_le)
423 key_le->index = cpu_to_le32(key->index);
424 key_le->len = cpu_to_le32(key->len);
425 key_le->algo = cpu_to_le32(key->algo);
426 key_le->flags = cpu_to_le32(key->flags);
427 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
428 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
429 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
430 memcpy(key_le->data, key->data, sizeof(key->data));
431 memcpy(key_le->ea, key->ea, sizeof(key->ea));
435 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
438 struct brcmf_wsec_key_le key_le;
440 convert_key_from_CPU(key, &key_le);
442 brcmf_netdev_wait_pend8021x(ifp);
444 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
448 brcmf_err("wsec_key error (%d)\n", err);
453 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
459 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
463 /* Try to set and enable ARP offload feature, this may fail, then it */
464 /* is simply not supported and err 0 will be returned */
465 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
467 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
471 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
473 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
477 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
485 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
487 struct brcmf_cfg80211_vif *vif;
488 struct brcmf_if *ifp;
490 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
493 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
494 (wdev->iftype == NL80211_IFTYPE_AP) ||
495 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
496 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
499 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
503 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
505 struct brcmf_mbss_ssid_le mbss_ssid_le;
509 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
510 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
514 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
515 mbss_ssid_le.SSID_len = cpu_to_le32(5);
516 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
518 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
519 sizeof(mbss_ssid_le));
521 brcmf_err("setting ssid failed %d\n", err);
527 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
529 * @wiphy: wiphy device of new interface.
530 * @name: name of the new interface.
532 * @params: contains mac address for AP device.
535 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
536 u32 *flags, struct vif_params *params)
538 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
539 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
540 struct brcmf_cfg80211_vif *vif;
543 if (brcmf_cfg80211_vif_event_armed(cfg))
544 return ERR_PTR(-EBUSY);
546 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
548 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
550 return (struct wireless_dev *)vif;
552 brcmf_cfg80211_arm_vif_event(cfg, vif);
554 err = brcmf_cfg80211_request_ap_if(ifp);
556 brcmf_cfg80211_arm_vif_event(cfg, NULL);
560 /* wait for firmware event */
561 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
562 msecs_to_jiffies(1500));
563 brcmf_cfg80211_arm_vif_event(cfg, NULL);
565 brcmf_err("timeout occurred\n");
570 /* interface created in firmware */
573 brcmf_err("no if pointer provided\n");
578 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
579 err = brcmf_net_attach(ifp, true);
581 brcmf_err("Registering netdevice failed\n");
585 return &ifp->vif->wdev;
592 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
594 enum nl80211_iftype iftype;
596 iftype = vif->wdev.iftype;
597 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
600 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
602 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
605 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
607 unsigned char name_assign_type,
608 enum nl80211_iftype type,
610 struct vif_params *params)
612 struct wireless_dev *wdev;
615 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
616 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
618 brcmf_err("iface validation failed: err=%d\n", err);
622 case NL80211_IFTYPE_ADHOC:
623 case NL80211_IFTYPE_STATION:
624 case NL80211_IFTYPE_AP_VLAN:
625 case NL80211_IFTYPE_WDS:
626 case NL80211_IFTYPE_MONITOR:
627 case NL80211_IFTYPE_MESH_POINT:
628 return ERR_PTR(-EOPNOTSUPP);
629 case NL80211_IFTYPE_AP:
630 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
632 brcmf_cfg80211_update_proto_addr_mode(wdev);
634 case NL80211_IFTYPE_P2P_CLIENT:
635 case NL80211_IFTYPE_P2P_GO:
636 case NL80211_IFTYPE_P2P_DEVICE:
637 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
639 brcmf_cfg80211_update_proto_addr_mode(wdev);
641 case NL80211_IFTYPE_UNSPECIFIED:
643 return ERR_PTR(-EINVAL);
647 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
649 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
650 brcmf_set_mpc(ifp, mpc);
653 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
657 if (check_vif_up(ifp->vif)) {
658 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
660 brcmf_err("fail to set mpc\n");
663 brcmf_dbg(INFO, "MPC : %d\n", mpc);
667 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
668 struct brcmf_if *ifp, bool aborted,
671 struct brcmf_scan_params_le params_le;
672 struct cfg80211_scan_request *scan_request;
675 brcmf_dbg(SCAN, "Enter\n");
677 /* clear scan request, because the FW abort can cause a second call */
678 /* to this functon and might cause a double cfg80211_scan_done */
679 scan_request = cfg->scan_request;
680 cfg->scan_request = NULL;
682 if (timer_pending(&cfg->escan_timeout))
683 del_timer_sync(&cfg->escan_timeout);
686 /* Do a scan abort to stop the driver's scan engine */
687 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
688 memset(¶ms_le, 0, sizeof(params_le));
689 eth_broadcast_addr(params_le.bssid);
690 params_le.bss_type = DOT11_BSSTYPE_ANY;
691 params_le.scan_type = 0;
692 params_le.channel_num = cpu_to_le32(1);
693 params_le.nprobes = cpu_to_le32(1);
694 params_le.active_time = cpu_to_le32(-1);
695 params_le.passive_time = cpu_to_le32(-1);
696 params_le.home_time = cpu_to_le32(-1);
697 /* Scan is aborted by setting channel_list[0] to -1 */
698 params_le.channel_list[0] = cpu_to_le16(-1);
699 /* E-Scan (or anyother type) can be aborted by SCAN */
700 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
701 ¶ms_le, sizeof(params_le));
703 brcmf_err("Scan abort failed\n");
706 brcmf_scan_config_mpc(ifp, 1);
709 * e-scan can be initiated by scheduled scan
710 * which takes precedence.
712 if (cfg->sched_escan) {
713 brcmf_dbg(SCAN, "scheduled scan completed\n");
714 cfg->sched_escan = false;
716 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
717 } else if (scan_request) {
718 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
719 aborted ? "Aborted" : "Done");
720 cfg80211_scan_done(scan_request, aborted);
722 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
723 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
729 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
731 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
732 struct net_device *ndev = wdev->netdev;
734 /* vif event pending in firmware */
735 if (brcmf_cfg80211_vif_event_armed(cfg))
739 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
740 cfg->escan_info.ifp == netdev_priv(ndev))
741 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
744 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
747 switch (wdev->iftype) {
748 case NL80211_IFTYPE_ADHOC:
749 case NL80211_IFTYPE_STATION:
750 case NL80211_IFTYPE_AP:
751 case NL80211_IFTYPE_AP_VLAN:
752 case NL80211_IFTYPE_WDS:
753 case NL80211_IFTYPE_MONITOR:
754 case NL80211_IFTYPE_MESH_POINT:
756 case NL80211_IFTYPE_P2P_CLIENT:
757 case NL80211_IFTYPE_P2P_GO:
758 case NL80211_IFTYPE_P2P_DEVICE:
759 return brcmf_p2p_del_vif(wiphy, wdev);
760 case NL80211_IFTYPE_UNSPECIFIED:
768 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
769 enum nl80211_iftype type, u32 *flags,
770 struct vif_params *params)
772 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
773 struct brcmf_if *ifp = netdev_priv(ndev);
774 struct brcmf_cfg80211_vif *vif = ifp->vif;
779 brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
781 /* WAR: There are a number of p2p interface related problems which
782 * need to be handled initially (before doing the validate).
783 * wpa_supplicant tends to do iface changes on p2p device/client/go
784 * which are not always possible/allowed. However we need to return
785 * OK otherwise the wpa_supplicant wont start. The situation differs
786 * on configuration and setup (p2pon=1 module param). The first check
787 * is to see if the request is a change to station for p2p iface.
789 if ((type == NL80211_IFTYPE_STATION) &&
790 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
791 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
792 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
793 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
794 /* Now depending on whether module param p2pon=1 was used the
795 * response needs to be either 0 or EOPNOTSUPP. The reason is
796 * that if p2pon=1 is used, but a newer supplicant is used then
797 * we should return an error, as this combination wont work.
798 * In other situations 0 is returned and supplicant will start
799 * normally. It will give a trace in cfg80211, but it is the
800 * only way to get it working. Unfortunately this will result
801 * in situation where we wont support new supplicant in
802 * combination with module param p2pon=1, but that is the way
803 * it is. If the user tries this then unloading of driver might
806 if (cfg->p2p.p2pdev_dynamically)
811 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
813 brcmf_err("iface validation failed: err=%d\n", err);
817 case NL80211_IFTYPE_MONITOR:
818 case NL80211_IFTYPE_WDS:
819 brcmf_err("type (%d) : currently we do not support this type\n",
822 case NL80211_IFTYPE_ADHOC:
825 case NL80211_IFTYPE_STATION:
828 case NL80211_IFTYPE_AP:
829 case NL80211_IFTYPE_P2P_GO:
838 if (type == NL80211_IFTYPE_P2P_GO) {
839 brcmf_dbg(INFO, "IF Type = P2P GO\n");
840 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
843 brcmf_dbg(INFO, "IF Type = AP\n");
846 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
848 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
852 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
855 ndev->ieee80211_ptr->iftype = type;
857 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
860 brcmf_dbg(TRACE, "Exit\n");
865 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
866 struct brcmf_scan_params_le *params_le,
867 struct cfg80211_scan_request *request)
875 struct brcmf_ssid_le ssid_le;
877 eth_broadcast_addr(params_le->bssid);
878 params_le->bss_type = DOT11_BSSTYPE_ANY;
879 params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
880 params_le->channel_num = 0;
881 params_le->nprobes = cpu_to_le32(-1);
882 params_le->active_time = cpu_to_le32(-1);
883 params_le->passive_time = cpu_to_le32(-1);
884 params_le->home_time = cpu_to_le32(-1);
885 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
887 n_ssids = request->n_ssids;
888 n_channels = request->n_channels;
890 /* Copy channel array if applicable */
891 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
893 if (n_channels > 0) {
894 for (i = 0; i < n_channels; i++) {
895 chanspec = channel_to_chanspec(&cfg->d11inf,
896 request->channels[i]);
897 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
898 request->channels[i]->hw_value, chanspec);
899 params_le->channel_list[i] = cpu_to_le16(chanspec);
902 brcmf_dbg(SCAN, "Scanning all channels\n");
904 /* Copy ssid array if applicable */
905 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
907 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
908 n_channels * sizeof(u16);
909 offset = roundup(offset, sizeof(u32));
910 ptr = (char *)params_le + offset;
911 for (i = 0; i < n_ssids; i++) {
912 memset(&ssid_le, 0, sizeof(ssid_le));
914 cpu_to_le32(request->ssids[i].ssid_len);
915 memcpy(ssid_le.SSID, request->ssids[i].ssid,
916 request->ssids[i].ssid_len);
917 if (!ssid_le.SSID_len)
918 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
920 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
921 i, ssid_le.SSID, ssid_le.SSID_len);
922 memcpy(ptr, &ssid_le, sizeof(ssid_le));
923 ptr += sizeof(ssid_le);
926 brcmf_dbg(SCAN, "Performing passive scan\n");
927 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
929 /* Adding mask to channel numbers */
930 params_le->channel_num =
931 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
932 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
936 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
937 struct cfg80211_scan_request *request, u16 action)
939 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
940 offsetof(struct brcmf_escan_params_le, params_le);
941 struct brcmf_escan_params_le *params;
944 brcmf_dbg(SCAN, "E-SCAN START\n");
946 if (request != NULL) {
947 /* Allocate space for populating ssids in struct */
948 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
950 /* Allocate space for populating ssids in struct */
951 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
954 params = kzalloc(params_size, GFP_KERNEL);
959 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
960 brcmf_escan_prep(cfg, ¶ms->params_le, request);
961 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
962 params->action = cpu_to_le16(action);
963 params->sync_id = cpu_to_le16(0x1234);
965 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
968 brcmf_dbg(INFO, "system busy : escan canceled\n");
970 brcmf_err("error (%d)\n", err);
979 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
980 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
984 struct brcmf_scan_results *results;
985 struct escan_info *escan = &cfg->escan_info;
987 brcmf_dbg(SCAN, "Enter\n");
989 escan->wiphy = wiphy;
990 escan->escan_state = WL_ESCAN_STATE_SCANNING;
991 passive_scan = cfg->active_scan ? 0 : 1;
992 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
995 brcmf_err("error (%d)\n", err);
998 brcmf_scan_config_mpc(ifp, 0);
999 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1000 results->version = 0;
1002 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1004 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
1006 brcmf_scan_config_mpc(ifp, 1);
1011 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1012 struct cfg80211_scan_request *request,
1013 struct cfg80211_ssid *this_ssid)
1015 struct brcmf_if *ifp = vif->ifp;
1016 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1017 struct cfg80211_ssid *ssids;
1018 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
1025 brcmf_dbg(SCAN, "START ESCAN\n");
1027 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1028 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1031 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1032 brcmf_err("Scanning being aborted: status (%lu)\n",
1036 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1037 brcmf_err("Scanning suppressed: status (%lu)\n",
1041 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1042 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1046 /* If scan req comes for p2p0, send it over primary I/F */
1047 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1048 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1053 ssids = request->ssids;
1057 /* we don't do escan in ibss */
1061 cfg->scan_request = request;
1062 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1064 cfg->escan_info.run = brcmf_run_escan;
1065 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1069 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1073 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1074 ssids->ssid, ssids->ssid_len);
1075 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1076 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1077 sr->ssid_le.SSID_len = cpu_to_le32(0);
1080 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1081 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1084 brcmf_dbg(SCAN, "Broadcast scan\n");
1086 passive_scan = cfg->active_scan ? 0 : 1;
1087 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1090 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1093 brcmf_scan_config_mpc(ifp, 0);
1094 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1095 &sr->ssid_le, sizeof(sr->ssid_le));
1098 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1101 brcmf_err("WLC_SCAN error (%d)\n", err);
1103 brcmf_scan_config_mpc(ifp, 1);
1108 /* Arm scan timeout timer */
1109 mod_timer(&cfg->escan_timeout, jiffies +
1110 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1115 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1116 cfg->scan_request = NULL;
1121 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1123 struct brcmf_cfg80211_vif *vif;
1126 brcmf_dbg(TRACE, "Enter\n");
1127 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1128 if (!check_vif_up(vif))
1131 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1134 brcmf_err("scan error (%d)\n", err);
1136 brcmf_dbg(TRACE, "Exit\n");
1140 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1144 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1147 brcmf_err("Error (%d)\n", err);
1152 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1156 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1159 brcmf_err("Error (%d)\n", err);
1164 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1167 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1169 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1171 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1177 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1179 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1180 struct net_device *ndev = cfg_to_ndev(cfg);
1181 struct brcmf_if *ifp = netdev_priv(ndev);
1184 brcmf_dbg(TRACE, "Enter\n");
1185 if (!check_vif_up(ifp->vif))
1188 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1189 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1190 cfg->conf->rts_threshold = wiphy->rts_threshold;
1191 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1195 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1196 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1197 cfg->conf->frag_threshold = wiphy->frag_threshold;
1198 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1202 if (changed & WIPHY_PARAM_RETRY_LONG
1203 && (cfg->conf->retry_long != wiphy->retry_long)) {
1204 cfg->conf->retry_long = wiphy->retry_long;
1205 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1209 if (changed & WIPHY_PARAM_RETRY_SHORT
1210 && (cfg->conf->retry_short != wiphy->retry_short)) {
1211 cfg->conf->retry_short = wiphy->retry_short;
1212 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1218 brcmf_dbg(TRACE, "Exit\n");
1222 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1224 memset(prof, 0, sizeof(*prof));
1227 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1231 switch (e->event_code) {
1232 case BRCMF_E_DEAUTH:
1233 case BRCMF_E_DEAUTH_IND:
1234 case BRCMF_E_DISASSOC_IND:
1245 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1247 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1250 brcmf_dbg(TRACE, "Enter\n");
1252 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1253 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1254 err = brcmf_fil_cmd_data_set(vif->ifp,
1255 BRCMF_C_DISASSOC, NULL, 0);
1257 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1259 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1260 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1264 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1265 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1266 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1267 brcmf_dbg(TRACE, "Exit\n");
1271 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1272 struct cfg80211_ibss_params *params)
1274 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1275 struct brcmf_if *ifp = netdev_priv(ndev);
1276 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1277 struct brcmf_join_params join_params;
1278 size_t join_params_size = 0;
1284 brcmf_dbg(TRACE, "Enter\n");
1285 if (!check_vif_up(ifp->vif))
1289 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1291 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1295 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1298 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1300 brcmf_dbg(CONN, "No BSSID specified\n");
1302 if (params->chandef.chan)
1303 brcmf_dbg(CONN, "channel: %d\n",
1304 params->chandef.chan->center_freq);
1306 brcmf_dbg(CONN, "no channel specified\n");
1308 if (params->channel_fixed)
1309 brcmf_dbg(CONN, "fixed channel required\n");
1311 brcmf_dbg(CONN, "no fixed channel required\n");
1313 if (params->ie && params->ie_len)
1314 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1316 brcmf_dbg(CONN, "no ie specified\n");
1318 if (params->beacon_interval)
1319 brcmf_dbg(CONN, "beacon interval: %d\n",
1320 params->beacon_interval);
1322 brcmf_dbg(CONN, "no beacon interval specified\n");
1324 if (params->basic_rates)
1325 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1327 brcmf_dbg(CONN, "no basic rates specified\n");
1329 if (params->privacy)
1330 brcmf_dbg(CONN, "privacy required\n");
1332 brcmf_dbg(CONN, "no privacy required\n");
1334 /* Configure Privacy for starter */
1335 if (params->privacy)
1336 wsec |= WEP_ENABLED;
1338 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1340 brcmf_err("wsec failed (%d)\n", err);
1344 /* Configure Beacon Interval for starter */
1345 if (params->beacon_interval)
1346 bcnprd = params->beacon_interval;
1350 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1352 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1356 /* Configure required join parameter */
1357 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1360 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1361 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1362 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1363 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1364 join_params_size = sizeof(join_params.ssid_le);
1367 if (params->bssid) {
1368 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1369 join_params_size = sizeof(join_params.ssid_le) +
1370 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1371 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1373 eth_broadcast_addr(join_params.params_le.bssid);
1374 eth_zero_addr(profile->bssid);
1378 if (params->chandef.chan) {
1382 ieee80211_frequency_to_channel(
1383 params->chandef.chan->center_freq);
1384 if (params->channel_fixed) {
1385 /* adding chanspec */
1386 chanspec = chandef_to_chanspec(&cfg->d11inf,
1388 join_params.params_le.chanspec_list[0] =
1389 cpu_to_le16(chanspec);
1390 join_params.params_le.chanspec_num = cpu_to_le32(1);
1391 join_params_size += sizeof(join_params.params_le);
1394 /* set channel for starter */
1395 target_channel = cfg->channel;
1396 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1399 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1405 cfg->ibss_starter = false;
1408 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1409 &join_params, join_params_size);
1411 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1417 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1418 brcmf_dbg(TRACE, "Exit\n");
1423 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1425 struct brcmf_if *ifp = netdev_priv(ndev);
1427 brcmf_dbg(TRACE, "Enter\n");
1428 if (!check_vif_up(ifp->vif))
1431 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1433 brcmf_dbg(TRACE, "Exit\n");
1438 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1439 struct cfg80211_connect_params *sme)
1441 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1442 struct brcmf_cfg80211_security *sec;
1446 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1447 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1448 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1449 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1451 val = WPA_AUTH_DISABLED;
1452 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1453 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1455 brcmf_err("set wpa_auth failed (%d)\n", err);
1458 sec = &profile->sec;
1459 sec->wpa_versions = sme->crypto.wpa_versions;
1463 static s32 brcmf_set_auth_type(struct net_device *ndev,
1464 struct cfg80211_connect_params *sme)
1466 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1467 struct brcmf_cfg80211_security *sec;
1471 switch (sme->auth_type) {
1472 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1474 brcmf_dbg(CONN, "open system\n");
1476 case NL80211_AUTHTYPE_SHARED_KEY:
1478 brcmf_dbg(CONN, "shared key\n");
1480 case NL80211_AUTHTYPE_AUTOMATIC:
1482 brcmf_dbg(CONN, "automatic\n");
1484 case NL80211_AUTHTYPE_NETWORK_EAP:
1485 brcmf_dbg(CONN, "network eap\n");
1488 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1492 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1494 brcmf_err("set auth failed (%d)\n", err);
1497 sec = &profile->sec;
1498 sec->auth_type = sme->auth_type;
1503 brcmf_set_wsec_mode(struct net_device *ndev,
1504 struct cfg80211_connect_params *sme, bool mfp)
1506 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1507 struct brcmf_cfg80211_security *sec;
1513 if (sme->crypto.n_ciphers_pairwise) {
1514 switch (sme->crypto.ciphers_pairwise[0]) {
1515 case WLAN_CIPHER_SUITE_WEP40:
1516 case WLAN_CIPHER_SUITE_WEP104:
1519 case WLAN_CIPHER_SUITE_TKIP:
1520 pval = TKIP_ENABLED;
1522 case WLAN_CIPHER_SUITE_CCMP:
1525 case WLAN_CIPHER_SUITE_AES_CMAC:
1529 brcmf_err("invalid cipher pairwise (%d)\n",
1530 sme->crypto.ciphers_pairwise[0]);
1534 if (sme->crypto.cipher_group) {
1535 switch (sme->crypto.cipher_group) {
1536 case WLAN_CIPHER_SUITE_WEP40:
1537 case WLAN_CIPHER_SUITE_WEP104:
1540 case WLAN_CIPHER_SUITE_TKIP:
1541 gval = TKIP_ENABLED;
1543 case WLAN_CIPHER_SUITE_CCMP:
1546 case WLAN_CIPHER_SUITE_AES_CMAC:
1550 brcmf_err("invalid cipher group (%d)\n",
1551 sme->crypto.cipher_group);
1556 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1557 /* In case of privacy, but no security and WPS then simulate */
1558 /* setting AES. WPS-2.0 allows no security */
1559 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1564 wsec = pval | gval | MFP_CAPABLE;
1567 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1569 brcmf_err("error (%d)\n", err);
1573 sec = &profile->sec;
1574 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1575 sec->cipher_group = sme->crypto.cipher_group;
1581 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1583 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1584 struct brcmf_cfg80211_security *sec;
1588 if (sme->crypto.n_akm_suites) {
1589 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1592 brcmf_err("could not get wpa_auth (%d)\n", err);
1595 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1596 switch (sme->crypto.akm_suites[0]) {
1597 case WLAN_AKM_SUITE_8021X:
1598 val = WPA_AUTH_UNSPECIFIED;
1600 case WLAN_AKM_SUITE_PSK:
1604 brcmf_err("invalid cipher group (%d)\n",
1605 sme->crypto.cipher_group);
1608 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1609 switch (sme->crypto.akm_suites[0]) {
1610 case WLAN_AKM_SUITE_8021X:
1611 val = WPA2_AUTH_UNSPECIFIED;
1613 case WLAN_AKM_SUITE_PSK:
1614 val = WPA2_AUTH_PSK;
1617 brcmf_err("invalid cipher group (%d)\n",
1618 sme->crypto.cipher_group);
1623 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1624 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1627 brcmf_err("could not set wpa_auth (%d)\n", err);
1631 sec = &profile->sec;
1632 sec->wpa_auth = sme->crypto.akm_suites[0];
1638 brcmf_set_sharedkey(struct net_device *ndev,
1639 struct cfg80211_connect_params *sme)
1641 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1642 struct brcmf_cfg80211_security *sec;
1643 struct brcmf_wsec_key key;
1647 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1649 if (sme->key_len == 0)
1652 sec = &profile->sec;
1653 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1654 sec->wpa_versions, sec->cipher_pairwise);
1656 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1659 if (!(sec->cipher_pairwise &
1660 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1663 memset(&key, 0, sizeof(key));
1664 key.len = (u32) sme->key_len;
1665 key.index = (u32) sme->key_idx;
1666 if (key.len > sizeof(key.data)) {
1667 brcmf_err("Too long key length (%u)\n", key.len);
1670 memcpy(key.data, sme->key, key.len);
1671 key.flags = BRCMF_PRIMARY_KEY;
1672 switch (sec->cipher_pairwise) {
1673 case WLAN_CIPHER_SUITE_WEP40:
1674 key.algo = CRYPTO_ALGO_WEP1;
1676 case WLAN_CIPHER_SUITE_WEP104:
1677 key.algo = CRYPTO_ALGO_WEP128;
1680 brcmf_err("Invalid algorithm (%d)\n",
1681 sme->crypto.ciphers_pairwise[0]);
1684 /* Set the new key/index */
1685 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1686 key.len, key.index, key.algo);
1687 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1688 err = send_key_to_dongle(netdev_priv(ndev), &key);
1692 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1693 brcmf_dbg(CONN, "set auth_type to shared key\n");
1694 val = WL_AUTH_SHARED_KEY; /* shared key */
1695 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1697 brcmf_err("set auth failed (%d)\n", err);
1703 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1704 enum nl80211_auth_type type)
1706 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1707 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1708 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1709 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1715 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1716 struct cfg80211_connect_params *sme)
1718 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1719 struct brcmf_if *ifp = netdev_priv(ndev);
1720 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1721 struct ieee80211_channel *chan = sme->channel;
1722 struct brcmf_join_params join_params;
1723 size_t join_params_size;
1724 const struct brcmf_tlv *rsn_ie;
1725 const struct brcmf_vs_tlv *wpa_ie;
1728 struct brcmf_ext_join_params_le *ext_join_params;
1732 brcmf_dbg(TRACE, "Enter\n");
1733 if (!check_vif_up(ifp->vif))
1737 brcmf_err("Invalid ssid\n");
1741 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1742 /* A normal (non P2P) connection request setup. */
1745 /* find the WPA_IE */
1746 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1749 ie_len = wpa_ie->len + TLV_HDR_LEN;
1751 /* find the RSN_IE */
1752 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1757 ie_len = rsn_ie->len + TLV_HDR_LEN;
1760 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1763 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1764 sme->ie, sme->ie_len);
1766 brcmf_err("Set Assoc REQ IE Failed\n");
1768 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1770 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1774 ieee80211_frequency_to_channel(chan->center_freq);
1775 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1776 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1777 cfg->channel, chan->center_freq, chanspec);
1783 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1785 err = brcmf_set_wpa_version(ndev, sme);
1787 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1791 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1792 err = brcmf_set_auth_type(ndev, sme);
1794 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1798 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1800 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1804 err = brcmf_set_key_mgmt(ndev, sme);
1806 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1810 err = brcmf_set_sharedkey(ndev, sme);
1812 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1816 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1817 (u32)sme->ssid_len);
1818 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1819 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1820 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1821 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1822 profile->ssid.SSID_len);
1825 /* Join with specific BSSID and cached SSID
1826 * If SSID is zero join based on BSSID only
1828 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1829 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1831 join_params_size += sizeof(u16);
1832 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1833 if (ext_join_params == NULL) {
1837 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1838 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1839 profile->ssid.SSID_len);
1841 /* Set up join scan parameters */
1842 ext_join_params->scan_le.scan_type = -1;
1843 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1846 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1848 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1851 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1853 ext_join_params->assoc_le.chanspec_list[0] =
1854 cpu_to_le16(chanspec);
1855 /* Increase dwell time to receive probe response or detect
1856 * beacon from target AP at a noisy air only during connect
1859 ext_join_params->scan_le.active_time =
1860 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1861 ext_join_params->scan_le.passive_time =
1862 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1863 /* To sync with presence period of VSDB GO send probe request
1864 * more frequently. Probe request will be stopped when it gets
1865 * probe response from target AP/GO.
1867 ext_join_params->scan_le.nprobes =
1868 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1869 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1871 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1872 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1873 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1876 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1878 kfree(ext_join_params);
1880 /* This is it. join command worked, we are done */
1883 /* join command failed, fallback to set ssid */
1884 memset(&join_params, 0, sizeof(join_params));
1885 join_params_size = sizeof(join_params.ssid_le);
1887 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1888 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1891 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1893 eth_broadcast_addr(join_params.params_le.bssid);
1896 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1897 join_params.params_le.chanspec_num = cpu_to_le32(1);
1898 join_params_size += sizeof(join_params.params_le);
1900 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1901 &join_params, join_params_size);
1903 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1907 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1908 brcmf_dbg(TRACE, "Exit\n");
1913 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1916 struct brcmf_if *ifp = netdev_priv(ndev);
1917 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1918 struct brcmf_scb_val_le scbval;
1921 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1922 if (!check_vif_up(ifp->vif))
1925 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1926 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1927 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1929 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1930 scbval.val = cpu_to_le32(reason_code);
1931 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1932 &scbval, sizeof(scbval));
1934 brcmf_err("error (%d)\n", err);
1936 brcmf_dbg(TRACE, "Exit\n");
1941 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1942 enum nl80211_tx_power_setting type, s32 mbm)
1944 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1945 struct net_device *ndev = cfg_to_ndev(cfg);
1946 struct brcmf_if *ifp = netdev_priv(ndev);
1951 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
1952 if (!check_vif_up(ifp->vif))
1956 case NL80211_TX_POWER_AUTOMATIC:
1958 case NL80211_TX_POWER_LIMITED:
1959 case NL80211_TX_POWER_FIXED:
1961 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1965 qdbm = MBM_TO_DBM(4 * mbm);
1968 qdbm |= WL_TXPWR_OVERRIDE;
1971 brcmf_err("Unsupported type %d\n", type);
1975 /* Make sure radio is off or on as far as software is concerned */
1976 disable = WL_RADIO_SW_DISABLE << 16;
1977 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1979 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1981 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
1983 brcmf_err("qtxpower error (%d)\n", err);
1986 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
1991 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1994 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1995 struct net_device *ndev = cfg_to_ndev(cfg);
1996 struct brcmf_if *ifp = netdev_priv(ndev);
2000 brcmf_dbg(TRACE, "Enter\n");
2001 if (!check_vif_up(ifp->vif))
2004 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
2006 brcmf_err("error (%d)\n", err);
2009 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2012 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2017 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2018 u8 key_idx, bool unicast, bool multicast)
2020 struct brcmf_if *ifp = netdev_priv(ndev);
2025 brcmf_dbg(TRACE, "Enter\n");
2026 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2027 if (!check_vif_up(ifp->vif))
2030 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2032 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2036 if (wsec & WEP_ENABLED) {
2037 /* Just select a new current key */
2039 err = brcmf_fil_cmd_int_set(ifp,
2040 BRCMF_C_SET_KEY_PRIMARY, index);
2042 brcmf_err("error (%d)\n", err);
2045 brcmf_dbg(TRACE, "Exit\n");
2050 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2051 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2053 struct brcmf_if *ifp = netdev_priv(ndev);
2054 struct brcmf_wsec_key key;
2058 memset(&key, 0, sizeof(key));
2059 key.index = (u32) key_idx;
2060 /* Instead of bcast for ea address for default wep keys,
2061 driver needs it to be Null */
2062 if (!is_multicast_ether_addr(mac_addr))
2063 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2064 key.len = (u32) params->key_len;
2065 /* check for key index change */
2068 err = send_key_to_dongle(ifp, &key);
2070 brcmf_err("key delete error (%d)\n", err);
2072 if (key.len > sizeof(key.data)) {
2073 brcmf_err("Invalid key length (%d)\n", key.len);
2077 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2078 memcpy(key.data, params->key, key.len);
2080 if (!brcmf_is_apmode(ifp->vif) &&
2081 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2082 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2083 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2084 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2085 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2088 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2089 if (params->seq && params->seq_len == 6) {
2092 ivptr = (u8 *) params->seq;
2093 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2094 (ivptr[3] << 8) | ivptr[2];
2095 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2096 key.iv_initialized = true;
2099 switch (params->cipher) {
2100 case WLAN_CIPHER_SUITE_WEP40:
2101 key.algo = CRYPTO_ALGO_WEP1;
2102 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2104 case WLAN_CIPHER_SUITE_WEP104:
2105 key.algo = CRYPTO_ALGO_WEP128;
2106 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2108 case WLAN_CIPHER_SUITE_TKIP:
2109 key.algo = CRYPTO_ALGO_TKIP;
2110 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2112 case WLAN_CIPHER_SUITE_AES_CMAC:
2113 key.algo = CRYPTO_ALGO_AES_CCM;
2114 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2116 case WLAN_CIPHER_SUITE_CCMP:
2117 key.algo = CRYPTO_ALGO_AES_CCM;
2118 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2121 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2124 err = send_key_to_dongle(ifp, &key);
2126 brcmf_err("wsec_key error (%d)\n", err);
2132 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2133 u8 key_idx, bool pairwise, const u8 *mac_addr,
2134 struct key_params *params)
2136 struct brcmf_if *ifp = netdev_priv(ndev);
2137 struct brcmf_wsec_key *key;
2143 brcmf_dbg(TRACE, "Enter\n");
2144 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2145 if (!check_vif_up(ifp->vif))
2148 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2149 /* we ignore this key index in this case */
2150 brcmf_err("invalid key index (%d)\n", key_idx);
2155 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2156 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2157 brcmf_dbg(TRACE, "Exit");
2158 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2161 key = &ifp->vif->profile.key[key_idx];
2162 memset(key, 0, sizeof(*key));
2164 if (params->key_len > sizeof(key->data)) {
2165 brcmf_err("Too long key length (%u)\n", params->key_len);
2169 key->len = params->key_len;
2170 key->index = key_idx;
2172 memcpy(key->data, params->key, key->len);
2174 key->flags = BRCMF_PRIMARY_KEY;
2175 switch (params->cipher) {
2176 case WLAN_CIPHER_SUITE_WEP40:
2177 key->algo = CRYPTO_ALGO_WEP1;
2179 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2181 case WLAN_CIPHER_SUITE_WEP104:
2182 key->algo = CRYPTO_ALGO_WEP128;
2184 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2186 case WLAN_CIPHER_SUITE_TKIP:
2187 if (!brcmf_is_apmode(ifp->vif)) {
2188 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2189 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2190 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2191 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2193 key->algo = CRYPTO_ALGO_TKIP;
2195 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2197 case WLAN_CIPHER_SUITE_AES_CMAC:
2198 key->algo = CRYPTO_ALGO_AES_CCM;
2200 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2202 case WLAN_CIPHER_SUITE_CCMP:
2203 key->algo = CRYPTO_ALGO_AES_CCM;
2205 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2208 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2213 err = send_key_to_dongle(ifp, key);
2217 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2219 brcmf_err("get wsec error (%d)\n", err);
2223 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2225 brcmf_err("set wsec error (%d)\n", err);
2230 brcmf_dbg(TRACE, "Exit\n");
2235 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2236 u8 key_idx, bool pairwise, const u8 *mac_addr)
2238 struct brcmf_if *ifp = netdev_priv(ndev);
2239 struct brcmf_wsec_key key;
2242 brcmf_dbg(TRACE, "Enter\n");
2243 if (!check_vif_up(ifp->vif))
2246 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2247 /* we ignore this key index in this case */
2251 memset(&key, 0, sizeof(key));
2253 key.index = (u32) key_idx;
2254 key.flags = BRCMF_PRIMARY_KEY;
2255 key.algo = CRYPTO_ALGO_OFF;
2257 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2259 /* Set the new key/index */
2260 err = send_key_to_dongle(ifp, &key);
2262 brcmf_dbg(TRACE, "Exit\n");
2267 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2268 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2269 void (*callback) (void *cookie, struct key_params * params))
2271 struct key_params params;
2272 struct brcmf_if *ifp = netdev_priv(ndev);
2273 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2274 struct brcmf_cfg80211_security *sec;
2278 brcmf_dbg(TRACE, "Enter\n");
2279 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2280 if (!check_vif_up(ifp->vif))
2283 memset(¶ms, 0, sizeof(params));
2285 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2287 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2288 /* Ignore this error, may happen during DISASSOC */
2292 if (wsec & WEP_ENABLED) {
2293 sec = &profile->sec;
2294 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2295 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2296 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2297 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2298 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2299 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2301 } else if (wsec & TKIP_ENABLED) {
2302 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2303 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2304 } else if (wsec & AES_ENABLED) {
2305 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2306 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2308 brcmf_err("Invalid algo (0x%x)\n", wsec);
2312 callback(cookie, ¶ms);
2315 brcmf_dbg(TRACE, "Exit\n");
2320 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2321 struct net_device *ndev, u8 key_idx)
2323 brcmf_dbg(INFO, "Not supported\n");
2329 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2333 struct brcmf_wsec_key *key;
2336 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2337 key = &ifp->vif->profile.key[key_idx];
2338 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2339 (key->algo == CRYPTO_ALGO_WEP128))
2342 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2345 err = send_key_to_dongle(ifp, key);
2347 brcmf_err("Setting WEP key failed (%d)\n", err);
2350 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2352 brcmf_err("get wsec error (%d)\n", err);
2355 wsec |= WEP_ENABLED;
2356 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2358 brcmf_err("set wsec error (%d)\n", err);
2361 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2363 struct nl80211_sta_flag_update *sfu;
2365 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2366 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2367 sfu = &si->sta_flags;
2368 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2369 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2370 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2371 BIT(NL80211_STA_FLAG_AUTHORIZED);
2372 if (fw_sta_flags & BRCMF_STA_WME)
2373 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2374 if (fw_sta_flags & BRCMF_STA_AUTHE)
2375 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2376 if (fw_sta_flags & BRCMF_STA_ASSOC)
2377 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2378 if (fw_sta_flags & BRCMF_STA_AUTHO)
2379 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2382 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2386 struct brcmf_bss_info_le bss_le;
2391 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2395 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2396 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2399 brcmf_err("Failed to get bss info (%d)\n", err);
2402 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2403 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2404 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2405 capability = le16_to_cpu(buf->bss_le.capability);
2406 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2407 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2408 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2409 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2410 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2411 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2418 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2419 const u8 *mac, struct station_info *sinfo)
2421 struct brcmf_if *ifp = netdev_priv(ndev);
2423 struct brcmf_sta_info_le sta_info_le;
2430 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2431 if (!check_vif_up(ifp->vif))
2434 memset(&sta_info_le, 0, sizeof(sta_info_le));
2435 memcpy(&sta_info_le, mac, ETH_ALEN);
2436 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2438 sizeof(sta_info_le));
2439 is_tdls_peer = !err;
2441 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2443 sizeof(sta_info_le));
2445 brcmf_err("GET STA INFO failed, %d\n", err);
2449 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2450 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2451 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2452 sta_flags = le32_to_cpu(sta_info_le.flags);
2453 brcmf_convert_sta_flags(sta_flags, sinfo);
2454 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2456 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2458 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2459 if (sta_flags & BRCMF_STA_ASSOC) {
2460 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2461 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2462 brcmf_fill_bss_param(ifp, sinfo);
2464 if (sta_flags & BRCMF_STA_SCBSTATS) {
2465 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2466 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2467 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2468 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2469 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2470 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2471 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2472 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2473 if (sinfo->tx_packets) {
2474 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2475 sinfo->txrate.legacy =
2476 le32_to_cpu(sta_info_le.tx_rate) / 100;
2478 if (sinfo->rx_packets) {
2479 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2480 sinfo->rxrate.legacy =
2481 le32_to_cpu(sta_info_le.rx_rate) / 100;
2483 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2484 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2485 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2486 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2487 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2491 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2492 if (sta_info_le.rssi[i]) {
2493 sinfo->chain_signal_avg[count_rssi] =
2494 sta_info_le.rssi[i];
2495 sinfo->chain_signal[count_rssi] =
2496 sta_info_le.rssi[i];
2497 total_rssi += sta_info_le.rssi[i];
2502 sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2503 sinfo->chains = count_rssi;
2505 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2506 total_rssi /= count_rssi;
2507 sinfo->signal = total_rssi;
2511 brcmf_dbg(TRACE, "Exit\n");
2516 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2517 int idx, u8 *mac, struct station_info *sinfo)
2519 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2520 struct brcmf_if *ifp = netdev_priv(ndev);
2523 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2526 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2527 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2529 sizeof(cfg->assoclist));
2531 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2533 cfg->assoclist.count = 0;
2537 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2538 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2539 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2545 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2546 bool enabled, s32 timeout)
2550 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2551 struct brcmf_if *ifp = netdev_priv(ndev);
2553 brcmf_dbg(TRACE, "Enter\n");
2556 * Powersave enable/disable request is coming from the
2557 * cfg80211 even before the interface is up. In that
2558 * scenario, driver will be storing the power save
2559 * preference in cfg struct to apply this to
2560 * FW later while initializing the dongle
2562 cfg->pwr_save = enabled;
2563 if (!check_vif_up(ifp->vif)) {
2565 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2569 pm = enabled ? PM_FAST : PM_OFF;
2570 /* Do not enable the power save after assoc if it is a p2p interface */
2571 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2572 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2575 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2577 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2580 brcmf_err("net_device is not ready yet\n");
2582 brcmf_err("error (%d)\n", err);
2585 brcmf_dbg(TRACE, "Exit\n");
2589 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2590 struct brcmf_bss_info_le *bi)
2592 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2593 struct ieee80211_channel *notify_channel;
2594 struct cfg80211_bss *bss;
2595 struct ieee80211_supported_band *band;
2596 struct brcmu_chan ch;
2599 u16 notify_capability;
2600 u16 notify_interval;
2602 size_t notify_ielen;
2605 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2606 brcmf_err("Bss info is larger than buffer. Discarding\n");
2611 ch.chspec = le16_to_cpu(bi->chanspec);
2612 cfg->d11inf.decchspec(&ch);
2613 bi->ctl_ch = ch.chnum;
2615 channel = bi->ctl_ch;
2617 if (channel <= CH_MAX_2G_CHANNEL)
2618 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2620 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2622 freq = ieee80211_channel_to_frequency(channel, band->band);
2623 notify_channel = ieee80211_get_channel(wiphy, freq);
2625 notify_capability = le16_to_cpu(bi->capability);
2626 notify_interval = le16_to_cpu(bi->beacon_period);
2627 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2628 notify_ielen = le32_to_cpu(bi->ie_length);
2629 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2631 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2632 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2633 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2634 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2635 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2637 bss = cfg80211_inform_bss(wiphy, notify_channel,
2638 CFG80211_BSS_FTYPE_UNKNOWN,
2639 (const u8 *)bi->BSSID,
2640 0, notify_capability,
2641 notify_interval, notify_ie,
2642 notify_ielen, notify_signal,
2648 cfg80211_put_bss(wiphy, bss);
2653 static struct brcmf_bss_info_le *
2654 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2657 return list->bss_info_le;
2658 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2659 le32_to_cpu(bss->length));
2662 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2664 struct brcmf_scan_results *bss_list;
2665 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2669 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2670 if (bss_list->count != 0 &&
2671 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2672 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2676 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2677 for (i = 0; i < bss_list->count; i++) {
2678 bi = next_bss_le(bss_list, bi);
2679 err = brcmf_inform_single_bss(cfg, bi);
2686 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2687 struct net_device *ndev, const u8 *bssid)
2689 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2690 struct ieee80211_channel *notify_channel;
2691 struct brcmf_bss_info_le *bi = NULL;
2692 struct ieee80211_supported_band *band;
2693 struct cfg80211_bss *bss;
2694 struct brcmu_chan ch;
2698 u16 notify_capability;
2699 u16 notify_interval;
2701 size_t notify_ielen;
2704 brcmf_dbg(TRACE, "Enter\n");
2706 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2712 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2714 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2715 buf, WL_BSS_INFO_MAX);
2717 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2721 bi = (struct brcmf_bss_info_le *)(buf + 4);
2723 ch.chspec = le16_to_cpu(bi->chanspec);
2724 cfg->d11inf.decchspec(&ch);
2726 if (ch.band == BRCMU_CHAN_BAND_2G)
2727 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2729 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2731 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2732 notify_channel = ieee80211_get_channel(wiphy, freq);
2734 notify_capability = le16_to_cpu(bi->capability);
2735 notify_interval = le16_to_cpu(bi->beacon_period);
2736 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2737 notify_ielen = le32_to_cpu(bi->ie_length);
2738 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2740 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2741 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2742 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2743 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2745 bss = cfg80211_inform_bss(wiphy, notify_channel,
2746 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2747 notify_capability, notify_interval,
2748 notify_ie, notify_ielen, notify_signal,
2756 cfg80211_put_bss(wiphy, bss);
2762 brcmf_dbg(TRACE, "Exit\n");
2767 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2768 struct brcmf_if *ifp)
2770 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2771 struct brcmf_bss_info_le *bi;
2772 struct brcmf_ssid *ssid;
2773 const struct brcmf_tlv *tim;
2774 u16 beacon_interval;
2780 brcmf_dbg(TRACE, "Enter\n");
2781 if (brcmf_is_ibssmode(ifp->vif))
2784 ssid = &profile->ssid;
2786 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2787 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2788 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2790 brcmf_err("Could not get bss info %d\n", err);
2791 goto update_bss_info_out;
2794 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2795 err = brcmf_inform_single_bss(cfg, bi);
2797 goto update_bss_info_out;
2799 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2800 ie_len = le32_to_cpu(bi->ie_length);
2801 beacon_interval = le16_to_cpu(bi->beacon_period);
2803 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2805 dtim_period = tim->data[1];
2808 * active scan was done so we could not get dtim
2809 * information out of probe response.
2810 * so we speficially query dtim information to dongle.
2813 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2815 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2816 goto update_bss_info_out;
2818 dtim_period = (u8)var;
2821 update_bss_info_out:
2822 brcmf_dbg(TRACE, "Exit");
2826 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2828 struct escan_info *escan = &cfg->escan_info;
2830 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2831 if (cfg->scan_request) {
2832 escan->escan_state = WL_ESCAN_STATE_IDLE;
2833 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2835 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2836 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2839 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2841 struct brcmf_cfg80211_info *cfg =
2842 container_of(work, struct brcmf_cfg80211_info,
2843 escan_timeout_work);
2845 brcmf_inform_bss(cfg);
2846 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2849 static void brcmf_escan_timeout(unsigned long data)
2851 struct brcmf_cfg80211_info *cfg =
2852 (struct brcmf_cfg80211_info *)data;
2854 if (cfg->scan_request) {
2855 brcmf_err("timer expired\n");
2856 schedule_work(&cfg->escan_timeout_work);
2861 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2862 struct brcmf_bss_info_le *bss,
2863 struct brcmf_bss_info_le *bss_info_le)
2865 struct brcmu_chan ch_bss, ch_bss_info_le;
2867 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2868 cfg->d11inf.decchspec(&ch_bss);
2869 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2870 cfg->d11inf.decchspec(&ch_bss_info_le);
2872 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2873 ch_bss.band == ch_bss_info_le.band &&
2874 bss_info_le->SSID_len == bss->SSID_len &&
2875 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2876 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2877 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2878 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2879 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2881 /* preserve max RSSI if the measurements are
2882 * both on-channel or both off-channel
2884 if (bss_info_rssi > bss_rssi)
2885 bss->RSSI = bss_info_le->RSSI;
2886 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2887 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2888 /* preserve the on-channel rssi measurement
2889 * if the new measurement is off channel
2891 bss->RSSI = bss_info_le->RSSI;
2892 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2900 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2901 const struct brcmf_event_msg *e, void *data)
2903 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2905 struct brcmf_escan_result_le *escan_result_le;
2907 struct brcmf_bss_info_le *bss_info_le;
2908 struct brcmf_bss_info_le *bss = NULL;
2910 struct brcmf_scan_results *list;
2916 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2917 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2921 if (status == BRCMF_E_STATUS_PARTIAL) {
2922 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2923 if (e->datalen < sizeof(*escan_result_le)) {
2924 brcmf_err("invalid event data length\n");
2927 escan_result_le = (struct brcmf_escan_result_le *) data;
2928 if (!escan_result_le) {
2929 brcmf_err("Invalid escan result (NULL pointer)\n");
2932 escan_buflen = le32_to_cpu(escan_result_le->buflen);
2933 if (escan_buflen > WL_ESCAN_BUF_SIZE ||
2934 escan_buflen > e->datalen ||
2935 escan_buflen < sizeof(*escan_result_le)) {
2936 brcmf_err("Invalid escan buffer length: %d\n",
2940 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2941 brcmf_err("Invalid bss_count %d: ignoring\n",
2942 escan_result_le->bss_count);
2945 bss_info_le = &escan_result_le->bss_info_le;
2947 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2950 if (!cfg->scan_request) {
2951 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2955 bi_length = le32_to_cpu(bss_info_le->length);
2956 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
2957 brcmf_err("Ignoring invalid bss_info length: %d\n",
2962 if (!(cfg_to_wiphy(cfg)->interface_modes &
2963 BIT(NL80211_IFTYPE_ADHOC))) {
2964 if (le16_to_cpu(bss_info_le->capability) &
2965 WLAN_CAPABILITY_IBSS) {
2966 brcmf_err("Ignoring IBSS result\n");
2971 list = (struct brcmf_scan_results *)
2972 cfg->escan_info.escan_buf;
2973 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2974 brcmf_err("Buffer is too small: ignoring\n");
2978 for (i = 0; i < list->count; i++) {
2979 bss = bss ? (struct brcmf_bss_info_le *)
2980 ((unsigned char *)bss +
2981 le32_to_cpu(bss->length)) : list->bss_info_le;
2982 if (brcmf_compare_update_same_bss(cfg, bss,
2986 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2987 bss_info_le, bi_length);
2988 list->version = le32_to_cpu(bss_info_le->version);
2989 list->buflen += bi_length;
2992 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2993 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2995 if (cfg->scan_request) {
2996 brcmf_inform_bss(cfg);
2997 aborted = status != BRCMF_E_STATUS_SUCCESS;
2998 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3000 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3007 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3009 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3010 brcmf_cfg80211_escan_handler);
3011 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3012 /* Init scan_timeout timer */
3013 init_timer(&cfg->escan_timeout);
3014 cfg->escan_timeout.data = (unsigned long) cfg;
3015 cfg->escan_timeout.function = brcmf_escan_timeout;
3016 INIT_WORK(&cfg->escan_timeout_work,
3017 brcmf_cfg80211_escan_timeout_worker);
3020 static __always_inline void brcmf_delay(u32 ms)
3022 if (ms < 1000 / HZ) {
3030 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3031 u8 *pattern, u32 patternsize, u8 *mask,
3034 struct brcmf_fil_wowl_pattern_le *filter;
3041 masksize = (patternsize + 7) / 8;
3042 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3044 bufsize = sizeof(*filter) + patternsize + masksize;
3045 buf = kzalloc(bufsize, GFP_KERNEL);
3048 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3050 memcpy(filter->cmd, cmd, 4);
3051 filter->masksize = cpu_to_le32(masksize);
3052 filter->offset = cpu_to_le32(packet_offset);
3053 filter->patternoffset = cpu_to_le32(patternoffset);
3054 filter->patternsize = cpu_to_le32(patternsize);
3055 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3057 if ((mask) && (masksize))
3058 memcpy(buf + sizeof(*filter), mask, masksize);
3059 if ((pattern) && (patternsize))
3060 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3062 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3068 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3070 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3071 struct net_device *ndev = cfg_to_ndev(cfg);
3072 struct brcmf_if *ifp = netdev_priv(ndev);
3074 brcmf_dbg(TRACE, "Enter\n");
3076 if (cfg->wowl_enabled) {
3077 brcmf_configure_arp_offload(ifp, true);
3078 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3079 cfg->pre_wowl_pmmode);
3080 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3081 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3082 cfg->wowl_enabled = false;
3087 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3088 struct brcmf_if *ifp,
3089 struct cfg80211_wowlan *wowl)
3094 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3096 brcmf_configure_arp_offload(ifp, false);
3097 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
3098 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3101 if (wowl->disconnect)
3102 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3103 if (wowl->magic_pkt)
3104 wowl_config |= BRCMF_WOWL_MAGIC;
3105 if ((wowl->patterns) && (wowl->n_patterns)) {
3106 wowl_config |= BRCMF_WOWL_NET;
3107 for (i = 0; i < wowl->n_patterns; i++) {
3108 brcmf_config_wowl_pattern(ifp, "add",
3109 (u8 *)wowl->patterns[i].pattern,
3110 wowl->patterns[i].pattern_len,
3111 (u8 *)wowl->patterns[i].mask,
3112 wowl->patterns[i].pkt_offset);
3115 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3116 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3117 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3118 cfg->wowl_enabled = true;
3121 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3122 struct cfg80211_wowlan *wowl)
3124 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3125 struct net_device *ndev = cfg_to_ndev(cfg);
3126 struct brcmf_if *ifp = netdev_priv(ndev);
3127 struct brcmf_cfg80211_vif *vif;
3129 brcmf_dbg(TRACE, "Enter\n");
3131 /* if the primary net_device is not READY there is nothing
3132 * we can do but pray resume goes smoothly.
3134 if (!check_vif_up(ifp->vif))
3137 /* end any scanning */
3138 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3139 brcmf_abort_scanning(cfg);
3142 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3143 list_for_each_entry(vif, &cfg->vif_list, list) {
3144 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3146 /* While going to suspend if associated with AP
3147 * disassociate from AP to save power while system is
3148 * in suspended state
3150 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3151 /* Make sure WPA_Supplicant receives all the event
3152 * generated due to DISASSOC call to the fw to keep
3153 * the state fw and WPA_Supplicant state consistent
3158 brcmf_set_mpc(ifp, 1);
3161 /* Configure WOWL paramaters */
3162 brcmf_configure_wowl(cfg, ifp, wowl);
3166 brcmf_dbg(TRACE, "Exit\n");
3167 /* clear any scanning activity */
3168 cfg->scan_status = 0;
3173 brcmf_update_pmklist(struct net_device *ndev,
3174 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3179 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3181 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
3182 for (i = 0; i < pmkid_len; i++) {
3183 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
3184 &pmk_list->pmkids.pmkid[i].BSSID);
3185 for (j = 0; j < WLAN_PMKID_LEN; j++)
3186 brcmf_dbg(CONN, "%02x\n",
3187 pmk_list->pmkids.pmkid[i].PMKID[j]);
3191 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
3192 (char *)pmk_list, sizeof(*pmk_list));
3198 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3199 struct cfg80211_pmksa *pmksa)
3201 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3202 struct brcmf_if *ifp = netdev_priv(ndev);
3203 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3207 brcmf_dbg(TRACE, "Enter\n");
3208 if (!check_vif_up(ifp->vif))
3211 pmkid_len = le32_to_cpu(pmkids->npmkid);
3212 for (i = 0; i < pmkid_len; i++)
3213 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3215 if (i < WL_NUM_PMKIDS_MAX) {
3216 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3217 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3218 if (i == pmkid_len) {
3220 pmkids->npmkid = cpu_to_le32(pmkid_len);
3225 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3226 pmkids->pmkid[pmkid_len].BSSID);
3227 for (i = 0; i < WLAN_PMKID_LEN; i++)
3228 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3230 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3232 brcmf_dbg(TRACE, "Exit\n");
3237 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3238 struct cfg80211_pmksa *pmksa)
3240 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3241 struct brcmf_if *ifp = netdev_priv(ndev);
3242 struct pmkid_list pmkid;
3246 brcmf_dbg(TRACE, "Enter\n");
3247 if (!check_vif_up(ifp->vif))
3250 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3251 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3253 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3254 &pmkid.pmkid[0].BSSID);
3255 for (i = 0; i < WLAN_PMKID_LEN; i++)
3256 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
3258 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3259 for (i = 0; i < pmkid_len; i++)
3261 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3266 && (i < pmkid_len)) {
3267 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3268 sizeof(struct pmkid));
3269 for (; i < (pmkid_len - 1); i++) {
3270 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3271 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3273 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3274 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3277 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3281 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3283 brcmf_dbg(TRACE, "Exit\n");
3289 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3291 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3292 struct brcmf_if *ifp = netdev_priv(ndev);
3295 brcmf_dbg(TRACE, "Enter\n");
3296 if (!check_vif_up(ifp->vif))
3299 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3300 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3302 brcmf_dbg(TRACE, "Exit\n");
3308 * PFN result doesn't have all the info which are
3309 * required by the supplicant
3310 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3311 * via wl_inform_single_bss in the required format. Escan does require the
3312 * scan request in the form of cfg80211_scan_request. For timebeing, create
3313 * cfg80211_scan_request one out of the received PNO event.
3316 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3317 const struct brcmf_event_msg *e, void *data)
3319 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3320 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3321 struct cfg80211_scan_request *request = NULL;
3322 struct cfg80211_ssid *ssid = NULL;
3323 struct ieee80211_channel *channel = NULL;
3324 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3326 int channel_req = 0;
3328 struct brcmf_pno_scanresults_le *pfn_result;
3333 brcmf_dbg(SCAN, "Enter\n");
3335 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3336 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3340 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3341 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3345 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3346 result_count = le32_to_cpu(pfn_result->count);
3347 status = le32_to_cpu(pfn_result->status);
3350 * PFN event is limited to fit 512 bytes so we may get
3351 * multiple NET_FOUND events. For now place a warning here.
3353 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3354 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3355 if (result_count > 0) {
3358 data += sizeof(struct brcmf_pno_scanresults_le);
3359 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3360 datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3361 if (datalen < result_count * sizeof(*netinfo)) {
3362 brcmf_err("insufficient event data\n");
3366 request = kzalloc(sizeof(*request), GFP_KERNEL);
3367 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3368 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3369 if (!request || !ssid || !channel) {
3374 request->wiphy = wiphy;
3375 for (i = 0; i < result_count; i++) {
3376 netinfo = &netinfo_start[i];
3378 brcmf_err("Invalid netinfo ptr. index: %d\n",
3384 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3385 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3386 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3387 netinfo->SSID, netinfo->channel);
3388 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3389 ssid[i].ssid_len = netinfo->SSID_len;
3392 channel_req = netinfo->channel;
3393 if (channel_req <= CH_MAX_2G_CHANNEL)
3394 band = NL80211_BAND_2GHZ;
3396 band = NL80211_BAND_5GHZ;
3397 channel[i].center_freq =
3398 ieee80211_channel_to_frequency(channel_req,
3400 channel[i].band = band;
3401 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3402 request->channels[i] = &channel[i];
3403 request->n_channels++;
3406 /* assign parsed ssid array */
3407 if (request->n_ssids)
3408 request->ssids = &ssid[0];
3410 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3411 /* Abort any on-going scan */
3412 brcmf_abort_scanning(cfg);
3415 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3416 cfg->escan_info.run = brcmf_run_escan;
3417 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3419 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3422 cfg->sched_escan = true;
3423 cfg->scan_request = request;
3425 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3438 cfg80211_sched_scan_stopped(wiphy);
3442 static int brcmf_dev_pno_clean(struct net_device *ndev)
3447 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3450 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3454 brcmf_err("failed code %d\n", ret);
3459 static int brcmf_dev_pno_config(struct net_device *ndev)
3461 struct brcmf_pno_param_le pfn_param;
3463 memset(&pfn_param, 0, sizeof(pfn_param));
3464 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3466 /* set extra pno params */
3467 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3468 pfn_param.repeat = BRCMF_PNO_REPEAT;
3469 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3471 /* set up pno scan fr */
3472 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3474 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3475 &pfn_param, sizeof(pfn_param));
3479 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3480 struct net_device *ndev,
3481 struct cfg80211_sched_scan_request *request)
3483 struct brcmf_if *ifp = netdev_priv(ndev);
3484 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3485 struct brcmf_pno_net_param_le pfn;
3489 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3490 request->n_match_sets, request->n_ssids);
3491 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3492 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3495 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3496 brcmf_err("Scanning suppressed: status (%lu)\n",
3501 if (!request->n_ssids || !request->n_match_sets) {
3502 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3507 if (request->n_ssids > 0) {
3508 for (i = 0; i < request->n_ssids; i++) {
3509 /* Active scan req for ssids */
3510 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3511 request->ssids[i].ssid);
3514 * match_set ssids is a supert set of n_ssid list,
3515 * so we need not add these set seperately.
3520 if (request->n_match_sets > 0) {
3521 /* clean up everything */
3522 ret = brcmf_dev_pno_clean(ndev);
3524 brcmf_err("failed error=%d\n", ret);
3529 ret = brcmf_dev_pno_config(ndev);
3531 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3535 /* configure each match set */
3536 for (i = 0; i < request->n_match_sets; i++) {
3537 struct cfg80211_ssid *ssid;
3540 ssid = &request->match_sets[i].ssid;
3541 ssid_len = ssid->ssid_len;
3544 brcmf_err("skip broadcast ssid\n");
3547 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3548 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3549 pfn.wsec = cpu_to_le32(0);
3550 pfn.infra = cpu_to_le32(1);
3551 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3552 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3553 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3554 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3556 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3557 ret == 0 ? "set" : "failed", ssid->ssid);
3559 /* Enable the PNO */
3560 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3561 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3571 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3572 struct net_device *ndev)
3574 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3576 brcmf_dbg(SCAN, "enter\n");
3577 brcmf_dev_pno_clean(ndev);
3578 if (cfg->sched_escan)
3579 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3583 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3588 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3590 brcmf_err("auth error %d\n", err);
3594 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3596 brcmf_err("wsec error %d\n", err);
3599 /* set upper-layer auth */
3600 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3602 brcmf_err("wpa_auth error %d\n", err);
3609 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3612 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3614 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3618 brcmf_configure_wpaie(struct brcmf_if *ifp,
3619 const struct brcmf_vs_tlv *wpa_ie,
3622 u32 auth = 0; /* d11 open authentication */
3634 u32 wme_bss_disable;
3636 brcmf_dbg(TRACE, "Enter\n");
3640 len = wpa_ie->len + TLV_HDR_LEN;
3641 data = (u8 *)wpa_ie;
3642 offset = TLV_HDR_LEN;
3644 offset += VS_IE_FIXED_HDR_LEN;
3646 offset += WPA_IE_VERSION_LEN;
3648 /* check for multicast cipher suite */
3649 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3651 brcmf_err("no multicast cipher suite\n");
3655 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3657 brcmf_err("ivalid OUI\n");
3660 offset += TLV_OUI_LEN;
3662 /* pick up multicast cipher */
3663 switch (data[offset]) {
3664 case WPA_CIPHER_NONE:
3667 case WPA_CIPHER_WEP_40:
3668 case WPA_CIPHER_WEP_104:
3671 case WPA_CIPHER_TKIP:
3672 gval = TKIP_ENABLED;
3674 case WPA_CIPHER_AES_CCM:
3679 brcmf_err("Invalid multi cast cipher info\n");
3684 /* walk thru unicast cipher list and pick up what we recognize */
3685 count = data[offset] + (data[offset + 1] << 8);
3686 offset += WPA_IE_SUITE_COUNT_LEN;
3687 /* Check for unicast suite(s) */
3688 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3690 brcmf_err("no unicast cipher suite\n");
3693 for (i = 0; i < count; i++) {
3694 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3696 brcmf_err("ivalid OUI\n");
3699 offset += TLV_OUI_LEN;
3700 switch (data[offset]) {
3701 case WPA_CIPHER_NONE:
3703 case WPA_CIPHER_WEP_40:
3704 case WPA_CIPHER_WEP_104:
3705 pval |= WEP_ENABLED;
3707 case WPA_CIPHER_TKIP:
3708 pval |= TKIP_ENABLED;
3710 case WPA_CIPHER_AES_CCM:
3711 pval |= AES_ENABLED;
3714 brcmf_err("Ivalid unicast security info\n");
3718 /* walk thru auth management suite list and pick up what we recognize */
3719 count = data[offset] + (data[offset + 1] << 8);
3720 offset += WPA_IE_SUITE_COUNT_LEN;
3721 /* Check for auth key management suite(s) */
3722 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3724 brcmf_err("no auth key mgmt suite\n");
3727 for (i = 0; i < count; i++) {
3728 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3730 brcmf_err("ivalid OUI\n");
3733 offset += TLV_OUI_LEN;
3734 switch (data[offset]) {
3736 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3737 wpa_auth |= WPA_AUTH_NONE;
3739 case RSN_AKM_UNSPECIFIED:
3740 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3741 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3742 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3745 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3746 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3747 (wpa_auth |= WPA_AUTH_PSK);
3750 brcmf_err("Ivalid key mgmt info\n");
3756 wme_bss_disable = 1;
3757 if ((offset + RSN_CAP_LEN) <= len) {
3758 rsn_cap = data[offset] + (data[offset + 1] << 8);
3759 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3760 wme_bss_disable = 0;
3762 /* set wme_bss_disable to sync RSN Capabilities */
3763 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3766 brcmf_err("wme_bss_disable error %d\n", err);
3770 /* FOR WPS , set SES_OW_ENABLED */
3771 wsec = (pval | gval | SES_OW_ENABLED);
3774 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3776 brcmf_err("auth error %d\n", err);
3780 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3782 brcmf_err("wsec error %d\n", err);
3785 /* set upper-layer auth */
3786 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3788 brcmf_err("wpa_auth error %d\n", err);
3797 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3798 struct parsed_vndr_ies *vndr_ies)
3800 struct brcmf_vs_tlv *vndrie;
3801 struct brcmf_tlv *ie;
3802 struct parsed_vndr_ie_info *parsed_info;
3805 remaining_len = (s32)vndr_ie_len;
3806 memset(vndr_ies, 0, sizeof(*vndr_ies));
3808 ie = (struct brcmf_tlv *)vndr_ie_buf;
3810 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3812 vndrie = (struct brcmf_vs_tlv *)ie;
3813 /* len should be bigger than OUI length + one */
3814 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3815 brcmf_err("invalid vndr ie. length is too small %d\n",
3819 /* if wpa or wme ie, do not add ie */
3820 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3821 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3822 (vndrie->oui_type == WME_OUI_TYPE))) {
3823 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3827 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3829 /* save vndr ie information */
3830 parsed_info->ie_ptr = (char *)vndrie;
3831 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3832 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3836 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3837 parsed_info->vndrie.oui[0],
3838 parsed_info->vndrie.oui[1],
3839 parsed_info->vndrie.oui[2],
3840 parsed_info->vndrie.oui_type);
3842 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3845 remaining_len -= (ie->len + TLV_HDR_LEN);
3846 if (remaining_len <= TLV_HDR_LEN)
3849 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3856 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3859 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3860 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3862 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3864 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3866 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3868 return ie_len + VNDR_IE_HDR_SIZE;
3871 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3872 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3874 struct brcmf_if *ifp;
3875 struct vif_saved_ie *saved_ie;
3879 u8 *mgmt_ie_buf = NULL;
3880 int mgmt_ie_buf_len;
3882 u32 del_add_ie_buf_len = 0;
3883 u32 total_ie_buf_len = 0;
3884 u32 parsed_ie_buf_len = 0;
3885 struct parsed_vndr_ies old_vndr_ies;
3886 struct parsed_vndr_ies new_vndr_ies;
3887 struct parsed_vndr_ie_info *vndrie_info;
3890 int remained_buf_len;
3895 saved_ie = &vif->saved_ie;
3897 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3898 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3901 curr_ie_buf = iovar_ie_buf;
3903 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3904 mgmt_ie_buf = saved_ie->probe_req_ie;
3905 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3906 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3908 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3909 mgmt_ie_buf = saved_ie->probe_res_ie;
3910 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3911 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3913 case BRCMF_VNDR_IE_BEACON_FLAG:
3914 mgmt_ie_buf = saved_ie->beacon_ie;
3915 mgmt_ie_len = &saved_ie->beacon_ie_len;
3916 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3918 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3919 mgmt_ie_buf = saved_ie->assoc_req_ie;
3920 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3921 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3925 brcmf_err("not suitable type\n");
3929 if (vndr_ie_len > mgmt_ie_buf_len) {
3931 brcmf_err("extra IE size too big\n");
3935 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3936 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3938 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3939 for (i = 0; i < new_vndr_ies.count; i++) {
3940 vndrie_info = &new_vndr_ies.ie_info[i];
3941 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3942 vndrie_info->ie_len);
3943 parsed_ie_buf_len += vndrie_info->ie_len;
3947 if (mgmt_ie_buf && *mgmt_ie_len) {
3948 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3949 (memcmp(mgmt_ie_buf, curr_ie_buf,
3950 parsed_ie_buf_len) == 0)) {
3951 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3955 /* parse old vndr_ie */
3956 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3958 /* make a command to delete old ie */
3959 for (i = 0; i < old_vndr_ies.count; i++) {
3960 vndrie_info = &old_vndr_ies.ie_info[i];
3962 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3963 vndrie_info->vndrie.id,
3964 vndrie_info->vndrie.len,
3965 vndrie_info->vndrie.oui[0],
3966 vndrie_info->vndrie.oui[1],
3967 vndrie_info->vndrie.oui[2]);
3969 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3970 vndrie_info->ie_ptr,
3971 vndrie_info->ie_len,
3973 curr_ie_buf += del_add_ie_buf_len;
3974 total_ie_buf_len += del_add_ie_buf_len;
3979 /* Add if there is any extra IE */
3980 if (mgmt_ie_buf && parsed_ie_buf_len) {
3983 remained_buf_len = mgmt_ie_buf_len;
3985 /* make a command to add new ie */
3986 for (i = 0; i < new_vndr_ies.count; i++) {
3987 vndrie_info = &new_vndr_ies.ie_info[i];
3989 /* verify remained buf size before copy data */
3990 if (remained_buf_len < (vndrie_info->vndrie.len +
3991 VNDR_IE_VSIE_OFFSET)) {
3992 brcmf_err("no space in mgmt_ie_buf: len left %d",
3996 remained_buf_len -= (vndrie_info->ie_len +
3997 VNDR_IE_VSIE_OFFSET);
3999 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4000 vndrie_info->vndrie.id,
4001 vndrie_info->vndrie.len,
4002 vndrie_info->vndrie.oui[0],
4003 vndrie_info->vndrie.oui[1],
4004 vndrie_info->vndrie.oui[2]);
4006 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4007 vndrie_info->ie_ptr,
4008 vndrie_info->ie_len,
4011 /* save the parsed IE in wl struct */
4012 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4013 vndrie_info->ie_len);
4014 *mgmt_ie_len += vndrie_info->ie_len;
4016 curr_ie_buf += del_add_ie_buf_len;
4017 total_ie_buf_len += del_add_ie_buf_len;
4020 if (total_ie_buf_len) {
4021 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4024 brcmf_err("vndr ie set error : %d\n", err);
4028 kfree(iovar_ie_buf);
4032 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4035 BRCMF_VNDR_IE_PRBREQ_FLAG,
4036 BRCMF_VNDR_IE_PRBRSP_FLAG,
4037 BRCMF_VNDR_IE_BEACON_FLAG
4041 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4042 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4044 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4049 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4050 struct cfg80211_beacon_data *beacon)
4054 /* Set Beacon IEs to FW */
4055 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4056 beacon->tail, beacon->tail_len);
4058 brcmf_err("Set Beacon IE Failed\n");
4061 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4063 /* Set Probe Response IEs to FW */
4064 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4065 beacon->proberesp_ies,
4066 beacon->proberesp_ies_len);
4068 brcmf_err("Set Probe Resp IE Failed\n");
4070 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4076 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4077 struct cfg80211_ap_settings *settings)
4080 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4081 struct brcmf_if *ifp = netdev_priv(ndev);
4082 const struct brcmf_tlv *ssid_ie;
4083 const struct brcmf_tlv *country_ie;
4084 struct brcmf_ssid_le ssid_le;
4086 const struct brcmf_tlv *rsn_ie;
4087 const struct brcmf_vs_tlv *wpa_ie;
4088 struct brcmf_join_params join_params;
4089 enum nl80211_iftype dev_role;
4090 struct brcmf_fil_bss_enable_le bss_enable;
4095 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4096 settings->chandef.chan->hw_value,
4097 settings->chandef.center_freq1, settings->chandef.width,
4098 settings->beacon_interval, settings->dtim_period);
4099 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4100 settings->ssid, settings->ssid_len, settings->auth_type,
4101 settings->inactivity_timeout);
4102 dev_role = ifp->vif->wdev.iftype;
4103 mbss = ifp->vif->mbss;
4105 /* store current 11d setting */
4106 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4107 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4108 settings->beacon.tail_len,
4110 is_11d = country_ie ? 1 : 0;
4112 memset(&ssid_le, 0, sizeof(ssid_le));
4113 if (settings->ssid == NULL || settings->ssid_len == 0) {
4114 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4115 ssid_ie = brcmf_parse_tlvs(
4116 (u8 *)&settings->beacon.head[ie_offset],
4117 settings->beacon.head_len - ie_offset,
4119 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4122 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4123 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4124 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4126 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4127 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4131 brcmf_set_mpc(ifp, 0);
4132 brcmf_configure_arp_offload(ifp, false);
4135 /* find the RSN_IE */
4136 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4137 settings->beacon.tail_len, WLAN_EID_RSN);
4139 /* find the WPA_IE */
4140 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4141 settings->beacon.tail_len);
4143 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4144 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4145 if (wpa_ie != NULL) {
4147 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4151 struct brcmf_vs_tlv *tmp_ie;
4153 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4156 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4161 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4162 brcmf_configure_opensecurity(ifp);
4165 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4168 chanspec = chandef_to_chanspec(&cfg->d11inf,
4169 &settings->chandef);
4170 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4172 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4177 if (is_11d != ifp->vif->is_11d) {
4178 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4181 brcmf_err("Regulatory Set Error, %d\n", err);
4185 if (settings->beacon_interval) {
4186 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4187 settings->beacon_interval);
4189 brcmf_err("Beacon Interval Set Error, %d\n",
4194 if (settings->dtim_period) {
4195 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4196 settings->dtim_period);
4198 brcmf_err("DTIM Interval Set Error, %d\n", err);
4203 if (dev_role == NL80211_IFTYPE_AP) {
4204 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4206 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4209 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4212 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4214 brcmf_err("SET INFRA error %d\n", err);
4217 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4218 /* Multiple-BSS should use same 11d configuration */
4222 if (dev_role == NL80211_IFTYPE_AP) {
4223 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4224 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4226 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4228 brcmf_err("setting AP mode failed %d\n", err);
4231 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4233 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4236 /* On DOWN the firmware removes the WEP keys, reconfigure
4237 * them if they were set.
4239 brcmf_cfg80211_reconfigure_wep(ifp);
4241 memset(&join_params, 0, sizeof(join_params));
4242 /* join parameters starts with ssid */
4243 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4245 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4246 &join_params, sizeof(join_params));
4248 brcmf_err("SET SSID error (%d)\n", err);
4251 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4253 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4256 brcmf_err("setting ssid failed %d\n", err);
4259 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4260 bss_enable.enable = cpu_to_le32(1);
4261 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4262 sizeof(bss_enable));
4264 brcmf_err("bss_enable config failed %d\n", err);
4268 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4270 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4271 brcmf_net_setcarrier(ifp, true);
4274 if ((err) && (!mbss)) {
4275 brcmf_set_mpc(ifp, 1);
4276 brcmf_configure_arp_offload(ifp, true);
4281 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4283 struct brcmf_if *ifp = netdev_priv(ndev);
4285 struct brcmf_fil_bss_enable_le bss_enable;
4286 struct brcmf_join_params join_params;
4288 brcmf_dbg(TRACE, "Enter\n");
4290 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4291 /* Due to most likely deauths outstanding we sleep */
4292 /* first to make sure they get processed by fw. */
4295 if (ifp->vif->mbss) {
4296 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4300 memset(&join_params, 0, sizeof(join_params));
4301 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4302 &join_params, sizeof(join_params));
4304 brcmf_err("SET SSID error (%d)\n", err);
4305 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4307 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4308 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4310 brcmf_err("setting AP mode failed %d\n", err);
4311 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4312 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4313 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4316 brcmf_err("restoring REGULATORY setting failed %d\n",
4318 /* Bring device back up so it can be used again */
4319 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4321 brcmf_err("BRCMF_C_UP error %d\n", err);
4323 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4324 bss_enable.enable = cpu_to_le32(0);
4325 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4326 sizeof(bss_enable));
4328 brcmf_err("bss_enable config failed %d\n", err);
4330 brcmf_set_mpc(ifp, 1);
4331 brcmf_configure_arp_offload(ifp, true);
4332 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4333 brcmf_net_setcarrier(ifp, false);
4339 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4340 struct cfg80211_beacon_data *info)
4342 struct brcmf_if *ifp = netdev_priv(ndev);
4345 brcmf_dbg(TRACE, "Enter\n");
4347 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4353 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4354 struct station_del_parameters *params)
4356 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4357 struct brcmf_scb_val_le scbval;
4358 struct brcmf_if *ifp = netdev_priv(ndev);
4364 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4366 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4367 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4368 if (!check_vif_up(ifp->vif))
4371 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4372 scbval.val = cpu_to_le32(params->reason_code);
4373 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4374 &scbval, sizeof(scbval));
4376 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4378 brcmf_dbg(TRACE, "Exit\n");
4383 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4384 const u8 *mac, struct station_parameters *params)
4386 struct brcmf_if *ifp = netdev_priv(ndev);
4389 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4390 params->sta_flags_mask, params->sta_flags_set);
4392 /* Ignore all 00 MAC */
4393 if (is_zero_ether_addr(mac))
4396 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4399 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4400 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4401 (void *)mac, ETH_ALEN);
4403 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4404 (void *)mac, ETH_ALEN);
4406 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4412 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4413 struct wireless_dev *wdev,
4414 u16 frame_type, bool reg)
4416 struct brcmf_cfg80211_vif *vif;
4419 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4421 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4422 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4424 vif->mgmt_rx_reg |= BIT(mgmt_type);
4426 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4431 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4432 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4434 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4435 struct ieee80211_channel *chan = params->chan;
4436 const u8 *buf = params->buf;
4437 size_t len = params->len;
4438 const struct ieee80211_mgmt *mgmt;
4439 struct brcmf_cfg80211_vif *vif;
4443 struct brcmf_fil_action_frame_le *action_frame;
4444 struct brcmf_fil_af_params_le *af_params;
4449 brcmf_dbg(TRACE, "Enter\n");
4453 mgmt = (const struct ieee80211_mgmt *)buf;
4455 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4456 brcmf_err("Driver only allows MGMT packet type\n");
4460 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4462 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4463 /* Right now the only reason to get a probe response */
4464 /* is for p2p listen response or for p2p GO from */
4465 /* wpa_supplicant. Unfortunately the probe is send */
4466 /* on primary ndev, while dongle wants it on the p2p */
4467 /* vif. Since this is only reason for a probe */
4468 /* response to be sent, the vif is taken from cfg. */
4469 /* If ever desired to send proberesp for non p2p */
4470 /* response then data should be checked for */
4471 /* "DIRECT-". Note in future supplicant will take */
4472 /* dedicated p2p wdev to do this and then this 'hack'*/
4473 /* is not needed anymore. */
4474 ie_offset = DOT11_MGMT_HDR_LEN +
4475 DOT11_BCN_PRB_FIXED_LEN;
4476 ie_len = len - ie_offset;
4477 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4478 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4479 err = brcmf_vif_set_mgmt_ie(vif,
4480 BRCMF_VNDR_IE_PRBRSP_FLAG,
4483 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4485 } else if (ieee80211_is_action(mgmt->frame_control)) {
4486 if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
4487 brcmf_err("invalid action frame length\n");
4491 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4492 if (af_params == NULL) {
4493 brcmf_err("unable to allocate frame\n");
4497 action_frame = &af_params->action_frame;
4498 /* Add the packet Id */
4499 action_frame->packet_id = cpu_to_le32(*cookie);
4501 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4502 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4503 /* Add the length exepted for 802.11 header */
4504 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4505 /* Add the channel. Use the one specified as parameter if any or
4506 * the current one (got from the firmware) otherwise
4509 freq = chan->center_freq;
4511 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4513 chan_nr = ieee80211_frequency_to_channel(freq);
4514 af_params->channel = cpu_to_le32(chan_nr);
4516 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4517 le16_to_cpu(action_frame->len));
4519 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4520 *cookie, le16_to_cpu(action_frame->len), freq);
4522 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4525 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4529 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4530 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4539 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4540 struct wireless_dev *wdev,
4543 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4544 struct brcmf_cfg80211_vif *vif;
4547 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4549 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4551 brcmf_err("No p2p device available for probe response\n");
4555 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4560 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4561 struct wireless_dev *wdev,
4562 enum nl80211_crit_proto_id proto,
4565 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4566 struct brcmf_cfg80211_vif *vif;
4568 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4570 /* only DHCP support for now */
4571 if (proto != NL80211_CRIT_PROTO_DHCP)
4574 /* suppress and abort scanning */
4575 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4576 brcmf_abort_scanning(cfg);
4578 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4581 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4582 struct wireless_dev *wdev)
4584 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4585 struct brcmf_cfg80211_vif *vif;
4587 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4589 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4590 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4594 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4595 const struct brcmf_event_msg *e, void *data)
4597 switch (e->reason) {
4598 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4599 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4601 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4602 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4603 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4605 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4606 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4607 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4614 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4619 case NL80211_TDLS_DISCOVERY_REQ:
4620 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4622 case NL80211_TDLS_SETUP:
4623 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4625 case NL80211_TDLS_TEARDOWN:
4626 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4629 brcmf_err("unsupported operation: %d\n", oper);
4635 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4636 struct net_device *ndev, const u8 *peer,
4637 enum nl80211_tdls_operation oper)
4639 struct brcmf_if *ifp;
4640 struct brcmf_tdls_iovar_le info;
4643 ret = brcmf_convert_nl80211_tdls_oper(oper);
4647 ifp = netdev_priv(ndev);
4648 memset(&info, 0, sizeof(info));
4649 info.mode = (u8)ret;
4651 memcpy(info.ea, peer, ETH_ALEN);
4653 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4654 &info, sizeof(info));
4656 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4661 static struct cfg80211_ops wl_cfg80211_ops = {
4662 .add_virtual_intf = brcmf_cfg80211_add_iface,
4663 .del_virtual_intf = brcmf_cfg80211_del_iface,
4664 .change_virtual_intf = brcmf_cfg80211_change_iface,
4665 .scan = brcmf_cfg80211_scan,
4666 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4667 .join_ibss = brcmf_cfg80211_join_ibss,
4668 .leave_ibss = brcmf_cfg80211_leave_ibss,
4669 .get_station = brcmf_cfg80211_get_station,
4670 .dump_station = brcmf_cfg80211_dump_station,
4671 .set_tx_power = brcmf_cfg80211_set_tx_power,
4672 .get_tx_power = brcmf_cfg80211_get_tx_power,
4673 .add_key = brcmf_cfg80211_add_key,
4674 .del_key = brcmf_cfg80211_del_key,
4675 .get_key = brcmf_cfg80211_get_key,
4676 .set_default_key = brcmf_cfg80211_config_default_key,
4677 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4678 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4679 .connect = brcmf_cfg80211_connect,
4680 .disconnect = brcmf_cfg80211_disconnect,
4681 .suspend = brcmf_cfg80211_suspend,
4682 .resume = brcmf_cfg80211_resume,
4683 .set_pmksa = brcmf_cfg80211_set_pmksa,
4684 .del_pmksa = brcmf_cfg80211_del_pmksa,
4685 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4686 .start_ap = brcmf_cfg80211_start_ap,
4687 .stop_ap = brcmf_cfg80211_stop_ap,
4688 .change_beacon = brcmf_cfg80211_change_beacon,
4689 .del_station = brcmf_cfg80211_del_station,
4690 .change_station = brcmf_cfg80211_change_station,
4691 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4692 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4693 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4694 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4695 .remain_on_channel = brcmf_p2p_remain_on_channel,
4696 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4697 .start_p2p_device = brcmf_p2p_start_device,
4698 .stop_p2p_device = brcmf_p2p_stop_device,
4699 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4700 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4701 .tdls_oper = brcmf_cfg80211_tdls_oper,
4704 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4705 enum nl80211_iftype type,
4708 struct brcmf_cfg80211_vif *vif_walk;
4709 struct brcmf_cfg80211_vif *vif;
4712 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4714 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4716 return ERR_PTR(-ENOMEM);
4718 vif->wdev.wiphy = cfg->wiphy;
4719 vif->wdev.iftype = type;
4721 vif->pm_block = pm_block;
4724 brcmf_init_prof(&vif->profile);
4726 if (type == NL80211_IFTYPE_AP) {
4728 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4729 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4737 list_add_tail(&vif->list, &cfg->vif_list);
4741 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4743 list_del(&vif->list);
4747 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4749 struct brcmf_cfg80211_vif *vif;
4750 struct brcmf_if *ifp;
4752 ifp = netdev_priv(ndev);
4756 brcmf_free_vif(vif);
4760 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4762 u32 event = e->event_code;
4763 u32 status = e->status;
4765 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4766 brcmf_dbg(CONN, "Processing set ssid\n");
4773 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4775 u32 event = e->event_code;
4776 u16 flags = e->flags;
4778 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4779 (event == BRCMF_E_DISASSOC_IND) ||
4780 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4781 brcmf_dbg(CONN, "Processing link down\n");
4787 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4788 const struct brcmf_event_msg *e)
4790 u32 event = e->event_code;
4791 u32 status = e->status;
4793 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4794 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4795 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4799 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4800 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4807 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4809 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4811 kfree(conn_info->req_ie);
4812 conn_info->req_ie = NULL;
4813 conn_info->req_ie_len = 0;
4814 kfree(conn_info->resp_ie);
4815 conn_info->resp_ie = NULL;
4816 conn_info->resp_ie_len = 0;
4819 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4820 struct brcmf_if *ifp)
4822 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4823 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4828 brcmf_clear_assoc_ies(cfg);
4830 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4831 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4833 brcmf_err("could not get assoc info (%d)\n", err);
4837 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4838 req_len = le32_to_cpu(assoc_info->req_len);
4839 resp_len = le32_to_cpu(assoc_info->resp_len);
4841 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4845 brcmf_err("could not get assoc req (%d)\n", err);
4848 conn_info->req_ie_len = req_len;
4850 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4852 if (!conn_info->req_ie)
4853 conn_info->req_ie_len = 0;
4855 conn_info->req_ie_len = 0;
4856 conn_info->req_ie = NULL;
4859 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4863 brcmf_err("could not get assoc resp (%d)\n", err);
4866 conn_info->resp_ie_len = resp_len;
4867 conn_info->resp_ie =
4868 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4870 if (!conn_info->resp_ie)
4871 conn_info->resp_ie_len = 0;
4873 conn_info->resp_ie_len = 0;
4874 conn_info->resp_ie = NULL;
4876 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4877 conn_info->req_ie_len, conn_info->resp_ie_len);
4883 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4884 struct net_device *ndev,
4885 const struct brcmf_event_msg *e)
4887 struct brcmf_if *ifp = netdev_priv(ndev);
4888 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4889 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4890 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4891 struct ieee80211_channel *notify_channel = NULL;
4892 struct ieee80211_supported_band *band;
4893 struct brcmf_bss_info_le *bi;
4894 struct brcmu_chan ch;
4899 brcmf_dbg(TRACE, "Enter\n");
4901 brcmf_get_assoc_ies(cfg, ifp);
4902 memcpy(profile->bssid, e->addr, ETH_ALEN);
4903 brcmf_update_bss_info(cfg, ifp);
4905 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4911 /* data sent to dongle has to be little endian */
4912 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4913 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4914 buf, WL_BSS_INFO_MAX);
4919 bi = (struct brcmf_bss_info_le *)(buf + 4);
4920 ch.chspec = le16_to_cpu(bi->chanspec);
4921 cfg->d11inf.decchspec(&ch);
4923 if (ch.band == BRCMU_CHAN_BAND_2G)
4924 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4926 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4928 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4929 notify_channel = ieee80211_get_channel(wiphy, freq);
4933 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4934 conn_info->req_ie, conn_info->req_ie_len,
4935 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4936 brcmf_dbg(CONN, "Report roaming result\n");
4938 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4939 brcmf_dbg(TRACE, "Exit\n");
4944 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4945 struct net_device *ndev, const struct brcmf_event_msg *e,
4948 struct brcmf_if *ifp = netdev_priv(ndev);
4949 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4950 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4952 brcmf_dbg(TRACE, "Enter\n");
4954 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4955 &ifp->vif->sme_state)) {
4957 brcmf_get_assoc_ies(cfg, ifp);
4958 memcpy(profile->bssid, e->addr, ETH_ALEN);
4959 brcmf_update_bss_info(cfg, ifp);
4960 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4961 &ifp->vif->sme_state);
4963 cfg80211_connect_result(ndev,
4964 (u8 *)profile->bssid,
4966 conn_info->req_ie_len,
4968 conn_info->resp_ie_len,
4969 completed ? WLAN_STATUS_SUCCESS :
4970 WLAN_STATUS_AUTH_TIMEOUT,
4972 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4973 completed ? "succeeded" : "failed");
4975 brcmf_dbg(TRACE, "Exit\n");
4980 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4981 struct net_device *ndev,
4982 const struct brcmf_event_msg *e, void *data)
4984 struct brcmf_if *ifp = netdev_priv(ndev);
4985 static int generation;
4986 u32 event = e->event_code;
4987 u32 reason = e->reason;
4988 struct station_info sinfo;
4990 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4991 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4992 ndev != cfg_to_ndev(cfg)) {
4993 brcmf_dbg(CONN, "AP mode link down\n");
4994 complete(&cfg->vif_disabled);
4996 brcmf_remove_interface(ifp);
5000 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5001 (reason == BRCMF_E_STATUS_SUCCESS)) {
5002 memset(&sinfo, 0, sizeof(sinfo));
5004 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5007 sinfo.assoc_req_ies = data;
5008 sinfo.assoc_req_ies_len = e->datalen;
5010 sinfo.generation = generation;
5011 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5012 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5013 (event == BRCMF_E_DEAUTH_IND) ||
5014 (event == BRCMF_E_DEAUTH)) {
5015 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5021 brcmf_notify_connect_status(struct brcmf_if *ifp,
5022 const struct brcmf_event_msg *e, void *data)
5024 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5025 struct net_device *ndev = ifp->ndev;
5026 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5027 struct ieee80211_channel *chan;
5030 if ((e->event_code == BRCMF_E_DEAUTH) ||
5031 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5032 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5033 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5034 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5037 if (brcmf_is_apmode(ifp->vif)) {
5038 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5039 } else if (brcmf_is_linkup(e)) {
5040 brcmf_dbg(CONN, "Linkup\n");
5041 if (brcmf_is_ibssmode(ifp->vif)) {
5042 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5043 memcpy(profile->bssid, e->addr, ETH_ALEN);
5044 wl_inform_ibss(cfg, ndev, e->addr);
5045 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5046 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5047 &ifp->vif->sme_state);
5048 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5049 &ifp->vif->sme_state);
5051 brcmf_bss_connect_done(cfg, ndev, e, true);
5052 brcmf_net_setcarrier(ifp, true);
5053 } else if (brcmf_is_linkdown(e)) {
5054 brcmf_dbg(CONN, "Linkdown\n");
5055 if (!brcmf_is_ibssmode(ifp->vif)) {
5056 brcmf_bss_connect_done(cfg, ndev, e, false);
5058 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
5059 brcmf_init_prof(ndev_to_prof(ndev));
5060 if (ndev != cfg_to_ndev(cfg))
5061 complete(&cfg->vif_disabled);
5062 brcmf_net_setcarrier(ifp, false);
5063 } else if (brcmf_is_nonetwork(cfg, e)) {
5064 if (brcmf_is_ibssmode(ifp->vif))
5065 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5066 &ifp->vif->sme_state);
5068 brcmf_bss_connect_done(cfg, ndev, e, false);
5075 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5076 const struct brcmf_event_msg *e, void *data)
5078 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5079 u32 event = e->event_code;
5080 u32 status = e->status;
5082 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5083 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5084 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5086 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5093 brcmf_notify_mic_status(struct brcmf_if *ifp,
5094 const struct brcmf_event_msg *e, void *data)
5096 u16 flags = e->flags;
5097 enum nl80211_key_type key_type;
5099 if (flags & BRCMF_EVENT_MSG_GROUP)
5100 key_type = NL80211_KEYTYPE_GROUP;
5102 key_type = NL80211_KEYTYPE_PAIRWISE;
5104 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5110 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5111 const struct brcmf_event_msg *e, void *data)
5113 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5114 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5115 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5116 struct brcmf_cfg80211_vif *vif;
5118 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
5119 ifevent->action, ifevent->flags, ifevent->ifidx,
5122 mutex_lock(&event->vif_event_lock);
5123 event->action = ifevent->action;
5126 switch (ifevent->action) {
5127 case BRCMF_E_IF_ADD:
5128 /* waiting process may have timed out */
5129 if (!cfg->vif_event.vif) {
5130 mutex_unlock(&event->vif_event_lock);
5137 vif->wdev.netdev = ifp->ndev;
5138 ifp->ndev->ieee80211_ptr = &vif->wdev;
5139 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5141 mutex_unlock(&event->vif_event_lock);
5142 wake_up(&event->vif_wq);
5145 case BRCMF_E_IF_DEL:
5146 mutex_unlock(&event->vif_event_lock);
5147 /* event may not be upon user request */
5148 if (brcmf_cfg80211_vif_event_armed(cfg))
5149 wake_up(&event->vif_wq);
5152 case BRCMF_E_IF_CHANGE:
5153 mutex_unlock(&event->vif_event_lock);
5154 wake_up(&event->vif_wq);
5158 mutex_unlock(&event->vif_event_lock);
5164 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5166 conf->frag_threshold = (u32)-1;
5167 conf->rts_threshold = (u32)-1;
5168 conf->retry_short = (u32)-1;
5169 conf->retry_long = (u32)-1;
5170 conf->tx_power = -1;
5173 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5175 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5176 brcmf_notify_connect_status);
5177 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5178 brcmf_notify_connect_status);
5179 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5180 brcmf_notify_connect_status);
5181 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5182 brcmf_notify_connect_status);
5183 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5184 brcmf_notify_connect_status);
5185 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5186 brcmf_notify_connect_status);
5187 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5188 brcmf_notify_roaming_status);
5189 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5190 brcmf_notify_mic_status);
5191 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5192 brcmf_notify_connect_status);
5193 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5194 brcmf_notify_sched_scan_results);
5195 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5196 brcmf_notify_vif_event);
5197 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5198 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5199 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5200 brcmf_p2p_notify_listen_complete);
5201 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5202 brcmf_p2p_notify_action_frame_rx);
5203 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5204 brcmf_p2p_notify_action_tx_complete);
5205 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5206 brcmf_p2p_notify_action_tx_complete);
5209 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5213 kfree(cfg->escan_ioctl_buf);
5214 cfg->escan_ioctl_buf = NULL;
5215 kfree(cfg->extra_buf);
5216 cfg->extra_buf = NULL;
5217 kfree(cfg->pmk_list);
5218 cfg->pmk_list = NULL;
5221 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5223 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5225 goto init_priv_mem_out;
5226 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5227 if (!cfg->escan_ioctl_buf)
5228 goto init_priv_mem_out;
5229 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5230 if (!cfg->extra_buf)
5231 goto init_priv_mem_out;
5232 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
5234 goto init_priv_mem_out;
5239 brcmf_deinit_priv_mem(cfg);
5244 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5248 cfg->scan_request = NULL;
5249 cfg->pwr_save = true;
5250 cfg->active_scan = true; /* we do active scan per default */
5251 cfg->dongle_up = false; /* dongle is not up yet */
5252 err = brcmf_init_priv_mem(cfg);
5255 brcmf_register_event_handlers(cfg);
5256 mutex_init(&cfg->usr_sync);
5257 brcmf_init_escan(cfg);
5258 brcmf_init_conf(cfg->conf);
5259 init_completion(&cfg->vif_disabled);
5263 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5265 cfg->dongle_up = false; /* dongle down */
5266 brcmf_abort_scanning(cfg);
5267 brcmf_deinit_priv_mem(cfg);
5270 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5272 init_waitqueue_head(&event->vif_wq);
5273 mutex_init(&event->vif_event_lock);
5277 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5280 __le32 roamtrigger[2];
5281 __le32 roam_delta[2];
5284 * Setup timeout if Beacons are lost and roam is
5285 * off to report link down
5287 if (brcmf_roamoff) {
5288 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5290 brcmf_err("bcn_timeout error (%d)\n", err);
5291 goto dongle_rom_out;
5296 * Enable/Disable built-in roaming to allow supplicant
5297 * to take care of roaming
5299 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5300 brcmf_roamoff ? "Off" : "On");
5301 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5303 brcmf_err("roam_off error (%d)\n", err);
5304 goto dongle_rom_out;
5307 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5308 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5309 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5310 (void *)roamtrigger, sizeof(roamtrigger));
5312 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5313 goto dongle_rom_out;
5316 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5317 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5318 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5319 (void *)roam_delta, sizeof(roam_delta));
5321 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5322 goto dongle_rom_out;
5330 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5331 s32 scan_unassoc_time, s32 scan_passive_time)
5335 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5338 if (err == -EOPNOTSUPP)
5339 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5341 brcmf_err("Scan assoc time error (%d)\n", err);
5342 goto dongle_scantime_out;
5344 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5347 if (err == -EOPNOTSUPP)
5348 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5350 brcmf_err("Scan unassoc time error (%d)\n", err);
5351 goto dongle_scantime_out;
5354 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5357 if (err == -EOPNOTSUPP)
5358 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5360 brcmf_err("Scan passive time error (%d)\n", err);
5361 goto dongle_scantime_out;
5364 dongle_scantime_out:
5368 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5369 struct brcmu_chan *ch)
5373 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5374 if (ch->sb == BRCMU_CHAN_SB_U) {
5375 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5376 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5377 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5379 /* It should be one of
5380 * IEEE80211_CHAN_NO_HT40 or
5381 * IEEE80211_CHAN_NO_HT40PLUS
5383 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5384 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5385 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5389 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5392 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5393 struct ieee80211_supported_band *band;
5394 struct ieee80211_channel *channel;
5395 struct wiphy *wiphy;
5396 struct brcmf_chanspec_list *list;
5397 struct brcmu_chan ch;
5405 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5410 list = (struct brcmf_chanspec_list *)pbuf;
5412 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5415 brcmf_err("get chanspecs error (%d)\n", err);
5419 wiphy = cfg_to_wiphy(cfg);
5420 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5422 for (i = 0; i < band->n_channels; i++)
5423 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5424 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5426 for (i = 0; i < band->n_channels; i++)
5427 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5429 total = le32_to_cpu(list->count);
5430 for (i = 0; i < total; i++) {
5431 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5432 cfg->d11inf.decchspec(&ch);
5434 if (ch.band == BRCMU_CHAN_BAND_2G) {
5435 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5436 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5437 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5439 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5444 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5445 ch.bw == BRCMU_CHAN_BW_40)
5447 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5448 ch.bw == BRCMU_CHAN_BW_80)
5451 channel = band->channels;
5452 index = band->n_channels;
5453 for (j = 0; j < band->n_channels; j++) {
5454 if (channel[j].hw_value == ch.chnum) {
5459 channel[index].center_freq =
5460 ieee80211_channel_to_frequency(ch.chnum, band->band);
5461 channel[index].hw_value = ch.chnum;
5463 /* assuming the chanspecs order is HT20,
5464 * HT40 upper, HT40 lower, and VHT80.
5466 if (ch.bw == BRCMU_CHAN_BW_80) {
5467 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5468 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5469 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5471 /* enable the channel and disable other bandwidths
5472 * for now as mentioned order assure they are enabled
5473 * for subsequent chanspecs.
5475 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5476 IEEE80211_CHAN_NO_80MHZ;
5477 ch.bw = BRCMU_CHAN_BW_20;
5478 cfg->d11inf.encchspec(&ch);
5479 chaninfo = ch.chspec;
5480 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5483 if (chaninfo & WL_CHAN_RADAR)
5484 channel[index].flags |=
5485 (IEEE80211_CHAN_RADAR |
5486 IEEE80211_CHAN_NO_IR);
5487 if (chaninfo & WL_CHAN_PASSIVE)
5488 channel[index].flags |=
5489 IEEE80211_CHAN_NO_IR;
5499 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5501 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5502 struct ieee80211_supported_band *band;
5503 struct brcmf_fil_bwcap_le band_bwcap;
5504 struct brcmf_chanspec_list *list;
5508 struct brcmu_chan ch;
5512 /* verify support for bw_cap command */
5514 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5517 /* only set 2G bandwidth using bw_cap command */
5518 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5519 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5520 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5521 sizeof(band_bwcap));
5523 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5524 val = WLC_N_BW_40ALL;
5525 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5529 /* update channel info in 2G band */
5530 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5535 ch.band = BRCMU_CHAN_BAND_2G;
5536 ch.bw = BRCMU_CHAN_BW_40;
5537 ch.sb = BRCMU_CHAN_SB_NONE;
5539 cfg->d11inf.encchspec(&ch);
5541 /* pass encoded chanspec in query */
5542 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5544 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5547 brcmf_err("get chanspecs error (%d)\n", err);
5552 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5553 list = (struct brcmf_chanspec_list *)pbuf;
5554 num_chan = le32_to_cpu(list->count);
5555 for (i = 0; i < num_chan; i++) {
5556 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5557 cfg->d11inf.decchspec(&ch);
5558 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5560 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5562 for (j = 0; j < band->n_channels; j++) {
5563 if (band->channels[j].hw_value == ch.chnum)
5566 if (WARN_ON(j == band->n_channels))
5569 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5576 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5578 u32 band, mimo_bwcap;
5582 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5584 bw_cap[IEEE80211_BAND_2GHZ] = band;
5586 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5588 bw_cap[IEEE80211_BAND_5GHZ] = band;
5594 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5596 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5598 /* assume 20MHz if firmware does not give a clue */
5599 mimo_bwcap = WLC_N_BW_20ALL;
5601 switch (mimo_bwcap) {
5602 case WLC_N_BW_40ALL:
5603 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5605 case WLC_N_BW_20IN2G_40IN5G:
5606 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5608 case WLC_N_BW_20ALL:
5609 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5610 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5613 brcmf_err("invalid mimo_bw_cap value\n");
5617 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5618 u32 bw_cap[2], u32 nchain)
5620 band->ht_cap.ht_supported = true;
5621 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5622 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5623 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5625 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5626 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5627 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5628 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5629 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5630 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5633 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5638 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5639 mcs_map = (mcs_map << 2) | supp;
5641 return cpu_to_le16(mcs_map);
5644 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5645 u32 bw_cap[2], u32 nchain)
5649 /* not allowed in 2.4G band */
5650 if (band->band == IEEE80211_BAND_2GHZ)
5653 band->vht_cap.vht_supported = true;
5654 /* 80MHz is mandatory */
5655 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5656 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5657 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5658 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5660 /* all support 256-QAM */
5661 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5662 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5663 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5666 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5668 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5669 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5672 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5677 struct ieee80211_supported_band *band;
5679 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5680 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5682 brcmf_err("nmode error (%d)\n", err);
5684 brcmf_get_bwcap(ifp, bw_cap);
5686 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5687 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5688 bw_cap[IEEE80211_BAND_5GHZ]);
5690 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5692 brcmf_err("rxchain error (%d)\n", err);
5695 for (nchain = 0; rxchain; nchain++)
5696 rxchain = rxchain & (rxchain - 1);
5698 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5700 err = brcmf_construct_chaninfo(cfg, bw_cap);
5702 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5706 wiphy = cfg_to_wiphy(cfg);
5707 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5708 band = wiphy->bands[i];
5713 brcmf_update_ht_cap(band, bw_cap, nchain);
5715 brcmf_update_vht_cap(band, bw_cap, nchain);
5721 static const struct ieee80211_txrx_stypes
5722 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5723 [NL80211_IFTYPE_STATION] = {
5725 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5726 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5728 [NL80211_IFTYPE_P2P_CLIENT] = {
5730 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5731 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5733 [NL80211_IFTYPE_P2P_GO] = {
5735 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5736 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5737 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5738 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5739 BIT(IEEE80211_STYPE_AUTH >> 4) |
5740 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5741 BIT(IEEE80211_STYPE_ACTION >> 4)
5743 [NL80211_IFTYPE_P2P_DEVICE] = {
5745 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5746 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5751 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5753 * @wiphy: wiphy object.
5754 * @ifp: interface object needed for feat module api.
5756 * The interface modes and combinations are determined dynamically here
5757 * based on firmware functionality.
5759 * no p2p and no mbss:
5761 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5765 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5766 * #AP <= 4, matching BI, channels = 1, 4 total
5768 * p2p, no mchan, and mbss:
5770 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
5771 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5772 * #AP <= 4, matching BI, channels = 1, 4 total
5774 * p2p, mchan, and mbss:
5776 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
5777 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5778 * #AP <= 4, matching BI, channels = 1, 4 total
5780 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5782 struct ieee80211_iface_combination *combo = NULL;
5783 struct ieee80211_iface_limit *c0_limits = NULL;
5784 struct ieee80211_iface_limit *p2p_limits = NULL;
5785 struct ieee80211_iface_limit *mbss_limits = NULL;
5789 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
5790 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
5792 n_combos = 1 + !!p2p + !!mbss;
5793 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
5797 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
5802 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
5808 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
5813 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5814 BIT(NL80211_IFTYPE_ADHOC) |
5815 BIT(NL80211_IFTYPE_AP);
5819 combo[c].num_different_channels = 1;
5820 c0_limits[i].max = 1;
5821 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5823 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5824 combo[c].num_different_channels = 2;
5825 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5826 BIT(NL80211_IFTYPE_P2P_GO) |
5827 BIT(NL80211_IFTYPE_P2P_DEVICE);
5828 c0_limits[i].max = 1;
5829 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5830 c0_limits[i].max = 1;
5831 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5832 BIT(NL80211_IFTYPE_P2P_GO);
5834 c0_limits[i].max = 1;
5835 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5837 combo[c].max_interfaces = i;
5838 combo[c].n_limits = i;
5839 combo[c].limits = c0_limits;
5844 combo[c].num_different_channels = 1;
5845 p2p_limits[i].max = 1;
5846 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5847 p2p_limits[i].max = 1;
5848 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5849 p2p_limits[i].max = 1;
5850 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
5851 p2p_limits[i].max = 1;
5852 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5853 combo[c].max_interfaces = i;
5854 combo[c].n_limits = i;
5855 combo[c].limits = p2p_limits;
5860 combo[c].beacon_int_infra_match = true;
5861 combo[c].num_different_channels = 1;
5862 mbss_limits[0].max = 4;
5863 mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
5864 combo[c].max_interfaces = 4;
5865 combo[c].n_limits = 1;
5866 combo[c].limits = mbss_limits;
5868 wiphy->n_iface_combinations = n_combos;
5869 wiphy->iface_combinations = combo;
5880 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5882 /* scheduled scan settings */
5883 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5884 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5885 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5886 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5890 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5891 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5892 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5893 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5894 .pattern_min_len = 1,
5895 .max_pkt_offset = 1500,
5899 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5903 wiphy->wowlan = &brcmf_wowlan_support;
5907 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5909 struct brcmf_pub *drvr = ifp->drvr;
5910 const struct ieee80211_iface_combination *combo;
5911 struct ieee80211_supported_band *band;
5912 u16 max_interfaces = 0;
5917 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5918 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5919 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5921 err = brcmf_setup_ifmodes(wiphy, ifp);
5925 for (i = 0, combo = wiphy->iface_combinations;
5926 i < wiphy->n_iface_combinations; i++, combo++) {
5927 max_interfaces = max(max_interfaces, combo->max_interfaces);
5930 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
5932 u8 *addr = drvr->addresses[i].addr;
5934 memcpy(addr, drvr->mac, ETH_ALEN);
5937 addr[ETH_ALEN - 1] ^= i;
5940 wiphy->addresses = drvr->addresses;
5941 wiphy->n_addresses = i;
5943 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5944 wiphy->cipher_suites = __wl_cipher_suites;
5945 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5946 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5947 WIPHY_FLAG_OFFCHAN_TX |
5948 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5949 WIPHY_FLAG_SUPPORTS_TDLS;
5951 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5952 wiphy->mgmt_stypes = brcmf_txrx_stypes;
5953 wiphy->max_remain_on_channel_duration = 5000;
5954 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
5955 brcmf_wiphy_pno_params(wiphy);
5957 /* vendor commands/events support */
5958 wiphy->vendor_commands = brcmf_vendor_cmds;
5959 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5961 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
5962 brcmf_wiphy_wowl_params(wiphy);
5964 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
5967 brcmf_err("could not obtain band info: err=%d\n", err);
5970 /* first entry in bandlist is number of bands */
5971 n_bands = le32_to_cpu(bandlist[0]);
5972 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
5973 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
5974 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5979 band->channels = kmemdup(&__wl_2ghz_channels,
5980 sizeof(__wl_2ghz_channels),
5982 if (!band->channels) {
5987 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
5988 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5990 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
5991 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
5996 band->channels = kmemdup(&__wl_5ghz_channels,
5997 sizeof(__wl_5ghz_channels),
5999 if (!band->channels) {
6004 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6005 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6008 err = brcmf_setup_wiphybands(wiphy);
6012 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6014 struct net_device *ndev;
6015 struct wireless_dev *wdev;
6016 struct brcmf_if *ifp;
6023 ndev = cfg_to_ndev(cfg);
6024 wdev = ndev->ieee80211_ptr;
6025 ifp = netdev_priv(ndev);
6027 /* make sure RF is ready for work */
6028 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6030 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
6031 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
6033 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6034 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6036 goto default_conf_out;
6037 brcmf_dbg(INFO, "power save set to %s\n",
6038 (power_mode ? "enabled" : "disabled"));
6040 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
6042 goto default_conf_out;
6043 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6046 goto default_conf_out;
6048 brcmf_configure_arp_offload(ifp, true);
6050 cfg->dongle_up = true;
6057 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6059 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6061 return brcmf_config_dongle(ifp->drvr->config);
6064 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6066 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6069 * While going down, if associated with AP disassociate
6070 * from AP to save power
6072 if (check_vif_up(ifp->vif)) {
6073 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6075 /* Make sure WPA_Supplicant receives all the event
6076 generated due to DISASSOC call to the fw to keep
6077 the state fw and WPA_Supplicant state consistent
6082 brcmf_abort_scanning(cfg);
6083 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6088 s32 brcmf_cfg80211_up(struct net_device *ndev)
6090 struct brcmf_if *ifp = netdev_priv(ndev);
6091 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6094 mutex_lock(&cfg->usr_sync);
6095 err = __brcmf_cfg80211_up(ifp);
6096 mutex_unlock(&cfg->usr_sync);
6101 s32 brcmf_cfg80211_down(struct net_device *ndev)
6103 struct brcmf_if *ifp = netdev_priv(ndev);
6104 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6107 mutex_lock(&cfg->usr_sync);
6108 err = __brcmf_cfg80211_down(ifp);
6109 mutex_unlock(&cfg->usr_sync);
6114 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6116 struct wireless_dev *wdev = &ifp->vif->wdev;
6118 return wdev->iftype;
6121 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6122 unsigned long state)
6124 struct brcmf_cfg80211_vif *vif;
6126 list_for_each_entry(vif, &cfg->vif_list, list) {
6127 if (test_bit(state, &vif->sme_state))
6133 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6138 mutex_lock(&event->vif_event_lock);
6139 evt_action = event->action;
6140 mutex_unlock(&event->vif_event_lock);
6141 return evt_action == action;
6144 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6145 struct brcmf_cfg80211_vif *vif)
6147 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6149 mutex_lock(&event->vif_event_lock);
6152 mutex_unlock(&event->vif_event_lock);
6155 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6157 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6160 mutex_lock(&event->vif_event_lock);
6161 armed = event->vif != NULL;
6162 mutex_unlock(&event->vif_event_lock);
6166 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6167 u8 action, ulong timeout)
6169 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6171 return wait_event_timeout(event->vif_wq,
6172 vif_event_equals(event, action), timeout);
6175 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6176 struct regulatory_request *req)
6178 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6179 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6180 struct brcmf_fil_country_le ccreq;
6183 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6184 req->alpha2[0], req->alpha2[1]);
6186 /* ignore non-ISO3166 country codes */
6187 for (i = 0; i < 2; i++)
6188 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6189 brcmf_err("not a ISO3166 code\n");
6192 memset(&ccreq, 0, sizeof(ccreq));
6193 ccreq.rev = cpu_to_le32(-1);
6194 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6195 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6196 brcmf_err("firmware rejected country setting\n");
6199 brcmf_setup_wiphybands(wiphy);
6202 static void brcmf_free_wiphy(struct wiphy *wiphy)
6209 if (wiphy->iface_combinations) {
6210 for (i = 0; i < wiphy->n_iface_combinations; i++)
6211 kfree(wiphy->iface_combinations[i].limits);
6213 kfree(wiphy->iface_combinations);
6214 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6215 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6216 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6218 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6219 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6220 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6225 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6226 struct device *busdev,
6229 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6230 struct brcmf_cfg80211_info *cfg;
6231 struct wiphy *wiphy;
6232 struct brcmf_cfg80211_vif *vif;
6233 struct brcmf_if *ifp;
6239 brcmf_err("ndev is invalid\n");
6243 ifp = netdev_priv(ndev);
6244 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6246 brcmf_err("Could not allocate wiphy device\n");
6249 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6250 set_wiphy_dev(wiphy, busdev);
6252 cfg = wiphy_priv(wiphy);
6255 init_vif_event(&cfg->vif_event);
6256 INIT_LIST_HEAD(&cfg->vif_list);
6258 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6263 vif->wdev.netdev = ndev;
6264 ndev->ieee80211_ptr = &vif->wdev;
6265 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6267 err = wl_init_priv(cfg);
6269 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6270 brcmf_free_vif(vif);
6275 /* determine d11 io type before wiphy setup */
6276 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6278 brcmf_err("Failed to get D11 version (%d)\n", err);
6281 cfg->d11inf.io_type = (u8)io_type;
6282 brcmu_d11_attach(&cfg->d11inf);
6284 err = brcmf_setup_wiphy(wiphy, ifp);
6288 brcmf_dbg(INFO, "Registering custom regulatory\n");
6289 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6290 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6291 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6293 /* firmware defaults to 40MHz disabled in 2G band. We signal
6294 * cfg80211 here that we do and have it decide we can enable
6295 * it. But first check if device does support 2G operation.
6297 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6298 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6299 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6301 err = wiphy_register(wiphy);
6303 brcmf_err("Could not register wiphy device (%d)\n", err);
6307 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6308 * setup 40MHz in 2GHz band and enable OBSS scanning.
6310 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6311 err = brcmf_enable_bw40_2g(cfg);
6313 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6314 BRCMF_OBSS_COEX_AUTO);
6316 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6318 /* p2p might require that "if-events" get processed by fweh. So
6319 * activate the already registered event handlers now and activate
6320 * the rest when initialization has completed. drvr->config needs to
6321 * be assigned before activating events.
6324 err = brcmf_fweh_activate_events(ifp);
6326 brcmf_err("FWEH activation failed (%d)\n", err);
6327 goto wiphy_unreg_out;
6330 err = brcmf_p2p_attach(cfg, p2pdev_forced);
6332 brcmf_err("P2P initilisation failed (%d)\n", err);
6333 goto wiphy_unreg_out;
6335 err = brcmf_btcoex_attach(cfg);
6337 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6338 brcmf_p2p_detach(&cfg->p2p);
6339 goto wiphy_unreg_out;
6342 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6344 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6345 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6347 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6348 brcmf_notify_tdls_peer_event);
6351 /* (re-) activate FWEH event handling */
6352 err = brcmf_fweh_activate_events(ifp);
6354 brcmf_err("FWEH activation failed (%d)\n", err);
6355 goto wiphy_unreg_out;
6361 wiphy_unregister(cfg->wiphy);
6363 wl_deinit_priv(cfg);
6364 brcmf_free_vif(vif);
6367 brcmf_free_wiphy(wiphy);
6371 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6376 brcmf_btcoex_detach(cfg);
6377 wiphy_unregister(cfg->wiphy);
6378 wl_deinit_priv(cfg);
6379 brcmf_free_wiphy(cfg->wiphy);