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"
35 #include "wl_cfg80211.h"
40 #define BRCMF_SCAN_IE_LEN_MAX 2048
41 #define BRCMF_PNO_VERSION 2
42 #define BRCMF_PNO_TIME 30
43 #define BRCMF_PNO_REPEAT 4
44 #define BRCMF_PNO_FREQ_EXPO_MAX 3
45 #define BRCMF_PNO_MAX_PFN_COUNT 16
46 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
47 #define BRCMF_PNO_HIDDEN_BIT 2
48 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
49 #define BRCMF_PNO_SCAN_COMPLETE 1
50 #define BRCMF_PNO_SCAN_INCOMPLETE 0
52 #define BRCMF_IFACE_MAX_CNT 3
54 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
55 #define WPA_OUI_TYPE 1
56 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
57 #define WME_OUI_TYPE 2
58 #define WPS_OUI_TYPE 4
60 #define VS_IE_FIXED_HDR_LEN 6
61 #define WPA_IE_VERSION_LEN 2
62 #define WPA_IE_MIN_OUI_LEN 4
63 #define WPA_IE_SUITE_COUNT_LEN 2
65 #define WPA_CIPHER_NONE 0 /* None */
66 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
71 #define RSN_AKM_NONE 0 /* None (IBSS) */
72 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73 #define RSN_AKM_PSK 2 /* Pre-shared Key */
74 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
77 #define VNDR_IE_CMD_LEN 4 /* length of the set command
78 * string :"add", "del" (+ NUL)
80 #define VNDR_IE_COUNT_OFFSET 4
81 #define VNDR_IE_PKTFLAG_OFFSET 8
82 #define VNDR_IE_VSIE_OFFSET 12
83 #define VNDR_IE_HDR_SIZE 12
84 #define VNDR_IE_PARSE_LIMIT 5
86 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
87 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
89 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
90 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
91 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
93 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
94 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
96 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
98 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
99 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
106 #define CHAN2G(_channel, _freq, _flags) { \
107 .band = IEEE80211_BAND_2GHZ, \
108 .center_freq = (_freq), \
109 .hw_value = (_channel), \
111 .max_antenna_gain = 0, \
115 #define CHAN5G(_channel, _flags) { \
116 .band = IEEE80211_BAND_5GHZ, \
117 .center_freq = 5000 + (5 * (_channel)), \
118 .hw_value = (_channel), \
120 .max_antenna_gain = 0, \
124 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
125 #define RATETAB_ENT(_rateid, _flags) \
127 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
128 .hw_value = (_rateid), \
132 static struct ieee80211_rate __wl_rates[] = {
133 RATETAB_ENT(BRCM_RATE_1M, 0),
134 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
135 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
136 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
137 RATETAB_ENT(BRCM_RATE_6M, 0),
138 RATETAB_ENT(BRCM_RATE_9M, 0),
139 RATETAB_ENT(BRCM_RATE_12M, 0),
140 RATETAB_ENT(BRCM_RATE_18M, 0),
141 RATETAB_ENT(BRCM_RATE_24M, 0),
142 RATETAB_ENT(BRCM_RATE_36M, 0),
143 RATETAB_ENT(BRCM_RATE_48M, 0),
144 RATETAB_ENT(BRCM_RATE_54M, 0),
147 #define wl_a_rates (__wl_rates + 4)
148 #define wl_a_rates_size 8
149 #define wl_g_rates (__wl_rates + 0)
150 #define wl_g_rates_size 12
152 static struct ieee80211_channel __wl_2ghz_channels[] = {
169 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
170 CHAN5G(34, 0), CHAN5G(36, 0),
171 CHAN5G(38, 0), CHAN5G(40, 0),
172 CHAN5G(42, 0), CHAN5G(44, 0),
173 CHAN5G(46, 0), CHAN5G(48, 0),
174 CHAN5G(52, 0), CHAN5G(56, 0),
175 CHAN5G(60, 0), CHAN5G(64, 0),
176 CHAN5G(100, 0), CHAN5G(104, 0),
177 CHAN5G(108, 0), CHAN5G(112, 0),
178 CHAN5G(116, 0), CHAN5G(120, 0),
179 CHAN5G(124, 0), CHAN5G(128, 0),
180 CHAN5G(132, 0), CHAN5G(136, 0),
181 CHAN5G(140, 0), CHAN5G(149, 0),
182 CHAN5G(153, 0), CHAN5G(157, 0),
183 CHAN5G(161, 0), CHAN5G(165, 0),
184 CHAN5G(184, 0), CHAN5G(188, 0),
185 CHAN5G(192, 0), CHAN5G(196, 0),
186 CHAN5G(200, 0), CHAN5G(204, 0),
187 CHAN5G(208, 0), CHAN5G(212, 0),
191 static struct ieee80211_supported_band __wl_band_2ghz = {
192 .band = IEEE80211_BAND_2GHZ,
193 .channels = __wl_2ghz_channels,
194 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
195 .bitrates = wl_g_rates,
196 .n_bitrates = wl_g_rates_size,
197 .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
200 static struct ieee80211_supported_band __wl_band_5ghz_a = {
201 .band = IEEE80211_BAND_5GHZ,
202 .channels = __wl_5ghz_a_channels,
203 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
204 .bitrates = wl_a_rates,
205 .n_bitrates = wl_a_rates_size,
208 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
209 * By default world regulatory domain defined in reg.c puts the flags
210 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
211 * With respect to these flags, wpa_supplicant doesn't * start p2p
212 * operations on 5GHz channels. All the changes in world regulatory
213 * domain are to be done here.
215 static const struct ieee80211_regdomain brcmf_regdom = {
219 /* IEEE 802.11b/g, channels 1..11 */
220 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
222 /* IEEE 802.11 channel 14 - Only JP enables
223 * this and for 802.11b only
225 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
226 /* IEEE 802.11a, channel 36..64 */
227 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
228 /* IEEE 802.11a, channel 100..165 */
229 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
232 static const u32 __wl_cipher_suites[] = {
233 WLAN_CIPHER_SUITE_WEP40,
234 WLAN_CIPHER_SUITE_WEP104,
235 WLAN_CIPHER_SUITE_TKIP,
236 WLAN_CIPHER_SUITE_CCMP,
237 WLAN_CIPHER_SUITE_AES_CMAC,
240 /* Vendor specific ie. id = 221, oui and type defines exact ie */
241 struct brcmf_vs_tlv {
248 struct parsed_vndr_ie_info {
250 u32 ie_len; /* total length including id & length field */
251 struct brcmf_vs_tlv vndrie;
254 struct parsed_vndr_ies {
256 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
259 static int brcmf_roamoff;
260 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
261 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
263 /* Quarter dBm units to mW
264 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
265 * Table is offset so the last entry is largest mW value that fits in
269 #define QDBM_OFFSET 153 /* Offset for first entry */
270 #define QDBM_TABLE_LEN 40 /* Table size */
272 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
273 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
275 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
277 /* Largest mW value that will round down to the last table entry,
278 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
279 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
280 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
282 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
284 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
285 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
286 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
287 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
288 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
289 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
290 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
293 static u16 brcmf_qdbm_to_mw(u8 qdbm)
296 int idx = qdbm - QDBM_OFFSET;
298 if (idx >= QDBM_TABLE_LEN)
299 /* clamp to max u16 mW value */
302 /* scale the qdBm index up to the range of the table 0-40
303 * where an offset of 40 qdBm equals a factor of 10 mW.
310 /* return the mW value scaled down to the correct factor of 10,
311 * adding in factor/2 to get proper rounding.
313 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
316 static u8 brcmf_mw_to_qdbm(u16 mw)
323 /* handle boundary case */
327 offset = QDBM_OFFSET;
329 /* move mw into the range of the table */
330 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
335 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
336 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
337 nqdBm_to_mW_map[qdbm]) / 2;
338 if (mw_uint < boundary)
347 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
348 struct cfg80211_chan_def *ch)
350 struct brcmu_chan ch_inf;
353 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
354 ch->chan->center_freq, ch->center_freq1, ch->width);
355 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
356 primary_offset = ch->center_freq1 - ch->chan->center_freq;
358 case NL80211_CHAN_WIDTH_20:
359 ch_inf.bw = BRCMU_CHAN_BW_20;
360 WARN_ON(primary_offset != 0);
362 case NL80211_CHAN_WIDTH_40:
363 ch_inf.bw = BRCMU_CHAN_BW_40;
364 if (primary_offset < 0)
365 ch_inf.sb = BRCMU_CHAN_SB_U;
367 ch_inf.sb = BRCMU_CHAN_SB_L;
369 case NL80211_CHAN_WIDTH_80:
370 ch_inf.bw = BRCMU_CHAN_BW_80;
371 if (primary_offset < 0) {
372 if (primary_offset < -CH_10MHZ_APART)
373 ch_inf.sb = BRCMU_CHAN_SB_UU;
375 ch_inf.sb = BRCMU_CHAN_SB_UL;
377 if (primary_offset > CH_10MHZ_APART)
378 ch_inf.sb = BRCMU_CHAN_SB_LL;
380 ch_inf.sb = BRCMU_CHAN_SB_LU;
386 switch (ch->chan->band) {
387 case IEEE80211_BAND_2GHZ:
388 ch_inf.band = BRCMU_CHAN_BAND_2G;
390 case IEEE80211_BAND_5GHZ:
391 ch_inf.band = BRCMU_CHAN_BAND_5G;
396 d11inf->encchspec(&ch_inf);
398 return ch_inf.chspec;
401 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
402 struct ieee80211_channel *ch)
404 struct brcmu_chan ch_inf;
406 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
407 ch_inf.bw = BRCMU_CHAN_BW_20;
408 d11inf->encchspec(&ch_inf);
410 return ch_inf.chspec;
413 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
414 * triples, returning a pointer to the substring whose first element
417 const struct brcmf_tlv *
418 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
420 const struct brcmf_tlv *elt = buf;
423 /* find tagged parameter */
424 while (totlen >= TLV_HDR_LEN) {
427 /* validate remaining totlen */
428 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
431 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
432 totlen -= (len + TLV_HDR_LEN);
438 /* Is any of the tlvs the expected entry? If
439 * not update the tlvs buffer pointer/length.
442 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
443 const u8 *oui, u32 oui_len, u8 type)
445 /* If the contents match the OUI and the type */
446 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
447 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
448 type == ie[TLV_BODY_OFF + oui_len]) {
454 /* point to the next ie */
455 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
456 /* calculate the length of the rest of the buffer */
457 *tlvs_len -= (int)(ie - *tlvs);
458 /* update the pointer to the start of the buffer */
464 static struct brcmf_vs_tlv *
465 brcmf_find_wpaie(const u8 *parse, u32 len)
467 const struct brcmf_tlv *ie;
469 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
470 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
471 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
472 return (struct brcmf_vs_tlv *)ie;
477 static struct brcmf_vs_tlv *
478 brcmf_find_wpsie(const u8 *parse, u32 len)
480 const struct brcmf_tlv *ie;
482 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
483 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
484 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
485 return (struct brcmf_vs_tlv *)ie;
491 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
492 struct brcmf_wsec_key_le *key_le)
494 key_le->index = cpu_to_le32(key->index);
495 key_le->len = cpu_to_le32(key->len);
496 key_le->algo = cpu_to_le32(key->algo);
497 key_le->flags = cpu_to_le32(key->flags);
498 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
499 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
500 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
501 memcpy(key_le->data, key->data, sizeof(key->data));
502 memcpy(key_le->ea, key->ea, sizeof(key->ea));
506 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
509 struct brcmf_wsec_key_le key_le;
511 convert_key_from_CPU(key, &key_le);
513 brcmf_netdev_wait_pend8021x(ndev);
515 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
519 brcmf_err("wsec_key error (%d)\n", err);
524 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
530 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
534 /* Try to set and enable ARP offload feature, this may fail, then it */
535 /* is simply not supported and err 0 will be returned */
536 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
538 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
542 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
544 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
548 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
555 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
557 enum nl80211_iftype iftype;
559 iftype = vif->wdev.iftype;
560 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
563 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
565 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
568 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
570 enum nl80211_iftype type,
572 struct vif_params *params)
574 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
576 case NL80211_IFTYPE_ADHOC:
577 case NL80211_IFTYPE_STATION:
578 case NL80211_IFTYPE_AP:
579 case NL80211_IFTYPE_AP_VLAN:
580 case NL80211_IFTYPE_WDS:
581 case NL80211_IFTYPE_MONITOR:
582 case NL80211_IFTYPE_MESH_POINT:
583 return ERR_PTR(-EOPNOTSUPP);
584 case NL80211_IFTYPE_P2P_CLIENT:
585 case NL80211_IFTYPE_P2P_GO:
586 case NL80211_IFTYPE_P2P_DEVICE:
587 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
588 case NL80211_IFTYPE_UNSPECIFIED:
590 return ERR_PTR(-EINVAL);
594 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
596 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
597 brcmf_set_mpc(ifp, mpc);
600 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
604 if (check_vif_up(ifp->vif)) {
605 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
607 brcmf_err("fail to set mpc\n");
610 brcmf_dbg(INFO, "MPC : %d\n", mpc);
614 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
615 struct brcmf_if *ifp, bool aborted,
618 struct brcmf_scan_params_le params_le;
619 struct cfg80211_scan_request *scan_request;
622 brcmf_dbg(SCAN, "Enter\n");
624 /* clear scan request, because the FW abort can cause a second call */
625 /* to this functon and might cause a double cfg80211_scan_done */
626 scan_request = cfg->scan_request;
627 cfg->scan_request = NULL;
629 if (timer_pending(&cfg->escan_timeout))
630 del_timer_sync(&cfg->escan_timeout);
633 /* Do a scan abort to stop the driver's scan engine */
634 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
635 memset(¶ms_le, 0, sizeof(params_le));
636 memset(params_le.bssid, 0xFF, ETH_ALEN);
637 params_le.bss_type = DOT11_BSSTYPE_ANY;
638 params_le.scan_type = 0;
639 params_le.channel_num = cpu_to_le32(1);
640 params_le.nprobes = cpu_to_le32(1);
641 params_le.active_time = cpu_to_le32(-1);
642 params_le.passive_time = cpu_to_le32(-1);
643 params_le.home_time = cpu_to_le32(-1);
644 /* Scan is aborted by setting channel_list[0] to -1 */
645 params_le.channel_list[0] = cpu_to_le16(-1);
646 /* E-Scan (or anyother type) can be aborted by SCAN */
647 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
648 ¶ms_le, sizeof(params_le));
650 brcmf_err("Scan abort failed\n");
653 brcmf_scan_config_mpc(ifp, 1);
656 * e-scan can be initiated by scheduled scan
657 * which takes precedence.
659 if (cfg->sched_escan) {
660 brcmf_dbg(SCAN, "scheduled scan completed\n");
661 cfg->sched_escan = false;
663 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
664 } else if (scan_request) {
665 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
666 aborted ? "Aborted" : "Done");
667 cfg80211_scan_done(scan_request, aborted);
669 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
670 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
676 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
678 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
679 struct net_device *ndev = wdev->netdev;
681 /* vif event pending in firmware */
682 if (brcmf_cfg80211_vif_event_armed(cfg))
686 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
687 cfg->escan_info.ifp == netdev_priv(ndev))
688 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
691 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
694 switch (wdev->iftype) {
695 case NL80211_IFTYPE_ADHOC:
696 case NL80211_IFTYPE_STATION:
697 case NL80211_IFTYPE_AP:
698 case NL80211_IFTYPE_AP_VLAN:
699 case NL80211_IFTYPE_WDS:
700 case NL80211_IFTYPE_MONITOR:
701 case NL80211_IFTYPE_MESH_POINT:
703 case NL80211_IFTYPE_P2P_CLIENT:
704 case NL80211_IFTYPE_P2P_GO:
705 case NL80211_IFTYPE_P2P_DEVICE:
706 return brcmf_p2p_del_vif(wiphy, wdev);
707 case NL80211_IFTYPE_UNSPECIFIED:
715 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
716 enum nl80211_iftype type, u32 *flags,
717 struct vif_params *params)
719 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
720 struct brcmf_if *ifp = netdev_priv(ndev);
721 struct brcmf_cfg80211_vif *vif = ifp->vif;
726 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
729 case NL80211_IFTYPE_MONITOR:
730 case NL80211_IFTYPE_WDS:
731 brcmf_err("type (%d) : currently we do not support this type\n",
734 case NL80211_IFTYPE_ADHOC:
737 case NL80211_IFTYPE_STATION:
738 /* Ignore change for p2p IF. Unclear why supplicant does this */
739 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
740 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
741 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
742 /* WAR: It is unexpected to get a change of VIF for P2P
743 * IF, but it happens. The request can not be handled
744 * but returning EPERM causes a crash. Returning 0
745 * without setting ieee80211_ptr->iftype causes trace
746 * (WARN_ON) but it works with wpa_supplicant
752 case NL80211_IFTYPE_AP:
753 case NL80211_IFTYPE_P2P_GO:
762 if (type == NL80211_IFTYPE_P2P_GO) {
763 brcmf_dbg(INFO, "IF Type = P2P GO\n");
764 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
767 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
768 brcmf_dbg(INFO, "IF Type = AP\n");
771 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
773 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
777 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
780 ndev->ieee80211_ptr->iftype = type;
783 brcmf_dbg(TRACE, "Exit\n");
788 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
789 struct brcmf_scan_params_le *params_le,
790 struct cfg80211_scan_request *request)
798 struct brcmf_ssid_le ssid_le;
800 memset(params_le->bssid, 0xFF, ETH_ALEN);
801 params_le->bss_type = DOT11_BSSTYPE_ANY;
802 params_le->scan_type = 0;
803 params_le->channel_num = 0;
804 params_le->nprobes = cpu_to_le32(-1);
805 params_le->active_time = cpu_to_le32(-1);
806 params_le->passive_time = cpu_to_le32(-1);
807 params_le->home_time = cpu_to_le32(-1);
808 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
810 /* if request is null exit so it will be all channel broadcast scan */
814 n_ssids = request->n_ssids;
815 n_channels = request->n_channels;
816 /* Copy channel array if applicable */
817 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
819 if (n_channels > 0) {
820 for (i = 0; i < n_channels; i++) {
821 chanspec = channel_to_chanspec(&cfg->d11inf,
822 request->channels[i]);
823 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
824 request->channels[i]->hw_value, chanspec);
825 params_le->channel_list[i] = cpu_to_le16(chanspec);
828 brcmf_dbg(SCAN, "Scanning all channels\n");
830 /* Copy ssid array if applicable */
831 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
833 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
834 n_channels * sizeof(u16);
835 offset = roundup(offset, sizeof(u32));
836 ptr = (char *)params_le + offset;
837 for (i = 0; i < n_ssids; i++) {
838 memset(&ssid_le, 0, sizeof(ssid_le));
840 cpu_to_le32(request->ssids[i].ssid_len);
841 memcpy(ssid_le.SSID, request->ssids[i].ssid,
842 request->ssids[i].ssid_len);
843 if (!ssid_le.SSID_len)
844 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
846 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
847 i, ssid_le.SSID, ssid_le.SSID_len);
848 memcpy(ptr, &ssid_le, sizeof(ssid_le));
849 ptr += sizeof(ssid_le);
852 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
853 if ((request->ssids) && request->ssids->ssid_len) {
854 brcmf_dbg(SCAN, "SSID %s len=%d\n",
855 params_le->ssid_le.SSID,
856 request->ssids->ssid_len);
857 params_le->ssid_le.SSID_len =
858 cpu_to_le32(request->ssids->ssid_len);
859 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
860 request->ssids->ssid_len);
863 /* Adding mask to channel numbers */
864 params_le->channel_num =
865 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
866 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
870 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
871 struct cfg80211_scan_request *request, u16 action)
873 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
874 offsetof(struct brcmf_escan_params_le, params_le);
875 struct brcmf_escan_params_le *params;
878 brcmf_dbg(SCAN, "E-SCAN START\n");
880 if (request != NULL) {
881 /* Allocate space for populating ssids in struct */
882 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
884 /* Allocate space for populating ssids in struct */
885 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
888 params = kzalloc(params_size, GFP_KERNEL);
893 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
894 brcmf_escan_prep(cfg, ¶ms->params_le, request);
895 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
896 params->action = cpu_to_le16(action);
897 params->sync_id = cpu_to_le16(0x1234);
899 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
902 brcmf_dbg(INFO, "system busy : escan canceled\n");
904 brcmf_err("error (%d)\n", err);
913 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
914 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
918 struct brcmf_scan_results *results;
919 struct escan_info *escan = &cfg->escan_info;
921 brcmf_dbg(SCAN, "Enter\n");
923 escan->wiphy = wiphy;
924 escan->escan_state = WL_ESCAN_STATE_SCANNING;
925 passive_scan = cfg->active_scan ? 0 : 1;
926 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
929 brcmf_err("error (%d)\n", err);
932 brcmf_scan_config_mpc(ifp, 0);
933 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
934 results->version = 0;
936 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
938 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
940 brcmf_scan_config_mpc(ifp, 1);
945 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
946 struct cfg80211_scan_request *request,
947 struct cfg80211_ssid *this_ssid)
949 struct brcmf_if *ifp = vif->ifp;
950 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
951 struct cfg80211_ssid *ssids;
952 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
959 brcmf_dbg(SCAN, "START ESCAN\n");
961 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
962 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
965 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
966 brcmf_err("Scanning being aborted: status (%lu)\n",
970 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
971 brcmf_err("Scanning suppressed: status (%lu)\n",
975 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
976 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
980 /* If scan req comes for p2p0, send it over primary I/F */
981 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
982 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
984 /* Arm scan timeout timer */
985 mod_timer(&cfg->escan_timeout, jiffies +
986 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
991 ssids = request->ssids;
995 /* we don't do escan in ibss */
999 cfg->scan_request = request;
1000 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1002 cfg->escan_info.run = brcmf_run_escan;
1003 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1007 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1011 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1012 ssids->ssid, ssids->ssid_len);
1013 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1014 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1015 sr->ssid_le.SSID_len = cpu_to_le32(0);
1018 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1019 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1022 brcmf_dbg(SCAN, "Broadcast scan\n");
1024 passive_scan = cfg->active_scan ? 0 : 1;
1025 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1028 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1031 brcmf_scan_config_mpc(ifp, 0);
1032 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1033 &sr->ssid_le, sizeof(sr->ssid_le));
1036 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1039 brcmf_err("WLC_SCAN error (%d)\n", err);
1041 brcmf_scan_config_mpc(ifp, 1);
1049 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1050 if (timer_pending(&cfg->escan_timeout))
1051 del_timer_sync(&cfg->escan_timeout);
1052 cfg->scan_request = NULL;
1057 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1059 struct brcmf_cfg80211_vif *vif;
1062 brcmf_dbg(TRACE, "Enter\n");
1063 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1064 if (!check_vif_up(vif))
1067 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1070 brcmf_err("scan error (%d)\n", err);
1072 brcmf_dbg(TRACE, "Exit\n");
1076 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1080 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1083 brcmf_err("Error (%d)\n", err);
1088 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1092 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1095 brcmf_err("Error (%d)\n", err);
1100 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1103 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1105 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1107 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1113 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1115 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1116 struct net_device *ndev = cfg_to_ndev(cfg);
1117 struct brcmf_if *ifp = netdev_priv(ndev);
1120 brcmf_dbg(TRACE, "Enter\n");
1121 if (!check_vif_up(ifp->vif))
1124 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1125 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1126 cfg->conf->rts_threshold = wiphy->rts_threshold;
1127 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1131 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1132 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1133 cfg->conf->frag_threshold = wiphy->frag_threshold;
1134 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1138 if (changed & WIPHY_PARAM_RETRY_LONG
1139 && (cfg->conf->retry_long != wiphy->retry_long)) {
1140 cfg->conf->retry_long = wiphy->retry_long;
1141 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1145 if (changed & WIPHY_PARAM_RETRY_SHORT
1146 && (cfg->conf->retry_short != wiphy->retry_short)) {
1147 cfg->conf->retry_short = wiphy->retry_short;
1148 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1154 brcmf_dbg(TRACE, "Exit\n");
1158 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1160 memset(prof, 0, sizeof(*prof));
1163 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1165 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1168 brcmf_dbg(TRACE, "Enter\n");
1170 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1171 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1172 err = brcmf_fil_cmd_data_set(vif->ifp,
1173 BRCMF_C_DISASSOC, NULL, 0);
1175 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1177 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1178 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1181 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1182 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1183 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1184 brcmf_dbg(TRACE, "Exit\n");
1188 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1189 struct cfg80211_ibss_params *params)
1191 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1192 struct brcmf_if *ifp = netdev_priv(ndev);
1193 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1194 struct brcmf_join_params join_params;
1195 size_t join_params_size = 0;
1201 brcmf_dbg(TRACE, "Enter\n");
1202 if (!check_vif_up(ifp->vif))
1206 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1208 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1212 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1215 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1217 brcmf_dbg(CONN, "No BSSID specified\n");
1219 if (params->chandef.chan)
1220 brcmf_dbg(CONN, "channel: %d\n",
1221 params->chandef.chan->center_freq);
1223 brcmf_dbg(CONN, "no channel specified\n");
1225 if (params->channel_fixed)
1226 brcmf_dbg(CONN, "fixed channel required\n");
1228 brcmf_dbg(CONN, "no fixed channel required\n");
1230 if (params->ie && params->ie_len)
1231 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1233 brcmf_dbg(CONN, "no ie specified\n");
1235 if (params->beacon_interval)
1236 brcmf_dbg(CONN, "beacon interval: %d\n",
1237 params->beacon_interval);
1239 brcmf_dbg(CONN, "no beacon interval specified\n");
1241 if (params->basic_rates)
1242 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1244 brcmf_dbg(CONN, "no basic rates specified\n");
1246 if (params->privacy)
1247 brcmf_dbg(CONN, "privacy required\n");
1249 brcmf_dbg(CONN, "no privacy required\n");
1251 /* Configure Privacy for starter */
1252 if (params->privacy)
1253 wsec |= WEP_ENABLED;
1255 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1257 brcmf_err("wsec failed (%d)\n", err);
1261 /* Configure Beacon Interval for starter */
1262 if (params->beacon_interval)
1263 bcnprd = params->beacon_interval;
1267 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1269 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1273 /* Configure required join parameter */
1274 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1277 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1278 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1279 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1280 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1281 join_params_size = sizeof(join_params.ssid_le);
1284 if (params->bssid) {
1285 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1286 join_params_size = sizeof(join_params.ssid_le) +
1287 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1288 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1290 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1291 memset(profile->bssid, 0, ETH_ALEN);
1295 if (params->chandef.chan) {
1299 ieee80211_frequency_to_channel(
1300 params->chandef.chan->center_freq);
1301 if (params->channel_fixed) {
1302 /* adding chanspec */
1303 chanspec = chandef_to_chanspec(&cfg->d11inf,
1305 join_params.params_le.chanspec_list[0] =
1306 cpu_to_le16(chanspec);
1307 join_params.params_le.chanspec_num = cpu_to_le32(1);
1308 join_params_size += sizeof(join_params.params_le);
1311 /* set channel for starter */
1312 target_channel = cfg->channel;
1313 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1316 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1322 cfg->ibss_starter = false;
1325 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1326 &join_params, join_params_size);
1328 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1334 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1335 brcmf_dbg(TRACE, "Exit\n");
1340 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1342 struct brcmf_if *ifp = netdev_priv(ndev);
1344 brcmf_dbg(TRACE, "Enter\n");
1345 if (!check_vif_up(ifp->vif))
1348 brcmf_link_down(ifp->vif);
1350 brcmf_dbg(TRACE, "Exit\n");
1355 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1356 struct cfg80211_connect_params *sme)
1358 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1359 struct brcmf_cfg80211_security *sec;
1363 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1364 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1365 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1366 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1368 val = WPA_AUTH_DISABLED;
1369 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1370 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1372 brcmf_err("set wpa_auth failed (%d)\n", err);
1375 sec = &profile->sec;
1376 sec->wpa_versions = sme->crypto.wpa_versions;
1380 static s32 brcmf_set_auth_type(struct net_device *ndev,
1381 struct cfg80211_connect_params *sme)
1383 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1384 struct brcmf_cfg80211_security *sec;
1388 switch (sme->auth_type) {
1389 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1391 brcmf_dbg(CONN, "open system\n");
1393 case NL80211_AUTHTYPE_SHARED_KEY:
1395 brcmf_dbg(CONN, "shared key\n");
1397 case NL80211_AUTHTYPE_AUTOMATIC:
1399 brcmf_dbg(CONN, "automatic\n");
1401 case NL80211_AUTHTYPE_NETWORK_EAP:
1402 brcmf_dbg(CONN, "network eap\n");
1405 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1409 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1411 brcmf_err("set auth failed (%d)\n", err);
1414 sec = &profile->sec;
1415 sec->auth_type = sme->auth_type;
1420 brcmf_set_wsec_mode(struct net_device *ndev,
1421 struct cfg80211_connect_params *sme, bool mfp)
1423 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1424 struct brcmf_cfg80211_security *sec;
1430 if (sme->crypto.n_ciphers_pairwise) {
1431 switch (sme->crypto.ciphers_pairwise[0]) {
1432 case WLAN_CIPHER_SUITE_WEP40:
1433 case WLAN_CIPHER_SUITE_WEP104:
1436 case WLAN_CIPHER_SUITE_TKIP:
1437 pval = TKIP_ENABLED;
1439 case WLAN_CIPHER_SUITE_CCMP:
1442 case WLAN_CIPHER_SUITE_AES_CMAC:
1446 brcmf_err("invalid cipher pairwise (%d)\n",
1447 sme->crypto.ciphers_pairwise[0]);
1451 if (sme->crypto.cipher_group) {
1452 switch (sme->crypto.cipher_group) {
1453 case WLAN_CIPHER_SUITE_WEP40:
1454 case WLAN_CIPHER_SUITE_WEP104:
1457 case WLAN_CIPHER_SUITE_TKIP:
1458 gval = TKIP_ENABLED;
1460 case WLAN_CIPHER_SUITE_CCMP:
1463 case WLAN_CIPHER_SUITE_AES_CMAC:
1467 brcmf_err("invalid cipher group (%d)\n",
1468 sme->crypto.cipher_group);
1473 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1474 /* In case of privacy, but no security and WPS then simulate */
1475 /* setting AES. WPS-2.0 allows no security */
1476 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1481 wsec = pval | gval | MFP_CAPABLE;
1484 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1486 brcmf_err("error (%d)\n", err);
1490 sec = &profile->sec;
1491 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1492 sec->cipher_group = sme->crypto.cipher_group;
1498 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1500 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1501 struct brcmf_cfg80211_security *sec;
1505 if (sme->crypto.n_akm_suites) {
1506 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1509 brcmf_err("could not get wpa_auth (%d)\n", err);
1512 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1513 switch (sme->crypto.akm_suites[0]) {
1514 case WLAN_AKM_SUITE_8021X:
1515 val = WPA_AUTH_UNSPECIFIED;
1517 case WLAN_AKM_SUITE_PSK:
1521 brcmf_err("invalid cipher group (%d)\n",
1522 sme->crypto.cipher_group);
1525 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1526 switch (sme->crypto.akm_suites[0]) {
1527 case WLAN_AKM_SUITE_8021X:
1528 val = WPA2_AUTH_UNSPECIFIED;
1530 case WLAN_AKM_SUITE_PSK:
1531 val = WPA2_AUTH_PSK;
1534 brcmf_err("invalid cipher group (%d)\n",
1535 sme->crypto.cipher_group);
1540 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1541 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1544 brcmf_err("could not set wpa_auth (%d)\n", err);
1548 sec = &profile->sec;
1549 sec->wpa_auth = sme->crypto.akm_suites[0];
1555 brcmf_set_sharedkey(struct net_device *ndev,
1556 struct cfg80211_connect_params *sme)
1558 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1559 struct brcmf_cfg80211_security *sec;
1560 struct brcmf_wsec_key key;
1564 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1566 if (sme->key_len == 0)
1569 sec = &profile->sec;
1570 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1571 sec->wpa_versions, sec->cipher_pairwise);
1573 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1576 if (!(sec->cipher_pairwise &
1577 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1580 memset(&key, 0, sizeof(key));
1581 key.len = (u32) sme->key_len;
1582 key.index = (u32) sme->key_idx;
1583 if (key.len > sizeof(key.data)) {
1584 brcmf_err("Too long key length (%u)\n", key.len);
1587 memcpy(key.data, sme->key, key.len);
1588 key.flags = BRCMF_PRIMARY_KEY;
1589 switch (sec->cipher_pairwise) {
1590 case WLAN_CIPHER_SUITE_WEP40:
1591 key.algo = CRYPTO_ALGO_WEP1;
1593 case WLAN_CIPHER_SUITE_WEP104:
1594 key.algo = CRYPTO_ALGO_WEP128;
1597 brcmf_err("Invalid algorithm (%d)\n",
1598 sme->crypto.ciphers_pairwise[0]);
1601 /* Set the new key/index */
1602 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1603 key.len, key.index, key.algo);
1604 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1605 err = send_key_to_dongle(ndev, &key);
1609 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1610 brcmf_dbg(CONN, "set auth_type to shared key\n");
1611 val = WL_AUTH_SHARED_KEY; /* shared key */
1612 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1614 brcmf_err("set auth failed (%d)\n", err);
1620 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1621 enum nl80211_auth_type type)
1623 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1624 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1625 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1626 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1632 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1633 struct cfg80211_connect_params *sme)
1635 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1636 struct brcmf_if *ifp = netdev_priv(ndev);
1637 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1638 struct ieee80211_channel *chan = sme->channel;
1639 struct brcmf_join_params join_params;
1640 size_t join_params_size;
1641 const struct brcmf_tlv *rsn_ie;
1642 const struct brcmf_vs_tlv *wpa_ie;
1645 struct brcmf_ext_join_params_le *ext_join_params;
1649 brcmf_dbg(TRACE, "Enter\n");
1650 if (!check_vif_up(ifp->vif))
1654 brcmf_err("Invalid ssid\n");
1658 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1659 /* A normal (non P2P) connection request setup. */
1662 /* find the WPA_IE */
1663 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1666 ie_len = wpa_ie->len + TLV_HDR_LEN;
1668 /* find the RSN_IE */
1669 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1674 ie_len = rsn_ie->len + TLV_HDR_LEN;
1677 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1680 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1681 sme->ie, sme->ie_len);
1683 brcmf_err("Set Assoc REQ IE Failed\n");
1685 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1687 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1691 ieee80211_frequency_to_channel(chan->center_freq);
1692 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1693 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1694 cfg->channel, chan->center_freq, chanspec);
1700 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1702 err = brcmf_set_wpa_version(ndev, sme);
1704 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1708 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1709 err = brcmf_set_auth_type(ndev, sme);
1711 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1715 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1717 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1721 err = brcmf_set_key_mgmt(ndev, sme);
1723 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1727 err = brcmf_set_sharedkey(ndev, sme);
1729 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1733 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1734 (u32)sme->ssid_len);
1735 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1736 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1737 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1738 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1739 profile->ssid.SSID_len);
1742 /* Join with specific BSSID and cached SSID
1743 * If SSID is zero join based on BSSID only
1745 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1746 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1748 join_params_size += sizeof(u16);
1749 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1750 if (ext_join_params == NULL) {
1754 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1755 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1756 profile->ssid.SSID_len);
1758 /* Set up join scan parameters */
1759 ext_join_params->scan_le.scan_type = -1;
1760 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1763 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1765 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1768 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1770 ext_join_params->assoc_le.chanspec_list[0] =
1771 cpu_to_le16(chanspec);
1772 /* Increase dwell time to receive probe response or detect
1773 * beacon from target AP at a noisy air only during connect
1776 ext_join_params->scan_le.active_time =
1777 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1778 ext_join_params->scan_le.passive_time =
1779 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1780 /* To sync with presence period of VSDB GO send probe request
1781 * more frequently. Probe request will be stopped when it gets
1782 * probe response from target AP/GO.
1784 ext_join_params->scan_le.nprobes =
1785 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1786 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1788 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1789 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1790 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1793 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1795 kfree(ext_join_params);
1797 /* This is it. join command worked, we are done */
1800 /* join command failed, fallback to set ssid */
1801 memset(&join_params, 0, sizeof(join_params));
1802 join_params_size = sizeof(join_params.ssid_le);
1804 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1805 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1808 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1810 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1813 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1814 join_params.params_le.chanspec_num = cpu_to_le32(1);
1815 join_params_size += sizeof(join_params.params_le);
1817 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1818 &join_params, join_params_size);
1820 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1824 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1825 brcmf_dbg(TRACE, "Exit\n");
1830 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1833 struct brcmf_if *ifp = netdev_priv(ndev);
1834 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1835 struct brcmf_scb_val_le scbval;
1838 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1839 if (!check_vif_up(ifp->vif))
1842 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1843 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1845 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1846 scbval.val = cpu_to_le32(reason_code);
1847 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1848 &scbval, sizeof(scbval));
1850 brcmf_err("error (%d)\n", err);
1852 brcmf_dbg(TRACE, "Exit\n");
1857 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1858 enum nl80211_tx_power_setting type, s32 mbm)
1861 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1862 struct net_device *ndev = cfg_to_ndev(cfg);
1863 struct brcmf_if *ifp = netdev_priv(ndev);
1867 s32 dbm = MBM_TO_DBM(mbm);
1869 brcmf_dbg(TRACE, "Enter\n");
1870 if (!check_vif_up(ifp->vif))
1874 case NL80211_TX_POWER_AUTOMATIC:
1876 case NL80211_TX_POWER_LIMITED:
1877 case NL80211_TX_POWER_FIXED:
1879 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1885 /* Make sure radio is off or on as far as software is concerned */
1886 disable = WL_RADIO_SW_DISABLE << 16;
1887 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1889 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1894 txpwrmw = (u16) dbm;
1895 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1896 (s32)brcmf_mw_to_qdbm(txpwrmw));
1898 brcmf_err("qtxpower error (%d)\n", err);
1899 cfg->conf->tx_power = dbm;
1902 brcmf_dbg(TRACE, "Exit\n");
1906 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1907 struct wireless_dev *wdev,
1910 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1911 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1916 brcmf_dbg(TRACE, "Enter\n");
1917 if (!check_vif_up(ifp->vif))
1920 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1922 brcmf_err("error (%d)\n", err);
1926 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1927 *dbm = (s32) brcmf_qdbm_to_mw(result);
1930 brcmf_dbg(TRACE, "Exit\n");
1935 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1936 u8 key_idx, bool unicast, bool multicast)
1938 struct brcmf_if *ifp = netdev_priv(ndev);
1943 brcmf_dbg(TRACE, "Enter\n");
1944 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1945 if (!check_vif_up(ifp->vif))
1948 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1950 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1954 if (wsec & WEP_ENABLED) {
1955 /* Just select a new current key */
1957 err = brcmf_fil_cmd_int_set(ifp,
1958 BRCMF_C_SET_KEY_PRIMARY, index);
1960 brcmf_err("error (%d)\n", err);
1963 brcmf_dbg(TRACE, "Exit\n");
1968 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1969 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1971 struct brcmf_if *ifp = netdev_priv(ndev);
1972 struct brcmf_wsec_key key;
1976 memset(&key, 0, sizeof(key));
1977 key.index = (u32) key_idx;
1978 /* Instead of bcast for ea address for default wep keys,
1979 driver needs it to be Null */
1980 if (!is_multicast_ether_addr(mac_addr))
1981 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1982 key.len = (u32) params->key_len;
1983 /* check for key index change */
1986 err = send_key_to_dongle(ndev, &key);
1988 brcmf_err("key delete error (%d)\n", err);
1990 if (key.len > sizeof(key.data)) {
1991 brcmf_err("Invalid key length (%d)\n", key.len);
1995 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1996 memcpy(key.data, params->key, key.len);
1998 if (!brcmf_is_apmode(ifp->vif) &&
1999 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2000 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2001 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2002 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2003 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2006 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2007 if (params->seq && params->seq_len == 6) {
2010 ivptr = (u8 *) params->seq;
2011 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2012 (ivptr[3] << 8) | ivptr[2];
2013 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2014 key.iv_initialized = true;
2017 switch (params->cipher) {
2018 case WLAN_CIPHER_SUITE_WEP40:
2019 key.algo = CRYPTO_ALGO_WEP1;
2020 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2022 case WLAN_CIPHER_SUITE_WEP104:
2023 key.algo = CRYPTO_ALGO_WEP128;
2024 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2026 case WLAN_CIPHER_SUITE_TKIP:
2027 key.algo = CRYPTO_ALGO_TKIP;
2028 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2030 case WLAN_CIPHER_SUITE_AES_CMAC:
2031 key.algo = CRYPTO_ALGO_AES_CCM;
2032 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2034 case WLAN_CIPHER_SUITE_CCMP:
2035 key.algo = CRYPTO_ALGO_AES_CCM;
2036 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2039 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2042 err = send_key_to_dongle(ndev, &key);
2044 brcmf_err("wsec_key error (%d)\n", err);
2050 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2051 u8 key_idx, bool pairwise, const u8 *mac_addr,
2052 struct key_params *params)
2054 struct brcmf_if *ifp = netdev_priv(ndev);
2055 struct brcmf_wsec_key key;
2061 brcmf_dbg(TRACE, "Enter\n");
2062 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2063 if (!check_vif_up(ifp->vif))
2067 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2068 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2069 brcmf_dbg(TRACE, "Exit");
2070 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2072 memset(&key, 0, sizeof(key));
2074 key.len = (u32) params->key_len;
2075 key.index = (u32) key_idx;
2077 if (key.len > sizeof(key.data)) {
2078 brcmf_err("Too long key length (%u)\n", key.len);
2082 memcpy(key.data, params->key, key.len);
2084 key.flags = BRCMF_PRIMARY_KEY;
2085 switch (params->cipher) {
2086 case WLAN_CIPHER_SUITE_WEP40:
2087 key.algo = CRYPTO_ALGO_WEP1;
2089 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2091 case WLAN_CIPHER_SUITE_WEP104:
2092 key.algo = CRYPTO_ALGO_WEP128;
2094 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2096 case WLAN_CIPHER_SUITE_TKIP:
2097 if (!brcmf_is_apmode(ifp->vif)) {
2098 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2099 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2100 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2101 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2103 key.algo = CRYPTO_ALGO_TKIP;
2105 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2107 case WLAN_CIPHER_SUITE_AES_CMAC:
2108 key.algo = CRYPTO_ALGO_AES_CCM;
2110 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2112 case WLAN_CIPHER_SUITE_CCMP:
2113 key.algo = CRYPTO_ALGO_AES_CCM;
2115 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2118 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2123 err = send_key_to_dongle(ndev, &key);
2127 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2129 brcmf_err("get wsec error (%d)\n", err);
2133 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2135 brcmf_err("set wsec error (%d)\n", err);
2140 brcmf_dbg(TRACE, "Exit\n");
2145 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2146 u8 key_idx, bool pairwise, const u8 *mac_addr)
2148 struct brcmf_if *ifp = netdev_priv(ndev);
2149 struct brcmf_wsec_key key;
2152 brcmf_dbg(TRACE, "Enter\n");
2153 if (!check_vif_up(ifp->vif))
2156 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2157 /* we ignore this key index in this case */
2158 brcmf_err("invalid key index (%d)\n", key_idx);
2162 memset(&key, 0, sizeof(key));
2164 key.index = (u32) key_idx;
2165 key.flags = BRCMF_PRIMARY_KEY;
2166 key.algo = CRYPTO_ALGO_OFF;
2168 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2170 /* Set the new key/index */
2171 err = send_key_to_dongle(ndev, &key);
2173 brcmf_dbg(TRACE, "Exit\n");
2178 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2179 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2180 void (*callback) (void *cookie, struct key_params * params))
2182 struct key_params params;
2183 struct brcmf_if *ifp = netdev_priv(ndev);
2184 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2185 struct brcmf_cfg80211_security *sec;
2189 brcmf_dbg(TRACE, "Enter\n");
2190 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2191 if (!check_vif_up(ifp->vif))
2194 memset(¶ms, 0, sizeof(params));
2196 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2198 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2199 /* Ignore this error, may happen during DISASSOC */
2203 if (wsec & WEP_ENABLED) {
2204 sec = &profile->sec;
2205 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2206 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2207 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2208 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2209 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2210 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2212 } else if (wsec & TKIP_ENABLED) {
2213 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2214 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2215 } else if (wsec & AES_ENABLED) {
2216 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2217 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2219 brcmf_err("Invalid algo (0x%x)\n", wsec);
2223 callback(cookie, ¶ms);
2226 brcmf_dbg(TRACE, "Exit\n");
2231 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2232 struct net_device *ndev, u8 key_idx)
2234 brcmf_dbg(INFO, "Not supported\n");
2240 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2241 const u8 *mac, struct station_info *sinfo)
2243 struct brcmf_if *ifp = netdev_priv(ndev);
2244 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2245 struct brcmf_scb_val_le scb_val;
2249 u8 *bssid = profile->bssid;
2250 struct brcmf_sta_info_le sta_info_le;
2254 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2255 if (!check_vif_up(ifp->vif))
2258 if (brcmf_is_apmode(ifp->vif)) {
2259 memcpy(&sta_info_le, mac, ETH_ALEN);
2260 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2262 sizeof(sta_info_le));
2264 brcmf_err("GET STA INFO failed, %d\n", err);
2267 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2268 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2269 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2270 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2271 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2273 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2274 sinfo->inactive_time, sinfo->connected_time);
2275 } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
2276 if (memcmp(mac, bssid, ETH_ALEN)) {
2277 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2282 /* Report the current tx rate */
2283 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2285 brcmf_err("Could not get rate (%d)\n", err);
2288 sinfo->filled |= STATION_INFO_TX_BITRATE;
2289 sinfo->txrate.legacy = rate * 5;
2290 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2293 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2294 &ifp->vif->sme_state)) {
2295 memset(&scb_val, 0, sizeof(scb_val));
2296 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2297 &scb_val, sizeof(scb_val));
2299 brcmf_err("Could not get rssi (%d)\n", err);
2302 rssi = le32_to_cpu(scb_val.val);
2303 sinfo->filled |= STATION_INFO_SIGNAL;
2304 sinfo->signal = rssi;
2305 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2307 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2310 brcmf_err("Could not get beacon period (%d)\n",
2314 sinfo->bss_param.beacon_interval =
2316 brcmf_dbg(CONN, "Beacon peroid %d\n",
2319 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2322 brcmf_err("Could not get DTIM period (%d)\n",
2326 sinfo->bss_param.dtim_period = dtim_period;
2327 brcmf_dbg(CONN, "DTIM peroid %d\n",
2330 sinfo->filled |= STATION_INFO_BSS_PARAM;
2335 brcmf_dbg(TRACE, "Exit\n");
2340 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2341 bool enabled, s32 timeout)
2345 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2346 struct brcmf_if *ifp = netdev_priv(ndev);
2348 brcmf_dbg(TRACE, "Enter\n");
2351 * Powersave enable/disable request is coming from the
2352 * cfg80211 even before the interface is up. In that
2353 * scenario, driver will be storing the power save
2354 * preference in cfg struct to apply this to
2355 * FW later while initializing the dongle
2357 cfg->pwr_save = enabled;
2358 if (!check_vif_up(ifp->vif)) {
2360 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2364 pm = enabled ? PM_FAST : PM_OFF;
2365 /* Do not enable the power save after assoc if it is a p2p interface */
2366 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2367 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2370 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2372 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2375 brcmf_err("net_device is not ready yet\n");
2377 brcmf_err("error (%d)\n", err);
2380 brcmf_dbg(TRACE, "Exit\n");
2384 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2385 struct brcmf_bss_info_le *bi)
2387 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2388 struct ieee80211_channel *notify_channel;
2389 struct cfg80211_bss *bss;
2390 struct ieee80211_supported_band *band;
2391 struct brcmu_chan ch;
2394 u16 notify_capability;
2395 u16 notify_interval;
2397 size_t notify_ielen;
2400 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2401 brcmf_err("Bss info is larger than buffer. Discarding\n");
2406 ch.chspec = le16_to_cpu(bi->chanspec);
2407 cfg->d11inf.decchspec(&ch);
2408 bi->ctl_ch = ch.chnum;
2410 channel = bi->ctl_ch;
2412 if (channel <= CH_MAX_2G_CHANNEL)
2413 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2415 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2417 freq = ieee80211_channel_to_frequency(channel, band->band);
2418 notify_channel = ieee80211_get_channel(wiphy, freq);
2420 notify_capability = le16_to_cpu(bi->capability);
2421 notify_interval = le16_to_cpu(bi->beacon_period);
2422 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2423 notify_ielen = le32_to_cpu(bi->ie_length);
2424 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2426 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2427 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2428 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2429 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2430 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2432 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2433 0, notify_capability, notify_interval, notify_ie,
2434 notify_ielen, notify_signal, GFP_KERNEL);
2439 cfg80211_put_bss(wiphy, bss);
2444 static struct brcmf_bss_info_le *
2445 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2448 return list->bss_info_le;
2449 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2450 le32_to_cpu(bss->length));
2453 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2455 struct brcmf_scan_results *bss_list;
2456 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2460 bss_list = cfg->bss_list;
2461 if (bss_list->count != 0 &&
2462 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2463 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2467 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2468 for (i = 0; i < bss_list->count; i++) {
2469 bi = next_bss_le(bss_list, bi);
2470 err = brcmf_inform_single_bss(cfg, bi);
2477 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2478 struct net_device *ndev, const u8 *bssid)
2480 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2481 struct ieee80211_channel *notify_channel;
2482 struct brcmf_bss_info_le *bi = NULL;
2483 struct ieee80211_supported_band *band;
2484 struct cfg80211_bss *bss;
2485 struct brcmu_chan ch;
2489 u16 notify_capability;
2490 u16 notify_interval;
2492 size_t notify_ielen;
2495 brcmf_dbg(TRACE, "Enter\n");
2497 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2503 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2505 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2506 buf, WL_BSS_INFO_MAX);
2508 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2512 bi = (struct brcmf_bss_info_le *)(buf + 4);
2514 ch.chspec = le16_to_cpu(bi->chanspec);
2515 cfg->d11inf.decchspec(&ch);
2517 if (ch.band == BRCMU_CHAN_BAND_2G)
2518 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2520 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2522 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2523 notify_channel = ieee80211_get_channel(wiphy, freq);
2525 notify_capability = le16_to_cpu(bi->capability);
2526 notify_interval = le16_to_cpu(bi->beacon_period);
2527 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2528 notify_ielen = le32_to_cpu(bi->ie_length);
2529 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2531 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2532 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2533 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2534 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2536 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2537 0, notify_capability, notify_interval,
2538 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2545 cfg80211_put_bss(wiphy, bss);
2551 brcmf_dbg(TRACE, "Exit\n");
2556 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2557 struct brcmf_if *ifp)
2559 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2560 struct brcmf_bss_info_le *bi;
2561 struct brcmf_ssid *ssid;
2562 const struct brcmf_tlv *tim;
2563 u16 beacon_interval;
2569 brcmf_dbg(TRACE, "Enter\n");
2570 if (brcmf_is_ibssmode(ifp->vif))
2573 ssid = &profile->ssid;
2575 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2576 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2577 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2579 brcmf_err("Could not get bss info %d\n", err);
2580 goto update_bss_info_out;
2583 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2584 err = brcmf_inform_single_bss(cfg, bi);
2586 goto update_bss_info_out;
2588 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2589 ie_len = le32_to_cpu(bi->ie_length);
2590 beacon_interval = le16_to_cpu(bi->beacon_period);
2592 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2594 dtim_period = tim->data[1];
2597 * active scan was done so we could not get dtim
2598 * information out of probe response.
2599 * so we speficially query dtim information to dongle.
2602 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2604 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2605 goto update_bss_info_out;
2607 dtim_period = (u8)var;
2610 update_bss_info_out:
2611 brcmf_dbg(TRACE, "Exit");
2615 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2617 struct escan_info *escan = &cfg->escan_info;
2619 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2620 if (cfg->scan_request) {
2621 escan->escan_state = WL_ESCAN_STATE_IDLE;
2622 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2624 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2625 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2628 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2630 struct brcmf_cfg80211_info *cfg =
2631 container_of(work, struct brcmf_cfg80211_info,
2632 escan_timeout_work);
2634 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2637 static void brcmf_escan_timeout(unsigned long data)
2639 struct brcmf_cfg80211_info *cfg =
2640 (struct brcmf_cfg80211_info *)data;
2642 if (cfg->scan_request) {
2643 brcmf_err("timer expired\n");
2644 schedule_work(&cfg->escan_timeout_work);
2649 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2650 struct brcmf_bss_info_le *bss,
2651 struct brcmf_bss_info_le *bss_info_le)
2653 struct brcmu_chan ch_bss, ch_bss_info_le;
2655 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2656 cfg->d11inf.decchspec(&ch_bss);
2657 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2658 cfg->d11inf.decchspec(&ch_bss_info_le);
2660 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2661 ch_bss.band == ch_bss_info_le.band &&
2662 bss_info_le->SSID_len == bss->SSID_len &&
2663 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2664 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2665 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2666 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2667 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2669 /* preserve max RSSI if the measurements are
2670 * both on-channel or both off-channel
2672 if (bss_info_rssi > bss_rssi)
2673 bss->RSSI = bss_info_le->RSSI;
2674 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2675 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2676 /* preserve the on-channel rssi measurement
2677 * if the new measurement is off channel
2679 bss->RSSI = bss_info_le->RSSI;
2680 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2688 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2689 const struct brcmf_event_msg *e, void *data)
2691 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2693 struct brcmf_escan_result_le *escan_result_le;
2694 struct brcmf_bss_info_le *bss_info_le;
2695 struct brcmf_bss_info_le *bss = NULL;
2697 struct brcmf_scan_results *list;
2703 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2704 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2708 if (status == BRCMF_E_STATUS_PARTIAL) {
2709 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2710 escan_result_le = (struct brcmf_escan_result_le *) data;
2711 if (!escan_result_le) {
2712 brcmf_err("Invalid escan result (NULL pointer)\n");
2715 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2716 brcmf_err("Invalid bss_count %d: ignoring\n",
2717 escan_result_le->bss_count);
2720 bss_info_le = &escan_result_le->bss_info_le;
2722 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2725 if (!cfg->scan_request) {
2726 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2730 bi_length = le32_to_cpu(bss_info_le->length);
2731 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2732 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2733 brcmf_err("Invalid bss_info length %d: ignoring\n",
2738 if (!(cfg_to_wiphy(cfg)->interface_modes &
2739 BIT(NL80211_IFTYPE_ADHOC))) {
2740 if (le16_to_cpu(bss_info_le->capability) &
2741 WLAN_CAPABILITY_IBSS) {
2742 brcmf_err("Ignoring IBSS result\n");
2747 list = (struct brcmf_scan_results *)
2748 cfg->escan_info.escan_buf;
2749 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2750 brcmf_err("Buffer is too small: ignoring\n");
2754 for (i = 0; i < list->count; i++) {
2755 bss = bss ? (struct brcmf_bss_info_le *)
2756 ((unsigned char *)bss +
2757 le32_to_cpu(bss->length)) : list->bss_info_le;
2758 if (brcmf_compare_update_same_bss(cfg, bss,
2762 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2763 bss_info_le, bi_length);
2764 list->version = le32_to_cpu(bss_info_le->version);
2765 list->buflen += bi_length;
2768 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2769 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2771 if (cfg->scan_request) {
2772 cfg->bss_list = (struct brcmf_scan_results *)
2773 cfg->escan_info.escan_buf;
2774 brcmf_inform_bss(cfg);
2775 aborted = status != BRCMF_E_STATUS_SUCCESS;
2776 brcmf_notify_escan_complete(cfg, ifp, aborted,
2779 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2786 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2788 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2789 brcmf_cfg80211_escan_handler);
2790 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2791 /* Init scan_timeout timer */
2792 init_timer(&cfg->escan_timeout);
2793 cfg->escan_timeout.data = (unsigned long) cfg;
2794 cfg->escan_timeout.function = brcmf_escan_timeout;
2795 INIT_WORK(&cfg->escan_timeout_work,
2796 brcmf_cfg80211_escan_timeout_worker);
2799 static __always_inline void brcmf_delay(u32 ms)
2801 if (ms < 1000 / HZ) {
2809 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2811 brcmf_dbg(TRACE, "Enter\n");
2816 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2817 struct cfg80211_wowlan *wow)
2819 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2820 struct net_device *ndev = cfg_to_ndev(cfg);
2821 struct brcmf_cfg80211_vif *vif;
2823 brcmf_dbg(TRACE, "Enter\n");
2826 * if the primary net_device is not READY there is nothing
2827 * we can do but pray resume goes smoothly.
2829 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2830 if (!check_vif_up(vif))
2833 list_for_each_entry(vif, &cfg->vif_list, list) {
2834 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2837 * While going to suspend if associated with AP disassociate
2838 * from AP to save power while system is in suspended state
2840 brcmf_link_down(vif);
2842 /* Make sure WPA_Supplicant receives all the event
2843 * generated due to DISASSOC call to the fw to keep
2844 * the state fw and WPA_Supplicant state consistent
2849 /* end any scanning */
2850 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2851 brcmf_abort_scanning(cfg);
2853 /* Turn off watchdog timer */
2854 brcmf_set_mpc(netdev_priv(ndev), 1);
2857 brcmf_dbg(TRACE, "Exit\n");
2858 /* clear any scanning activity */
2859 cfg->scan_status = 0;
2864 brcmf_update_pmklist(struct net_device *ndev,
2865 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2870 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2872 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2873 for (i = 0; i < pmkid_len; i++) {
2874 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2875 &pmk_list->pmkids.pmkid[i].BSSID);
2876 for (j = 0; j < WLAN_PMKID_LEN; j++)
2877 brcmf_dbg(CONN, "%02x\n",
2878 pmk_list->pmkids.pmkid[i].PMKID[j]);
2882 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2883 (char *)pmk_list, sizeof(*pmk_list));
2889 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2890 struct cfg80211_pmksa *pmksa)
2892 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2893 struct brcmf_if *ifp = netdev_priv(ndev);
2894 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2899 brcmf_dbg(TRACE, "Enter\n");
2900 if (!check_vif_up(ifp->vif))
2903 pmkid_len = le32_to_cpu(pmkids->npmkid);
2904 for (i = 0; i < pmkid_len; i++)
2905 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2907 if (i < WL_NUM_PMKIDS_MAX) {
2908 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2909 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2910 if (i == pmkid_len) {
2912 pmkids->npmkid = cpu_to_le32(pmkid_len);
2917 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2918 pmkids->pmkid[pmkid_len].BSSID);
2919 for (i = 0; i < WLAN_PMKID_LEN; i++)
2920 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2922 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2924 brcmf_dbg(TRACE, "Exit\n");
2929 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2930 struct cfg80211_pmksa *pmksa)
2932 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2933 struct brcmf_if *ifp = netdev_priv(ndev);
2934 struct pmkid_list pmkid;
2938 brcmf_dbg(TRACE, "Enter\n");
2939 if (!check_vif_up(ifp->vif))
2942 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2943 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2945 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2946 &pmkid.pmkid[0].BSSID);
2947 for (i = 0; i < WLAN_PMKID_LEN; i++)
2948 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2950 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2951 for (i = 0; i < pmkid_len; i++)
2953 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2958 && (i < pmkid_len)) {
2959 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2960 sizeof(struct pmkid));
2961 for (; i < (pmkid_len - 1); i++) {
2962 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2963 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2965 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2966 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2969 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2973 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2975 brcmf_dbg(TRACE, "Exit\n");
2981 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2983 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2984 struct brcmf_if *ifp = netdev_priv(ndev);
2987 brcmf_dbg(TRACE, "Enter\n");
2988 if (!check_vif_up(ifp->vif))
2991 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2992 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2994 brcmf_dbg(TRACE, "Exit\n");
3000 * PFN result doesn't have all the info which are
3001 * required by the supplicant
3002 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3003 * via wl_inform_single_bss in the required format. Escan does require the
3004 * scan request in the form of cfg80211_scan_request. For timebeing, create
3005 * cfg80211_scan_request one out of the received PNO event.
3008 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3009 const struct brcmf_event_msg *e, void *data)
3011 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3012 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3013 struct cfg80211_scan_request *request = NULL;
3014 struct cfg80211_ssid *ssid = NULL;
3015 struct ieee80211_channel *channel = NULL;
3016 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3018 int channel_req = 0;
3020 struct brcmf_pno_scanresults_le *pfn_result;
3024 brcmf_dbg(SCAN, "Enter\n");
3026 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3027 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3031 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3032 result_count = le32_to_cpu(pfn_result->count);
3033 status = le32_to_cpu(pfn_result->status);
3036 * PFN event is limited to fit 512 bytes so we may get
3037 * multiple NET_FOUND events. For now place a warning here.
3039 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3040 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3041 if (result_count > 0) {
3044 request = kzalloc(sizeof(*request), GFP_KERNEL);
3045 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3046 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3047 if (!request || !ssid || !channel) {
3052 request->wiphy = wiphy;
3053 data += sizeof(struct brcmf_pno_scanresults_le);
3054 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3056 for (i = 0; i < result_count; i++) {
3057 netinfo = &netinfo_start[i];
3059 brcmf_err("Invalid netinfo ptr. index: %d\n",
3065 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3066 netinfo->SSID, netinfo->channel);
3067 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3068 ssid[i].ssid_len = netinfo->SSID_len;
3071 channel_req = netinfo->channel;
3072 if (channel_req <= CH_MAX_2G_CHANNEL)
3073 band = NL80211_BAND_2GHZ;
3075 band = NL80211_BAND_5GHZ;
3076 channel[i].center_freq =
3077 ieee80211_channel_to_frequency(channel_req,
3079 channel[i].band = band;
3080 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3081 request->channels[i] = &channel[i];
3082 request->n_channels++;
3085 /* assign parsed ssid array */
3086 if (request->n_ssids)
3087 request->ssids = &ssid[0];
3089 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3090 /* Abort any on-going scan */
3091 brcmf_abort_scanning(cfg);
3094 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3095 cfg->escan_info.run = brcmf_run_escan;
3096 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3098 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3101 cfg->sched_escan = true;
3102 cfg->scan_request = request;
3104 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3117 cfg80211_sched_scan_stopped(wiphy);
3121 static int brcmf_dev_pno_clean(struct net_device *ndev)
3126 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3129 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3133 brcmf_err("failed code %d\n", ret);
3138 static int brcmf_dev_pno_config(struct net_device *ndev)
3140 struct brcmf_pno_param_le pfn_param;
3142 memset(&pfn_param, 0, sizeof(pfn_param));
3143 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3145 /* set extra pno params */
3146 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3147 pfn_param.repeat = BRCMF_PNO_REPEAT;
3148 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3150 /* set up pno scan fr */
3151 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3153 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3154 &pfn_param, sizeof(pfn_param));
3158 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3159 struct net_device *ndev,
3160 struct cfg80211_sched_scan_request *request)
3162 struct brcmf_if *ifp = netdev_priv(ndev);
3163 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3164 struct brcmf_pno_net_param_le pfn;
3168 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3169 request->n_match_sets, request->n_ssids);
3170 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3171 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3174 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3175 brcmf_err("Scanning suppressed: status (%lu)\n",
3180 if (!request->n_ssids || !request->n_match_sets) {
3181 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3186 if (request->n_ssids > 0) {
3187 for (i = 0; i < request->n_ssids; i++) {
3188 /* Active scan req for ssids */
3189 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3190 request->ssids[i].ssid);
3193 * match_set ssids is a supert set of n_ssid list,
3194 * so we need not add these set seperately.
3199 if (request->n_match_sets > 0) {
3200 /* clean up everything */
3201 ret = brcmf_dev_pno_clean(ndev);
3203 brcmf_err("failed error=%d\n", ret);
3208 ret = brcmf_dev_pno_config(ndev);
3210 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3214 /* configure each match set */
3215 for (i = 0; i < request->n_match_sets; i++) {
3216 struct cfg80211_ssid *ssid;
3219 ssid = &request->match_sets[i].ssid;
3220 ssid_len = ssid->ssid_len;
3223 brcmf_err("skip broadcast ssid\n");
3226 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3227 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3228 pfn.wsec = cpu_to_le32(0);
3229 pfn.infra = cpu_to_le32(1);
3230 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3231 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3232 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3233 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3235 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3236 ret == 0 ? "set" : "failed", ssid->ssid);
3238 /* Enable the PNO */
3239 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3240 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3250 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3251 struct net_device *ndev)
3253 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3255 brcmf_dbg(SCAN, "enter\n");
3256 brcmf_dev_pno_clean(ndev);
3257 if (cfg->sched_escan)
3258 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3262 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3267 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3269 brcmf_err("auth error %d\n", err);
3273 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3275 brcmf_err("wsec error %d\n", err);
3278 /* set upper-layer auth */
3279 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3281 brcmf_err("wpa_auth error %d\n", err);
3288 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3291 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3293 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3297 brcmf_configure_wpaie(struct net_device *ndev,
3298 const struct brcmf_vs_tlv *wpa_ie,
3301 struct brcmf_if *ifp = netdev_priv(ndev);
3302 u32 auth = 0; /* d11 open authentication */
3314 u32 wme_bss_disable;
3316 brcmf_dbg(TRACE, "Enter\n");
3320 len = wpa_ie->len + TLV_HDR_LEN;
3321 data = (u8 *)wpa_ie;
3322 offset = TLV_HDR_LEN;
3324 offset += VS_IE_FIXED_HDR_LEN;
3326 offset += WPA_IE_VERSION_LEN;
3328 /* check for multicast cipher suite */
3329 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3331 brcmf_err("no multicast cipher suite\n");
3335 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3337 brcmf_err("ivalid OUI\n");
3340 offset += TLV_OUI_LEN;
3342 /* pick up multicast cipher */
3343 switch (data[offset]) {
3344 case WPA_CIPHER_NONE:
3347 case WPA_CIPHER_WEP_40:
3348 case WPA_CIPHER_WEP_104:
3351 case WPA_CIPHER_TKIP:
3352 gval = TKIP_ENABLED;
3354 case WPA_CIPHER_AES_CCM:
3359 brcmf_err("Invalid multi cast cipher info\n");
3364 /* walk thru unicast cipher list and pick up what we recognize */
3365 count = data[offset] + (data[offset + 1] << 8);
3366 offset += WPA_IE_SUITE_COUNT_LEN;
3367 /* Check for unicast suite(s) */
3368 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3370 brcmf_err("no unicast cipher suite\n");
3373 for (i = 0; i < count; i++) {
3374 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3376 brcmf_err("ivalid OUI\n");
3379 offset += TLV_OUI_LEN;
3380 switch (data[offset]) {
3381 case WPA_CIPHER_NONE:
3383 case WPA_CIPHER_WEP_40:
3384 case WPA_CIPHER_WEP_104:
3385 pval |= WEP_ENABLED;
3387 case WPA_CIPHER_TKIP:
3388 pval |= TKIP_ENABLED;
3390 case WPA_CIPHER_AES_CCM:
3391 pval |= AES_ENABLED;
3394 brcmf_err("Ivalid unicast security info\n");
3398 /* walk thru auth management suite list and pick up what we recognize */
3399 count = data[offset] + (data[offset + 1] << 8);
3400 offset += WPA_IE_SUITE_COUNT_LEN;
3401 /* Check for auth key management suite(s) */
3402 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3404 brcmf_err("no auth key mgmt suite\n");
3407 for (i = 0; i < count; i++) {
3408 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3410 brcmf_err("ivalid OUI\n");
3413 offset += TLV_OUI_LEN;
3414 switch (data[offset]) {
3416 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3417 wpa_auth |= WPA_AUTH_NONE;
3419 case RSN_AKM_UNSPECIFIED:
3420 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3421 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3422 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3425 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3426 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3427 (wpa_auth |= WPA_AUTH_PSK);
3430 brcmf_err("Ivalid key mgmt info\n");
3436 wme_bss_disable = 1;
3437 if ((offset + RSN_CAP_LEN) <= len) {
3438 rsn_cap = data[offset] + (data[offset + 1] << 8);
3439 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3440 wme_bss_disable = 0;
3442 /* set wme_bss_disable to sync RSN Capabilities */
3443 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3446 brcmf_err("wme_bss_disable error %d\n", err);
3450 /* FOR WPS , set SES_OW_ENABLED */
3451 wsec = (pval | gval | SES_OW_ENABLED);
3454 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3456 brcmf_err("auth error %d\n", err);
3460 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3462 brcmf_err("wsec error %d\n", err);
3465 /* set upper-layer auth */
3466 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3468 brcmf_err("wpa_auth error %d\n", err);
3477 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3478 struct parsed_vndr_ies *vndr_ies)
3480 struct brcmf_vs_tlv *vndrie;
3481 struct brcmf_tlv *ie;
3482 struct parsed_vndr_ie_info *parsed_info;
3485 remaining_len = (s32)vndr_ie_len;
3486 memset(vndr_ies, 0, sizeof(*vndr_ies));
3488 ie = (struct brcmf_tlv *)vndr_ie_buf;
3490 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3492 vndrie = (struct brcmf_vs_tlv *)ie;
3493 /* len should be bigger than OUI length + one */
3494 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3495 brcmf_err("invalid vndr ie. length is too small %d\n",
3499 /* if wpa or wme ie, do not add ie */
3500 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3501 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3502 (vndrie->oui_type == WME_OUI_TYPE))) {
3503 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3507 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3509 /* save vndr ie information */
3510 parsed_info->ie_ptr = (char *)vndrie;
3511 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3512 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3516 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3517 parsed_info->vndrie.oui[0],
3518 parsed_info->vndrie.oui[1],
3519 parsed_info->vndrie.oui[2],
3520 parsed_info->vndrie.oui_type);
3522 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3525 remaining_len -= (ie->len + TLV_HDR_LEN);
3526 if (remaining_len <= TLV_HDR_LEN)
3529 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3536 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3542 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3543 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3545 iecount_le = cpu_to_le32(1);
3546 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3548 pktflag_le = cpu_to_le32(pktflag);
3549 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3551 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3553 return ie_len + VNDR_IE_HDR_SIZE;
3556 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3557 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3559 struct brcmf_if *ifp;
3560 struct vif_saved_ie *saved_ie;
3564 u8 *mgmt_ie_buf = NULL;
3565 int mgmt_ie_buf_len;
3567 u32 del_add_ie_buf_len = 0;
3568 u32 total_ie_buf_len = 0;
3569 u32 parsed_ie_buf_len = 0;
3570 struct parsed_vndr_ies old_vndr_ies;
3571 struct parsed_vndr_ies new_vndr_ies;
3572 struct parsed_vndr_ie_info *vndrie_info;
3575 int remained_buf_len;
3580 saved_ie = &vif->saved_ie;
3582 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3583 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3586 curr_ie_buf = iovar_ie_buf;
3588 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3589 mgmt_ie_buf = saved_ie->probe_req_ie;
3590 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3591 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3593 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3594 mgmt_ie_buf = saved_ie->probe_res_ie;
3595 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3596 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3598 case BRCMF_VNDR_IE_BEACON_FLAG:
3599 mgmt_ie_buf = saved_ie->beacon_ie;
3600 mgmt_ie_len = &saved_ie->beacon_ie_len;
3601 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3603 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3604 mgmt_ie_buf = saved_ie->assoc_req_ie;
3605 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3606 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3610 brcmf_err("not suitable type\n");
3614 if (vndr_ie_len > mgmt_ie_buf_len) {
3616 brcmf_err("extra IE size too big\n");
3620 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3621 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3623 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3624 for (i = 0; i < new_vndr_ies.count; i++) {
3625 vndrie_info = &new_vndr_ies.ie_info[i];
3626 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3627 vndrie_info->ie_len);
3628 parsed_ie_buf_len += vndrie_info->ie_len;
3632 if (mgmt_ie_buf && *mgmt_ie_len) {
3633 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3634 (memcmp(mgmt_ie_buf, curr_ie_buf,
3635 parsed_ie_buf_len) == 0)) {
3636 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3640 /* parse old vndr_ie */
3641 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3643 /* make a command to delete old ie */
3644 for (i = 0; i < old_vndr_ies.count; i++) {
3645 vndrie_info = &old_vndr_ies.ie_info[i];
3647 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3648 vndrie_info->vndrie.id,
3649 vndrie_info->vndrie.len,
3650 vndrie_info->vndrie.oui[0],
3651 vndrie_info->vndrie.oui[1],
3652 vndrie_info->vndrie.oui[2]);
3654 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3655 vndrie_info->ie_ptr,
3656 vndrie_info->ie_len,
3658 curr_ie_buf += del_add_ie_buf_len;
3659 total_ie_buf_len += del_add_ie_buf_len;
3664 /* Add if there is any extra IE */
3665 if (mgmt_ie_buf && parsed_ie_buf_len) {
3668 remained_buf_len = mgmt_ie_buf_len;
3670 /* make a command to add new ie */
3671 for (i = 0; i < new_vndr_ies.count; i++) {
3672 vndrie_info = &new_vndr_ies.ie_info[i];
3674 /* verify remained buf size before copy data */
3675 if (remained_buf_len < (vndrie_info->vndrie.len +
3676 VNDR_IE_VSIE_OFFSET)) {
3677 brcmf_err("no space in mgmt_ie_buf: len left %d",
3681 remained_buf_len -= (vndrie_info->ie_len +
3682 VNDR_IE_VSIE_OFFSET);
3684 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3685 vndrie_info->vndrie.id,
3686 vndrie_info->vndrie.len,
3687 vndrie_info->vndrie.oui[0],
3688 vndrie_info->vndrie.oui[1],
3689 vndrie_info->vndrie.oui[2]);
3691 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3692 vndrie_info->ie_ptr,
3693 vndrie_info->ie_len,
3696 /* save the parsed IE in wl struct */
3697 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3698 vndrie_info->ie_len);
3699 *mgmt_ie_len += vndrie_info->ie_len;
3701 curr_ie_buf += del_add_ie_buf_len;
3702 total_ie_buf_len += del_add_ie_buf_len;
3705 if (total_ie_buf_len) {
3706 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3709 brcmf_err("vndr ie set error : %d\n", err);
3713 kfree(iovar_ie_buf);
3717 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3720 BRCMF_VNDR_IE_PRBREQ_FLAG,
3721 BRCMF_VNDR_IE_PRBRSP_FLAG,
3722 BRCMF_VNDR_IE_BEACON_FLAG
3726 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3727 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3729 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3734 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3735 struct cfg80211_beacon_data *beacon)
3739 /* Set Beacon IEs to FW */
3740 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3741 beacon->tail, beacon->tail_len);
3743 brcmf_err("Set Beacon IE Failed\n");
3746 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3748 /* Set Probe Response IEs to FW */
3749 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3750 beacon->proberesp_ies,
3751 beacon->proberesp_ies_len);
3753 brcmf_err("Set Probe Resp IE Failed\n");
3755 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3761 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3762 struct cfg80211_ap_settings *settings)
3765 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3766 struct brcmf_if *ifp = netdev_priv(ndev);
3767 const struct brcmf_tlv *ssid_ie;
3768 struct brcmf_ssid_le ssid_le;
3770 const struct brcmf_tlv *rsn_ie;
3771 const struct brcmf_vs_tlv *wpa_ie;
3772 struct brcmf_join_params join_params;
3773 enum nl80211_iftype dev_role;
3774 struct brcmf_fil_bss_enable_le bss_enable;
3777 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3778 settings->chandef.chan->hw_value,
3779 settings->chandef.center_freq1, settings->chandef.width,
3780 settings->beacon_interval, settings->dtim_period);
3781 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3782 settings->ssid, settings->ssid_len, settings->auth_type,
3783 settings->inactivity_timeout);
3785 dev_role = ifp->vif->wdev.iftype;
3787 memset(&ssid_le, 0, sizeof(ssid_le));
3788 if (settings->ssid == NULL || settings->ssid_len == 0) {
3789 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3790 ssid_ie = brcmf_parse_tlvs(
3791 (u8 *)&settings->beacon.head[ie_offset],
3792 settings->beacon.head_len - ie_offset,
3797 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3798 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3799 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3801 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3802 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3805 brcmf_set_mpc(ifp, 0);
3806 brcmf_configure_arp_offload(ifp, false);
3808 /* find the RSN_IE */
3809 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3810 settings->beacon.tail_len, WLAN_EID_RSN);
3812 /* find the WPA_IE */
3813 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3814 settings->beacon.tail_len);
3816 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3817 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3818 if (wpa_ie != NULL) {
3820 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3825 err = brcmf_configure_wpaie(ndev,
3826 (struct brcmf_vs_tlv *)rsn_ie, true);
3831 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3832 brcmf_configure_opensecurity(ifp);
3835 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3837 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
3838 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3840 brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
3844 if (settings->beacon_interval) {
3845 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3846 settings->beacon_interval);
3848 brcmf_err("Beacon Interval Set Error, %d\n", err);
3852 if (settings->dtim_period) {
3853 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3854 settings->dtim_period);
3856 brcmf_err("DTIM Interval Set Error, %d\n", err);
3861 if (dev_role == NL80211_IFTYPE_AP) {
3862 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3864 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3867 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3870 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3872 brcmf_err("SET INFRA error %d\n", err);
3875 if (dev_role == NL80211_IFTYPE_AP) {
3876 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3878 brcmf_err("setting AP mode failed %d\n", err);
3881 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3883 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3887 memset(&join_params, 0, sizeof(join_params));
3888 /* join parameters starts with ssid */
3889 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3891 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3892 &join_params, sizeof(join_params));
3894 brcmf_err("SET SSID error (%d)\n", err);
3897 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3899 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3902 brcmf_err("setting ssid failed %d\n", err);
3905 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3906 bss_enable.enable = cpu_to_le32(1);
3907 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3908 sizeof(bss_enable));
3910 brcmf_err("bss_enable config failed %d\n", err);
3914 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3916 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3917 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3921 brcmf_set_mpc(ifp, 1);
3922 brcmf_configure_arp_offload(ifp, true);
3927 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3929 struct brcmf_if *ifp = netdev_priv(ndev);
3931 struct brcmf_fil_bss_enable_le bss_enable;
3932 struct brcmf_join_params join_params;
3934 brcmf_dbg(TRACE, "Enter\n");
3936 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3937 /* Due to most likely deauths outstanding we sleep */
3938 /* first to make sure they get processed by fw. */
3941 memset(&join_params, 0, sizeof(join_params));
3942 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3943 &join_params, sizeof(join_params));
3945 brcmf_err("SET SSID error (%d)\n", err);
3946 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3948 brcmf_err("BRCMF_C_UP error %d\n", err);
3949 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3951 brcmf_err("setting AP mode failed %d\n", err);
3952 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3954 brcmf_err("setting INFRA mode failed %d\n", err);
3956 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3957 bss_enable.enable = cpu_to_le32(0);
3958 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3959 sizeof(bss_enable));
3961 brcmf_err("bss_enable config failed %d\n", err);
3963 brcmf_set_mpc(ifp, 1);
3964 brcmf_configure_arp_offload(ifp, true);
3965 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3966 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3972 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3973 struct cfg80211_beacon_data *info)
3975 struct brcmf_if *ifp = netdev_priv(ndev);
3978 brcmf_dbg(TRACE, "Enter\n");
3980 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3986 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3989 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3990 struct brcmf_scb_val_le scbval;
3991 struct brcmf_if *ifp = netdev_priv(ndev);
3997 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3999 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4000 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4001 if (!check_vif_up(ifp->vif))
4004 memcpy(&scbval.ea, mac, ETH_ALEN);
4005 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4006 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4007 &scbval, sizeof(scbval));
4009 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4011 brcmf_dbg(TRACE, "Exit\n");
4017 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4018 struct wireless_dev *wdev,
4019 u16 frame_type, bool reg)
4021 struct brcmf_cfg80211_vif *vif;
4024 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4026 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4027 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4029 vif->mgmt_rx_reg |= BIT(mgmt_type);
4031 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4036 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4037 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4039 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4040 struct ieee80211_channel *chan = params->chan;
4041 const u8 *buf = params->buf;
4042 size_t len = params->len;
4043 const struct ieee80211_mgmt *mgmt;
4044 struct brcmf_cfg80211_vif *vif;
4048 struct brcmf_fil_action_frame_le *action_frame;
4049 struct brcmf_fil_af_params_le *af_params;
4054 brcmf_dbg(TRACE, "Enter\n");
4058 mgmt = (const struct ieee80211_mgmt *)buf;
4060 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4061 brcmf_err("Driver only allows MGMT packet type\n");
4065 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4067 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4068 /* Right now the only reason to get a probe response */
4069 /* is for p2p listen response or for p2p GO from */
4070 /* wpa_supplicant. Unfortunately the probe is send */
4071 /* on primary ndev, while dongle wants it on the p2p */
4072 /* vif. Since this is only reason for a probe */
4073 /* response to be sent, the vif is taken from cfg. */
4074 /* If ever desired to send proberesp for non p2p */
4075 /* response then data should be checked for */
4076 /* "DIRECT-". Note in future supplicant will take */
4077 /* dedicated p2p wdev to do this and then this 'hack'*/
4078 /* is not needed anymore. */
4079 ie_offset = DOT11_MGMT_HDR_LEN +
4080 DOT11_BCN_PRB_FIXED_LEN;
4081 ie_len = len - ie_offset;
4082 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4083 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4084 err = brcmf_vif_set_mgmt_ie(vif,
4085 BRCMF_VNDR_IE_PRBRSP_FLAG,
4088 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4090 } else if (ieee80211_is_action(mgmt->frame_control)) {
4091 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4092 if (af_params == NULL) {
4093 brcmf_err("unable to allocate frame\n");
4097 action_frame = &af_params->action_frame;
4098 /* Add the packet Id */
4099 action_frame->packet_id = cpu_to_le32(*cookie);
4101 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4102 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4103 /* Add the length exepted for 802.11 header */
4104 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4105 /* Add the channel. Use the one specified as parameter if any or
4106 * the current one (got from the firmware) otherwise
4109 freq = chan->center_freq;
4111 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4113 chan_nr = ieee80211_frequency_to_channel(freq);
4114 af_params->channel = cpu_to_le32(chan_nr);
4116 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4117 le16_to_cpu(action_frame->len));
4119 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4120 *cookie, le16_to_cpu(action_frame->len), freq);
4122 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4125 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4129 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4130 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4139 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4140 struct wireless_dev *wdev,
4143 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4144 struct brcmf_cfg80211_vif *vif;
4147 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4149 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4151 brcmf_err("No p2p device available for probe response\n");
4155 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4160 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4161 struct wireless_dev *wdev,
4162 enum nl80211_crit_proto_id proto,
4165 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4166 struct brcmf_cfg80211_vif *vif;
4168 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4170 /* only DHCP support for now */
4171 if (proto != NL80211_CRIT_PROTO_DHCP)
4174 /* suppress and abort scanning */
4175 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4176 brcmf_abort_scanning(cfg);
4178 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4181 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4182 struct wireless_dev *wdev)
4184 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4185 struct brcmf_cfg80211_vif *vif;
4187 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4189 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4190 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4193 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4198 case NL80211_TDLS_DISCOVERY_REQ:
4199 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4201 case NL80211_TDLS_SETUP:
4202 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4204 case NL80211_TDLS_TEARDOWN:
4205 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4208 brcmf_err("unsupported operation: %d\n", oper);
4214 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4215 struct net_device *ndev, const u8 *peer,
4216 enum nl80211_tdls_operation oper)
4218 struct brcmf_if *ifp;
4219 struct brcmf_tdls_iovar_le info;
4222 ret = brcmf_convert_nl80211_tdls_oper(oper);
4226 ifp = netdev_priv(ndev);
4227 memset(&info, 0, sizeof(info));
4228 info.mode = (u8)ret;
4230 memcpy(info.ea, peer, ETH_ALEN);
4232 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4233 &info, sizeof(info));
4235 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4240 static struct cfg80211_ops wl_cfg80211_ops = {
4241 .add_virtual_intf = brcmf_cfg80211_add_iface,
4242 .del_virtual_intf = brcmf_cfg80211_del_iface,
4243 .change_virtual_intf = brcmf_cfg80211_change_iface,
4244 .scan = brcmf_cfg80211_scan,
4245 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4246 .join_ibss = brcmf_cfg80211_join_ibss,
4247 .leave_ibss = brcmf_cfg80211_leave_ibss,
4248 .get_station = brcmf_cfg80211_get_station,
4249 .set_tx_power = brcmf_cfg80211_set_tx_power,
4250 .get_tx_power = brcmf_cfg80211_get_tx_power,
4251 .add_key = brcmf_cfg80211_add_key,
4252 .del_key = brcmf_cfg80211_del_key,
4253 .get_key = brcmf_cfg80211_get_key,
4254 .set_default_key = brcmf_cfg80211_config_default_key,
4255 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4256 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4257 .connect = brcmf_cfg80211_connect,
4258 .disconnect = brcmf_cfg80211_disconnect,
4259 .suspend = brcmf_cfg80211_suspend,
4260 .resume = brcmf_cfg80211_resume,
4261 .set_pmksa = brcmf_cfg80211_set_pmksa,
4262 .del_pmksa = brcmf_cfg80211_del_pmksa,
4263 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4264 .start_ap = brcmf_cfg80211_start_ap,
4265 .stop_ap = brcmf_cfg80211_stop_ap,
4266 .change_beacon = brcmf_cfg80211_change_beacon,
4267 .del_station = brcmf_cfg80211_del_station,
4268 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4269 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4270 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4271 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4272 .remain_on_channel = brcmf_p2p_remain_on_channel,
4273 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4274 .start_p2p_device = brcmf_p2p_start_device,
4275 .stop_p2p_device = brcmf_p2p_stop_device,
4276 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4277 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4278 .tdls_oper = brcmf_cfg80211_tdls_oper,
4281 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4283 /* scheduled scan settings */
4284 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4285 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4286 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4287 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4290 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4293 .types = BIT(NL80211_IFTYPE_STATION) |
4294 BIT(NL80211_IFTYPE_ADHOC) |
4295 BIT(NL80211_IFTYPE_AP)
4299 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4300 BIT(NL80211_IFTYPE_P2P_GO)
4304 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4307 static struct ieee80211_iface_combination brcmf_iface_combos[] = {
4309 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4310 .num_different_channels = 1,
4311 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4312 .limits = brcmf_iface_limits
4316 static const struct ieee80211_txrx_stypes
4317 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4318 [NL80211_IFTYPE_STATION] = {
4320 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4321 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4323 [NL80211_IFTYPE_P2P_CLIENT] = {
4325 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4326 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4328 [NL80211_IFTYPE_P2P_GO] = {
4330 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4331 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4332 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4333 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4334 BIT(IEEE80211_STYPE_AUTH >> 4) |
4335 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4336 BIT(IEEE80211_STYPE_ACTION >> 4)
4338 [NL80211_IFTYPE_P2P_DEVICE] = {
4340 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4341 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4346 struct wiphy *brcmf_setup_wiphy(struct brcmf_if *ifp, struct device *phydev)
4348 struct wiphy *wiphy;
4351 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4353 brcmf_err("Could not allocate wiphy device\n");
4354 return ERR_PTR(-ENOMEM);
4356 set_wiphy_dev(wiphy, phydev);
4357 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4358 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4359 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4360 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4361 BIT(NL80211_IFTYPE_ADHOC) |
4362 BIT(NL80211_IFTYPE_AP) |
4363 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4364 BIT(NL80211_IFTYPE_P2P_GO) |
4365 BIT(NL80211_IFTYPE_P2P_DEVICE);
4366 /* need VSDB firmware feature for concurrent channels */
4367 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
4368 brcmf_iface_combos[0].num_different_channels = 2;
4369 wiphy->iface_combinations = brcmf_iface_combos;
4370 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4371 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4372 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4373 wiphy->cipher_suites = __wl_cipher_suites;
4374 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4375 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4376 WIPHY_FLAG_OFFCHAN_TX |
4377 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4378 WIPHY_FLAG_SUPPORTS_TDLS;
4380 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4381 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4382 wiphy->max_remain_on_channel_duration = 5000;
4383 brcmf_wiphy_pno_params(wiphy);
4384 brcmf_dbg(INFO, "Registering custom regulatory\n");
4385 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4386 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4388 /* vendor commands/events support */
4389 wiphy->vendor_commands = brcmf_vendor_cmds;
4390 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
4392 err = wiphy_register(wiphy);
4394 brcmf_err("Could not register wiphy device (%d)\n", err);
4396 return ERR_PTR(err);
4401 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4402 enum nl80211_iftype type,
4405 struct brcmf_cfg80211_vif *vif;
4407 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4409 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4411 return ERR_PTR(-ENOMEM);
4413 vif->wdev.wiphy = cfg->wiphy;
4414 vif->wdev.iftype = type;
4416 vif->pm_block = pm_block;
4419 brcmf_init_prof(&vif->profile);
4421 list_add_tail(&vif->list, &cfg->vif_list);
4425 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4427 list_del(&vif->list);
4431 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4433 struct brcmf_cfg80211_vif *vif;
4434 struct brcmf_if *ifp;
4436 ifp = netdev_priv(ndev);
4439 brcmf_free_vif(vif);
4443 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4445 u32 event = e->event_code;
4446 u32 status = e->status;
4448 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4449 brcmf_dbg(CONN, "Processing set ssid\n");
4456 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4458 u32 event = e->event_code;
4459 u16 flags = e->flags;
4461 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4462 (event == BRCMF_E_DISASSOC_IND) ||
4463 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4464 brcmf_dbg(CONN, "Processing link down\n");
4470 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4471 const struct brcmf_event_msg *e)
4473 u32 event = e->event_code;
4474 u32 status = e->status;
4476 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4477 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4478 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4482 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4483 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4490 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4492 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4494 kfree(conn_info->req_ie);
4495 conn_info->req_ie = NULL;
4496 conn_info->req_ie_len = 0;
4497 kfree(conn_info->resp_ie);
4498 conn_info->resp_ie = NULL;
4499 conn_info->resp_ie_len = 0;
4502 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4503 struct brcmf_if *ifp)
4505 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4506 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4511 brcmf_clear_assoc_ies(cfg);
4513 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4514 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4516 brcmf_err("could not get assoc info (%d)\n", err);
4520 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4521 req_len = le32_to_cpu(assoc_info->req_len);
4522 resp_len = le32_to_cpu(assoc_info->resp_len);
4524 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4528 brcmf_err("could not get assoc req (%d)\n", err);
4531 conn_info->req_ie_len = req_len;
4533 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4536 conn_info->req_ie_len = 0;
4537 conn_info->req_ie = NULL;
4540 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4544 brcmf_err("could not get assoc resp (%d)\n", err);
4547 conn_info->resp_ie_len = resp_len;
4548 conn_info->resp_ie =
4549 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4552 conn_info->resp_ie_len = 0;
4553 conn_info->resp_ie = NULL;
4555 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4556 conn_info->req_ie_len, conn_info->resp_ie_len);
4562 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4563 struct net_device *ndev,
4564 const struct brcmf_event_msg *e)
4566 struct brcmf_if *ifp = netdev_priv(ndev);
4567 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4568 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4569 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4570 struct ieee80211_channel *notify_channel = NULL;
4571 struct ieee80211_supported_band *band;
4572 struct brcmf_bss_info_le *bi;
4573 struct brcmu_chan ch;
4578 brcmf_dbg(TRACE, "Enter\n");
4580 brcmf_get_assoc_ies(cfg, ifp);
4581 memcpy(profile->bssid, e->addr, ETH_ALEN);
4582 brcmf_update_bss_info(cfg, ifp);
4584 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4590 /* data sent to dongle has to be little endian */
4591 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4592 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4593 buf, WL_BSS_INFO_MAX);
4598 bi = (struct brcmf_bss_info_le *)(buf + 4);
4599 ch.chspec = le16_to_cpu(bi->chanspec);
4600 cfg->d11inf.decchspec(&ch);
4602 if (ch.band == BRCMU_CHAN_BAND_2G)
4603 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4605 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4607 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4608 notify_channel = ieee80211_get_channel(wiphy, freq);
4612 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4613 conn_info->req_ie, conn_info->req_ie_len,
4614 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4615 brcmf_dbg(CONN, "Report roaming result\n");
4617 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4618 brcmf_dbg(TRACE, "Exit\n");
4623 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4624 struct net_device *ndev, const struct brcmf_event_msg *e,
4627 struct brcmf_if *ifp = netdev_priv(ndev);
4628 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4629 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4631 brcmf_dbg(TRACE, "Enter\n");
4633 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4634 &ifp->vif->sme_state)) {
4636 brcmf_get_assoc_ies(cfg, ifp);
4637 memcpy(profile->bssid, e->addr, ETH_ALEN);
4638 brcmf_update_bss_info(cfg, ifp);
4639 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4640 &ifp->vif->sme_state);
4642 cfg80211_connect_result(ndev,
4643 (u8 *)profile->bssid,
4645 conn_info->req_ie_len,
4647 conn_info->resp_ie_len,
4648 completed ? WLAN_STATUS_SUCCESS :
4649 WLAN_STATUS_AUTH_TIMEOUT,
4651 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4652 completed ? "succeeded" : "failed");
4654 brcmf_dbg(TRACE, "Exit\n");
4659 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4660 struct net_device *ndev,
4661 const struct brcmf_event_msg *e, void *data)
4663 static int generation;
4664 u32 event = e->event_code;
4665 u32 reason = e->reason;
4666 struct station_info sinfo;
4668 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4669 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4670 ndev != cfg_to_ndev(cfg)) {
4671 brcmf_dbg(CONN, "AP mode link down\n");
4672 complete(&cfg->vif_disabled);
4676 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4677 (reason == BRCMF_E_STATUS_SUCCESS)) {
4678 memset(&sinfo, 0, sizeof(sinfo));
4679 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4681 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4684 sinfo.assoc_req_ies = data;
4685 sinfo.assoc_req_ies_len = e->datalen;
4687 sinfo.generation = generation;
4688 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4689 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4690 (event == BRCMF_E_DEAUTH_IND) ||
4691 (event == BRCMF_E_DEAUTH)) {
4692 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4698 brcmf_notify_connect_status(struct brcmf_if *ifp,
4699 const struct brcmf_event_msg *e, void *data)
4701 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4702 struct net_device *ndev = ifp->ndev;
4703 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4704 struct ieee80211_channel *chan;
4707 if (brcmf_is_apmode(ifp->vif)) {
4708 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4709 } else if (brcmf_is_linkup(e)) {
4710 brcmf_dbg(CONN, "Linkup\n");
4711 if (brcmf_is_ibssmode(ifp->vif)) {
4712 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4713 memcpy(profile->bssid, e->addr, ETH_ALEN);
4714 wl_inform_ibss(cfg, ndev, e->addr);
4715 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4716 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4717 &ifp->vif->sme_state);
4718 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4719 &ifp->vif->sme_state);
4721 brcmf_bss_connect_done(cfg, ndev, e, true);
4722 } else if (brcmf_is_linkdown(e)) {
4723 brcmf_dbg(CONN, "Linkdown\n");
4724 if (!brcmf_is_ibssmode(ifp->vif)) {
4725 brcmf_bss_connect_done(cfg, ndev, e, false);
4727 brcmf_link_down(ifp->vif);
4728 brcmf_init_prof(ndev_to_prof(ndev));
4729 if (ndev != cfg_to_ndev(cfg))
4730 complete(&cfg->vif_disabled);
4731 } else if (brcmf_is_nonetwork(cfg, e)) {
4732 if (brcmf_is_ibssmode(ifp->vif))
4733 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4734 &ifp->vif->sme_state);
4736 brcmf_bss_connect_done(cfg, ndev, e, false);
4743 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4744 const struct brcmf_event_msg *e, void *data)
4746 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4747 u32 event = e->event_code;
4748 u32 status = e->status;
4750 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4751 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4752 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4754 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4761 brcmf_notify_mic_status(struct brcmf_if *ifp,
4762 const struct brcmf_event_msg *e, void *data)
4764 u16 flags = e->flags;
4765 enum nl80211_key_type key_type;
4767 if (flags & BRCMF_EVENT_MSG_GROUP)
4768 key_type = NL80211_KEYTYPE_GROUP;
4770 key_type = NL80211_KEYTYPE_PAIRWISE;
4772 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4778 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4779 const struct brcmf_event_msg *e, void *data)
4781 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4782 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4783 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4784 struct brcmf_cfg80211_vif *vif;
4786 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4787 ifevent->action, ifevent->flags, ifevent->ifidx,
4790 mutex_lock(&event->vif_event_lock);
4791 event->action = ifevent->action;
4794 switch (ifevent->action) {
4795 case BRCMF_E_IF_ADD:
4796 /* waiting process may have timed out */
4797 if (!cfg->vif_event.vif) {
4798 mutex_unlock(&event->vif_event_lock);
4805 vif->wdev.netdev = ifp->ndev;
4806 ifp->ndev->ieee80211_ptr = &vif->wdev;
4807 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4809 mutex_unlock(&event->vif_event_lock);
4810 wake_up(&event->vif_wq);
4813 case BRCMF_E_IF_DEL:
4814 mutex_unlock(&event->vif_event_lock);
4815 /* event may not be upon user request */
4816 if (brcmf_cfg80211_vif_event_armed(cfg))
4817 wake_up(&event->vif_wq);
4820 case BRCMF_E_IF_CHANGE:
4821 mutex_unlock(&event->vif_event_lock);
4822 wake_up(&event->vif_wq);
4826 mutex_unlock(&event->vif_event_lock);
4832 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4834 conf->frag_threshold = (u32)-1;
4835 conf->rts_threshold = (u32)-1;
4836 conf->retry_short = (u32)-1;
4837 conf->retry_long = (u32)-1;
4838 conf->tx_power = -1;
4841 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4843 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4844 brcmf_notify_connect_status);
4845 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4846 brcmf_notify_connect_status);
4847 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4848 brcmf_notify_connect_status);
4849 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4850 brcmf_notify_connect_status);
4851 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4852 brcmf_notify_connect_status);
4853 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4854 brcmf_notify_connect_status);
4855 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4856 brcmf_notify_roaming_status);
4857 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4858 brcmf_notify_mic_status);
4859 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4860 brcmf_notify_connect_status);
4861 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4862 brcmf_notify_sched_scan_results);
4863 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4864 brcmf_notify_vif_event);
4865 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4866 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4867 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4868 brcmf_p2p_notify_listen_complete);
4869 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4870 brcmf_p2p_notify_action_frame_rx);
4871 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4872 brcmf_p2p_notify_action_tx_complete);
4873 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4874 brcmf_p2p_notify_action_tx_complete);
4877 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4881 kfree(cfg->escan_ioctl_buf);
4882 cfg->escan_ioctl_buf = NULL;
4883 kfree(cfg->extra_buf);
4884 cfg->extra_buf = NULL;
4885 kfree(cfg->pmk_list);
4886 cfg->pmk_list = NULL;
4889 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4891 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4893 goto init_priv_mem_out;
4894 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4895 if (!cfg->escan_ioctl_buf)
4896 goto init_priv_mem_out;
4897 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4898 if (!cfg->extra_buf)
4899 goto init_priv_mem_out;
4900 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4902 goto init_priv_mem_out;
4907 brcmf_deinit_priv_mem(cfg);
4912 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4916 cfg->scan_request = NULL;
4917 cfg->pwr_save = true;
4918 cfg->active_scan = true; /* we do active scan per default */
4919 cfg->dongle_up = false; /* dongle is not up yet */
4920 err = brcmf_init_priv_mem(cfg);
4923 brcmf_register_event_handlers(cfg);
4924 mutex_init(&cfg->usr_sync);
4925 brcmf_init_escan(cfg);
4926 brcmf_init_conf(cfg->conf);
4927 init_completion(&cfg->vif_disabled);
4931 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4933 cfg->dongle_up = false; /* dongle down */
4934 brcmf_abort_scanning(cfg);
4935 brcmf_deinit_priv_mem(cfg);
4938 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4940 init_waitqueue_head(&event->vif_wq);
4941 mutex_init(&event->vif_event_lock);
4944 static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4946 struct brcmf_fil_bwcap_le band_bwcap;
4950 /* verify support for bw_cap command */
4952 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
4955 /* only set 2G bandwidth using bw_cap command */
4956 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4957 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
4958 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4959 sizeof(band_bwcap));
4961 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
4962 val = WLC_N_BW_40ALL;
4963 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
4969 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
4972 __le32 roamtrigger[2];
4973 __le32 roam_delta[2];
4976 * Setup timeout if Beacons are lost and roam is
4977 * off to report link down
4979 if (brcmf_roamoff) {
4980 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4982 brcmf_err("bcn_timeout error (%d)\n", err);
4983 goto dongle_rom_out;
4988 * Enable/Disable built-in roaming to allow supplicant
4989 * to take care of roaming
4991 brcmf_dbg(INFO, "Internal Roaming = %s\n",
4992 brcmf_roamoff ? "Off" : "On");
4993 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
4995 brcmf_err("roam_off error (%d)\n", err);
4996 goto dongle_rom_out;
4999 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5000 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5001 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5002 (void *)roamtrigger, sizeof(roamtrigger));
5004 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5005 goto dongle_rom_out;
5008 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5009 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5010 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5011 (void *)roam_delta, sizeof(roam_delta));
5013 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5014 goto dongle_rom_out;
5022 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5023 s32 scan_unassoc_time, s32 scan_passive_time)
5027 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5030 if (err == -EOPNOTSUPP)
5031 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5033 brcmf_err("Scan assoc time error (%d)\n", err);
5034 goto dongle_scantime_out;
5036 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5039 if (err == -EOPNOTSUPP)
5040 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5042 brcmf_err("Scan unassoc time error (%d)\n", err);
5043 goto dongle_scantime_out;
5046 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5049 if (err == -EOPNOTSUPP)
5050 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5052 brcmf_err("Scan passive time error (%d)\n", err);
5053 goto dongle_scantime_out;
5056 dongle_scantime_out:
5061 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5064 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5065 struct ieee80211_channel *band_chan_arr;
5066 struct brcmf_chanspec_list *list;
5067 struct brcmu_chan ch;
5072 enum ieee80211_band band;
5080 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5085 list = (struct brcmf_chanspec_list *)pbuf;
5087 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5090 brcmf_err("get chanspecs error (%d)\n", err);
5094 __wl_band_2ghz.n_channels = 0;
5095 __wl_band_5ghz_a.n_channels = 0;
5097 total = le32_to_cpu(list->count);
5098 for (i = 0; i < total; i++) {
5099 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5100 cfg->d11inf.decchspec(&ch);
5102 if (ch.band == BRCMU_CHAN_BAND_2G) {
5103 band_chan_arr = __wl_2ghz_channels;
5104 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5105 n_cnt = &__wl_band_2ghz.n_channels;
5106 band = IEEE80211_BAND_2GHZ;
5107 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5108 band_chan_arr = __wl_5ghz_a_channels;
5109 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5110 n_cnt = &__wl_band_5ghz_a.n_channels;
5111 band = IEEE80211_BAND_5GHZ;
5113 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5116 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5117 ch.bw == BRCMU_CHAN_BW_40)
5119 if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
5120 ch.bw == BRCMU_CHAN_BW_80)
5123 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5124 if (band_chan_arr[j].hw_value == ch.chnum) {
5133 if (index < array_size) {
5134 band_chan_arr[index].center_freq =
5135 ieee80211_channel_to_frequency(ch.chnum, band);
5136 band_chan_arr[index].hw_value = ch.chnum;
5138 /* assuming the chanspecs order is HT20,
5139 * HT40 upper, HT40 lower, and VHT80.
5141 if (ch.bw == BRCMU_CHAN_BW_80) {
5142 band_chan_arr[index].flags &=
5143 ~IEEE80211_CHAN_NO_80MHZ;
5144 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5145 ht40_flag = band_chan_arr[index].flags &
5146 IEEE80211_CHAN_NO_HT40;
5147 if (ch.sb == BRCMU_CHAN_SB_U) {
5148 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5149 band_chan_arr[index].flags &=
5150 ~IEEE80211_CHAN_NO_HT40;
5151 band_chan_arr[index].flags |=
5152 IEEE80211_CHAN_NO_HT40PLUS;
5154 /* It should be one of
5155 * IEEE80211_CHAN_NO_HT40 or
5156 * IEEE80211_CHAN_NO_HT40PLUS
5158 band_chan_arr[index].flags &=
5159 ~IEEE80211_CHAN_NO_HT40;
5160 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5161 band_chan_arr[index].flags |=
5162 IEEE80211_CHAN_NO_HT40MINUS;
5165 /* disable other bandwidths for now as mentioned
5166 * order assure they are enabled for subsequent
5169 band_chan_arr[index].flags =
5170 IEEE80211_CHAN_NO_HT40 |
5171 IEEE80211_CHAN_NO_80MHZ;
5172 ch.bw = BRCMU_CHAN_BW_20;
5173 cfg->d11inf.encchspec(&ch);
5174 channel = ch.chspec;
5175 err = brcmf_fil_bsscfg_int_get(ifp,
5179 if (channel & WL_CHAN_RADAR)
5180 band_chan_arr[index].flags |=
5181 (IEEE80211_CHAN_RADAR |
5182 IEEE80211_CHAN_NO_IR);
5183 if (channel & WL_CHAN_PASSIVE)
5184 band_chan_arr[index].flags |=
5185 IEEE80211_CHAN_NO_IR;
5197 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5199 u32 band, mimo_bwcap;
5203 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5205 bw_cap[IEEE80211_BAND_2GHZ] = band;
5207 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5209 bw_cap[IEEE80211_BAND_5GHZ] = band;
5215 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5217 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5219 /* assume 20MHz if firmware does not give a clue */
5220 mimo_bwcap = WLC_N_BW_20ALL;
5222 switch (mimo_bwcap) {
5223 case WLC_N_BW_40ALL:
5224 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5226 case WLC_N_BW_20IN2G_40IN5G:
5227 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5229 case WLC_N_BW_20ALL:
5230 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5231 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5234 brcmf_err("invalid mimo_bw_cap value\n");
5238 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5239 u32 bw_cap[2], u32 nchain)
5241 band->ht_cap.ht_supported = true;
5242 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5243 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5244 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5246 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5247 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5248 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5249 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5250 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5251 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5254 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5259 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5260 mcs_map = (mcs_map << 2) | supp;
5262 return cpu_to_le16(mcs_map);
5265 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5266 u32 bw_cap[2], u32 nchain)
5270 /* not allowed in 2.4G band */
5271 if (band->band == IEEE80211_BAND_2GHZ)
5274 band->vht_cap.vht_supported = true;
5275 /* 80MHz is mandatory */
5276 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5277 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5278 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5279 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5281 /* all support 256-QAM */
5282 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5283 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5284 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5287 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5289 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5290 struct wiphy *wiphy;
5295 u32 bw_cap[2] = { 0, 0 };
5302 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5303 struct ieee80211_supported_band *band;
5305 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5306 &phy_list, sizeof(phy_list));
5308 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5312 phy = ((char *)&phy_list)[0];
5313 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5316 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5317 &band_list, sizeof(band_list));
5319 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5322 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5323 band_list[0], band_list[1], band_list[2]);
5325 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5326 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5328 brcmf_err("nmode error (%d)\n", err);
5330 brcmf_get_bwcap(ifp, bw_cap);
5332 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5333 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5334 bw_cap[IEEE80211_BAND_5GHZ]);
5336 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5338 brcmf_err("rxchain error (%d)\n", err);
5341 for (nchain = 0; rxchain; nchain++)
5342 rxchain = rxchain & (rxchain - 1);
5344 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5346 err = brcmf_construct_reginfo(cfg, bw_cap);
5348 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5352 nband = band_list[0];
5354 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5356 if ((band_list[i] == WLC_BAND_5G) &&
5357 (__wl_band_5ghz_a.n_channels > 0))
5358 band = &__wl_band_5ghz_a;
5359 else if ((band_list[i] == WLC_BAND_2G) &&
5360 (__wl_band_2ghz.n_channels > 0))
5361 band = &__wl_band_2ghz;
5366 brcmf_update_ht_cap(band, bw_cap, nchain);
5368 brcmf_update_vht_cap(band, bw_cap, nchain);
5369 bands[band->band] = band;
5372 wiphy = cfg_to_wiphy(cfg);
5373 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5374 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5375 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5381 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5383 return brcmf_update_wiphybands(cfg);
5386 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5388 struct net_device *ndev;
5389 struct wireless_dev *wdev;
5390 struct brcmf_if *ifp;
5397 ndev = cfg_to_ndev(cfg);
5398 wdev = ndev->ieee80211_ptr;
5399 ifp = netdev_priv(ndev);
5401 /* make sure RF is ready for work */
5402 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5404 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5405 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5407 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5408 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5410 goto default_conf_out;
5411 brcmf_dbg(INFO, "power save set to %s\n",
5412 (power_mode ? "enabled" : "disabled"));
5414 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5416 goto default_conf_out;
5417 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5420 goto default_conf_out;
5421 err = brcmf_dongle_probecap(cfg);
5423 goto default_conf_out;
5425 brcmf_configure_arp_offload(ifp, true);
5427 cfg->dongle_up = true;
5434 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5436 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5438 return brcmf_config_dongle(ifp->drvr->config);
5441 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5443 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5446 * While going down, if associated with AP disassociate
5447 * from AP to save power
5449 if (check_vif_up(ifp->vif)) {
5450 brcmf_link_down(ifp->vif);
5452 /* Make sure WPA_Supplicant receives all the event
5453 generated due to DISASSOC call to the fw to keep
5454 the state fw and WPA_Supplicant state consistent
5459 brcmf_abort_scanning(cfg);
5460 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5465 s32 brcmf_cfg80211_up(struct net_device *ndev)
5467 struct brcmf_if *ifp = netdev_priv(ndev);
5468 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5471 mutex_lock(&cfg->usr_sync);
5472 err = __brcmf_cfg80211_up(ifp);
5473 mutex_unlock(&cfg->usr_sync);
5478 s32 brcmf_cfg80211_down(struct net_device *ndev)
5480 struct brcmf_if *ifp = netdev_priv(ndev);
5481 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5484 mutex_lock(&cfg->usr_sync);
5485 err = __brcmf_cfg80211_down(ifp);
5486 mutex_unlock(&cfg->usr_sync);
5491 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5493 struct wireless_dev *wdev = &ifp->vif->wdev;
5495 return wdev->iftype;
5498 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg, unsigned long state)
5500 struct brcmf_cfg80211_vif *vif;
5502 list_for_each_entry(vif, &cfg->vif_list, list) {
5503 if (test_bit(state, &vif->sme_state))
5509 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5514 mutex_lock(&event->vif_event_lock);
5515 evt_action = event->action;
5516 mutex_unlock(&event->vif_event_lock);
5517 return evt_action == action;
5520 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5521 struct brcmf_cfg80211_vif *vif)
5523 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5525 mutex_lock(&event->vif_event_lock);
5528 mutex_unlock(&event->vif_event_lock);
5531 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5533 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5536 mutex_lock(&event->vif_event_lock);
5537 armed = event->vif != NULL;
5538 mutex_unlock(&event->vif_event_lock);
5542 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5543 u8 action, ulong timeout)
5545 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5547 return wait_event_timeout(event->vif_wq,
5548 vif_event_equals(event, action), timeout);
5551 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
5552 struct device *busdev)
5554 struct net_device *ndev = drvr->iflist[0]->ndev;
5555 struct brcmf_cfg80211_info *cfg;
5556 struct wiphy *wiphy;
5557 struct brcmf_cfg80211_vif *vif;
5558 struct brcmf_if *ifp;
5563 brcmf_err("ndev is invalid\n");
5567 ifp = netdev_priv(ndev);
5568 wiphy = brcmf_setup_wiphy(ifp, busdev);
5572 cfg = wiphy_priv(wiphy);
5575 init_vif_event(&cfg->vif_event);
5576 INIT_LIST_HEAD(&cfg->vif_list);
5578 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
5585 vif->wdev.netdev = ndev;
5586 ndev->ieee80211_ptr = &vif->wdev;
5587 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5589 err = wl_init_priv(cfg);
5591 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5592 goto cfg80211_attach_out;
5596 err = brcmf_p2p_attach(cfg);
5598 brcmf_err("P2P initilisation failed (%d)\n", err);
5599 goto cfg80211_p2p_attach_out;
5601 err = brcmf_btcoex_attach(cfg);
5603 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5604 brcmf_p2p_detach(&cfg->p2p);
5605 goto cfg80211_p2p_attach_out;
5608 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5609 * setup 40MHz in 2GHz band and enable OBSS scanning.
5611 if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
5612 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
5613 err = brcmf_enable_bw40_2g(ifp);
5615 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5616 BRCMF_OBSS_COEX_AUTO);
5618 /* clear for now and rely on update later */
5619 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.ht_supported = false;
5620 wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap = 0;
5622 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5624 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5625 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5628 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
5631 brcmf_err("Failed to get D11 version (%d)\n", err);
5632 goto cfg80211_p2p_attach_out;
5634 cfg->d11inf.io_type = (u8)io_type;
5635 brcmu_d11_attach(&cfg->d11inf);
5639 cfg80211_p2p_attach_out:
5640 wl_deinit_priv(cfg);
5642 cfg80211_attach_out:
5643 brcmf_free_vif(vif);
5647 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5652 WARN_ON(!list_empty(&cfg->vif_list));
5653 wiphy_unregister(cfg->wiphy);
5654 brcmf_btcoex_detach(cfg);
5655 wl_deinit_priv(cfg);
5656 wiphy_free(cfg->wiphy);