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->chan->center_freq - ch->center_freq1;
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 == -30)
267 ch_inf.sb = BRCMU_CHAN_SB_LL;
268 else if (primary_offset == -10)
269 ch_inf.sb = BRCMU_CHAN_SB_LU;
270 else if (primary_offset == 10)
271 ch_inf.sb = BRCMU_CHAN_SB_UL;
273 ch_inf.sb = BRCMU_CHAN_SB_UU;
275 case NL80211_CHAN_WIDTH_80P80:
276 case NL80211_CHAN_WIDTH_160:
277 case NL80211_CHAN_WIDTH_5:
278 case NL80211_CHAN_WIDTH_10:
282 switch (ch->chan->band) {
283 case IEEE80211_BAND_2GHZ:
284 ch_inf.band = BRCMU_CHAN_BAND_2G;
286 case IEEE80211_BAND_5GHZ:
287 ch_inf.band = BRCMU_CHAN_BAND_5G;
289 case IEEE80211_BAND_60GHZ:
293 d11inf->encchspec(&ch_inf);
295 return ch_inf.chspec;
298 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
299 struct ieee80211_channel *ch)
301 struct brcmu_chan ch_inf;
303 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
304 ch_inf.bw = BRCMU_CHAN_BW_20;
305 d11inf->encchspec(&ch_inf);
307 return ch_inf.chspec;
310 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
311 * triples, returning a pointer to the substring whose first element
314 const struct brcmf_tlv *
315 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
317 const struct brcmf_tlv *elt = buf;
320 /* find tagged parameter */
321 while (totlen >= TLV_HDR_LEN) {
324 /* validate remaining totlen */
325 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
328 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
329 totlen -= (len + TLV_HDR_LEN);
335 /* Is any of the tlvs the expected entry? If
336 * not update the tlvs buffer pointer/length.
339 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
340 const u8 *oui, u32 oui_len, u8 type)
342 /* If the contents match the OUI and the type */
343 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
344 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
345 type == ie[TLV_BODY_OFF + oui_len]) {
351 /* point to the next ie */
352 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
353 /* calculate the length of the rest of the buffer */
354 *tlvs_len -= (int)(ie - *tlvs);
355 /* update the pointer to the start of the buffer */
361 static struct brcmf_vs_tlv *
362 brcmf_find_wpaie(const u8 *parse, u32 len)
364 const struct brcmf_tlv *ie;
366 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
367 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
368 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
369 return (struct brcmf_vs_tlv *)ie;
374 static struct brcmf_vs_tlv *
375 brcmf_find_wpsie(const u8 *parse, u32 len)
377 const struct brcmf_tlv *ie;
379 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
380 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
381 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
382 return (struct brcmf_vs_tlv *)ie;
387 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
388 struct brcmf_cfg80211_vif *vif,
389 enum nl80211_iftype new_type)
391 int iftype_num[NUM_NL80211_IFTYPES];
392 struct brcmf_cfg80211_vif *pos;
393 bool check_combos = false;
396 memset(&iftype_num[0], 0, sizeof(iftype_num));
397 list_for_each_entry(pos, &cfg->vif_list, list)
399 iftype_num[new_type]++;
401 /* concurrent interfaces so need check combinations */
403 iftype_num[pos->wdev.iftype]++;
407 ret = cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
412 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
413 enum nl80211_iftype new_type)
415 int iftype_num[NUM_NL80211_IFTYPES];
416 struct brcmf_cfg80211_vif *pos;
418 memset(&iftype_num[0], 0, sizeof(iftype_num));
419 list_for_each_entry(pos, &cfg->vif_list, list)
420 iftype_num[pos->wdev.iftype]++;
422 iftype_num[new_type]++;
423 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
426 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
427 struct brcmf_wsec_key_le *key_le)
429 key_le->index = cpu_to_le32(key->index);
430 key_le->len = cpu_to_le32(key->len);
431 key_le->algo = cpu_to_le32(key->algo);
432 key_le->flags = cpu_to_le32(key->flags);
433 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
434 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
435 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
436 memcpy(key_le->data, key->data, sizeof(key->data));
437 memcpy(key_le->ea, key->ea, sizeof(key->ea));
441 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
444 struct brcmf_wsec_key_le key_le;
446 convert_key_from_CPU(key, &key_le);
448 brcmf_netdev_wait_pend8021x(ifp);
450 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
454 brcmf_err("wsec_key error (%d)\n", err);
459 brcmf_configure_arp_nd_offload(struct brcmf_if *ifp, bool enable)
465 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
469 /* Try to set and enable ARP offload feature, this may fail, then it */
470 /* is simply not supported and err 0 will be returned */
471 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
473 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
477 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
479 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
483 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
487 err = brcmf_fil_iovar_int_set(ifp, "ndoe", enable);
489 brcmf_dbg(TRACE, "failed to configure (%d) ND offload err = %d\n",
493 brcmf_dbg(TRACE, "successfully configured (%d) ND offload to 0x%x\n",
500 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
502 struct brcmf_cfg80211_vif *vif;
503 struct brcmf_if *ifp;
505 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
508 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
509 (wdev->iftype == NL80211_IFTYPE_AP) ||
510 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
511 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
514 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
518 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
520 struct brcmf_mbss_ssid_le mbss_ssid_le;
524 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
525 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
529 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
530 mbss_ssid_le.SSID_len = cpu_to_le32(5);
531 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
533 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
534 sizeof(mbss_ssid_le));
536 brcmf_err("setting ssid failed %d\n", err);
542 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
544 * @wiphy: wiphy device of new interface.
545 * @name: name of the new interface.
547 * @params: contains mac address for AP device.
550 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
551 u32 *flags, struct vif_params *params)
553 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
554 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
555 struct brcmf_cfg80211_vif *vif;
558 if (brcmf_cfg80211_vif_event_armed(cfg))
559 return ERR_PTR(-EBUSY);
561 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
563 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
565 return (struct wireless_dev *)vif;
567 brcmf_cfg80211_arm_vif_event(cfg, vif);
569 err = brcmf_cfg80211_request_ap_if(ifp);
571 brcmf_cfg80211_arm_vif_event(cfg, NULL);
575 /* wait for firmware event */
576 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
577 BRCMF_VIF_EVENT_TIMEOUT);
578 brcmf_cfg80211_arm_vif_event(cfg, NULL);
580 brcmf_err("timeout occurred\n");
585 /* interface created in firmware */
588 brcmf_err("no if pointer provided\n");
593 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
594 err = brcmf_net_attach(ifp, true);
596 brcmf_err("Registering netdevice failed\n");
600 return &ifp->vif->wdev;
607 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
609 enum nl80211_iftype iftype;
611 iftype = vif->wdev.iftype;
612 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
615 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
617 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
620 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
622 unsigned char name_assign_type,
623 enum nl80211_iftype type,
625 struct vif_params *params)
627 struct wireless_dev *wdev;
630 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
631 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
633 brcmf_err("iface validation failed: err=%d\n", err);
637 case NL80211_IFTYPE_ADHOC:
638 case NL80211_IFTYPE_STATION:
639 case NL80211_IFTYPE_AP_VLAN:
640 case NL80211_IFTYPE_WDS:
641 case NL80211_IFTYPE_MONITOR:
642 case NL80211_IFTYPE_MESH_POINT:
643 return ERR_PTR(-EOPNOTSUPP);
644 case NL80211_IFTYPE_AP:
645 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
647 brcmf_cfg80211_update_proto_addr_mode(wdev);
649 case NL80211_IFTYPE_P2P_CLIENT:
650 case NL80211_IFTYPE_P2P_GO:
651 case NL80211_IFTYPE_P2P_DEVICE:
652 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
654 brcmf_cfg80211_update_proto_addr_mode(wdev);
656 case NL80211_IFTYPE_UNSPECIFIED:
658 return ERR_PTR(-EINVAL);
662 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
664 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
665 brcmf_set_mpc(ifp, mpc);
668 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
672 if (check_vif_up(ifp->vif)) {
673 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
675 brcmf_err("fail to set mpc\n");
678 brcmf_dbg(INFO, "MPC : %d\n", mpc);
682 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
683 struct brcmf_if *ifp, bool aborted,
686 struct brcmf_scan_params_le params_le;
687 struct cfg80211_scan_request *scan_request;
690 brcmf_dbg(SCAN, "Enter\n");
692 /* clear scan request, because the FW abort can cause a second call */
693 /* to this functon and might cause a double cfg80211_scan_done */
694 scan_request = cfg->scan_request;
695 cfg->scan_request = NULL;
697 if (timer_pending(&cfg->escan_timeout))
698 del_timer_sync(&cfg->escan_timeout);
701 /* Do a scan abort to stop the driver's scan engine */
702 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
703 memset(¶ms_le, 0, sizeof(params_le));
704 eth_broadcast_addr(params_le.bssid);
705 params_le.bss_type = DOT11_BSSTYPE_ANY;
706 params_le.scan_type = 0;
707 params_le.channel_num = cpu_to_le32(1);
708 params_le.nprobes = cpu_to_le32(1);
709 params_le.active_time = cpu_to_le32(-1);
710 params_le.passive_time = cpu_to_le32(-1);
711 params_le.home_time = cpu_to_le32(-1);
712 /* Scan is aborted by setting channel_list[0] to -1 */
713 params_le.channel_list[0] = cpu_to_le16(-1);
714 /* E-Scan (or anyother type) can be aborted by SCAN */
715 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
716 ¶ms_le, sizeof(params_le));
718 brcmf_err("Scan abort failed\n");
721 brcmf_scan_config_mpc(ifp, 1);
724 * e-scan can be initiated by scheduled scan
725 * which takes precedence.
727 if (cfg->sched_escan) {
728 brcmf_dbg(SCAN, "scheduled scan completed\n");
729 cfg->sched_escan = false;
731 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
732 } else if (scan_request) {
733 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
734 aborted ? "Aborted" : "Done");
735 cfg80211_scan_done(scan_request, aborted);
737 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
738 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
744 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
746 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
747 struct net_device *ndev = wdev->netdev;
749 /* vif event pending in firmware */
750 if (brcmf_cfg80211_vif_event_armed(cfg))
754 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
755 cfg->escan_info.ifp == netdev_priv(ndev))
756 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
759 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
762 switch (wdev->iftype) {
763 case NL80211_IFTYPE_ADHOC:
764 case NL80211_IFTYPE_STATION:
765 case NL80211_IFTYPE_AP:
766 case NL80211_IFTYPE_AP_VLAN:
767 case NL80211_IFTYPE_WDS:
768 case NL80211_IFTYPE_MONITOR:
769 case NL80211_IFTYPE_MESH_POINT:
771 case NL80211_IFTYPE_P2P_CLIENT:
772 case NL80211_IFTYPE_P2P_GO:
773 case NL80211_IFTYPE_P2P_DEVICE:
774 return brcmf_p2p_del_vif(wiphy, wdev);
775 case NL80211_IFTYPE_UNSPECIFIED:
783 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
784 enum nl80211_iftype type, u32 *flags,
785 struct vif_params *params)
787 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
788 struct brcmf_if *ifp = netdev_priv(ndev);
789 struct brcmf_cfg80211_vif *vif = ifp->vif;
794 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
797 /* WAR: There are a number of p2p interface related problems which
798 * need to be handled initially (before doing the validate).
799 * wpa_supplicant tends to do iface changes on p2p device/client/go
800 * which are not always possible/allowed. However we need to return
801 * OK otherwise the wpa_supplicant wont start. The situation differs
802 * on configuration and setup (p2pon=1 module param). The first check
803 * is to see if the request is a change to station for p2p iface.
805 if ((type == NL80211_IFTYPE_STATION) &&
806 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
807 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
808 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
809 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
810 /* Now depending on whether module param p2pon=1 was used the
811 * response needs to be either 0 or EOPNOTSUPP. The reason is
812 * that if p2pon=1 is used, but a newer supplicant is used then
813 * we should return an error, as this combination wont work.
814 * In other situations 0 is returned and supplicant will start
815 * normally. It will give a trace in cfg80211, but it is the
816 * only way to get it working. Unfortunately this will result
817 * in situation where we wont support new supplicant in
818 * combination with module param p2pon=1, but that is the way
819 * it is. If the user tries this then unloading of driver might
822 if (cfg->p2p.p2pdev_dynamically)
827 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
829 brcmf_err("iface validation failed: err=%d\n", err);
833 case NL80211_IFTYPE_MONITOR:
834 case NL80211_IFTYPE_WDS:
835 brcmf_err("type (%d) : currently we do not support this type\n",
838 case NL80211_IFTYPE_ADHOC:
841 case NL80211_IFTYPE_STATION:
844 case NL80211_IFTYPE_AP:
845 case NL80211_IFTYPE_P2P_GO:
854 if (type == NL80211_IFTYPE_P2P_GO) {
855 brcmf_dbg(INFO, "IF Type = P2P GO\n");
856 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
859 brcmf_dbg(INFO, "IF Type = AP\n");
862 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
864 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
868 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
871 ndev->ieee80211_ptr->iftype = type;
873 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
876 brcmf_dbg(TRACE, "Exit\n");
881 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
882 struct brcmf_scan_params_le *params_le,
883 struct cfg80211_scan_request *request)
891 struct brcmf_ssid_le ssid_le;
893 eth_broadcast_addr(params_le->bssid);
894 params_le->bss_type = DOT11_BSSTYPE_ANY;
895 params_le->scan_type = 0;
896 params_le->channel_num = 0;
897 params_le->nprobes = cpu_to_le32(-1);
898 params_le->active_time = cpu_to_le32(-1);
899 params_le->passive_time = cpu_to_le32(-1);
900 params_le->home_time = cpu_to_le32(-1);
901 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
903 /* if request is null exit so it will be all channel broadcast scan */
907 n_ssids = request->n_ssids;
908 n_channels = request->n_channels;
909 /* Copy channel array if applicable */
910 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
912 if (n_channels > 0) {
913 for (i = 0; i < n_channels; i++) {
914 chanspec = channel_to_chanspec(&cfg->d11inf,
915 request->channels[i]);
916 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
917 request->channels[i]->hw_value, chanspec);
918 params_le->channel_list[i] = cpu_to_le16(chanspec);
921 brcmf_dbg(SCAN, "Scanning all channels\n");
923 /* Copy ssid array if applicable */
924 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
926 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
927 n_channels * sizeof(u16);
928 offset = roundup(offset, sizeof(u32));
929 ptr = (char *)params_le + offset;
930 for (i = 0; i < n_ssids; i++) {
931 memset(&ssid_le, 0, sizeof(ssid_le));
933 cpu_to_le32(request->ssids[i].ssid_len);
934 memcpy(ssid_le.SSID, request->ssids[i].ssid,
935 request->ssids[i].ssid_len);
936 if (!ssid_le.SSID_len)
937 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
939 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
940 i, ssid_le.SSID, ssid_le.SSID_len);
941 memcpy(ptr, &ssid_le, sizeof(ssid_le));
942 ptr += sizeof(ssid_le);
945 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
946 if ((request->ssids) && request->ssids->ssid_len) {
947 brcmf_dbg(SCAN, "SSID %s len=%d\n",
948 params_le->ssid_le.SSID,
949 request->ssids->ssid_len);
950 params_le->ssid_le.SSID_len =
951 cpu_to_le32(request->ssids->ssid_len);
952 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
953 request->ssids->ssid_len);
956 /* Adding mask to channel numbers */
957 params_le->channel_num =
958 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
959 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
963 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
964 struct cfg80211_scan_request *request)
966 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
967 offsetof(struct brcmf_escan_params_le, params_le);
968 struct brcmf_escan_params_le *params;
971 brcmf_dbg(SCAN, "E-SCAN START\n");
973 if (request != NULL) {
974 /* Allocate space for populating ssids in struct */
975 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
977 /* Allocate space for populating ssids in struct */
978 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
981 params = kzalloc(params_size, GFP_KERNEL);
986 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
987 brcmf_escan_prep(cfg, ¶ms->params_le, request);
988 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
989 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
990 params->sync_id = cpu_to_le16(0x1234);
992 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
995 brcmf_dbg(INFO, "system busy : escan canceled\n");
997 brcmf_err("error (%d)\n", err);
1006 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1007 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1011 struct brcmf_scan_results *results;
1012 struct escan_info *escan = &cfg->escan_info;
1014 brcmf_dbg(SCAN, "Enter\n");
1016 escan->wiphy = wiphy;
1017 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1018 passive_scan = cfg->active_scan ? 0 : 1;
1019 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1022 brcmf_err("error (%d)\n", err);
1025 brcmf_scan_config_mpc(ifp, 0);
1026 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1027 results->version = 0;
1029 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1031 err = escan->run(cfg, ifp, request);
1033 brcmf_scan_config_mpc(ifp, 1);
1038 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1039 struct cfg80211_scan_request *request,
1040 struct cfg80211_ssid *this_ssid)
1042 struct brcmf_if *ifp = vif->ifp;
1043 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1044 struct cfg80211_ssid *ssids;
1049 struct brcmf_ssid_le ssid_le;
1052 brcmf_dbg(SCAN, "START ESCAN\n");
1054 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1055 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1058 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1059 brcmf_err("Scanning being aborted: status (%lu)\n",
1063 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1064 brcmf_err("Scanning suppressed: status (%lu)\n",
1068 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1069 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1073 /* If scan req comes for p2p0, send it over primary I/F */
1074 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1075 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1080 ssids = request->ssids;
1084 /* we don't do escan in ibss */
1088 cfg->scan_request = request;
1089 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1091 cfg->escan_info.run = brcmf_run_escan;
1092 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1096 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1100 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1101 ssids->ssid, ssids->ssid_len);
1102 memset(&ssid_le, 0, sizeof(ssid_le));
1103 SSID_len = min_t(u8, sizeof(ssid_le.SSID), ssids->ssid_len);
1104 ssid_le.SSID_len = cpu_to_le32(0);
1107 memcpy(ssid_le.SSID, ssids->ssid, SSID_len);
1108 ssid_le.SSID_len = cpu_to_le32(SSID_len);
1111 brcmf_dbg(SCAN, "Broadcast scan\n");
1113 passive_scan = cfg->active_scan ? 0 : 1;
1114 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1117 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1120 brcmf_scan_config_mpc(ifp, 0);
1121 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN, &ssid_le,
1125 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1128 brcmf_err("WLC_SCAN error (%d)\n", err);
1130 brcmf_scan_config_mpc(ifp, 1);
1135 /* Arm scan timeout timer */
1136 mod_timer(&cfg->escan_timeout, jiffies +
1137 BRCMF_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1142 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1143 cfg->scan_request = NULL;
1148 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1150 struct brcmf_cfg80211_vif *vif;
1153 brcmf_dbg(TRACE, "Enter\n");
1154 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1155 if (!check_vif_up(vif))
1158 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1161 brcmf_err("scan error (%d)\n", err);
1163 brcmf_dbg(TRACE, "Exit\n");
1167 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1171 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1174 brcmf_err("Error (%d)\n", err);
1179 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1183 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1186 brcmf_err("Error (%d)\n", err);
1191 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1194 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1196 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1198 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1204 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1206 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1207 struct net_device *ndev = cfg_to_ndev(cfg);
1208 struct brcmf_if *ifp = netdev_priv(ndev);
1211 brcmf_dbg(TRACE, "Enter\n");
1212 if (!check_vif_up(ifp->vif))
1215 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1216 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1217 cfg->conf->rts_threshold = wiphy->rts_threshold;
1218 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1222 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1223 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1224 cfg->conf->frag_threshold = wiphy->frag_threshold;
1225 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1229 if (changed & WIPHY_PARAM_RETRY_LONG
1230 && (cfg->conf->retry_long != wiphy->retry_long)) {
1231 cfg->conf->retry_long = wiphy->retry_long;
1232 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1236 if (changed & WIPHY_PARAM_RETRY_SHORT
1237 && (cfg->conf->retry_short != wiphy->retry_short)) {
1238 cfg->conf->retry_short = wiphy->retry_short;
1239 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1245 brcmf_dbg(TRACE, "Exit\n");
1249 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1251 memset(prof, 0, sizeof(*prof));
1254 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1258 switch (e->event_code) {
1259 case BRCMF_E_DEAUTH:
1260 case BRCMF_E_DEAUTH_IND:
1261 case BRCMF_E_DISASSOC_IND:
1272 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1274 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1277 brcmf_dbg(TRACE, "Enter\n");
1279 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1280 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1281 err = brcmf_fil_cmd_data_set(vif->ifp,
1282 BRCMF_C_DISASSOC, NULL, 0);
1284 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1286 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1287 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1288 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1291 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1292 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1293 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1294 brcmf_dbg(TRACE, "Exit\n");
1298 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1299 struct cfg80211_ibss_params *params)
1301 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1302 struct brcmf_if *ifp = netdev_priv(ndev);
1303 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1304 struct brcmf_join_params join_params;
1305 size_t join_params_size = 0;
1312 brcmf_dbg(TRACE, "Enter\n");
1313 if (!check_vif_up(ifp->vif))
1317 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1319 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1323 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1326 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1328 brcmf_dbg(CONN, "No BSSID specified\n");
1330 if (params->chandef.chan)
1331 brcmf_dbg(CONN, "channel: %d\n",
1332 params->chandef.chan->center_freq);
1334 brcmf_dbg(CONN, "no channel specified\n");
1336 if (params->channel_fixed)
1337 brcmf_dbg(CONN, "fixed channel required\n");
1339 brcmf_dbg(CONN, "no fixed channel required\n");
1341 if (params->ie && params->ie_len)
1342 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1344 brcmf_dbg(CONN, "no ie specified\n");
1346 if (params->beacon_interval)
1347 brcmf_dbg(CONN, "beacon interval: %d\n",
1348 params->beacon_interval);
1350 brcmf_dbg(CONN, "no beacon interval specified\n");
1352 if (params->basic_rates)
1353 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1355 brcmf_dbg(CONN, "no basic rates specified\n");
1357 if (params->privacy)
1358 brcmf_dbg(CONN, "privacy required\n");
1360 brcmf_dbg(CONN, "no privacy required\n");
1362 /* Configure Privacy for starter */
1363 if (params->privacy)
1364 wsec |= WEP_ENABLED;
1366 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1368 brcmf_err("wsec failed (%d)\n", err);
1372 /* Configure Beacon Interval for starter */
1373 if (params->beacon_interval)
1374 bcnprd = params->beacon_interval;
1378 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1380 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1384 /* Configure required join parameter */
1385 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1388 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1389 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1390 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1391 join_params_size = sizeof(join_params.ssid_le);
1394 if (params->bssid) {
1395 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1396 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1397 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1399 eth_broadcast_addr(join_params.params_le.bssid);
1400 eth_zero_addr(profile->bssid);
1404 if (params->chandef.chan) {
1408 ieee80211_frequency_to_channel(
1409 params->chandef.chan->center_freq);
1410 if (params->channel_fixed) {
1411 /* adding chanspec */
1412 chanspec = chandef_to_chanspec(&cfg->d11inf,
1414 join_params.params_le.chanspec_list[0] =
1415 cpu_to_le16(chanspec);
1416 join_params.params_le.chanspec_num = cpu_to_le32(1);
1417 join_params_size += sizeof(join_params.params_le);
1420 /* set channel for starter */
1421 target_channel = cfg->channel;
1422 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1425 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1431 cfg->ibss_starter = false;
1434 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1435 &join_params, join_params_size);
1437 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1443 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1444 brcmf_dbg(TRACE, "Exit\n");
1449 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1451 struct brcmf_if *ifp = netdev_priv(ndev);
1453 brcmf_dbg(TRACE, "Enter\n");
1454 if (!check_vif_up(ifp->vif)) {
1455 /* When driver is being unloaded, it can end up here. If an
1456 * error is returned then later on a debug trace in the wireless
1457 * core module will be printed. To avoid this 0 is returned.
1462 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1463 brcmf_net_setcarrier(ifp, false);
1465 brcmf_dbg(TRACE, "Exit\n");
1470 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1471 struct cfg80211_connect_params *sme)
1473 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1474 struct brcmf_cfg80211_security *sec;
1478 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1479 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1480 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1481 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1483 val = WPA_AUTH_DISABLED;
1484 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1485 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1487 brcmf_err("set wpa_auth failed (%d)\n", err);
1490 sec = &profile->sec;
1491 sec->wpa_versions = sme->crypto.wpa_versions;
1495 static s32 brcmf_set_auth_type(struct net_device *ndev,
1496 struct cfg80211_connect_params *sme)
1498 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1499 struct brcmf_cfg80211_security *sec;
1503 switch (sme->auth_type) {
1504 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1506 brcmf_dbg(CONN, "open system\n");
1508 case NL80211_AUTHTYPE_SHARED_KEY:
1510 brcmf_dbg(CONN, "shared key\n");
1512 case NL80211_AUTHTYPE_AUTOMATIC:
1514 brcmf_dbg(CONN, "automatic\n");
1516 case NL80211_AUTHTYPE_NETWORK_EAP:
1517 brcmf_dbg(CONN, "network eap\n");
1520 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1524 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1526 brcmf_err("set auth failed (%d)\n", err);
1529 sec = &profile->sec;
1530 sec->auth_type = sme->auth_type;
1535 brcmf_set_wsec_mode(struct net_device *ndev,
1536 struct cfg80211_connect_params *sme, bool mfp)
1538 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1539 struct brcmf_cfg80211_security *sec;
1545 if (sme->crypto.n_ciphers_pairwise) {
1546 switch (sme->crypto.ciphers_pairwise[0]) {
1547 case WLAN_CIPHER_SUITE_WEP40:
1548 case WLAN_CIPHER_SUITE_WEP104:
1551 case WLAN_CIPHER_SUITE_TKIP:
1552 pval = TKIP_ENABLED;
1554 case WLAN_CIPHER_SUITE_CCMP:
1557 case WLAN_CIPHER_SUITE_AES_CMAC:
1561 brcmf_err("invalid cipher pairwise (%d)\n",
1562 sme->crypto.ciphers_pairwise[0]);
1566 if (sme->crypto.cipher_group) {
1567 switch (sme->crypto.cipher_group) {
1568 case WLAN_CIPHER_SUITE_WEP40:
1569 case WLAN_CIPHER_SUITE_WEP104:
1572 case WLAN_CIPHER_SUITE_TKIP:
1573 gval = TKIP_ENABLED;
1575 case WLAN_CIPHER_SUITE_CCMP:
1578 case WLAN_CIPHER_SUITE_AES_CMAC:
1582 brcmf_err("invalid cipher group (%d)\n",
1583 sme->crypto.cipher_group);
1588 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1589 /* In case of privacy, but no security and WPS then simulate */
1590 /* setting AES. WPS-2.0 allows no security */
1591 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1596 wsec = pval | gval | MFP_CAPABLE;
1599 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1601 brcmf_err("error (%d)\n", err);
1605 sec = &profile->sec;
1606 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1607 sec->cipher_group = sme->crypto.cipher_group;
1613 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1615 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1616 struct brcmf_cfg80211_security *sec;
1620 if (sme->crypto.n_akm_suites) {
1621 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1624 brcmf_err("could not get wpa_auth (%d)\n", err);
1627 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1628 switch (sme->crypto.akm_suites[0]) {
1629 case WLAN_AKM_SUITE_8021X:
1630 val = WPA_AUTH_UNSPECIFIED;
1632 case WLAN_AKM_SUITE_PSK:
1636 brcmf_err("invalid cipher group (%d)\n",
1637 sme->crypto.cipher_group);
1640 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1641 switch (sme->crypto.akm_suites[0]) {
1642 case WLAN_AKM_SUITE_8021X:
1643 val = WPA2_AUTH_UNSPECIFIED;
1645 case WLAN_AKM_SUITE_PSK:
1646 val = WPA2_AUTH_PSK;
1649 brcmf_err("invalid cipher group (%d)\n",
1650 sme->crypto.cipher_group);
1655 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1656 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1659 brcmf_err("could not set wpa_auth (%d)\n", err);
1663 sec = &profile->sec;
1664 sec->wpa_auth = sme->crypto.akm_suites[0];
1670 brcmf_set_sharedkey(struct net_device *ndev,
1671 struct cfg80211_connect_params *sme)
1673 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1674 struct brcmf_cfg80211_security *sec;
1675 struct brcmf_wsec_key key;
1679 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1681 if (sme->key_len == 0)
1684 sec = &profile->sec;
1685 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1686 sec->wpa_versions, sec->cipher_pairwise);
1688 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1691 if (!(sec->cipher_pairwise &
1692 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1695 memset(&key, 0, sizeof(key));
1696 key.len = (u32) sme->key_len;
1697 key.index = (u32) sme->key_idx;
1698 if (key.len > sizeof(key.data)) {
1699 brcmf_err("Too long key length (%u)\n", key.len);
1702 memcpy(key.data, sme->key, key.len);
1703 key.flags = BRCMF_PRIMARY_KEY;
1704 switch (sec->cipher_pairwise) {
1705 case WLAN_CIPHER_SUITE_WEP40:
1706 key.algo = CRYPTO_ALGO_WEP1;
1708 case WLAN_CIPHER_SUITE_WEP104:
1709 key.algo = CRYPTO_ALGO_WEP128;
1712 brcmf_err("Invalid algorithm (%d)\n",
1713 sme->crypto.ciphers_pairwise[0]);
1716 /* Set the new key/index */
1717 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1718 key.len, key.index, key.algo);
1719 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1720 err = send_key_to_dongle(netdev_priv(ndev), &key);
1724 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1725 brcmf_dbg(CONN, "set auth_type to shared key\n");
1726 val = WL_AUTH_SHARED_KEY; /* shared key */
1727 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1729 brcmf_err("set auth failed (%d)\n", err);
1735 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1736 enum nl80211_auth_type type)
1738 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1739 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1740 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1741 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1747 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1748 struct cfg80211_connect_params *sme)
1750 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1751 struct brcmf_if *ifp = netdev_priv(ndev);
1752 struct ieee80211_channel *chan = sme->channel;
1753 struct brcmf_join_params join_params;
1754 size_t join_params_size;
1755 const struct brcmf_tlv *rsn_ie;
1756 const struct brcmf_vs_tlv *wpa_ie;
1759 struct brcmf_ext_join_params_le *ext_join_params;
1764 brcmf_dbg(TRACE, "Enter\n");
1765 if (!check_vif_up(ifp->vif))
1769 brcmf_err("Invalid ssid\n");
1773 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1774 /* A normal (non P2P) connection request setup. */
1777 /* find the WPA_IE */
1778 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1781 ie_len = wpa_ie->len + TLV_HDR_LEN;
1783 /* find the RSN_IE */
1784 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1789 ie_len = rsn_ie->len + TLV_HDR_LEN;
1792 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1795 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1796 sme->ie, sme->ie_len);
1798 brcmf_err("Set Assoc REQ IE Failed\n");
1800 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1802 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1806 ieee80211_frequency_to_channel(chan->center_freq);
1807 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1808 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1809 cfg->channel, chan->center_freq, chanspec);
1815 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1817 err = brcmf_set_wpa_version(ndev, sme);
1819 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1823 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1824 err = brcmf_set_auth_type(ndev, sme);
1826 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1830 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1832 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1836 err = brcmf_set_key_mgmt(ndev, sme);
1838 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1842 err = brcmf_set_sharedkey(ndev, sme);
1844 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1848 /* Join with specific BSSID and cached SSID
1849 * If SSID is zero join based on BSSID only
1851 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1852 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1854 join_params_size += sizeof(u16);
1855 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1856 if (ext_join_params == NULL) {
1860 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
1861 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
1862 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
1863 if (ssid_len < IEEE80211_MAX_SSID_LEN)
1864 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
1865 ext_join_params->ssid_le.SSID, ssid_len);
1867 /* Set up join scan parameters */
1868 ext_join_params->scan_le.scan_type = -1;
1869 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1872 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1874 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1877 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1879 ext_join_params->assoc_le.chanspec_list[0] =
1880 cpu_to_le16(chanspec);
1881 /* Increase dwell time to receive probe response or detect
1882 * beacon from target AP at a noisy air only during connect
1885 ext_join_params->scan_le.active_time =
1886 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1887 ext_join_params->scan_le.passive_time =
1888 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1889 /* To sync with presence period of VSDB GO send probe request
1890 * more frequently. Probe request will be stopped when it gets
1891 * probe response from target AP/GO.
1893 ext_join_params->scan_le.nprobes =
1894 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1895 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1897 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1898 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1899 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1902 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1904 kfree(ext_join_params);
1906 /* This is it. join command worked, we are done */
1909 /* join command failed, fallback to set ssid */
1910 memset(&join_params, 0, sizeof(join_params));
1911 join_params_size = sizeof(join_params.ssid_le);
1913 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
1914 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1917 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1919 eth_broadcast_addr(join_params.params_le.bssid);
1922 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1923 join_params.params_le.chanspec_num = cpu_to_le32(1);
1924 join_params_size += sizeof(join_params.params_le);
1926 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1927 &join_params, join_params_size);
1929 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1933 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1934 brcmf_dbg(TRACE, "Exit\n");
1939 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1942 struct brcmf_if *ifp = netdev_priv(ndev);
1943 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1944 struct brcmf_scb_val_le scbval;
1947 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1948 if (!check_vif_up(ifp->vif))
1951 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1952 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1953 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1955 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1956 scbval.val = cpu_to_le32(reason_code);
1957 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1958 &scbval, sizeof(scbval));
1960 brcmf_err("error (%d)\n", err);
1962 brcmf_dbg(TRACE, "Exit\n");
1967 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1968 enum nl80211_tx_power_setting type, s32 mbm)
1970 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1971 struct net_device *ndev = cfg_to_ndev(cfg);
1972 struct brcmf_if *ifp = netdev_priv(ndev);
1977 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
1978 if (!check_vif_up(ifp->vif))
1982 case NL80211_TX_POWER_AUTOMATIC:
1984 case NL80211_TX_POWER_LIMITED:
1985 case NL80211_TX_POWER_FIXED:
1987 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1991 qdbm = MBM_TO_DBM(4 * mbm);
1994 qdbm |= WL_TXPWR_OVERRIDE;
1997 brcmf_err("Unsupported type %d\n", type);
2001 /* Make sure radio is off or on as far as software is concerned */
2002 disable = WL_RADIO_SW_DISABLE << 16;
2003 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2005 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2007 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2009 brcmf_err("qtxpower error (%d)\n", err);
2012 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2017 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2020 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2021 struct net_device *ndev = cfg_to_ndev(cfg);
2022 struct brcmf_if *ifp = netdev_priv(ndev);
2026 brcmf_dbg(TRACE, "Enter\n");
2027 if (!check_vif_up(ifp->vif))
2030 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
2032 brcmf_err("error (%d)\n", err);
2035 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2038 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2043 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2044 u8 key_idx, bool unicast, bool multicast)
2046 struct brcmf_if *ifp = netdev_priv(ndev);
2051 brcmf_dbg(TRACE, "Enter\n");
2052 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2053 if (!check_vif_up(ifp->vif))
2056 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2058 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2062 if (wsec & WEP_ENABLED) {
2063 /* Just select a new current key */
2065 err = brcmf_fil_cmd_int_set(ifp,
2066 BRCMF_C_SET_KEY_PRIMARY, index);
2068 brcmf_err("error (%d)\n", err);
2071 brcmf_dbg(TRACE, "Exit\n");
2076 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2077 u8 key_idx, bool pairwise, const u8 *mac_addr)
2079 struct brcmf_if *ifp = netdev_priv(ndev);
2080 struct brcmf_wsec_key key;
2083 brcmf_dbg(TRACE, "Enter\n");
2084 if (!check_vif_up(ifp->vif))
2087 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2088 /* we ignore this key index in this case */
2092 memset(&key, 0, sizeof(key));
2094 key.index = (u32)key_idx;
2095 key.flags = BRCMF_PRIMARY_KEY;
2096 key.algo = CRYPTO_ALGO_OFF;
2098 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2100 /* Set the new key/index */
2101 err = send_key_to_dongle(ifp, &key);
2103 brcmf_dbg(TRACE, "Exit\n");
2108 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2109 u8 key_idx, bool pairwise, const u8 *mac_addr,
2110 struct key_params *params)
2112 struct brcmf_if *ifp = netdev_priv(ndev);
2113 struct brcmf_wsec_key *key;
2120 brcmf_dbg(TRACE, "Enter\n");
2121 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2122 if (!check_vif_up(ifp->vif))
2125 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2126 /* we ignore this key index in this case */
2127 brcmf_err("invalid key index (%d)\n", key_idx);
2131 if (params->key_len == 0)
2132 return brcmf_cfg80211_del_key(wiphy, ndev, key_idx, pairwise,
2135 if (params->key_len > sizeof(key->data)) {
2136 brcmf_err("Too long key length (%u)\n", params->key_len);
2141 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2142 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2143 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2147 key = &ifp->vif->profile.key[key_idx];
2148 memset(key, 0, sizeof(*key));
2149 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2150 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2151 key->len = params->key_len;
2152 key->index = key_idx;
2153 memcpy(key->data, params->key, key->len);
2155 key->flags = BRCMF_PRIMARY_KEY;
2157 switch (params->cipher) {
2158 case WLAN_CIPHER_SUITE_WEP40:
2159 key->algo = CRYPTO_ALGO_WEP1;
2161 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2163 case WLAN_CIPHER_SUITE_WEP104:
2164 key->algo = CRYPTO_ALGO_WEP128;
2166 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2168 case WLAN_CIPHER_SUITE_TKIP:
2169 if (!brcmf_is_apmode(ifp->vif)) {
2170 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2171 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2172 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2173 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2175 key->algo = CRYPTO_ALGO_TKIP;
2177 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2179 case WLAN_CIPHER_SUITE_AES_CMAC:
2180 key->algo = CRYPTO_ALGO_AES_CCM;
2182 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2184 case WLAN_CIPHER_SUITE_CCMP:
2185 key->algo = CRYPTO_ALGO_AES_CCM;
2187 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2190 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2195 err = send_key_to_dongle(ifp, key);
2199 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2201 brcmf_err("get wsec error (%d)\n", err);
2205 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2207 brcmf_err("set wsec error (%d)\n", err);
2212 brcmf_dbg(TRACE, "Exit\n");
2217 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2218 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2219 void (*callback) (void *cookie, struct key_params * params))
2221 struct key_params params;
2222 struct brcmf_if *ifp = netdev_priv(ndev);
2223 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2224 struct brcmf_cfg80211_security *sec;
2228 brcmf_dbg(TRACE, "Enter\n");
2229 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2230 if (!check_vif_up(ifp->vif))
2233 memset(¶ms, 0, sizeof(params));
2235 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2237 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2238 /* Ignore this error, may happen during DISASSOC */
2242 if (wsec & WEP_ENABLED) {
2243 sec = &profile->sec;
2244 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2245 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2246 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2247 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2248 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2249 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2251 } else if (wsec & TKIP_ENABLED) {
2252 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2253 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2254 } else if (wsec & AES_ENABLED) {
2255 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2256 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2258 brcmf_err("Invalid algo (0x%x)\n", wsec);
2262 callback(cookie, ¶ms);
2265 brcmf_dbg(TRACE, "Exit\n");
2270 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2271 struct net_device *ndev, u8 key_idx)
2273 brcmf_dbg(INFO, "Not supported\n");
2279 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2283 struct brcmf_wsec_key *key;
2286 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2287 key = &ifp->vif->profile.key[key_idx];
2288 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2289 (key->algo == CRYPTO_ALGO_WEP128))
2292 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2295 err = send_key_to_dongle(ifp, key);
2297 brcmf_err("Setting WEP key failed (%d)\n", err);
2300 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2302 brcmf_err("get wsec error (%d)\n", err);
2305 wsec |= WEP_ENABLED;
2306 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2308 brcmf_err("set wsec error (%d)\n", err);
2311 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2313 struct nl80211_sta_flag_update *sfu;
2315 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2316 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2317 sfu = &si->sta_flags;
2318 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2319 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2320 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2321 BIT(NL80211_STA_FLAG_AUTHORIZED);
2322 if (fw_sta_flags & BRCMF_STA_WME)
2323 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2324 if (fw_sta_flags & BRCMF_STA_AUTHE)
2325 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2326 if (fw_sta_flags & BRCMF_STA_ASSOC)
2327 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2328 if (fw_sta_flags & BRCMF_STA_AUTHO)
2329 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2332 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2336 struct brcmf_bss_info_le bss_le;
2341 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2345 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2346 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2349 brcmf_err("Failed to get bss info (%d)\n", err);
2352 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2353 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2354 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2355 capability = le16_to_cpu(buf->bss_le.capability);
2356 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2357 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2358 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2359 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2360 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2361 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2365 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
2366 struct station_info *sinfo)
2368 struct brcmf_scb_val_le scbval;
2369 struct brcmf_pktcnt_le pktcnt;
2374 /* Get the current tx rate */
2375 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2377 brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err);
2380 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2381 sinfo->txrate.legacy = rate * 5;
2383 memset(&scbval, 0, sizeof(scbval));
2384 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
2387 brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err);
2390 rssi = le32_to_cpu(scbval.val);
2391 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2392 sinfo->signal = rssi;
2394 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
2397 brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
2400 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS) |
2401 BIT(NL80211_STA_INFO_RX_DROP_MISC) |
2402 BIT(NL80211_STA_INFO_TX_PACKETS) |
2403 BIT(NL80211_STA_INFO_TX_FAILED);
2404 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
2405 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
2406 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
2407 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
2413 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2414 const u8 *mac, struct station_info *sinfo)
2416 struct brcmf_if *ifp = netdev_priv(ndev);
2418 struct brcmf_sta_info_le sta_info_le;
2425 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2426 if (!check_vif_up(ifp->vif))
2429 if (brcmf_is_ibssmode(ifp->vif))
2430 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
2432 memset(&sta_info_le, 0, sizeof(sta_info_le));
2433 memcpy(&sta_info_le, mac, ETH_ALEN);
2434 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2436 sizeof(sta_info_le));
2437 is_tdls_peer = !err;
2439 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2441 sizeof(sta_info_le));
2443 brcmf_err("GET STA INFO failed, %d\n", err);
2447 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2448 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2449 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2450 sta_flags = le32_to_cpu(sta_info_le.flags);
2451 brcmf_convert_sta_flags(sta_flags, sinfo);
2452 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2454 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2456 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2457 if (sta_flags & BRCMF_STA_ASSOC) {
2458 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2459 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2460 brcmf_fill_bss_param(ifp, sinfo);
2462 if (sta_flags & BRCMF_STA_SCBSTATS) {
2463 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2464 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2465 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2466 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2467 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2468 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2469 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2470 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2471 if (sinfo->tx_packets) {
2472 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2473 sinfo->txrate.legacy =
2474 le32_to_cpu(sta_info_le.tx_rate) / 100;
2476 if (sinfo->rx_packets) {
2477 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2478 sinfo->rxrate.legacy =
2479 le32_to_cpu(sta_info_le.rx_rate) / 100;
2481 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2482 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2483 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2484 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2485 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2489 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2490 if (sta_info_le.rssi[i]) {
2491 sinfo->chain_signal_avg[count_rssi] =
2492 sta_info_le.rssi[i];
2493 sinfo->chain_signal[count_rssi] =
2494 sta_info_le.rssi[i];
2495 total_rssi += sta_info_le.rssi[i];
2500 sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2501 sinfo->chains = count_rssi;
2503 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2504 total_rssi /= count_rssi;
2505 sinfo->signal = total_rssi;
2509 brcmf_dbg(TRACE, "Exit\n");
2514 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2515 int idx, u8 *mac, struct station_info *sinfo)
2517 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2518 struct brcmf_if *ifp = netdev_priv(ndev);
2521 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2524 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2525 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2527 sizeof(cfg->assoclist));
2529 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2531 cfg->assoclist.count = 0;
2535 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2536 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2537 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2543 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2544 bool enabled, s32 timeout)
2548 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2549 struct brcmf_if *ifp = netdev_priv(ndev);
2551 brcmf_dbg(TRACE, "Enter\n");
2554 * Powersave enable/disable request is coming from the
2555 * cfg80211 even before the interface is up. In that
2556 * scenario, driver will be storing the power save
2557 * preference in cfg struct to apply this to
2558 * FW later while initializing the dongle
2560 cfg->pwr_save = enabled;
2561 if (!check_vif_up(ifp->vif)) {
2563 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2567 pm = enabled ? PM_FAST : PM_OFF;
2568 /* Do not enable the power save after assoc if it is a p2p interface */
2569 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2570 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2573 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2575 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2578 brcmf_err("net_device is not ready yet\n");
2580 brcmf_err("error (%d)\n", err);
2583 brcmf_dbg(TRACE, "Exit\n");
2587 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2588 struct brcmf_bss_info_le *bi)
2590 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2591 struct ieee80211_channel *notify_channel;
2592 struct cfg80211_bss *bss;
2593 struct ieee80211_supported_band *band;
2594 struct brcmu_chan ch;
2597 u16 notify_capability;
2598 u16 notify_interval;
2600 size_t notify_ielen;
2603 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2604 brcmf_err("Bss info is larger than buffer. Discarding\n");
2609 ch.chspec = le16_to_cpu(bi->chanspec);
2610 cfg->d11inf.decchspec(&ch);
2611 bi->ctl_ch = ch.chnum;
2613 channel = bi->ctl_ch;
2615 if (channel <= CH_MAX_2G_CHANNEL)
2616 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2618 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2620 freq = ieee80211_channel_to_frequency(channel, band->band);
2621 notify_channel = ieee80211_get_channel(wiphy, freq);
2623 notify_capability = le16_to_cpu(bi->capability);
2624 notify_interval = le16_to_cpu(bi->beacon_period);
2625 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2626 notify_ielen = le32_to_cpu(bi->ie_length);
2627 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2629 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2630 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2631 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2632 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2633 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2635 bss = cfg80211_inform_bss(wiphy, notify_channel,
2636 CFG80211_BSS_FTYPE_UNKNOWN,
2637 (const u8 *)bi->BSSID,
2638 0, notify_capability,
2639 notify_interval, notify_ie,
2640 notify_ielen, notify_signal,
2646 cfg80211_put_bss(wiphy, bss);
2651 static struct brcmf_bss_info_le *
2652 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2655 return list->bss_info_le;
2656 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2657 le32_to_cpu(bss->length));
2660 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2662 struct brcmf_scan_results *bss_list;
2663 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2667 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2668 if (bss_list->count != 0 &&
2669 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2670 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2674 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2675 for (i = 0; i < bss_list->count; i++) {
2676 bi = next_bss_le(bss_list, bi);
2677 err = brcmf_inform_single_bss(cfg, bi);
2684 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
2685 struct net_device *ndev, const u8 *bssid)
2687 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2688 struct ieee80211_channel *notify_channel;
2689 struct brcmf_bss_info_le *bi = NULL;
2690 struct ieee80211_supported_band *band;
2691 struct cfg80211_bss *bss;
2692 struct brcmu_chan ch;
2696 u16 notify_capability;
2697 u16 notify_interval;
2699 size_t notify_ielen;
2702 brcmf_dbg(TRACE, "Enter\n");
2704 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2710 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2712 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2713 buf, WL_BSS_INFO_MAX);
2715 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2719 bi = (struct brcmf_bss_info_le *)(buf + 4);
2721 ch.chspec = le16_to_cpu(bi->chanspec);
2722 cfg->d11inf.decchspec(&ch);
2724 if (ch.band == BRCMU_CHAN_BAND_2G)
2725 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2727 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2729 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2730 cfg->channel = freq;
2731 notify_channel = ieee80211_get_channel(wiphy, freq);
2733 notify_capability = le16_to_cpu(bi->capability);
2734 notify_interval = le16_to_cpu(bi->beacon_period);
2735 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2736 notify_ielen = le32_to_cpu(bi->ie_length);
2737 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2739 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2740 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2741 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2742 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2744 bss = cfg80211_inform_bss(wiphy, notify_channel,
2745 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2746 notify_capability, notify_interval,
2747 notify_ie, notify_ielen, notify_signal,
2755 cfg80211_put_bss(wiphy, bss);
2761 brcmf_dbg(TRACE, "Exit\n");
2766 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2767 struct brcmf_if *ifp)
2769 struct brcmf_bss_info_le *bi;
2770 const struct brcmf_tlv *tim;
2771 u16 beacon_interval;
2777 brcmf_dbg(TRACE, "Enter\n");
2778 if (brcmf_is_ibssmode(ifp->vif))
2781 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2782 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2783 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2785 brcmf_err("Could not get bss info %d\n", err);
2786 goto update_bss_info_out;
2789 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2790 err = brcmf_inform_single_bss(cfg, bi);
2792 goto update_bss_info_out;
2794 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2795 ie_len = le32_to_cpu(bi->ie_length);
2796 beacon_interval = le16_to_cpu(bi->beacon_period);
2798 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2800 dtim_period = tim->data[1];
2803 * active scan was done so we could not get dtim
2804 * information out of probe response.
2805 * so we speficially query dtim information to dongle.
2808 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2810 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2811 goto update_bss_info_out;
2813 dtim_period = (u8)var;
2816 update_bss_info_out:
2817 brcmf_dbg(TRACE, "Exit");
2821 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2823 struct escan_info *escan = &cfg->escan_info;
2825 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2826 if (cfg->scan_request) {
2827 escan->escan_state = WL_ESCAN_STATE_IDLE;
2828 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2830 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2831 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2834 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2836 struct brcmf_cfg80211_info *cfg =
2837 container_of(work, struct brcmf_cfg80211_info,
2838 escan_timeout_work);
2840 brcmf_inform_bss(cfg);
2841 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2844 static void brcmf_escan_timeout(unsigned long data)
2846 struct brcmf_cfg80211_info *cfg =
2847 (struct brcmf_cfg80211_info *)data;
2849 if (cfg->scan_request) {
2850 brcmf_err("timer expired\n");
2851 schedule_work(&cfg->escan_timeout_work);
2856 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2857 struct brcmf_bss_info_le *bss,
2858 struct brcmf_bss_info_le *bss_info_le)
2860 struct brcmu_chan ch_bss, ch_bss_info_le;
2862 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2863 cfg->d11inf.decchspec(&ch_bss);
2864 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2865 cfg->d11inf.decchspec(&ch_bss_info_le);
2867 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2868 ch_bss.band == ch_bss_info_le.band &&
2869 bss_info_le->SSID_len == bss->SSID_len &&
2870 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2871 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2872 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2873 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2874 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2876 /* preserve max RSSI if the measurements are
2877 * both on-channel or both off-channel
2879 if (bss_info_rssi > bss_rssi)
2880 bss->RSSI = bss_info_le->RSSI;
2881 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2882 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2883 /* preserve the on-channel rssi measurement
2884 * if the new measurement is off channel
2886 bss->RSSI = bss_info_le->RSSI;
2887 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2895 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2896 const struct brcmf_event_msg *e, void *data)
2898 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2900 struct brcmf_escan_result_le *escan_result_le;
2901 struct brcmf_bss_info_le *bss_info_le;
2902 struct brcmf_bss_info_le *bss = NULL;
2904 struct brcmf_scan_results *list;
2910 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2911 brcmf_err("scan not ready, bsscfgidx=%d\n", ifp->bsscfgidx);
2915 if (status == BRCMF_E_STATUS_PARTIAL) {
2916 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2917 escan_result_le = (struct brcmf_escan_result_le *) data;
2918 if (!escan_result_le) {
2919 brcmf_err("Invalid escan result (NULL pointer)\n");
2922 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2923 brcmf_err("Invalid bss_count %d: ignoring\n",
2924 escan_result_le->bss_count);
2927 bss_info_le = &escan_result_le->bss_info_le;
2929 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2932 if (!cfg->scan_request) {
2933 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2937 bi_length = le32_to_cpu(bss_info_le->length);
2938 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2939 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2940 brcmf_err("Invalid bss_info length %d: ignoring\n",
2945 if (!(cfg_to_wiphy(cfg)->interface_modes &
2946 BIT(NL80211_IFTYPE_ADHOC))) {
2947 if (le16_to_cpu(bss_info_le->capability) &
2948 WLAN_CAPABILITY_IBSS) {
2949 brcmf_err("Ignoring IBSS result\n");
2954 list = (struct brcmf_scan_results *)
2955 cfg->escan_info.escan_buf;
2956 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
2957 brcmf_err("Buffer is too small: ignoring\n");
2961 for (i = 0; i < list->count; i++) {
2962 bss = bss ? (struct brcmf_bss_info_le *)
2963 ((unsigned char *)bss +
2964 le32_to_cpu(bss->length)) : list->bss_info_le;
2965 if (brcmf_compare_update_same_bss(cfg, bss,
2969 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
2971 list->version = le32_to_cpu(bss_info_le->version);
2972 list->buflen += bi_length;
2975 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2976 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2978 if (cfg->scan_request) {
2979 brcmf_inform_bss(cfg);
2980 aborted = status != BRCMF_E_STATUS_SUCCESS;
2981 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
2983 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2990 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2992 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2993 brcmf_cfg80211_escan_handler);
2994 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2995 /* Init scan_timeout timer */
2996 init_timer(&cfg->escan_timeout);
2997 cfg->escan_timeout.data = (unsigned long) cfg;
2998 cfg->escan_timeout.function = brcmf_escan_timeout;
2999 INIT_WORK(&cfg->escan_timeout_work,
3000 brcmf_cfg80211_escan_timeout_worker);
3003 /* PFN result doesn't have all the info which are required by the supplicant
3004 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3005 * via wl_inform_single_bss in the required format. Escan does require the
3006 * scan request in the form of cfg80211_scan_request. For timebeing, create
3007 * cfg80211_scan_request one out of the received PNO event.
3010 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3011 const struct brcmf_event_msg *e, void *data)
3013 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3014 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3015 struct cfg80211_scan_request *request = NULL;
3016 struct cfg80211_ssid *ssid = NULL;
3017 struct ieee80211_channel *channel = NULL;
3018 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3020 int channel_req = 0;
3022 struct brcmf_pno_scanresults_le *pfn_result;
3026 brcmf_dbg(SCAN, "Enter\n");
3028 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3029 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3033 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3034 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3038 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3039 result_count = le32_to_cpu(pfn_result->count);
3040 status = le32_to_cpu(pfn_result->status);
3042 /* PFN event is limited to fit 512 bytes so we may get
3043 * multiple NET_FOUND events. For now place a warning here.
3045 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3046 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3047 if (result_count > 0) {
3050 request = kzalloc(sizeof(*request), GFP_KERNEL);
3051 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3052 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3053 if (!request || !ssid || !channel) {
3058 request->wiphy = wiphy;
3059 data += sizeof(struct brcmf_pno_scanresults_le);
3060 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3062 for (i = 0; i < result_count; i++) {
3063 netinfo = &netinfo_start[i];
3065 brcmf_err("Invalid netinfo ptr. index: %d\n",
3071 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3072 netinfo->SSID, netinfo->channel);
3073 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3074 ssid[i].ssid_len = netinfo->SSID_len;
3077 channel_req = netinfo->channel;
3078 if (channel_req <= CH_MAX_2G_CHANNEL)
3079 band = NL80211_BAND_2GHZ;
3081 band = NL80211_BAND_5GHZ;
3082 channel[i].center_freq =
3083 ieee80211_channel_to_frequency(channel_req,
3085 channel[i].band = band;
3086 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3087 request->channels[i] = &channel[i];
3088 request->n_channels++;
3091 /* assign parsed ssid array */
3092 if (request->n_ssids)
3093 request->ssids = &ssid[0];
3095 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3096 /* Abort any on-going scan */
3097 brcmf_abort_scanning(cfg);
3100 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3101 cfg->escan_info.run = brcmf_run_escan;
3102 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3104 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3107 cfg->sched_escan = true;
3108 cfg->scan_request = request;
3110 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3123 cfg80211_sched_scan_stopped(wiphy);
3127 static int brcmf_dev_pno_clean(struct net_device *ndev)
3132 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3135 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3139 brcmf_err("failed code %d\n", ret);
3144 static int brcmf_dev_pno_config(struct brcmf_if *ifp,
3145 struct cfg80211_sched_scan_request *request)
3147 struct brcmf_pno_param_le pfn_param;
3148 struct brcmf_pno_macaddr_le pfn_mac;
3153 memset(&pfn_param, 0, sizeof(pfn_param));
3154 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3156 /* set extra pno params */
3157 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3158 pfn_param.repeat = BRCMF_PNO_REPEAT;
3159 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3161 /* set up pno scan fr */
3162 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3164 err = brcmf_fil_iovar_data_set(ifp, "pfn_set", &pfn_param,
3167 brcmf_err("pfn_set failed, err=%d\n", err);
3171 /* Find out if mac randomization should be turned on */
3172 if (!(request->flags & NL80211_SCAN_FLAG_RANDOM_ADDR))
3175 pfn_mac.version = BRCMF_PFN_MACADDR_CFG_VER;
3176 pfn_mac.flags = BRCMF_PFN_MAC_OUI_ONLY | BRCMF_PFN_SET_MAC_UNASSOC;
3178 memcpy(pfn_mac.mac, request->mac_addr, ETH_ALEN);
3179 mac_mask = request->mac_addr_mask;
3180 for (i = 0; i < ETH_ALEN; i++) {
3181 pfn_mac.mac[i] &= mac_mask[i];
3182 pfn_mac.mac[i] |= get_random_int() & ~(mac_mask[i]);
3184 /* Clear multi bit */
3185 pfn_mac.mac[0] &= 0xFE;
3186 /* Set locally administered */
3187 pfn_mac.mac[0] |= 0x02;
3189 err = brcmf_fil_iovar_data_set(ifp, "pfn_macaddr", &pfn_mac,
3192 brcmf_err("pfn_macaddr failed, err=%d\n", err);
3198 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3199 struct net_device *ndev,
3200 struct cfg80211_sched_scan_request *request)
3202 struct brcmf_if *ifp = netdev_priv(ndev);
3203 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3204 struct brcmf_pno_net_param_le pfn;
3208 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3209 request->n_match_sets, request->n_ssids);
3210 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3211 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3214 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3215 brcmf_err("Scanning suppressed: status (%lu)\n",
3220 if (!request->n_ssids || !request->n_match_sets) {
3221 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3226 if (request->n_ssids > 0) {
3227 for (i = 0; i < request->n_ssids; i++) {
3228 /* Active scan req for ssids */
3229 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3230 request->ssids[i].ssid);
3232 /* match_set ssids is a supert set of n_ssid list,
3233 * so we need not add these set separately.
3238 if (request->n_match_sets > 0) {
3239 /* clean up everything */
3240 ret = brcmf_dev_pno_clean(ndev);
3242 brcmf_err("failed error=%d\n", ret);
3247 if (brcmf_dev_pno_config(ifp, request))
3250 /* configure each match set */
3251 for (i = 0; i < request->n_match_sets; i++) {
3252 struct cfg80211_ssid *ssid;
3255 ssid = &request->match_sets[i].ssid;
3256 ssid_len = ssid->ssid_len;
3259 brcmf_err("skip broadcast ssid\n");
3262 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3263 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3264 pfn.wsec = cpu_to_le32(0);
3265 pfn.infra = cpu_to_le32(1);
3266 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3267 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3268 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3269 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3271 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3272 ret == 0 ? "set" : "failed", ssid->ssid);
3274 /* Enable the PNO */
3275 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3276 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3286 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3287 struct net_device *ndev)
3289 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3291 brcmf_dbg(SCAN, "enter\n");
3292 brcmf_dev_pno_clean(ndev);
3293 if (cfg->sched_escan)
3294 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3298 static __always_inline void brcmf_delay(u32 ms)
3300 if (ms < 1000 / HZ) {
3308 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3309 u8 *pattern, u32 patternsize, u8 *mask,
3312 struct brcmf_fil_wowl_pattern_le *filter;
3319 masksize = (patternsize + 7) / 8;
3320 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3322 bufsize = sizeof(*filter) + patternsize + masksize;
3323 buf = kzalloc(bufsize, GFP_KERNEL);
3326 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3328 memcpy(filter->cmd, cmd, 4);
3329 filter->masksize = cpu_to_le32(masksize);
3330 filter->offset = cpu_to_le32(packet_offset);
3331 filter->patternoffset = cpu_to_le32(patternoffset);
3332 filter->patternsize = cpu_to_le32(patternsize);
3333 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3335 if ((mask) && (masksize))
3336 memcpy(buf + sizeof(*filter), mask, masksize);
3337 if ((pattern) && (patternsize))
3338 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3340 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3347 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
3350 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3351 struct brcmf_pno_scanresults_le *pfn_result;
3352 struct brcmf_pno_net_info_le *netinfo;
3354 brcmf_dbg(SCAN, "Enter\n");
3356 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3357 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3361 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3363 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3364 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
3368 if (le32_to_cpu(pfn_result->count) < 1) {
3369 brcmf_err("Invalid result count, expected 1 (%d)\n",
3370 le32_to_cpu(pfn_result->count));
3374 data += sizeof(struct brcmf_pno_scanresults_le);
3375 netinfo = (struct brcmf_pno_net_info_le *)data;
3376 memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
3377 cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
3378 cfg->wowl.nd->n_channels = 1;
3379 cfg->wowl.nd->channels[0] =
3380 ieee80211_channel_to_frequency(netinfo->channel,
3381 netinfo->channel <= CH_MAX_2G_CHANNEL ?
3382 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
3383 cfg->wowl.nd_info->n_matches = 1;
3384 cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
3386 /* Inform (the resume task) that the net detect information was recvd */
3387 cfg->wowl.nd_data_completed = true;
3388 wake_up(&cfg->wowl.nd_data_wait);
3395 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3397 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3398 struct brcmf_wowl_wakeind_le wake_ind_le;
3399 struct cfg80211_wowlan_wakeup wakeup_data;
3400 struct cfg80211_wowlan_wakeup *wakeup;
3405 err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
3406 sizeof(wake_ind_le));
3408 brcmf_err("Get wowl_wakeind failed, err = %d\n", err);
3412 wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
3413 if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
3414 BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
3415 BRCMF_WOWL_PFN_FOUND)) {
3416 wakeup = &wakeup_data;
3417 memset(&wakeup_data, 0, sizeof(wakeup_data));
3418 wakeup_data.pattern_idx = -1;
3420 if (wakeind & BRCMF_WOWL_MAGIC) {
3421 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3422 wakeup_data.magic_pkt = true;
3424 if (wakeind & BRCMF_WOWL_DIS) {
3425 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3426 wakeup_data.disconnect = true;
3428 if (wakeind & BRCMF_WOWL_BCN) {
3429 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3430 wakeup_data.disconnect = true;
3432 if (wakeind & BRCMF_WOWL_RETR) {
3433 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3434 wakeup_data.disconnect = true;
3436 if (wakeind & BRCMF_WOWL_NET) {
3437 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3438 /* For now always map to pattern 0, no API to get
3439 * correct information available at the moment.
3441 wakeup_data.pattern_idx = 0;
3443 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
3444 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3445 timeout = wait_event_timeout(cfg->wowl.nd_data_wait,
3446 cfg->wowl.nd_data_completed,
3447 BRCMF_ND_INFO_TIMEOUT);
3449 brcmf_err("No result for wowl net detect\n");
3451 wakeup_data.net_detect = cfg->wowl.nd_info;
3453 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
3454 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3455 wakeup_data.gtk_rekey_failure = true;
3460 cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
3465 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
3469 #endif /* CONFIG_PM */
3471 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3473 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3474 struct net_device *ndev = cfg_to_ndev(cfg);
3475 struct brcmf_if *ifp = netdev_priv(ndev);
3477 brcmf_dbg(TRACE, "Enter\n");
3479 if (cfg->wowl.active) {
3480 brcmf_report_wowl_wakeind(wiphy, ifp);
3481 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3482 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3483 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3484 brcmf_configure_arp_nd_offload(ifp, true);
3485 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3486 cfg->wowl.pre_pmmode);
3487 cfg->wowl.active = false;
3488 if (cfg->wowl.nd_enabled) {
3489 brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev);
3490 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3491 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3492 brcmf_notify_sched_scan_results);
3493 cfg->wowl.nd_enabled = false;
3499 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3500 struct brcmf_if *ifp,
3501 struct cfg80211_wowlan *wowl)
3506 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3508 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
3509 brcmf_configure_arp_nd_offload(ifp, false);
3510 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
3511 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3514 if (wowl->disconnect)
3515 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3516 if (wowl->magic_pkt)
3517 wowl_config |= BRCMF_WOWL_MAGIC;
3518 if ((wowl->patterns) && (wowl->n_patterns)) {
3519 wowl_config |= BRCMF_WOWL_NET;
3520 for (i = 0; i < wowl->n_patterns; i++) {
3521 brcmf_config_wowl_pattern(ifp, "add",
3522 (u8 *)wowl->patterns[i].pattern,
3523 wowl->patterns[i].pattern_len,
3524 (u8 *)wowl->patterns[i].mask,
3525 wowl->patterns[i].pkt_offset);
3528 if (wowl->nd_config) {
3529 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
3531 wowl_config |= BRCMF_WOWL_PFN_FOUND;
3533 cfg->wowl.nd_data_completed = false;
3534 cfg->wowl.nd_enabled = true;
3535 /* Now reroute the event for PFN to the wowl function. */
3536 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
3537 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
3538 brcmf_wowl_nd_results);
3540 if (wowl->gtk_rekey_failure)
3541 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
3542 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
3543 wowl_config |= BRCMF_WOWL_UNASSOC;
3545 brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", "clear", strlen("clear"));
3546 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3547 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3548 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3549 cfg->wowl.active = true;
3552 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3553 struct cfg80211_wowlan *wowl)
3555 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3556 struct net_device *ndev = cfg_to_ndev(cfg);
3557 struct brcmf_if *ifp = netdev_priv(ndev);
3558 struct brcmf_cfg80211_vif *vif;
3560 brcmf_dbg(TRACE, "Enter\n");
3562 /* if the primary net_device is not READY there is nothing
3563 * we can do but pray resume goes smoothly.
3565 if (!check_vif_up(ifp->vif))
3568 /* Stop scheduled scan */
3569 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
3570 brcmf_cfg80211_sched_scan_stop(wiphy, ndev);
3572 /* end any scanning */
3573 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3574 brcmf_abort_scanning(cfg);
3577 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3578 list_for_each_entry(vif, &cfg->vif_list, list) {
3579 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3581 /* While going to suspend if associated with AP
3582 * disassociate from AP to save power while system is
3583 * in suspended state
3585 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3586 /* Make sure WPA_Supplicant receives all the event
3587 * generated due to DISASSOC call to the fw to keep
3588 * the state fw and WPA_Supplicant state consistent
3593 brcmf_set_mpc(ifp, 1);
3596 /* Configure WOWL paramaters */
3597 brcmf_configure_wowl(cfg, ifp, wowl);
3601 brcmf_dbg(TRACE, "Exit\n");
3602 /* clear any scanning activity */
3603 cfg->scan_status = 0;
3608 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
3610 struct brcmf_pmk_list_le *pmk_list;
3615 pmk_list = &cfg->pmk_list;
3616 npmk = le32_to_cpu(pmk_list->npmk);
3618 brcmf_dbg(CONN, "No of elements %d\n", npmk);
3619 for (i = 0; i < npmk; i++)
3620 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
3622 err = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
3629 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3630 struct cfg80211_pmksa *pmksa)
3632 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3633 struct brcmf_if *ifp = netdev_priv(ndev);
3634 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3638 brcmf_dbg(TRACE, "Enter\n");
3639 if (!check_vif_up(ifp->vif))
3642 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3643 for (i = 0; i < npmk; i++)
3644 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
3646 if (i < BRCMF_MAXPMKID) {
3647 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
3648 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
3651 cfg->pmk_list.npmk = cpu_to_le32(npmk);
3654 brcmf_err("Too many PMKSA entries cached %d\n", npmk);
3658 brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmk[npmk].bssid);
3659 for (i = 0; i < WLAN_PMKID_LEN; i += 4)
3660 brcmf_dbg(CONN, "%02x %02x %02x %02x\n", pmk[npmk].pmkid[i],
3661 pmk[npmk].pmkid[i + 1], pmk[npmk].pmkid[i + 2],
3662 pmk[npmk].pmkid[i + 3]);
3664 err = brcmf_update_pmklist(cfg, ifp);
3666 brcmf_dbg(TRACE, "Exit\n");
3671 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3672 struct cfg80211_pmksa *pmksa)
3674 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3675 struct brcmf_if *ifp = netdev_priv(ndev);
3676 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
3680 brcmf_dbg(TRACE, "Enter\n");
3681 if (!check_vif_up(ifp->vif))
3684 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", &pmksa->bssid);
3686 npmk = le32_to_cpu(cfg->pmk_list.npmk);
3687 for (i = 0; i < npmk; i++)
3688 if (!memcmp(&pmksa->bssid, &pmk[i].bssid, ETH_ALEN))
3691 if ((npmk > 0) && (i < npmk)) {
3692 for (; i < (npmk - 1); i++) {
3693 memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
3694 memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
3697 memset(&pmk[i], 0, sizeof(*pmk));
3698 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
3700 brcmf_err("Cache entry not found\n");
3704 err = brcmf_update_pmklist(cfg, ifp);
3706 brcmf_dbg(TRACE, "Exit\n");
3712 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3714 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3715 struct brcmf_if *ifp = netdev_priv(ndev);
3718 brcmf_dbg(TRACE, "Enter\n");
3719 if (!check_vif_up(ifp->vif))
3722 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
3723 err = brcmf_update_pmklist(cfg, ifp);
3725 brcmf_dbg(TRACE, "Exit\n");
3730 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3735 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3737 brcmf_err("auth error %d\n", err);
3741 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3743 brcmf_err("wsec error %d\n", err);
3746 /* set upper-layer auth */
3747 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3749 brcmf_err("wpa_auth error %d\n", err);
3756 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3759 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3761 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3765 brcmf_configure_wpaie(struct brcmf_if *ifp,
3766 const struct brcmf_vs_tlv *wpa_ie,
3769 u32 auth = 0; /* d11 open authentication */
3781 u32 wme_bss_disable;
3783 brcmf_dbg(TRACE, "Enter\n");
3787 len = wpa_ie->len + TLV_HDR_LEN;
3788 data = (u8 *)wpa_ie;
3789 offset = TLV_HDR_LEN;
3791 offset += VS_IE_FIXED_HDR_LEN;
3793 offset += WPA_IE_VERSION_LEN;
3795 /* check for multicast cipher suite */
3796 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3798 brcmf_err("no multicast cipher suite\n");
3802 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3804 brcmf_err("ivalid OUI\n");
3807 offset += TLV_OUI_LEN;
3809 /* pick up multicast cipher */
3810 switch (data[offset]) {
3811 case WPA_CIPHER_NONE:
3814 case WPA_CIPHER_WEP_40:
3815 case WPA_CIPHER_WEP_104:
3818 case WPA_CIPHER_TKIP:
3819 gval = TKIP_ENABLED;
3821 case WPA_CIPHER_AES_CCM:
3826 brcmf_err("Invalid multi cast cipher info\n");
3831 /* walk thru unicast cipher list and pick up what we recognize */
3832 count = data[offset] + (data[offset + 1] << 8);
3833 offset += WPA_IE_SUITE_COUNT_LEN;
3834 /* Check for unicast suite(s) */
3835 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3837 brcmf_err("no unicast cipher suite\n");
3840 for (i = 0; i < count; i++) {
3841 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3843 brcmf_err("ivalid OUI\n");
3846 offset += TLV_OUI_LEN;
3847 switch (data[offset]) {
3848 case WPA_CIPHER_NONE:
3850 case WPA_CIPHER_WEP_40:
3851 case WPA_CIPHER_WEP_104:
3852 pval |= WEP_ENABLED;
3854 case WPA_CIPHER_TKIP:
3855 pval |= TKIP_ENABLED;
3857 case WPA_CIPHER_AES_CCM:
3858 pval |= AES_ENABLED;
3861 brcmf_err("Ivalid unicast security info\n");
3865 /* walk thru auth management suite list and pick up what we recognize */
3866 count = data[offset] + (data[offset + 1] << 8);
3867 offset += WPA_IE_SUITE_COUNT_LEN;
3868 /* Check for auth key management suite(s) */
3869 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3871 brcmf_err("no auth key mgmt suite\n");
3874 for (i = 0; i < count; i++) {
3875 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3877 brcmf_err("ivalid OUI\n");
3880 offset += TLV_OUI_LEN;
3881 switch (data[offset]) {
3883 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3884 wpa_auth |= WPA_AUTH_NONE;
3886 case RSN_AKM_UNSPECIFIED:
3887 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3888 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3889 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3892 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3893 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3894 (wpa_auth |= WPA_AUTH_PSK);
3897 brcmf_err("Ivalid key mgmt info\n");
3903 wme_bss_disable = 1;
3904 if ((offset + RSN_CAP_LEN) <= len) {
3905 rsn_cap = data[offset] + (data[offset + 1] << 8);
3906 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3907 wme_bss_disable = 0;
3909 /* set wme_bss_disable to sync RSN Capabilities */
3910 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3913 brcmf_err("wme_bss_disable error %d\n", err);
3917 /* FOR WPS , set SES_OW_ENABLED */
3918 wsec = (pval | gval | SES_OW_ENABLED);
3921 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3923 brcmf_err("auth error %d\n", err);
3927 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3929 brcmf_err("wsec error %d\n", err);
3932 /* set upper-layer auth */
3933 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3935 brcmf_err("wpa_auth error %d\n", err);
3944 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3945 struct parsed_vndr_ies *vndr_ies)
3947 struct brcmf_vs_tlv *vndrie;
3948 struct brcmf_tlv *ie;
3949 struct parsed_vndr_ie_info *parsed_info;
3952 remaining_len = (s32)vndr_ie_len;
3953 memset(vndr_ies, 0, sizeof(*vndr_ies));
3955 ie = (struct brcmf_tlv *)vndr_ie_buf;
3957 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3959 vndrie = (struct brcmf_vs_tlv *)ie;
3960 /* len should be bigger than OUI length + one */
3961 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3962 brcmf_err("invalid vndr ie. length is too small %d\n",
3966 /* if wpa or wme ie, do not add ie */
3967 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3968 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3969 (vndrie->oui_type == WME_OUI_TYPE))) {
3970 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3974 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3976 /* save vndr ie information */
3977 parsed_info->ie_ptr = (char *)vndrie;
3978 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3979 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3983 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3984 parsed_info->vndrie.oui[0],
3985 parsed_info->vndrie.oui[1],
3986 parsed_info->vndrie.oui[2],
3987 parsed_info->vndrie.oui_type);
3989 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3992 remaining_len -= (ie->len + TLV_HDR_LEN);
3993 if (remaining_len <= TLV_HDR_LEN)
3996 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4003 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4006 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
4007 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
4009 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4011 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4013 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4015 return ie_len + VNDR_IE_HDR_SIZE;
4018 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4019 const u8 *vndr_ie_buf, u32 vndr_ie_len)
4021 struct brcmf_if *ifp;
4022 struct vif_saved_ie *saved_ie;
4026 u8 *mgmt_ie_buf = NULL;
4027 int mgmt_ie_buf_len;
4029 u32 del_add_ie_buf_len = 0;
4030 u32 total_ie_buf_len = 0;
4031 u32 parsed_ie_buf_len = 0;
4032 struct parsed_vndr_ies old_vndr_ies;
4033 struct parsed_vndr_ies new_vndr_ies;
4034 struct parsed_vndr_ie_info *vndrie_info;
4037 int remained_buf_len;
4042 saved_ie = &vif->saved_ie;
4044 brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4046 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4049 curr_ie_buf = iovar_ie_buf;
4051 case BRCMF_VNDR_IE_PRBREQ_FLAG:
4052 mgmt_ie_buf = saved_ie->probe_req_ie;
4053 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4054 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4056 case BRCMF_VNDR_IE_PRBRSP_FLAG:
4057 mgmt_ie_buf = saved_ie->probe_res_ie;
4058 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4059 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4061 case BRCMF_VNDR_IE_BEACON_FLAG:
4062 mgmt_ie_buf = saved_ie->beacon_ie;
4063 mgmt_ie_len = &saved_ie->beacon_ie_len;
4064 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4066 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4067 mgmt_ie_buf = saved_ie->assoc_req_ie;
4068 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4069 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4073 brcmf_err("not suitable type\n");
4077 if (vndr_ie_len > mgmt_ie_buf_len) {
4079 brcmf_err("extra IE size too big\n");
4083 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4084 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4086 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4087 for (i = 0; i < new_vndr_ies.count; i++) {
4088 vndrie_info = &new_vndr_ies.ie_info[i];
4089 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4090 vndrie_info->ie_len);
4091 parsed_ie_buf_len += vndrie_info->ie_len;
4095 if (mgmt_ie_buf && *mgmt_ie_len) {
4096 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4097 (memcmp(mgmt_ie_buf, curr_ie_buf,
4098 parsed_ie_buf_len) == 0)) {
4099 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4103 /* parse old vndr_ie */
4104 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4106 /* make a command to delete old ie */
4107 for (i = 0; i < old_vndr_ies.count; i++) {
4108 vndrie_info = &old_vndr_ies.ie_info[i];
4110 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4111 vndrie_info->vndrie.id,
4112 vndrie_info->vndrie.len,
4113 vndrie_info->vndrie.oui[0],
4114 vndrie_info->vndrie.oui[1],
4115 vndrie_info->vndrie.oui[2]);
4117 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4118 vndrie_info->ie_ptr,
4119 vndrie_info->ie_len,
4121 curr_ie_buf += del_add_ie_buf_len;
4122 total_ie_buf_len += del_add_ie_buf_len;
4127 /* Add if there is any extra IE */
4128 if (mgmt_ie_buf && parsed_ie_buf_len) {
4131 remained_buf_len = mgmt_ie_buf_len;
4133 /* make a command to add new ie */
4134 for (i = 0; i < new_vndr_ies.count; i++) {
4135 vndrie_info = &new_vndr_ies.ie_info[i];
4137 /* verify remained buf size before copy data */
4138 if (remained_buf_len < (vndrie_info->vndrie.len +
4139 VNDR_IE_VSIE_OFFSET)) {
4140 brcmf_err("no space in mgmt_ie_buf: len left %d",
4144 remained_buf_len -= (vndrie_info->ie_len +
4145 VNDR_IE_VSIE_OFFSET);
4147 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4148 vndrie_info->vndrie.id,
4149 vndrie_info->vndrie.len,
4150 vndrie_info->vndrie.oui[0],
4151 vndrie_info->vndrie.oui[1],
4152 vndrie_info->vndrie.oui[2]);
4154 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4155 vndrie_info->ie_ptr,
4156 vndrie_info->ie_len,
4159 /* save the parsed IE in wl struct */
4160 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4161 vndrie_info->ie_len);
4162 *mgmt_ie_len += vndrie_info->ie_len;
4164 curr_ie_buf += del_add_ie_buf_len;
4165 total_ie_buf_len += del_add_ie_buf_len;
4168 if (total_ie_buf_len) {
4169 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4172 brcmf_err("vndr ie set error : %d\n", err);
4176 kfree(iovar_ie_buf);
4180 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4183 BRCMF_VNDR_IE_PRBREQ_FLAG,
4184 BRCMF_VNDR_IE_PRBRSP_FLAG,
4185 BRCMF_VNDR_IE_BEACON_FLAG
4189 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4190 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4192 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4197 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4198 struct cfg80211_beacon_data *beacon)
4202 /* Set Beacon IEs to FW */
4203 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4204 beacon->tail, beacon->tail_len);
4206 brcmf_err("Set Beacon IE Failed\n");
4209 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4211 /* Set Probe Response IEs to FW */
4212 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4213 beacon->proberesp_ies,
4214 beacon->proberesp_ies_len);
4216 brcmf_err("Set Probe Resp IE Failed\n");
4218 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4224 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4225 struct cfg80211_ap_settings *settings)
4228 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4229 struct brcmf_if *ifp = netdev_priv(ndev);
4230 const struct brcmf_tlv *ssid_ie;
4231 const struct brcmf_tlv *country_ie;
4232 struct brcmf_ssid_le ssid_le;
4234 const struct brcmf_tlv *rsn_ie;
4235 const struct brcmf_vs_tlv *wpa_ie;
4236 struct brcmf_join_params join_params;
4237 enum nl80211_iftype dev_role;
4238 struct brcmf_fil_bss_enable_le bss_enable;
4243 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4244 settings->chandef.chan->hw_value,
4245 settings->chandef.center_freq1, settings->chandef.width,
4246 settings->beacon_interval, settings->dtim_period);
4247 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4248 settings->ssid, settings->ssid_len, settings->auth_type,
4249 settings->inactivity_timeout);
4250 dev_role = ifp->vif->wdev.iftype;
4251 mbss = ifp->vif->mbss;
4253 /* store current 11d setting */
4254 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4255 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4256 settings->beacon.tail_len,
4258 is_11d = country_ie ? 1 : 0;
4260 memset(&ssid_le, 0, sizeof(ssid_le));
4261 if (settings->ssid == NULL || settings->ssid_len == 0) {
4262 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4263 ssid_ie = brcmf_parse_tlvs(
4264 (u8 *)&settings->beacon.head[ie_offset],
4265 settings->beacon.head_len - ie_offset,
4270 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4271 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4272 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4274 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4275 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4279 brcmf_set_mpc(ifp, 0);
4280 brcmf_configure_arp_nd_offload(ifp, false);
4283 /* find the RSN_IE */
4284 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4285 settings->beacon.tail_len, WLAN_EID_RSN);
4287 /* find the WPA_IE */
4288 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4289 settings->beacon.tail_len);
4291 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4292 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4293 if (wpa_ie != NULL) {
4295 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4299 struct brcmf_vs_tlv *tmp_ie;
4301 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4304 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4309 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4310 brcmf_configure_opensecurity(ifp);
4313 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4316 chanspec = chandef_to_chanspec(&cfg->d11inf,
4317 &settings->chandef);
4318 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4320 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4325 if (is_11d != ifp->vif->is_11d) {
4326 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4329 brcmf_err("Regulatory Set Error, %d\n", err);
4333 if (settings->beacon_interval) {
4334 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4335 settings->beacon_interval);
4337 brcmf_err("Beacon Interval Set Error, %d\n",
4342 if (settings->dtim_period) {
4343 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4344 settings->dtim_period);
4346 brcmf_err("DTIM Interval Set Error, %d\n", err);
4351 if ((dev_role == NL80211_IFTYPE_AP) &&
4352 ((ifp->ifidx == 0) ||
4353 !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB))) {
4354 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4356 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4359 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4362 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4364 brcmf_err("SET INFRA error %d\n", err);
4367 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4368 /* Multiple-BSS should use same 11d configuration */
4372 if (dev_role == NL80211_IFTYPE_AP) {
4373 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4374 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4376 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4378 brcmf_err("setting AP mode failed %d\n", err);
4381 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4383 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4386 /* On DOWN the firmware removes the WEP keys, reconfigure
4387 * them if they were set.
4389 brcmf_cfg80211_reconfigure_wep(ifp);
4391 memset(&join_params, 0, sizeof(join_params));
4392 /* join parameters starts with ssid */
4393 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4395 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4396 &join_params, sizeof(join_params));
4398 brcmf_err("SET SSID error (%d)\n", err);
4401 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4403 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4406 brcmf_err("setting ssid failed %d\n", err);
4409 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4410 bss_enable.enable = cpu_to_le32(1);
4411 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4412 sizeof(bss_enable));
4414 brcmf_err("bss_enable config failed %d\n", err);
4418 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4420 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4421 brcmf_net_setcarrier(ifp, true);
4424 if ((err) && (!mbss)) {
4425 brcmf_set_mpc(ifp, 1);
4426 brcmf_configure_arp_nd_offload(ifp, true);
4431 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4433 struct brcmf_if *ifp = netdev_priv(ndev);
4435 struct brcmf_fil_bss_enable_le bss_enable;
4436 struct brcmf_join_params join_params;
4438 brcmf_dbg(TRACE, "Enter\n");
4440 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4441 /* Due to most likely deauths outstanding we sleep */
4442 /* first to make sure they get processed by fw. */
4445 if (ifp->vif->mbss) {
4446 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4450 memset(&join_params, 0, sizeof(join_params));
4451 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4452 &join_params, sizeof(join_params));
4454 brcmf_err("SET SSID error (%d)\n", err);
4455 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4457 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4458 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4460 brcmf_err("setting AP mode failed %d\n", err);
4461 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4463 brcmf_err("setting INFRA mode failed %d\n", err);
4464 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4465 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4466 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4469 brcmf_err("restoring REGULATORY setting failed %d\n",
4471 /* Bring device back up so it can be used again */
4472 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4474 brcmf_err("BRCMF_C_UP error %d\n", err);
4476 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
4477 bss_enable.enable = cpu_to_le32(0);
4478 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4479 sizeof(bss_enable));
4481 brcmf_err("bss_enable config failed %d\n", err);
4483 brcmf_set_mpc(ifp, 1);
4484 brcmf_configure_arp_nd_offload(ifp, true);
4485 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4486 brcmf_net_setcarrier(ifp, false);
4492 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4493 struct cfg80211_beacon_data *info)
4495 struct brcmf_if *ifp = netdev_priv(ndev);
4498 brcmf_dbg(TRACE, "Enter\n");
4500 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4506 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4507 struct station_del_parameters *params)
4509 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4510 struct brcmf_scb_val_le scbval;
4511 struct brcmf_if *ifp = netdev_priv(ndev);
4517 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4519 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4520 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4521 if (!check_vif_up(ifp->vif))
4524 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4525 scbval.val = cpu_to_le32(params->reason_code);
4526 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4527 &scbval, sizeof(scbval));
4529 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4531 brcmf_dbg(TRACE, "Exit\n");
4536 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4537 const u8 *mac, struct station_parameters *params)
4539 struct brcmf_if *ifp = netdev_priv(ndev);
4542 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4543 params->sta_flags_mask, params->sta_flags_set);
4545 /* Ignore all 00 MAC */
4546 if (is_zero_ether_addr(mac))
4549 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4552 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4553 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4554 (void *)mac, ETH_ALEN);
4556 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4557 (void *)mac, ETH_ALEN);
4559 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4565 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4566 struct wireless_dev *wdev,
4567 u16 frame_type, bool reg)
4569 struct brcmf_cfg80211_vif *vif;
4572 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4574 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4575 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4577 vif->mgmt_rx_reg |= BIT(mgmt_type);
4579 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4584 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4585 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4587 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4588 struct ieee80211_channel *chan = params->chan;
4589 const u8 *buf = params->buf;
4590 size_t len = params->len;
4591 const struct ieee80211_mgmt *mgmt;
4592 struct brcmf_cfg80211_vif *vif;
4596 struct brcmf_fil_action_frame_le *action_frame;
4597 struct brcmf_fil_af_params_le *af_params;
4602 brcmf_dbg(TRACE, "Enter\n");
4606 mgmt = (const struct ieee80211_mgmt *)buf;
4608 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4609 brcmf_err("Driver only allows MGMT packet type\n");
4613 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4615 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4616 /* Right now the only reason to get a probe response */
4617 /* is for p2p listen response or for p2p GO from */
4618 /* wpa_supplicant. Unfortunately the probe is send */
4619 /* on primary ndev, while dongle wants it on the p2p */
4620 /* vif. Since this is only reason for a probe */
4621 /* response to be sent, the vif is taken from cfg. */
4622 /* If ever desired to send proberesp for non p2p */
4623 /* response then data should be checked for */
4624 /* "DIRECT-". Note in future supplicant will take */
4625 /* dedicated p2p wdev to do this and then this 'hack'*/
4626 /* is not needed anymore. */
4627 ie_offset = DOT11_MGMT_HDR_LEN +
4628 DOT11_BCN_PRB_FIXED_LEN;
4629 ie_len = len - ie_offset;
4630 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4631 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4632 err = brcmf_vif_set_mgmt_ie(vif,
4633 BRCMF_VNDR_IE_PRBRSP_FLAG,
4636 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4638 } else if (ieee80211_is_action(mgmt->frame_control)) {
4639 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4640 if (af_params == NULL) {
4641 brcmf_err("unable to allocate frame\n");
4645 action_frame = &af_params->action_frame;
4646 /* Add the packet Id */
4647 action_frame->packet_id = cpu_to_le32(*cookie);
4649 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4650 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4651 /* Add the length exepted for 802.11 header */
4652 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4653 /* Add the channel. Use the one specified as parameter if any or
4654 * the current one (got from the firmware) otherwise
4657 freq = chan->center_freq;
4659 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4661 chan_nr = ieee80211_frequency_to_channel(freq);
4662 af_params->channel = cpu_to_le32(chan_nr);
4664 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4665 le16_to_cpu(action_frame->len));
4667 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4668 *cookie, le16_to_cpu(action_frame->len), freq);
4670 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4673 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4677 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4678 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4687 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4688 struct wireless_dev *wdev,
4691 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4692 struct brcmf_cfg80211_vif *vif;
4695 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4697 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4699 brcmf_err("No p2p device available for probe response\n");
4703 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4708 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4709 struct wireless_dev *wdev,
4710 enum nl80211_crit_proto_id proto,
4713 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4714 struct brcmf_cfg80211_vif *vif;
4716 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4718 /* only DHCP support for now */
4719 if (proto != NL80211_CRIT_PROTO_DHCP)
4722 /* suppress and abort scanning */
4723 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4724 brcmf_abort_scanning(cfg);
4726 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4729 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4730 struct wireless_dev *wdev)
4732 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4733 struct brcmf_cfg80211_vif *vif;
4735 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4737 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4738 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4742 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4743 const struct brcmf_event_msg *e, void *data)
4745 switch (e->reason) {
4746 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4747 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4749 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4750 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4751 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4753 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4754 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4755 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4762 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4767 case NL80211_TDLS_DISCOVERY_REQ:
4768 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4770 case NL80211_TDLS_SETUP:
4771 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4773 case NL80211_TDLS_TEARDOWN:
4774 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4777 brcmf_err("unsupported operation: %d\n", oper);
4783 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4784 struct net_device *ndev, const u8 *peer,
4785 enum nl80211_tdls_operation oper)
4787 struct brcmf_if *ifp;
4788 struct brcmf_tdls_iovar_le info;
4791 ret = brcmf_convert_nl80211_tdls_oper(oper);
4795 ifp = netdev_priv(ndev);
4796 memset(&info, 0, sizeof(info));
4797 info.mode = (u8)ret;
4799 memcpy(info.ea, peer, ETH_ALEN);
4801 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4802 &info, sizeof(info));
4804 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4811 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
4812 struct cfg80211_gtk_rekey_data *gtk)
4814 struct brcmf_if *ifp = netdev_priv(ndev);
4815 struct brcmf_gtk_keyinfo_le gtk_le;
4818 brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
4820 memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
4821 memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
4822 memcpy(gtk_le.replay_counter, gtk->replay_ctr,
4823 sizeof(gtk_le.replay_counter));
4825 ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
4828 brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret);
4834 static struct cfg80211_ops brcmf_cfg80211_ops = {
4835 .add_virtual_intf = brcmf_cfg80211_add_iface,
4836 .del_virtual_intf = brcmf_cfg80211_del_iface,
4837 .change_virtual_intf = brcmf_cfg80211_change_iface,
4838 .scan = brcmf_cfg80211_scan,
4839 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4840 .join_ibss = brcmf_cfg80211_join_ibss,
4841 .leave_ibss = brcmf_cfg80211_leave_ibss,
4842 .get_station = brcmf_cfg80211_get_station,
4843 .dump_station = brcmf_cfg80211_dump_station,
4844 .set_tx_power = brcmf_cfg80211_set_tx_power,
4845 .get_tx_power = brcmf_cfg80211_get_tx_power,
4846 .add_key = brcmf_cfg80211_add_key,
4847 .del_key = brcmf_cfg80211_del_key,
4848 .get_key = brcmf_cfg80211_get_key,
4849 .set_default_key = brcmf_cfg80211_config_default_key,
4850 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4851 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4852 .connect = brcmf_cfg80211_connect,
4853 .disconnect = brcmf_cfg80211_disconnect,
4854 .suspend = brcmf_cfg80211_suspend,
4855 .resume = brcmf_cfg80211_resume,
4856 .set_pmksa = brcmf_cfg80211_set_pmksa,
4857 .del_pmksa = brcmf_cfg80211_del_pmksa,
4858 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4859 .start_ap = brcmf_cfg80211_start_ap,
4860 .stop_ap = brcmf_cfg80211_stop_ap,
4861 .change_beacon = brcmf_cfg80211_change_beacon,
4862 .del_station = brcmf_cfg80211_del_station,
4863 .change_station = brcmf_cfg80211_change_station,
4864 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4865 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4866 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4867 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4868 .remain_on_channel = brcmf_p2p_remain_on_channel,
4869 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4870 .start_p2p_device = brcmf_p2p_start_device,
4871 .stop_p2p_device = brcmf_p2p_stop_device,
4872 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4873 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4874 .tdls_oper = brcmf_cfg80211_tdls_oper,
4877 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4878 enum nl80211_iftype type,
4881 struct brcmf_cfg80211_vif *vif_walk;
4882 struct brcmf_cfg80211_vif *vif;
4885 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4887 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4889 return ERR_PTR(-ENOMEM);
4891 vif->wdev.wiphy = cfg->wiphy;
4892 vif->wdev.iftype = type;
4894 vif->pm_block = pm_block;
4896 brcmf_init_prof(&vif->profile);
4898 if (type == NL80211_IFTYPE_AP) {
4900 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4901 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4909 list_add_tail(&vif->list, &cfg->vif_list);
4913 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4915 list_del(&vif->list);
4919 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4921 struct brcmf_cfg80211_vif *vif;
4922 struct brcmf_if *ifp;
4924 ifp = netdev_priv(ndev);
4928 brcmf_free_vif(vif);
4932 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4934 u32 event = e->event_code;
4935 u32 status = e->status;
4937 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4938 brcmf_dbg(CONN, "Processing set ssid\n");
4945 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4947 u32 event = e->event_code;
4948 u16 flags = e->flags;
4950 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4951 (event == BRCMF_E_DISASSOC_IND) ||
4952 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4953 brcmf_dbg(CONN, "Processing link down\n");
4959 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4960 const struct brcmf_event_msg *e)
4962 u32 event = e->event_code;
4963 u32 status = e->status;
4965 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4966 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4967 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4971 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4972 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4979 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4981 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4983 kfree(conn_info->req_ie);
4984 conn_info->req_ie = NULL;
4985 conn_info->req_ie_len = 0;
4986 kfree(conn_info->resp_ie);
4987 conn_info->resp_ie = NULL;
4988 conn_info->resp_ie_len = 0;
4991 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4992 struct brcmf_if *ifp)
4994 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4995 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5000 brcmf_clear_assoc_ies(cfg);
5002 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
5003 cfg->extra_buf, WL_ASSOC_INFO_MAX);
5005 brcmf_err("could not get assoc info (%d)\n", err);
5009 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
5010 req_len = le32_to_cpu(assoc_info->req_len);
5011 resp_len = le32_to_cpu(assoc_info->resp_len);
5013 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
5017 brcmf_err("could not get assoc req (%d)\n", err);
5020 conn_info->req_ie_len = req_len;
5022 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
5025 conn_info->req_ie_len = 0;
5026 conn_info->req_ie = NULL;
5029 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
5033 brcmf_err("could not get assoc resp (%d)\n", err);
5036 conn_info->resp_ie_len = resp_len;
5037 conn_info->resp_ie =
5038 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
5041 conn_info->resp_ie_len = 0;
5042 conn_info->resp_ie = NULL;
5044 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
5045 conn_info->req_ie_len, conn_info->resp_ie_len);
5051 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
5052 struct net_device *ndev,
5053 const struct brcmf_event_msg *e)
5055 struct brcmf_if *ifp = netdev_priv(ndev);
5056 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5057 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5058 struct wiphy *wiphy = cfg_to_wiphy(cfg);
5059 struct ieee80211_channel *notify_channel = NULL;
5060 struct ieee80211_supported_band *band;
5061 struct brcmf_bss_info_le *bi;
5062 struct brcmu_chan ch;
5067 brcmf_dbg(TRACE, "Enter\n");
5069 brcmf_get_assoc_ies(cfg, ifp);
5070 memcpy(profile->bssid, e->addr, ETH_ALEN);
5071 brcmf_update_bss_info(cfg, ifp);
5073 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
5079 /* data sent to dongle has to be little endian */
5080 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
5081 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
5082 buf, WL_BSS_INFO_MAX);
5087 bi = (struct brcmf_bss_info_le *)(buf + 4);
5088 ch.chspec = le16_to_cpu(bi->chanspec);
5089 cfg->d11inf.decchspec(&ch);
5091 if (ch.band == BRCMU_CHAN_BAND_2G)
5092 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5094 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5096 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
5097 notify_channel = ieee80211_get_channel(wiphy, freq);
5101 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
5102 conn_info->req_ie, conn_info->req_ie_len,
5103 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
5104 brcmf_dbg(CONN, "Report roaming result\n");
5106 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
5107 brcmf_dbg(TRACE, "Exit\n");
5112 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
5113 struct net_device *ndev, const struct brcmf_event_msg *e,
5116 struct brcmf_if *ifp = netdev_priv(ndev);
5117 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5118 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
5120 brcmf_dbg(TRACE, "Enter\n");
5122 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5123 &ifp->vif->sme_state)) {
5125 brcmf_get_assoc_ies(cfg, ifp);
5126 memcpy(profile->bssid, e->addr, ETH_ALEN);
5127 brcmf_update_bss_info(cfg, ifp);
5128 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5129 &ifp->vif->sme_state);
5131 cfg80211_connect_result(ndev,
5132 (u8 *)profile->bssid,
5134 conn_info->req_ie_len,
5136 conn_info->resp_ie_len,
5137 completed ? WLAN_STATUS_SUCCESS :
5138 WLAN_STATUS_AUTH_TIMEOUT,
5140 brcmf_dbg(CONN, "Report connect result - connection %s\n",
5141 completed ? "succeeded" : "failed");
5143 brcmf_dbg(TRACE, "Exit\n");
5148 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
5149 struct net_device *ndev,
5150 const struct brcmf_event_msg *e, void *data)
5152 struct brcmf_if *ifp = netdev_priv(ndev);
5153 static int generation;
5154 u32 event = e->event_code;
5155 u32 reason = e->reason;
5156 struct station_info sinfo;
5158 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
5159 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5160 ndev != cfg_to_ndev(cfg)) {
5161 brcmf_dbg(CONN, "AP mode link down\n");
5162 complete(&cfg->vif_disabled);
5164 brcmf_remove_interface(ifp);
5168 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5169 (reason == BRCMF_E_STATUS_SUCCESS)) {
5170 memset(&sinfo, 0, sizeof(sinfo));
5172 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5175 sinfo.assoc_req_ies = data;
5176 sinfo.assoc_req_ies_len = e->datalen;
5178 sinfo.generation = generation;
5179 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5180 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5181 (event == BRCMF_E_DEAUTH_IND) ||
5182 (event == BRCMF_E_DEAUTH)) {
5183 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5189 brcmf_notify_connect_status(struct brcmf_if *ifp,
5190 const struct brcmf_event_msg *e, void *data)
5192 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5193 struct net_device *ndev = ifp->ndev;
5194 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5195 struct ieee80211_channel *chan;
5198 if ((e->event_code == BRCMF_E_DEAUTH) ||
5199 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5200 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5201 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5202 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5205 if (brcmf_is_apmode(ifp->vif)) {
5206 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5207 } else if (brcmf_is_linkup(e)) {
5208 brcmf_dbg(CONN, "Linkup\n");
5209 if (brcmf_is_ibssmode(ifp->vif)) {
5210 brcmf_inform_ibss(cfg, ndev, e->addr);
5211 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5212 memcpy(profile->bssid, e->addr, ETH_ALEN);
5213 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5214 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5215 &ifp->vif->sme_state);
5216 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5217 &ifp->vif->sme_state);
5219 brcmf_bss_connect_done(cfg, ndev, e, true);
5220 brcmf_net_setcarrier(ifp, true);
5221 } else if (brcmf_is_linkdown(e)) {
5222 brcmf_dbg(CONN, "Linkdown\n");
5223 if (!brcmf_is_ibssmode(ifp->vif)) {
5224 brcmf_bss_connect_done(cfg, ndev, e, false);
5225 brcmf_link_down(ifp->vif,
5226 brcmf_map_fw_linkdown_reason(e));
5227 brcmf_init_prof(ndev_to_prof(ndev));
5228 if (ndev != cfg_to_ndev(cfg))
5229 complete(&cfg->vif_disabled);
5230 brcmf_net_setcarrier(ifp, false);
5232 } else if (brcmf_is_nonetwork(cfg, e)) {
5233 if (brcmf_is_ibssmode(ifp->vif))
5234 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5235 &ifp->vif->sme_state);
5237 brcmf_bss_connect_done(cfg, ndev, e, false);
5244 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5245 const struct brcmf_event_msg *e, void *data)
5247 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5248 u32 event = e->event_code;
5249 u32 status = e->status;
5251 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5252 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5253 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5255 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5262 brcmf_notify_mic_status(struct brcmf_if *ifp,
5263 const struct brcmf_event_msg *e, void *data)
5265 u16 flags = e->flags;
5266 enum nl80211_key_type key_type;
5268 if (flags & BRCMF_EVENT_MSG_GROUP)
5269 key_type = NL80211_KEYTYPE_GROUP;
5271 key_type = NL80211_KEYTYPE_PAIRWISE;
5273 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5279 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5280 const struct brcmf_event_msg *e, void *data)
5282 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5283 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5284 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5285 struct brcmf_cfg80211_vif *vif;
5287 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5288 ifevent->action, ifevent->flags, ifevent->ifidx,
5289 ifevent->bsscfgidx);
5291 mutex_lock(&event->vif_event_lock);
5292 event->action = ifevent->action;
5295 switch (ifevent->action) {
5296 case BRCMF_E_IF_ADD:
5297 /* waiting process may have timed out */
5298 if (!cfg->vif_event.vif) {
5299 mutex_unlock(&event->vif_event_lock);
5306 vif->wdev.netdev = ifp->ndev;
5307 ifp->ndev->ieee80211_ptr = &vif->wdev;
5308 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5310 mutex_unlock(&event->vif_event_lock);
5311 wake_up(&event->vif_wq);
5314 case BRCMF_E_IF_DEL:
5315 mutex_unlock(&event->vif_event_lock);
5316 /* event may not be upon user request */
5317 if (brcmf_cfg80211_vif_event_armed(cfg))
5318 wake_up(&event->vif_wq);
5321 case BRCMF_E_IF_CHANGE:
5322 mutex_unlock(&event->vif_event_lock);
5323 wake_up(&event->vif_wq);
5327 mutex_unlock(&event->vif_event_lock);
5333 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5335 conf->frag_threshold = (u32)-1;
5336 conf->rts_threshold = (u32)-1;
5337 conf->retry_short = (u32)-1;
5338 conf->retry_long = (u32)-1;
5341 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5343 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5344 brcmf_notify_connect_status);
5345 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5346 brcmf_notify_connect_status);
5347 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5348 brcmf_notify_connect_status);
5349 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5350 brcmf_notify_connect_status);
5351 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5352 brcmf_notify_connect_status);
5353 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5354 brcmf_notify_connect_status);
5355 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5356 brcmf_notify_roaming_status);
5357 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5358 brcmf_notify_mic_status);
5359 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5360 brcmf_notify_connect_status);
5361 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5362 brcmf_notify_sched_scan_results);
5363 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5364 brcmf_notify_vif_event);
5365 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5366 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5367 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5368 brcmf_p2p_notify_listen_complete);
5369 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5370 brcmf_p2p_notify_action_frame_rx);
5371 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5372 brcmf_p2p_notify_action_tx_complete);
5373 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5374 brcmf_p2p_notify_action_tx_complete);
5377 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5381 kfree(cfg->extra_buf);
5382 cfg->extra_buf = NULL;
5383 kfree(cfg->wowl.nd);
5384 cfg->wowl.nd = NULL;
5385 kfree(cfg->wowl.nd_info);
5386 cfg->wowl.nd_info = NULL;
5387 kfree(cfg->escan_info.escan_buf);
5388 cfg->escan_info.escan_buf = NULL;
5391 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5393 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5395 goto init_priv_mem_out;
5396 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5397 if (!cfg->extra_buf)
5398 goto init_priv_mem_out;
5399 cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
5401 goto init_priv_mem_out;
5402 cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
5403 sizeof(struct cfg80211_wowlan_nd_match *),
5405 if (!cfg->wowl.nd_info)
5406 goto init_priv_mem_out;
5407 cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
5408 if (!cfg->escan_info.escan_buf)
5409 goto init_priv_mem_out;
5414 brcmf_deinit_priv_mem(cfg);
5419 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5423 cfg->scan_request = NULL;
5424 cfg->pwr_save = true;
5425 cfg->active_scan = true; /* we do active scan per default */
5426 cfg->dongle_up = false; /* dongle is not up yet */
5427 err = brcmf_init_priv_mem(cfg);
5430 brcmf_register_event_handlers(cfg);
5431 mutex_init(&cfg->usr_sync);
5432 brcmf_init_escan(cfg);
5433 brcmf_init_conf(cfg->conf);
5434 init_completion(&cfg->vif_disabled);
5438 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5440 cfg->dongle_up = false; /* dongle down */
5441 brcmf_abort_scanning(cfg);
5442 brcmf_deinit_priv_mem(cfg);
5445 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5447 init_waitqueue_head(&event->vif_wq);
5448 mutex_init(&event->vif_event_lock);
5451 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
5455 __le32 roamtrigger[2];
5456 __le32 roam_delta[2];
5458 /* Configure beacon timeout value based upon roaming setting */
5459 if (ifp->drvr->settings->roamoff)
5460 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
5462 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
5463 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5465 brcmf_err("bcn_timeout error (%d)\n", err);
5466 goto roam_setup_done;
5469 /* Enable/Disable built-in roaming to allow supplicant to take care of
5472 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5473 ifp->drvr->settings->roamoff ? "Off" : "On");
5474 err = brcmf_fil_iovar_int_set(ifp, "roam_off",
5475 ifp->drvr->settings->roamoff);
5477 brcmf_err("roam_off error (%d)\n", err);
5478 goto roam_setup_done;
5481 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5482 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5483 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5484 (void *)roamtrigger, sizeof(roamtrigger));
5486 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5487 goto roam_setup_done;
5490 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5491 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5492 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5493 (void *)roam_delta, sizeof(roam_delta));
5495 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5496 goto roam_setup_done;
5504 brcmf_dongle_scantime(struct brcmf_if *ifp)
5508 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5509 BRCMF_SCAN_CHANNEL_TIME);
5511 brcmf_err("Scan assoc time error (%d)\n", err);
5512 goto dongle_scantime_out;
5514 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5515 BRCMF_SCAN_UNASSOC_TIME);
5517 brcmf_err("Scan unassoc time error (%d)\n", err);
5518 goto dongle_scantime_out;
5521 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5522 BRCMF_SCAN_PASSIVE_TIME);
5524 brcmf_err("Scan passive time error (%d)\n", err);
5525 goto dongle_scantime_out;
5528 dongle_scantime_out:
5532 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5533 struct brcmu_chan *ch)
5537 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5538 if (ch->sb == BRCMU_CHAN_SB_U) {
5539 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5540 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5541 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5543 /* It should be one of
5544 * IEEE80211_CHAN_NO_HT40 or
5545 * IEEE80211_CHAN_NO_HT40PLUS
5547 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5548 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5549 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5553 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5556 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5557 struct ieee80211_supported_band *band;
5558 struct ieee80211_channel *channel;
5559 struct wiphy *wiphy;
5560 struct brcmf_chanspec_list *list;
5561 struct brcmu_chan ch;
5569 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5574 list = (struct brcmf_chanspec_list *)pbuf;
5576 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5579 brcmf_err("get chanspecs error (%d)\n", err);
5583 wiphy = cfg_to_wiphy(cfg);
5584 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5586 for (i = 0; i < band->n_channels; i++)
5587 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5588 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5590 for (i = 0; i < band->n_channels; i++)
5591 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5593 total = le32_to_cpu(list->count);
5594 for (i = 0; i < total; i++) {
5595 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5596 cfg->d11inf.decchspec(&ch);
5598 if (ch.band == BRCMU_CHAN_BAND_2G) {
5599 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5600 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5601 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5603 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5608 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5609 ch.bw == BRCMU_CHAN_BW_40)
5611 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5612 ch.bw == BRCMU_CHAN_BW_80)
5615 channel = band->channels;
5616 index = band->n_channels;
5617 for (j = 0; j < band->n_channels; j++) {
5618 if (channel[j].hw_value == ch.chnum) {
5623 channel[index].center_freq =
5624 ieee80211_channel_to_frequency(ch.chnum, band->band);
5625 channel[index].hw_value = ch.chnum;
5627 /* assuming the chanspecs order is HT20,
5628 * HT40 upper, HT40 lower, and VHT80.
5630 if (ch.bw == BRCMU_CHAN_BW_80) {
5631 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5632 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5633 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5635 /* enable the channel and disable other bandwidths
5636 * for now as mentioned order assure they are enabled
5637 * for subsequent chanspecs.
5639 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5640 IEEE80211_CHAN_NO_80MHZ;
5641 ch.bw = BRCMU_CHAN_BW_20;
5642 cfg->d11inf.encchspec(&ch);
5643 chaninfo = ch.chspec;
5644 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5647 if (chaninfo & WL_CHAN_RADAR)
5648 channel[index].flags |=
5649 (IEEE80211_CHAN_RADAR |
5650 IEEE80211_CHAN_NO_IR);
5651 if (chaninfo & WL_CHAN_PASSIVE)
5652 channel[index].flags |=
5653 IEEE80211_CHAN_NO_IR;
5663 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5665 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5666 struct ieee80211_supported_band *band;
5667 struct brcmf_fil_bwcap_le band_bwcap;
5668 struct brcmf_chanspec_list *list;
5672 struct brcmu_chan ch;
5676 /* verify support for bw_cap command */
5678 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5681 /* only set 2G bandwidth using bw_cap command */
5682 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5683 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5684 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5685 sizeof(band_bwcap));
5687 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5688 val = WLC_N_BW_40ALL;
5689 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5693 /* update channel info in 2G band */
5694 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5699 ch.band = BRCMU_CHAN_BAND_2G;
5700 ch.bw = BRCMU_CHAN_BW_40;
5701 ch.sb = BRCMU_CHAN_SB_NONE;
5703 cfg->d11inf.encchspec(&ch);
5705 /* pass encoded chanspec in query */
5706 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5708 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5711 brcmf_err("get chanspecs error (%d)\n", err);
5716 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5717 list = (struct brcmf_chanspec_list *)pbuf;
5718 num_chan = le32_to_cpu(list->count);
5719 for (i = 0; i < num_chan; i++) {
5720 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5721 cfg->d11inf.decchspec(&ch);
5722 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5724 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5726 for (j = 0; j < band->n_channels; j++) {
5727 if (band->channels[j].hw_value == ch.chnum)
5730 if (WARN_ON(j == band->n_channels))
5733 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5740 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5742 u32 band, mimo_bwcap;
5746 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5748 bw_cap[IEEE80211_BAND_2GHZ] = band;
5750 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5752 bw_cap[IEEE80211_BAND_5GHZ] = band;
5758 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5760 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5762 /* assume 20MHz if firmware does not give a clue */
5763 mimo_bwcap = WLC_N_BW_20ALL;
5765 switch (mimo_bwcap) {
5766 case WLC_N_BW_40ALL:
5767 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5769 case WLC_N_BW_20IN2G_40IN5G:
5770 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5772 case WLC_N_BW_20ALL:
5773 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5774 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5777 brcmf_err("invalid mimo_bw_cap value\n");
5781 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5782 u32 bw_cap[2], u32 nchain)
5784 band->ht_cap.ht_supported = true;
5785 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5786 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5787 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5789 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5790 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5791 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5792 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5793 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5794 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5797 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5802 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5803 mcs_map = (mcs_map << 2) | supp;
5805 return cpu_to_le16(mcs_map);
5808 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5809 u32 bw_cap[2], u32 nchain, u32 txstreams,
5810 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
5814 /* not allowed in 2.4G band */
5815 if (band->band == IEEE80211_BAND_2GHZ)
5818 band->vht_cap.vht_supported = true;
5819 /* 80MHz is mandatory */
5820 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5821 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5822 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5823 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5825 /* all support 256-QAM */
5826 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5827 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5828 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5830 /* Beamforming support information */
5831 if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
5832 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
5833 if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
5834 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
5835 if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
5836 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
5837 if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
5838 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
5840 if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
5841 band->vht_cap.cap |=
5842 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
5843 band->vht_cap.cap |= ((txstreams - 1) <<
5844 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
5845 band->vht_cap.cap |=
5846 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
5850 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5852 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5853 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5856 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5861 struct ieee80211_supported_band *band;
5863 u32 txbf_bfe_cap = 0;
5864 u32 txbf_bfr_cap = 0;
5866 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5867 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5869 brcmf_err("nmode error (%d)\n", err);
5871 brcmf_get_bwcap(ifp, bw_cap);
5873 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5874 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5875 bw_cap[IEEE80211_BAND_5GHZ]);
5877 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5879 brcmf_err("rxchain error (%d)\n", err);
5882 for (nchain = 0; rxchain; nchain++)
5883 rxchain = rxchain & (rxchain - 1);
5885 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5887 err = brcmf_construct_chaninfo(cfg, bw_cap);
5889 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5894 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
5895 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
5897 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
5901 wiphy = cfg_to_wiphy(cfg);
5902 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5903 band = wiphy->bands[i];
5908 brcmf_update_ht_cap(band, bw_cap, nchain);
5910 brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
5911 txbf_bfe_cap, txbf_bfr_cap);
5917 static const struct ieee80211_txrx_stypes
5918 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5919 [NL80211_IFTYPE_STATION] = {
5921 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5922 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5924 [NL80211_IFTYPE_P2P_CLIENT] = {
5926 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5927 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5929 [NL80211_IFTYPE_P2P_GO] = {
5931 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5932 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5933 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5934 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5935 BIT(IEEE80211_STYPE_AUTH >> 4) |
5936 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5937 BIT(IEEE80211_STYPE_ACTION >> 4)
5939 [NL80211_IFTYPE_P2P_DEVICE] = {
5941 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5942 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5947 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5949 * @wiphy: wiphy object.
5950 * @ifp: interface object needed for feat module api.
5952 * The interface modes and combinations are determined dynamically here
5953 * based on firmware functionality.
5955 * no p2p and no mbss:
5957 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5961 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5962 * #AP <= 4, matching BI, channels = 1, 4 total
5964 * p2p, no mchan, and mbss:
5966 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
5967 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5968 * #AP <= 4, matching BI, channels = 1, 4 total
5970 * p2p, mchan, and mbss:
5972 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
5973 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5974 * #AP <= 4, matching BI, channels = 1, 4 total
5976 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5978 struct ieee80211_iface_combination *combo = NULL;
5979 struct ieee80211_iface_limit *c0_limits = NULL;
5980 struct ieee80211_iface_limit *p2p_limits = NULL;
5981 struct ieee80211_iface_limit *mbss_limits = NULL;
5985 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
5986 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
5988 n_combos = 1 + !!p2p + !!mbss;
5989 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
5993 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
5998 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
6004 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
6009 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6010 BIT(NL80211_IFTYPE_ADHOC) |
6011 BIT(NL80211_IFTYPE_AP);
6015 combo[c].num_different_channels = 1;
6016 c0_limits[i].max = 1;
6017 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6019 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
6020 combo[c].num_different_channels = 2;
6021 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
6022 BIT(NL80211_IFTYPE_P2P_GO) |
6023 BIT(NL80211_IFTYPE_P2P_DEVICE);
6024 c0_limits[i].max = 1;
6025 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6026 c0_limits[i].max = 1;
6027 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
6028 BIT(NL80211_IFTYPE_P2P_GO);
6030 c0_limits[i].max = 1;
6031 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6033 combo[c].max_interfaces = i;
6034 combo[c].n_limits = i;
6035 combo[c].limits = c0_limits;
6040 combo[c].num_different_channels = 1;
6041 p2p_limits[i].max = 1;
6042 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
6043 p2p_limits[i].max = 1;
6044 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
6045 p2p_limits[i].max = 1;
6046 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
6047 p2p_limits[i].max = 1;
6048 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
6049 combo[c].max_interfaces = i;
6050 combo[c].n_limits = i;
6051 combo[c].limits = p2p_limits;
6056 combo[c].beacon_int_infra_match = true;
6057 combo[c].num_different_channels = 1;
6058 mbss_limits[0].max = 4;
6059 mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
6060 combo[c].max_interfaces = 4;
6061 combo[c].n_limits = 1;
6062 combo[c].limits = mbss_limits;
6064 wiphy->n_iface_combinations = n_combos;
6065 wiphy->iface_combinations = combo;
6076 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
6078 /* scheduled scan settings */
6079 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
6080 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
6081 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6082 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
6086 static struct wiphy_wowlan_support brcmf_wowlan_support = {
6087 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
6088 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
6089 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
6090 .pattern_min_len = 1,
6091 .max_pkt_offset = 1500,
6095 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
6098 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
6100 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
6101 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
6102 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_NET_DETECT;
6103 init_waitqueue_head(&cfg->wowl.nd_data_wait);
6106 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
6107 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
6108 brcmf_wowlan_support.flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
6111 wiphy->wowlan = &brcmf_wowlan_support;
6115 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
6117 struct brcmf_pub *drvr = ifp->drvr;
6118 const struct ieee80211_iface_combination *combo;
6119 struct ieee80211_supported_band *band;
6120 u16 max_interfaces = 0;
6125 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
6126 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
6127 wiphy->max_num_pmkids = BRCMF_MAXPMKID;
6129 err = brcmf_setup_ifmodes(wiphy, ifp);
6133 for (i = 0, combo = wiphy->iface_combinations;
6134 i < wiphy->n_iface_combinations; i++, combo++) {
6135 max_interfaces = max(max_interfaces, combo->max_interfaces);
6138 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
6140 u8 *addr = drvr->addresses[i].addr;
6142 memcpy(addr, drvr->mac, ETH_ALEN);
6145 addr[ETH_ALEN - 1] ^= i;
6148 wiphy->addresses = drvr->addresses;
6149 wiphy->n_addresses = i;
6151 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
6152 wiphy->cipher_suites = __wl_cipher_suites;
6153 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
6154 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
6155 WIPHY_FLAG_OFFCHAN_TX |
6156 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
6157 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
6158 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
6159 if (!ifp->drvr->settings->roamoff)
6160 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
6161 wiphy->mgmt_stypes = brcmf_txrx_stypes;
6162 wiphy->max_remain_on_channel_duration = 5000;
6163 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
6164 brcmf_wiphy_pno_params(wiphy);
6166 /* vendor commands/events support */
6167 wiphy->vendor_commands = brcmf_vendor_cmds;
6168 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
6170 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
6171 brcmf_wiphy_wowl_params(wiphy, ifp);
6172 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
6175 brcmf_err("could not obtain band info: err=%d\n", err);
6178 /* first entry in bandlist is number of bands */
6179 n_bands = le32_to_cpu(bandlist[0]);
6180 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
6181 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
6182 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
6187 band->channels = kmemdup(&__wl_2ghz_channels,
6188 sizeof(__wl_2ghz_channels),
6190 if (!band->channels) {
6195 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6196 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
6198 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6199 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6204 band->channels = kmemdup(&__wl_5ghz_channels,
6205 sizeof(__wl_5ghz_channels),
6207 if (!band->channels) {
6212 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6213 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6216 err = brcmf_setup_wiphybands(wiphy);
6220 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6222 struct net_device *ndev;
6223 struct wireless_dev *wdev;
6224 struct brcmf_if *ifp;
6231 ndev = cfg_to_ndev(cfg);
6232 wdev = ndev->ieee80211_ptr;
6233 ifp = netdev_priv(ndev);
6235 /* make sure RF is ready for work */
6236 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6238 brcmf_dongle_scantime(ifp);
6240 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6241 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6243 goto default_conf_out;
6244 brcmf_dbg(INFO, "power save set to %s\n",
6245 (power_mode ? "enabled" : "disabled"));
6247 err = brcmf_dongle_roam(ifp);
6249 goto default_conf_out;
6250 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6253 goto default_conf_out;
6255 brcmf_configure_arp_nd_offload(ifp, true);
6257 cfg->dongle_up = true;
6264 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6266 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6268 return brcmf_config_dongle(ifp->drvr->config);
6271 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6273 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6276 * While going down, if associated with AP disassociate
6277 * from AP to save power
6279 if (check_vif_up(ifp->vif)) {
6280 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6282 /* Make sure WPA_Supplicant receives all the event
6283 generated due to DISASSOC call to the fw to keep
6284 the state fw and WPA_Supplicant state consistent
6289 brcmf_abort_scanning(cfg);
6290 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6295 s32 brcmf_cfg80211_up(struct net_device *ndev)
6297 struct brcmf_if *ifp = netdev_priv(ndev);
6298 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6301 mutex_lock(&cfg->usr_sync);
6302 err = __brcmf_cfg80211_up(ifp);
6303 mutex_unlock(&cfg->usr_sync);
6308 s32 brcmf_cfg80211_down(struct net_device *ndev)
6310 struct brcmf_if *ifp = netdev_priv(ndev);
6311 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6314 mutex_lock(&cfg->usr_sync);
6315 err = __brcmf_cfg80211_down(ifp);
6316 mutex_unlock(&cfg->usr_sync);
6321 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6323 struct wireless_dev *wdev = &ifp->vif->wdev;
6325 return wdev->iftype;
6328 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6329 unsigned long state)
6331 struct brcmf_cfg80211_vif *vif;
6333 list_for_each_entry(vif, &cfg->vif_list, list) {
6334 if (test_bit(state, &vif->sme_state))
6340 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6345 mutex_lock(&event->vif_event_lock);
6346 evt_action = event->action;
6347 mutex_unlock(&event->vif_event_lock);
6348 return evt_action == action;
6351 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6352 struct brcmf_cfg80211_vif *vif)
6354 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6356 mutex_lock(&event->vif_event_lock);
6359 mutex_unlock(&event->vif_event_lock);
6362 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6364 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6367 mutex_lock(&event->vif_event_lock);
6368 armed = event->vif != NULL;
6369 mutex_unlock(&event->vif_event_lock);
6374 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
6375 u8 action, ulong timeout)
6377 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6379 return wait_event_timeout(event->vif_wq,
6380 vif_event_equals(event, action), timeout);
6383 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
6384 struct brcmf_fil_country_le *ccreq)
6386 struct brcmfmac_pd_cc *country_codes;
6387 struct brcmfmac_pd_cc_entry *cc;
6391 country_codes = drvr->settings->country_codes;
6392 if (!country_codes) {
6393 brcmf_dbg(TRACE, "No country codes configured for device\n");
6397 if ((alpha2[0] == ccreq->country_abbrev[0]) &&
6398 (alpha2[1] == ccreq->country_abbrev[1])) {
6399 brcmf_dbg(TRACE, "Country code already set\n");
6404 for (i = 0; i < country_codes->table_size; i++) {
6405 cc = &country_codes->table[i];
6406 if ((cc->iso3166[0] == '\0') && (found_index == -1))
6408 if ((cc->iso3166[0] == alpha2[0]) &&
6409 (cc->iso3166[1] == alpha2[1])) {
6414 if (found_index == -1) {
6415 brcmf_dbg(TRACE, "No country code match found\n");
6418 memset(ccreq, 0, sizeof(*ccreq));
6419 ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
6420 memcpy(ccreq->ccode, country_codes->table[found_index].cc,
6421 BRCMF_COUNTRY_BUF_SZ);
6422 ccreq->country_abbrev[0] = alpha2[0];
6423 ccreq->country_abbrev[1] = alpha2[1];
6424 ccreq->country_abbrev[2] = 0;
6429 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6430 struct regulatory_request *req)
6432 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6433 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6434 struct brcmf_fil_country_le ccreq;
6438 /* ignore non-ISO3166 country codes */
6439 for (i = 0; i < sizeof(req->alpha2); i++)
6440 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6441 brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
6442 req->alpha2[0], req->alpha2[1]);
6446 brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
6447 req->alpha2[0], req->alpha2[1]);
6449 err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
6451 brcmf_err("Country code iovar returned err = %d\n", err);
6455 err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
6459 err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
6461 brcmf_err("Firmware rejected country setting\n");
6464 brcmf_setup_wiphybands(wiphy);
6467 static void brcmf_free_wiphy(struct wiphy *wiphy)
6474 if (wiphy->iface_combinations) {
6475 for (i = 0; i < wiphy->n_iface_combinations; i++)
6476 kfree(wiphy->iface_combinations[i].limits);
6478 kfree(wiphy->iface_combinations);
6479 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6480 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6481 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6483 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6484 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6485 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6490 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6491 struct device *busdev,
6494 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6495 struct brcmf_cfg80211_info *cfg;
6496 struct wiphy *wiphy;
6497 struct cfg80211_ops *ops;
6498 struct brcmf_cfg80211_vif *vif;
6499 struct brcmf_if *ifp;
6505 brcmf_err("ndev is invalid\n");
6509 ops = kzalloc(sizeof(*ops), GFP_KERNEL);
6513 memcpy(ops, &brcmf_cfg80211_ops, sizeof(*ops));
6514 ifp = netdev_priv(ndev);
6516 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
6517 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
6519 wiphy = wiphy_new(ops, sizeof(struct brcmf_cfg80211_info));
6521 brcmf_err("Could not allocate wiphy device\n");
6524 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6525 set_wiphy_dev(wiphy, busdev);
6527 cfg = wiphy_priv(wiphy);
6531 init_vif_event(&cfg->vif_event);
6532 INIT_LIST_HEAD(&cfg->vif_list);
6534 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6539 vif->wdev.netdev = ndev;
6540 ndev->ieee80211_ptr = &vif->wdev;
6541 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6543 err = wl_init_priv(cfg);
6545 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6546 brcmf_free_vif(vif);
6551 /* determine d11 io type before wiphy setup */
6552 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6554 brcmf_err("Failed to get D11 version (%d)\n", err);
6557 cfg->d11inf.io_type = (u8)io_type;
6558 brcmu_d11_attach(&cfg->d11inf);
6560 err = brcmf_setup_wiphy(wiphy, ifp);
6564 brcmf_dbg(INFO, "Registering custom regulatory\n");
6565 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6566 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6567 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6569 /* firmware defaults to 40MHz disabled in 2G band. We signal
6570 * cfg80211 here that we do and have it decide we can enable
6571 * it. But first check if device does support 2G operation.
6573 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6574 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6575 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6577 err = wiphy_register(wiphy);
6579 brcmf_err("Could not register wiphy device (%d)\n", err);
6583 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6584 * setup 40MHz in 2GHz band and enable OBSS scanning.
6586 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6587 err = brcmf_enable_bw40_2g(cfg);
6589 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6590 BRCMF_OBSS_COEX_AUTO);
6592 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6594 /* p2p might require that "if-events" get processed by fweh. So
6595 * activate the already registered event handlers now and activate
6596 * the rest when initialization has completed. drvr->config needs to
6597 * be assigned before activating events.
6600 err = brcmf_fweh_activate_events(ifp);
6602 brcmf_err("FWEH activation failed (%d)\n", err);
6603 goto wiphy_unreg_out;
6606 err = brcmf_p2p_attach(cfg, p2pdev_forced);
6608 brcmf_err("P2P initilisation failed (%d)\n", err);
6609 goto wiphy_unreg_out;
6611 err = brcmf_btcoex_attach(cfg);
6613 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6614 brcmf_p2p_detach(&cfg->p2p);
6615 goto wiphy_unreg_out;
6618 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
6619 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6621 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6622 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6624 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6625 brcmf_notify_tdls_peer_event);
6629 /* (re-) activate FWEH event handling */
6630 err = brcmf_fweh_activate_events(ifp);
6632 brcmf_err("FWEH activation failed (%d)\n", err);
6633 goto wiphy_unreg_out;
6636 /* Fill in some of the advertised nl80211 supported features */
6637 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
6638 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
6640 if (wiphy->wowlan &&
6641 wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
6642 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
6649 wiphy_unregister(cfg->wiphy);
6651 wl_deinit_priv(cfg);
6652 brcmf_free_vif(vif);
6655 brcmf_free_wiphy(wiphy);
6660 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6665 brcmf_btcoex_detach(cfg);
6666 wiphy_unregister(cfg->wiphy);
6668 wl_deinit_priv(cfg);
6669 brcmf_free_wiphy(cfg->wiphy);