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 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 * e-scan can be initiated by scheduled scan
645 * which takes precedence.
647 if (cfg->sched_escan) {
648 brcmf_dbg(SCAN, "scheduled scan completed\n");
649 cfg->sched_escan = false;
651 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
652 brcmf_set_mpc(ifp, 1);
653 } else if (scan_request) {
654 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
655 aborted ? "Aborted" : "Done");
656 cfg80211_scan_done(scan_request, aborted);
657 brcmf_set_mpc(ifp, 1);
659 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
660 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
666 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
668 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
669 struct net_device *ndev = wdev->netdev;
671 /* vif event pending in firmware */
672 if (brcmf_cfg80211_vif_event_armed(cfg))
676 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
677 cfg->escan_info.ifp == netdev_priv(ndev))
678 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
681 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
684 switch (wdev->iftype) {
685 case NL80211_IFTYPE_ADHOC:
686 case NL80211_IFTYPE_STATION:
687 case NL80211_IFTYPE_AP:
688 case NL80211_IFTYPE_AP_VLAN:
689 case NL80211_IFTYPE_WDS:
690 case NL80211_IFTYPE_MONITOR:
691 case NL80211_IFTYPE_MESH_POINT:
693 case NL80211_IFTYPE_P2P_CLIENT:
694 case NL80211_IFTYPE_P2P_GO:
695 case NL80211_IFTYPE_P2P_DEVICE:
696 return brcmf_p2p_del_vif(wiphy, wdev);
697 case NL80211_IFTYPE_UNSPECIFIED:
705 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
706 enum nl80211_iftype type, u32 *flags,
707 struct vif_params *params)
709 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
710 struct brcmf_if *ifp = netdev_priv(ndev);
711 struct brcmf_cfg80211_vif *vif = ifp->vif;
716 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
719 case NL80211_IFTYPE_MONITOR:
720 case NL80211_IFTYPE_WDS:
721 brcmf_err("type (%d) : currently we do not support this type\n",
724 case NL80211_IFTYPE_ADHOC:
727 case NL80211_IFTYPE_STATION:
728 /* Ignore change for p2p IF. Unclear why supplicant does this */
729 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
730 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
731 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
732 /* WAR: It is unexpected to get a change of VIF for P2P
733 * IF, but it happens. The request can not be handled
734 * but returning EPERM causes a crash. Returning 0
735 * without setting ieee80211_ptr->iftype causes trace
736 * (WARN_ON) but it works with wpa_supplicant
742 case NL80211_IFTYPE_AP:
743 case NL80211_IFTYPE_P2P_GO:
752 if (type == NL80211_IFTYPE_P2P_GO) {
753 brcmf_dbg(INFO, "IF Type = P2P GO\n");
754 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
757 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
758 brcmf_dbg(INFO, "IF Type = AP\n");
761 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
763 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
767 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
770 ndev->ieee80211_ptr->iftype = type;
773 brcmf_dbg(TRACE, "Exit\n");
778 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
779 struct brcmf_scan_params_le *params_le,
780 struct cfg80211_scan_request *request)
788 struct brcmf_ssid_le ssid_le;
790 memset(params_le->bssid, 0xFF, ETH_ALEN);
791 params_le->bss_type = DOT11_BSSTYPE_ANY;
792 params_le->scan_type = 0;
793 params_le->channel_num = 0;
794 params_le->nprobes = cpu_to_le32(-1);
795 params_le->active_time = cpu_to_le32(-1);
796 params_le->passive_time = cpu_to_le32(-1);
797 params_le->home_time = cpu_to_le32(-1);
798 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
800 /* if request is null exit so it will be all channel broadcast scan */
804 n_ssids = request->n_ssids;
805 n_channels = request->n_channels;
806 /* Copy channel array if applicable */
807 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
809 if (n_channels > 0) {
810 for (i = 0; i < n_channels; i++) {
811 chanspec = channel_to_chanspec(&cfg->d11inf,
812 request->channels[i]);
813 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
814 request->channels[i]->hw_value, chanspec);
815 params_le->channel_list[i] = cpu_to_le16(chanspec);
818 brcmf_dbg(SCAN, "Scanning all channels\n");
820 /* Copy ssid array if applicable */
821 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
823 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
824 n_channels * sizeof(u16);
825 offset = roundup(offset, sizeof(u32));
826 ptr = (char *)params_le + offset;
827 for (i = 0; i < n_ssids; i++) {
828 memset(&ssid_le, 0, sizeof(ssid_le));
830 cpu_to_le32(request->ssids[i].ssid_len);
831 memcpy(ssid_le.SSID, request->ssids[i].ssid,
832 request->ssids[i].ssid_len);
833 if (!ssid_le.SSID_len)
834 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
836 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
837 i, ssid_le.SSID, ssid_le.SSID_len);
838 memcpy(ptr, &ssid_le, sizeof(ssid_le));
839 ptr += sizeof(ssid_le);
842 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
843 if ((request->ssids) && request->ssids->ssid_len) {
844 brcmf_dbg(SCAN, "SSID %s len=%d\n",
845 params_le->ssid_le.SSID,
846 request->ssids->ssid_len);
847 params_le->ssid_le.SSID_len =
848 cpu_to_le32(request->ssids->ssid_len);
849 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
850 request->ssids->ssid_len);
853 /* Adding mask to channel numbers */
854 params_le->channel_num =
855 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
856 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
860 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
861 struct cfg80211_scan_request *request, u16 action)
863 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
864 offsetof(struct brcmf_escan_params_le, params_le);
865 struct brcmf_escan_params_le *params;
868 brcmf_dbg(SCAN, "E-SCAN START\n");
870 if (request != NULL) {
871 /* Allocate space for populating ssids in struct */
872 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
874 /* Allocate space for populating ssids in struct */
875 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
878 params = kzalloc(params_size, GFP_KERNEL);
883 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
884 brcmf_escan_prep(cfg, ¶ms->params_le, request);
885 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
886 params->action = cpu_to_le16(action);
887 params->sync_id = cpu_to_le16(0x1234);
889 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
892 brcmf_dbg(INFO, "system busy : escan canceled\n");
894 brcmf_err("error (%d)\n", err);
903 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
904 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
908 struct brcmf_scan_results *results;
909 struct escan_info *escan = &cfg->escan_info;
911 brcmf_dbg(SCAN, "Enter\n");
913 escan->wiphy = wiphy;
914 escan->escan_state = WL_ESCAN_STATE_SCANNING;
915 passive_scan = cfg->active_scan ? 0 : 1;
916 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
919 brcmf_err("error (%d)\n", err);
922 brcmf_set_mpc(ifp, 0);
923 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
924 results->version = 0;
926 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
928 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
930 brcmf_set_mpc(ifp, 1);
935 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
936 struct cfg80211_scan_request *request,
937 struct cfg80211_ssid *this_ssid)
939 struct brcmf_if *ifp = vif->ifp;
940 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
941 struct cfg80211_ssid *ssids;
942 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
949 brcmf_dbg(SCAN, "START ESCAN\n");
951 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
952 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
955 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
956 brcmf_err("Scanning being aborted: status (%lu)\n",
960 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
961 brcmf_err("Scanning suppressed: status (%lu)\n",
965 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
966 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
970 /* If scan req comes for p2p0, send it over primary I/F */
971 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
972 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
974 /* Arm scan timeout timer */
975 mod_timer(&cfg->escan_timeout, jiffies +
976 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
981 ssids = request->ssids;
985 /* we don't do escan in ibss */
989 cfg->scan_request = request;
990 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
992 cfg->escan_info.run = brcmf_run_escan;
993 err = brcmf_p2p_scan_prep(wiphy, request, vif);
997 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1001 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1002 ssids->ssid, ssids->ssid_len);
1003 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1004 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1005 sr->ssid_le.SSID_len = cpu_to_le32(0);
1008 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1009 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1012 brcmf_dbg(SCAN, "Broadcast scan\n");
1014 passive_scan = cfg->active_scan ? 0 : 1;
1015 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1018 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1021 brcmf_set_mpc(ifp, 0);
1022 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1023 &sr->ssid_le, sizeof(sr->ssid_le));
1026 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1029 brcmf_err("WLC_SCAN error (%d)\n", err);
1031 brcmf_set_mpc(ifp, 1);
1039 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1040 if (timer_pending(&cfg->escan_timeout))
1041 del_timer_sync(&cfg->escan_timeout);
1042 cfg->scan_request = NULL;
1047 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1049 struct brcmf_cfg80211_vif *vif;
1052 brcmf_dbg(TRACE, "Enter\n");
1053 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1054 if (!check_vif_up(vif))
1057 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1060 brcmf_err("scan error (%d)\n", err);
1062 brcmf_dbg(TRACE, "Exit\n");
1066 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1070 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1073 brcmf_err("Error (%d)\n", err);
1078 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1082 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1085 brcmf_err("Error (%d)\n", err);
1090 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1093 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1095 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1097 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1103 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1105 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1106 struct net_device *ndev = cfg_to_ndev(cfg);
1107 struct brcmf_if *ifp = netdev_priv(ndev);
1110 brcmf_dbg(TRACE, "Enter\n");
1111 if (!check_vif_up(ifp->vif))
1114 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1115 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1116 cfg->conf->rts_threshold = wiphy->rts_threshold;
1117 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1121 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1122 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1123 cfg->conf->frag_threshold = wiphy->frag_threshold;
1124 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1128 if (changed & WIPHY_PARAM_RETRY_LONG
1129 && (cfg->conf->retry_long != wiphy->retry_long)) {
1130 cfg->conf->retry_long = wiphy->retry_long;
1131 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1135 if (changed & WIPHY_PARAM_RETRY_SHORT
1136 && (cfg->conf->retry_short != wiphy->retry_short)) {
1137 cfg->conf->retry_short = wiphy->retry_short;
1138 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1144 brcmf_dbg(TRACE, "Exit\n");
1148 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1150 memset(prof, 0, sizeof(*prof));
1153 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1155 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1158 brcmf_dbg(TRACE, "Enter\n");
1160 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1161 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1162 err = brcmf_fil_cmd_data_set(vif->ifp,
1163 BRCMF_C_DISASSOC, NULL, 0);
1165 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1167 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1168 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1171 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1172 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1173 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1174 brcmf_dbg(TRACE, "Exit\n");
1178 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1179 struct cfg80211_ibss_params *params)
1181 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1182 struct brcmf_if *ifp = netdev_priv(ndev);
1183 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1184 struct brcmf_join_params join_params;
1185 size_t join_params_size = 0;
1191 brcmf_dbg(TRACE, "Enter\n");
1192 if (!check_vif_up(ifp->vif))
1196 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1198 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1202 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1205 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1207 brcmf_dbg(CONN, "No BSSID specified\n");
1209 if (params->chandef.chan)
1210 brcmf_dbg(CONN, "channel: %d\n",
1211 params->chandef.chan->center_freq);
1213 brcmf_dbg(CONN, "no channel specified\n");
1215 if (params->channel_fixed)
1216 brcmf_dbg(CONN, "fixed channel required\n");
1218 brcmf_dbg(CONN, "no fixed channel required\n");
1220 if (params->ie && params->ie_len)
1221 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1223 brcmf_dbg(CONN, "no ie specified\n");
1225 if (params->beacon_interval)
1226 brcmf_dbg(CONN, "beacon interval: %d\n",
1227 params->beacon_interval);
1229 brcmf_dbg(CONN, "no beacon interval specified\n");
1231 if (params->basic_rates)
1232 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1234 brcmf_dbg(CONN, "no basic rates specified\n");
1236 if (params->privacy)
1237 brcmf_dbg(CONN, "privacy required\n");
1239 brcmf_dbg(CONN, "no privacy required\n");
1241 /* Configure Privacy for starter */
1242 if (params->privacy)
1243 wsec |= WEP_ENABLED;
1245 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1247 brcmf_err("wsec failed (%d)\n", err);
1251 /* Configure Beacon Interval for starter */
1252 if (params->beacon_interval)
1253 bcnprd = params->beacon_interval;
1257 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1259 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1263 /* Configure required join parameter */
1264 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1267 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1268 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1269 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1270 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1271 join_params_size = sizeof(join_params.ssid_le);
1274 if (params->bssid) {
1275 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1276 join_params_size = sizeof(join_params.ssid_le) +
1277 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1278 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1280 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1281 memset(profile->bssid, 0, ETH_ALEN);
1285 if (params->chandef.chan) {
1289 ieee80211_frequency_to_channel(
1290 params->chandef.chan->center_freq);
1291 if (params->channel_fixed) {
1292 /* adding chanspec */
1293 chanspec = chandef_to_chanspec(&cfg->d11inf,
1295 join_params.params_le.chanspec_list[0] =
1296 cpu_to_le16(chanspec);
1297 join_params.params_le.chanspec_num = cpu_to_le32(1);
1298 join_params_size += sizeof(join_params.params_le);
1301 /* set channel for starter */
1302 target_channel = cfg->channel;
1303 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1306 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1312 cfg->ibss_starter = false;
1315 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1316 &join_params, join_params_size);
1318 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1324 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1325 brcmf_dbg(TRACE, "Exit\n");
1330 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1332 struct brcmf_if *ifp = netdev_priv(ndev);
1335 brcmf_dbg(TRACE, "Enter\n");
1336 if (!check_vif_up(ifp->vif))
1339 brcmf_link_down(ifp->vif);
1341 brcmf_dbg(TRACE, "Exit\n");
1346 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1347 struct cfg80211_connect_params *sme)
1349 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1350 struct brcmf_cfg80211_security *sec;
1354 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1355 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1356 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1357 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1359 val = WPA_AUTH_DISABLED;
1360 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1361 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1363 brcmf_err("set wpa_auth failed (%d)\n", err);
1366 sec = &profile->sec;
1367 sec->wpa_versions = sme->crypto.wpa_versions;
1371 static s32 brcmf_set_auth_type(struct net_device *ndev,
1372 struct cfg80211_connect_params *sme)
1374 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1375 struct brcmf_cfg80211_security *sec;
1379 switch (sme->auth_type) {
1380 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1382 brcmf_dbg(CONN, "open system\n");
1384 case NL80211_AUTHTYPE_SHARED_KEY:
1386 brcmf_dbg(CONN, "shared key\n");
1388 case NL80211_AUTHTYPE_AUTOMATIC:
1390 brcmf_dbg(CONN, "automatic\n");
1392 case NL80211_AUTHTYPE_NETWORK_EAP:
1393 brcmf_dbg(CONN, "network eap\n");
1396 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1400 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1402 brcmf_err("set auth failed (%d)\n", err);
1405 sec = &profile->sec;
1406 sec->auth_type = sme->auth_type;
1411 brcmf_set_wsec_mode(struct net_device *ndev,
1412 struct cfg80211_connect_params *sme, bool mfp)
1414 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1415 struct brcmf_cfg80211_security *sec;
1421 if (sme->crypto.n_ciphers_pairwise) {
1422 switch (sme->crypto.ciphers_pairwise[0]) {
1423 case WLAN_CIPHER_SUITE_WEP40:
1424 case WLAN_CIPHER_SUITE_WEP104:
1427 case WLAN_CIPHER_SUITE_TKIP:
1428 pval = TKIP_ENABLED;
1430 case WLAN_CIPHER_SUITE_CCMP:
1433 case WLAN_CIPHER_SUITE_AES_CMAC:
1437 brcmf_err("invalid cipher pairwise (%d)\n",
1438 sme->crypto.ciphers_pairwise[0]);
1442 if (sme->crypto.cipher_group) {
1443 switch (sme->crypto.cipher_group) {
1444 case WLAN_CIPHER_SUITE_WEP40:
1445 case WLAN_CIPHER_SUITE_WEP104:
1448 case WLAN_CIPHER_SUITE_TKIP:
1449 gval = TKIP_ENABLED;
1451 case WLAN_CIPHER_SUITE_CCMP:
1454 case WLAN_CIPHER_SUITE_AES_CMAC:
1458 brcmf_err("invalid cipher group (%d)\n",
1459 sme->crypto.cipher_group);
1464 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1465 /* In case of privacy, but no security and WPS then simulate */
1466 /* setting AES. WPS-2.0 allows no security */
1467 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1472 wsec = pval | gval | MFP_CAPABLE;
1475 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1477 brcmf_err("error (%d)\n", err);
1481 sec = &profile->sec;
1482 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1483 sec->cipher_group = sme->crypto.cipher_group;
1489 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1491 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1492 struct brcmf_cfg80211_security *sec;
1496 if (sme->crypto.n_akm_suites) {
1497 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1500 brcmf_err("could not get wpa_auth (%d)\n", err);
1503 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1504 switch (sme->crypto.akm_suites[0]) {
1505 case WLAN_AKM_SUITE_8021X:
1506 val = WPA_AUTH_UNSPECIFIED;
1508 case WLAN_AKM_SUITE_PSK:
1512 brcmf_err("invalid cipher group (%d)\n",
1513 sme->crypto.cipher_group);
1516 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1517 switch (sme->crypto.akm_suites[0]) {
1518 case WLAN_AKM_SUITE_8021X:
1519 val = WPA2_AUTH_UNSPECIFIED;
1521 case WLAN_AKM_SUITE_PSK:
1522 val = WPA2_AUTH_PSK;
1525 brcmf_err("invalid cipher group (%d)\n",
1526 sme->crypto.cipher_group);
1531 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1532 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1535 brcmf_err("could not set wpa_auth (%d)\n", err);
1539 sec = &profile->sec;
1540 sec->wpa_auth = sme->crypto.akm_suites[0];
1546 brcmf_set_sharedkey(struct net_device *ndev,
1547 struct cfg80211_connect_params *sme)
1549 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1550 struct brcmf_cfg80211_security *sec;
1551 struct brcmf_wsec_key key;
1555 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1557 if (sme->key_len == 0)
1560 sec = &profile->sec;
1561 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1562 sec->wpa_versions, sec->cipher_pairwise);
1564 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1567 if (!(sec->cipher_pairwise &
1568 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1571 memset(&key, 0, sizeof(key));
1572 key.len = (u32) sme->key_len;
1573 key.index = (u32) sme->key_idx;
1574 if (key.len > sizeof(key.data)) {
1575 brcmf_err("Too long key length (%u)\n", key.len);
1578 memcpy(key.data, sme->key, key.len);
1579 key.flags = BRCMF_PRIMARY_KEY;
1580 switch (sec->cipher_pairwise) {
1581 case WLAN_CIPHER_SUITE_WEP40:
1582 key.algo = CRYPTO_ALGO_WEP1;
1584 case WLAN_CIPHER_SUITE_WEP104:
1585 key.algo = CRYPTO_ALGO_WEP128;
1588 brcmf_err("Invalid algorithm (%d)\n",
1589 sme->crypto.ciphers_pairwise[0]);
1592 /* Set the new key/index */
1593 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1594 key.len, key.index, key.algo);
1595 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1596 err = send_key_to_dongle(ndev, &key);
1600 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1601 brcmf_dbg(CONN, "set auth_type to shared key\n");
1602 val = WL_AUTH_SHARED_KEY; /* shared key */
1603 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1605 brcmf_err("set auth failed (%d)\n", err);
1611 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1612 enum nl80211_auth_type type)
1615 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1616 /* shift to ignore chip revision */
1617 ci = brcmf_get_chip_info(ifp) >> 4;
1620 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1621 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1630 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1631 struct cfg80211_connect_params *sme)
1633 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1634 struct brcmf_if *ifp = netdev_priv(ndev);
1635 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1636 struct ieee80211_channel *chan = sme->channel;
1637 struct brcmf_join_params join_params;
1638 size_t join_params_size;
1639 const struct brcmf_tlv *rsn_ie;
1640 const struct brcmf_vs_tlv *wpa_ie;
1643 struct brcmf_ext_join_params_le *ext_join_params;
1647 brcmf_dbg(TRACE, "Enter\n");
1648 if (!check_vif_up(ifp->vif))
1652 brcmf_err("Invalid ssid\n");
1656 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1657 /* A normal (non P2P) connection request setup. */
1660 /* find the WPA_IE */
1661 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1664 ie_len = wpa_ie->len + TLV_HDR_LEN;
1666 /* find the RSN_IE */
1667 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1672 ie_len = rsn_ie->len + TLV_HDR_LEN;
1675 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1678 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1679 sme->ie, sme->ie_len);
1681 brcmf_err("Set Assoc REQ IE Failed\n");
1683 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1685 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1689 ieee80211_frequency_to_channel(chan->center_freq);
1690 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1691 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1692 cfg->channel, chan->center_freq, chanspec);
1698 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1700 err = brcmf_set_wpa_version(ndev, sme);
1702 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1706 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1707 err = brcmf_set_auth_type(ndev, sme);
1709 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1713 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1715 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1719 err = brcmf_set_key_mgmt(ndev, sme);
1721 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1725 err = brcmf_set_sharedkey(ndev, sme);
1727 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1731 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1732 (u32)sme->ssid_len);
1733 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1734 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1735 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1736 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1737 profile->ssid.SSID_len);
1740 /* Join with specific BSSID and cached SSID
1741 * If SSID is zero join based on BSSID only
1743 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1744 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1746 join_params_size += sizeof(u16);
1747 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1748 if (ext_join_params == NULL) {
1752 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1753 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1754 profile->ssid.SSID_len);
1756 /* Set up join scan parameters */
1757 ext_join_params->scan_le.scan_type = -1;
1758 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1761 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1763 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1766 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1768 ext_join_params->assoc_le.chanspec_list[0] =
1769 cpu_to_le16(chanspec);
1770 /* Increase dwell time to receive probe response or detect
1771 * beacon from target AP at a noisy air only during connect
1774 ext_join_params->scan_le.active_time =
1775 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1776 ext_join_params->scan_le.passive_time =
1777 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1778 /* To sync with presence period of VSDB GO send probe request
1779 * more frequently. Probe request will be stopped when it gets
1780 * probe response from target AP/GO.
1782 ext_join_params->scan_le.nprobes =
1783 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1784 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1786 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1787 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1788 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1791 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1793 kfree(ext_join_params);
1795 /* This is it. join command worked, we are done */
1798 /* join command failed, fallback to set ssid */
1799 memset(&join_params, 0, sizeof(join_params));
1800 join_params_size = sizeof(join_params.ssid_le);
1802 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1803 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1806 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1808 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1811 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1812 join_params.params_le.chanspec_num = cpu_to_le32(1);
1813 join_params_size += sizeof(join_params.params_le);
1815 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1816 &join_params, join_params_size);
1818 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1822 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1823 brcmf_dbg(TRACE, "Exit\n");
1828 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1831 struct brcmf_if *ifp = netdev_priv(ndev);
1832 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1833 struct brcmf_scb_val_le scbval;
1836 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1837 if (!check_vif_up(ifp->vif))
1840 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1841 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1843 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1844 scbval.val = cpu_to_le32(reason_code);
1845 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1846 &scbval, sizeof(scbval));
1848 brcmf_err("error (%d)\n", err);
1850 brcmf_dbg(TRACE, "Exit\n");
1855 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1856 enum nl80211_tx_power_setting type, s32 mbm)
1859 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1860 struct net_device *ndev = cfg_to_ndev(cfg);
1861 struct brcmf_if *ifp = netdev_priv(ndev);
1865 s32 dbm = MBM_TO_DBM(mbm);
1867 brcmf_dbg(TRACE, "Enter\n");
1868 if (!check_vif_up(ifp->vif))
1872 case NL80211_TX_POWER_AUTOMATIC:
1874 case NL80211_TX_POWER_LIMITED:
1875 case NL80211_TX_POWER_FIXED:
1877 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1883 /* Make sure radio is off or on as far as software is concerned */
1884 disable = WL_RADIO_SW_DISABLE << 16;
1885 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1887 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1892 txpwrmw = (u16) dbm;
1893 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1894 (s32)brcmf_mw_to_qdbm(txpwrmw));
1896 brcmf_err("qtxpower error (%d)\n", err);
1897 cfg->conf->tx_power = dbm;
1900 brcmf_dbg(TRACE, "Exit\n");
1904 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1905 struct wireless_dev *wdev,
1908 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1909 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1914 brcmf_dbg(TRACE, "Enter\n");
1915 if (!check_vif_up(ifp->vif))
1918 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1920 brcmf_err("error (%d)\n", err);
1924 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1925 *dbm = (s32) brcmf_qdbm_to_mw(result);
1928 brcmf_dbg(TRACE, "Exit\n");
1933 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1934 u8 key_idx, bool unicast, bool multicast)
1936 struct brcmf_if *ifp = netdev_priv(ndev);
1941 brcmf_dbg(TRACE, "Enter\n");
1942 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1943 if (!check_vif_up(ifp->vif))
1946 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1948 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1952 if (wsec & WEP_ENABLED) {
1953 /* Just select a new current key */
1955 err = brcmf_fil_cmd_int_set(ifp,
1956 BRCMF_C_SET_KEY_PRIMARY, index);
1958 brcmf_err("error (%d)\n", err);
1961 brcmf_dbg(TRACE, "Exit\n");
1966 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1967 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1969 struct brcmf_if *ifp = netdev_priv(ndev);
1970 struct brcmf_wsec_key key;
1974 memset(&key, 0, sizeof(key));
1975 key.index = (u32) key_idx;
1976 /* Instead of bcast for ea address for default wep keys,
1977 driver needs it to be Null */
1978 if (!is_multicast_ether_addr(mac_addr))
1979 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1980 key.len = (u32) params->key_len;
1981 /* check for key index change */
1984 err = send_key_to_dongle(ndev, &key);
1986 brcmf_err("key delete error (%d)\n", err);
1988 if (key.len > sizeof(key.data)) {
1989 brcmf_err("Invalid key length (%d)\n", key.len);
1993 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1994 memcpy(key.data, params->key, key.len);
1996 if (!brcmf_is_apmode(ifp->vif) &&
1997 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1998 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1999 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2000 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2001 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2004 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2005 if (params->seq && params->seq_len == 6) {
2008 ivptr = (u8 *) params->seq;
2009 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2010 (ivptr[3] << 8) | ivptr[2];
2011 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2012 key.iv_initialized = true;
2015 switch (params->cipher) {
2016 case WLAN_CIPHER_SUITE_WEP40:
2017 key.algo = CRYPTO_ALGO_WEP1;
2018 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2020 case WLAN_CIPHER_SUITE_WEP104:
2021 key.algo = CRYPTO_ALGO_WEP128;
2022 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2024 case WLAN_CIPHER_SUITE_TKIP:
2025 key.algo = CRYPTO_ALGO_TKIP;
2026 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2028 case WLAN_CIPHER_SUITE_AES_CMAC:
2029 key.algo = CRYPTO_ALGO_AES_CCM;
2030 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2032 case WLAN_CIPHER_SUITE_CCMP:
2033 key.algo = CRYPTO_ALGO_AES_CCM;
2034 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2037 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2040 err = send_key_to_dongle(ndev, &key);
2042 brcmf_err("wsec_key error (%d)\n", err);
2048 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2049 u8 key_idx, bool pairwise, const u8 *mac_addr,
2050 struct key_params *params)
2052 struct brcmf_if *ifp = netdev_priv(ndev);
2053 struct brcmf_wsec_key key;
2059 brcmf_dbg(TRACE, "Enter\n");
2060 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2061 if (!check_vif_up(ifp->vif))
2065 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2066 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2067 brcmf_dbg(TRACE, "Exit");
2068 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2070 memset(&key, 0, sizeof(key));
2072 key.len = (u32) params->key_len;
2073 key.index = (u32) key_idx;
2075 if (key.len > sizeof(key.data)) {
2076 brcmf_err("Too long key length (%u)\n", key.len);
2080 memcpy(key.data, params->key, key.len);
2082 key.flags = BRCMF_PRIMARY_KEY;
2083 switch (params->cipher) {
2084 case WLAN_CIPHER_SUITE_WEP40:
2085 key.algo = CRYPTO_ALGO_WEP1;
2087 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2089 case WLAN_CIPHER_SUITE_WEP104:
2090 key.algo = CRYPTO_ALGO_WEP128;
2092 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2094 case WLAN_CIPHER_SUITE_TKIP:
2095 if (!brcmf_is_apmode(ifp->vif)) {
2096 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2097 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2098 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2099 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2101 key.algo = CRYPTO_ALGO_TKIP;
2103 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2105 case WLAN_CIPHER_SUITE_AES_CMAC:
2106 key.algo = CRYPTO_ALGO_AES_CCM;
2108 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2110 case WLAN_CIPHER_SUITE_CCMP:
2111 key.algo = CRYPTO_ALGO_AES_CCM;
2113 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2116 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2121 err = send_key_to_dongle(ndev, &key);
2125 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2127 brcmf_err("get wsec error (%d)\n", err);
2131 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2133 brcmf_err("set wsec error (%d)\n", err);
2138 brcmf_dbg(TRACE, "Exit\n");
2143 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2144 u8 key_idx, bool pairwise, const u8 *mac_addr)
2146 struct brcmf_if *ifp = netdev_priv(ndev);
2147 struct brcmf_wsec_key key;
2150 brcmf_dbg(TRACE, "Enter\n");
2151 if (!check_vif_up(ifp->vif))
2154 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2155 /* we ignore this key index in this case */
2156 brcmf_err("invalid key index (%d)\n", key_idx);
2160 memset(&key, 0, sizeof(key));
2162 key.index = (u32) key_idx;
2163 key.flags = BRCMF_PRIMARY_KEY;
2164 key.algo = CRYPTO_ALGO_OFF;
2166 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2168 /* Set the new key/index */
2169 err = send_key_to_dongle(ndev, &key);
2171 brcmf_dbg(TRACE, "Exit\n");
2176 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2177 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2178 void (*callback) (void *cookie, struct key_params * params))
2180 struct key_params params;
2181 struct brcmf_if *ifp = netdev_priv(ndev);
2182 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2183 struct brcmf_cfg80211_security *sec;
2187 brcmf_dbg(TRACE, "Enter\n");
2188 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2189 if (!check_vif_up(ifp->vif))
2192 memset(¶ms, 0, sizeof(params));
2194 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2196 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2197 /* Ignore this error, may happen during DISASSOC */
2201 if (wsec & WEP_ENABLED) {
2202 sec = &profile->sec;
2203 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2204 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2205 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2206 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2207 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2208 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2210 } else if (wsec & TKIP_ENABLED) {
2211 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2212 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2213 } else if (wsec & AES_ENABLED) {
2214 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2215 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2217 brcmf_err("Invalid algo (0x%x)\n", wsec);
2221 callback(cookie, ¶ms);
2224 brcmf_dbg(TRACE, "Exit\n");
2229 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2230 struct net_device *ndev, u8 key_idx)
2232 brcmf_dbg(INFO, "Not supported\n");
2238 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2239 u8 *mac, struct station_info *sinfo)
2241 struct brcmf_if *ifp = netdev_priv(ndev);
2242 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2243 struct brcmf_scb_val_le scb_val;
2247 u8 *bssid = profile->bssid;
2248 struct brcmf_sta_info_le sta_info_le;
2252 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2253 if (!check_vif_up(ifp->vif))
2256 if (brcmf_is_apmode(ifp->vif)) {
2257 memcpy(&sta_info_le, mac, ETH_ALEN);
2258 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2260 sizeof(sta_info_le));
2262 brcmf_err("GET STA INFO failed, %d\n", err);
2265 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2266 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2267 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2268 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2269 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2271 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2272 sinfo->inactive_time, sinfo->connected_time);
2273 } else if (ifp->vif->wdev.iftype == NL80211_IFTYPE_STATION) {
2274 if (memcmp(mac, bssid, ETH_ALEN)) {
2275 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2280 /* Report the current tx rate */
2281 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2283 brcmf_err("Could not get rate (%d)\n", err);
2286 sinfo->filled |= STATION_INFO_TX_BITRATE;
2287 sinfo->txrate.legacy = rate * 5;
2288 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2291 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2292 &ifp->vif->sme_state)) {
2293 memset(&scb_val, 0, sizeof(scb_val));
2294 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2295 &scb_val, sizeof(scb_val));
2297 brcmf_err("Could not get rssi (%d)\n", err);
2300 rssi = le32_to_cpu(scb_val.val);
2301 sinfo->filled |= STATION_INFO_SIGNAL;
2302 sinfo->signal = rssi;
2303 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2305 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2308 brcmf_err("Could not get beacon period (%d)\n",
2312 sinfo->bss_param.beacon_interval =
2314 brcmf_dbg(CONN, "Beacon peroid %d\n",
2317 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2320 brcmf_err("Could not get DTIM period (%d)\n",
2324 sinfo->bss_param.dtim_period = dtim_period;
2325 brcmf_dbg(CONN, "DTIM peroid %d\n",
2328 sinfo->filled |= STATION_INFO_BSS_PARAM;
2333 brcmf_dbg(TRACE, "Exit\n");
2338 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2339 bool enabled, s32 timeout)
2343 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2344 struct brcmf_if *ifp = netdev_priv(ndev);
2346 brcmf_dbg(TRACE, "Enter\n");
2349 * Powersave enable/disable request is coming from the
2350 * cfg80211 even before the interface is up. In that
2351 * scenario, driver will be storing the power save
2352 * preference in cfg struct to apply this to
2353 * FW later while initializing the dongle
2355 cfg->pwr_save = enabled;
2356 if (!check_vif_up(ifp->vif)) {
2358 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2362 pm = enabled ? PM_FAST : PM_OFF;
2363 /* Do not enable the power save after assoc if it is a p2p interface */
2364 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2365 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2368 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2370 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2373 brcmf_err("net_device is not ready yet\n");
2375 brcmf_err("error (%d)\n", err);
2378 brcmf_dbg(TRACE, "Exit\n");
2382 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2383 struct brcmf_bss_info_le *bi)
2385 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2386 struct ieee80211_channel *notify_channel;
2387 struct cfg80211_bss *bss;
2388 struct ieee80211_supported_band *band;
2389 struct brcmu_chan ch;
2393 u16 notify_capability;
2394 u16 notify_interval;
2396 size_t notify_ielen;
2399 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2400 brcmf_err("Bss info is larger than buffer. Discarding\n");
2405 ch.chspec = le16_to_cpu(bi->chanspec);
2406 cfg->d11inf.decchspec(&ch);
2407 bi->ctl_ch = ch.chnum;
2409 channel = bi->ctl_ch;
2411 if (channel <= CH_MAX_2G_CHANNEL)
2412 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2414 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2416 freq = ieee80211_channel_to_frequency(channel, band->band);
2417 notify_channel = ieee80211_get_channel(wiphy, freq);
2419 notify_capability = le16_to_cpu(bi->capability);
2420 notify_interval = le16_to_cpu(bi->beacon_period);
2421 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2422 notify_ielen = le32_to_cpu(bi->ie_length);
2423 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2425 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2426 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2427 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2428 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2429 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2431 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2432 0, notify_capability, notify_interval, notify_ie,
2433 notify_ielen, notify_signal, GFP_KERNEL);
2438 cfg80211_put_bss(wiphy, bss);
2443 static struct brcmf_bss_info_le *
2444 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2447 return list->bss_info_le;
2448 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2449 le32_to_cpu(bss->length));
2452 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2454 struct brcmf_scan_results *bss_list;
2455 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2459 bss_list = cfg->bss_list;
2460 if (bss_list->count != 0 &&
2461 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2462 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2466 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2467 for (i = 0; i < bss_list->count; i++) {
2468 bi = next_bss_le(bss_list, bi);
2469 err = brcmf_inform_single_bss(cfg, bi);
2476 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2477 struct net_device *ndev, const u8 *bssid)
2479 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2480 struct ieee80211_channel *notify_channel;
2481 struct brcmf_bss_info_le *bi = NULL;
2482 struct ieee80211_supported_band *band;
2483 struct cfg80211_bss *bss;
2484 struct brcmu_chan ch;
2488 u16 notify_capability;
2489 u16 notify_interval;
2491 size_t notify_ielen;
2494 brcmf_dbg(TRACE, "Enter\n");
2496 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2502 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2504 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2505 buf, WL_BSS_INFO_MAX);
2507 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2511 bi = (struct brcmf_bss_info_le *)(buf + 4);
2513 ch.chspec = le16_to_cpu(bi->chanspec);
2514 cfg->d11inf.decchspec(&ch);
2516 if (ch.band == BRCMU_CHAN_BAND_2G)
2517 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2519 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2521 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2522 notify_channel = ieee80211_get_channel(wiphy, freq);
2524 notify_capability = le16_to_cpu(bi->capability);
2525 notify_interval = le16_to_cpu(bi->beacon_period);
2526 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2527 notify_ielen = le32_to_cpu(bi->ie_length);
2528 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2530 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2531 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2532 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2533 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2535 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2536 0, notify_capability, notify_interval,
2537 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2544 cfg80211_put_bss(wiphy, bss);
2550 brcmf_dbg(TRACE, "Exit\n");
2555 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2556 struct brcmf_if *ifp)
2558 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2559 struct brcmf_bss_info_le *bi;
2560 struct brcmf_ssid *ssid;
2561 const struct brcmf_tlv *tim;
2562 u16 beacon_interval;
2568 brcmf_dbg(TRACE, "Enter\n");
2569 if (brcmf_is_ibssmode(ifp->vif))
2572 ssid = &profile->ssid;
2574 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2575 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2576 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2578 brcmf_err("Could not get bss info %d\n", err);
2579 goto update_bss_info_out;
2582 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2583 err = brcmf_inform_single_bss(cfg, bi);
2585 goto update_bss_info_out;
2587 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2588 ie_len = le32_to_cpu(bi->ie_length);
2589 beacon_interval = le16_to_cpu(bi->beacon_period);
2591 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2593 dtim_period = tim->data[1];
2596 * active scan was done so we could not get dtim
2597 * information out of probe response.
2598 * so we speficially query dtim information to dongle.
2601 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2603 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2604 goto update_bss_info_out;
2606 dtim_period = (u8)var;
2609 update_bss_info_out:
2610 brcmf_dbg(TRACE, "Exit");
2614 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2616 struct escan_info *escan = &cfg->escan_info;
2618 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2619 if (cfg->scan_request) {
2620 escan->escan_state = WL_ESCAN_STATE_IDLE;
2621 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2623 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2624 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2627 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2629 struct brcmf_cfg80211_info *cfg =
2630 container_of(work, struct brcmf_cfg80211_info,
2631 escan_timeout_work);
2633 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2636 static void brcmf_escan_timeout(unsigned long data)
2638 struct brcmf_cfg80211_info *cfg =
2639 (struct brcmf_cfg80211_info *)data;
2641 if (cfg->scan_request) {
2642 brcmf_err("timer expired\n");
2643 schedule_work(&cfg->escan_timeout_work);
2648 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2649 struct brcmf_bss_info_le *bss,
2650 struct brcmf_bss_info_le *bss_info_le)
2652 struct brcmu_chan ch_bss, ch_bss_info_le;
2654 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2655 cfg->d11inf.decchspec(&ch_bss);
2656 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2657 cfg->d11inf.decchspec(&ch_bss_info_le);
2659 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2660 ch_bss.band == ch_bss_info_le.band &&
2661 bss_info_le->SSID_len == bss->SSID_len &&
2662 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2663 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2664 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2665 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2666 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2668 /* preserve max RSSI if the measurements are
2669 * both on-channel or both off-channel
2671 if (bss_info_rssi > bss_rssi)
2672 bss->RSSI = bss_info_le->RSSI;
2673 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2674 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2675 /* preserve the on-channel rssi measurement
2676 * if the new measurement is off channel
2678 bss->RSSI = bss_info_le->RSSI;
2679 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2687 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2688 const struct brcmf_event_msg *e, void *data)
2690 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2693 struct brcmf_escan_result_le *escan_result_le;
2694 struct brcmf_bss_info_le *bss_info_le;
2695 struct brcmf_bss_info_le *bss = NULL;
2697 struct brcmf_scan_results *list;
2703 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2704 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2708 if (status == BRCMF_E_STATUS_PARTIAL) {
2709 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2710 escan_result_le = (struct brcmf_escan_result_le *) data;
2711 if (!escan_result_le) {
2712 brcmf_err("Invalid escan result (NULL pointer)\n");
2715 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2716 brcmf_err("Invalid bss_count %d: ignoring\n",
2717 escan_result_le->bss_count);
2720 bss_info_le = &escan_result_le->bss_info_le;
2722 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2725 if (!cfg->scan_request) {
2726 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2730 bi_length = le32_to_cpu(bss_info_le->length);
2731 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2732 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2733 brcmf_err("Invalid bss_info length %d: ignoring\n",
2738 if (!(cfg_to_wiphy(cfg)->interface_modes &
2739 BIT(NL80211_IFTYPE_ADHOC))) {
2740 if (le16_to_cpu(bss_info_le->capability) &
2741 WLAN_CAPABILITY_IBSS) {
2742 brcmf_err("Ignoring IBSS result\n");
2747 list = (struct brcmf_scan_results *)
2748 cfg->escan_info.escan_buf;
2749 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2750 brcmf_err("Buffer is too small: ignoring\n");
2754 for (i = 0; i < list->count; i++) {
2755 bss = bss ? (struct brcmf_bss_info_le *)
2756 ((unsigned char *)bss +
2757 le32_to_cpu(bss->length)) : list->bss_info_le;
2758 if (brcmf_compare_update_same_bss(cfg, bss,
2762 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2763 bss_info_le, bi_length);
2764 list->version = le32_to_cpu(bss_info_le->version);
2765 list->buflen += bi_length;
2768 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2769 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2771 if (cfg->scan_request) {
2772 cfg->bss_list = (struct brcmf_scan_results *)
2773 cfg->escan_info.escan_buf;
2774 brcmf_inform_bss(cfg);
2775 aborted = status != BRCMF_E_STATUS_SUCCESS;
2776 brcmf_notify_escan_complete(cfg, ifp, aborted,
2779 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2786 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2788 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2789 brcmf_cfg80211_escan_handler);
2790 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2791 /* Init scan_timeout timer */
2792 init_timer(&cfg->escan_timeout);
2793 cfg->escan_timeout.data = (unsigned long) cfg;
2794 cfg->escan_timeout.function = brcmf_escan_timeout;
2795 INIT_WORK(&cfg->escan_timeout_work,
2796 brcmf_cfg80211_escan_timeout_worker);
2799 static __always_inline void brcmf_delay(u32 ms)
2801 if (ms < 1000 / HZ) {
2809 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2811 brcmf_dbg(TRACE, "Enter\n");
2816 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2817 struct cfg80211_wowlan *wow)
2819 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2820 struct net_device *ndev = cfg_to_ndev(cfg);
2821 struct brcmf_cfg80211_vif *vif;
2823 brcmf_dbg(TRACE, "Enter\n");
2826 * if the primary net_device is not READY there is nothing
2827 * we can do but pray resume goes smoothly.
2829 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2830 if (!check_vif_up(vif))
2833 list_for_each_entry(vif, &cfg->vif_list, list) {
2834 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2837 * While going to suspend if associated with AP disassociate
2838 * from AP to save power while system is in suspended state
2840 brcmf_link_down(vif);
2842 /* Make sure WPA_Supplicant receives all the event
2843 * generated due to DISASSOC call to the fw to keep
2844 * the state fw and WPA_Supplicant state consistent
2849 /* end any scanning */
2850 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2851 brcmf_abort_scanning(cfg);
2853 /* Turn off watchdog timer */
2854 brcmf_set_mpc(netdev_priv(ndev), 1);
2857 brcmf_dbg(TRACE, "Exit\n");
2858 /* clear any scanning activity */
2859 cfg->scan_status = 0;
2864 brcmf_update_pmklist(struct net_device *ndev,
2865 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2870 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2872 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2873 for (i = 0; i < pmkid_len; i++) {
2874 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2875 &pmk_list->pmkids.pmkid[i].BSSID);
2876 for (j = 0; j < WLAN_PMKID_LEN; j++)
2877 brcmf_dbg(CONN, "%02x\n",
2878 pmk_list->pmkids.pmkid[i].PMKID[j]);
2882 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2883 (char *)pmk_list, sizeof(*pmk_list));
2889 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2890 struct cfg80211_pmksa *pmksa)
2892 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2893 struct brcmf_if *ifp = netdev_priv(ndev);
2894 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2899 brcmf_dbg(TRACE, "Enter\n");
2900 if (!check_vif_up(ifp->vif))
2903 pmkid_len = le32_to_cpu(pmkids->npmkid);
2904 for (i = 0; i < pmkid_len; i++)
2905 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2907 if (i < WL_NUM_PMKIDS_MAX) {
2908 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2909 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2910 if (i == pmkid_len) {
2912 pmkids->npmkid = cpu_to_le32(pmkid_len);
2917 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2918 pmkids->pmkid[pmkid_len].BSSID);
2919 for (i = 0; i < WLAN_PMKID_LEN; i++)
2920 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2922 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2924 brcmf_dbg(TRACE, "Exit\n");
2929 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2930 struct cfg80211_pmksa *pmksa)
2932 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2933 struct brcmf_if *ifp = netdev_priv(ndev);
2934 struct pmkid_list pmkid;
2938 brcmf_dbg(TRACE, "Enter\n");
2939 if (!check_vif_up(ifp->vif))
2942 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2943 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2945 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2946 &pmkid.pmkid[0].BSSID);
2947 for (i = 0; i < WLAN_PMKID_LEN; i++)
2948 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2950 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2951 for (i = 0; i < pmkid_len; i++)
2953 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2958 && (i < pmkid_len)) {
2959 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2960 sizeof(struct pmkid));
2961 for (; i < (pmkid_len - 1); i++) {
2962 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2963 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2965 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2966 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2969 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2973 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2975 brcmf_dbg(TRACE, "Exit\n");
2981 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2983 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2984 struct brcmf_if *ifp = netdev_priv(ndev);
2987 brcmf_dbg(TRACE, "Enter\n");
2988 if (!check_vif_up(ifp->vif))
2991 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2992 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2994 brcmf_dbg(TRACE, "Exit\n");
3000 * PFN result doesn't have all the info which are
3001 * required by the supplicant
3002 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3003 * via wl_inform_single_bss in the required format. Escan does require the
3004 * scan request in the form of cfg80211_scan_request. For timebeing, create
3005 * cfg80211_scan_request one out of the received PNO event.
3008 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3009 const struct brcmf_event_msg *e, void *data)
3011 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3012 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3013 struct cfg80211_scan_request *request = NULL;
3014 struct cfg80211_ssid *ssid = NULL;
3015 struct ieee80211_channel *channel = NULL;
3016 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3018 int channel_req = 0;
3020 struct brcmf_pno_scanresults_le *pfn_result;
3024 brcmf_dbg(SCAN, "Enter\n");
3026 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3027 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3031 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3032 result_count = le32_to_cpu(pfn_result->count);
3033 status = le32_to_cpu(pfn_result->status);
3036 * PFN event is limited to fit 512 bytes so we may get
3037 * multiple NET_FOUND events. For now place a warning here.
3039 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3040 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3041 if (result_count > 0) {
3044 request = kzalloc(sizeof(*request), GFP_KERNEL);
3045 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3046 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3047 if (!request || !ssid || !channel) {
3052 request->wiphy = wiphy;
3053 data += sizeof(struct brcmf_pno_scanresults_le);
3054 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3056 for (i = 0; i < result_count; i++) {
3057 netinfo = &netinfo_start[i];
3059 brcmf_err("Invalid netinfo ptr. index: %d\n",
3065 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3066 netinfo->SSID, netinfo->channel);
3067 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3068 ssid[i].ssid_len = netinfo->SSID_len;
3071 channel_req = netinfo->channel;
3072 if (channel_req <= CH_MAX_2G_CHANNEL)
3073 band = NL80211_BAND_2GHZ;
3075 band = NL80211_BAND_5GHZ;
3076 channel[i].center_freq =
3077 ieee80211_channel_to_frequency(channel_req,
3079 channel[i].band = band;
3080 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3081 request->channels[i] = &channel[i];
3082 request->n_channels++;
3085 /* assign parsed ssid array */
3086 if (request->n_ssids)
3087 request->ssids = &ssid[0];
3089 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3090 /* Abort any on-going scan */
3091 brcmf_abort_scanning(cfg);
3094 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3095 cfg->escan_info.run = brcmf_run_escan;
3096 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3098 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3101 cfg->sched_escan = true;
3102 cfg->scan_request = request;
3104 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3117 cfg80211_sched_scan_stopped(wiphy);
3121 static int brcmf_dev_pno_clean(struct net_device *ndev)
3126 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3129 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3133 brcmf_err("failed code %d\n", ret);
3138 static int brcmf_dev_pno_config(struct net_device *ndev)
3140 struct brcmf_pno_param_le pfn_param;
3142 memset(&pfn_param, 0, sizeof(pfn_param));
3143 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3145 /* set extra pno params */
3146 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3147 pfn_param.repeat = BRCMF_PNO_REPEAT;
3148 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3150 /* set up pno scan fr */
3151 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3153 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3154 &pfn_param, sizeof(pfn_param));
3158 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3159 struct net_device *ndev,
3160 struct cfg80211_sched_scan_request *request)
3162 struct brcmf_if *ifp = netdev_priv(ndev);
3163 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3164 struct brcmf_pno_net_param_le pfn;
3168 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3169 request->n_match_sets, request->n_ssids);
3170 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3171 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3174 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3175 brcmf_err("Scanning suppressed: status (%lu)\n",
3180 if (!request->n_ssids || !request->n_match_sets) {
3181 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3186 if (request->n_ssids > 0) {
3187 for (i = 0; i < request->n_ssids; i++) {
3188 /* Active scan req for ssids */
3189 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3190 request->ssids[i].ssid);
3193 * match_set ssids is a supert set of n_ssid list,
3194 * so we need not add these set seperately.
3199 if (request->n_match_sets > 0) {
3200 /* clean up everything */
3201 ret = brcmf_dev_pno_clean(ndev);
3203 brcmf_err("failed error=%d\n", ret);
3208 ret = brcmf_dev_pno_config(ndev);
3210 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3214 /* configure each match set */
3215 for (i = 0; i < request->n_match_sets; i++) {
3216 struct cfg80211_ssid *ssid;
3219 ssid = &request->match_sets[i].ssid;
3220 ssid_len = ssid->ssid_len;
3223 brcmf_err("skip broadcast ssid\n");
3226 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3227 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3228 pfn.wsec = cpu_to_le32(0);
3229 pfn.infra = cpu_to_le32(1);
3230 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3231 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3232 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3233 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3235 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3236 ret == 0 ? "set" : "failed", ssid->ssid);
3238 /* Enable the PNO */
3239 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3240 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3250 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3251 struct net_device *ndev)
3253 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3255 brcmf_dbg(SCAN, "enter\n");
3256 brcmf_dev_pno_clean(ndev);
3257 if (cfg->sched_escan)
3258 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3262 #ifdef CONFIG_NL80211_TESTMODE
3263 static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3264 struct wireless_dev *wdev,
3265 void *data, int len)
3267 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3268 struct net_device *ndev = cfg_to_ndev(cfg);
3269 struct brcmf_dcmd *dcmd = data;
3270 struct sk_buff *reply;
3273 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3274 dcmd->buf, dcmd->len);
3277 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3278 dcmd->buf, dcmd->len);
3280 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3281 dcmd->buf, dcmd->len);
3283 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3284 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3285 ret = cfg80211_testmode_reply(reply);
3291 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3296 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3298 brcmf_err("auth error %d\n", err);
3302 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3304 brcmf_err("wsec error %d\n", err);
3307 /* set upper-layer auth */
3308 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3310 brcmf_err("wpa_auth error %d\n", err);
3317 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3320 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3322 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3326 brcmf_configure_wpaie(struct net_device *ndev,
3327 const struct brcmf_vs_tlv *wpa_ie,
3330 struct brcmf_if *ifp = netdev_priv(ndev);
3331 u32 auth = 0; /* d11 open authentication */
3343 u32 wme_bss_disable;
3345 brcmf_dbg(TRACE, "Enter\n");
3349 len = wpa_ie->len + TLV_HDR_LEN;
3350 data = (u8 *)wpa_ie;
3351 offset = TLV_HDR_LEN;
3353 offset += VS_IE_FIXED_HDR_LEN;
3355 offset += WPA_IE_VERSION_LEN;
3357 /* check for multicast cipher suite */
3358 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3360 brcmf_err("no multicast cipher suite\n");
3364 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3366 brcmf_err("ivalid OUI\n");
3369 offset += TLV_OUI_LEN;
3371 /* pick up multicast cipher */
3372 switch (data[offset]) {
3373 case WPA_CIPHER_NONE:
3376 case WPA_CIPHER_WEP_40:
3377 case WPA_CIPHER_WEP_104:
3380 case WPA_CIPHER_TKIP:
3381 gval = TKIP_ENABLED;
3383 case WPA_CIPHER_AES_CCM:
3388 brcmf_err("Invalid multi cast cipher info\n");
3393 /* walk thru unicast cipher list and pick up what we recognize */
3394 count = data[offset] + (data[offset + 1] << 8);
3395 offset += WPA_IE_SUITE_COUNT_LEN;
3396 /* Check for unicast suite(s) */
3397 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3399 brcmf_err("no unicast cipher suite\n");
3402 for (i = 0; i < count; i++) {
3403 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3405 brcmf_err("ivalid OUI\n");
3408 offset += TLV_OUI_LEN;
3409 switch (data[offset]) {
3410 case WPA_CIPHER_NONE:
3412 case WPA_CIPHER_WEP_40:
3413 case WPA_CIPHER_WEP_104:
3414 pval |= WEP_ENABLED;
3416 case WPA_CIPHER_TKIP:
3417 pval |= TKIP_ENABLED;
3419 case WPA_CIPHER_AES_CCM:
3420 pval |= AES_ENABLED;
3423 brcmf_err("Ivalid unicast security info\n");
3427 /* walk thru auth management suite list and pick up what we recognize */
3428 count = data[offset] + (data[offset + 1] << 8);
3429 offset += WPA_IE_SUITE_COUNT_LEN;
3430 /* Check for auth key management suite(s) */
3431 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3433 brcmf_err("no auth key mgmt suite\n");
3436 for (i = 0; i < count; i++) {
3437 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3439 brcmf_err("ivalid OUI\n");
3442 offset += TLV_OUI_LEN;
3443 switch (data[offset]) {
3445 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3446 wpa_auth |= WPA_AUTH_NONE;
3448 case RSN_AKM_UNSPECIFIED:
3449 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3450 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3451 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3454 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3455 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3456 (wpa_auth |= WPA_AUTH_PSK);
3459 brcmf_err("Ivalid key mgmt info\n");
3465 wme_bss_disable = 1;
3466 if ((offset + RSN_CAP_LEN) <= len) {
3467 rsn_cap = data[offset] + (data[offset + 1] << 8);
3468 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3469 wme_bss_disable = 0;
3471 /* set wme_bss_disable to sync RSN Capabilities */
3472 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3475 brcmf_err("wme_bss_disable error %d\n", err);
3479 /* FOR WPS , set SES_OW_ENABLED */
3480 wsec = (pval | gval | SES_OW_ENABLED);
3483 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3485 brcmf_err("auth error %d\n", err);
3489 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3491 brcmf_err("wsec error %d\n", err);
3494 /* set upper-layer auth */
3495 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3497 brcmf_err("wpa_auth error %d\n", err);
3506 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3507 struct parsed_vndr_ies *vndr_ies)
3510 struct brcmf_vs_tlv *vndrie;
3511 struct brcmf_tlv *ie;
3512 struct parsed_vndr_ie_info *parsed_info;
3515 remaining_len = (s32)vndr_ie_len;
3516 memset(vndr_ies, 0, sizeof(*vndr_ies));
3518 ie = (struct brcmf_tlv *)vndr_ie_buf;
3520 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3522 vndrie = (struct brcmf_vs_tlv *)ie;
3523 /* len should be bigger than OUI length + one */
3524 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3525 brcmf_err("invalid vndr ie. length is too small %d\n",
3529 /* if wpa or wme ie, do not add ie */
3530 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3531 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3532 (vndrie->oui_type == WME_OUI_TYPE))) {
3533 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3537 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3539 /* save vndr ie information */
3540 parsed_info->ie_ptr = (char *)vndrie;
3541 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3542 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3546 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3547 parsed_info->vndrie.oui[0],
3548 parsed_info->vndrie.oui[1],
3549 parsed_info->vndrie.oui[2],
3550 parsed_info->vndrie.oui_type);
3552 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3555 remaining_len -= (ie->len + TLV_HDR_LEN);
3556 if (remaining_len <= TLV_HDR_LEN)
3559 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3566 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3572 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3573 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3575 iecount_le = cpu_to_le32(1);
3576 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3578 pktflag_le = cpu_to_le32(pktflag);
3579 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3581 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3583 return ie_len + VNDR_IE_HDR_SIZE;
3586 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3587 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3589 struct brcmf_if *ifp;
3590 struct vif_saved_ie *saved_ie;
3594 u8 *mgmt_ie_buf = NULL;
3595 int mgmt_ie_buf_len;
3597 u32 del_add_ie_buf_len = 0;
3598 u32 total_ie_buf_len = 0;
3599 u32 parsed_ie_buf_len = 0;
3600 struct parsed_vndr_ies old_vndr_ies;
3601 struct parsed_vndr_ies new_vndr_ies;
3602 struct parsed_vndr_ie_info *vndrie_info;
3605 int remained_buf_len;
3610 saved_ie = &vif->saved_ie;
3612 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3613 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3616 curr_ie_buf = iovar_ie_buf;
3618 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3619 mgmt_ie_buf = saved_ie->probe_req_ie;
3620 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3621 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3623 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3624 mgmt_ie_buf = saved_ie->probe_res_ie;
3625 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3626 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3628 case BRCMF_VNDR_IE_BEACON_FLAG:
3629 mgmt_ie_buf = saved_ie->beacon_ie;
3630 mgmt_ie_len = &saved_ie->beacon_ie_len;
3631 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3633 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3634 mgmt_ie_buf = saved_ie->assoc_req_ie;
3635 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3636 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3640 brcmf_err("not suitable type\n");
3644 if (vndr_ie_len > mgmt_ie_buf_len) {
3646 brcmf_err("extra IE size too big\n");
3650 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3651 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3653 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3654 for (i = 0; i < new_vndr_ies.count; i++) {
3655 vndrie_info = &new_vndr_ies.ie_info[i];
3656 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3657 vndrie_info->ie_len);
3658 parsed_ie_buf_len += vndrie_info->ie_len;
3662 if (mgmt_ie_buf && *mgmt_ie_len) {
3663 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3664 (memcmp(mgmt_ie_buf, curr_ie_buf,
3665 parsed_ie_buf_len) == 0)) {
3666 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3670 /* parse old vndr_ie */
3671 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3673 /* make a command to delete old ie */
3674 for (i = 0; i < old_vndr_ies.count; i++) {
3675 vndrie_info = &old_vndr_ies.ie_info[i];
3677 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3678 vndrie_info->vndrie.id,
3679 vndrie_info->vndrie.len,
3680 vndrie_info->vndrie.oui[0],
3681 vndrie_info->vndrie.oui[1],
3682 vndrie_info->vndrie.oui[2]);
3684 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3685 vndrie_info->ie_ptr,
3686 vndrie_info->ie_len,
3688 curr_ie_buf += del_add_ie_buf_len;
3689 total_ie_buf_len += del_add_ie_buf_len;
3694 /* Add if there is any extra IE */
3695 if (mgmt_ie_buf && parsed_ie_buf_len) {
3698 remained_buf_len = mgmt_ie_buf_len;
3700 /* make a command to add new ie */
3701 for (i = 0; i < new_vndr_ies.count; i++) {
3702 vndrie_info = &new_vndr_ies.ie_info[i];
3704 /* verify remained buf size before copy data */
3705 if (remained_buf_len < (vndrie_info->vndrie.len +
3706 VNDR_IE_VSIE_OFFSET)) {
3707 brcmf_err("no space in mgmt_ie_buf: len left %d",
3711 remained_buf_len -= (vndrie_info->ie_len +
3712 VNDR_IE_VSIE_OFFSET);
3714 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3715 vndrie_info->vndrie.id,
3716 vndrie_info->vndrie.len,
3717 vndrie_info->vndrie.oui[0],
3718 vndrie_info->vndrie.oui[1],
3719 vndrie_info->vndrie.oui[2]);
3721 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3722 vndrie_info->ie_ptr,
3723 vndrie_info->ie_len,
3726 /* save the parsed IE in wl struct */
3727 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3728 vndrie_info->ie_len);
3729 *mgmt_ie_len += vndrie_info->ie_len;
3731 curr_ie_buf += del_add_ie_buf_len;
3732 total_ie_buf_len += del_add_ie_buf_len;
3735 if (total_ie_buf_len) {
3736 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3739 brcmf_err("vndr ie set error : %d\n", err);
3743 kfree(iovar_ie_buf);
3747 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3750 BRCMF_VNDR_IE_PRBREQ_FLAG,
3751 BRCMF_VNDR_IE_PRBRSP_FLAG,
3752 BRCMF_VNDR_IE_BEACON_FLAG
3756 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3757 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3759 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3764 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3765 struct cfg80211_beacon_data *beacon)
3769 /* Set Beacon IEs to FW */
3770 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3771 beacon->tail, beacon->tail_len);
3773 brcmf_err("Set Beacon IE Failed\n");
3776 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3778 /* Set Probe Response IEs to FW */
3779 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3780 beacon->proberesp_ies,
3781 beacon->proberesp_ies_len);
3783 brcmf_err("Set Probe Resp IE Failed\n");
3785 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3791 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3792 struct cfg80211_ap_settings *settings)
3795 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3796 struct brcmf_if *ifp = netdev_priv(ndev);
3797 const struct brcmf_tlv *ssid_ie;
3798 struct brcmf_ssid_le ssid_le;
3800 const struct brcmf_tlv *rsn_ie;
3801 const struct brcmf_vs_tlv *wpa_ie;
3802 struct brcmf_join_params join_params;
3803 enum nl80211_iftype dev_role;
3804 struct brcmf_fil_bss_enable_le bss_enable;
3807 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3808 settings->chandef.chan->hw_value,
3809 settings->chandef.center_freq1, settings->chandef.width,
3810 settings->beacon_interval, settings->dtim_period);
3811 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3812 settings->ssid, settings->ssid_len, settings->auth_type,
3813 settings->inactivity_timeout);
3815 dev_role = ifp->vif->wdev.iftype;
3817 memset(&ssid_le, 0, sizeof(ssid_le));
3818 if (settings->ssid == NULL || settings->ssid_len == 0) {
3819 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3820 ssid_ie = brcmf_parse_tlvs(
3821 (u8 *)&settings->beacon.head[ie_offset],
3822 settings->beacon.head_len - ie_offset,
3827 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3828 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3829 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3831 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3832 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3835 brcmf_set_mpc(ifp, 0);
3836 brcmf_configure_arp_offload(ifp, false);
3838 /* find the RSN_IE */
3839 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3840 settings->beacon.tail_len, WLAN_EID_RSN);
3842 /* find the WPA_IE */
3843 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3844 settings->beacon.tail_len);
3846 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3847 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3848 if (wpa_ie != NULL) {
3850 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3855 err = brcmf_configure_wpaie(ndev,
3856 (struct brcmf_vs_tlv *)rsn_ie, true);
3861 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3862 brcmf_configure_opensecurity(ifp);
3865 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3867 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
3868 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3870 brcmf_err("Set Channel failed: chspec=%d, %d\n", chanspec, err);
3874 if (settings->beacon_interval) {
3875 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3876 settings->beacon_interval);
3878 brcmf_err("Beacon Interval Set Error, %d\n", err);
3882 if (settings->dtim_period) {
3883 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3884 settings->dtim_period);
3886 brcmf_err("DTIM Interval Set Error, %d\n", err);
3891 if (dev_role == NL80211_IFTYPE_AP) {
3892 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3894 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3897 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3900 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3902 brcmf_err("SET INFRA error %d\n", err);
3905 if (dev_role == NL80211_IFTYPE_AP) {
3906 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3908 brcmf_err("setting AP mode failed %d\n", err);
3911 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3913 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3917 memset(&join_params, 0, sizeof(join_params));
3918 /* join parameters starts with ssid */
3919 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3921 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3922 &join_params, sizeof(join_params));
3924 brcmf_err("SET SSID error (%d)\n", err);
3927 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3929 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3932 brcmf_err("setting ssid failed %d\n", err);
3935 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3936 bss_enable.enable = cpu_to_le32(1);
3937 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3938 sizeof(bss_enable));
3940 brcmf_err("bss_enable config failed %d\n", err);
3944 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3946 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3947 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3951 brcmf_set_mpc(ifp, 1);
3952 brcmf_configure_arp_offload(ifp, true);
3957 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3959 struct brcmf_if *ifp = netdev_priv(ndev);
3961 struct brcmf_fil_bss_enable_le bss_enable;
3962 struct brcmf_join_params join_params;
3964 brcmf_dbg(TRACE, "Enter\n");
3966 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3967 /* Due to most likely deauths outstanding we sleep */
3968 /* first to make sure they get processed by fw. */
3971 memset(&join_params, 0, sizeof(join_params));
3972 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3973 &join_params, sizeof(join_params));
3975 brcmf_err("SET SSID error (%d)\n", err);
3976 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3978 brcmf_err("BRCMF_C_UP error %d\n", err);
3979 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3981 brcmf_err("setting AP mode failed %d\n", err);
3982 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3984 brcmf_err("setting INFRA mode failed %d\n", err);
3986 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3987 bss_enable.enable = cpu_to_le32(0);
3988 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3989 sizeof(bss_enable));
3991 brcmf_err("bss_enable config failed %d\n", err);
3993 brcmf_set_mpc(ifp, 1);
3994 brcmf_configure_arp_offload(ifp, true);
3995 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3996 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4002 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4003 struct cfg80211_beacon_data *info)
4005 struct brcmf_if *ifp = netdev_priv(ndev);
4008 brcmf_dbg(TRACE, "Enter\n");
4010 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4016 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4019 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4020 struct brcmf_scb_val_le scbval;
4021 struct brcmf_if *ifp = netdev_priv(ndev);
4027 brcmf_dbg(TRACE, "Enter %pM\n", mac);
4029 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4030 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4031 if (!check_vif_up(ifp->vif))
4034 memcpy(&scbval.ea, mac, ETH_ALEN);
4035 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4036 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4037 &scbval, sizeof(scbval));
4039 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4041 brcmf_dbg(TRACE, "Exit\n");
4047 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4048 struct wireless_dev *wdev,
4049 u16 frame_type, bool reg)
4051 struct brcmf_cfg80211_vif *vif;
4054 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4056 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4057 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4059 vif->mgmt_rx_reg |= BIT(mgmt_type);
4061 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4066 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4067 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4069 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4070 struct ieee80211_channel *chan = params->chan;
4071 const u8 *buf = params->buf;
4072 size_t len = params->len;
4073 const struct ieee80211_mgmt *mgmt;
4074 struct brcmf_cfg80211_vif *vif;
4078 struct brcmf_fil_action_frame_le *action_frame;
4079 struct brcmf_fil_af_params_le *af_params;
4084 brcmf_dbg(TRACE, "Enter\n");
4088 mgmt = (const struct ieee80211_mgmt *)buf;
4090 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4091 brcmf_err("Driver only allows MGMT packet type\n");
4095 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4097 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4098 /* Right now the only reason to get a probe response */
4099 /* is for p2p listen response or for p2p GO from */
4100 /* wpa_supplicant. Unfortunately the probe is send */
4101 /* on primary ndev, while dongle wants it on the p2p */
4102 /* vif. Since this is only reason for a probe */
4103 /* response to be sent, the vif is taken from cfg. */
4104 /* If ever desired to send proberesp for non p2p */
4105 /* response then data should be checked for */
4106 /* "DIRECT-". Note in future supplicant will take */
4107 /* dedicated p2p wdev to do this and then this 'hack'*/
4108 /* is not needed anymore. */
4109 ie_offset = DOT11_MGMT_HDR_LEN +
4110 DOT11_BCN_PRB_FIXED_LEN;
4111 ie_len = len - ie_offset;
4112 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4113 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4114 err = brcmf_vif_set_mgmt_ie(vif,
4115 BRCMF_VNDR_IE_PRBRSP_FLAG,
4118 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4120 } else if (ieee80211_is_action(mgmt->frame_control)) {
4121 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4122 if (af_params == NULL) {
4123 brcmf_err("unable to allocate frame\n");
4127 action_frame = &af_params->action_frame;
4128 /* Add the packet Id */
4129 action_frame->packet_id = cpu_to_le32(*cookie);
4131 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4132 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4133 /* Add the length exepted for 802.11 header */
4134 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4135 /* Add the channel. Use the one specified as parameter if any or
4136 * the current one (got from the firmware) otherwise
4139 freq = chan->center_freq;
4141 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4143 chan_nr = ieee80211_frequency_to_channel(freq);
4144 af_params->channel = cpu_to_le32(chan_nr);
4146 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4147 le16_to_cpu(action_frame->len));
4149 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4150 *cookie, le16_to_cpu(action_frame->len), freq);
4152 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4155 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4159 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4160 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4169 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4170 struct wireless_dev *wdev,
4173 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4174 struct brcmf_cfg80211_vif *vif;
4177 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4179 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4181 brcmf_err("No p2p device available for probe response\n");
4185 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4190 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4191 struct wireless_dev *wdev,
4192 enum nl80211_crit_proto_id proto,
4195 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4196 struct brcmf_cfg80211_vif *vif;
4198 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4200 /* only DHCP support for now */
4201 if (proto != NL80211_CRIT_PROTO_DHCP)
4204 /* suppress and abort scanning */
4205 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4206 brcmf_abort_scanning(cfg);
4208 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4211 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4212 struct wireless_dev *wdev)
4214 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4215 struct brcmf_cfg80211_vif *vif;
4217 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4219 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4220 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4223 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4228 case NL80211_TDLS_DISCOVERY_REQ:
4229 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4231 case NL80211_TDLS_SETUP:
4232 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4234 case NL80211_TDLS_TEARDOWN:
4235 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4238 brcmf_err("unsupported operation: %d\n", oper);
4244 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4245 struct net_device *ndev, u8 *peer,
4246 enum nl80211_tdls_operation oper)
4248 struct brcmf_if *ifp;
4249 struct brcmf_tdls_iovar_le info;
4252 ret = brcmf_convert_nl80211_tdls_oper(oper);
4256 ifp = netdev_priv(ndev);
4257 memset(&info, 0, sizeof(info));
4258 info.mode = (u8)ret;
4260 memcpy(info.ea, peer, ETH_ALEN);
4262 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4263 &info, sizeof(info));
4265 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4270 static struct cfg80211_ops wl_cfg80211_ops = {
4271 .add_virtual_intf = brcmf_cfg80211_add_iface,
4272 .del_virtual_intf = brcmf_cfg80211_del_iface,
4273 .change_virtual_intf = brcmf_cfg80211_change_iface,
4274 .scan = brcmf_cfg80211_scan,
4275 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4276 .join_ibss = brcmf_cfg80211_join_ibss,
4277 .leave_ibss = brcmf_cfg80211_leave_ibss,
4278 .get_station = brcmf_cfg80211_get_station,
4279 .set_tx_power = brcmf_cfg80211_set_tx_power,
4280 .get_tx_power = brcmf_cfg80211_get_tx_power,
4281 .add_key = brcmf_cfg80211_add_key,
4282 .del_key = brcmf_cfg80211_del_key,
4283 .get_key = brcmf_cfg80211_get_key,
4284 .set_default_key = brcmf_cfg80211_config_default_key,
4285 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4286 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4287 .connect = brcmf_cfg80211_connect,
4288 .disconnect = brcmf_cfg80211_disconnect,
4289 .suspend = brcmf_cfg80211_suspend,
4290 .resume = brcmf_cfg80211_resume,
4291 .set_pmksa = brcmf_cfg80211_set_pmksa,
4292 .del_pmksa = brcmf_cfg80211_del_pmksa,
4293 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4294 .start_ap = brcmf_cfg80211_start_ap,
4295 .stop_ap = brcmf_cfg80211_stop_ap,
4296 .change_beacon = brcmf_cfg80211_change_beacon,
4297 .del_station = brcmf_cfg80211_del_station,
4298 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4299 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4300 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4301 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4302 .remain_on_channel = brcmf_p2p_remain_on_channel,
4303 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4304 .start_p2p_device = brcmf_p2p_start_device,
4305 .stop_p2p_device = brcmf_p2p_stop_device,
4306 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4307 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4308 .tdls_oper = brcmf_cfg80211_tdls_oper,
4309 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4312 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4314 /* scheduled scan settings */
4315 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4316 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4317 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4318 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4321 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4324 .types = BIT(NL80211_IFTYPE_STATION) |
4325 BIT(NL80211_IFTYPE_ADHOC) |
4326 BIT(NL80211_IFTYPE_AP)
4330 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4331 BIT(NL80211_IFTYPE_P2P_GO)
4335 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4338 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4340 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4341 .num_different_channels = 2,
4342 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4343 .limits = brcmf_iface_limits
4347 static const struct ieee80211_txrx_stypes
4348 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4349 [NL80211_IFTYPE_STATION] = {
4351 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4352 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4354 [NL80211_IFTYPE_P2P_CLIENT] = {
4356 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4357 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4359 [NL80211_IFTYPE_P2P_GO] = {
4361 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4362 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4363 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4364 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4365 BIT(IEEE80211_STYPE_AUTH >> 4) |
4366 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4367 BIT(IEEE80211_STYPE_ACTION >> 4)
4369 [NL80211_IFTYPE_P2P_DEVICE] = {
4371 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4372 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4376 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4378 struct wiphy *wiphy;
4381 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4383 brcmf_err("Could not allocate wiphy device\n");
4384 return ERR_PTR(-ENOMEM);
4386 set_wiphy_dev(wiphy, phydev);
4387 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4388 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4389 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4390 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4391 BIT(NL80211_IFTYPE_ADHOC) |
4392 BIT(NL80211_IFTYPE_AP) |
4393 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4394 BIT(NL80211_IFTYPE_P2P_GO) |
4395 BIT(NL80211_IFTYPE_P2P_DEVICE);
4396 wiphy->iface_combinations = brcmf_iface_combos;
4397 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4398 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4399 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4400 wiphy->cipher_suites = __wl_cipher_suites;
4401 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4402 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4403 WIPHY_FLAG_OFFCHAN_TX |
4404 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4405 WIPHY_FLAG_SUPPORTS_TDLS;
4407 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
4408 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4409 wiphy->max_remain_on_channel_duration = 5000;
4410 brcmf_wiphy_pno_params(wiphy);
4411 brcmf_dbg(INFO, "Registering custom regulatory\n");
4412 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4413 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4414 err = wiphy_register(wiphy);
4416 brcmf_err("Could not register wiphy device (%d)\n", err);
4418 return ERR_PTR(err);
4423 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4424 enum nl80211_iftype type,
4427 struct brcmf_cfg80211_vif *vif;
4429 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4431 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4433 return ERR_PTR(-ENOMEM);
4435 vif->wdev.wiphy = cfg->wiphy;
4436 vif->wdev.iftype = type;
4438 vif->pm_block = pm_block;
4441 brcmf_init_prof(&vif->profile);
4443 list_add_tail(&vif->list, &cfg->vif_list);
4447 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4449 list_del(&vif->list);
4453 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4455 struct brcmf_cfg80211_vif *vif;
4456 struct brcmf_if *ifp;
4458 ifp = netdev_priv(ndev);
4461 brcmf_free_vif(vif);
4465 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4467 u32 event = e->event_code;
4468 u32 status = e->status;
4470 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4471 brcmf_dbg(CONN, "Processing set ssid\n");
4478 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4480 u32 event = e->event_code;
4481 u16 flags = e->flags;
4483 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4484 (event == BRCMF_E_DISASSOC_IND) ||
4485 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4486 brcmf_dbg(CONN, "Processing link down\n");
4492 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4493 const struct brcmf_event_msg *e)
4495 u32 event = e->event_code;
4496 u32 status = e->status;
4498 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4499 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4500 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4504 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4505 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4512 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4514 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4516 kfree(conn_info->req_ie);
4517 conn_info->req_ie = NULL;
4518 conn_info->req_ie_len = 0;
4519 kfree(conn_info->resp_ie);
4520 conn_info->resp_ie = NULL;
4521 conn_info->resp_ie_len = 0;
4524 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4525 struct brcmf_if *ifp)
4527 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4528 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4533 brcmf_clear_assoc_ies(cfg);
4535 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4536 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4538 brcmf_err("could not get assoc info (%d)\n", err);
4542 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4543 req_len = le32_to_cpu(assoc_info->req_len);
4544 resp_len = le32_to_cpu(assoc_info->resp_len);
4546 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4550 brcmf_err("could not get assoc req (%d)\n", err);
4553 conn_info->req_ie_len = req_len;
4555 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4558 conn_info->req_ie_len = 0;
4559 conn_info->req_ie = NULL;
4562 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4566 brcmf_err("could not get assoc resp (%d)\n", err);
4569 conn_info->resp_ie_len = resp_len;
4570 conn_info->resp_ie =
4571 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4574 conn_info->resp_ie_len = 0;
4575 conn_info->resp_ie = NULL;
4577 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4578 conn_info->req_ie_len, conn_info->resp_ie_len);
4584 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4585 struct net_device *ndev,
4586 const struct brcmf_event_msg *e)
4588 struct brcmf_if *ifp = netdev_priv(ndev);
4589 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4590 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4591 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4592 struct ieee80211_channel *notify_channel = NULL;
4593 struct ieee80211_supported_band *band;
4594 struct brcmf_bss_info_le *bi;
4595 struct brcmu_chan ch;
4600 brcmf_dbg(TRACE, "Enter\n");
4602 brcmf_get_assoc_ies(cfg, ifp);
4603 memcpy(profile->bssid, e->addr, ETH_ALEN);
4604 brcmf_update_bss_info(cfg, ifp);
4606 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4612 /* data sent to dongle has to be little endian */
4613 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4614 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4615 buf, WL_BSS_INFO_MAX);
4620 bi = (struct brcmf_bss_info_le *)(buf + 4);
4621 ch.chspec = le16_to_cpu(bi->chanspec);
4622 cfg->d11inf.decchspec(&ch);
4624 if (ch.band == BRCMU_CHAN_BAND_2G)
4625 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4627 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4629 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4630 notify_channel = ieee80211_get_channel(wiphy, freq);
4634 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4635 conn_info->req_ie, conn_info->req_ie_len,
4636 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4637 brcmf_dbg(CONN, "Report roaming result\n");
4639 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4640 brcmf_dbg(TRACE, "Exit\n");
4645 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4646 struct net_device *ndev, const struct brcmf_event_msg *e,
4649 struct brcmf_if *ifp = netdev_priv(ndev);
4650 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4651 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4654 brcmf_dbg(TRACE, "Enter\n");
4656 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4657 &ifp->vif->sme_state)) {
4659 brcmf_get_assoc_ies(cfg, ifp);
4660 memcpy(profile->bssid, e->addr, ETH_ALEN);
4661 brcmf_update_bss_info(cfg, ifp);
4662 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4663 &ifp->vif->sme_state);
4665 cfg80211_connect_result(ndev,
4666 (u8 *)profile->bssid,
4668 conn_info->req_ie_len,
4670 conn_info->resp_ie_len,
4671 completed ? WLAN_STATUS_SUCCESS :
4672 WLAN_STATUS_AUTH_TIMEOUT,
4674 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4675 completed ? "succeeded" : "failed");
4677 brcmf_dbg(TRACE, "Exit\n");
4682 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4683 struct net_device *ndev,
4684 const struct brcmf_event_msg *e, void *data)
4686 static int generation;
4687 u32 event = e->event_code;
4688 u32 reason = e->reason;
4689 struct station_info sinfo;
4691 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4692 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4693 ndev != cfg_to_ndev(cfg)) {
4694 brcmf_dbg(CONN, "AP mode link down\n");
4695 complete(&cfg->vif_disabled);
4699 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4700 (reason == BRCMF_E_STATUS_SUCCESS)) {
4701 memset(&sinfo, 0, sizeof(sinfo));
4702 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4704 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4707 sinfo.assoc_req_ies = data;
4708 sinfo.assoc_req_ies_len = e->datalen;
4710 sinfo.generation = generation;
4711 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4712 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4713 (event == BRCMF_E_DEAUTH_IND) ||
4714 (event == BRCMF_E_DEAUTH)) {
4715 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4721 brcmf_notify_connect_status(struct brcmf_if *ifp,
4722 const struct brcmf_event_msg *e, void *data)
4724 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4725 struct net_device *ndev = ifp->ndev;
4726 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4727 struct ieee80211_channel *chan;
4730 if (brcmf_is_apmode(ifp->vif)) {
4731 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4732 } else if (brcmf_is_linkup(e)) {
4733 brcmf_dbg(CONN, "Linkup\n");
4734 if (brcmf_is_ibssmode(ifp->vif)) {
4735 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4736 memcpy(profile->bssid, e->addr, ETH_ALEN);
4737 wl_inform_ibss(cfg, ndev, e->addr);
4738 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4739 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4740 &ifp->vif->sme_state);
4741 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4742 &ifp->vif->sme_state);
4744 brcmf_bss_connect_done(cfg, ndev, e, true);
4745 } else if (brcmf_is_linkdown(e)) {
4746 brcmf_dbg(CONN, "Linkdown\n");
4747 if (!brcmf_is_ibssmode(ifp->vif)) {
4748 brcmf_bss_connect_done(cfg, ndev, e, false);
4750 brcmf_link_down(ifp->vif);
4751 brcmf_init_prof(ndev_to_prof(ndev));
4752 if (ndev != cfg_to_ndev(cfg))
4753 complete(&cfg->vif_disabled);
4754 } else if (brcmf_is_nonetwork(cfg, e)) {
4755 if (brcmf_is_ibssmode(ifp->vif))
4756 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4757 &ifp->vif->sme_state);
4759 brcmf_bss_connect_done(cfg, ndev, e, false);
4766 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4767 const struct brcmf_event_msg *e, void *data)
4769 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4771 u32 event = e->event_code;
4772 u32 status = e->status;
4774 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4775 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4776 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4778 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4785 brcmf_notify_mic_status(struct brcmf_if *ifp,
4786 const struct brcmf_event_msg *e, void *data)
4788 u16 flags = e->flags;
4789 enum nl80211_key_type key_type;
4791 if (flags & BRCMF_EVENT_MSG_GROUP)
4792 key_type = NL80211_KEYTYPE_GROUP;
4794 key_type = NL80211_KEYTYPE_PAIRWISE;
4796 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4802 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4803 const struct brcmf_event_msg *e, void *data)
4805 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4806 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4807 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4808 struct brcmf_cfg80211_vif *vif;
4810 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4811 ifevent->action, ifevent->flags, ifevent->ifidx,
4814 mutex_lock(&event->vif_event_lock);
4815 event->action = ifevent->action;
4818 switch (ifevent->action) {
4819 case BRCMF_E_IF_ADD:
4820 /* waiting process may have timed out */
4821 if (!cfg->vif_event.vif) {
4822 mutex_unlock(&event->vif_event_lock);
4829 vif->wdev.netdev = ifp->ndev;
4830 ifp->ndev->ieee80211_ptr = &vif->wdev;
4831 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4833 mutex_unlock(&event->vif_event_lock);
4834 wake_up(&event->vif_wq);
4837 case BRCMF_E_IF_DEL:
4838 mutex_unlock(&event->vif_event_lock);
4839 /* event may not be upon user request */
4840 if (brcmf_cfg80211_vif_event_armed(cfg))
4841 wake_up(&event->vif_wq);
4844 case BRCMF_E_IF_CHANGE:
4845 mutex_unlock(&event->vif_event_lock);
4846 wake_up(&event->vif_wq);
4850 mutex_unlock(&event->vif_event_lock);
4856 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4858 conf->frag_threshold = (u32)-1;
4859 conf->rts_threshold = (u32)-1;
4860 conf->retry_short = (u32)-1;
4861 conf->retry_long = (u32)-1;
4862 conf->tx_power = -1;
4865 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4867 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4868 brcmf_notify_connect_status);
4869 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4870 brcmf_notify_connect_status);
4871 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4872 brcmf_notify_connect_status);
4873 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4874 brcmf_notify_connect_status);
4875 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4876 brcmf_notify_connect_status);
4877 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4878 brcmf_notify_connect_status);
4879 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4880 brcmf_notify_roaming_status);
4881 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4882 brcmf_notify_mic_status);
4883 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4884 brcmf_notify_connect_status);
4885 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4886 brcmf_notify_sched_scan_results);
4887 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4888 brcmf_notify_vif_event);
4889 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4890 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4891 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4892 brcmf_p2p_notify_listen_complete);
4893 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4894 brcmf_p2p_notify_action_frame_rx);
4895 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4896 brcmf_p2p_notify_action_tx_complete);
4897 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4898 brcmf_p2p_notify_action_tx_complete);
4901 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4905 kfree(cfg->escan_ioctl_buf);
4906 cfg->escan_ioctl_buf = NULL;
4907 kfree(cfg->extra_buf);
4908 cfg->extra_buf = NULL;
4909 kfree(cfg->pmk_list);
4910 cfg->pmk_list = NULL;
4913 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4915 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4917 goto init_priv_mem_out;
4918 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4919 if (!cfg->escan_ioctl_buf)
4920 goto init_priv_mem_out;
4921 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4922 if (!cfg->extra_buf)
4923 goto init_priv_mem_out;
4924 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4926 goto init_priv_mem_out;
4931 brcmf_deinit_priv_mem(cfg);
4936 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4940 cfg->scan_request = NULL;
4941 cfg->pwr_save = true;
4942 cfg->active_scan = true; /* we do active scan per default */
4943 cfg->dongle_up = false; /* dongle is not up yet */
4944 err = brcmf_init_priv_mem(cfg);
4947 brcmf_register_event_handlers(cfg);
4948 mutex_init(&cfg->usr_sync);
4949 brcmf_init_escan(cfg);
4950 brcmf_init_conf(cfg->conf);
4951 init_completion(&cfg->vif_disabled);
4955 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4957 cfg->dongle_up = false; /* dongle down */
4958 brcmf_abort_scanning(cfg);
4959 brcmf_deinit_priv_mem(cfg);
4962 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4964 init_waitqueue_head(&event->vif_wq);
4965 mutex_init(&event->vif_event_lock);
4968 static int brcmf_enable_bw40_2g(struct brcmf_if *ifp)
4970 struct brcmf_fil_bwcap_le band_bwcap;
4974 /* verify support for bw_cap command */
4976 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
4979 /* only set 2G bandwidth using bw_cap command */
4980 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
4981 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
4982 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
4983 sizeof(band_bwcap));
4985 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
4986 val = WLC_N_BW_40ALL;
4987 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
4992 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4993 struct device *busdev)
4995 struct net_device *ndev = drvr->iflist[0]->ndev;
4996 struct brcmf_cfg80211_info *cfg;
4997 struct wiphy *wiphy;
4998 struct brcmf_cfg80211_vif *vif;
4999 struct brcmf_if *ifp;
5004 brcmf_err("ndev is invalid\n");
5008 ifp = netdev_priv(ndev);
5009 wiphy = brcmf_setup_wiphy(busdev);
5013 cfg = wiphy_priv(wiphy);
5016 init_vif_event(&cfg->vif_event);
5017 INIT_LIST_HEAD(&cfg->vif_list);
5019 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
5026 vif->wdev.netdev = ndev;
5027 ndev->ieee80211_ptr = &vif->wdev;
5028 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
5030 err = wl_init_priv(cfg);
5032 brcmf_err("Failed to init iwm_priv (%d)\n", err);
5033 goto cfg80211_attach_out;
5037 err = brcmf_p2p_attach(cfg);
5039 brcmf_err("P2P initilisation failed (%d)\n", err);
5040 goto cfg80211_p2p_attach_out;
5042 err = brcmf_btcoex_attach(cfg);
5044 brcmf_err("BT-coex initialisation failed (%d)\n", err);
5045 brcmf_p2p_detach(&cfg->p2p);
5046 goto cfg80211_p2p_attach_out;
5049 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5050 * setup 40MHz in 2GHz band and enable OBSS scanning.
5052 if (wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap &
5053 IEEE80211_HT_CAP_SUP_WIDTH_20_40) {
5054 err = brcmf_enable_bw40_2g(ifp);
5056 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
5057 BRCMF_OBSS_COEX_AUTO);
5060 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
5062 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
5063 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
5066 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
5069 brcmf_err("Failed to get D11 version (%d)\n", err);
5070 goto cfg80211_p2p_attach_out;
5072 cfg->d11inf.io_type = (u8)io_type;
5073 brcmu_d11_attach(&cfg->d11inf);
5077 cfg80211_p2p_attach_out:
5078 wl_deinit_priv(cfg);
5080 cfg80211_attach_out:
5081 brcmf_free_vif(vif);
5085 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5090 WARN_ON(!list_empty(&cfg->vif_list));
5091 wiphy_unregister(cfg->wiphy);
5092 brcmf_btcoex_detach(cfg);
5093 wl_deinit_priv(cfg);
5094 wiphy_free(cfg->wiphy);
5098 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5101 __le32 roamtrigger[2];
5102 __le32 roam_delta[2];
5105 * Setup timeout if Beacons are lost and roam is
5106 * off to report link down
5108 if (brcmf_roamoff) {
5109 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5111 brcmf_err("bcn_timeout error (%d)\n", err);
5112 goto dongle_rom_out;
5117 * Enable/Disable built-in roaming to allow supplicant
5118 * to take care of roaming
5120 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5121 brcmf_roamoff ? "Off" : "On");
5122 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5124 brcmf_err("roam_off error (%d)\n", err);
5125 goto dongle_rom_out;
5128 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5129 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5130 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5131 (void *)roamtrigger, sizeof(roamtrigger));
5133 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5134 goto dongle_rom_out;
5137 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5138 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5139 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5140 (void *)roam_delta, sizeof(roam_delta));
5142 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5143 goto dongle_rom_out;
5151 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5152 s32 scan_unassoc_time, s32 scan_passive_time)
5156 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5159 if (err == -EOPNOTSUPP)
5160 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5162 brcmf_err("Scan assoc time error (%d)\n", err);
5163 goto dongle_scantime_out;
5165 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5168 if (err == -EOPNOTSUPP)
5169 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5171 brcmf_err("Scan unassoc time error (%d)\n", err);
5172 goto dongle_scantime_out;
5175 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5178 if (err == -EOPNOTSUPP)
5179 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5181 brcmf_err("Scan passive time error (%d)\n", err);
5182 goto dongle_scantime_out;
5185 dongle_scantime_out:
5190 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5193 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5194 struct ieee80211_channel *band_chan_arr;
5195 struct brcmf_chanspec_list *list;
5196 struct brcmu_chan ch;
5201 enum ieee80211_band band;
5209 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5214 list = (struct brcmf_chanspec_list *)pbuf;
5216 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5219 brcmf_err("get chanspecs error (%d)\n", err);
5223 __wl_band_2ghz.n_channels = 0;
5224 __wl_band_5ghz_a.n_channels = 0;
5226 total = le32_to_cpu(list->count);
5227 for (i = 0; i < total; i++) {
5228 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5229 cfg->d11inf.decchspec(&ch);
5231 if (ch.band == BRCMU_CHAN_BAND_2G) {
5232 band_chan_arr = __wl_2ghz_channels;
5233 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5234 n_cnt = &__wl_band_2ghz.n_channels;
5235 band = IEEE80211_BAND_2GHZ;
5236 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5237 band_chan_arr = __wl_5ghz_a_channels;
5238 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5239 n_cnt = &__wl_band_5ghz_a.n_channels;
5240 band = IEEE80211_BAND_5GHZ;
5242 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5245 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5246 ch.bw == BRCMU_CHAN_BW_40)
5248 if (!(bw_cap[band] & WLC_BW_80MHZ_BIT) &&
5249 ch.bw == BRCMU_CHAN_BW_80)
5252 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5253 if (band_chan_arr[j].hw_value == ch.chnum) {
5262 if (index < array_size) {
5263 band_chan_arr[index].center_freq =
5264 ieee80211_channel_to_frequency(ch.chnum, band);
5265 band_chan_arr[index].hw_value = ch.chnum;
5267 /* assuming the chanspecs order is HT20,
5268 * HT40 upper, HT40 lower, and VHT80.
5270 if (ch.bw == BRCMU_CHAN_BW_80) {
5271 band_chan_arr[index].flags &=
5272 ~IEEE80211_CHAN_NO_80MHZ;
5273 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5274 ht40_flag = band_chan_arr[index].flags &
5275 IEEE80211_CHAN_NO_HT40;
5276 if (ch.sb == BRCMU_CHAN_SB_U) {
5277 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5278 band_chan_arr[index].flags &=
5279 ~IEEE80211_CHAN_NO_HT40;
5280 band_chan_arr[index].flags |=
5281 IEEE80211_CHAN_NO_HT40PLUS;
5283 /* It should be one of
5284 * IEEE80211_CHAN_NO_HT40 or
5285 * IEEE80211_CHAN_NO_HT40PLUS
5287 band_chan_arr[index].flags &=
5288 ~IEEE80211_CHAN_NO_HT40;
5289 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5290 band_chan_arr[index].flags |=
5291 IEEE80211_CHAN_NO_HT40MINUS;
5294 /* disable other bandwidths for now as mentioned
5295 * order assure they are enabled for subsequent
5298 band_chan_arr[index].flags =
5299 IEEE80211_CHAN_NO_HT40 |
5300 IEEE80211_CHAN_NO_80MHZ;
5301 ch.bw = BRCMU_CHAN_BW_20;
5302 cfg->d11inf.encchspec(&ch);
5303 channel = ch.chspec;
5304 err = brcmf_fil_bsscfg_int_get(ifp,
5308 if (channel & WL_CHAN_RADAR)
5309 band_chan_arr[index].flags |=
5310 (IEEE80211_CHAN_RADAR |
5311 IEEE80211_CHAN_NO_IR);
5312 if (channel & WL_CHAN_PASSIVE)
5313 band_chan_arr[index].flags |=
5314 IEEE80211_CHAN_NO_IR;
5326 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5328 u32 band, mimo_bwcap;
5332 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5334 bw_cap[IEEE80211_BAND_2GHZ] = band;
5336 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5338 bw_cap[IEEE80211_BAND_5GHZ] = band;
5344 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5346 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5348 /* assume 20MHz if firmware does not give a clue */
5349 mimo_bwcap = WLC_N_BW_20ALL;
5351 switch (mimo_bwcap) {
5352 case WLC_N_BW_40ALL:
5353 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5355 case WLC_N_BW_20IN2G_40IN5G:
5356 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5358 case WLC_N_BW_20ALL:
5359 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5360 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5363 brcmf_err("invalid mimo_bw_cap value\n");
5367 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5368 u32 bw_cap[2], u32 nchain)
5370 band->ht_cap.ht_supported = true;
5371 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5372 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5373 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5375 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5376 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5377 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5378 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5379 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5380 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5383 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5388 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5389 mcs_map = (mcs_map << 2) | supp;
5391 return cpu_to_le16(mcs_map);
5394 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5395 u32 bw_cap[2], u32 nchain)
5399 /* not allowed in 2.4G band */
5400 if (band->band == IEEE80211_BAND_2GHZ)
5403 band->vht_cap.vht_supported = true;
5404 /* 80MHz is mandatory */
5405 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5406 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5407 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5408 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5410 /* all support 256-QAM */
5411 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5412 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5413 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5416 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5418 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5419 struct wiphy *wiphy;
5424 u32 bw_cap[2] = { 0, 0 };
5431 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5432 struct ieee80211_supported_band *band;
5434 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5435 &phy_list, sizeof(phy_list));
5437 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5441 phy = ((char *)&phy_list)[0];
5442 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5445 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5446 &band_list, sizeof(band_list));
5448 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5451 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5452 band_list[0], band_list[1], band_list[2]);
5454 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5455 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5457 brcmf_err("nmode error (%d)\n", err);
5459 brcmf_get_bwcap(ifp, bw_cap);
5461 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5462 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5463 bw_cap[IEEE80211_BAND_5GHZ]);
5465 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5467 brcmf_err("rxchain error (%d)\n", err);
5470 for (nchain = 0; rxchain; nchain++)
5471 rxchain = rxchain & (rxchain - 1);
5473 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5475 err = brcmf_construct_reginfo(cfg, bw_cap);
5477 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5481 nband = band_list[0];
5483 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5485 if ((band_list[i] == WLC_BAND_5G) &&
5486 (__wl_band_5ghz_a.n_channels > 0))
5487 band = &__wl_band_5ghz_a;
5488 else if ((band_list[i] == WLC_BAND_2G) &&
5489 (__wl_band_2ghz.n_channels > 0))
5490 band = &__wl_band_2ghz;
5495 brcmf_update_ht_cap(band, bw_cap, nchain);
5497 brcmf_update_vht_cap(band, bw_cap, nchain);
5498 bands[band->band] = band;
5501 wiphy = cfg_to_wiphy(cfg);
5502 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5503 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5504 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5510 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5512 return brcmf_update_wiphybands(cfg);
5515 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5517 struct net_device *ndev;
5518 struct wireless_dev *wdev;
5519 struct brcmf_if *ifp;
5526 ndev = cfg_to_ndev(cfg);
5527 wdev = ndev->ieee80211_ptr;
5528 ifp = netdev_priv(ndev);
5530 /* make sure RF is ready for work */
5531 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5533 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5534 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5536 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5537 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5539 goto default_conf_out;
5540 brcmf_dbg(INFO, "power save set to %s\n",
5541 (power_mode ? "enabled" : "disabled"));
5543 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5545 goto default_conf_out;
5546 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5549 goto default_conf_out;
5550 err = brcmf_dongle_probecap(cfg);
5552 goto default_conf_out;
5554 brcmf_configure_arp_offload(ifp, true);
5556 cfg->dongle_up = true;
5563 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5565 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5567 return brcmf_config_dongle(ifp->drvr->config);
5570 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5572 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5575 * While going down, if associated with AP disassociate
5576 * from AP to save power
5578 if (check_vif_up(ifp->vif)) {
5579 brcmf_link_down(ifp->vif);
5581 /* Make sure WPA_Supplicant receives all the event
5582 generated due to DISASSOC call to the fw to keep
5583 the state fw and WPA_Supplicant state consistent
5588 brcmf_abort_scanning(cfg);
5589 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5594 s32 brcmf_cfg80211_up(struct net_device *ndev)
5596 struct brcmf_if *ifp = netdev_priv(ndev);
5597 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5600 mutex_lock(&cfg->usr_sync);
5601 err = __brcmf_cfg80211_up(ifp);
5602 mutex_unlock(&cfg->usr_sync);
5607 s32 brcmf_cfg80211_down(struct net_device *ndev)
5609 struct brcmf_if *ifp = netdev_priv(ndev);
5610 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5613 mutex_lock(&cfg->usr_sync);
5614 err = __brcmf_cfg80211_down(ifp);
5615 mutex_unlock(&cfg->usr_sync);
5620 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5622 struct wireless_dev *wdev = &ifp->vif->wdev;
5624 return wdev->iftype;
5627 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5629 struct brcmf_cfg80211_vif *vif;
5632 list_for_each_entry(vif, &cfg->vif_list, list) {
5633 if (test_bit(state, &vif->sme_state))
5639 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5644 mutex_lock(&event->vif_event_lock);
5645 evt_action = event->action;
5646 mutex_unlock(&event->vif_event_lock);
5647 return evt_action == action;
5650 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5651 struct brcmf_cfg80211_vif *vif)
5653 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5655 mutex_lock(&event->vif_event_lock);
5658 mutex_unlock(&event->vif_event_lock);
5661 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5663 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5666 mutex_lock(&event->vif_event_lock);
5667 armed = event->vif != NULL;
5668 mutex_unlock(&event->vif_event_lock);
5672 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5673 u8 action, ulong timeout)
5675 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5677 return wait_event_timeout(event->vif_wq,
5678 vif_event_equals(event, action), timeout);