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 <net/cfg80211.h>
23 #include <net/netlink.h>
25 #include <brcmu_utils.h>
27 #include <brcmu_wifi.h>
30 #include "tracepoint.h"
31 #include "fwil_types.h"
34 #include "wl_cfg80211.h"
37 #define BRCMF_SCAN_IE_LEN_MAX 2048
38 #define BRCMF_PNO_VERSION 2
39 #define BRCMF_PNO_TIME 30
40 #define BRCMF_PNO_REPEAT 4
41 #define BRCMF_PNO_FREQ_EXPO_MAX 3
42 #define BRCMF_PNO_MAX_PFN_COUNT 16
43 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
44 #define BRCMF_PNO_HIDDEN_BIT 2
45 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
46 #define BRCMF_PNO_SCAN_COMPLETE 1
47 #define BRCMF_PNO_SCAN_INCOMPLETE 0
49 #define BRCMF_IFACE_MAX_CNT 3
51 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
52 #define WPA_OUI_TYPE 1
53 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
54 #define WME_OUI_TYPE 2
55 #define WPS_OUI_TYPE 4
57 #define VS_IE_FIXED_HDR_LEN 6
58 #define WPA_IE_VERSION_LEN 2
59 #define WPA_IE_MIN_OUI_LEN 4
60 #define WPA_IE_SUITE_COUNT_LEN 2
62 #define WPA_CIPHER_NONE 0 /* None */
63 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
64 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
65 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
66 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
68 #define RSN_AKM_NONE 0 /* None (IBSS) */
69 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
70 #define RSN_AKM_PSK 2 /* Pre-shared Key */
71 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
72 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
74 #define VNDR_IE_CMD_LEN 4 /* length of the set command
75 * string :"add", "del" (+ NUL)
77 #define VNDR_IE_COUNT_OFFSET 4
78 #define VNDR_IE_PKTFLAG_OFFSET 8
79 #define VNDR_IE_VSIE_OFFSET 12
80 #define VNDR_IE_HDR_SIZE 12
81 #define VNDR_IE_PARSE_LIMIT 5
83 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
86 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
87 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
88 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
90 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
91 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
93 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
95 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
96 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
103 #define CHAN2G(_channel, _freq, _flags) { \
104 .band = IEEE80211_BAND_2GHZ, \
105 .center_freq = (_freq), \
106 .hw_value = (_channel), \
108 .max_antenna_gain = 0, \
112 #define CHAN5G(_channel, _flags) { \
113 .band = IEEE80211_BAND_5GHZ, \
114 .center_freq = 5000 + (5 * (_channel)), \
115 .hw_value = (_channel), \
117 .max_antenna_gain = 0, \
121 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
122 #define RATETAB_ENT(_rateid, _flags) \
124 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
125 .hw_value = (_rateid), \
129 static struct ieee80211_rate __wl_rates[] = {
130 RATETAB_ENT(BRCM_RATE_1M, 0),
131 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
134 RATETAB_ENT(BRCM_RATE_6M, 0),
135 RATETAB_ENT(BRCM_RATE_9M, 0),
136 RATETAB_ENT(BRCM_RATE_12M, 0),
137 RATETAB_ENT(BRCM_RATE_18M, 0),
138 RATETAB_ENT(BRCM_RATE_24M, 0),
139 RATETAB_ENT(BRCM_RATE_36M, 0),
140 RATETAB_ENT(BRCM_RATE_48M, 0),
141 RATETAB_ENT(BRCM_RATE_54M, 0),
144 #define wl_a_rates (__wl_rates + 4)
145 #define wl_a_rates_size 8
146 #define wl_g_rates (__wl_rates + 0)
147 #define wl_g_rates_size 12
149 static struct ieee80211_channel __wl_2ghz_channels[] = {
166 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
167 CHAN5G(34, 0), CHAN5G(36, 0),
168 CHAN5G(38, 0), CHAN5G(40, 0),
169 CHAN5G(42, 0), CHAN5G(44, 0),
170 CHAN5G(46, 0), CHAN5G(48, 0),
171 CHAN5G(52, 0), CHAN5G(56, 0),
172 CHAN5G(60, 0), CHAN5G(64, 0),
173 CHAN5G(100, 0), CHAN5G(104, 0),
174 CHAN5G(108, 0), CHAN5G(112, 0),
175 CHAN5G(116, 0), CHAN5G(120, 0),
176 CHAN5G(124, 0), CHAN5G(128, 0),
177 CHAN5G(132, 0), CHAN5G(136, 0),
178 CHAN5G(140, 0), CHAN5G(149, 0),
179 CHAN5G(153, 0), CHAN5G(157, 0),
180 CHAN5G(161, 0), CHAN5G(165, 0),
181 CHAN5G(184, 0), CHAN5G(188, 0),
182 CHAN5G(192, 0), CHAN5G(196, 0),
183 CHAN5G(200, 0), CHAN5G(204, 0),
184 CHAN5G(208, 0), CHAN5G(212, 0),
188 static struct ieee80211_supported_band __wl_band_2ghz = {
189 .band = IEEE80211_BAND_2GHZ,
190 .channels = __wl_2ghz_channels,
191 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
192 .bitrates = wl_g_rates,
193 .n_bitrates = wl_g_rates_size,
194 .ht_cap = {IEEE80211_HT_CAP_SUP_WIDTH_20_40, true},
197 static struct ieee80211_supported_band __wl_band_5ghz_a = {
198 .band = IEEE80211_BAND_5GHZ,
199 .channels = __wl_5ghz_a_channels,
200 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
201 .bitrates = wl_a_rates,
202 .n_bitrates = wl_a_rates_size,
205 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
206 * By default world regulatory domain defined in reg.c puts the flags
207 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
208 * With respect to these flags, wpa_supplicant doesn't * start p2p
209 * operations on 5GHz channels. All the changes in world regulatory
210 * domain are to be done here.
212 static const struct ieee80211_regdomain brcmf_regdom = {
216 /* IEEE 802.11b/g, channels 1..11 */
217 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
219 /* IEEE 802.11 channel 14 - Only JP enables
220 * this and for 802.11b only
222 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
223 /* IEEE 802.11a, channel 36..64 */
224 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
225 /* IEEE 802.11a, channel 100..165 */
226 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
229 static const u32 __wl_cipher_suites[] = {
230 WLAN_CIPHER_SUITE_WEP40,
231 WLAN_CIPHER_SUITE_WEP104,
232 WLAN_CIPHER_SUITE_TKIP,
233 WLAN_CIPHER_SUITE_CCMP,
234 WLAN_CIPHER_SUITE_AES_CMAC,
237 /* Vendor specific ie. id = 221, oui and type defines exact ie */
238 struct brcmf_vs_tlv {
245 struct parsed_vndr_ie_info {
247 u32 ie_len; /* total length including id & length field */
248 struct brcmf_vs_tlv vndrie;
251 struct parsed_vndr_ies {
253 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
256 static int brcmf_roamoff;
257 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
258 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
260 /* Quarter dBm units to mW
261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
262 * Table is offset so the last entry is largest mW value that fits in
266 #define QDBM_OFFSET 153 /* Offset for first entry */
267 #define QDBM_TABLE_LEN 40 /* Table size */
269 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
270 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
272 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
274 /* Largest mW value that will round down to the last table entry,
275 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
276 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
277 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
279 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
281 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
282 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
283 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
284 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
285 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
286 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
287 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
290 static u16 brcmf_qdbm_to_mw(u8 qdbm)
293 int idx = qdbm - QDBM_OFFSET;
295 if (idx >= QDBM_TABLE_LEN)
296 /* clamp to max u16 mW value */
299 /* scale the qdBm index up to the range of the table 0-40
300 * where an offset of 40 qdBm equals a factor of 10 mW.
307 /* return the mW value scaled down to the correct factor of 10,
308 * adding in factor/2 to get proper rounding.
310 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
313 static u8 brcmf_mw_to_qdbm(u16 mw)
320 /* handle boundary case */
324 offset = QDBM_OFFSET;
326 /* move mw into the range of the table */
327 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
332 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
333 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
334 nqdBm_to_mW_map[qdbm]) / 2;
335 if (mw_uint < boundary)
344 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
345 struct cfg80211_chan_def *ch)
347 struct brcmu_chan ch_inf;
350 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
351 ch->chan->center_freq, ch->center_freq1, ch->width);
352 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
353 primary_offset = ch->center_freq1 - ch->chan->center_freq;
355 case NL80211_CHAN_WIDTH_20:
356 ch_inf.bw = BRCMU_CHAN_BW_20;
357 WARN_ON(primary_offset != 0);
359 case NL80211_CHAN_WIDTH_40:
360 ch_inf.bw = BRCMU_CHAN_BW_40;
361 if (primary_offset < 0)
362 ch_inf.sb = BRCMU_CHAN_SB_U;
364 ch_inf.sb = BRCMU_CHAN_SB_L;
366 case NL80211_CHAN_WIDTH_80:
367 ch_inf.bw = BRCMU_CHAN_BW_80;
368 if (primary_offset < 0) {
369 if (primary_offset < -CH_10MHZ_APART)
370 ch_inf.sb = BRCMU_CHAN_SB_UU;
372 ch_inf.sb = BRCMU_CHAN_SB_UL;
374 if (primary_offset > CH_10MHZ_APART)
375 ch_inf.sb = BRCMU_CHAN_SB_LL;
377 ch_inf.sb = BRCMU_CHAN_SB_LU;
383 switch (ch->chan->band) {
384 case IEEE80211_BAND_2GHZ:
385 ch_inf.band = BRCMU_CHAN_BAND_2G;
387 case IEEE80211_BAND_5GHZ:
388 ch_inf.band = BRCMU_CHAN_BAND_5G;
393 d11inf->encchspec(&ch_inf);
395 return ch_inf.chspec;
398 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
399 struct ieee80211_channel *ch)
401 struct brcmu_chan ch_inf;
403 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
404 ch_inf.bw = BRCMU_CHAN_BW_20;
405 d11inf->encchspec(&ch_inf);
407 return ch_inf.chspec;
410 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
411 * triples, returning a pointer to the substring whose first element
414 const struct brcmf_tlv *
415 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
417 const struct brcmf_tlv *elt = buf;
420 /* find tagged parameter */
421 while (totlen >= TLV_HDR_LEN) {
424 /* validate remaining totlen */
425 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
428 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
429 totlen -= (len + TLV_HDR_LEN);
435 /* Is any of the tlvs the expected entry? If
436 * not update the tlvs buffer pointer/length.
439 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
440 const u8 *oui, u32 oui_len, u8 type)
442 /* If the contents match the OUI and the type */
443 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
444 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
445 type == ie[TLV_BODY_OFF + oui_len]) {
451 /* point to the next ie */
452 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
453 /* calculate the length of the rest of the buffer */
454 *tlvs_len -= (int)(ie - *tlvs);
455 /* update the pointer to the start of the buffer */
461 static struct brcmf_vs_tlv *
462 brcmf_find_wpaie(const u8 *parse, u32 len)
464 const struct brcmf_tlv *ie;
466 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
467 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
468 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
469 return (struct brcmf_vs_tlv *)ie;
474 static struct brcmf_vs_tlv *
475 brcmf_find_wpsie(const u8 *parse, u32 len)
477 const struct brcmf_tlv *ie;
479 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
480 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
481 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
482 return (struct brcmf_vs_tlv *)ie;
488 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
489 struct brcmf_wsec_key_le *key_le)
491 key_le->index = cpu_to_le32(key->index);
492 key_le->len = cpu_to_le32(key->len);
493 key_le->algo = cpu_to_le32(key->algo);
494 key_le->flags = cpu_to_le32(key->flags);
495 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
496 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
497 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
498 memcpy(key_le->data, key->data, sizeof(key->data));
499 memcpy(key_le->ea, key->ea, sizeof(key->ea));
503 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
506 struct brcmf_wsec_key_le key_le;
508 convert_key_from_CPU(key, &key_le);
510 brcmf_netdev_wait_pend8021x(ndev);
512 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
516 brcmf_err("wsec_key error (%d)\n", err);
521 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
527 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
531 /* Try to set and enable ARP offload feature, this may fail, then it */
532 /* is simply not supported and err 0 will be returned */
533 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
535 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
539 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
541 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
545 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
552 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
554 enum nl80211_iftype iftype;
556 iftype = vif->wdev.iftype;
557 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
560 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
562 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
565 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
567 enum nl80211_iftype type,
569 struct vif_params *params)
571 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
573 case NL80211_IFTYPE_ADHOC:
574 case NL80211_IFTYPE_STATION:
575 case NL80211_IFTYPE_AP:
576 case NL80211_IFTYPE_AP_VLAN:
577 case NL80211_IFTYPE_WDS:
578 case NL80211_IFTYPE_MONITOR:
579 case NL80211_IFTYPE_MESH_POINT:
580 return ERR_PTR(-EOPNOTSUPP);
581 case NL80211_IFTYPE_P2P_CLIENT:
582 case NL80211_IFTYPE_P2P_GO:
583 case NL80211_IFTYPE_P2P_DEVICE:
584 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
585 case NL80211_IFTYPE_UNSPECIFIED:
587 return ERR_PTR(-EINVAL);
591 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
595 if (check_vif_up(ifp->vif)) {
596 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
598 brcmf_err("fail to set mpc\n");
601 brcmf_dbg(INFO, "MPC : %d\n", mpc);
605 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
606 struct brcmf_if *ifp, bool aborted,
609 struct brcmf_scan_params_le params_le;
610 struct cfg80211_scan_request *scan_request;
613 brcmf_dbg(SCAN, "Enter\n");
615 /* clear scan request, because the FW abort can cause a second call */
616 /* to this functon and might cause a double cfg80211_scan_done */
617 scan_request = cfg->scan_request;
618 cfg->scan_request = NULL;
620 if (timer_pending(&cfg->escan_timeout))
621 del_timer_sync(&cfg->escan_timeout);
624 /* Do a scan abort to stop the driver's scan engine */
625 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
626 memset(¶ms_le, 0, sizeof(params_le));
627 memset(params_le.bssid, 0xFF, ETH_ALEN);
628 params_le.bss_type = DOT11_BSSTYPE_ANY;
629 params_le.scan_type = 0;
630 params_le.channel_num = cpu_to_le32(1);
631 params_le.nprobes = cpu_to_le32(1);
632 params_le.active_time = cpu_to_le32(-1);
633 params_le.passive_time = cpu_to_le32(-1);
634 params_le.home_time = cpu_to_le32(-1);
635 /* Scan is aborted by setting channel_list[0] to -1 */
636 params_le.channel_list[0] = cpu_to_le16(-1);
637 /* E-Scan (or anyother type) can be aborted by SCAN */
638 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
639 ¶ms_le, sizeof(params_le));
641 brcmf_err("Scan abort failed\n");
644 brcmf_set_mpc(ifp, 1);
647 * e-scan can be initiated by scheduled scan
648 * which takes precedence.
650 if (cfg->sched_escan) {
651 brcmf_dbg(SCAN, "scheduled scan completed\n");
652 cfg->sched_escan = false;
654 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
655 } else if (scan_request) {
656 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
657 aborted ? "Aborted" : "Done");
658 cfg80211_scan_done(scan_request, aborted);
660 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
661 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
667 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
669 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
670 struct net_device *ndev = wdev->netdev;
672 /* vif event pending in firmware */
673 if (brcmf_cfg80211_vif_event_armed(cfg))
677 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
678 cfg->escan_info.ifp == netdev_priv(ndev))
679 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
682 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
685 switch (wdev->iftype) {
686 case NL80211_IFTYPE_ADHOC:
687 case NL80211_IFTYPE_STATION:
688 case NL80211_IFTYPE_AP:
689 case NL80211_IFTYPE_AP_VLAN:
690 case NL80211_IFTYPE_WDS:
691 case NL80211_IFTYPE_MONITOR:
692 case NL80211_IFTYPE_MESH_POINT:
694 case NL80211_IFTYPE_P2P_CLIENT:
695 case NL80211_IFTYPE_P2P_GO:
696 case NL80211_IFTYPE_P2P_DEVICE:
697 return brcmf_p2p_del_vif(wiphy, wdev);
698 case NL80211_IFTYPE_UNSPECIFIED:
706 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
707 enum nl80211_iftype type, u32 *flags,
708 struct vif_params *params)
710 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
711 struct brcmf_if *ifp = netdev_priv(ndev);
712 struct brcmf_cfg80211_vif *vif = ifp->vif;
717 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
720 case NL80211_IFTYPE_MONITOR:
721 case NL80211_IFTYPE_WDS:
722 brcmf_err("type (%d) : currently we do not support this type\n",
725 case NL80211_IFTYPE_ADHOC:
728 case NL80211_IFTYPE_STATION:
729 /* Ignore change for p2p IF. Unclear why supplicant does this */
730 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
731 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
732 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
733 /* WAR: It is unexpected to get a change of VIF for P2P
734 * IF, but it happens. The request can not be handled
735 * but returning EPERM causes a crash. Returning 0
736 * without setting ieee80211_ptr->iftype causes trace
737 * (WARN_ON) but it works with wpa_supplicant
743 case NL80211_IFTYPE_AP:
744 case NL80211_IFTYPE_P2P_GO:
753 if (type == NL80211_IFTYPE_P2P_GO) {
754 brcmf_dbg(INFO, "IF Type = P2P GO\n");
755 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
758 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
759 brcmf_dbg(INFO, "IF Type = AP\n");
762 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
764 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
768 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
771 ndev->ieee80211_ptr->iftype = type;
774 brcmf_dbg(TRACE, "Exit\n");
779 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
780 struct brcmf_scan_params_le *params_le,
781 struct cfg80211_scan_request *request)
789 struct brcmf_ssid_le ssid_le;
791 memset(params_le->bssid, 0xFF, ETH_ALEN);
792 params_le->bss_type = DOT11_BSSTYPE_ANY;
793 params_le->scan_type = 0;
794 params_le->channel_num = 0;
795 params_le->nprobes = cpu_to_le32(-1);
796 params_le->active_time = cpu_to_le32(-1);
797 params_le->passive_time = cpu_to_le32(-1);
798 params_le->home_time = cpu_to_le32(-1);
799 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
801 /* if request is null exit so it will be all channel broadcast scan */
805 n_ssids = request->n_ssids;
806 n_channels = request->n_channels;
807 /* Copy channel array if applicable */
808 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
810 if (n_channels > 0) {
811 for (i = 0; i < n_channels; i++) {
812 chanspec = channel_to_chanspec(&cfg->d11inf,
813 request->channels[i]);
814 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
815 request->channels[i]->hw_value, chanspec);
816 params_le->channel_list[i] = cpu_to_le16(chanspec);
819 brcmf_dbg(SCAN, "Scanning all channels\n");
821 /* Copy ssid array if applicable */
822 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
824 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
825 n_channels * sizeof(u16);
826 offset = roundup(offset, sizeof(u32));
827 ptr = (char *)params_le + offset;
828 for (i = 0; i < n_ssids; i++) {
829 memset(&ssid_le, 0, sizeof(ssid_le));
831 cpu_to_le32(request->ssids[i].ssid_len);
832 memcpy(ssid_le.SSID, request->ssids[i].ssid,
833 request->ssids[i].ssid_len);
834 if (!ssid_le.SSID_len)
835 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
837 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
838 i, ssid_le.SSID, ssid_le.SSID_len);
839 memcpy(ptr, &ssid_le, sizeof(ssid_le));
840 ptr += sizeof(ssid_le);
843 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
844 if ((request->ssids) && request->ssids->ssid_len) {
845 brcmf_dbg(SCAN, "SSID %s len=%d\n",
846 params_le->ssid_le.SSID,
847 request->ssids->ssid_len);
848 params_le->ssid_le.SSID_len =
849 cpu_to_le32(request->ssids->ssid_len);
850 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
851 request->ssids->ssid_len);
854 /* Adding mask to channel numbers */
855 params_le->channel_num =
856 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
857 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
861 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
862 struct cfg80211_scan_request *request, u16 action)
864 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
865 offsetof(struct brcmf_escan_params_le, params_le);
866 struct brcmf_escan_params_le *params;
869 brcmf_dbg(SCAN, "E-SCAN START\n");
871 if (request != NULL) {
872 /* Allocate space for populating ssids in struct */
873 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
875 /* Allocate space for populating ssids in struct */
876 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
879 params = kzalloc(params_size, GFP_KERNEL);
884 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
885 brcmf_escan_prep(cfg, ¶ms->params_le, request);
886 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
887 params->action = cpu_to_le16(action);
888 params->sync_id = cpu_to_le16(0x1234);
890 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
893 brcmf_dbg(INFO, "system busy : escan canceled\n");
895 brcmf_err("error (%d)\n", err);
904 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
905 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
909 struct brcmf_scan_results *results;
910 struct escan_info *escan = &cfg->escan_info;
912 brcmf_dbg(SCAN, "Enter\n");
914 escan->wiphy = wiphy;
915 escan->escan_state = WL_ESCAN_STATE_SCANNING;
916 passive_scan = cfg->active_scan ? 0 : 1;
917 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
920 brcmf_err("error (%d)\n", err);
923 brcmf_set_mpc(ifp, 0);
924 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
925 results->version = 0;
927 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
929 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
931 brcmf_set_mpc(ifp, 1);
936 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
937 struct cfg80211_scan_request *request,
938 struct cfg80211_ssid *this_ssid)
940 struct brcmf_if *ifp = vif->ifp;
941 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
942 struct cfg80211_ssid *ssids;
943 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
950 brcmf_dbg(SCAN, "START ESCAN\n");
952 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
953 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
956 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
957 brcmf_err("Scanning being aborted: status (%lu)\n",
961 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
962 brcmf_err("Scanning suppressed: status (%lu)\n",
966 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
967 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
971 /* If scan req comes for p2p0, send it over primary I/F */
972 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
973 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
975 /* Arm scan timeout timer */
976 mod_timer(&cfg->escan_timeout, jiffies +
977 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
982 ssids = request->ssids;
986 /* we don't do escan in ibss */
990 cfg->scan_request = request;
991 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
993 cfg->escan_info.run = brcmf_run_escan;
994 err = brcmf_p2p_scan_prep(wiphy, request, vif);
998 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1002 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1003 ssids->ssid, ssids->ssid_len);
1004 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1005 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1006 sr->ssid_le.SSID_len = cpu_to_le32(0);
1009 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1010 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1013 brcmf_dbg(SCAN, "Broadcast scan\n");
1015 passive_scan = cfg->active_scan ? 0 : 1;
1016 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1019 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1022 brcmf_set_mpc(ifp, 0);
1023 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1024 &sr->ssid_le, sizeof(sr->ssid_le));
1027 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1030 brcmf_err("WLC_SCAN error (%d)\n", err);
1032 brcmf_set_mpc(ifp, 1);
1040 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1041 if (timer_pending(&cfg->escan_timeout))
1042 del_timer_sync(&cfg->escan_timeout);
1043 cfg->scan_request = NULL;
1048 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1050 struct brcmf_cfg80211_vif *vif;
1053 brcmf_dbg(TRACE, "Enter\n");
1054 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1055 if (!check_vif_up(vif))
1058 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1061 brcmf_err("scan error (%d)\n", err);
1063 brcmf_dbg(TRACE, "Exit\n");
1067 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1071 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1074 brcmf_err("Error (%d)\n", err);
1079 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1083 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1086 brcmf_err("Error (%d)\n", err);
1091 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1094 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1096 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1098 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1104 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1106 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1107 struct net_device *ndev = cfg_to_ndev(cfg);
1108 struct brcmf_if *ifp = netdev_priv(ndev);
1111 brcmf_dbg(TRACE, "Enter\n");
1112 if (!check_vif_up(ifp->vif))
1115 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1116 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1117 cfg->conf->rts_threshold = wiphy->rts_threshold;
1118 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1122 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1123 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1124 cfg->conf->frag_threshold = wiphy->frag_threshold;
1125 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1129 if (changed & WIPHY_PARAM_RETRY_LONG
1130 && (cfg->conf->retry_long != wiphy->retry_long)) {
1131 cfg->conf->retry_long = wiphy->retry_long;
1132 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1136 if (changed & WIPHY_PARAM_RETRY_SHORT
1137 && (cfg->conf->retry_short != wiphy->retry_short)) {
1138 cfg->conf->retry_short = wiphy->retry_short;
1139 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1145 brcmf_dbg(TRACE, "Exit\n");
1149 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1151 memset(prof, 0, sizeof(*prof));
1154 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1156 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1159 brcmf_dbg(TRACE, "Enter\n");
1161 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1162 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1163 err = brcmf_fil_cmd_data_set(vif->ifp,
1164 BRCMF_C_DISASSOC, NULL, 0);
1166 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1168 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1169 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1172 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1173 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1174 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1175 brcmf_dbg(TRACE, "Exit\n");
1179 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1180 struct cfg80211_ibss_params *params)
1182 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1183 struct brcmf_if *ifp = netdev_priv(ndev);
1184 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1185 struct brcmf_join_params join_params;
1186 size_t join_params_size = 0;
1192 brcmf_dbg(TRACE, "Enter\n");
1193 if (!check_vif_up(ifp->vif))
1197 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1199 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1203 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1206 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1208 brcmf_dbg(CONN, "No BSSID specified\n");
1210 if (params->chandef.chan)
1211 brcmf_dbg(CONN, "channel: %d\n",
1212 params->chandef.chan->center_freq);
1214 brcmf_dbg(CONN, "no channel specified\n");
1216 if (params->channel_fixed)
1217 brcmf_dbg(CONN, "fixed channel required\n");
1219 brcmf_dbg(CONN, "no fixed channel required\n");
1221 if (params->ie && params->ie_len)
1222 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1224 brcmf_dbg(CONN, "no ie specified\n");
1226 if (params->beacon_interval)
1227 brcmf_dbg(CONN, "beacon interval: %d\n",
1228 params->beacon_interval);
1230 brcmf_dbg(CONN, "no beacon interval specified\n");
1232 if (params->basic_rates)
1233 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1235 brcmf_dbg(CONN, "no basic rates specified\n");
1237 if (params->privacy)
1238 brcmf_dbg(CONN, "privacy required\n");
1240 brcmf_dbg(CONN, "no privacy required\n");
1242 /* Configure Privacy for starter */
1243 if (params->privacy)
1244 wsec |= WEP_ENABLED;
1246 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1248 brcmf_err("wsec failed (%d)\n", err);
1252 /* Configure Beacon Interval for starter */
1253 if (params->beacon_interval)
1254 bcnprd = params->beacon_interval;
1258 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1260 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1264 /* Configure required join parameter */
1265 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1268 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1269 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1270 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1271 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1272 join_params_size = sizeof(join_params.ssid_le);
1275 if (params->bssid) {
1276 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1277 join_params_size = sizeof(join_params.ssid_le) +
1278 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1279 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1281 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1282 memset(profile->bssid, 0, ETH_ALEN);
1286 if (params->chandef.chan) {
1290 ieee80211_frequency_to_channel(
1291 params->chandef.chan->center_freq);
1292 if (params->channel_fixed) {
1293 /* adding chanspec */
1294 chanspec = chandef_to_chanspec(&cfg->d11inf,
1296 join_params.params_le.chanspec_list[0] =
1297 cpu_to_le16(chanspec);
1298 join_params.params_le.chanspec_num = cpu_to_le32(1);
1299 join_params_size += sizeof(join_params.params_le);
1302 /* set channel for starter */
1303 target_channel = cfg->channel;
1304 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1307 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1313 cfg->ibss_starter = false;
1316 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1317 &join_params, join_params_size);
1319 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1325 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1326 brcmf_dbg(TRACE, "Exit\n");
1331 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1333 struct brcmf_if *ifp = netdev_priv(ndev);
1336 brcmf_dbg(TRACE, "Enter\n");
1337 if (!check_vif_up(ifp->vif))
1340 brcmf_link_down(ifp->vif);
1342 brcmf_dbg(TRACE, "Exit\n");
1347 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1348 struct cfg80211_connect_params *sme)
1350 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1351 struct brcmf_cfg80211_security *sec;
1355 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1356 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1357 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1358 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1360 val = WPA_AUTH_DISABLED;
1361 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1362 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1364 brcmf_err("set wpa_auth failed (%d)\n", err);
1367 sec = &profile->sec;
1368 sec->wpa_versions = sme->crypto.wpa_versions;
1372 static s32 brcmf_set_auth_type(struct net_device *ndev,
1373 struct cfg80211_connect_params *sme)
1375 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1376 struct brcmf_cfg80211_security *sec;
1380 switch (sme->auth_type) {
1381 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1383 brcmf_dbg(CONN, "open system\n");
1385 case NL80211_AUTHTYPE_SHARED_KEY:
1387 brcmf_dbg(CONN, "shared key\n");
1389 case NL80211_AUTHTYPE_AUTOMATIC:
1391 brcmf_dbg(CONN, "automatic\n");
1393 case NL80211_AUTHTYPE_NETWORK_EAP:
1394 brcmf_dbg(CONN, "network eap\n");
1397 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1401 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1403 brcmf_err("set auth failed (%d)\n", err);
1406 sec = &profile->sec;
1407 sec->auth_type = sme->auth_type;
1412 brcmf_set_wsec_mode(struct net_device *ndev,
1413 struct cfg80211_connect_params *sme, bool mfp)
1415 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1416 struct brcmf_cfg80211_security *sec;
1422 if (sme->crypto.n_ciphers_pairwise) {
1423 switch (sme->crypto.ciphers_pairwise[0]) {
1424 case WLAN_CIPHER_SUITE_WEP40:
1425 case WLAN_CIPHER_SUITE_WEP104:
1428 case WLAN_CIPHER_SUITE_TKIP:
1429 pval = TKIP_ENABLED;
1431 case WLAN_CIPHER_SUITE_CCMP:
1434 case WLAN_CIPHER_SUITE_AES_CMAC:
1438 brcmf_err("invalid cipher pairwise (%d)\n",
1439 sme->crypto.ciphers_pairwise[0]);
1443 if (sme->crypto.cipher_group) {
1444 switch (sme->crypto.cipher_group) {
1445 case WLAN_CIPHER_SUITE_WEP40:
1446 case WLAN_CIPHER_SUITE_WEP104:
1449 case WLAN_CIPHER_SUITE_TKIP:
1450 gval = TKIP_ENABLED;
1452 case WLAN_CIPHER_SUITE_CCMP:
1455 case WLAN_CIPHER_SUITE_AES_CMAC:
1459 brcmf_err("invalid cipher group (%d)\n",
1460 sme->crypto.cipher_group);
1465 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1466 /* In case of privacy, but no security and WPS then simulate */
1467 /* setting AES. WPS-2.0 allows no security */
1468 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1473 wsec = pval | gval | MFP_CAPABLE;
1476 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1478 brcmf_err("error (%d)\n", err);
1482 sec = &profile->sec;
1483 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1484 sec->cipher_group = sme->crypto.cipher_group;
1490 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1492 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1493 struct brcmf_cfg80211_security *sec;
1497 if (sme->crypto.n_akm_suites) {
1498 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1501 brcmf_err("could not get wpa_auth (%d)\n", err);
1504 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1505 switch (sme->crypto.akm_suites[0]) {
1506 case WLAN_AKM_SUITE_8021X:
1507 val = WPA_AUTH_UNSPECIFIED;
1509 case WLAN_AKM_SUITE_PSK:
1513 brcmf_err("invalid cipher group (%d)\n",
1514 sme->crypto.cipher_group);
1517 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1518 switch (sme->crypto.akm_suites[0]) {
1519 case WLAN_AKM_SUITE_8021X:
1520 val = WPA2_AUTH_UNSPECIFIED;
1522 case WLAN_AKM_SUITE_PSK:
1523 val = WPA2_AUTH_PSK;
1526 brcmf_err("invalid cipher group (%d)\n",
1527 sme->crypto.cipher_group);
1532 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1533 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1536 brcmf_err("could not set wpa_auth (%d)\n", err);
1540 sec = &profile->sec;
1541 sec->wpa_auth = sme->crypto.akm_suites[0];
1547 brcmf_set_sharedkey(struct net_device *ndev,
1548 struct cfg80211_connect_params *sme)
1550 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1551 struct brcmf_cfg80211_security *sec;
1552 struct brcmf_wsec_key key;
1556 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1558 if (sme->key_len == 0)
1561 sec = &profile->sec;
1562 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1563 sec->wpa_versions, sec->cipher_pairwise);
1565 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1568 if (!(sec->cipher_pairwise &
1569 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1572 memset(&key, 0, sizeof(key));
1573 key.len = (u32) sme->key_len;
1574 key.index = (u32) sme->key_idx;
1575 if (key.len > sizeof(key.data)) {
1576 brcmf_err("Too long key length (%u)\n", key.len);
1579 memcpy(key.data, sme->key, key.len);
1580 key.flags = BRCMF_PRIMARY_KEY;
1581 switch (sec->cipher_pairwise) {
1582 case WLAN_CIPHER_SUITE_WEP40:
1583 key.algo = CRYPTO_ALGO_WEP1;
1585 case WLAN_CIPHER_SUITE_WEP104:
1586 key.algo = CRYPTO_ALGO_WEP128;
1589 brcmf_err("Invalid algorithm (%d)\n",
1590 sme->crypto.ciphers_pairwise[0]);
1593 /* Set the new key/index */
1594 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1595 key.len, key.index, key.algo);
1596 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1597 err = send_key_to_dongle(ndev, &key);
1601 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1602 brcmf_dbg(CONN, "set auth_type to shared key\n");
1603 val = WL_AUTH_SHARED_KEY; /* shared key */
1604 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1606 brcmf_err("set auth failed (%d)\n", err);
1612 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1613 enum nl80211_auth_type type)
1616 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1617 /* shift to ignore chip revision */
1618 ci = brcmf_get_chip_info(ifp) >> 4;
1621 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1622 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1631 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1632 struct cfg80211_connect_params *sme)
1634 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1635 struct brcmf_if *ifp = netdev_priv(ndev);
1636 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1637 struct ieee80211_channel *chan = sme->channel;
1638 struct brcmf_join_params join_params;
1639 size_t join_params_size;
1640 const struct brcmf_tlv *rsn_ie;
1641 const struct brcmf_vs_tlv *wpa_ie;
1644 struct brcmf_ext_join_params_le *ext_join_params;
1648 brcmf_dbg(TRACE, "Enter\n");
1649 if (!check_vif_up(ifp->vif))
1653 brcmf_err("Invalid ssid\n");
1657 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1658 /* A normal (non P2P) connection request setup. */
1661 /* find the WPA_IE */
1662 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1665 ie_len = wpa_ie->len + TLV_HDR_LEN;
1667 /* find the RSN_IE */
1668 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1673 ie_len = rsn_ie->len + TLV_HDR_LEN;
1676 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1679 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1680 sme->ie, sme->ie_len);
1682 brcmf_err("Set Assoc REQ IE Failed\n");
1684 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1686 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1690 ieee80211_frequency_to_channel(chan->center_freq);
1691 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1692 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1693 cfg->channel, chan->center_freq, chanspec);
1699 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1701 err = brcmf_set_wpa_version(ndev, sme);
1703 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1707 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1708 err = brcmf_set_auth_type(ndev, sme);
1710 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1714 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1716 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1720 err = brcmf_set_key_mgmt(ndev, sme);
1722 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1726 err = brcmf_set_sharedkey(ndev, sme);
1728 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1732 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1733 (u32)sme->ssid_len);
1734 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1735 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1736 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1737 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1738 profile->ssid.SSID_len);
1741 /* Join with specific BSSID and cached SSID
1742 * If SSID is zero join based on BSSID only
1744 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1745 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1747 join_params_size += sizeof(u16);
1748 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1749 if (ext_join_params == NULL) {
1753 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1754 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1755 profile->ssid.SSID_len);
1757 /* Set up join scan parameters */
1758 ext_join_params->scan_le.scan_type = -1;
1759 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1762 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1764 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1767 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1769 ext_join_params->assoc_le.chanspec_list[0] =
1770 cpu_to_le16(chanspec);
1771 /* Increase dwell time to receive probe response or detect
1772 * beacon from target AP at a noisy air only during connect
1775 ext_join_params->scan_le.active_time =
1776 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1777 ext_join_params->scan_le.passive_time =
1778 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1779 /* To sync with presence period of VSDB GO send probe request
1780 * more frequently. Probe request will be stopped when it gets
1781 * probe response from target AP/GO.
1783 ext_join_params->scan_le.nprobes =
1784 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1785 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1787 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1788 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1789 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1792 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1794 kfree(ext_join_params);
1796 /* This is it. join command worked, we are done */
1799 /* join command failed, fallback to set ssid */
1800 memset(&join_params, 0, sizeof(join_params));
1801 join_params_size = sizeof(join_params.ssid_le);
1803 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1804 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1807 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1809 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1812 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1813 join_params.params_le.chanspec_num = cpu_to_le32(1);
1814 join_params_size += sizeof(join_params.params_le);
1816 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1817 &join_params, join_params_size);
1819 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1823 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1824 brcmf_dbg(TRACE, "Exit\n");
1829 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1832 struct brcmf_if *ifp = netdev_priv(ndev);
1833 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1834 struct brcmf_scb_val_le scbval;
1837 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1838 if (!check_vif_up(ifp->vif))
1841 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1842 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1844 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1845 scbval.val = cpu_to_le32(reason_code);
1846 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1847 &scbval, sizeof(scbval));
1849 brcmf_err("error (%d)\n", err);
1851 brcmf_dbg(TRACE, "Exit\n");
1856 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1857 enum nl80211_tx_power_setting type, s32 mbm)
1860 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1861 struct net_device *ndev = cfg_to_ndev(cfg);
1862 struct brcmf_if *ifp = netdev_priv(ndev);
1866 s32 dbm = MBM_TO_DBM(mbm);
1868 brcmf_dbg(TRACE, "Enter\n");
1869 if (!check_vif_up(ifp->vif))
1873 case NL80211_TX_POWER_AUTOMATIC:
1875 case NL80211_TX_POWER_LIMITED:
1876 case NL80211_TX_POWER_FIXED:
1878 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1884 /* Make sure radio is off or on as far as software is concerned */
1885 disable = WL_RADIO_SW_DISABLE << 16;
1886 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1888 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1893 txpwrmw = (u16) dbm;
1894 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1895 (s32)brcmf_mw_to_qdbm(txpwrmw));
1897 brcmf_err("qtxpower error (%d)\n", err);
1898 cfg->conf->tx_power = dbm;
1901 brcmf_dbg(TRACE, "Exit\n");
1905 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1906 struct wireless_dev *wdev,
1909 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1910 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1915 brcmf_dbg(TRACE, "Enter\n");
1916 if (!check_vif_up(ifp->vif))
1919 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1921 brcmf_err("error (%d)\n", err);
1925 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1926 *dbm = (s32) brcmf_qdbm_to_mw(result);
1929 brcmf_dbg(TRACE, "Exit\n");
1934 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1935 u8 key_idx, bool unicast, bool multicast)
1937 struct brcmf_if *ifp = netdev_priv(ndev);
1942 brcmf_dbg(TRACE, "Enter\n");
1943 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1944 if (!check_vif_up(ifp->vif))
1947 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1949 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1953 if (wsec & WEP_ENABLED) {
1954 /* Just select a new current key */
1956 err = brcmf_fil_cmd_int_set(ifp,
1957 BRCMF_C_SET_KEY_PRIMARY, index);
1959 brcmf_err("error (%d)\n", err);
1962 brcmf_dbg(TRACE, "Exit\n");
1967 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1968 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1970 struct brcmf_if *ifp = netdev_priv(ndev);
1971 struct brcmf_wsec_key key;
1975 memset(&key, 0, sizeof(key));
1976 key.index = (u32) key_idx;
1977 /* Instead of bcast for ea address for default wep keys,
1978 driver needs it to be Null */
1979 if (!is_multicast_ether_addr(mac_addr))
1980 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1981 key.len = (u32) params->key_len;
1982 /* check for key index change */
1985 err = send_key_to_dongle(ndev, &key);
1987 brcmf_err("key delete error (%d)\n", err);
1989 if (key.len > sizeof(key.data)) {
1990 brcmf_err("Invalid key length (%d)\n", key.len);
1994 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1995 memcpy(key.data, params->key, key.len);
1997 if (!brcmf_is_apmode(ifp->vif) &&
1998 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1999 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2000 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2001 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2002 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2005 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2006 if (params->seq && params->seq_len == 6) {
2009 ivptr = (u8 *) params->seq;
2010 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2011 (ivptr[3] << 8) | ivptr[2];
2012 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2013 key.iv_initialized = true;
2016 switch (params->cipher) {
2017 case WLAN_CIPHER_SUITE_WEP40:
2018 key.algo = CRYPTO_ALGO_WEP1;
2019 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2021 case WLAN_CIPHER_SUITE_WEP104:
2022 key.algo = CRYPTO_ALGO_WEP128;
2023 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2025 case WLAN_CIPHER_SUITE_TKIP:
2026 key.algo = CRYPTO_ALGO_TKIP;
2027 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2029 case WLAN_CIPHER_SUITE_AES_CMAC:
2030 key.algo = CRYPTO_ALGO_AES_CCM;
2031 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2033 case WLAN_CIPHER_SUITE_CCMP:
2034 key.algo = CRYPTO_ALGO_AES_CCM;
2035 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2038 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2041 err = send_key_to_dongle(ndev, &key);
2043 brcmf_err("wsec_key error (%d)\n", err);
2049 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2050 u8 key_idx, bool pairwise, const u8 *mac_addr,
2051 struct key_params *params)
2053 struct brcmf_if *ifp = netdev_priv(ndev);
2054 struct brcmf_wsec_key key;
2060 brcmf_dbg(TRACE, "Enter\n");
2061 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2062 if (!check_vif_up(ifp->vif))
2066 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2067 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2068 brcmf_dbg(TRACE, "Exit");
2069 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2071 memset(&key, 0, sizeof(key));
2073 key.len = (u32) params->key_len;
2074 key.index = (u32) key_idx;
2076 if (key.len > sizeof(key.data)) {
2077 brcmf_err("Too long key length (%u)\n", key.len);
2081 memcpy(key.data, params->key, key.len);
2083 key.flags = BRCMF_PRIMARY_KEY;
2084 switch (params->cipher) {
2085 case WLAN_CIPHER_SUITE_WEP40:
2086 key.algo = CRYPTO_ALGO_WEP1;
2088 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2090 case WLAN_CIPHER_SUITE_WEP104:
2091 key.algo = CRYPTO_ALGO_WEP128;
2093 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2095 case WLAN_CIPHER_SUITE_TKIP:
2096 if (!brcmf_is_apmode(ifp->vif)) {
2097 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2098 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2099 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2100 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2102 key.algo = CRYPTO_ALGO_TKIP;
2104 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2106 case WLAN_CIPHER_SUITE_AES_CMAC:
2107 key.algo = CRYPTO_ALGO_AES_CCM;
2109 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2111 case WLAN_CIPHER_SUITE_CCMP:
2112 key.algo = CRYPTO_ALGO_AES_CCM;
2114 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2117 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2122 err = send_key_to_dongle(ndev, &key);
2126 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2128 brcmf_err("get wsec error (%d)\n", err);
2132 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2134 brcmf_err("set wsec error (%d)\n", err);
2139 brcmf_dbg(TRACE, "Exit\n");
2144 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2145 u8 key_idx, bool pairwise, const u8 *mac_addr)
2147 struct brcmf_if *ifp = netdev_priv(ndev);
2148 struct brcmf_wsec_key key;
2151 brcmf_dbg(TRACE, "Enter\n");
2152 if (!check_vif_up(ifp->vif))
2155 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2156 /* we ignore this key index in this case */
2157 brcmf_err("invalid key index (%d)\n", key_idx);
2161 memset(&key, 0, sizeof(key));
2163 key.index = (u32) key_idx;
2164 key.flags = BRCMF_PRIMARY_KEY;
2165 key.algo = CRYPTO_ALGO_OFF;
2167 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2169 /* Set the new key/index */
2170 err = send_key_to_dongle(ndev, &key);
2172 brcmf_dbg(TRACE, "Exit\n");
2177 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2178 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2179 void (*callback) (void *cookie, struct key_params * params))
2181 struct key_params params;
2182 struct brcmf_if *ifp = netdev_priv(ndev);
2183 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2184 struct brcmf_cfg80211_security *sec;
2188 brcmf_dbg(TRACE, "Enter\n");
2189 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2190 if (!check_vif_up(ifp->vif))
2193 memset(¶ms, 0, sizeof(params));
2195 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2197 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2198 /* Ignore this error, may happen during DISASSOC */
2202 if (wsec & WEP_ENABLED) {
2203 sec = &profile->sec;
2204 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2205 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2206 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2207 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2208 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2209 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2211 } else if (wsec & TKIP_ENABLED) {
2212 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2213 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2214 } else if (wsec & AES_ENABLED) {
2215 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2216 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2218 brcmf_err("Invalid algo (0x%x)\n", wsec);
2222 callback(cookie, ¶ms);
2225 brcmf_dbg(TRACE, "Exit\n");
2230 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2231 struct net_device *ndev, u8 key_idx)
2233 brcmf_dbg(INFO, "Not supported\n");
2239 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2240 const u8 *mac, struct station_info *sinfo)
2242 struct brcmf_if *ifp = netdev_priv(ndev);
2243 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2244 struct brcmf_scb_val_le scb_val;
2248 u8 *bssid = profile->bssid;
2249 struct brcmf_sta_info_le sta_info_le;
2253 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2254 if (!check_vif_up(ifp->vif))
2257 if (brcmf_is_apmode(ifp->vif)) {
2258 memcpy(&sta_info_le, mac, ETH_ALEN);
2259 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2261 sizeof(sta_info_le));
2263 brcmf_err("GET STA INFO failed, %d\n", err);
2266 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2267 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2268 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2269 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2270 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2272 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2273 sinfo->inactive_time, sinfo->connected_time);
2274 } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
2275 if (memcmp(mac, bssid, ETH_ALEN)) {
2276 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2281 /* Report the current tx rate */
2282 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2284 brcmf_err("Could not get rate (%d)\n", err);
2287 sinfo->filled |= STATION_INFO_TX_BITRATE;
2288 sinfo->txrate.legacy = rate * 5;
2289 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2292 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2293 &ifp->vif->sme_state)) {
2294 memset(&scb_val, 0, sizeof(scb_val));
2295 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2296 &scb_val, sizeof(scb_val));
2298 brcmf_err("Could not get rssi (%d)\n", err);
2301 rssi = le32_to_cpu(scb_val.val);
2302 sinfo->filled |= STATION_INFO_SIGNAL;
2303 sinfo->signal = rssi;
2304 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2306 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2309 brcmf_err("Could not get beacon period (%d)\n",
2313 sinfo->bss_param.beacon_interval =
2315 brcmf_dbg(CONN, "Beacon peroid %d\n",
2318 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2321 brcmf_err("Could not get DTIM period (%d)\n",
2325 sinfo->bss_param.dtim_period = dtim_period;
2326 brcmf_dbg(CONN, "DTIM peroid %d\n",
2329 sinfo->filled |= STATION_INFO_BSS_PARAM;
2334 brcmf_dbg(TRACE, "Exit\n");
2339 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2340 bool enabled, s32 timeout)
2344 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2345 struct brcmf_if *ifp = netdev_priv(ndev);
2347 brcmf_dbg(TRACE, "Enter\n");
2350 * Powersave enable/disable request is coming from the
2351 * cfg80211 even before the interface is up. In that
2352 * scenario, driver will be storing the power save
2353 * preference in cfg struct to apply this to
2354 * FW later while initializing the dongle
2356 cfg->pwr_save = enabled;
2357 if (!check_vif_up(ifp->vif)) {
2359 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2363 pm = enabled ? PM_FAST : PM_OFF;
2364 /* Do not enable the power save after assoc if it is a p2p interface */
2365 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2366 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2369 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2371 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2374 brcmf_err("net_device is not ready yet\n");
2376 brcmf_err("error (%d)\n", err);
2379 brcmf_dbg(TRACE, "Exit\n");
2383 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2384 struct brcmf_bss_info_le *bi)
2386 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2387 struct ieee80211_channel *notify_channel;
2388 struct cfg80211_bss *bss;
2389 struct ieee80211_supported_band *band;
2390 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;
2694 struct brcmf_escan_result_le *escan_result_le;
2695 struct brcmf_bss_info_le *bss_info_le;
2696 struct brcmf_bss_info_le *bss = NULL;
2698 struct brcmf_scan_results *list;
2704 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2705 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2709 if (status == BRCMF_E_STATUS_PARTIAL) {
2710 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2711 escan_result_le = (struct brcmf_escan_result_le *) data;
2712 if (!escan_result_le) {
2713 brcmf_err("Invalid escan result (NULL pointer)\n");
2716 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2717 brcmf_err("Invalid bss_count %d: ignoring\n",
2718 escan_result_le->bss_count);
2721 bss_info_le = &escan_result_le->bss_info_le;
2723 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2726 if (!cfg->scan_request) {
2727 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2731 bi_length = le32_to_cpu(bss_info_le->length);
2732 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2733 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2734 brcmf_err("Invalid bss_info length %d: ignoring\n",
2739 if (!(cfg_to_wiphy(cfg)->interface_modes &
2740 BIT(NL80211_IFTYPE_ADHOC))) {
2741 if (le16_to_cpu(bss_info_le->capability) &
2742 WLAN_CAPABILITY_IBSS) {
2743 brcmf_err("Ignoring IBSS result\n");
2748 list = (struct brcmf_scan_results *)
2749 cfg->escan_info.escan_buf;
2750 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2751 brcmf_err("Buffer is too small: ignoring\n");
2755 for (i = 0; i < list->count; i++) {
2756 bss = bss ? (struct brcmf_bss_info_le *)
2757 ((unsigned char *)bss +
2758 le32_to_cpu(bss->length)) : list->bss_info_le;
2759 if (brcmf_compare_update_same_bss(cfg, bss,
2763 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2764 bss_info_le, bi_length);
2765 list->version = le32_to_cpu(bss_info_le->version);
2766 list->buflen += bi_length;
2769 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2770 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2772 if (cfg->scan_request) {
2773 cfg->bss_list = (struct brcmf_scan_results *)
2774 cfg->escan_info.escan_buf;
2775 brcmf_inform_bss(cfg);
2776 aborted = status != BRCMF_E_STATUS_SUCCESS;
2777 brcmf_notify_escan_complete(cfg, ifp, aborted,
2780 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2787 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2789 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2790 brcmf_cfg80211_escan_handler);
2791 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2792 /* Init scan_timeout timer */
2793 init_timer(&cfg->escan_timeout);
2794 cfg->escan_timeout.data = (unsigned long) cfg;
2795 cfg->escan_timeout.function = brcmf_escan_timeout;
2796 INIT_WORK(&cfg->escan_timeout_work,
2797 brcmf_cfg80211_escan_timeout_worker);
2800 static __always_inline void brcmf_delay(u32 ms)
2802 if (ms < 1000 / HZ) {
2810 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2812 brcmf_dbg(TRACE, "Enter\n");
2817 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2818 struct cfg80211_wowlan *wow)
2820 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2821 struct net_device *ndev = cfg_to_ndev(cfg);
2822 struct brcmf_cfg80211_vif *vif;
2824 brcmf_dbg(TRACE, "Enter\n");
2827 * if the primary net_device is not READY there is nothing
2828 * we can do but pray resume goes smoothly.
2830 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2831 if (!check_vif_up(vif))
2834 list_for_each_entry(vif, &cfg->vif_list, list) {
2835 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2838 * While going to suspend if associated with AP disassociate
2839 * from AP to save power while system is in suspended state
2841 brcmf_link_down(vif);
2843 /* Make sure WPA_Supplicant receives all the event
2844 * generated due to DISASSOC call to the fw to keep
2845 * the state fw and WPA_Supplicant state consistent
2850 /* end any scanning */
2851 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2852 brcmf_abort_scanning(cfg);
2854 /* Turn off watchdog timer */
2855 brcmf_set_mpc(netdev_priv(ndev), 1);
2858 brcmf_dbg(TRACE, "Exit\n");
2859 /* clear any scanning activity */
2860 cfg->scan_status = 0;
2865 brcmf_update_pmklist(struct net_device *ndev,
2866 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2871 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2873 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2874 for (i = 0; i < pmkid_len; i++) {
2875 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2876 &pmk_list->pmkids.pmkid[i].BSSID);
2877 for (j = 0; j < WLAN_PMKID_LEN; j++)
2878 brcmf_dbg(CONN, "%02x\n",
2879 pmk_list->pmkids.pmkid[i].PMKID[j]);
2883 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2884 (char *)pmk_list, sizeof(*pmk_list));
2890 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2891 struct cfg80211_pmksa *pmksa)
2893 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2894 struct brcmf_if *ifp = netdev_priv(ndev);
2895 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2900 brcmf_dbg(TRACE, "Enter\n");
2901 if (!check_vif_up(ifp->vif))
2904 pmkid_len = le32_to_cpu(pmkids->npmkid);
2905 for (i = 0; i < pmkid_len; i++)
2906 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2908 if (i < WL_NUM_PMKIDS_MAX) {
2909 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2910 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2911 if (i == pmkid_len) {
2913 pmkids->npmkid = cpu_to_le32(pmkid_len);
2918 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2919 pmkids->pmkid[pmkid_len].BSSID);
2920 for (i = 0; i < WLAN_PMKID_LEN; i++)
2921 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2923 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2925 brcmf_dbg(TRACE, "Exit\n");
2930 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2931 struct cfg80211_pmksa *pmksa)
2933 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2934 struct brcmf_if *ifp = netdev_priv(ndev);
2935 struct pmkid_list pmkid;
2939 brcmf_dbg(TRACE, "Enter\n");
2940 if (!check_vif_up(ifp->vif))
2943 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2944 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2946 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2947 &pmkid.pmkid[0].BSSID);
2948 for (i = 0; i < WLAN_PMKID_LEN; i++)
2949 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2951 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2952 for (i = 0; i < pmkid_len; i++)
2954 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2959 && (i < pmkid_len)) {
2960 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2961 sizeof(struct pmkid));
2962 for (; i < (pmkid_len - 1); i++) {
2963 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2964 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2966 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2967 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2970 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2974 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2976 brcmf_dbg(TRACE, "Exit\n");
2982 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2984 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2985 struct brcmf_if *ifp = netdev_priv(ndev);
2988 brcmf_dbg(TRACE, "Enter\n");
2989 if (!check_vif_up(ifp->vif))
2992 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2993 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2995 brcmf_dbg(TRACE, "Exit\n");
3001 * PFN result doesn't have all the info which are
3002 * required by the supplicant
3003 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3004 * via wl_inform_single_bss in the required format. Escan does require the
3005 * scan request in the form of cfg80211_scan_request. For timebeing, create
3006 * cfg80211_scan_request one out of the received PNO event.
3009 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3010 const struct brcmf_event_msg *e, void *data)
3012 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3013 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3014 struct cfg80211_scan_request *request = NULL;
3015 struct cfg80211_ssid *ssid = NULL;
3016 struct ieee80211_channel *channel = NULL;
3017 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3019 int channel_req = 0;
3021 struct brcmf_pno_scanresults_le *pfn_result;
3025 brcmf_dbg(SCAN, "Enter\n");
3027 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3028 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3032 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3033 result_count = le32_to_cpu(pfn_result->count);
3034 status = le32_to_cpu(pfn_result->status);
3037 * PFN event is limited to fit 512 bytes so we may get
3038 * multiple NET_FOUND events. For now place a warning here.
3040 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3041 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3042 if (result_count > 0) {
3045 request = kzalloc(sizeof(*request), GFP_KERNEL);
3046 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3047 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3048 if (!request || !ssid || !channel) {
3053 request->wiphy = wiphy;
3054 data += sizeof(struct brcmf_pno_scanresults_le);
3055 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3057 for (i = 0; i < result_count; i++) {
3058 netinfo = &netinfo_start[i];
3060 brcmf_err("Invalid netinfo ptr. index: %d\n",
3066 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3067 netinfo->SSID, netinfo->channel);
3068 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3069 ssid[i].ssid_len = netinfo->SSID_len;
3072 channel_req = netinfo->channel;
3073 if (channel_req <= CH_MAX_2G_CHANNEL)
3074 band = NL80211_BAND_2GHZ;
3076 band = NL80211_BAND_5GHZ;
3077 channel[i].center_freq =
3078 ieee80211_channel_to_frequency(channel_req,
3080 channel[i].band = band;
3081 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3082 request->channels[i] = &channel[i];
3083 request->n_channels++;
3086 /* assign parsed ssid array */
3087 if (request->n_ssids)
3088 request->ssids = &ssid[0];
3090 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3091 /* Abort any on-going scan */
3092 brcmf_abort_scanning(cfg);
3095 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3096 cfg->escan_info.run = brcmf_run_escan;
3097 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3099 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3102 cfg->sched_escan = true;
3103 cfg->scan_request = request;
3105 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3118 cfg80211_sched_scan_stopped(wiphy);
3122 static int brcmf_dev_pno_clean(struct net_device *ndev)
3127 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3130 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3134 brcmf_err("failed code %d\n", ret);
3139 static int brcmf_dev_pno_config(struct net_device *ndev)
3141 struct brcmf_pno_param_le pfn_param;
3143 memset(&pfn_param, 0, sizeof(pfn_param));
3144 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3146 /* set extra pno params */
3147 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3148 pfn_param.repeat = BRCMF_PNO_REPEAT;
3149 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3151 /* set up pno scan fr */
3152 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3154 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3155 &pfn_param, sizeof(pfn_param));
3159 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3160 struct net_device *ndev,
3161 struct cfg80211_sched_scan_request *request)
3163 struct brcmf_if *ifp = netdev_priv(ndev);
3164 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3165 struct brcmf_pno_net_param_le pfn;
3169 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3170 request->n_match_sets, request->n_ssids);
3171 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3172 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3175 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3176 brcmf_err("Scanning suppressed: status (%lu)\n",
3181 if (!request->n_ssids || !request->n_match_sets) {
3182 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3187 if (request->n_ssids > 0) {
3188 for (i = 0; i < request->n_ssids; i++) {
3189 /* Active scan req for ssids */
3190 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3191 request->ssids[i].ssid);
3194 * match_set ssids is a supert set of n_ssid list,
3195 * so we need not add these set seperately.
3200 if (request->n_match_sets > 0) {
3201 /* clean up everything */
3202 ret = brcmf_dev_pno_clean(ndev);
3204 brcmf_err("failed error=%d\n", ret);
3209 ret = brcmf_dev_pno_config(ndev);
3211 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3215 /* configure each match set */
3216 for (i = 0; i < request->n_match_sets; i++) {
3217 struct cfg80211_ssid *ssid;
3220 ssid = &request->match_sets[i].ssid;
3221 ssid_len = ssid->ssid_len;
3224 brcmf_err("skip broadcast ssid\n");
3227 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3228 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3229 pfn.wsec = cpu_to_le32(0);
3230 pfn.infra = cpu_to_le32(1);
3231 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3232 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3233 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3234 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3236 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3237 ret == 0 ? "set" : "failed", ssid->ssid);
3239 /* Enable the PNO */
3240 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3241 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3251 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3252 struct net_device *ndev)
3254 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3256 brcmf_dbg(SCAN, "enter\n");
3257 brcmf_dev_pno_clean(ndev);
3258 if (cfg->sched_escan)
3259 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3263 #ifdef CONFIG_NL80211_TESTMODE
3264 static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3265 struct wireless_dev *wdev,
3266 void *data, int len)
3268 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3269 struct net_device *ndev = cfg_to_ndev(cfg);
3270 struct brcmf_dcmd *dcmd = data;
3271 struct sk_buff *reply;
3274 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3275 dcmd->buf, dcmd->len);
3278 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3279 dcmd->buf, dcmd->len);
3281 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3282 dcmd->buf, dcmd->len);
3284 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3285 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3286 ret = cfg80211_testmode_reply(reply);
3292 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3297 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3299 brcmf_err("auth error %d\n", err);
3303 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3305 brcmf_err("wsec error %d\n", err);
3308 /* set upper-layer auth */
3309 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3311 brcmf_err("wpa_auth error %d\n", err);
3318 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3321 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3323 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3327 brcmf_configure_wpaie(struct net_device *ndev,
3328 const struct brcmf_vs_tlv *wpa_ie,
3331 struct brcmf_if *ifp = netdev_priv(ndev);
3332 u32 auth = 0; /* d11 open authentication */
3344 u32 wme_bss_disable;
3346 brcmf_dbg(TRACE, "Enter\n");
3350 len = wpa_ie->len + TLV_HDR_LEN;
3351 data = (u8 *)wpa_ie;
3352 offset = TLV_HDR_LEN;
3354 offset += VS_IE_FIXED_HDR_LEN;
3356 offset += WPA_IE_VERSION_LEN;
3358 /* check for multicast cipher suite */
3359 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3361 brcmf_err("no multicast cipher suite\n");
3365 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3367 brcmf_err("ivalid OUI\n");
3370 offset += TLV_OUI_LEN;
3372 /* pick up multicast cipher */
3373 switch (data[offset]) {
3374 case WPA_CIPHER_NONE:
3377 case WPA_CIPHER_WEP_40:
3378 case WPA_CIPHER_WEP_104:
3381 case WPA_CIPHER_TKIP:
3382 gval = TKIP_ENABLED;
3384 case WPA_CIPHER_AES_CCM:
3389 brcmf_err("Invalid multi cast cipher info\n");
3394 /* walk thru unicast cipher list and pick up what we recognize */
3395 count = data[offset] + (data[offset + 1] << 8);
3396 offset += WPA_IE_SUITE_COUNT_LEN;
3397 /* Check for unicast suite(s) */
3398 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3400 brcmf_err("no unicast cipher suite\n");
3403 for (i = 0; i < count; i++) {
3404 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3406 brcmf_err("ivalid OUI\n");
3409 offset += TLV_OUI_LEN;
3410 switch (data[offset]) {
3411 case WPA_CIPHER_NONE:
3413 case WPA_CIPHER_WEP_40:
3414 case WPA_CIPHER_WEP_104:
3415 pval |= WEP_ENABLED;
3417 case WPA_CIPHER_TKIP:
3418 pval |= TKIP_ENABLED;
3420 case WPA_CIPHER_AES_CCM:
3421 pval |= AES_ENABLED;
3424 brcmf_err("Ivalid unicast security info\n");
3428 /* walk thru auth management suite list and pick up what we recognize */
3429 count = data[offset] + (data[offset + 1] << 8);
3430 offset += WPA_IE_SUITE_COUNT_LEN;
3431 /* Check for auth key management suite(s) */
3432 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3434 brcmf_err("no auth key mgmt suite\n");
3437 for (i = 0; i < count; i++) {
3438 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3440 brcmf_err("ivalid OUI\n");
3443 offset += TLV_OUI_LEN;
3444 switch (data[offset]) {
3446 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3447 wpa_auth |= WPA_AUTH_NONE;
3449 case RSN_AKM_UNSPECIFIED:
3450 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3451 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3452 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3455 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3456 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3457 (wpa_auth |= WPA_AUTH_PSK);
3460 brcmf_err("Ivalid key mgmt info\n");
3466 wme_bss_disable = 1;
3467 if ((offset + RSN_CAP_LEN) <= len) {
3468 rsn_cap = data[offset] + (data[offset + 1] << 8);
3469 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3470 wme_bss_disable = 0;
3472 /* set wme_bss_disable to sync RSN Capabilities */
3473 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3476 brcmf_err("wme_bss_disable error %d\n", err);
3480 /* FOR WPS , set SES_OW_ENABLED */
3481 wsec = (pval | gval | SES_OW_ENABLED);
3484 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3486 brcmf_err("auth error %d\n", err);
3490 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3492 brcmf_err("wsec error %d\n", err);
3495 /* set upper-layer auth */
3496 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3498 brcmf_err("wpa_auth error %d\n", err);
3507 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3508 struct parsed_vndr_ies *vndr_ies)
3511 struct brcmf_vs_tlv *vndrie;
3512 struct brcmf_tlv *ie;
3513 struct parsed_vndr_ie_info *parsed_info;
3516 remaining_len = (s32)vndr_ie_len;
3517 memset(vndr_ies, 0, sizeof(*vndr_ies));
3519 ie = (struct brcmf_tlv *)vndr_ie_buf;
3521 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3523 vndrie = (struct brcmf_vs_tlv *)ie;
3524 /* len should be bigger than OUI length + one */
3525 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3526 brcmf_err("invalid vndr ie. length is too small %d\n",
3530 /* if wpa or wme ie, do not add ie */
3531 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3532 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3533 (vndrie->oui_type == WME_OUI_TYPE))) {
3534 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3538 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3540 /* save vndr ie information */
3541 parsed_info->ie_ptr = (char *)vndrie;
3542 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3543 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3547 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3548 parsed_info->vndrie.oui[0],
3549 parsed_info->vndrie.oui[1],
3550 parsed_info->vndrie.oui[2],
3551 parsed_info->vndrie.oui_type);
3553 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3556 remaining_len -= (ie->len + TLV_HDR_LEN);
3557 if (remaining_len <= TLV_HDR_LEN)
3560 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3567 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3573 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3574 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3576 iecount_le = cpu_to_le32(1);
3577 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3579 pktflag_le = cpu_to_le32(pktflag);
3580 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3582 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3584 return ie_len + VNDR_IE_HDR_SIZE;
3587 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3588 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3590 struct brcmf_if *ifp;
3591 struct vif_saved_ie *saved_ie;
3595 u8 *mgmt_ie_buf = NULL;
3596 int mgmt_ie_buf_len;
3598 u32 del_add_ie_buf_len = 0;
3599 u32 total_ie_buf_len = 0;
3600 u32 parsed_ie_buf_len = 0;
3601 struct parsed_vndr_ies old_vndr_ies;
3602 struct parsed_vndr_ies new_vndr_ies;
3603 struct parsed_vndr_ie_info *vndrie_info;
3606 int remained_buf_len;
3611 saved_ie = &vif->saved_ie;
3613 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3614 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3617 curr_ie_buf = iovar_ie_buf;
3619 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3620 mgmt_ie_buf = saved_ie->probe_req_ie;
3621 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3622 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3624 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3625 mgmt_ie_buf = saved_ie->probe_res_ie;
3626 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3627 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3629 case BRCMF_VNDR_IE_BEACON_FLAG:
3630 mgmt_ie_buf = saved_ie->beacon_ie;
3631 mgmt_ie_len = &saved_ie->beacon_ie_len;
3632 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3634 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3635 mgmt_ie_buf = saved_ie->assoc_req_ie;
3636 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3637 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3641 brcmf_err("not suitable type\n");
3645 if (vndr_ie_len > mgmt_ie_buf_len) {
3647 brcmf_err("extra IE size too big\n");
3651 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3652 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3654 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3655 for (i = 0; i < new_vndr_ies.count; i++) {
3656 vndrie_info = &new_vndr_ies.ie_info[i];
3657 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3658 vndrie_info->ie_len);
3659 parsed_ie_buf_len += vndrie_info->ie_len;
3663 if (mgmt_ie_buf && *mgmt_ie_len) {
3664 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3665 (memcmp(mgmt_ie_buf, curr_ie_buf,
3666 parsed_ie_buf_len) == 0)) {
3667 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3671 /* parse old vndr_ie */
3672 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3674 /* make a command to delete old ie */
3675 for (i = 0; i < old_vndr_ies.count; i++) {
3676 vndrie_info = &old_vndr_ies.ie_info[i];
3678 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3679 vndrie_info->vndrie.id,
3680 vndrie_info->vndrie.len,
3681 vndrie_info->vndrie.oui[0],
3682 vndrie_info->vndrie.oui[1],
3683 vndrie_info->vndrie.oui[2]);
3685 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3686 vndrie_info->ie_ptr,
3687 vndrie_info->ie_len,
3689 curr_ie_buf += del_add_ie_buf_len;
3690 total_ie_buf_len += del_add_ie_buf_len;
3695 /* Add if there is any extra IE */
3696 if (mgmt_ie_buf && parsed_ie_buf_len) {
3699 remained_buf_len = mgmt_ie_buf_len;
3701 /* make a command to add new ie */
3702 for (i = 0; i < new_vndr_ies.count; i++) {
3703 vndrie_info = &new_vndr_ies.ie_info[i];
3705 /* verify remained buf size before copy data */
3706 if (remained_buf_len < (vndrie_info->vndrie.len +
3707 VNDR_IE_VSIE_OFFSET)) {
3708 brcmf_err("no space in mgmt_ie_buf: len left %d",
3712 remained_buf_len -= (vndrie_info->ie_len +
3713 VNDR_IE_VSIE_OFFSET);
3715 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3716 vndrie_info->vndrie.id,
3717 vndrie_info->vndrie.len,
3718 vndrie_info->vndrie.oui[0],
3719 vndrie_info->vndrie.oui[1],
3720 vndrie_info->vndrie.oui[2]);
3722 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3723 vndrie_info->ie_ptr,
3724 vndrie_info->ie_len,
3727 /* save the parsed IE in wl struct */
3728 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3729 vndrie_info->ie_len);
3730 *mgmt_ie_len += vndrie_info->ie_len;
3732 curr_ie_buf += del_add_ie_buf_len;
3733 total_ie_buf_len += del_add_ie_buf_len;
3736 if (total_ie_buf_len) {
3737 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3740 brcmf_err("vndr ie set error : %d\n", err);
3744 kfree(iovar_ie_buf);
3748 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3751 BRCMF_VNDR_IE_PRBREQ_FLAG,
3752 BRCMF_VNDR_IE_PRBRSP_FLAG,
3753 BRCMF_VNDR_IE_BEACON_FLAG
3757 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3758 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3760 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3765 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3766 struct cfg80211_beacon_data *beacon)
3770 /* Set Beacon IEs to FW */
3771 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3772 beacon->tail, beacon->tail_len);
3774 brcmf_err("Set Beacon IE Failed\n");
3777 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3779 /* Set Probe Response IEs to FW */
3780 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3781 beacon->proberesp_ies,
3782 beacon->proberesp_ies_len);
3784 brcmf_err("Set Probe Resp IE Failed\n");
3786 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3792 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3793 struct cfg80211_ap_settings *settings)
3796 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3797 struct brcmf_if *ifp = netdev_priv(ndev);
3798 const struct brcmf_tlv *ssid_ie;
3799 struct brcmf_ssid_le ssid_le;
3801 const struct brcmf_tlv *rsn_ie;
3802 const struct brcmf_vs_tlv *wpa_ie;
3803 struct brcmf_join_params join_params;
3804 enum nl80211_iftype dev_role;
3805 struct brcmf_fil_bss_enable_le bss_enable;
3808 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3809 settings->chandef.chan->hw_value,
3810 settings->chandef.center_freq1, settings->chandef.width,
3811 settings->beacon_interval, settings->dtim_period);
3812 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3813 settings->ssid, settings->ssid_len, settings->auth_type,
3814 settings->inactivity_timeout);
3816 dev_role = ifp->vif->wdev.iftype;
3818 memset(&ssid_le, 0, sizeof(ssid_le));
3819 if (settings->ssid == NULL || settings->ssid_len == 0) {
3820 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3821 ssid_ie = brcmf_parse_tlvs(
3822 (u8 *)&settings->beacon.head[ie_offset],
3823 settings->beacon.head_len - ie_offset,
3828 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3829 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3830 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3832 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3833 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3836 brcmf_set_mpc(ifp, 0);
3837 brcmf_configure_arp_offload(ifp, false);
3839 /* find the RSN_IE */
3840 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3841 settings->beacon.tail_len, WLAN_EID_RSN);
3843 /* find the WPA_IE */
3844 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3845 settings->beacon.tail_len);
3847 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3848 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3849 if (wpa_ie != NULL) {
3851 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3856 err = brcmf_configure_wpaie(ndev,
3857 (struct brcmf_vs_tlv *)rsn_ie, true);
3862 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3863 brcmf_configure_opensecurity(ifp);
3866 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3868 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
3869 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3871 brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
3875 if (settings->beacon_interval) {
3876 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3877 settings->beacon_interval);
3879 brcmf_err("Beacon Interval Set Error, %d\n", err);
3883 if (settings->dtim_period) {
3884 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3885 settings->dtim_period);
3887 brcmf_err("DTIM Interval Set Error, %d\n", err);
3892 if (dev_role == NL80211_IFTYPE_AP) {
3893 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3895 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3898 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3901 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3903 brcmf_err("SET INFRA error %d\n", err);
3906 if (dev_role == NL80211_IFTYPE_AP) {
3907 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3909 brcmf_err("setting AP mode failed %d\n", err);
3912 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3914 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3918 memset(&join_params, 0, sizeof(join_params));
3919 /* join parameters starts with ssid */
3920 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3922 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3923 &join_params, sizeof(join_params));
3925 brcmf_err("SET SSID error (%d)\n", err);
3928 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3930 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3933 brcmf_err("setting ssid failed %d\n", err);
3936 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3937 bss_enable.enable = cpu_to_le32(1);
3938 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3939 sizeof(bss_enable));
3941 brcmf_err("bss_enable config failed %d\n", err);
3945 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3947 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3948 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3952 brcmf_set_mpc(ifp, 1);
3953 brcmf_configure_arp_offload(ifp, true);
3958 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3960 struct brcmf_if *ifp = netdev_priv(ndev);
3962 struct brcmf_fil_bss_enable_le bss_enable;
3963 struct brcmf_join_params join_params;
3965 brcmf_dbg(TRACE, "Enter\n");
3967 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3968 /* Due to most likely deauths outstanding we sleep */
3969 /* first to make sure they get processed by fw. */
3972 memset(&join_params, 0, sizeof(join_params));
3973 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3974 &join_params, sizeof(join_params));
3976 brcmf_err("SET SSID error (%d)\n", err);
3977 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3979 brcmf_err("BRCMF_C_UP error %d\n", err);
3980 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3982 brcmf_err("setting AP mode failed %d\n", err);
3983 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3985 brcmf_err("setting INFRA mode failed %d\n", err);
3987 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3988 bss_enable.enable = cpu_to_le32(0);
3989 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3990 sizeof(bss_enable));
3992 brcmf_err("bss_enable config failed %d\n", err);
3994 brcmf_set_mpc(ifp, 1);
3995 brcmf_configure_arp_offload(ifp, true);
3996 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3997 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4003 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4004 struct cfg80211_beacon_data *info)
4006 struct brcmf_if *ifp = netdev_priv(ndev);
4009 brcmf_dbg(TRACE, "Enter\n");
4011 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4017 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4020 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4021 struct brcmf_scb_val_le scbval;
4022 struct brcmf_if *ifp = netdev_priv(ndev);
4028 brcmf_dbg(TRACE, "Enter %pM\n", mac);
4030 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4031 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4032 if (!check_vif_up(ifp->vif))
4035 memcpy(&scbval.ea, mac, ETH_ALEN);
4036 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4037 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4038 &scbval, sizeof(scbval));
4040 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4042 brcmf_dbg(TRACE, "Exit\n");
4048 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4049 struct wireless_dev *wdev,
4050 u16 frame_type, bool reg)
4052 struct brcmf_cfg80211_vif *vif;
4055 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4057 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4058 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4060 vif->mgmt_rx_reg |= BIT(mgmt_type);
4062 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4067 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4068 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4070 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4071 struct ieee80211_channel *chan = params->chan;
4072 const u8 *buf = params->buf;
4073 size_t len = params->len;
4074 const struct ieee80211_mgmt *mgmt;
4075 struct brcmf_cfg80211_vif *vif;
4079 struct brcmf_fil_action_frame_le *action_frame;
4080 struct brcmf_fil_af_params_le *af_params;
4085 brcmf_dbg(TRACE, "Enter\n");
4089 mgmt = (const struct ieee80211_mgmt *)buf;
4091 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4092 brcmf_err("Driver only allows MGMT packet type\n");
4096 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4098 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4099 /* Right now the only reason to get a probe response */
4100 /* is for p2p listen response or for p2p GO from */
4101 /* wpa_supplicant. Unfortunately the probe is send */
4102 /* on primary ndev, while dongle wants it on the p2p */
4103 /* vif. Since this is only reason for a probe */
4104 /* response to be sent, the vif is taken from cfg. */
4105 /* If ever desired to send proberesp for non p2p */
4106 /* response then data should be checked for */
4107 /* "DIRECT-". Note in future supplicant will take */
4108 /* dedicated p2p wdev to do this and then this 'hack'*/
4109 /* is not needed anymore. */
4110 ie_offset = DOT11_MGMT_HDR_LEN +
4111 DOT11_BCN_PRB_FIXED_LEN;
4112 ie_len = len - ie_offset;
4113 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4114 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4115 err = brcmf_vif_set_mgmt_ie(vif,
4116 BRCMF_VNDR_IE_PRBRSP_FLAG,
4119 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4121 } else if (ieee80211_is_action(mgmt->frame_control)) {
4122 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4123 if (af_params == NULL) {
4124 brcmf_err("unable to allocate frame\n");
4128 action_frame = &af_params->action_frame;
4129 /* Add the packet Id */
4130 action_frame->packet_id = cpu_to_le32(*cookie);
4132 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4133 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4134 /* Add the length exepted for 802.11 header */
4135 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4136 /* Add the channel. Use the one specified as parameter if any or
4137 * the current one (got from the firmware) otherwise
4140 freq = chan->center_freq;
4142 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4144 chan_nr = ieee80211_frequency_to_channel(freq);
4145 af_params->channel = cpu_to_le32(chan_nr);
4147 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4148 le16_to_cpu(action_frame->len));
4150 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4151 *cookie, le16_to_cpu(action_frame->len), freq);
4153 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4156 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4160 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4161 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4170 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4171 struct wireless_dev *wdev,
4174 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4175 struct brcmf_cfg80211_vif *vif;
4178 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4180 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4182 brcmf_err("No p2p device available for probe response\n");
4186 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4191 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4192 struct wireless_dev *wdev,
4193 enum nl80211_crit_proto_id proto,
4196 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4197 struct brcmf_cfg80211_vif *vif;
4199 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4201 /* only DHCP support for now */
4202 if (proto != NL80211_CRIT_PROTO_DHCP)
4205 /* suppress and abort scanning */
4206 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4207 brcmf_abort_scanning(cfg);
4209 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4212 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4213 struct wireless_dev *wdev)
4215 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4216 struct brcmf_cfg80211_vif *vif;
4218 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4220 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4221 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4224 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4229 case NL80211_TDLS_DISCOVERY_REQ:
4230 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4232 case NL80211_TDLS_SETUP:
4233 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4235 case NL80211_TDLS_TEARDOWN:
4236 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4239 brcmf_err("unsupported operation: %d\n", oper);
4245 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4246 struct net_device *ndev, const u8 *peer,
4247 enum nl80211_tdls_operation oper)
4249 struct brcmf_if *ifp;
4250 struct brcmf_tdls_iovar_le info;
4253 ret = brcmf_convert_nl80211_tdls_oper(oper);
4257 ifp = netdev_priv(ndev);
4258 memset(&info, 0, sizeof(info));
4259 info.mode = (u8)ret;
4261 memcpy(info.ea, peer, ETH_ALEN);
4263 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4264 &info, sizeof(info));
4266 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4271 static struct cfg80211_ops wl_cfg80211_ops = {
4272 .add_virtual_intf = brcmf_cfg80211_add_iface,
4273 .del_virtual_intf = brcmf_cfg80211_del_iface,
4274 .change_virtual_intf = brcmf_cfg80211_change_iface,
4275 .scan = brcmf_cfg80211_scan,
4276 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4277 .join_ibss = brcmf_cfg80211_join_ibss,
4278 .leave_ibss = brcmf_cfg80211_leave_ibss,
4279 .get_station = brcmf_cfg80211_get_station,
4280 .set_tx_power = brcmf_cfg80211_set_tx_power,
4281 .get_tx_power = brcmf_cfg80211_get_tx_power,
4282 .add_key = brcmf_cfg80211_add_key,
4283 .del_key = brcmf_cfg80211_del_key,
4284 .get_key = brcmf_cfg80211_get_key,
4285 .set_default_key = brcmf_cfg80211_config_default_key,
4286 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4287 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4288 .connect = brcmf_cfg80211_connect,
4289 .disconnect = brcmf_cfg80211_disconnect,
4290 .suspend = brcmf_cfg80211_suspend,
4291 .resume = brcmf_cfg80211_resume,
4292 .set_pmksa = brcmf_cfg80211_set_pmksa,
4293 .del_pmksa = brcmf_cfg80211_del_pmksa,
4294 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4295 .start_ap = brcmf_cfg80211_start_ap,
4296 .stop_ap = brcmf_cfg80211_stop_ap,
4297 .change_beacon = brcmf_cfg80211_change_beacon,
4298 .del_station = brcmf_cfg80211_del_station,
4299 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4300 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4301 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4302 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4303 .remain_on_channel = brcmf_p2p_remain_on_channel,
4304 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4305 .start_p2p_device = brcmf_p2p_start_device,
4306 .stop_p2p_device = brcmf_p2p_stop_device,
4307 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4308 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4309 .tdls_oper = brcmf_cfg80211_tdls_oper,
4310 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4313 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4315 /* scheduled scan settings */
4316 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4317 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4318 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4319 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4322 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4325 .types = BIT(NL80211_IFTYPE_STATION) |
4326 BIT(NL80211_IFTYPE_ADHOC) |
4327 BIT(NL80211_IFTYPE_AP)
4331 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4332 BIT(NL80211_IFTYPE_P2P_GO)
4336 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4339 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4341 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4342 .num_different_channels = 2,
4343 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4344 .limits = brcmf_iface_limits
4348 static const struct ieee80211_txrx_stypes
4349 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4350 [NL80211_IFTYPE_STATION] = {
4352 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4353 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4355 [NL80211_IFTYPE_P2P_CLIENT] = {
4357 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4358 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4360 [NL80211_IFTYPE_P2P_GO] = {
4362 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4363 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4364 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4365 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4366 BIT(IEEE80211_STYPE_AUTH >> 4) |
4367 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4368 BIT(IEEE80211_STYPE_ACTION >> 4)
4370 [NL80211_IFTYPE_P2P_DEVICE] = {
4372 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4373 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4377 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4379 struct wiphy *wiphy;
4382 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4384 brcmf_err("Could not allocate wiphy device\n");
4385 return ERR_PTR(-ENOMEM);
4387 set_wiphy_dev(wiphy, phydev);
4388 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4389 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4390 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4391 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4392 BIT(NL80211_IFTYPE_ADHOC) |
4393 BIT(NL80211_IFTYPE_AP) |
4394 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4395 BIT(NL80211_IFTYPE_P2P_GO) |
4396 BIT(NL80211_IFTYPE_P2P_DEVICE);
4397 wiphy->iface_combinations = brcmf_iface_combos;
4398 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4399 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4400 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4401 wiphy->cipher_suites = __wl_cipher_suites;
4402 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4403 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4404 WIPHY_FLAG_OFFCHAN_TX |
4405 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4406 WIPHY_FLAG_SUPPORTS_TDLS;
4408 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4409 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4410 wiphy->max_remain_on_channel_duration = 5000;
4411 brcmf_wiphy_pno_params(wiphy);
4412 brcmf_dbg(INFO, "Registering custom regulatory\n");
4413 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4414 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4415 err = wiphy_register(wiphy);
4417 brcmf_err("Could not register wiphy device (%d)\n", err);
4419 return ERR_PTR(err);
4424 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4425 enum nl80211_iftype type,
4428 struct brcmf_cfg80211_vif *vif;
4430 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4432 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4434 return ERR_PTR(-ENOMEM);
4436 vif->wdev.wiphy = cfg->wiphy;
4437 vif->wdev.iftype = type;
4439 vif->pm_block = pm_block;
4442 brcmf_init_prof(&vif->profile);
4444 list_add_tail(&vif->list, &cfg->vif_list);
4448 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4450 list_del(&vif->list);
4454 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4456 struct brcmf_cfg80211_vif *vif;
4457 struct brcmf_if *ifp;
4459 ifp = netdev_priv(ndev);
4462 brcmf_free_vif(vif);
4466 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4468 u32 event = e->event_code;
4469 u32 status = e->status;
4471 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4472 brcmf_dbg(CONN, "Processing set ssid\n");
4479 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4481 u32 event = e->event_code;
4482 u16 flags = e->flags;
4484 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4485 (event == BRCMF_E_DISASSOC_IND) ||
4486 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4487 brcmf_dbg(CONN, "Processing link down\n");
4493 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4494 const struct brcmf_event_msg *e)
4496 u32 event = e->event_code;
4497 u32 status = e->status;
4499 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4500 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4501 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4505 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4506 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4513 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4515 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4517 kfree(conn_info->req_ie);
4518 conn_info->req_ie = NULL;
4519 conn_info->req_ie_len = 0;
4520 kfree(conn_info->resp_ie);
4521 conn_info->resp_ie = NULL;
4522 conn_info->resp_ie_len = 0;
4525 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4526 struct brcmf_if *ifp)
4528 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4529 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4534 brcmf_clear_assoc_ies(cfg);
4536 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4537 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4539 brcmf_err("could not get assoc info (%d)\n", err);
4543 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4544 req_len = le32_to_cpu(assoc_info->req_len);
4545 resp_len = le32_to_cpu(assoc_info->resp_len);
4547 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4551 brcmf_err("could not get assoc req (%d)\n", err);
4554 conn_info->req_ie_len = req_len;
4556 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4559 conn_info->req_ie_len = 0;
4560 conn_info->req_ie = NULL;
4563 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4567 brcmf_err("could not get assoc resp (%d)\n", err);
4570 conn_info->resp_ie_len = resp_len;
4571 conn_info->resp_ie =
4572 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4575 conn_info->resp_ie_len = 0;
4576 conn_info->resp_ie = NULL;
4578 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4579 conn_info->req_ie_len, conn_info->resp_ie_len);
4585 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4586 struct net_device *ndev,
4587 const struct brcmf_event_msg *e)
4589 struct brcmf_if *ifp = netdev_priv(ndev);
4590 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4591 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4592 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4593 struct ieee80211_channel *notify_channel = NULL;
4594 struct ieee80211_supported_band *band;
4595 struct brcmf_bss_info_le *bi;
4596 struct brcmu_chan ch;
4601 brcmf_dbg(TRACE, "Enter\n");
4603 brcmf_get_assoc_ies(cfg, ifp);
4604 memcpy(profile->bssid, e->addr, ETH_ALEN);
4605 brcmf_update_bss_info(cfg, ifp);
4607 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4613 /* data sent to dongle has to be little endian */
4614 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4615 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4616 buf, WL_BSS_INFO_MAX);
4621 bi = (struct brcmf_bss_info_le *)(buf + 4);
4622 ch.chspec = le16_to_cpu(bi->chanspec);
4623 cfg->d11inf.decchspec(&ch);
4625 if (ch.band == BRCMU_CHAN_BAND_2G)
4626 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4628 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4630 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4631 notify_channel = ieee80211_get_channel(wiphy, freq);
4635 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4636 conn_info->req_ie, conn_info->req_ie_len,
4637 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4638 brcmf_dbg(CONN, "Report roaming result\n");
4640 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4641 brcmf_dbg(TRACE, "Exit\n");
4646 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4647 struct net_device *ndev, const struct brcmf_event_msg *e,
4650 struct brcmf_if *ifp = netdev_priv(ndev);
4651 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4655 brcmf_dbg(TRACE, "Enter\n");
4657 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4658 &ifp->vif->sme_state)) {
4660 brcmf_get_assoc_ies(cfg, ifp);
4661 memcpy(profile->bssid, e->addr, ETH_ALEN);
4662 brcmf_update_bss_info(cfg, ifp);
4663 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4664 &ifp->vif->sme_state);
4666 cfg80211_connect_result(ndev,
4667 (u8 *)profile->bssid,
4669 conn_info->req_ie_len,
4671 conn_info->resp_ie_len,
4672 completed ? WLAN_STATUS_SUCCESS :
4673 WLAN_STATUS_AUTH_TIMEOUT,
4675 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4676 completed ? "succeeded" : "failed");
4678 brcmf_dbg(TRACE, "Exit\n");
4683 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4684 struct net_device *ndev,
4685 const struct brcmf_event_msg *e, void *data)
4687 static int generation;
4688 u32 event = e->event_code;
4689 u32 reason = e->reason;
4690 struct station_info sinfo;
4692 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4693 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4694 ndev != cfg_to_ndev(cfg)) {
4695 brcmf_dbg(CONN, "AP mode link down\n");
4696 complete(&cfg->vif_disabled);
4700 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4701 (reason == BRCMF_E_STATUS_SUCCESS)) {
4702 memset(&sinfo, 0, sizeof(sinfo));
4703 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4705 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4708 sinfo.assoc_req_ies = data;
4709 sinfo.assoc_req_ies_len = e->datalen;
4711 sinfo.generation = generation;
4712 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4713 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4714 (event == BRCMF_E_DEAUTH_IND) ||
4715 (event == BRCMF_E_DEAUTH)) {
4716 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4722 brcmf_notify_connect_status(struct brcmf_if *ifp,
4723 const struct brcmf_event_msg *e, void *data)
4725 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4726 struct net_device *ndev = ifp->ndev;
4727 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4728 struct ieee80211_channel *chan;
4731 if (brcmf_is_apmode(ifp->vif)) {
4732 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4733 } else if (brcmf_is_linkup(e)) {
4734 brcmf_dbg(CONN, "Linkup\n");
4735 if (brcmf_is_ibssmode(ifp->vif)) {
4736 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4737 memcpy(profile->bssid, e->addr, ETH_ALEN);
4738 wl_inform_ibss(cfg, ndev, e->addr);
4739 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4740 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4741 &ifp->vif->sme_state);
4742 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4743 &ifp->vif->sme_state);
4745 brcmf_bss_connect_done(cfg, ndev, e, true);
4746 } else if (brcmf_is_linkdown(e)) {
4747 brcmf_dbg(CONN, "Linkdown\n");
4748 if (!brcmf_is_ibssmode(ifp->vif)) {
4749 brcmf_bss_connect_done(cfg, ndev, e, false);
4751 brcmf_link_down(ifp->vif);
4752 brcmf_init_prof(ndev_to_prof(ndev));
4753 if (ndev != cfg_to_ndev(cfg))
4754 complete(&cfg->vif_disabled);
4755 } else if (brcmf_is_nonetwork(cfg, e)) {
4756 if (brcmf_is_ibssmode(ifp->vif))
4757 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4758 &ifp->vif->sme_state);
4760 brcmf_bss_connect_done(cfg, ndev, e, false);
4767 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4768 const struct brcmf_event_msg *e, void *data)
4770 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4772 u32 event = e->event_code;
4773 u32 status = e->status;
4775 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4776 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4777 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4779 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4786 brcmf_notify_mic_status(struct brcmf_if *ifp,
4787 const struct brcmf_event_msg *e, void *data)
4789 u16 flags = e->flags;
4790 enum nl80211_key_type key_type;
4792 if (flags & BRCMF_EVENT_MSG_GROUP)
4793 key_type = NL80211_KEYTYPE_GROUP;
4795 key_type = NL80211_KEYTYPE_PAIRWISE;
4797 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4803 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4804 const struct brcmf_event_msg *e, void *data)
4806 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4807 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4808 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4809 struct brcmf_cfg80211_vif *vif;
4811 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4812 ifevent->action, ifevent->flags, ifevent->ifidx,
4815 mutex_lock(&event->vif_event_lock);
4816 event->action = ifevent->action;
4819 switch (ifevent->action) {
4820 case BRCMF_E_IF_ADD:
4821 /* waiting process may have timed out */
4822 if (!cfg->vif_event.vif) {
4823 mutex_unlock(&event->vif_event_lock);
4830 vif->wdev.netdev = ifp->ndev;
4831 ifp->ndev->ieee80211_ptr = &vif->wdev;
4832 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4834 mutex_unlock(&event->vif_event_lock);
4835 wake_up(&event->vif_wq);
4838 case BRCMF_E_IF_DEL:
4839 mutex_unlock(&event->vif_event_lock);
4840 /* event may not be upon user request */
4841 if (brcmf_cfg80211_vif_event_armed(cfg))
4842 wake_up(&event->vif_wq);
4845 case BRCMF_E_IF_CHANGE:
4846 mutex_unlock(&event->vif_event_lock);
4847 wake_up(&event->vif_wq);
4851 mutex_unlock(&event->vif_event_lock);
4857 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4859 conf->frag_threshold = (u32)-1;
4860 conf->rts_threshold = (u32)-1;
4861 conf->retry_short = (u32)-1;
4862 conf->retry_long = (u32)-1;
4863 conf->tx_power = -1;
4866 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4868 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4869 brcmf_notify_connect_status);
4870 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4871 brcmf_notify_connect_status);
4872 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4873 brcmf_notify_connect_status);
4874 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4875 brcmf_notify_connect_status);
4876 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4877 brcmf_notify_connect_status);
4878 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4879 brcmf_notify_connect_status);
4880 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4881 brcmf_notify_roaming_status);
4882 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4883 brcmf_notify_mic_status);
4884 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4885 brcmf_notify_connect_status);
4886 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4887 brcmf_notify_sched_scan_results);
4888 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4889 brcmf_notify_vif_event);
4890 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4891 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4892 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4893 brcmf_p2p_notify_listen_complete);
4894 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4895 brcmf_p2p_notify_action_frame_rx);
4896 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4897 brcmf_p2p_notify_action_tx_complete);
4898 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4899 brcmf_p2p_notify_action_tx_complete);
4902 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4906 kfree(cfg->escan_ioctl_buf);
4907 cfg->escan_ioctl_buf = NULL;
4908 kfree(cfg->extra_buf);
4909 cfg->extra_buf = NULL;
4910 kfree(cfg->pmk_list);
4911 cfg->pmk_list = NULL;
4914 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4916 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4918 goto init_priv_mem_out;
4919 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4920 if (!cfg->escan_ioctl_buf)
4921 goto init_priv_mem_out;
4922 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4923 if (!cfg->extra_buf)
4924 goto init_priv_mem_out;
4925 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4927 goto init_priv_mem_out;
4932 brcmf_deinit_priv_mem(cfg);
4937 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4941 cfg->scan_request = NULL;
4942 cfg->pwr_save = true;
4943 cfg->active_scan = true; /* we do active scan per default */
4944 cfg->dongle_up = false; /* dongle is not up yet */
4945 err = brcmf_init_priv_mem(cfg);
4948 brcmf_register_event_handlers(cfg);
4949 mutex_init(&cfg->usr_sync);
4950 brcmf_init_escan(cfg);
4951 brcmf_init_conf(cfg->conf);
4952 init_completion(&cfg->vif_disabled);
4956 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4958 cfg->dongle_up = false; /* dongle down */
4959 brcmf_abort_scanning(cfg);
4960 brcmf_deinit_priv_mem(cfg);
4963 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4965 init_waitqueue_head(&event->vif_wq);
4966 mutex_init(&event->vif_event_lock);
4969 static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4971 struct brcmf_fil_bwcap_le band_bwcap;
4975 /* verify support for bw_cap command */
4977 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
4980 /* only set 2G bandwidth using bw_cap command */
4981 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4982 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
4983 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4984 sizeof(band_bwcap));
4986 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
4987 val = WLC_N_BW_40ALL;
4988 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
4993 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4994 struct device *busdev)
4996 struct net_device *ndev = drvr->iflist[0]->ndev;
4997 struct brcmf_cfg80211_info *cfg;
4998 struct wiphy *wiphy;
4999 struct brcmf_cfg80211_vif *vif;
5000 struct brcmf_if *ifp;
5005 brcmf_err("ndev is invalid\n");
5009 ifp = netdev_priv(ndev);
5010 wiphy = brcmf_setup_wiphy(busdev);
5014 cfg = wiphy_priv(wiphy);
5017 init_vif_event(&cfg->vif_event);
5018 INIT_LIST_HEAD(&cfg->vif_list);
5020 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
5027 vif->wdev.netdev = ndev;
5028 ndev->ieee80211_ptr = &vif->wdev;
5029 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5031 err = wl_init_priv(cfg);
5033 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5034 goto cfg80211_attach_out;
5038 err = brcmf_p2p_attach(cfg);
5040 brcmf_err("P2P initilisation failed (%d)\n", err);
5041 goto cfg80211_p2p_attach_out;
5043 err = brcmf_btcoex_attach(cfg);
5045 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5046 brcmf_p2p_detach(&cfg->p2p);
5047 goto cfg80211_p2p_attach_out;
5050 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5051 * setup 40MHz in 2GHz band and enable OBSS scanning.
5053 if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
5054 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
5055 err = brcmf_enable_bw40_2g(ifp);
5057 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5058 BRCMF_OBSS_COEX_AUTO);
5061 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5063 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5064 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5067 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
5070 brcmf_err("Failed to get D11 version (%d)\n", err);
5071 goto cfg80211_p2p_attach_out;
5073 cfg->d11inf.io_type = (u8)io_type;
5074 brcmu_d11_attach(&cfg->d11inf);
5078 cfg80211_p2p_attach_out:
5079 wl_deinit_priv(cfg);
5081 cfg80211_attach_out:
5082 brcmf_free_vif(vif);
5086 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5091 WARN_ON(!list_empty(&cfg->vif_list));
5092 wiphy_unregister(cfg->wiphy);
5093 brcmf_btcoex_detach(cfg);
5094 wl_deinit_priv(cfg);
5095 wiphy_free(cfg->wiphy);
5099 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5102 __le32 roamtrigger[2];
5103 __le32 roam_delta[2];
5106 * Setup timeout if Beacons are lost and roam is
5107 * off to report link down
5109 if (brcmf_roamoff) {
5110 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5112 brcmf_err("bcn_timeout error (%d)\n", err);
5113 goto dongle_rom_out;
5118 * Enable/Disable built-in roaming to allow supplicant
5119 * to take care of roaming
5121 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5122 brcmf_roamoff ? "Off" : "On");
5123 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5125 brcmf_err("roam_off error (%d)\n", err);
5126 goto dongle_rom_out;
5129 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5130 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5131 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5132 (void *)roamtrigger, sizeof(roamtrigger));
5134 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5135 goto dongle_rom_out;
5138 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5139 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5140 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5141 (void *)roam_delta, sizeof(roam_delta));
5143 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5144 goto dongle_rom_out;
5152 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5153 s32 scan_unassoc_time, s32 scan_passive_time)
5157 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5160 if (err == -EOPNOTSUPP)
5161 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5163 brcmf_err("Scan assoc time error (%d)\n", err);
5164 goto dongle_scantime_out;
5166 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5169 if (err == -EOPNOTSUPP)
5170 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5172 brcmf_err("Scan unassoc time error (%d)\n", err);
5173 goto dongle_scantime_out;
5176 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5179 if (err == -EOPNOTSUPP)
5180 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5182 brcmf_err("Scan passive time error (%d)\n", err);
5183 goto dongle_scantime_out;
5186 dongle_scantime_out:
5191 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5194 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5195 struct ieee80211_channel *band_chan_arr;
5196 struct brcmf_chanspec_list *list;
5197 struct brcmu_chan ch;
5202 enum ieee80211_band band;
5210 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5215 list = (struct brcmf_chanspec_list *)pbuf;
5217 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5220 brcmf_err("get chanspecs error (%d)\n", err);
5224 __wl_band_2ghz.n_channels = 0;
5225 __wl_band_5ghz_a.n_channels = 0;
5227 total = le32_to_cpu(list->count);
5228 for (i = 0; i < total; i++) {
5229 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5230 cfg->d11inf.decchspec(&ch);
5232 if (ch.band == BRCMU_CHAN_BAND_2G) {
5233 band_chan_arr = __wl_2ghz_channels;
5234 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5235 n_cnt = &__wl_band_2ghz.n_channels;
5236 band = IEEE80211_BAND_2GHZ;
5237 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5238 band_chan_arr = __wl_5ghz_a_channels;
5239 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5240 n_cnt = &__wl_band_5ghz_a.n_channels;
5241 band = IEEE80211_BAND_5GHZ;
5243 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5246 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5247 ch.bw == BRCMU_CHAN_BW_40)
5249 if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
5250 ch.bw == BRCMU_CHAN_BW_80)
5253 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5254 if (band_chan_arr[j].hw_value == ch.chnum) {
5263 if (index < array_size) {
5264 band_chan_arr[index].center_freq =
5265 ieee80211_channel_to_frequency(ch.chnum, band);
5266 band_chan_arr[index].hw_value = ch.chnum;
5268 /* assuming the chanspecs order is HT20,
5269 * HT40 upper, HT40 lower, and VHT80.
5271 if (ch.bw == BRCMU_CHAN_BW_80) {
5272 band_chan_arr[index].flags &=
5273 ~IEEE80211_CHAN_NO_80MHZ;
5274 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5275 ht40_flag = band_chan_arr[index].flags &
5276 IEEE80211_CHAN_NO_HT40;
5277 if (ch.sb == BRCMU_CHAN_SB_U) {
5278 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5279 band_chan_arr[index].flags &=
5280 ~IEEE80211_CHAN_NO_HT40;
5281 band_chan_arr[index].flags |=
5282 IEEE80211_CHAN_NO_HT40PLUS;
5284 /* It should be one of
5285 * IEEE80211_CHAN_NO_HT40 or
5286 * IEEE80211_CHAN_NO_HT40PLUS
5288 band_chan_arr[index].flags &=
5289 ~IEEE80211_CHAN_NO_HT40;
5290 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5291 band_chan_arr[index].flags |=
5292 IEEE80211_CHAN_NO_HT40MINUS;
5295 /* disable other bandwidths for now as mentioned
5296 * order assure they are enabled for subsequent
5299 band_chan_arr[index].flags =
5300 IEEE80211_CHAN_NO_HT40 |
5301 IEEE80211_CHAN_NO_80MHZ;
5302 ch.bw = BRCMU_CHAN_BW_20;
5303 cfg->d11inf.encchspec(&ch);
5304 channel = ch.chspec;
5305 err = brcmf_fil_bsscfg_int_get(ifp,
5309 if (channel & WL_CHAN_RADAR)
5310 band_chan_arr[index].flags |=
5311 (IEEE80211_CHAN_RADAR |
5312 IEEE80211_CHAN_NO_IR);
5313 if (channel & WL_CHAN_PASSIVE)
5314 band_chan_arr[index].flags |=
5315 IEEE80211_CHAN_NO_IR;
5327 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5329 u32 band, mimo_bwcap;
5333 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5335 bw_cap[IEEE80211_BAND_2GHZ] = band;
5337 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5339 bw_cap[IEEE80211_BAND_5GHZ] = band;
5345 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5347 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5349 /* assume 20MHz if firmware does not give a clue */
5350 mimo_bwcap = WLC_N_BW_20ALL;
5352 switch (mimo_bwcap) {
5353 case WLC_N_BW_40ALL:
5354 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5356 case WLC_N_BW_20IN2G_40IN5G:
5357 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5359 case WLC_N_BW_20ALL:
5360 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5361 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5364 brcmf_err("invalid mimo_bw_cap value\n");
5368 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5369 u32 bw_cap[2], u32 nchain)
5371 band->ht_cap.ht_supported = true;
5372 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5373 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5374 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5376 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5377 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5378 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5379 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5380 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5381 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5384 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5389 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5390 mcs_map = (mcs_map << 2) | supp;
5392 return cpu_to_le16(mcs_map);
5395 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5396 u32 bw_cap[2], u32 nchain)
5400 /* not allowed in 2.4G band */
5401 if (band->band == IEEE80211_BAND_2GHZ)
5404 band->vht_cap.vht_supported = true;
5405 /* 80MHz is mandatory */
5406 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5407 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5408 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5409 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5411 /* all support 256-QAM */
5412 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5413 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5414 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5417 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5419 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5420 struct wiphy *wiphy;
5425 u32 bw_cap[2] = { 0, 0 };
5432 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5433 struct ieee80211_supported_band *band;
5435 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5436 &phy_list, sizeof(phy_list));
5438 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5442 phy = ((char *)&phy_list)[0];
5443 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5446 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5447 &band_list, sizeof(band_list));
5449 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5452 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5453 band_list[0], band_list[1], band_list[2]);
5455 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5456 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5458 brcmf_err("nmode error (%d)\n", err);
5460 brcmf_get_bwcap(ifp, bw_cap);
5462 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5463 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5464 bw_cap[IEEE80211_BAND_5GHZ]);
5466 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5468 brcmf_err("rxchain error (%d)\n", err);
5471 for (nchain = 0; rxchain; nchain++)
5472 rxchain = rxchain & (rxchain - 1);
5474 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5476 err = brcmf_construct_reginfo(cfg, bw_cap);
5478 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5482 nband = band_list[0];
5484 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5486 if ((band_list[i] == WLC_BAND_5G) &&
5487 (__wl_band_5ghz_a.n_channels > 0))
5488 band = &__wl_band_5ghz_a;
5489 else if ((band_list[i] == WLC_BAND_2G) &&
5490 (__wl_band_2ghz.n_channels > 0))
5491 band = &__wl_band_2ghz;
5496 brcmf_update_ht_cap(band, bw_cap, nchain);
5498 brcmf_update_vht_cap(band, bw_cap, nchain);
5499 bands[band->band] = band;
5502 wiphy = cfg_to_wiphy(cfg);
5503 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5504 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5505 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5511 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5513 return brcmf_update_wiphybands(cfg);
5516 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5518 struct net_device *ndev;
5519 struct wireless_dev *wdev;
5520 struct brcmf_if *ifp;
5527 ndev = cfg_to_ndev(cfg);
5528 wdev = ndev->ieee80211_ptr;
5529 ifp = netdev_priv(ndev);
5531 /* make sure RF is ready for work */
5532 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5534 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5535 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5537 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5538 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5540 goto default_conf_out;
5541 brcmf_dbg(INFO, "power save set to %s\n",
5542 (power_mode ? "enabled" : "disabled"));
5544 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5546 goto default_conf_out;
5547 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5550 goto default_conf_out;
5551 err = brcmf_dongle_probecap(cfg);
5553 goto default_conf_out;
5555 brcmf_configure_arp_offload(ifp, true);
5557 cfg->dongle_up = true;
5564 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5566 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5568 return brcmf_config_dongle(ifp->drvr->config);
5571 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5573 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5576 * While going down, if associated with AP disassociate
5577 * from AP to save power
5579 if (check_vif_up(ifp->vif)) {
5580 brcmf_link_down(ifp->vif);
5582 /* Make sure WPA_Supplicant receives all the event
5583 generated due to DISASSOC call to the fw to keep
5584 the state fw and WPA_Supplicant state consistent
5589 brcmf_abort_scanning(cfg);
5590 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5595 s32 brcmf_cfg80211_up(struct net_device *ndev)
5597 struct brcmf_if *ifp = netdev_priv(ndev);
5598 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5601 mutex_lock(&cfg->usr_sync);
5602 err = __brcmf_cfg80211_up(ifp);
5603 mutex_unlock(&cfg->usr_sync);
5608 s32 brcmf_cfg80211_down(struct net_device *ndev)
5610 struct brcmf_if *ifp = netdev_priv(ndev);
5611 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5614 mutex_lock(&cfg->usr_sync);
5615 err = __brcmf_cfg80211_down(ifp);
5616 mutex_unlock(&cfg->usr_sync);
5621 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5623 struct wireless_dev *wdev = &ifp->vif->wdev;
5625 return wdev->iftype;
5628 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5630 struct brcmf_cfg80211_vif *vif;
5633 list_for_each_entry(vif, &cfg->vif_list, list) {
5634 if (test_bit(state, &vif->sme_state))
5640 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5645 mutex_lock(&event->vif_event_lock);
5646 evt_action = event->action;
5647 mutex_unlock(&event->vif_event_lock);
5648 return evt_action == action;
5651 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5652 struct brcmf_cfg80211_vif *vif)
5654 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5656 mutex_lock(&event->vif_event_lock);
5659 mutex_unlock(&event->vif_event_lock);
5662 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5664 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5667 mutex_lock(&event->vif_event_lock);
5668 armed = event->vif != NULL;
5669 mutex_unlock(&event->vif_event_lock);
5673 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5674 u8 action, ulong timeout)
5676 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5678 return wait_event_timeout(event->vif_wq,
5679 vif_event_equals(event, action), timeout);