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_SCAN_CHANNEL_TIME 40
95 #define BRCMF_SCAN_UNASSOC_TIME 40
96 #define BRCMF_SCAN_PASSIVE_TIME 120
98 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
100 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
101 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
103 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
105 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
106 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
113 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
114 #define RATETAB_ENT(_rateid, _flags) \
116 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
117 .hw_value = (_rateid), \
121 static struct ieee80211_rate __wl_rates[] = {
122 RATETAB_ENT(BRCM_RATE_1M, 0),
123 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
124 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
125 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
126 RATETAB_ENT(BRCM_RATE_6M, 0),
127 RATETAB_ENT(BRCM_RATE_9M, 0),
128 RATETAB_ENT(BRCM_RATE_12M, 0),
129 RATETAB_ENT(BRCM_RATE_18M, 0),
130 RATETAB_ENT(BRCM_RATE_24M, 0),
131 RATETAB_ENT(BRCM_RATE_36M, 0),
132 RATETAB_ENT(BRCM_RATE_48M, 0),
133 RATETAB_ENT(BRCM_RATE_54M, 0),
136 #define wl_g_rates (__wl_rates + 0)
137 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
138 #define wl_a_rates (__wl_rates + 4)
139 #define wl_a_rates_size (wl_g_rates_size - 4)
141 #define CHAN2G(_channel, _freq) { \
142 .band = IEEE80211_BAND_2GHZ, \
143 .center_freq = (_freq), \
144 .hw_value = (_channel), \
145 .flags = IEEE80211_CHAN_DISABLED, \
146 .max_antenna_gain = 0, \
150 #define CHAN5G(_channel) { \
151 .band = IEEE80211_BAND_5GHZ, \
152 .center_freq = 5000 + (5 * (_channel)), \
153 .hw_value = (_channel), \
154 .flags = IEEE80211_CHAN_DISABLED, \
155 .max_antenna_gain = 0, \
159 static struct ieee80211_channel __wl_2ghz_channels[] = {
160 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
161 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
162 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
163 CHAN2G(13, 2472), CHAN2G(14, 2484)
166 static struct ieee80211_channel __wl_5ghz_channels[] = {
167 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
168 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
169 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
170 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
171 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
172 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
175 /* Band templates duplicated per wiphy. The channel info
176 * above is added to the band during setup.
178 static const struct ieee80211_supported_band __wl_band_2ghz = {
179 .band = IEEE80211_BAND_2GHZ,
180 .bitrates = wl_g_rates,
181 .n_bitrates = wl_g_rates_size,
184 static const struct ieee80211_supported_band __wl_band_5ghz = {
185 .band = IEEE80211_BAND_5GHZ,
186 .bitrates = wl_a_rates,
187 .n_bitrates = wl_a_rates_size,
190 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
191 * By default world regulatory domain defined in reg.c puts the flags
192 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
193 * With respect to these flags, wpa_supplicant doesn't * start p2p
194 * operations on 5GHz channels. All the changes in world regulatory
195 * domain are to be done here.
197 static const struct ieee80211_regdomain brcmf_regdom = {
201 /* IEEE 802.11b/g, channels 1..11 */
202 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
204 /* IEEE 802.11 channel 14 - Only JP enables
205 * this and for 802.11b only
207 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
208 /* IEEE 802.11a, channel 36..64 */
209 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
210 /* IEEE 802.11a, channel 100..165 */
211 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
214 static const u32 __wl_cipher_suites[] = {
215 WLAN_CIPHER_SUITE_WEP40,
216 WLAN_CIPHER_SUITE_WEP104,
217 WLAN_CIPHER_SUITE_TKIP,
218 WLAN_CIPHER_SUITE_CCMP,
219 WLAN_CIPHER_SUITE_AES_CMAC,
222 /* Vendor specific ie. id = 221, oui and type defines exact ie */
223 struct brcmf_vs_tlv {
230 struct parsed_vndr_ie_info {
232 u32 ie_len; /* total length including id & length field */
233 struct brcmf_vs_tlv vndrie;
236 struct parsed_vndr_ies {
238 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
241 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
242 struct cfg80211_chan_def *ch)
244 struct brcmu_chan ch_inf;
247 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
248 ch->chan->center_freq, ch->center_freq1, ch->width);
249 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
250 primary_offset = ch->center_freq1 - ch->chan->center_freq;
252 case NL80211_CHAN_WIDTH_20:
253 case NL80211_CHAN_WIDTH_20_NOHT:
254 ch_inf.bw = BRCMU_CHAN_BW_20;
255 WARN_ON(primary_offset != 0);
257 case NL80211_CHAN_WIDTH_40:
258 ch_inf.bw = BRCMU_CHAN_BW_40;
259 if (primary_offset < 0)
260 ch_inf.sb = BRCMU_CHAN_SB_U;
262 ch_inf.sb = BRCMU_CHAN_SB_L;
264 case NL80211_CHAN_WIDTH_80:
265 ch_inf.bw = BRCMU_CHAN_BW_80;
266 if (primary_offset < 0) {
267 if (primary_offset < -CH_10MHZ_APART)
268 ch_inf.sb = BRCMU_CHAN_SB_UU;
270 ch_inf.sb = BRCMU_CHAN_SB_UL;
272 if (primary_offset > CH_10MHZ_APART)
273 ch_inf.sb = BRCMU_CHAN_SB_LL;
275 ch_inf.sb = BRCMU_CHAN_SB_LU;
278 case NL80211_CHAN_WIDTH_80P80:
279 case NL80211_CHAN_WIDTH_160:
280 case NL80211_CHAN_WIDTH_5:
281 case NL80211_CHAN_WIDTH_10:
285 switch (ch->chan->band) {
286 case IEEE80211_BAND_2GHZ:
287 ch_inf.band = BRCMU_CHAN_BAND_2G;
289 case IEEE80211_BAND_5GHZ:
290 ch_inf.band = BRCMU_CHAN_BAND_5G;
292 case IEEE80211_BAND_60GHZ:
296 d11inf->encchspec(&ch_inf);
298 return ch_inf.chspec;
301 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
302 struct ieee80211_channel *ch)
304 struct brcmu_chan ch_inf;
306 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
307 ch_inf.bw = BRCMU_CHAN_BW_20;
308 d11inf->encchspec(&ch_inf);
310 return ch_inf.chspec;
313 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
314 * triples, returning a pointer to the substring whose first element
317 const struct brcmf_tlv *
318 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
320 const struct brcmf_tlv *elt = buf;
323 /* find tagged parameter */
324 while (totlen >= TLV_HDR_LEN) {
327 /* validate remaining totlen */
328 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
331 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
332 totlen -= (len + TLV_HDR_LEN);
338 /* Is any of the tlvs the expected entry? If
339 * not update the tlvs buffer pointer/length.
342 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
343 const u8 *oui, u32 oui_len, u8 type)
345 /* If the contents match the OUI and the type */
346 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
347 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
348 type == ie[TLV_BODY_OFF + oui_len]) {
354 /* point to the next ie */
355 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
356 /* calculate the length of the rest of the buffer */
357 *tlvs_len -= (int)(ie - *tlvs);
358 /* update the pointer to the start of the buffer */
364 static struct brcmf_vs_tlv *
365 brcmf_find_wpaie(const u8 *parse, u32 len)
367 const struct brcmf_tlv *ie;
369 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
370 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
371 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
372 return (struct brcmf_vs_tlv *)ie;
377 static struct brcmf_vs_tlv *
378 brcmf_find_wpsie(const u8 *parse, u32 len)
380 const struct brcmf_tlv *ie;
382 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
383 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
384 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
385 return (struct brcmf_vs_tlv *)ie;
390 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
391 struct brcmf_cfg80211_vif *vif,
392 enum nl80211_iftype new_type)
394 int iftype_num[NUM_NL80211_IFTYPES];
395 struct brcmf_cfg80211_vif *pos;
396 bool check_combos = false;
399 memset(&iftype_num[0], 0, sizeof(iftype_num));
400 list_for_each_entry(pos, &cfg->vif_list, list)
402 iftype_num[new_type]++;
404 /* concurrent interfaces so need check combinations */
406 iftype_num[pos->wdev.iftype]++;
410 ret = cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
415 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
416 enum nl80211_iftype new_type)
418 int iftype_num[NUM_NL80211_IFTYPES];
419 struct brcmf_cfg80211_vif *pos;
421 memset(&iftype_num[0], 0, sizeof(iftype_num));
422 list_for_each_entry(pos, &cfg->vif_list, list)
423 iftype_num[pos->wdev.iftype]++;
425 iftype_num[new_type]++;
426 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
429 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
430 struct brcmf_wsec_key_le *key_le)
432 key_le->index = cpu_to_le32(key->index);
433 key_le->len = cpu_to_le32(key->len);
434 key_le->algo = cpu_to_le32(key->algo);
435 key_le->flags = cpu_to_le32(key->flags);
436 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
437 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
438 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
439 memcpy(key_le->data, key->data, sizeof(key->data));
440 memcpy(key_le->ea, key->ea, sizeof(key->ea));
444 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
447 struct brcmf_wsec_key_le key_le;
449 convert_key_from_CPU(key, &key_le);
451 brcmf_netdev_wait_pend8021x(ifp);
453 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
457 brcmf_err("wsec_key error (%d)\n", err);
462 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
468 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
472 /* Try to set and enable ARP offload feature, this may fail, then it */
473 /* is simply not supported and err 0 will be returned */
474 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
476 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
480 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
482 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
486 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
494 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
496 struct brcmf_cfg80211_vif *vif;
497 struct brcmf_if *ifp;
499 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
502 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
503 (wdev->iftype == NL80211_IFTYPE_AP) ||
504 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
505 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
508 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
512 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
514 struct brcmf_mbss_ssid_le mbss_ssid_le;
518 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
519 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
523 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
524 mbss_ssid_le.SSID_len = cpu_to_le32(5);
525 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
527 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
528 sizeof(mbss_ssid_le));
530 brcmf_err("setting ssid failed %d\n", err);
536 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
538 * @wiphy: wiphy device of new interface.
539 * @name: name of the new interface.
541 * @params: contains mac address for AP device.
544 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
545 u32 *flags, struct vif_params *params)
547 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
548 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
549 struct brcmf_cfg80211_vif *vif;
552 if (brcmf_cfg80211_vif_event_armed(cfg))
553 return ERR_PTR(-EBUSY);
555 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
557 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
559 return (struct wireless_dev *)vif;
561 brcmf_cfg80211_arm_vif_event(cfg, vif);
563 err = brcmf_cfg80211_request_ap_if(ifp);
565 brcmf_cfg80211_arm_vif_event(cfg, NULL);
569 /* wait for firmware event */
570 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
571 BRCMF_VIF_EVENT_TIMEOUT);
572 brcmf_cfg80211_arm_vif_event(cfg, NULL);
574 brcmf_err("timeout occurred\n");
579 /* interface created in firmware */
582 brcmf_err("no if pointer provided\n");
587 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
588 err = brcmf_net_attach(ifp, true);
590 brcmf_err("Registering netdevice failed\n");
594 return &ifp->vif->wdev;
601 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
603 enum nl80211_iftype iftype;
605 iftype = vif->wdev.iftype;
606 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
609 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
611 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
614 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
616 unsigned char name_assign_type,
617 enum nl80211_iftype type,
619 struct vif_params *params)
621 struct wireless_dev *wdev;
624 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
625 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
627 brcmf_err("iface validation failed: err=%d\n", err);
631 case NL80211_IFTYPE_ADHOC:
632 case NL80211_IFTYPE_STATION:
633 case NL80211_IFTYPE_AP_VLAN:
634 case NL80211_IFTYPE_WDS:
635 case NL80211_IFTYPE_MONITOR:
636 case NL80211_IFTYPE_MESH_POINT:
637 return ERR_PTR(-EOPNOTSUPP);
638 case NL80211_IFTYPE_AP:
639 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
641 brcmf_cfg80211_update_proto_addr_mode(wdev);
643 case NL80211_IFTYPE_P2P_CLIENT:
644 case NL80211_IFTYPE_P2P_GO:
645 case NL80211_IFTYPE_P2P_DEVICE:
646 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
648 brcmf_cfg80211_update_proto_addr_mode(wdev);
650 case NL80211_IFTYPE_UNSPECIFIED:
652 return ERR_PTR(-EINVAL);
656 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
658 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
659 brcmf_set_mpc(ifp, mpc);
662 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
666 if (check_vif_up(ifp->vif)) {
667 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
669 brcmf_err("fail to set mpc\n");
672 brcmf_dbg(INFO, "MPC : %d\n", mpc);
676 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
677 struct brcmf_if *ifp, bool aborted,
680 struct brcmf_scan_params_le params_le;
681 struct cfg80211_scan_request *scan_request;
684 brcmf_dbg(SCAN, "Enter\n");
686 /* clear scan request, because the FW abort can cause a second call */
687 /* to this functon and might cause a double cfg80211_scan_done */
688 scan_request = cfg->scan_request;
689 cfg->scan_request = NULL;
691 if (timer_pending(&cfg->escan_timeout))
692 del_timer_sync(&cfg->escan_timeout);
695 /* Do a scan abort to stop the driver's scan engine */
696 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
697 memset(¶ms_le, 0, sizeof(params_le));
698 eth_broadcast_addr(params_le.bssid);
699 params_le.bss_type = DOT11_BSSTYPE_ANY;
700 params_le.scan_type = 0;
701 params_le.channel_num = cpu_to_le32(1);
702 params_le.nprobes = cpu_to_le32(1);
703 params_le.active_time = cpu_to_le32(-1);
704 params_le.passive_time = cpu_to_le32(-1);
705 params_le.home_time = cpu_to_le32(-1);
706 /* Scan is aborted by setting channel_list[0] to -1 */
707 params_le.channel_list[0] = cpu_to_le16(-1);
708 /* E-Scan (or anyother type) can be aborted by SCAN */
709 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
710 ¶ms_le, sizeof(params_le));
712 brcmf_err("Scan abort failed\n");
715 brcmf_scan_config_mpc(ifp, 1);
718 * e-scan can be initiated by scheduled scan
719 * which takes precedence.
721 if (cfg->sched_escan) {
722 brcmf_dbg(SCAN, "scheduled scan completed\n");
723 cfg->sched_escan = false;
725 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
726 } else if (scan_request) {
727 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
728 aborted ? "Aborted" : "Done");
729 cfg80211_scan_done(scan_request, aborted);
731 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
732 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
738 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
740 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
741 struct net_device *ndev = wdev->netdev;
743 /* vif event pending in firmware */
744 if (brcmf_cfg80211_vif_event_armed(cfg))
748 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
749 cfg->escan_info.ifp == netdev_priv(ndev))
750 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
753 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
756 switch (wdev->iftype) {
757 case NL80211_IFTYPE_ADHOC:
758 case NL80211_IFTYPE_STATION:
759 case NL80211_IFTYPE_AP:
760 case NL80211_IFTYPE_AP_VLAN:
761 case NL80211_IFTYPE_WDS:
762 case NL80211_IFTYPE_MONITOR:
763 case NL80211_IFTYPE_MESH_POINT:
765 case NL80211_IFTYPE_P2P_CLIENT:
766 case NL80211_IFTYPE_P2P_GO:
767 case NL80211_IFTYPE_P2P_DEVICE:
768 return brcmf_p2p_del_vif(wiphy, wdev);
769 case NL80211_IFTYPE_UNSPECIFIED:
777 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
778 enum nl80211_iftype type, u32 *flags,
779 struct vif_params *params)
781 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
782 struct brcmf_if *ifp = netdev_priv(ndev);
783 struct brcmf_cfg80211_vif *vif = ifp->vif;
788 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
791 /* WAR: There are a number of p2p interface related problems which
792 * need to be handled initially (before doing the validate).
793 * wpa_supplicant tends to do iface changes on p2p device/client/go
794 * which are not always possible/allowed. However we need to return
795 * OK otherwise the wpa_supplicant wont start. The situation differs
796 * on configuration and setup (p2pon=1 module param). The first check
797 * is to see if the request is a change to station for p2p iface.
799 if ((type == NL80211_IFTYPE_STATION) &&
800 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
801 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
802 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
803 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
804 /* Now depending on whether module param p2pon=1 was used the
805 * response needs to be either 0 or EOPNOTSUPP. The reason is
806 * that if p2pon=1 is used, but a newer supplicant is used then
807 * we should return an error, as this combination wont work.
808 * In other situations 0 is returned and supplicant will start
809 * normally. It will give a trace in cfg80211, but it is the
810 * only way to get it working. Unfortunately this will result
811 * in situation where we wont support new supplicant in
812 * combination with module param p2pon=1, but that is the way
813 * it is. If the user tries this then unloading of driver might
816 if (cfg->p2p.p2pdev_dynamically)
821 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
823 brcmf_err("iface validation failed: err=%d\n", err);
827 case NL80211_IFTYPE_MONITOR:
828 case NL80211_IFTYPE_WDS:
829 brcmf_err("type (%d) : currently we do not support this type\n",
832 case NL80211_IFTYPE_ADHOC:
835 case NL80211_IFTYPE_STATION:
838 case NL80211_IFTYPE_AP:
839 case NL80211_IFTYPE_P2P_GO:
848 if (type == NL80211_IFTYPE_P2P_GO) {
849 brcmf_dbg(INFO, "IF Type = P2P GO\n");
850 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
853 brcmf_dbg(INFO, "IF Type = AP\n");
856 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
858 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
862 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
865 ndev->ieee80211_ptr->iftype = type;
867 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
870 brcmf_dbg(TRACE, "Exit\n");
875 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
876 struct brcmf_scan_params_le *params_le,
877 struct cfg80211_scan_request *request)
885 struct brcmf_ssid_le ssid_le;
887 eth_broadcast_addr(params_le->bssid);
888 params_le->bss_type = DOT11_BSSTYPE_ANY;
889 params_le->scan_type = 0;
890 params_le->channel_num = 0;
891 params_le->nprobes = cpu_to_le32(-1);
892 params_le->active_time = cpu_to_le32(-1);
893 params_le->passive_time = cpu_to_le32(-1);
894 params_le->home_time = cpu_to_le32(-1);
895 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
897 /* if request is null exit so it will be all channel broadcast scan */
901 n_ssids = request->n_ssids;
902 n_channels = request->n_channels;
903 /* Copy channel array if applicable */
904 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
906 if (n_channels > 0) {
907 for (i = 0; i < n_channels; i++) {
908 chanspec = channel_to_chanspec(&cfg->d11inf,
909 request->channels[i]);
910 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
911 request->channels[i]->hw_value, chanspec);
912 params_le->channel_list[i] = cpu_to_le16(chanspec);
915 brcmf_dbg(SCAN, "Scanning all channels\n");
917 /* Copy ssid array if applicable */
918 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
920 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
921 n_channels * sizeof(u16);
922 offset = roundup(offset, sizeof(u32));
923 ptr = (char *)params_le + offset;
924 for (i = 0; i < n_ssids; i++) {
925 memset(&ssid_le, 0, sizeof(ssid_le));
927 cpu_to_le32(request->ssids[i].ssid_len);
928 memcpy(ssid_le.SSID, request->ssids[i].ssid,
929 request->ssids[i].ssid_len);
930 if (!ssid_le.SSID_len)
931 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
933 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
934 i, ssid_le.SSID, ssid_le.SSID_len);
935 memcpy(ptr, &ssid_le, sizeof(ssid_le));
936 ptr += sizeof(ssid_le);
939 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
940 if ((request->ssids) && request->ssids->ssid_len) {
941 brcmf_dbg(SCAN, "SSID %s len=%d\n",
942 params_le->ssid_le.SSID,
943 request->ssids->ssid_len);
944 params_le->ssid_le.SSID_len =
945 cpu_to_le32(request->ssids->ssid_len);
946 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
947 request->ssids->ssid_len);
950 /* Adding mask to channel numbers */
951 params_le->channel_num =
952 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
953 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
957 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
958 struct cfg80211_scan_request *request)
960 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
961 offsetof(struct brcmf_escan_params_le, params_le);
962 struct brcmf_escan_params_le *params;
965 brcmf_dbg(SCAN, "E-SCAN START\n");
967 if (request != NULL) {
968 /* Allocate space for populating ssids in struct */
969 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
971 /* Allocate space for populating ssids in struct */
972 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
975 params = kzalloc(params_size, GFP_KERNEL);
980 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
981 brcmf_escan_prep(cfg, ¶ms->params_le, request);
982 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
983 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
984 params->sync_id = cpu_to_le16(0x1234);
986 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
989 brcmf_dbg(INFO, "system busy : escan canceled\n");
991 brcmf_err("error (%d)\n", err);
1000 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1001 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1005 struct brcmf_scan_results *results;
1006 struct escan_info *escan = &cfg->escan_info;
1008 brcmf_dbg(SCAN, "Enter\n");
1010 escan->wiphy = wiphy;
1011 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1012 passive_scan = cfg->active_scan ? 0 : 1;
1013 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1016 brcmf_err("error (%d)\n", err);
1019 brcmf_scan_config_mpc(ifp, 0);
1020 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1021 results->version = 0;
1023 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1025 err = escan->run(cfg, ifp, request);
1027 brcmf_scan_config_mpc(ifp, 1);
1032 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1033 struct cfg80211_scan_request *request,
1034 struct cfg80211_ssid *this_ssid)
1036 struct brcmf_if *ifp = vif->ifp;
1037 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1038 struct cfg80211_ssid *ssids;
1043 struct brcmf_ssid_le ssid_le;
1046 brcmf_dbg(SCAN, "START ESCAN\n");
1048 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1049 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1052 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1053 brcmf_err("Scanning being aborted: status (%lu)\n",
1057 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1058 brcmf_err("Scanning suppressed: status (%lu)\n",
1062 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1063 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1067 /* If scan req comes for p2p0, send it over primary I/F */
1068 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1069 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1074 ssids = request->ssids;
1078 /* we don't do escan in ibss */
1082 cfg->scan_request = request;
1083 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1085 cfg->escan_info.run = brcmf_run_escan;
1086 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1090 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1094 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1095 ssids->ssid, ssids->ssid_len);
1096 memset(&ssid_le, 0, sizeof(ssid_le));
1097 SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len);
1098 ssid_le.SSID_len = cpu_to_le32(0);
1101 memcpy(ssid_le.SSID, ssids->ssid, SSID_len);
1102 ssid_le.SSID_len = cpu_to_le32(SSID_len);
1105 brcmf_dbg(SCAN, "Broadcast scan\n");
1107 passive_scan = cfg->active_scan ? 0 : 1;
1108 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1111 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1114 brcmf_scan_config_mpc(ifp, 0);
1115 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le,
1119 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1122 brcmf_err("WLC_SCAN error (%d)\n", err);
1124 brcmf_scan_config_mpc(ifp, 1);
1129 /* Arm scan timeout timer */
1130 mod_timer(&cfg->escan_timeout, jiffies +
1131 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1136 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1137 cfg->scan_request = NULL;
1142 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1144 struct brcmf_cfg80211_vif *vif;
1147 brcmf_dbg(TRACE, "Enter\n");
1148 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1149 if (!check_vif_up(vif))
1152 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1155 brcmf_err("scan error (%d)\n", err);
1157 brcmf_dbg(TRACE, "Exit\n");
1161 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1165 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1168 brcmf_err("Error (%d)\n", err);
1173 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1177 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1180 brcmf_err("Error (%d)\n", err);
1185 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1188 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1190 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1192 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1198 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1200 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1201 struct net_device *ndev = cfg_to_ndev(cfg);
1202 struct brcmf_if *ifp = netdev_priv(ndev);
1205 brcmf_dbg(TRACE, "Enter\n");
1206 if (!check_vif_up(ifp->vif))
1209 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1210 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1211 cfg->conf->rts_threshold = wiphy->rts_threshold;
1212 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1216 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1217 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1218 cfg->conf->frag_threshold = wiphy->frag_threshold;
1219 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1223 if (changed & WIPHY_PARAM_RETRY_LONG
1224 && (cfg->conf->retry_long != wiphy->retry_long)) {
1225 cfg->conf->retry_long = wiphy->retry_long;
1226 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1230 if (changed & WIPHY_PARAM_RETRY_SHORT
1231 && (cfg->conf->retry_short != wiphy->retry_short)) {
1232 cfg->conf->retry_short = wiphy->retry_short;
1233 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1239 brcmf_dbg(TRACE, "Exit\n");
1243 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1245 memset(prof, 0, sizeof(*prof));
1248 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1252 switch (e->event_code) {
1253 case BRCMF_E_DEAUTH:
1254 case BRCMF_E_DEAUTH_IND:
1255 case BRCMF_E_DISASSOC_IND:
1266 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1268 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1271 brcmf_dbg(TRACE, "Enter\n");
1273 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1274 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1275 err = brcmf_fil_cmd_data_set(vif->ifp,
1276 BRCMF_C_DISASSOC, NULL, 0);
1278 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1280 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1281 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1282 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1285 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1286 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1287 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1288 brcmf_dbg(TRACE, "Exit\n");
1292 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1293 struct cfg80211_ibss_params *params)
1295 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1296 struct brcmf_if *ifp = netdev_priv(ndev);
1297 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1298 struct brcmf_join_params join_params;
1299 size_t join_params_size = 0;
1306 brcmf_dbg(TRACE, "Enter\n");
1307 if (!check_vif_up(ifp->vif))
1311 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1313 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1317 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1320 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1322 brcmf_dbg(CONN, "No BSSID specified\n");
1324 if (params->chandef.chan)
1325 brcmf_dbg(CONN, "channel: %d\n",
1326 params->chandef.chan->center_freq);
1328 brcmf_dbg(CONN, "no channel specified\n");
1330 if (params->channel_fixed)
1331 brcmf_dbg(CONN, "fixed channel required\n");
1333 brcmf_dbg(CONN, "no fixed channel required\n");
1335 if (params->ie && params->ie_len)
1336 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1338 brcmf_dbg(CONN, "no ie specified\n");
1340 if (params->beacon_interval)
1341 brcmf_dbg(CONN, "beacon interval: %d\n",
1342 params->beacon_interval);
1344 brcmf_dbg(CONN, "no beacon interval specified\n");
1346 if (params->basic_rates)
1347 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1349 brcmf_dbg(CONN, "no basic rates specified\n");
1351 if (params->privacy)
1352 brcmf_dbg(CONN, "privacy required\n");
1354 brcmf_dbg(CONN, "no privacy required\n");
1356 /* Configure Privacy for starter */
1357 if (params->privacy)
1358 wsec |= WEP_ENABLED;
1360 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1362 brcmf_err("wsec failed (%d)\n", err);
1366 /* Configure Beacon Interval for starter */
1367 if (params->beacon_interval)
1368 bcnprd = params->beacon_interval;
1372 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1374 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1378 /* Configure required join parameter */
1379 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1382 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1383 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1384 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1385 join_params_size = sizeof(join_params.ssid_le);
1388 if (params->bssid) {
1389 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1390 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1391 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1393 eth_broadcast_addr(join_params.params_le.bssid);
1394 eth_zero_addr(profile->bssid);
1398 if (params->chandef.chan) {
1402 ieee80211_frequency_to_channel(
1403 params->chandef.chan->center_freq);
1404 if (params->channel_fixed) {
1405 /* adding chanspec */
1406 chanspec = chandef_to_chanspec(&cfg->d11inf,
1408 join_params.params_le.chanspec_list[0] =
1409 cpu_to_le16(chanspec);
1410 join_params.params_le.chanspec_num = cpu_to_le32(1);
1411 join_params_size += sizeof(join_params.params_le);
1414 /* set channel for starter */
1415 target_channel = cfg->channel;
1416 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1419 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1425 cfg->ibss_starter = false;
1428 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1429 &join_params, join_params_size);
1431 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1437 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1438 brcmf_dbg(TRACE, "Exit\n");
1443 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1445 struct brcmf_if *ifp = netdev_priv(ndev);
1447 brcmf_dbg(TRACE, "Enter\n");
1448 if (!check_vif_up(ifp->vif)) {
1449 /* When driver is being unloaded, it can end up here. If an
1450 * error is returned then later on a debug trace in the wireless
1451 * core module will be printed. To avoid this 0 is returned.
1456 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1457 brcmf_net_setcarrier(ifp, false);
1459 brcmf_dbg(TRACE, "Exit\n");
1464 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1465 struct cfg80211_connect_params *sme)
1467 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1468 struct brcmf_cfg80211_security *sec;
1472 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1473 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1474 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1475 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1477 val = WPA_AUTH_DISABLED;
1478 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1479 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1481 brcmf_err("set wpa_auth failed (%d)\n", err);
1484 sec = &profile->sec;
1485 sec->wpa_versions = sme->crypto.wpa_versions;
1489 static s32 brcmf_set_auth_type(struct net_device *ndev,
1490 struct cfg80211_connect_params *sme)
1492 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1493 struct brcmf_cfg80211_security *sec;
1497 switch (sme->auth_type) {
1498 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1500 brcmf_dbg(CONN, "open system\n");
1502 case NL80211_AUTHTYPE_SHARED_KEY:
1504 brcmf_dbg(CONN, "shared key\n");
1506 case NL80211_AUTHTYPE_AUTOMATIC:
1508 brcmf_dbg(CONN, "automatic\n");
1510 case NL80211_AUTHTYPE_NETWORK_EAP:
1511 brcmf_dbg(CONN, "network eap\n");
1514 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1518 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1520 brcmf_err("set auth failed (%d)\n", err);
1523 sec = &profile->sec;
1524 sec->auth_type = sme->auth_type;
1529 brcmf_set_wsec_mode(struct net_device *ndev,
1530 struct cfg80211_connect_params *sme, bool mfp)
1532 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1533 struct brcmf_cfg80211_security *sec;
1539 if (sme->crypto.n_ciphers_pairwise) {
1540 switch (sme->crypto.ciphers_pairwise[0]) {
1541 case WLAN_CIPHER_SUITE_WEP40:
1542 case WLAN_CIPHER_SUITE_WEP104:
1545 case WLAN_CIPHER_SUITE_TKIP:
1546 pval = TKIP_ENABLED;
1548 case WLAN_CIPHER_SUITE_CCMP:
1551 case WLAN_CIPHER_SUITE_AES_CMAC:
1555 brcmf_err("invalid cipher pairwise (%d)\n",
1556 sme->crypto.ciphers_pairwise[0]);
1560 if (sme->crypto.cipher_group) {
1561 switch (sme->crypto.cipher_group) {
1562 case WLAN_CIPHER_SUITE_WEP40:
1563 case WLAN_CIPHER_SUITE_WEP104:
1566 case WLAN_CIPHER_SUITE_TKIP:
1567 gval = TKIP_ENABLED;
1569 case WLAN_CIPHER_SUITE_CCMP:
1572 case WLAN_CIPHER_SUITE_AES_CMAC:
1576 brcmf_err("invalid cipher group (%d)\n",
1577 sme->crypto.cipher_group);
1582 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1583 /* In case of privacy, but no security and WPS then simulate */
1584 /* setting AES. WPS-2.0 allows no security */
1585 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1590 wsec = pval | gval | MFP_CAPABLE;
1593 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1595 brcmf_err("error (%d)\n", err);
1599 sec = &profile->sec;
1600 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1601 sec->cipher_group = sme->crypto.cipher_group;
1607 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1609 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1610 struct brcmf_cfg80211_security *sec;
1614 if (sme->crypto.n_akm_suites) {
1615 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1618 brcmf_err("could not get wpa_auth (%d)\n", err);
1621 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1622 switch (sme->crypto.akm_suites[0]) {
1623 case WLAN_AKM_SUITE_8021X:
1624 val = WPA_AUTH_UNSPECIFIED;
1626 case WLAN_AKM_SUITE_PSK:
1630 brcmf_err("invalid cipher group (%d)\n",
1631 sme->crypto.cipher_group);
1634 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1635 switch (sme->crypto.akm_suites[0]) {
1636 case WLAN_AKM_SUITE_8021X:
1637 val = WPA2_AUTH_UNSPECIFIED;
1639 case WLAN_AKM_SUITE_PSK:
1640 val = WPA2_AUTH_PSK;
1643 brcmf_err("invalid cipher group (%d)\n",
1644 sme->crypto.cipher_group);
1649 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1650 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1653 brcmf_err("could not set wpa_auth (%d)\n", err);
1657 sec = &profile->sec;
1658 sec->wpa_auth = sme->crypto.akm_suites[0];
1664 brcmf_set_sharedkey(struct net_device *ndev,
1665 struct cfg80211_connect_params *sme)
1667 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1668 struct brcmf_cfg80211_security *sec;
1669 struct brcmf_wsec_key key;
1673 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1675 if (sme->key_len == 0)
1678 sec = &profile->sec;
1679 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1680 sec->wpa_versions, sec->cipher_pairwise);
1682 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1685 if (!(sec->cipher_pairwise &
1686 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1689 memset(&key, 0, sizeof(key));
1690 key.len = (u32) sme->key_len;
1691 key.index = (u32) sme->key_idx;
1692 if (key.len > sizeof(key.data)) {
1693 brcmf_err("Too long key length (%u)\n", key.len);
1696 memcpy(key.data, sme->key, key.len);
1697 key.flags = BRCMF_PRIMARY_KEY;
1698 switch (sec->cipher_pairwise) {
1699 case WLAN_CIPHER_SUITE_WEP40:
1700 key.algo = CRYPTO_ALGO_WEP1;
1702 case WLAN_CIPHER_SUITE_WEP104:
1703 key.algo = CRYPTO_ALGO_WEP128;
1706 brcmf_err("Invalid algorithm (%d)\n",
1707 sme->crypto.ciphers_pairwise[0]);
1710 /* Set the new key/index */
1711 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1712 key.len, key.index, key.algo);
1713 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1714 err = send_key_to_dongle(netdev_priv(ndev), &key);
1718 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1719 brcmf_dbg(CONN, "set auth_type to shared key\n");
1720 val = WL_AUTH_SHARED_KEY; /* shared key */
1721 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1723 brcmf_err("set auth failed (%d)\n", err);
1729 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1730 enum nl80211_auth_type type)
1732 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1733 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1734 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1735 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1741 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1742 struct cfg80211_connect_params *sme)
1744 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1745 struct brcmf_if *ifp = netdev_priv(ndev);
1746 struct ieee80211_channel *chan = sme->channel;
1747 struct brcmf_join_params join_params;
1748 size_t join_params_size;
1749 const struct brcmf_tlv *rsn_ie;
1750 const struct brcmf_vs_tlv *wpa_ie;
1753 struct brcmf_ext_join_params_le *ext_join_params;
1758 brcmf_dbg(TRACE, "Enter\n");
1759 if (!check_vif_up(ifp->vif))
1763 brcmf_err("Invalid ssid\n");
1767 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1768 /* A normal (non P2P) connection request setup. */
1771 /* find the WPA_IE */
1772 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1775 ie_len = wpa_ie->len + TLV_HDR_LEN;
1777 /* find the RSN_IE */
1778 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1783 ie_len = rsn_ie->len + TLV_HDR_LEN;
1786 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1789 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1790 sme->ie, sme->ie_len);
1792 brcmf_err("Set Assoc REQ IE Failed\n");
1794 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1796 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1800 ieee80211_frequency_to_channel(chan->center_freq);
1801 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1802 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1803 cfg->channel, chan->center_freq, chanspec);
1809 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1811 err = brcmf_set_wpa_version(ndev, sme);
1813 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1817 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1818 err = brcmf_set_auth_type(ndev, sme);
1820 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1824 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1826 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1830 err = brcmf_set_key_mgmt(ndev, sme);
1832 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1836 err = brcmf_set_sharedkey(ndev, sme);
1838 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1842 /* Join with specific BSSID and cached SSID
1843 * If SSID is zero join based on BSSID only
1845 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1846 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1848 join_params_size += sizeof(u16);
1849 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1850 if (ext_join_params == NULL) {
1854 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
1855 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
1856 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
1857 if (ssid_len < IEEE80211_MAX_SSID_LEN)
1858 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
1859 ext_join_params->ssid_le.SSID, ssid_len);
1861 /* Set up join scan parameters */
1862 ext_join_params->scan_le.scan_type = -1;
1863 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1866 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1868 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1871 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1873 ext_join_params->assoc_le.chanspec_list[0] =
1874 cpu_to_le16(chanspec);
1875 /* Increase dwell time to receive probe response or detect
1876 * beacon from target AP at a noisy air only during connect
1879 ext_join_params->scan_le.active_time =
1880 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1881 ext_join_params->scan_le.passive_time =
1882 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1883 /* To sync with presence period of VSDB GO send probe request
1884 * more frequently. Probe request will be stopped when it gets
1885 * probe response from target AP/GO.
1887 ext_join_params->scan_le.nprobes =
1888 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1889 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1891 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1892 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1893 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1896 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1898 kfree(ext_join_params);
1900 /* This is it. join command worked, we are done */
1903 /* join command failed, fallback to set ssid */
1904 memset(&join_params, 0, sizeof(join_params));
1905 join_params_size = sizeof(join_params.ssid_le);
1907 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
1908 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1911 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1913 eth_broadcast_addr(join_params.params_le.bssid);
1916 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1917 join_params.params_le.chanspec_num = cpu_to_le32(1);
1918 join_params_size += sizeof(join_params.params_le);
1920 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1921 &join_params, join_params_size);
1923 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1927 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1928 brcmf_dbg(TRACE, "Exit\n");
1933 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1936 struct brcmf_if *ifp = netdev_priv(ndev);
1937 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1938 struct brcmf_scb_val_le scbval;
1941 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1942 if (!check_vif_up(ifp->vif))
1945 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1946 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1947 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1949 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1950 scbval.val = cpu_to_le32(reason_code);
1951 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1952 &scbval, sizeof(scbval));
1954 brcmf_err("error (%d)\n", err);
1956 brcmf_dbg(TRACE, "Exit\n");
1961 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1962 enum nl80211_tx_power_setting type, s32 mbm)
1964 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1965 struct net_device *ndev = cfg_to_ndev(cfg);
1966 struct brcmf_if *ifp = netdev_priv(ndev);
1971 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
1972 if (!check_vif_up(ifp->vif))
1976 case NL80211_TX_POWER_AUTOMATIC:
1978 case NL80211_TX_POWER_LIMITED:
1979 case NL80211_TX_POWER_FIXED:
1981 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1985 qdbm = MBM_TO_DBM(4 * mbm);
1988 qdbm |= WL_TXPWR_OVERRIDE;
1991 brcmf_err("Unsupported type %d\n", type);
1995 /* Make sure radio is off or on as far as software is concerned */
1996 disable = WL_RADIO_SW_DISABLE << 16;
1997 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1999 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2001 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2003 brcmf_err("qtxpower error (%d)\n", err);
2006 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2011 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2014 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2015 struct net_device *ndev = cfg_to_ndev(cfg);
2016 struct brcmf_if *ifp = netdev_priv(ndev);
2020 brcmf_dbg(TRACE, "Enter\n");
2021 if (!check_vif_up(ifp->vif))
2024 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
2026 brcmf_err("error (%d)\n", err);
2029 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2032 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2037 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2038 u8 key_idx, bool unicast, bool multicast)
2040 struct brcmf_if *ifp = netdev_priv(ndev);
2045 brcmf_dbg(TRACE, "Enter\n");
2046 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2047 if (!check_vif_up(ifp->vif))
2050 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2052 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2056 if (wsec & WEP_ENABLED) {
2057 /* Just select a new current key */
2059 err = brcmf_fil_cmd_int_set(ifp,
2060 BRCMF_C_SET_KEY_PRIMARY, index);
2062 brcmf_err("error (%d)\n", err);
2065 brcmf_dbg(TRACE, "Exit\n");
2070 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2071 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2073 struct brcmf_if *ifp = netdev_priv(ndev);
2074 struct brcmf_wsec_key key;
2078 memset(&key, 0, sizeof(key));
2079 key.index = (u32) key_idx;
2080 /* Instead of bcast for ea address for default wep keys,
2081 driver needs it to be Null */
2082 if (!is_multicast_ether_addr(mac_addr))
2083 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2084 key.len = (u32) params->key_len;
2085 /* check for key index change */
2088 err = send_key_to_dongle(ifp, &key);
2090 brcmf_err("key delete error (%d)\n", err);
2092 if (key.len > sizeof(key.data)) {
2093 brcmf_err("Invalid key length (%d)\n", key.len);
2097 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2098 memcpy(key.data, params->key, key.len);
2100 if (!brcmf_is_apmode(ifp->vif) &&
2101 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2102 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2103 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2104 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2105 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2108 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2109 if (params->seq && params->seq_len == 6) {
2112 ivptr = (u8 *) params->seq;
2113 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2114 (ivptr[3] << 8) | ivptr[2];
2115 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2116 key.iv_initialized = true;
2119 switch (params->cipher) {
2120 case WLAN_CIPHER_SUITE_WEP40:
2121 key.algo = CRYPTO_ALGO_WEP1;
2122 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2124 case WLAN_CIPHER_SUITE_WEP104:
2125 key.algo = CRYPTO_ALGO_WEP128;
2126 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2128 case WLAN_CIPHER_SUITE_TKIP:
2129 key.algo = CRYPTO_ALGO_TKIP;
2130 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2132 case WLAN_CIPHER_SUITE_AES_CMAC:
2133 key.algo = CRYPTO_ALGO_AES_CCM;
2134 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2136 case WLAN_CIPHER_SUITE_CCMP:
2137 key.algo = CRYPTO_ALGO_AES_CCM;
2138 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2141 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2144 err = send_key_to_dongle(ifp, &key);
2146 brcmf_err("wsec_key error (%d)\n", err);
2152 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2153 u8 key_idx, bool pairwise, const u8 *mac_addr,
2154 struct key_params *params)
2156 struct brcmf_if *ifp = netdev_priv(ndev);
2157 struct brcmf_wsec_key *key;
2163 brcmf_dbg(TRACE, "Enter\n");
2164 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2165 if (!check_vif_up(ifp->vif))
2168 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2169 /* we ignore this key index in this case */
2170 brcmf_err("invalid key index (%d)\n", key_idx);
2175 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2176 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2177 brcmf_dbg(TRACE, "Exit");
2178 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2181 key = &ifp->vif->profile.key[key_idx];
2182 memset(key, 0, sizeof(*key));
2184 if (params->key_len > sizeof(key->data)) {
2185 brcmf_err("Too long key length (%u)\n", params->key_len);
2189 key->len = params->key_len;
2190 key->index = key_idx;
2192 memcpy(key->data, params->key, key->len);
2194 key->flags = BRCMF_PRIMARY_KEY;
2195 switch (params->cipher) {
2196 case WLAN_CIPHER_SUITE_WEP40:
2197 key->algo = CRYPTO_ALGO_WEP1;
2199 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2201 case WLAN_CIPHER_SUITE_WEP104:
2202 key->algo = CRYPTO_ALGO_WEP128;
2204 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2206 case WLAN_CIPHER_SUITE_TKIP:
2207 if (!brcmf_is_apmode(ifp->vif)) {
2208 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2209 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2210 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2211 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2213 key->algo = CRYPTO_ALGO_TKIP;
2215 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2217 case WLAN_CIPHER_SUITE_AES_CMAC:
2218 key->algo = CRYPTO_ALGO_AES_CCM;
2220 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2222 case WLAN_CIPHER_SUITE_CCMP:
2223 key->algo = CRYPTO_ALGO_AES_CCM;
2225 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2228 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2233 err = send_key_to_dongle(ifp, key);
2237 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2239 brcmf_err("get wsec error (%d)\n", err);
2243 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2245 brcmf_err("set wsec error (%d)\n", err);
2250 brcmf_dbg(TRACE, "Exit\n");
2255 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2256 u8 key_idx, bool pairwise, const u8 *mac_addr)
2258 struct brcmf_if *ifp = netdev_priv(ndev);
2259 struct brcmf_wsec_key key;
2262 brcmf_dbg(TRACE, "Enter\n");
2263 if (!check_vif_up(ifp->vif))
2266 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2267 /* we ignore this key index in this case */
2271 memset(&key, 0, sizeof(key));
2273 key.index = (u32) key_idx;
2274 key.flags = BRCMF_PRIMARY_KEY;
2275 key.algo = CRYPTO_ALGO_OFF;
2277 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2279 /* Set the new key/index */
2280 err = send_key_to_dongle(ifp, &key);
2282 brcmf_dbg(TRACE, "Exit\n");
2287 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2288 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2289 void (*callback) (void *cookie, struct key_params * params))
2291 struct key_params params;
2292 struct brcmf_if *ifp = netdev_priv(ndev);
2293 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2294 struct brcmf_cfg80211_security *sec;
2298 brcmf_dbg(TRACE, "Enter\n");
2299 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2300 if (!check_vif_up(ifp->vif))
2303 memset(¶ms, 0, sizeof(params));
2305 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2307 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2308 /* Ignore this error, may happen during DISASSOC */
2312 if (wsec & WEP_ENABLED) {
2313 sec = &profile->sec;
2314 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2315 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2316 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2317 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2318 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2319 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2321 } else if (wsec & TKIP_ENABLED) {
2322 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2323 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2324 } else if (wsec & AES_ENABLED) {
2325 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2326 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2328 brcmf_err("Invalid algo (0x%x)\n", wsec);
2332 callback(cookie, ¶ms);
2335 brcmf_dbg(TRACE, "Exit\n");
2340 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2341 struct net_device *ndev, u8 key_idx)
2343 brcmf_dbg(INFO, "Not supported\n");
2349 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2353 struct brcmf_wsec_key *key;
2356 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2357 key = &ifp->vif->profile.key[key_idx];
2358 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2359 (key->algo == CRYPTO_ALGO_WEP128))
2362 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2365 err = send_key_to_dongle(ifp, key);
2367 brcmf_err("Setting WEP key failed (%d)\n", err);
2370 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2372 brcmf_err("get wsec error (%d)\n", err);
2375 wsec |= WEP_ENABLED;
2376 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2378 brcmf_err("set wsec error (%d)\n", err);
2381 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2383 struct nl80211_sta_flag_update *sfu;
2385 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2386 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2387 sfu = &si->sta_flags;
2388 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2389 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2390 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2391 BIT(NL80211_STA_FLAG_AUTHORIZED);
2392 if (fw_sta_flags & BRCMF_STA_WME)
2393 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2394 if (fw_sta_flags & BRCMF_STA_AUTHE)
2395 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2396 if (fw_sta_flags & BRCMF_STA_ASSOC)
2397 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2398 if (fw_sta_flags & BRCMF_STA_AUTHO)
2399 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2402 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2406 struct brcmf_bss_info_le bss_le;
2411 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2415 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2416 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2419 brcmf_err("Failed to get bss info (%d)\n", err);
2422 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2423 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2424 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2425 capability = le16_to_cpu(buf->bss_le.capability);
2426 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2427 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2428 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2429 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2430 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2431 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2435 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2436 struct station_info *sinfo)
2438 struct brcmf_scb_val_le scbval;
2439 struct brcmf_pktcnt_le pktcnt;
2444 /* Get the current tx rate */
2445 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2447 brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err);
2450 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2451 sinfo->txrate.legacy = rate * 5;
2453 memset(&scbval, 0, sizeof(scbval));
2454 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2457 brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err);
2460 rssi = le32_to_cpu(scbval.val);
2461 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2462 sinfo->signal = rssi;
2464 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2467 brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2470 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
2471 BIT(NL80211_STA_INFO_RX_DROP_MISC) |
2472 BIT(NL80211_STA_INFO_TX_PACKETS) |
2473 BIT(NL80211_STA_INFO_TX_FAILED);
2474 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2475 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2476 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2477 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
2483 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2484 const u8 *mac, struct station_info *sinfo)
2486 struct brcmf_if *ifp = netdev_priv(ndev);
2488 struct brcmf_sta_info_le sta_info_le;
2495 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2496 if (!check_vif_up(ifp->vif))
2499 if (brcmf_is_ibssmode(ifp->vif))
2500 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2502 memset(&sta_info_le, 0, sizeof(sta_info_le));
2503 memcpy(&sta_info_le, mac, ETH_ALEN);
2504 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2506 sizeof(sta_info_le));
2507 is_tdls_peer = !err;
2509 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2511 sizeof(sta_info_le));
2513 brcmf_err("GET STA INFO failed, %d\n", err);
2517 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2518 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2519 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2520 sta_flags = le32_to_cpu(sta_info_le.flags);
2521 brcmf_convert_sta_flags(sta_flags, sinfo);
2522 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2524 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2526 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2527 if (sta_flags & BRCMF_STA_ASSOC) {
2528 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2529 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2530 brcmf_fill_bss_param(ifp, sinfo);
2532 if (sta_flags & BRCMF_STA_SCBSTATS) {
2533 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2534 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2535 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2536 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2537 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2538 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2539 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2540 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2541 if (sinfo->tx_packets) {
2542 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2543 sinfo->txrate.legacy =
2544 le32_to_cpu(sta_info_le.tx_rate) / 100;
2546 if (sinfo->rx_packets) {
2547 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2548 sinfo->rxrate.legacy =
2549 le32_to_cpu(sta_info_le.rx_rate) / 100;
2551 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2552 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2553 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2554 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2555 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2559 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2560 if (sta_info_le.rssi[i]) {
2561 sinfo->chain_signal_avg[count_rssi] =
2562 sta_info_le.rssi[i];
2563 sinfo->chain_signal[count_rssi] =
2564 sta_info_le.rssi[i];
2565 total_rssi += sta_info_le.rssi[i];
2570 sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2571 sinfo->chains = count_rssi;
2573 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2574 total_rssi /= count_rssi;
2575 sinfo->signal = total_rssi;
2579 brcmf_dbg(TRACE, "Exit\n");
2584 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2585 int idx, u8 *mac, struct station_info *sinfo)
2587 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2588 struct brcmf_if *ifp = netdev_priv(ndev);
2591 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2594 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2595 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2597 sizeof(cfg->assoclist));
2599 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2601 cfg->assoclist.count = 0;
2605 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2606 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2607 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2613 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2614 bool enabled, s32 timeout)
2618 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2619 struct brcmf_if *ifp = netdev_priv(ndev);
2621 brcmf_dbg(TRACE, "Enter\n");
2624 * Powersave enable/disable request is coming from the
2625 * cfg80211 even before the interface is up. In that
2626 * scenario, driver will be storing the power save
2627 * preference in cfg struct to apply this to
2628 * FW later while initializing the dongle
2630 cfg->pwr_save = enabled;
2631 if (!check_vif_up(ifp->vif)) {
2633 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2637 pm = enabled ? PM_FAST : PM_OFF;
2638 /* Do not enable the power save after assoc if it is a p2p interface */
2639 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2640 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2643 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2645 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2648 brcmf_err("net_device is not ready yet\n");
2650 brcmf_err("error (%d)\n", err);
2653 brcmf_dbg(TRACE, "Exit\n");
2657 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2658 struct brcmf_bss_info_le *bi)
2660 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2661 struct ieee80211_channel *notify_channel;
2662 struct cfg80211_bss *bss;
2663 struct ieee80211_supported_band *band;
2664 struct brcmu_chan ch;
2667 u16 notify_capability;
2668 u16 notify_interval;
2670 size_t notify_ielen;
2673 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2674 brcmf_err("Bss info is larger than buffer. Discarding\n");
2679 ch.chspec = le16_to_cpu(bi->chanspec);
2680 cfg->d11inf.decchspec(&ch);
2681 bi->ctl_ch = ch.chnum;
2683 channel = bi->ctl_ch;
2685 if (channel <= CH_MAX_2G_CHANNEL)
2686 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2688 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2690 freq = ieee80211_channel_to_frequency(channel, band->band);
2691 notify_channel = ieee80211_get_channel(wiphy, freq);
2693 notify_capability = le16_to_cpu(bi->capability);
2694 notify_interval = le16_to_cpu(bi->beacon_period);
2695 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2696 notify_ielen = le32_to_cpu(bi->ie_length);
2697 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2699 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2700 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2701 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2702 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2703 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2705 bss = cfg80211_inform_bss(wiphy, notify_channel,
2706 CFG80211_BSS_FTYPE_UNKNOWN,
2707 (const u8 *)bi->BSSID,
2708 0, notify_capability,
2709 notify_interval, notify_ie,
2710 notify_ielen, notify_signal,
2716 cfg80211_put_bss(wiphy, bss);
2721 static struct brcmf_bss_info_le *
2722 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2725 return list->bss_info_le;
2726 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2727 le32_to_cpu(bss->length));
2730 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2732 struct brcmf_scan_results *bss_list;
2733 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2737 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2738 if (bss_list->count != 0 &&
2739 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2740 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2744 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2745 for (i = 0; i < bss_list->count; i++) {
2746 bi = next_bss_le(bss_list, bi);
2747 err = brcmf_inform_single_bss(cfg, bi);
2754 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
2755 struct net_device *ndev, const u8 *bssid)
2757 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2758 struct ieee80211_channel *notify_channel;
2759 struct brcmf_bss_info_le *bi = NULL;
2760 struct ieee80211_supported_band *band;
2761 struct cfg80211_bss *bss;
2762 struct brcmu_chan ch;
2766 u16 notify_capability;
2767 u16 notify_interval;
2769 size_t notify_ielen;
2772 brcmf_dbg(TRACE, "Enter\n");
2774 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2780 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2782 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2783 buf, WL_BSS_INFO_MAX);
2785 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2789 bi = (struct brcmf_bss_info_le *)(buf + 4);
2791 ch.chspec = le16_to_cpu(bi->chanspec);
2792 cfg->d11inf.decchspec(&ch);
2794 if (ch.band == BRCMU_CHAN_BAND_2G)
2795 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2797 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2799 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2800 cfg->channel = freq;
2801 notify_channel = ieee80211_get_channel(wiphy, freq);
2803 notify_capability = le16_to_cpu(bi->capability);
2804 notify_interval = le16_to_cpu(bi->beacon_period);
2805 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2806 notify_ielen = le32_to_cpu(bi->ie_length);
2807 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2809 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2810 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2811 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2812 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2814 bss = cfg80211_inform_bss(wiphy, notify_channel,
2815 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2816 notify_capability, notify_interval,
2817 notify_ie, notify_ielen, notify_signal,
2825 cfg80211_put_bss(wiphy, bss);
2831 brcmf_dbg(TRACE, "Exit\n");
2836 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2837 struct brcmf_if *ifp)
2839 struct brcmf_bss_info_le *bi;
2840 const struct brcmf_tlv *tim;
2841 u16 beacon_interval;
2847 brcmf_dbg(TRACE, "Enter\n");
2848 if (brcmf_is_ibssmode(ifp->vif))
2851 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2852 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2853 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2855 brcmf_err("Could not get bss info %d\n", err);
2856 goto update_bss_info_out;
2859 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2860 err = brcmf_inform_single_bss(cfg, bi);
2862 goto update_bss_info_out;
2864 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2865 ie_len = le32_to_cpu(bi->ie_length);
2866 beacon_interval = le16_to_cpu(bi->beacon_period);
2868 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2870 dtim_period = tim->data[1];
2873 * active scan was done so we could not get dtim
2874 * information out of probe response.
2875 * so we speficially query dtim information to dongle.
2878 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2880 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2881 goto update_bss_info_out;
2883 dtim_period = (u8)var;
2886 update_bss_info_out:
2887 brcmf_dbg(TRACE, "Exit");
2891 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2893 struct escan_info *escan = &cfg->escan_info;
2895 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2896 if (cfg->scan_request) {
2897 escan->escan_state = WL_ESCAN_STATE_IDLE;
2898 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2900 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2901 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2904 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2906 struct brcmf_cfg80211_info *cfg =
2907 container_of(work, struct brcmf_cfg80211_info,
2908 escan_timeout_work);
2910 brcmf_inform_bss(cfg);
2911 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2914 static void brcmf_escan_timeout(unsigned long data)
2916 struct brcmf_cfg80211_info *cfg =
2917 (struct brcmf_cfg80211_info *)data;
2919 if (cfg->scan_request) {
2920 brcmf_err("timer expired\n");
2921 schedule_work(&cfg->escan_timeout_work);
2926 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2927 struct brcmf_bss_info_le *bss,
2928 struct brcmf_bss_info_le *bss_info_le)
2930 struct brcmu_chan ch_bss, ch_bss_info_le;
2932 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2933 cfg->d11inf.decchspec(&ch_bss);
2934 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2935 cfg->d11inf.decchspec(&ch_bss_info_le);
2937 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2938 ch_bss.band == ch_bss_info_le.band &&
2939 bss_info_le->SSID_len == bss->SSID_len &&
2940 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2941 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2942 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2943 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2944 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2946 /* preserve max RSSI if the measurements are
2947 * both on-channel or both off-channel
2949 if (bss_info_rssi > bss_rssi)
2950 bss->RSSI = bss_info_le->RSSI;
2951 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2952 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2953 /* preserve the on-channel rssi measurement
2954 * if the new measurement is off channel
2956 bss->RSSI = bss_info_le->RSSI;
2957 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2965 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2966 const struct brcmf_event_msg *e, void *data)
2968 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2970 struct brcmf_escan_result_le *escan_result_le;
2971 struct brcmf_bss_info_le *bss_info_le;
2972 struct brcmf_bss_info_le *bss = NULL;
2974 struct brcmf_scan_results *list;
2980 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2981 brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
2985 if (status == BRCMF_E_STATUS_PARTIAL) {
2986 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2987 escan_result_le = (struct brcmf_escan_result_le *) data;
2988 if (!escan_result_le) {
2989 brcmf_err("Invalid escan result (NULL pointer)\n");
2992 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2993 brcmf_err("Invalid bss_count %d: ignoring\n",
2994 escan_result_le->bss_count);
2997 bss_info_le = &escan_result_le->bss_info_le;
2999 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3002 if (!cfg->scan_request) {
3003 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3007 bi_length = le32_to_cpu(bss_info_le->length);
3008 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3009 WL_ESCAN_RESULTS_FIXED_SIZE)) {
3010 brcmf_err("Invalid bss_info length %d: ignoring\n",
3015 if (!(cfg_to_wiphy(cfg)->interface_modes &
3016 BIT(NL80211_IFTYPE_ADHOC))) {
3017 if (le16_to_cpu(bss_info_le->capability) &
3018 WLAN_CAPABILITY_IBSS) {
3019 brcmf_err("Ignoring IBSS result\n");
3024 list = (struct brcmf_scan_results *)
3025 cfg->escan_info.escan_buf;
3026 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
3027 brcmf_err("Buffer is too small: ignoring\n");
3031 for (i = 0; i < list->count; i++) {
3032 bss = bss ? (struct brcmf_bss_info_le *)
3033 ((unsigned char *)bss +
3034 le32_to_cpu(bss->length)) : list->bss_info_le;
3035 if (brcmf_compare_update_same_bss(cfg, bss,
3039 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3040 bss_info_le, bi_length);
3041 list->version = le32_to_cpu(bss_info_le->version);
3042 list->buflen += bi_length;
3045 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3046 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3048 if (cfg->scan_request) {
3049 brcmf_inform_bss(cfg);
3050 aborted = status != BRCMF_E_STATUS_SUCCESS;
3051 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3053 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3060 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3062 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3063 brcmf_cfg80211_escan_handler);
3064 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3065 /* Init scan_timeout timer */
3066 init_timer(&cfg->escan_timeout);
3067 cfg->escan_timeout.data = (unsigned long) cfg;
3068 cfg->escan_timeout.function = brcmf_escan_timeout;
3069 INIT_WORK(&cfg->escan_timeout_work,
3070 brcmf_cfg80211_escan_timeout_worker);
3073 /* PFN result doesn't have all the info which are required by the supplicant
3074 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3075 * via wl_inform_single_bss in the required format. Escan does require the
3076 * scan request in the form of cfg80211_scan_request. For timebeing, create
3077 * cfg80211_scan_request one out of the received PNO event.
3080 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3081 const struct brcmf_event_msg *e, void *data)
3083 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3084 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3085 struct cfg80211_scan_request *request = NULL;
3086 struct cfg80211_ssid *ssid = NULL;
3087 struct ieee80211_channel *channel = NULL;
3088 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3090 int channel_req = 0;
3092 struct brcmf_pno_scanresults_le *pfn_result;
3096 brcmf_dbg(SCAN, "Enter\n");
3098 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3099 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3103 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3104 result_count = le32_to_cpu(pfn_result->count);
3105 status = le32_to_cpu(pfn_result->status);
3107 /* PFN event is limited to fit 512 bytes so we may get
3108 * multiple NET_FOUND events. For now place a warning here.
3110 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3111 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3112 if (result_count > 0) {
3115 request = kzalloc(sizeof(*request), GFP_KERNEL);
3116 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3117 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3118 if (!request || !ssid || !channel) {
3123 request->wiphy = wiphy;
3124 data += sizeof(struct brcmf_pno_scanresults_le);
3125 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3127 for (i = 0; i < result_count; i++) {
3128 netinfo = &netinfo_start[i];
3130 brcmf_err("Invalid netinfo ptr. index: %d\n",
3136 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3137 netinfo->SSID, netinfo->channel);
3138 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3139 ssid[i].ssid_len = netinfo->SSID_len;
3142 channel_req = netinfo->channel;
3143 if (channel_req <= CH_MAX_2G_CHANNEL)
3144 band = NL80211_BAND_2GHZ;
3146 band = NL80211_BAND_5GHZ;
3147 channel[i].center_freq =
3148 ieee80211_channel_to_frequency(channel_req,
3150 channel[i].band = band;
3151 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3152 request->channels[i] = &channel[i];
3153 request->n_channels++;
3156 /* assign parsed ssid array */
3157 if (request->n_ssids)
3158 request->ssids = &ssid[0];
3160 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3161 /* Abort any on-going scan */
3162 brcmf_abort_scanning(cfg);
3165 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3166 cfg->escan_info.run = brcmf_run_escan;
3167 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3169 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3172 cfg->sched_escan = true;
3173 cfg->scan_request = request;
3175 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3188 cfg80211_sched_scan_stopped(wiphy);
3192 static int brcmf_dev_pno_clean(struct net_device *ndev)
3197 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3200 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3204 brcmf_err("failed code %d\n", ret);
3209 static int brcmf_dev_pno_config(struct brcmf_if *ifp,
3210 struct cfg80211_sched_scan_request *request)
3212 struct brcmf_pno_param_le pfn_param;
3213 struct brcmf_pno_macaddr_le pfn_mac;
3218 memset(&pfn_param, 0, sizeof(pfn_param));
3219 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3221 /* set extra pno params */
3222 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3223 pfn_param.repeat = BRCMF_PNO_REPEAT;
3224 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3226 /* set up pno scan fr */
3227 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3229 err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
3232 brcmf_err("pfn_set failed, err=%d\n", err);
3236 /* Find out if mac randomization should be turned on */
3237 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
3240 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
3241 pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
3243 memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
3244 mac_mask = request->mac_addr_mask;
3245 for (i = 0; i < ETH_ALEN; i++) {
3246 pfn_mac.mac[i] &= mac_mask[i];
3247 pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
3249 /* Clear multi bit */
3250 pfn_mac.mac[0] &= 0xFE;
3251 /* Set locally administered */
3252 pfn_mac.mac[0] |= 0x02;
3254 err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
3257 brcmf_err("pfn_macaddr failed, err=%d\n", err);
3263 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3264 struct net_device *ndev,
3265 struct cfg80211_sched_scan_request *request)
3267 struct brcmf_if *ifp = netdev_priv(ndev);
3268 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3269 struct brcmf_pno_net_param_le pfn;
3273 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3274 request->n_match_sets, request->n_ssids);
3275 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3276 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3279 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3280 brcmf_err("Scanning suppressed: status (%lu)\n",
3285 if (!request->n_ssids || !request->n_match_sets) {
3286 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3291 if (request->n_ssids > 0) {
3292 for (i = 0; i < request->n_ssids; i++) {
3293 /* Active scan req for ssids */
3294 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3295 request->ssids[i].ssid);
3297 /* match_set ssids is a supert set of n_ssid list,
3298 * so we need not add these set separately.
3303 if (request->n_match_sets > 0) {
3304 /* clean up everything */
3305 ret = brcmf_dev_pno_clean(ndev);
3307 brcmf_err("failed error=%d\n", ret);
3312 if (brcmf_dev_pno_config(ifp, request))
3315 /* configure each match set */
3316 for (i = 0; i < request->n_match_sets; i++) {
3317 struct cfg80211_ssid *ssid;
3320 ssid = &request->match_sets[i].ssid;
3321 ssid_len = ssid->ssid_len;
3324 brcmf_err("skip broadcast ssid\n");
3327 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3328 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3329 pfn.wsec = cpu_to_le32(0);
3330 pfn.infra = cpu_to_le32(1);
3331 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3332 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3333 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3334 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3336 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3337 ret == 0 ? "set" : "failed", ssid->ssid);
3339 /* Enable the PNO */
3340 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3341 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3351 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3352 struct net_device *ndev)
3354 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3356 brcmf_dbg(SCAN, "enter\n");
3357 brcmf_dev_pno_clean(ndev);
3358 if (cfg->sched_escan)
3359 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3363 static __always_inline void brcmf_delay(u32 ms)
3365 if (ms < 1000 / HZ) {
3373 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3374 u8 *pattern, u32 patternsize, u8 *mask,
3377 struct brcmf_fil_wowl_pattern_le *filter;
3384 masksize = (patternsize + 7) / 8;
3385 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3387 bufsize = sizeof(*filter) + patternsize + masksize;
3388 buf = kzalloc(bufsize, GFP_KERNEL);
3391 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3393 memcpy(filter->cmd, cmd, 4);
3394 filter->masksize = cpu_to_le32(masksize);
3395 filter->offset = cpu_to_le32(packet_offset);
3396 filter->patternoffset = cpu_to_le32(patternoffset);
3397 filter->patternsize = cpu_to_le32(patternsize);
3398 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3400 if ((mask) && (masksize))
3401 memcpy(buf + sizeof(*filter), mask, masksize);
3402 if ((pattern) && (patternsize))
3403 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3405 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3412 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3415 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3416 struct brcmf_pno_scanresults_le *pfn_result;
3417 struct brcmf_pno_net_info_le *netinfo;
3419 brcmf_dbg(SCAN, "Enter\n");
3421 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3423 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3424 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3428 if (le32_to_cpu(pfn_result->count) < 1) {
3429 brcmf_err("Invalid result count, expected 1 (%d)\n",
3430 le32_to_cpu(pfn_result->count));
3434 data += sizeof(struct brcmf_pno_scanresults_le);
3435 netinfo = (struct brcmf_pno_net_info_le *)data;
3436 memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3437 cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3438 cfg->wowl.nd->n_channels = 1;
3439 cfg->wowl.nd->channels[0] =
3440 ieee80211_channel_to_frequency(netinfo->channel,
3441 netinfo->channel <= CH_MAX_2G_CHANNEL ?
3442 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3443 cfg->wowl.nd_info->n_matches = 1;
3444 cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3446 /* Inform (the resume task) that the net detect information was recvd */
3447 cfg->wowl.nd_data_completed = true;
3448 wake_up(&cfg->wowl.nd_data_wait);
3455 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3457 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3458 struct brcmf_wowl_wakeind_le wake_ind_le;
3459 struct cfg80211_wowlan_wakeup wakeup_data;
3460 struct cfg80211_wowlan_wakeup *wakeup;
3465 err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3466 sizeof(wake_ind_le));
3468 brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
3472 wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3473 if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3474 BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3475 BRCMF_WOWL_PFN_FOUND)) {
3476 wakeup = &wakeup_data;
3477 memset(&wakeup_data, 0, sizeof(wakeup_data));
3478 wakeup_data.pattern_idx = -1;
3480 if (wakeind & BRCMF_WOWL_MAGIC) {
3481 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3482 wakeup_data.magic_pkt = true;
3484 if (wakeind & BRCMF_WOWL_DIS) {
3485 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3486 wakeup_data.disconnect = true;
3488 if (wakeind & BRCMF_WOWL_BCN) {
3489 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3490 wakeup_data.disconnect = true;
3492 if (wakeind & BRCMF_WOWL_RETR) {
3493 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3494 wakeup_data.disconnect = true;
3496 if (wakeind & BRCMF_WOWL_NET) {
3497 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3498 /* For now always map to pattern 0, no API to get
3499 * correct information available at the moment.
3501 wakeup_data.pattern_idx = 0;
3503 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3504 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3505 timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3506 cfg->wowl.nd_data_completed,
3507 BRCMF_ND_INFO_TIMEOUT);
3509 brcmf_err("No result for wowl net detect\n");
3511 wakeup_data.net_detect = cfg->wowl.nd_info;
3516 cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3521 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3525 #endif /* CONFIG_PM */
3527 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3529 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3530 struct net_device *ndev = cfg_to_ndev(cfg);
3531 struct brcmf_if *ifp = netdev_priv(ndev);
3533 brcmf_dbg(TRACE, "Enter\n");
3535 if (cfg->wowl.active) {
3536 brcmf_report_wowl_wakeind(wiphy, ifp);
3537 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3538 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3539 brcmf_configure_arp_offload(ifp, true);
3540 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3541 cfg->wowl.pre_pmmode);
3542 cfg->wowl.active = false;
3543 if (cfg->wowl.nd_enabled) {
3544 brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev);
3545 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3546 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3547 brcmf_notify_sched_scan_results);
3548 cfg->wowl.nd_enabled = false;
3554 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3555 struct brcmf_if *ifp,
3556 struct cfg80211_wowlan *wowl)
3561 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3563 brcmf_configure_arp_offload(ifp, false);
3564 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3565 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3568 if (wowl->disconnect)
3569 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3570 if (wowl->magic_pkt)
3571 wowl_config |= BRCMF_WOWL_MAGIC;
3572 if ((wowl->patterns) && (wowl->n_patterns)) {
3573 wowl_config |= BRCMF_WOWL_NET;
3574 for (i = 0; i < wowl->n_patterns; i++) {
3575 brcmf_config_wowl_pattern(ifp, "add",
3576 (u8 *)wowl->patterns[i].pattern,
3577 wowl->patterns[i].pattern_len,
3578 (u8 *)wowl->patterns[i].mask,
3579 wowl->patterns[i].pkt_offset);
3582 if (wowl->nd_config) {
3583 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3585 wowl_config |= BRCMF_WOWL_PFN_FOUND;
3587 cfg->wowl.nd_data_completed = false;
3588 cfg->wowl.nd_enabled = true;
3589 /* Now reroute the event for PFN to the wowl function. */
3590 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3591 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3592 brcmf_wowl_nd_results);
3594 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3595 wowl_config |= BRCMF_WOWL_UNASSOC;
3597 brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
3598 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3599 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3600 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3601 cfg->wowl.active = true;
3604 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3605 struct cfg80211_wowlan *wowl)
3607 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3608 struct net_device *ndev = cfg_to_ndev(cfg);
3609 struct brcmf_if *ifp = netdev_priv(ndev);
3610 struct brcmf_cfg80211_vif *vif;
3612 brcmf_dbg(TRACE, "Enter\n");
3614 /* if the primary net_device is not READY there is nothing
3615 * we can do but pray resume goes smoothly.
3617 if (!check_vif_up(ifp->vif))
3620 /* Stop scheduled scan */
3621 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3622 brcmf_cfg80211_sched_scan_stop(wiphy, ndev);
3624 /* end any scanning */
3625 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3626 brcmf_abort_scanning(cfg);
3629 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3630 list_for_each_entry(vif, &cfg->vif_list, list) {
3631 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3633 /* While going to suspend if associated with AP
3634 * disassociate from AP to save power while system is
3635 * in suspended state
3637 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3638 /* Make sure WPA_Supplicant receives all the event
3639 * generated due to DISASSOC call to the fw to keep
3640 * the state fw and WPA_Supplicant state consistent
3645 brcmf_set_mpc(ifp, 1);
3648 /* Configure WOWL paramaters */
3649 brcmf_configure_wowl(cfg, ifp, wowl);
3653 brcmf_dbg(TRACE, "Exit\n");
3654 /* clear any scanning activity */
3655 cfg->scan_status = 0;
3660 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3662 struct brcmf_pmk_list_le *pmk_list;
3667 pmk_list = &cfg->pmk_list;
3668 npmk = le32_to_cpu(pmk_list->npmk);
3670 brcmf_dbg(CONN, "No of elements %d\n", npmk);
3671 for (i = 0; i < npmk; i++)
3672 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3674 err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3681 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3682 struct cfg80211_pmksa *pmksa)
3684 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3685 struct brcmf_if *ifp = netdev_priv(ndev);
3686 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3690 brcmf_dbg(TRACE, "Enter\n");
3691 if (!check_vif_up(ifp->vif))
3694 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3695 for (i = 0; i < npmk; i++)
3696 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3698 if (i < BRCMF_MAXPMKID) {
3699 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
3700 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
3703 cfg->pmk_list.npmk = cpu_to_le32(npmk);
3706 brcmf_err("Too many PMKSA entries cached %d\n", npmk);
3710 brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
3711 for (i = 0; i < WLAN_PMKID_LEN; i += 4)
3712 brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
3713 pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
3714 pmk[npmk].pmkid[i + 3]);
3716 err = brcmf_update_pmklist(cfg, ifp);
3718 brcmf_dbg(TRACE, "Exit\n");
3723 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3724 struct cfg80211_pmksa *pmksa)
3726 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3727 struct brcmf_if *ifp = netdev_priv(ndev);
3728 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3732 brcmf_dbg(TRACE, "Enter\n");
3733 if (!check_vif_up(ifp->vif))
3736 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
3738 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3739 for (i = 0; i < npmk; i++)
3740 if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
3743 if ((npmk > 0) && (i < npmk)) {
3744 for (; i < (npmk - 1); i++) {
3745 memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
3746 memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
3749 memset(&pmk[i], 0, sizeof(*pmk));
3750 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
3752 brcmf_err("Cache entry not found\n");
3756 err = brcmf_update_pmklist(cfg, ifp);
3758 brcmf_dbg(TRACE, "Exit\n");
3764 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3766 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3767 struct brcmf_if *ifp = netdev_priv(ndev);
3770 brcmf_dbg(TRACE, "Enter\n");
3771 if (!check_vif_up(ifp->vif))
3774 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
3775 err = brcmf_update_pmklist(cfg, ifp);
3777 brcmf_dbg(TRACE, "Exit\n");
3782 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3787 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3789 brcmf_err("auth error %d\n", err);
3793 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3795 brcmf_err("wsec error %d\n", err);
3798 /* set upper-layer auth */
3799 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3801 brcmf_err("wpa_auth error %d\n", err);
3808 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3811 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3813 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3817 brcmf_configure_wpaie(struct brcmf_if *ifp,
3818 const struct brcmf_vs_tlv *wpa_ie,
3821 u32 auth = 0; /* d11 open authentication */
3833 u32 wme_bss_disable;
3835 brcmf_dbg(TRACE, "Enter\n");
3839 len = wpa_ie->len + TLV_HDR_LEN;
3840 data = (u8 *)wpa_ie;
3841 offset = TLV_HDR_LEN;
3843 offset += VS_IE_FIXED_HDR_LEN;
3845 offset += WPA_IE_VERSION_LEN;
3847 /* check for multicast cipher suite */
3848 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3850 brcmf_err("no multicast cipher suite\n");
3854 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3856 brcmf_err("ivalid OUI\n");
3859 offset += TLV_OUI_LEN;
3861 /* pick up multicast cipher */
3862 switch (data[offset]) {
3863 case WPA_CIPHER_NONE:
3866 case WPA_CIPHER_WEP_40:
3867 case WPA_CIPHER_WEP_104:
3870 case WPA_CIPHER_TKIP:
3871 gval = TKIP_ENABLED;
3873 case WPA_CIPHER_AES_CCM:
3878 brcmf_err("Invalid multi cast cipher info\n");
3883 /* walk thru unicast cipher list and pick up what we recognize */
3884 count = data[offset] + (data[offset + 1] << 8);
3885 offset += WPA_IE_SUITE_COUNT_LEN;
3886 /* Check for unicast suite(s) */
3887 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3889 brcmf_err("no unicast cipher suite\n");
3892 for (i = 0; i < count; i++) {
3893 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3895 brcmf_err("ivalid OUI\n");
3898 offset += TLV_OUI_LEN;
3899 switch (data[offset]) {
3900 case WPA_CIPHER_NONE:
3902 case WPA_CIPHER_WEP_40:
3903 case WPA_CIPHER_WEP_104:
3904 pval |= WEP_ENABLED;
3906 case WPA_CIPHER_TKIP:
3907 pval |= TKIP_ENABLED;
3909 case WPA_CIPHER_AES_CCM:
3910 pval |= AES_ENABLED;
3913 brcmf_err("Ivalid unicast security info\n");
3917 /* walk thru auth management suite list and pick up what we recognize */
3918 count = data[offset] + (data[offset + 1] << 8);
3919 offset += WPA_IE_SUITE_COUNT_LEN;
3920 /* Check for auth key management suite(s) */
3921 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3923 brcmf_err("no auth key mgmt suite\n");
3926 for (i = 0; i < count; i++) {
3927 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3929 brcmf_err("ivalid OUI\n");
3932 offset += TLV_OUI_LEN;
3933 switch (data[offset]) {
3935 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3936 wpa_auth |= WPA_AUTH_NONE;
3938 case RSN_AKM_UNSPECIFIED:
3939 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3940 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3941 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3944 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3945 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3946 (wpa_auth |= WPA_AUTH_PSK);
3949 brcmf_err("Ivalid key mgmt info\n");
3955 wme_bss_disable = 1;
3956 if ((offset + RSN_CAP_LEN) <= len) {
3957 rsn_cap = data[offset] + (data[offset + 1] << 8);
3958 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3959 wme_bss_disable = 0;
3961 /* set wme_bss_disable to sync RSN Capabilities */
3962 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3965 brcmf_err("wme_bss_disable error %d\n", err);
3969 /* FOR WPS , set SES_OW_ENABLED */
3970 wsec = (pval | gval | SES_OW_ENABLED);
3973 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3975 brcmf_err("auth error %d\n", err);
3979 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3981 brcmf_err("wsec error %d\n", err);
3984 /* set upper-layer auth */
3985 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3987 brcmf_err("wpa_auth error %d\n", err);
3996 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3997 struct parsed_vndr_ies *vndr_ies)
3999 struct brcmf_vs_tlv *vndrie;
4000 struct brcmf_tlv *ie;
4001 struct parsed_vndr_ie_info *parsed_info;
4004 remaining_len = (s32)vndr_ie_len;
4005 memset(vndr_ies, 0, sizeof(*vndr_ies));
4007 ie = (struct brcmf_tlv *)vndr_ie_buf;
4009 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4011 vndrie = (struct brcmf_vs_tlv *)ie;
4012 /* len should be bigger than OUI length + one */
4013 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4014 brcmf_err("invalid vndr ie. length is too small %d\n",
4018 /* if wpa or wme ie, do not add ie */
4019 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4020 ((vndrie->oui_type == WPA_OUI_TYPE) ||
4021 (vndrie->oui_type == WME_OUI_TYPE))) {
4022 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4026 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4028 /* save vndr ie information */
4029 parsed_info->ie_ptr = (char *)vndrie;
4030 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4031 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4035 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
4036 parsed_info->vndrie.oui[0],
4037 parsed_info->vndrie.oui[1],
4038 parsed_info->vndrie.oui[2],
4039 parsed_info->vndrie.oui_type);
4041 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4044 remaining_len -= (ie->len + TLV_HDR_LEN);
4045 if (remaining_len <= TLV_HDR_LEN)
4048 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4055 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4058 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
4059 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
4061 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4063 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4065 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4067 return ie_len + VNDR_IE_HDR_SIZE;
4070 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4071 const u8 *vndr_ie_buf, u32 vndr_ie_len)
4073 struct brcmf_if *ifp;
4074 struct vif_saved_ie *saved_ie;
4078 u8 *mgmt_ie_buf = NULL;
4079 int mgmt_ie_buf_len;
4081 u32 del_add_ie_buf_len = 0;
4082 u32 total_ie_buf_len = 0;
4083 u32 parsed_ie_buf_len = 0;
4084 struct parsed_vndr_ies old_vndr_ies;
4085 struct parsed_vndr_ies new_vndr_ies;
4086 struct parsed_vndr_ie_info *vndrie_info;
4089 int remained_buf_len;
4094 saved_ie = &vif->saved_ie;
4096 brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4098 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4101 curr_ie_buf = iovar_ie_buf;
4103 case BRCMF_VNDR_IE_PRBREQ_FLAG:
4104 mgmt_ie_buf = saved_ie->probe_req_ie;
4105 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4106 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4108 case BRCMF_VNDR_IE_PRBRSP_FLAG:
4109 mgmt_ie_buf = saved_ie->probe_res_ie;
4110 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4111 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4113 case BRCMF_VNDR_IE_BEACON_FLAG:
4114 mgmt_ie_buf = saved_ie->beacon_ie;
4115 mgmt_ie_len = &saved_ie->beacon_ie_len;
4116 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4118 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4119 mgmt_ie_buf = saved_ie->assoc_req_ie;
4120 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4121 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4125 brcmf_err("not suitable type\n");
4129 if (vndr_ie_len > mgmt_ie_buf_len) {
4131 brcmf_err("extra IE size too big\n");
4135 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4136 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4138 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4139 for (i = 0; i < new_vndr_ies.count; i++) {
4140 vndrie_info = &new_vndr_ies.ie_info[i];
4141 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4142 vndrie_info->ie_len);
4143 parsed_ie_buf_len += vndrie_info->ie_len;
4147 if (mgmt_ie_buf && *mgmt_ie_len) {
4148 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4149 (memcmp(mgmt_ie_buf, curr_ie_buf,
4150 parsed_ie_buf_len) == 0)) {
4151 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4155 /* parse old vndr_ie */
4156 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4158 /* make a command to delete old ie */
4159 for (i = 0; i < old_vndr_ies.count; i++) {
4160 vndrie_info = &old_vndr_ies.ie_info[i];
4162 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4163 vndrie_info->vndrie.id,
4164 vndrie_info->vndrie.len,
4165 vndrie_info->vndrie.oui[0],
4166 vndrie_info->vndrie.oui[1],
4167 vndrie_info->vndrie.oui[2]);
4169 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4170 vndrie_info->ie_ptr,
4171 vndrie_info->ie_len,
4173 curr_ie_buf += del_add_ie_buf_len;
4174 total_ie_buf_len += del_add_ie_buf_len;
4179 /* Add if there is any extra IE */
4180 if (mgmt_ie_buf && parsed_ie_buf_len) {
4183 remained_buf_len = mgmt_ie_buf_len;
4185 /* make a command to add new ie */
4186 for (i = 0; i < new_vndr_ies.count; i++) {
4187 vndrie_info = &new_vndr_ies.ie_info[i];
4189 /* verify remained buf size before copy data */
4190 if (remained_buf_len < (vndrie_info->vndrie.len +
4191 VNDR_IE_VSIE_OFFSET)) {
4192 brcmf_err("no space in mgmt_ie_buf: len left %d",
4196 remained_buf_len -= (vndrie_info->ie_len +
4197 VNDR_IE_VSIE_OFFSET);
4199 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4200 vndrie_info->vndrie.id,
4201 vndrie_info->vndrie.len,
4202 vndrie_info->vndrie.oui[0],
4203 vndrie_info->vndrie.oui[1],
4204 vndrie_info->vndrie.oui[2]);
4206 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4207 vndrie_info->ie_ptr,
4208 vndrie_info->ie_len,
4211 /* save the parsed IE in wl struct */
4212 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4213 vndrie_info->ie_len);
4214 *mgmt_ie_len += vndrie_info->ie_len;
4216 curr_ie_buf += del_add_ie_buf_len;
4217 total_ie_buf_len += del_add_ie_buf_len;
4220 if (total_ie_buf_len) {
4221 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4224 brcmf_err("vndr ie set error : %d\n", err);
4228 kfree(iovar_ie_buf);
4232 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4235 BRCMF_VNDR_IE_PRBREQ_FLAG,
4236 BRCMF_VNDR_IE_PRBRSP_FLAG,
4237 BRCMF_VNDR_IE_BEACON_FLAG
4241 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4242 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4244 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4249 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4250 struct cfg80211_beacon_data *beacon)
4254 /* Set Beacon IEs to FW */
4255 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4256 beacon->tail, beacon->tail_len);
4258 brcmf_err("Set Beacon IE Failed\n");
4261 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4263 /* Set Probe Response IEs to FW */
4264 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4265 beacon->proberesp_ies,
4266 beacon->proberesp_ies_len);
4268 brcmf_err("Set Probe Resp IE Failed\n");
4270 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4276 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4277 struct cfg80211_ap_settings *settings)
4280 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4281 struct brcmf_if *ifp = netdev_priv(ndev);
4282 const struct brcmf_tlv *ssid_ie;
4283 const struct brcmf_tlv *country_ie;
4284 struct brcmf_ssid_le ssid_le;
4286 const struct brcmf_tlv *rsn_ie;
4287 const struct brcmf_vs_tlv *wpa_ie;
4288 struct brcmf_join_params join_params;
4289 enum nl80211_iftype dev_role;
4290 struct brcmf_fil_bss_enable_le bss_enable;
4295 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4296 settings->chandef.chan->hw_value,
4297 settings->chandef.center_freq1, settings->chandef.width,
4298 settings->beacon_interval, settings->dtim_period);
4299 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4300 settings->ssid, settings->ssid_len, settings->auth_type,
4301 settings->inactivity_timeout);
4302 dev_role = ifp->vif->wdev.iftype;
4303 mbss = ifp->vif->mbss;
4305 /* store current 11d setting */
4306 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4307 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4308 settings->beacon.tail_len,
4310 is_11d = country_ie ? 1 : 0;
4312 memset(&ssid_le, 0, sizeof(ssid_le));
4313 if (settings->ssid == NULL || settings->ssid_len == 0) {
4314 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4315 ssid_ie = brcmf_parse_tlvs(
4316 (u8 *)&settings->beacon.head[ie_offset],
4317 settings->beacon.head_len - ie_offset,
4322 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4323 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4324 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4326 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4327 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4331 brcmf_set_mpc(ifp, 0);
4332 brcmf_configure_arp_offload(ifp, false);
4335 /* find the RSN_IE */
4336 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4337 settings->beacon.tail_len, WLAN_EID_RSN);
4339 /* find the WPA_IE */
4340 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4341 settings->beacon.tail_len);
4343 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4344 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4345 if (wpa_ie != NULL) {
4347 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4351 struct brcmf_vs_tlv *tmp_ie;
4353 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4356 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4361 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4362 brcmf_configure_opensecurity(ifp);
4365 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4368 chanspec = chandef_to_chanspec(&cfg->d11inf,
4369 &settings->chandef);
4370 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4372 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4377 if (is_11d != ifp->vif->is_11d) {
4378 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4381 brcmf_err("Regulatory Set Error, %d\n", err);
4385 if (settings->beacon_interval) {
4386 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4387 settings->beacon_interval);
4389 brcmf_err("Beacon Interval Set Error, %d\n",
4394 if (settings->dtim_period) {
4395 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4396 settings->dtim_period);
4398 brcmf_err("DTIM Interval Set Error, %d\n", err);
4403 if ((dev_role == NL80211_IFTYPE_AP) &&
4404 ((ifp->ifidx == 0) ||
4405 !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
4406 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4408 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4411 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4414 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4416 brcmf_err("SET INFRA error %d\n", err);
4419 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4420 /* Multiple-BSS should use same 11d configuration */
4424 if (dev_role == NL80211_IFTYPE_AP) {
4425 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4426 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4428 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4430 brcmf_err("setting AP mode failed %d\n", err);
4433 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4435 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4438 /* On DOWN the firmware removes the WEP keys, reconfigure
4439 * them if they were set.
4441 brcmf_cfg80211_reconfigure_wep(ifp);
4443 memset(&join_params, 0, sizeof(join_params));
4444 /* join parameters starts with ssid */
4445 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4447 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4448 &join_params, sizeof(join_params));
4450 brcmf_err("SET SSID error (%d)\n", err);
4453 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4455 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4458 brcmf_err("setting ssid failed %d\n", err);
4461 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4462 bss_enable.enable = cpu_to_le32(1);
4463 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4464 sizeof(bss_enable));
4466 brcmf_err("bss_enable config failed %d\n", err);
4470 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4472 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4473 brcmf_net_setcarrier(ifp, true);
4476 if ((err) && (!mbss)) {
4477 brcmf_set_mpc(ifp, 1);
4478 brcmf_configure_arp_offload(ifp, true);
4483 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4485 struct brcmf_if *ifp = netdev_priv(ndev);
4487 struct brcmf_fil_bss_enable_le bss_enable;
4488 struct brcmf_join_params join_params;
4490 brcmf_dbg(TRACE, "Enter\n");
4492 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4493 /* Due to most likely deauths outstanding we sleep */
4494 /* first to make sure they get processed by fw. */
4497 if (ifp->vif->mbss) {
4498 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4502 memset(&join_params, 0, sizeof(join_params));
4503 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4504 &join_params, sizeof(join_params));
4506 brcmf_err("SET SSID error (%d)\n", err);
4507 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4509 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4510 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4512 brcmf_err("setting AP mode failed %d\n", err);
4513 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4515 brcmf_err("setting INFRA mode failed %d\n", err);
4516 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4517 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4518 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4521 brcmf_err("restoring REGULATORY setting failed %d\n",
4523 /* Bring device back up so it can be used again */
4524 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4526 brcmf_err("BRCMF_C_UP error %d\n", err);
4528 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4529 bss_enable.enable = cpu_to_le32(0);
4530 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4531 sizeof(bss_enable));
4533 brcmf_err("bss_enable config failed %d\n", err);
4535 brcmf_set_mpc(ifp, 1);
4536 brcmf_configure_arp_offload(ifp, true);
4537 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4538 brcmf_net_setcarrier(ifp, false);
4544 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4545 struct cfg80211_beacon_data *info)
4547 struct brcmf_if *ifp = netdev_priv(ndev);
4550 brcmf_dbg(TRACE, "Enter\n");
4552 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4558 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4559 struct station_del_parameters *params)
4561 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4562 struct brcmf_scb_val_le scbval;
4563 struct brcmf_if *ifp = netdev_priv(ndev);
4569 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4571 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4572 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4573 if (!check_vif_up(ifp->vif))
4576 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4577 scbval.val = cpu_to_le32(params->reason_code);
4578 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4579 &scbval, sizeof(scbval));
4581 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4583 brcmf_dbg(TRACE, "Exit\n");
4588 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4589 const u8 *mac, struct station_parameters *params)
4591 struct brcmf_if *ifp = netdev_priv(ndev);
4594 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4595 params->sta_flags_mask, params->sta_flags_set);
4597 /* Ignore all 00 MAC */
4598 if (is_zero_ether_addr(mac))
4601 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4604 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4605 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4606 (void *)mac, ETH_ALEN);
4608 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4609 (void *)mac, ETH_ALEN);
4611 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4617 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4618 struct wireless_dev *wdev,
4619 u16 frame_type, bool reg)
4621 struct brcmf_cfg80211_vif *vif;
4624 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4626 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4627 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4629 vif->mgmt_rx_reg |= BIT(mgmt_type);
4631 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4636 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4637 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4639 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4640 struct ieee80211_channel *chan = params->chan;
4641 const u8 *buf = params->buf;
4642 size_t len = params->len;
4643 const struct ieee80211_mgmt *mgmt;
4644 struct brcmf_cfg80211_vif *vif;
4648 struct brcmf_fil_action_frame_le *action_frame;
4649 struct brcmf_fil_af_params_le *af_params;
4654 brcmf_dbg(TRACE, "Enter\n");
4658 mgmt = (const struct ieee80211_mgmt *)buf;
4660 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4661 brcmf_err("Driver only allows MGMT packet type\n");
4665 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4667 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4668 /* Right now the only reason to get a probe response */
4669 /* is for p2p listen response or for p2p GO from */
4670 /* wpa_supplicant. Unfortunately the probe is send */
4671 /* on primary ndev, while dongle wants it on the p2p */
4672 /* vif. Since this is only reason for a probe */
4673 /* response to be sent, the vif is taken from cfg. */
4674 /* If ever desired to send proberesp for non p2p */
4675 /* response then data should be checked for */
4676 /* "DIRECT-". Note in future supplicant will take */
4677 /* dedicated p2p wdev to do this and then this 'hack'*/
4678 /* is not needed anymore. */
4679 ie_offset = DOT11_MGMT_HDR_LEN +
4680 DOT11_BCN_PRB_FIXED_LEN;
4681 ie_len = len - ie_offset;
4682 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4683 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4684 err = brcmf_vif_set_mgmt_ie(vif,
4685 BRCMF_VNDR_IE_PRBRSP_FLAG,
4688 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4690 } else if (ieee80211_is_action(mgmt->frame_control)) {
4691 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4692 if (af_params == NULL) {
4693 brcmf_err("unable to allocate frame\n");
4697 action_frame = &af_params->action_frame;
4698 /* Add the packet Id */
4699 action_frame->packet_id = cpu_to_le32(*cookie);
4701 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4702 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4703 /* Add the length exepted for 802.11 header */
4704 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4705 /* Add the channel. Use the one specified as parameter if any or
4706 * the current one (got from the firmware) otherwise
4709 freq = chan->center_freq;
4711 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4713 chan_nr = ieee80211_frequency_to_channel(freq);
4714 af_params->channel = cpu_to_le32(chan_nr);
4716 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4717 le16_to_cpu(action_frame->len));
4719 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4720 *cookie, le16_to_cpu(action_frame->len), freq);
4722 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4725 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4729 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4730 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4739 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4740 struct wireless_dev *wdev,
4743 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4744 struct brcmf_cfg80211_vif *vif;
4747 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4749 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4751 brcmf_err("No p2p device available for probe response\n");
4755 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4760 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4761 struct wireless_dev *wdev,
4762 enum nl80211_crit_proto_id proto,
4765 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4766 struct brcmf_cfg80211_vif *vif;
4768 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4770 /* only DHCP support for now */
4771 if (proto != NL80211_CRIT_PROTO_DHCP)
4774 /* suppress and abort scanning */
4775 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4776 brcmf_abort_scanning(cfg);
4778 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4781 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4782 struct wireless_dev *wdev)
4784 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4785 struct brcmf_cfg80211_vif *vif;
4787 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4789 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4790 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4794 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4795 const struct brcmf_event_msg *e, void *data)
4797 switch (e->reason) {
4798 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4799 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4801 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4802 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4803 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4805 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4806 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4807 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4814 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4819 case NL80211_TDLS_DISCOVERY_REQ:
4820 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4822 case NL80211_TDLS_SETUP:
4823 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4825 case NL80211_TDLS_TEARDOWN:
4826 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4829 brcmf_err("unsupported operation: %d\n", oper);
4835 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4836 struct net_device *ndev, const u8 *peer,
4837 enum nl80211_tdls_operation oper)
4839 struct brcmf_if *ifp;
4840 struct brcmf_tdls_iovar_le info;
4843 ret = brcmf_convert_nl80211_tdls_oper(oper);
4847 ifp = netdev_priv(ndev);
4848 memset(&info, 0, sizeof(info));
4849 info.mode = (u8)ret;
4851 memcpy(info.ea, peer, ETH_ALEN);
4853 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4854 &info, sizeof(info));
4856 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4861 static struct cfg80211_ops wl_cfg80211_ops = {
4862 .add_virtual_intf = brcmf_cfg80211_add_iface,
4863 .del_virtual_intf = brcmf_cfg80211_del_iface,
4864 .change_virtual_intf = brcmf_cfg80211_change_iface,
4865 .scan = brcmf_cfg80211_scan,
4866 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4867 .join_ibss = brcmf_cfg80211_join_ibss,
4868 .leave_ibss = brcmf_cfg80211_leave_ibss,
4869 .get_station = brcmf_cfg80211_get_station,
4870 .dump_station = brcmf_cfg80211_dump_station,
4871 .set_tx_power = brcmf_cfg80211_set_tx_power,
4872 .get_tx_power = brcmf_cfg80211_get_tx_power,
4873 .add_key = brcmf_cfg80211_add_key,
4874 .del_key = brcmf_cfg80211_del_key,
4875 .get_key = brcmf_cfg80211_get_key,
4876 .set_default_key = brcmf_cfg80211_config_default_key,
4877 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4878 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4879 .connect = brcmf_cfg80211_connect,
4880 .disconnect = brcmf_cfg80211_disconnect,
4881 .suspend = brcmf_cfg80211_suspend,
4882 .resume = brcmf_cfg80211_resume,
4883 .set_pmksa = brcmf_cfg80211_set_pmksa,
4884 .del_pmksa = brcmf_cfg80211_del_pmksa,
4885 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4886 .start_ap = brcmf_cfg80211_start_ap,
4887 .stop_ap = brcmf_cfg80211_stop_ap,
4888 .change_beacon = brcmf_cfg80211_change_beacon,
4889 .del_station = brcmf_cfg80211_del_station,
4890 .change_station = brcmf_cfg80211_change_station,
4891 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4892 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4893 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4894 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4895 .remain_on_channel = brcmf_p2p_remain_on_channel,
4896 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4897 .start_p2p_device = brcmf_p2p_start_device,
4898 .stop_p2p_device = brcmf_p2p_stop_device,
4899 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4900 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4901 .tdls_oper = brcmf_cfg80211_tdls_oper,
4904 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4905 enum nl80211_iftype type,
4908 struct brcmf_cfg80211_vif *vif_walk;
4909 struct brcmf_cfg80211_vif *vif;
4912 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4914 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4916 return ERR_PTR(-ENOMEM);
4918 vif->wdev.wiphy = cfg->wiphy;
4919 vif->wdev.iftype = type;
4921 vif->pm_block = pm_block;
4923 brcmf_init_prof(&vif->profile);
4925 if (type == NL80211_IFTYPE_AP) {
4927 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4928 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4936 list_add_tail(&vif->list, &cfg->vif_list);
4940 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4942 list_del(&vif->list);
4946 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4948 struct brcmf_cfg80211_vif *vif;
4949 struct brcmf_if *ifp;
4951 ifp = netdev_priv(ndev);
4955 brcmf_free_vif(vif);
4959 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4961 u32 event = e->event_code;
4962 u32 status = e->status;
4964 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4965 brcmf_dbg(CONN, "Processing set ssid\n");
4972 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4974 u32 event = e->event_code;
4975 u16 flags = e->flags;
4977 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4978 (event == BRCMF_E_DISASSOC_IND) ||
4979 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4980 brcmf_dbg(CONN, "Processing link down\n");
4986 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4987 const struct brcmf_event_msg *e)
4989 u32 event = e->event_code;
4990 u32 status = e->status;
4992 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4993 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4994 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4998 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4999 brcmf_dbg(CONN, "Processing connecting & no network found\n");
5006 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
5008 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5010 kfree(conn_info->req_ie);
5011 conn_info->req_ie = NULL;
5012 conn_info->req_ie_len = 0;
5013 kfree(conn_info->resp_ie);
5014 conn_info->resp_ie = NULL;
5015 conn_info->resp_ie_len = 0;
5018 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
5019 struct brcmf_if *ifp)
5021 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
5022 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5027 brcmf_clear_assoc_ies(cfg);
5029 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5030 cfg->extra_buf, WL_ASSOC_INFO_MAX);
5032 brcmf_err("could not get assoc info (%d)\n", err);
5036 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5037 req_len = le32_to_cpu(assoc_info->req_len);
5038 resp_len = le32_to_cpu(assoc_info->resp_len);
5040 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5044 brcmf_err("could not get assoc req (%d)\n", err);
5047 conn_info->req_ie_len = req_len;
5049 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5052 conn_info->req_ie_len = 0;
5053 conn_info->req_ie = NULL;
5056 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5060 brcmf_err("could not get assoc resp (%d)\n", err);
5063 conn_info->resp_ie_len = resp_len;
5064 conn_info->resp_ie =
5065 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5068 conn_info->resp_ie_len = 0;
5069 conn_info->resp_ie = NULL;
5071 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5072 conn_info->req_ie_len, conn_info->resp_ie_len);
5078 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5079 struct net_device *ndev,
5080 const struct brcmf_event_msg *e)
5082 struct brcmf_if *ifp = netdev_priv(ndev);
5083 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5084 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5085 struct wiphy *wiphy = cfg_to_wiphy(cfg);
5086 struct ieee80211_channel *notify_channel = NULL;
5087 struct ieee80211_supported_band *band;
5088 struct brcmf_bss_info_le *bi;
5089 struct brcmu_chan ch;
5094 brcmf_dbg(TRACE, "Enter\n");
5096 brcmf_get_assoc_ies(cfg, ifp);
5097 memcpy(profile->bssid, e->addr, ETH_ALEN);
5098 brcmf_update_bss_info(cfg, ifp);
5100 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5106 /* data sent to dongle has to be little endian */
5107 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5108 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
5109 buf, WL_BSS_INFO_MAX);
5114 bi = (struct brcmf_bss_info_le *)(buf + 4);
5115 ch.chspec = le16_to_cpu(bi->chanspec);
5116 cfg->d11inf.decchspec(&ch);
5118 if (ch.band == BRCMU_CHAN_BAND_2G)
5119 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5121 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5123 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
5124 notify_channel = ieee80211_get_channel(wiphy, freq);
5128 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
5129 conn_info->req_ie, conn_info->req_ie_len,
5130 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
5131 brcmf_dbg(CONN, "Report roaming result\n");
5133 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
5134 brcmf_dbg(TRACE, "Exit\n");
5139 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
5140 struct net_device *ndev, const struct brcmf_event_msg *e,
5143 struct brcmf_if *ifp = netdev_priv(ndev);
5144 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5145 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5147 brcmf_dbg(TRACE, "Enter\n");
5149 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5150 &ifp->vif->sme_state)) {
5152 brcmf_get_assoc_ies(cfg, ifp);
5153 memcpy(profile->bssid, e->addr, ETH_ALEN);
5154 brcmf_update_bss_info(cfg, ifp);
5155 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5156 &ifp->vif->sme_state);
5158 cfg80211_connect_result(ndev,
5159 (u8 *)profile->bssid,
5161 conn_info->req_ie_len,
5163 conn_info->resp_ie_len,
5164 completed ? WLAN_STATUS_SUCCESS :
5165 WLAN_STATUS_AUTH_TIMEOUT,
5167 brcmf_dbg(CONN, "Report connect result - connection %s\n",
5168 completed ? "succeeded" : "failed");
5170 brcmf_dbg(TRACE, "Exit\n");
5175 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
5176 struct net_device *ndev,
5177 const struct brcmf_event_msg *e, void *data)
5179 struct brcmf_if *ifp = netdev_priv(ndev);
5180 static int generation;
5181 u32 event = e->event_code;
5182 u32 reason = e->reason;
5183 struct station_info sinfo;
5185 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
5186 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5187 ndev != cfg_to_ndev(cfg)) {
5188 brcmf_dbg(CONN, "AP mode link down\n");
5189 complete(&cfg->vif_disabled);
5191 brcmf_remove_interface(ifp);
5195 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5196 (reason == BRCMF_E_STATUS_SUCCESS)) {
5197 memset(&sinfo, 0, sizeof(sinfo));
5199 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5202 sinfo.assoc_req_ies = data;
5203 sinfo.assoc_req_ies_len = e->datalen;
5205 sinfo.generation = generation;
5206 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5207 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5208 (event == BRCMF_E_DEAUTH_IND) ||
5209 (event == BRCMF_E_DEAUTH)) {
5210 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5216 brcmf_notify_connect_status(struct brcmf_if *ifp,
5217 const struct brcmf_event_msg *e, void *data)
5219 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5220 struct net_device *ndev = ifp->ndev;
5221 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5222 struct ieee80211_channel *chan;
5225 if ((e->event_code == BRCMF_E_DEAUTH) ||
5226 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5227 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5228 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5229 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5232 if (brcmf_is_apmode(ifp->vif)) {
5233 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5234 } else if (brcmf_is_linkup(e)) {
5235 brcmf_dbg(CONN, "Linkup\n");
5236 if (brcmf_is_ibssmode(ifp->vif)) {
5237 brcmf_inform_ibss(cfg, ndev, e->addr);
5238 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5239 memcpy(profile->bssid, e->addr, ETH_ALEN);
5240 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5241 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5242 &ifp->vif->sme_state);
5243 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5244 &ifp->vif->sme_state);
5246 brcmf_bss_connect_done(cfg, ndev, e, true);
5247 brcmf_net_setcarrier(ifp, true);
5248 } else if (brcmf_is_linkdown(e)) {
5249 brcmf_dbg(CONN, "Linkdown\n");
5250 if (!brcmf_is_ibssmode(ifp->vif)) {
5251 brcmf_bss_connect_done(cfg, ndev, e, false);
5252 brcmf_link_down(ifp->vif,
5253 brcmf_map_fw_linkdown_reason(e));
5254 brcmf_init_prof(ndev_to_prof(ndev));
5255 if (ndev != cfg_to_ndev(cfg))
5256 complete(&cfg->vif_disabled);
5257 brcmf_net_setcarrier(ifp, false);
5259 } else if (brcmf_is_nonetwork(cfg, e)) {
5260 if (brcmf_is_ibssmode(ifp->vif))
5261 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5262 &ifp->vif->sme_state);
5264 brcmf_bss_connect_done(cfg, ndev, e, false);
5271 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5272 const struct brcmf_event_msg *e, void *data)
5274 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5275 u32 event = e->event_code;
5276 u32 status = e->status;
5278 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5279 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5280 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5282 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5289 brcmf_notify_mic_status(struct brcmf_if *ifp,
5290 const struct brcmf_event_msg *e, void *data)
5292 u16 flags = e->flags;
5293 enum nl80211_key_type key_type;
5295 if (flags & BRCMF_EVENT_MSG_GROUP)
5296 key_type = NL80211_KEYTYPE_GROUP;
5298 key_type = NL80211_KEYTYPE_PAIRWISE;
5300 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5306 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5307 const struct brcmf_event_msg *e, void *data)
5309 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5310 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5311 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5312 struct brcmf_cfg80211_vif *vif;
5314 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5315 ifevent->action, ifevent->flags, ifevent->ifidx,
5316 ifevent->bsscfgidx);
5318 mutex_lock(&event->vif_event_lock);
5319 event->action = ifevent->action;
5322 switch (ifevent->action) {
5323 case BRCMF_E_IF_ADD:
5324 /* waiting process may have timed out */
5325 if (!cfg->vif_event.vif) {
5326 mutex_unlock(&event->vif_event_lock);
5333 vif->wdev.netdev = ifp->ndev;
5334 ifp->ndev->ieee80211_ptr = &vif->wdev;
5335 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5337 mutex_unlock(&event->vif_event_lock);
5338 wake_up(&event->vif_wq);
5341 case BRCMF_E_IF_DEL:
5342 mutex_unlock(&event->vif_event_lock);
5343 /* event may not be upon user request */
5344 if (brcmf_cfg80211_vif_event_armed(cfg))
5345 wake_up(&event->vif_wq);
5348 case BRCMF_E_IF_CHANGE:
5349 mutex_unlock(&event->vif_event_lock);
5350 wake_up(&event->vif_wq);
5354 mutex_unlock(&event->vif_event_lock);
5360 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5362 conf->frag_threshold = (u32)-1;
5363 conf->rts_threshold = (u32)-1;
5364 conf->retry_short = (u32)-1;
5365 conf->retry_long = (u32)-1;
5368 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5370 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5371 brcmf_notify_connect_status);
5372 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5373 brcmf_notify_connect_status);
5374 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5375 brcmf_notify_connect_status);
5376 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5377 brcmf_notify_connect_status);
5378 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5379 brcmf_notify_connect_status);
5380 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5381 brcmf_notify_connect_status);
5382 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5383 brcmf_notify_roaming_status);
5384 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5385 brcmf_notify_mic_status);
5386 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5387 brcmf_notify_connect_status);
5388 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5389 brcmf_notify_sched_scan_results);
5390 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5391 brcmf_notify_vif_event);
5392 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5393 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5394 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5395 brcmf_p2p_notify_listen_complete);
5396 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5397 brcmf_p2p_notify_action_frame_rx);
5398 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5399 brcmf_p2p_notify_action_tx_complete);
5400 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5401 brcmf_p2p_notify_action_tx_complete);
5404 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5408 kfree(cfg->escan_ioctl_buf);
5409 cfg->escan_ioctl_buf = NULL;
5410 kfree(cfg->extra_buf);
5411 cfg->extra_buf = NULL;
5412 kfree(cfg->wowl.nd);
5413 cfg->wowl.nd = NULL;
5414 kfree(cfg->wowl.nd_info);
5415 cfg->wowl.nd_info = NULL;
5418 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5420 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5422 goto init_priv_mem_out;
5423 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5424 if (!cfg->escan_ioctl_buf)
5425 goto init_priv_mem_out;
5426 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5427 if (!cfg->extra_buf)
5428 goto init_priv_mem_out;
5429 cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
5431 goto init_priv_mem_out;
5432 cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
5433 sizeof(struct cfg80211_wowlan_nd_match *),
5435 if (!cfg->wowl.nd_info)
5436 goto init_priv_mem_out;
5441 brcmf_deinit_priv_mem(cfg);
5446 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5450 cfg->scan_request = NULL;
5451 cfg->pwr_save = true;
5452 cfg->active_scan = true; /* we do active scan per default */
5453 cfg->dongle_up = false; /* dongle is not up yet */
5454 err = brcmf_init_priv_mem(cfg);
5457 brcmf_register_event_handlers(cfg);
5458 mutex_init(&cfg->usr_sync);
5459 brcmf_init_escan(cfg);
5460 brcmf_init_conf(cfg->conf);
5461 init_completion(&cfg->vif_disabled);
5465 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5467 cfg->dongle_up = false; /* dongle down */
5468 brcmf_abort_scanning(cfg);
5469 brcmf_deinit_priv_mem(cfg);
5472 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5474 init_waitqueue_head(&event->vif_wq);
5475 mutex_init(&event->vif_event_lock);
5478 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
5482 __le32 roamtrigger[2];
5483 __le32 roam_delta[2];
5485 /* Configure beacon timeout value based upon roaming setting */
5486 if (ifp->drvr->settings->roamoff)
5487 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
5489 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
5490 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5492 brcmf_err("bcn_timeout error (%d)\n", err);
5493 goto roam_setup_done;
5496 /* Enable/Disable built-in roaming to allow supplicant to take care of
5499 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5500 ifp->drvr->settings->roamoff ? "Off" : "On");
5501 err = brcmf_fil_iovar_int_set(ifp, "roam_off",
5502 ifp->drvr->settings->roamoff);
5504 brcmf_err("roam_off error (%d)\n", err);
5505 goto roam_setup_done;
5508 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5509 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5510 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5511 (void *)roamtrigger, sizeof(roamtrigger));
5513 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5514 goto roam_setup_done;
5517 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5518 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5519 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5520 (void *)roam_delta, sizeof(roam_delta));
5522 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5523 goto roam_setup_done;
5531 brcmf_dongle_scantime(struct brcmf_if *ifp)
5535 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5536 BRCMF_SCAN_CHANNEL_TIME);
5538 brcmf_err("Scan assoc time error (%d)\n", err);
5539 goto dongle_scantime_out;
5541 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5542 BRCMF_SCAN_UNASSOC_TIME);
5544 brcmf_err("Scan unassoc time error (%d)\n", err);
5545 goto dongle_scantime_out;
5548 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5549 BRCMF_SCAN_PASSIVE_TIME);
5551 brcmf_err("Scan passive time error (%d)\n", err);
5552 goto dongle_scantime_out;
5555 dongle_scantime_out:
5559 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5560 struct brcmu_chan *ch)
5564 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5565 if (ch->sb == BRCMU_CHAN_SB_U) {
5566 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5567 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5568 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5570 /* It should be one of
5571 * IEEE80211_CHAN_NO_HT40 or
5572 * IEEE80211_CHAN_NO_HT40PLUS
5574 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5575 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5576 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5580 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5583 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5584 struct ieee80211_supported_band *band;
5585 struct ieee80211_channel *channel;
5586 struct wiphy *wiphy;
5587 struct brcmf_chanspec_list *list;
5588 struct brcmu_chan ch;
5596 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5601 list = (struct brcmf_chanspec_list *)pbuf;
5603 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5606 brcmf_err("get chanspecs error (%d)\n", err);
5610 wiphy = cfg_to_wiphy(cfg);
5611 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5613 for (i = 0; i < band->n_channels; i++)
5614 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5615 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5617 for (i = 0; i < band->n_channels; i++)
5618 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5620 total = le32_to_cpu(list->count);
5621 for (i = 0; i < total; i++) {
5622 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5623 cfg->d11inf.decchspec(&ch);
5625 if (ch.band == BRCMU_CHAN_BAND_2G) {
5626 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5627 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5628 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5630 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5635 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5636 ch.bw == BRCMU_CHAN_BW_40)
5638 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5639 ch.bw == BRCMU_CHAN_BW_80)
5642 channel = band->channels;
5643 index = band->n_channels;
5644 for (j = 0; j < band->n_channels; j++) {
5645 if (channel[j].hw_value == ch.chnum) {
5650 channel[index].center_freq =
5651 ieee80211_channel_to_frequency(ch.chnum, band->band);
5652 channel[index].hw_value = ch.chnum;
5654 /* assuming the chanspecs order is HT20,
5655 * HT40 upper, HT40 lower, and VHT80.
5657 if (ch.bw == BRCMU_CHAN_BW_80) {
5658 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5659 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5660 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5662 /* enable the channel and disable other bandwidths
5663 * for now as mentioned order assure they are enabled
5664 * for subsequent chanspecs.
5666 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5667 IEEE80211_CHAN_NO_80MHZ;
5668 ch.bw = BRCMU_CHAN_BW_20;
5669 cfg->d11inf.encchspec(&ch);
5670 chaninfo = ch.chspec;
5671 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5674 if (chaninfo & WL_CHAN_RADAR)
5675 channel[index].flags |=
5676 (IEEE80211_CHAN_RADAR |
5677 IEEE80211_CHAN_NO_IR);
5678 if (chaninfo & WL_CHAN_PASSIVE)
5679 channel[index].flags |=
5680 IEEE80211_CHAN_NO_IR;
5690 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5692 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5693 struct ieee80211_supported_band *band;
5694 struct brcmf_fil_bwcap_le band_bwcap;
5695 struct brcmf_chanspec_list *list;
5699 struct brcmu_chan ch;
5703 /* verify support for bw_cap command */
5705 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5708 /* only set 2G bandwidth using bw_cap command */
5709 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5710 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5711 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5712 sizeof(band_bwcap));
5714 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5715 val = WLC_N_BW_40ALL;
5716 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5720 /* update channel info in 2G band */
5721 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5726 ch.band = BRCMU_CHAN_BAND_2G;
5727 ch.bw = BRCMU_CHAN_BW_40;
5728 ch.sb = BRCMU_CHAN_SB_NONE;
5730 cfg->d11inf.encchspec(&ch);
5732 /* pass encoded chanspec in query */
5733 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5735 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5738 brcmf_err("get chanspecs error (%d)\n", err);
5743 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5744 list = (struct brcmf_chanspec_list *)pbuf;
5745 num_chan = le32_to_cpu(list->count);
5746 for (i = 0; i < num_chan; i++) {
5747 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5748 cfg->d11inf.decchspec(&ch);
5749 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5751 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5753 for (j = 0; j < band->n_channels; j++) {
5754 if (band->channels[j].hw_value == ch.chnum)
5757 if (WARN_ON(j == band->n_channels))
5760 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5767 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5769 u32 band, mimo_bwcap;
5773 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5775 bw_cap[IEEE80211_BAND_2GHZ] = band;
5777 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5779 bw_cap[IEEE80211_BAND_5GHZ] = band;
5785 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5787 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5789 /* assume 20MHz if firmware does not give a clue */
5790 mimo_bwcap = WLC_N_BW_20ALL;
5792 switch (mimo_bwcap) {
5793 case WLC_N_BW_40ALL:
5794 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5796 case WLC_N_BW_20IN2G_40IN5G:
5797 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5799 case WLC_N_BW_20ALL:
5800 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5801 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5804 brcmf_err("invalid mimo_bw_cap value\n");
5808 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5809 u32 bw_cap[2], u32 nchain)
5811 band->ht_cap.ht_supported = true;
5812 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5813 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5814 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5816 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5817 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5818 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5819 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5820 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5821 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5824 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5829 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5830 mcs_map = (mcs_map << 2) | supp;
5832 return cpu_to_le16(mcs_map);
5835 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5836 u32 bw_cap[2], u32 nchain, u32 txstreams,
5837 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
5841 /* not allowed in 2.4G band */
5842 if (band->band == IEEE80211_BAND_2GHZ)
5845 band->vht_cap.vht_supported = true;
5846 /* 80MHz is mandatory */
5847 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5848 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5849 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5850 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5852 /* all support 256-QAM */
5853 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5854 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5855 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5857 /* Beamforming support information */
5858 if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
5859 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
5860 if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
5861 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
5862 if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
5863 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
5864 if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
5865 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
5867 if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
5868 band->vht_cap.cap |=
5869 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
5870 band->vht_cap.cap |= ((txstreams - 1) <<
5871 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
5872 band->vht_cap.cap |=
5873 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
5877 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5879 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5880 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5883 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5888 struct ieee80211_supported_band *band;
5890 u32 txbf_bfe_cap = 0;
5891 u32 txbf_bfr_cap = 0;
5893 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5894 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5896 brcmf_err("nmode error (%d)\n", err);
5898 brcmf_get_bwcap(ifp, bw_cap);
5900 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5901 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5902 bw_cap[IEEE80211_BAND_5GHZ]);
5904 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5906 brcmf_err("rxchain error (%d)\n", err);
5909 for (nchain = 0; rxchain; nchain++)
5910 rxchain = rxchain & (rxchain - 1);
5912 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5914 err = brcmf_construct_chaninfo(cfg, bw_cap);
5916 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5921 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
5922 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
5924 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
5928 wiphy = cfg_to_wiphy(cfg);
5929 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5930 band = wiphy->bands[i];
5935 brcmf_update_ht_cap(band, bw_cap, nchain);
5937 brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
5938 txbf_bfe_cap, txbf_bfr_cap);
5944 static const struct ieee80211_txrx_stypes
5945 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5946 [NL80211_IFTYPE_STATION] = {
5948 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5949 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5951 [NL80211_IFTYPE_P2P_CLIENT] = {
5953 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5954 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5956 [NL80211_IFTYPE_P2P_GO] = {
5958 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5959 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5960 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5961 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5962 BIT(IEEE80211_STYPE_AUTH >> 4) |
5963 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5964 BIT(IEEE80211_STYPE_ACTION >> 4)
5966 [NL80211_IFTYPE_P2P_DEVICE] = {
5968 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5969 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5974 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5976 * @wiphy: wiphy object.
5977 * @ifp: interface object needed for feat module api.
5979 * The interface modes and combinations are determined dynamically here
5980 * based on firmware functionality.
5982 * no p2p and no mbss:
5984 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5988 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5989 * #AP <= 4, matching BI, channels = 1, 4 total
5991 * p2p, no mchan, and mbss:
5993 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
5994 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5995 * #AP <= 4, matching BI, channels = 1, 4 total
5997 * p2p, mchan, and mbss:
5999 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6000 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6001 * #AP <= 4, matching BI, channels = 1, 4 total
6003 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
6005 struct ieee80211_iface_combination *combo = NULL;
6006 struct ieee80211_iface_limit *c0_limits = NULL;
6007 struct ieee80211_iface_limit *p2p_limits = NULL;
6008 struct ieee80211_iface_limit *mbss_limits = NULL;
6012 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
6013 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
6015 n_combos = 1 + !!p2p + !!mbss;
6016 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
6020 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
6025 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
6031 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
6036 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6037 BIT(NL80211_IFTYPE_ADHOC) |
6038 BIT(NL80211_IFTYPE_AP);
6042 combo[c].num_different_channels = 1;
6043 c0_limits[i].max = 1;
6044 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6046 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
6047 combo[c].num_different_channels = 2;
6048 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
6049 BIT(NL80211_IFTYPE_P2P_GO) |
6050 BIT(NL80211_IFTYPE_P2P_DEVICE);
6051 c0_limits[i].max = 1;
6052 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6053 c0_limits[i].max = 1;
6054 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
6055 BIT(NL80211_IFTYPE_P2P_GO);
6057 c0_limits[i].max = 1;
6058 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6060 combo[c].max_interfaces = i;
6061 combo[c].n_limits = i;
6062 combo[c].limits = c0_limits;
6067 combo[c].num_different_channels = 1;
6068 p2p_limits[i].max = 1;
6069 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6070 p2p_limits[i].max = 1;
6071 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6072 p2p_limits[i].max = 1;
6073 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
6074 p2p_limits[i].max = 1;
6075 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6076 combo[c].max_interfaces = i;
6077 combo[c].n_limits = i;
6078 combo[c].limits = p2p_limits;
6083 combo[c].beacon_int_infra_match = true;
6084 combo[c].num_different_channels = 1;
6085 mbss_limits[0].max = 4;
6086 mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
6087 combo[c].max_interfaces = 4;
6088 combo[c].n_limits = 1;
6089 combo[c].limits = mbss_limits;
6091 wiphy->n_iface_combinations = n_combos;
6092 wiphy->iface_combinations = combo;
6103 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
6105 /* scheduled scan settings */
6106 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
6107 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6108 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6109 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6113 static struct wiphy_wowlan_support brcmf_wowlan_support = {
6114 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
6115 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
6116 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
6117 .pattern_min_len = 1,
6118 .max_pkt_offset = 1500,
6122 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6125 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6129 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6130 err = brcmf_fil_iovar_int_get(ifp, "wowl_cap", &wowl_cap);
6132 if (wowl_cap & BRCMF_WOWL_PFN_FOUND) {
6133 brcmf_wowlan_support.flags |=
6134 WIPHY_WOWLAN_NET_DETECT;
6135 init_waitqueue_head(&cfg->wowl.nd_data_wait);
6139 wiphy->wowlan = &brcmf_wowlan_support;
6143 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6145 struct brcmf_pub *drvr = ifp->drvr;
6146 const struct ieee80211_iface_combination *combo;
6147 struct ieee80211_supported_band *band;
6148 u16 max_interfaces = 0;
6153 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
6154 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6155 wiphy->max_num_pmkids = BRCMF_MAXPMKID;
6157 err = brcmf_setup_ifmodes(wiphy, ifp);
6161 for (i = 0, combo = wiphy->iface_combinations;
6162 i < wiphy->n_iface_combinations; i++, combo++) {
6163 max_interfaces = max(max_interfaces, combo->max_interfaces);
6166 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
6168 u8 *addr = drvr->addresses[i].addr;
6170 memcpy(addr, drvr->mac, ETH_ALEN);
6173 addr[ETH_ALEN - 1] ^= i;
6176 wiphy->addresses = drvr->addresses;
6177 wiphy->n_addresses = i;
6179 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6180 wiphy->cipher_suites = __wl_cipher_suites;
6181 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
6182 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
6183 WIPHY_FLAG_OFFCHAN_TX |
6184 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6185 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
6186 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6187 if (!ifp->drvr->settings->roamoff)
6188 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6189 wiphy->mgmt_stypes = brcmf_txrx_stypes;
6190 wiphy->max_remain_on_channel_duration = 5000;
6191 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
6192 brcmf_wiphy_pno_params(wiphy);
6194 /* vendor commands/events support */
6195 wiphy->vendor_commands = brcmf_vendor_cmds;
6196 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
6198 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
6199 brcmf_wiphy_wowl_params(wiphy, ifp);
6200 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
6203 brcmf_err("could not obtain band info: err=%d\n", err);
6206 /* first entry in bandlist is number of bands */
6207 n_bands = le32_to_cpu(bandlist[0]);
6208 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
6209 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
6210 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
6215 band->channels = kmemdup(&__wl_2ghz_channels,
6216 sizeof(__wl_2ghz_channels),
6218 if (!band->channels) {
6223 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6224 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
6226 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6227 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6232 band->channels = kmemdup(&__wl_5ghz_channels,
6233 sizeof(__wl_5ghz_channels),
6235 if (!band->channels) {
6240 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6241 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6244 err = brcmf_setup_wiphybands(wiphy);
6248 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6250 struct net_device *ndev;
6251 struct wireless_dev *wdev;
6252 struct brcmf_if *ifp;
6259 ndev = cfg_to_ndev(cfg);
6260 wdev = ndev->ieee80211_ptr;
6261 ifp = netdev_priv(ndev);
6263 /* make sure RF is ready for work */
6264 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6266 brcmf_dongle_scantime(ifp);
6268 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6269 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6271 goto default_conf_out;
6272 brcmf_dbg(INFO, "power save set to %s\n",
6273 (power_mode ? "enabled" : "disabled"));
6275 err = brcmf_dongle_roam(ifp);
6277 goto default_conf_out;
6278 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6281 goto default_conf_out;
6283 brcmf_configure_arp_offload(ifp, true);
6285 cfg->dongle_up = true;
6292 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6294 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6296 return brcmf_config_dongle(ifp->drvr->config);
6299 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6301 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6304 * While going down, if associated with AP disassociate
6305 * from AP to save power
6307 if (check_vif_up(ifp->vif)) {
6308 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6310 /* Make sure WPA_Supplicant receives all the event
6311 generated due to DISASSOC call to the fw to keep
6312 the state fw and WPA_Supplicant state consistent
6317 brcmf_abort_scanning(cfg);
6318 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6323 s32 brcmf_cfg80211_up(struct net_device *ndev)
6325 struct brcmf_if *ifp = netdev_priv(ndev);
6326 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6329 mutex_lock(&cfg->usr_sync);
6330 err = __brcmf_cfg80211_up(ifp);
6331 mutex_unlock(&cfg->usr_sync);
6336 s32 brcmf_cfg80211_down(struct net_device *ndev)
6338 struct brcmf_if *ifp = netdev_priv(ndev);
6339 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6342 mutex_lock(&cfg->usr_sync);
6343 err = __brcmf_cfg80211_down(ifp);
6344 mutex_unlock(&cfg->usr_sync);
6349 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6351 struct wireless_dev *wdev = &ifp->vif->wdev;
6353 return wdev->iftype;
6356 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6357 unsigned long state)
6359 struct brcmf_cfg80211_vif *vif;
6361 list_for_each_entry(vif, &cfg->vif_list, list) {
6362 if (test_bit(state, &vif->sme_state))
6368 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6373 mutex_lock(&event->vif_event_lock);
6374 evt_action = event->action;
6375 mutex_unlock(&event->vif_event_lock);
6376 return evt_action == action;
6379 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6380 struct brcmf_cfg80211_vif *vif)
6382 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6384 mutex_lock(&event->vif_event_lock);
6387 mutex_unlock(&event->vif_event_lock);
6390 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6392 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6395 mutex_lock(&event->vif_event_lock);
6396 armed = event->vif != NULL;
6397 mutex_unlock(&event->vif_event_lock);
6401 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6402 u8 action, ulong timeout)
6404 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6406 return wait_event_timeout(event->vif_wq,
6407 vif_event_equals(event, action), timeout);
6410 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6411 struct regulatory_request *req)
6413 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6414 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6415 struct brcmf_fil_country_le ccreq;
6418 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6419 req->alpha2[0], req->alpha2[1]);
6421 /* ignore non-ISO3166 country codes */
6422 for (i = 0; i < sizeof(req->alpha2); i++)
6423 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6424 brcmf_err("not a ISO3166 code\n");
6427 memset(&ccreq, 0, sizeof(ccreq));
6428 ccreq.rev = cpu_to_le32(-1);
6429 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6430 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6431 brcmf_err("firmware rejected country setting\n");
6434 brcmf_setup_wiphybands(wiphy);
6437 static void brcmf_free_wiphy(struct wiphy *wiphy)
6444 if (wiphy->iface_combinations) {
6445 for (i = 0; i < wiphy->n_iface_combinations; i++)
6446 kfree(wiphy->iface_combinations[i].limits);
6448 kfree(wiphy->iface_combinations);
6449 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6450 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6451 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6453 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6454 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6455 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6460 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6461 struct device *busdev,
6464 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6465 struct brcmf_cfg80211_info *cfg;
6466 struct wiphy *wiphy;
6467 struct brcmf_cfg80211_vif *vif;
6468 struct brcmf_if *ifp;
6474 brcmf_err("ndev is invalid\n");
6478 ifp = netdev_priv(ndev);
6479 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6481 brcmf_err("Could not allocate wiphy device\n");
6484 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6485 set_wiphy_dev(wiphy, busdev);
6487 cfg = wiphy_priv(wiphy);
6490 init_vif_event(&cfg->vif_event);
6491 INIT_LIST_HEAD(&cfg->vif_list);
6493 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6498 vif->wdev.netdev = ndev;
6499 ndev->ieee80211_ptr = &vif->wdev;
6500 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6502 err = wl_init_priv(cfg);
6504 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6505 brcmf_free_vif(vif);
6510 /* determine d11 io type before wiphy setup */
6511 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6513 brcmf_err("Failed to get D11 version (%d)\n", err);
6516 cfg->d11inf.io_type = (u8)io_type;
6517 brcmu_d11_attach(&cfg->d11inf);
6519 err = brcmf_setup_wiphy(wiphy, ifp);
6523 brcmf_dbg(INFO, "Registering custom regulatory\n");
6524 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6525 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6526 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6528 /* firmware defaults to 40MHz disabled in 2G band. We signal
6529 * cfg80211 here that we do and have it decide we can enable
6530 * it. But first check if device does support 2G operation.
6532 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6533 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6534 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6536 err = wiphy_register(wiphy);
6538 brcmf_err("Could not register wiphy device (%d)\n", err);
6542 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6543 * setup 40MHz in 2GHz band and enable OBSS scanning.
6545 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6546 err = brcmf_enable_bw40_2g(cfg);
6548 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6549 BRCMF_OBSS_COEX_AUTO);
6551 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6553 /* p2p might require that "if-events" get processed by fweh. So
6554 * activate the already registered event handlers now and activate
6555 * the rest when initialization has completed. drvr->config needs to
6556 * be assigned before activating events.
6559 err = brcmf_fweh_activate_events(ifp);
6561 brcmf_err("FWEH activation failed (%d)\n", err);
6562 goto wiphy_unreg_out;
6565 err = brcmf_p2p_attach(cfg, p2pdev_forced);
6567 brcmf_err("P2P initilisation failed (%d)\n", err);
6568 goto wiphy_unreg_out;
6570 err = brcmf_btcoex_attach(cfg);
6572 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6573 brcmf_p2p_detach(&cfg->p2p);
6574 goto wiphy_unreg_out;
6577 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
6578 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6580 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6581 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6583 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6584 brcmf_notify_tdls_peer_event);
6588 /* (re-) activate FWEH event handling */
6589 err = brcmf_fweh_activate_events(ifp);
6591 brcmf_err("FWEH activation failed (%d)\n", err);
6592 goto wiphy_unreg_out;
6595 /* Fill in some of the advertised nl80211 supported features */
6596 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
6597 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
6599 if (wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
6600 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6607 wiphy_unregister(cfg->wiphy);
6609 wl_deinit_priv(cfg);
6610 brcmf_free_vif(vif);
6613 brcmf_free_wiphy(wiphy);
6617 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6622 brcmf_btcoex_detach(cfg);
6623 wiphy_unregister(cfg->wiphy);
6624 wl_deinit_priv(cfg);
6625 brcmf_free_wiphy(cfg->wiphy);