2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <linux/module.h>
22 #include <linux/vmalloc.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
26 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
31 #include "tracepoint.h"
32 #include "fwil_types.h"
43 #define BRCMF_SCAN_IE_LEN_MAX 2048
44 #define BRCMF_PNO_VERSION 2
45 #define BRCMF_PNO_TIME 30
46 #define BRCMF_PNO_REPEAT 4
47 #define BRCMF_PNO_FREQ_EXPO_MAX 3
48 #define BRCMF_PNO_MAX_PFN_COUNT 16
49 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
50 #define BRCMF_PNO_HIDDEN_BIT 2
51 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
52 #define BRCMF_PNO_SCAN_COMPLETE 1
53 #define BRCMF_PNO_SCAN_INCOMPLETE 0
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
59 #define WPS_OUI_TYPE 4
61 #define VS_IE_FIXED_HDR_LEN 6
62 #define WPA_IE_VERSION_LEN 2
63 #define WPA_IE_MIN_OUI_LEN 4
64 #define WPA_IE_SUITE_COUNT_LEN 2
66 #define WPA_CIPHER_NONE 0 /* None */
67 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
72 #define RSN_AKM_NONE 0 /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74 #define RSN_AKM_PSK 2 /* Pre-shared Key */
75 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
81 #define VNDR_IE_COUNT_OFFSET 4
82 #define VNDR_IE_PKTFLAG_OFFSET 8
83 #define VNDR_IE_VSIE_OFFSET 12
84 #define VNDR_IE_HDR_SIZE 12
85 #define VNDR_IE_PARSE_LIMIT 5
87 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
91 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
92 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
97 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
99 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
100 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
107 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
108 #define RATETAB_ENT(_rateid, _flags) \
110 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
111 .hw_value = (_rateid), \
115 static struct ieee80211_rate __wl_rates[] = {
116 RATETAB_ENT(BRCM_RATE_1M, 0),
117 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
118 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATETAB_ENT(BRCM_RATE_6M, 0),
121 RATETAB_ENT(BRCM_RATE_9M, 0),
122 RATETAB_ENT(BRCM_RATE_12M, 0),
123 RATETAB_ENT(BRCM_RATE_18M, 0),
124 RATETAB_ENT(BRCM_RATE_24M, 0),
125 RATETAB_ENT(BRCM_RATE_36M, 0),
126 RATETAB_ENT(BRCM_RATE_48M, 0),
127 RATETAB_ENT(BRCM_RATE_54M, 0),
130 #define wl_g_rates (__wl_rates + 0)
131 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
132 #define wl_a_rates (__wl_rates + 4)
133 #define wl_a_rates_size (wl_g_rates_size - 4)
135 #define CHAN2G(_channel, _freq) { \
136 .band = IEEE80211_BAND_2GHZ, \
137 .center_freq = (_freq), \
138 .hw_value = (_channel), \
139 .flags = IEEE80211_CHAN_DISABLED, \
140 .max_antenna_gain = 0, \
144 #define CHAN5G(_channel) { \
145 .band = IEEE80211_BAND_5GHZ, \
146 .center_freq = 5000 + (5 * (_channel)), \
147 .hw_value = (_channel), \
148 .flags = IEEE80211_CHAN_DISABLED, \
149 .max_antenna_gain = 0, \
153 static struct ieee80211_channel __wl_2ghz_channels[] = {
154 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
155 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
156 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
157 CHAN2G(13, 2472), CHAN2G(14, 2484)
160 static struct ieee80211_channel __wl_5ghz_channels[] = {
161 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
162 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
163 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
164 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
165 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
166 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
169 /* Band templates duplicated per wiphy. The channel info
170 * above is added to the band during setup.
172 static const struct ieee80211_supported_band __wl_band_2ghz = {
173 .band = IEEE80211_BAND_2GHZ,
174 .bitrates = wl_g_rates,
175 .n_bitrates = wl_g_rates_size,
178 static const struct ieee80211_supported_band __wl_band_5ghz = {
179 .band = IEEE80211_BAND_5GHZ,
180 .bitrates = wl_a_rates,
181 .n_bitrates = wl_a_rates_size,
184 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
185 * By default world regulatory domain defined in reg.c puts the flags
186 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
187 * With respect to these flags, wpa_supplicant doesn't * start p2p
188 * operations on 5GHz channels. All the changes in world regulatory
189 * domain are to be done here.
191 static const struct ieee80211_regdomain brcmf_regdom = {
195 /* IEEE 802.11b/g, channels 1..11 */
196 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
198 /* IEEE 802.11 channel 14 - Only JP enables
199 * this and for 802.11b only
201 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
202 /* IEEE 802.11a, channel 36..64 */
203 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
204 /* IEEE 802.11a, channel 100..165 */
205 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
208 static const u32 __wl_cipher_suites[] = {
209 WLAN_CIPHER_SUITE_WEP40,
210 WLAN_CIPHER_SUITE_WEP104,
211 WLAN_CIPHER_SUITE_TKIP,
212 WLAN_CIPHER_SUITE_CCMP,
213 WLAN_CIPHER_SUITE_AES_CMAC,
216 /* Vendor specific ie. id = 221, oui and type defines exact ie */
217 struct brcmf_vs_tlv {
224 struct parsed_vndr_ie_info {
226 u32 ie_len; /* total length including id & length field */
227 struct brcmf_vs_tlv vndrie;
230 struct parsed_vndr_ies {
232 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
235 static int brcmf_roamoff;
236 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
237 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
239 /* Quarter dBm units to mW
240 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
241 * Table is offset so the last entry is largest mW value that fits in
245 #define QDBM_OFFSET 153 /* Offset for first entry */
246 #define QDBM_TABLE_LEN 40 /* Table size */
248 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
249 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
251 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
253 /* Largest mW value that will round down to the last table entry,
254 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
255 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
256 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
258 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
260 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
261 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
262 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
263 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
264 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
265 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
266 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
269 static u16 brcmf_qdbm_to_mw(u8 qdbm)
272 int idx = qdbm - QDBM_OFFSET;
274 if (idx >= QDBM_TABLE_LEN)
275 /* clamp to max u16 mW value */
278 /* scale the qdBm index up to the range of the table 0-40
279 * where an offset of 40 qdBm equals a factor of 10 mW.
286 /* return the mW value scaled down to the correct factor of 10,
287 * adding in factor/2 to get proper rounding.
289 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
292 static u8 brcmf_mw_to_qdbm(u16 mw)
299 /* handle boundary case */
303 offset = QDBM_OFFSET;
305 /* move mw into the range of the table */
306 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
311 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
312 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
313 nqdBm_to_mW_map[qdbm]) / 2;
314 if (mw_uint < boundary)
323 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
324 struct cfg80211_chan_def *ch)
326 struct brcmu_chan ch_inf;
329 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
330 ch->chan->center_freq, ch->center_freq1, ch->width);
331 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
332 primary_offset = ch->center_freq1 - ch->chan->center_freq;
334 case NL80211_CHAN_WIDTH_20:
335 case NL80211_CHAN_WIDTH_20_NOHT:
336 ch_inf.bw = BRCMU_CHAN_BW_20;
337 WARN_ON(primary_offset != 0);
339 case NL80211_CHAN_WIDTH_40:
340 ch_inf.bw = BRCMU_CHAN_BW_40;
341 if (primary_offset < 0)
342 ch_inf.sb = BRCMU_CHAN_SB_U;
344 ch_inf.sb = BRCMU_CHAN_SB_L;
346 case NL80211_CHAN_WIDTH_80:
347 ch_inf.bw = BRCMU_CHAN_BW_80;
348 if (primary_offset < 0) {
349 if (primary_offset < -CH_10MHZ_APART)
350 ch_inf.sb = BRCMU_CHAN_SB_UU;
352 ch_inf.sb = BRCMU_CHAN_SB_UL;
354 if (primary_offset > CH_10MHZ_APART)
355 ch_inf.sb = BRCMU_CHAN_SB_LL;
357 ch_inf.sb = BRCMU_CHAN_SB_LU;
360 case NL80211_CHAN_WIDTH_80P80:
361 case NL80211_CHAN_WIDTH_160:
362 case NL80211_CHAN_WIDTH_5:
363 case NL80211_CHAN_WIDTH_10:
367 switch (ch->chan->band) {
368 case IEEE80211_BAND_2GHZ:
369 ch_inf.band = BRCMU_CHAN_BAND_2G;
371 case IEEE80211_BAND_5GHZ:
372 ch_inf.band = BRCMU_CHAN_BAND_5G;
374 case IEEE80211_BAND_60GHZ:
378 d11inf->encchspec(&ch_inf);
380 return ch_inf.chspec;
383 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
384 struct ieee80211_channel *ch)
386 struct brcmu_chan ch_inf;
388 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
389 ch_inf.bw = BRCMU_CHAN_BW_20;
390 d11inf->encchspec(&ch_inf);
392 return ch_inf.chspec;
395 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
396 * triples, returning a pointer to the substring whose first element
399 const struct brcmf_tlv *
400 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
402 const struct brcmf_tlv *elt = buf;
405 /* find tagged parameter */
406 while (totlen >= TLV_HDR_LEN) {
409 /* validate remaining totlen */
410 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
413 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
414 totlen -= (len + TLV_HDR_LEN);
420 /* Is any of the tlvs the expected entry? If
421 * not update the tlvs buffer pointer/length.
424 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
425 const u8 *oui, u32 oui_len, u8 type)
427 /* If the contents match the OUI and the type */
428 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
429 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
430 type == ie[TLV_BODY_OFF + oui_len]) {
436 /* point to the next ie */
437 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
438 /* calculate the length of the rest of the buffer */
439 *tlvs_len -= (int)(ie - *tlvs);
440 /* update the pointer to the start of the buffer */
446 static struct brcmf_vs_tlv *
447 brcmf_find_wpaie(const u8 *parse, u32 len)
449 const struct brcmf_tlv *ie;
451 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
452 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
453 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
454 return (struct brcmf_vs_tlv *)ie;
459 static struct brcmf_vs_tlv *
460 brcmf_find_wpsie(const u8 *parse, u32 len)
462 const struct brcmf_tlv *ie;
464 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
465 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
466 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
467 return (struct brcmf_vs_tlv *)ie;
472 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
473 struct brcmf_cfg80211_vif *vif,
474 enum nl80211_iftype new_type)
476 int iftype_num[NUM_NL80211_IFTYPES];
477 struct brcmf_cfg80211_vif *pos;
479 memset(&iftype_num[0], 0, sizeof(iftype_num));
480 list_for_each_entry(pos, &cfg->vif_list, list)
482 iftype_num[new_type]++;
484 iftype_num[pos->wdev.iftype]++;
486 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
489 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
490 enum nl80211_iftype new_type)
492 int iftype_num[NUM_NL80211_IFTYPES];
493 struct brcmf_cfg80211_vif *pos;
495 memset(&iftype_num[0], 0, sizeof(iftype_num));
496 list_for_each_entry(pos, &cfg->vif_list, list)
497 iftype_num[pos->wdev.iftype]++;
499 iftype_num[new_type]++;
500 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
503 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
504 struct brcmf_wsec_key_le *key_le)
506 key_le->index = cpu_to_le32(key->index);
507 key_le->len = cpu_to_le32(key->len);
508 key_le->algo = cpu_to_le32(key->algo);
509 key_le->flags = cpu_to_le32(key->flags);
510 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
511 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
512 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
513 memcpy(key_le->data, key->data, sizeof(key->data));
514 memcpy(key_le->ea, key->ea, sizeof(key->ea));
518 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
521 struct brcmf_wsec_key_le key_le;
523 convert_key_from_CPU(key, &key_le);
525 brcmf_netdev_wait_pend8021x(ifp);
527 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
531 brcmf_err("wsec_key error (%d)\n", err);
536 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
542 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
546 /* Try to set and enable ARP offload feature, this may fail, then it */
547 /* is simply not supported and err 0 will be returned */
548 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
550 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
554 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
556 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
560 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
568 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
570 struct brcmf_cfg80211_vif *vif;
571 struct brcmf_if *ifp;
573 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
576 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
577 (wdev->iftype == NL80211_IFTYPE_AP) ||
578 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
579 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
582 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
586 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
588 struct brcmf_mbss_ssid_le mbss_ssid_le;
592 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
593 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
597 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
598 mbss_ssid_le.SSID_len = cpu_to_le32(5);
599 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
601 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
602 sizeof(mbss_ssid_le));
604 brcmf_err("setting ssid failed %d\n", err);
610 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
612 * @wiphy: wiphy device of new interface.
613 * @name: name of the new interface.
615 * @params: contains mac address for AP device.
618 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
619 u32 *flags, struct vif_params *params)
621 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
622 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
623 struct brcmf_cfg80211_vif *vif;
626 if (brcmf_cfg80211_vif_event_armed(cfg))
627 return ERR_PTR(-EBUSY);
629 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
631 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
633 return (struct wireless_dev *)vif;
635 brcmf_cfg80211_arm_vif_event(cfg, vif);
637 err = brcmf_cfg80211_request_ap_if(ifp);
639 brcmf_cfg80211_arm_vif_event(cfg, NULL);
643 /* wait for firmware event */
644 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
645 msecs_to_jiffies(1500));
646 brcmf_cfg80211_arm_vif_event(cfg, NULL);
648 brcmf_err("timeout occurred\n");
653 /* interface created in firmware */
656 brcmf_err("no if pointer provided\n");
661 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
662 err = brcmf_net_attach(ifp, true);
664 brcmf_err("Registering netdevice failed\n");
668 return &ifp->vif->wdev;
675 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
677 enum nl80211_iftype iftype;
679 iftype = vif->wdev.iftype;
680 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
683 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
685 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
688 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
690 unsigned char name_assign_type,
691 enum nl80211_iftype type,
693 struct vif_params *params)
695 struct wireless_dev *wdev;
698 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
699 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
701 brcmf_err("iface validation failed: err=%d\n", err);
705 case NL80211_IFTYPE_ADHOC:
706 case NL80211_IFTYPE_STATION:
707 case NL80211_IFTYPE_AP_VLAN:
708 case NL80211_IFTYPE_WDS:
709 case NL80211_IFTYPE_MONITOR:
710 case NL80211_IFTYPE_MESH_POINT:
711 return ERR_PTR(-EOPNOTSUPP);
712 case NL80211_IFTYPE_AP:
713 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
715 brcmf_cfg80211_update_proto_addr_mode(wdev);
717 case NL80211_IFTYPE_P2P_CLIENT:
718 case NL80211_IFTYPE_P2P_GO:
719 case NL80211_IFTYPE_P2P_DEVICE:
720 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
722 brcmf_cfg80211_update_proto_addr_mode(wdev);
724 case NL80211_IFTYPE_UNSPECIFIED:
726 return ERR_PTR(-EINVAL);
730 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
732 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
733 brcmf_set_mpc(ifp, mpc);
736 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
740 if (check_vif_up(ifp->vif)) {
741 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
743 brcmf_err("fail to set mpc\n");
746 brcmf_dbg(INFO, "MPC : %d\n", mpc);
750 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
751 struct brcmf_if *ifp, bool aborted,
754 struct brcmf_scan_params_le params_le;
755 struct cfg80211_scan_request *scan_request;
758 brcmf_dbg(SCAN, "Enter\n");
760 /* clear scan request, because the FW abort can cause a second call */
761 /* to this functon and might cause a double cfg80211_scan_done */
762 scan_request = cfg->scan_request;
763 cfg->scan_request = NULL;
765 if (timer_pending(&cfg->escan_timeout))
766 del_timer_sync(&cfg->escan_timeout);
769 /* Do a scan abort to stop the driver's scan engine */
770 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
771 memset(¶ms_le, 0, sizeof(params_le));
772 eth_broadcast_addr(params_le.bssid);
773 params_le.bss_type = DOT11_BSSTYPE_ANY;
774 params_le.scan_type = 0;
775 params_le.channel_num = cpu_to_le32(1);
776 params_le.nprobes = cpu_to_le32(1);
777 params_le.active_time = cpu_to_le32(-1);
778 params_le.passive_time = cpu_to_le32(-1);
779 params_le.home_time = cpu_to_le32(-1);
780 /* Scan is aborted by setting channel_list[0] to -1 */
781 params_le.channel_list[0] = cpu_to_le16(-1);
782 /* E-Scan (or anyother type) can be aborted by SCAN */
783 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
784 ¶ms_le, sizeof(params_le));
786 brcmf_err("Scan abort failed\n");
789 brcmf_scan_config_mpc(ifp, 1);
792 * e-scan can be initiated by scheduled scan
793 * which takes precedence.
795 if (cfg->sched_escan) {
796 brcmf_dbg(SCAN, "scheduled scan completed\n");
797 cfg->sched_escan = false;
799 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
800 } else if (scan_request) {
801 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
802 aborted ? "Aborted" : "Done");
803 cfg80211_scan_done(scan_request, aborted);
805 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
806 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
812 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
814 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
815 struct net_device *ndev = wdev->netdev;
817 /* vif event pending in firmware */
818 if (brcmf_cfg80211_vif_event_armed(cfg))
822 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
823 cfg->escan_info.ifp == netdev_priv(ndev))
824 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
827 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
830 switch (wdev->iftype) {
831 case NL80211_IFTYPE_ADHOC:
832 case NL80211_IFTYPE_STATION:
833 case NL80211_IFTYPE_AP:
834 case NL80211_IFTYPE_AP_VLAN:
835 case NL80211_IFTYPE_WDS:
836 case NL80211_IFTYPE_MONITOR:
837 case NL80211_IFTYPE_MESH_POINT:
839 case NL80211_IFTYPE_P2P_CLIENT:
840 case NL80211_IFTYPE_P2P_GO:
841 case NL80211_IFTYPE_P2P_DEVICE:
842 return brcmf_p2p_del_vif(wiphy, wdev);
843 case NL80211_IFTYPE_UNSPECIFIED:
851 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
852 enum nl80211_iftype type, u32 *flags,
853 struct vif_params *params)
855 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
856 struct brcmf_if *ifp = netdev_priv(ndev);
857 struct brcmf_cfg80211_vif *vif = ifp->vif;
862 brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
863 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
865 brcmf_err("iface validation failed: err=%d\n", err);
869 case NL80211_IFTYPE_MONITOR:
870 case NL80211_IFTYPE_WDS:
871 brcmf_err("type (%d) : currently we do not support this type\n",
874 case NL80211_IFTYPE_ADHOC:
877 case NL80211_IFTYPE_STATION:
878 /* Ignore change for p2p IF. Unclear why supplicant does this */
879 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
880 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
881 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
882 /* WAR: It is unexpected to get a change of VIF for P2P
883 * IF, but it happens. The request can not be handled
884 * but returning EPERM causes a crash. Returning 0
885 * without setting ieee80211_ptr->iftype causes trace
886 * (WARN_ON) but it works with wpa_supplicant
892 case NL80211_IFTYPE_AP:
893 case NL80211_IFTYPE_P2P_GO:
902 if (type == NL80211_IFTYPE_P2P_GO) {
903 brcmf_dbg(INFO, "IF Type = P2P GO\n");
904 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
907 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
908 brcmf_dbg(INFO, "IF Type = AP\n");
911 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
913 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
917 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
920 ndev->ieee80211_ptr->iftype = type;
922 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
925 brcmf_dbg(TRACE, "Exit\n");
930 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
931 struct brcmf_scan_params_le *params_le,
932 struct cfg80211_scan_request *request)
940 struct brcmf_ssid_le ssid_le;
942 eth_broadcast_addr(params_le->bssid);
943 params_le->bss_type = DOT11_BSSTYPE_ANY;
944 params_le->scan_type = 0;
945 params_le->channel_num = 0;
946 params_le->nprobes = cpu_to_le32(-1);
947 params_le->active_time = cpu_to_le32(-1);
948 params_le->passive_time = cpu_to_le32(-1);
949 params_le->home_time = cpu_to_le32(-1);
950 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
952 /* if request is null exit so it will be all channel broadcast scan */
956 n_ssids = request->n_ssids;
957 n_channels = request->n_channels;
958 /* Copy channel array if applicable */
959 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
961 if (n_channels > 0) {
962 for (i = 0; i < n_channels; i++) {
963 chanspec = channel_to_chanspec(&cfg->d11inf,
964 request->channels[i]);
965 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
966 request->channels[i]->hw_value, chanspec);
967 params_le->channel_list[i] = cpu_to_le16(chanspec);
970 brcmf_dbg(SCAN, "Scanning all channels\n");
972 /* Copy ssid array if applicable */
973 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
975 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
976 n_channels * sizeof(u16);
977 offset = roundup(offset, sizeof(u32));
978 ptr = (char *)params_le + offset;
979 for (i = 0; i < n_ssids; i++) {
980 memset(&ssid_le, 0, sizeof(ssid_le));
982 cpu_to_le32(request->ssids[i].ssid_len);
983 memcpy(ssid_le.SSID, request->ssids[i].ssid,
984 request->ssids[i].ssid_len);
985 if (!ssid_le.SSID_len)
986 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
988 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
989 i, ssid_le.SSID, ssid_le.SSID_len);
990 memcpy(ptr, &ssid_le, sizeof(ssid_le));
991 ptr += sizeof(ssid_le);
994 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
995 if ((request->ssids) && request->ssids->ssid_len) {
996 brcmf_dbg(SCAN, "SSID %s len=%d\n",
997 params_le->ssid_le.SSID,
998 request->ssids->ssid_len);
999 params_le->ssid_le.SSID_len =
1000 cpu_to_le32(request->ssids->ssid_len);
1001 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
1002 request->ssids->ssid_len);
1005 /* Adding mask to channel numbers */
1006 params_le->channel_num =
1007 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1008 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1012 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1013 struct cfg80211_scan_request *request, u16 action)
1015 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1016 offsetof(struct brcmf_escan_params_le, params_le);
1017 struct brcmf_escan_params_le *params;
1020 brcmf_dbg(SCAN, "E-SCAN START\n");
1022 if (request != NULL) {
1023 /* Allocate space for populating ssids in struct */
1024 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1026 /* Allocate space for populating ssids in struct */
1027 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
1030 params = kzalloc(params_size, GFP_KERNEL);
1035 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1036 brcmf_escan_prep(cfg, ¶ms->params_le, request);
1037 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1038 params->action = cpu_to_le16(action);
1039 params->sync_id = cpu_to_le16(0x1234);
1041 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1044 brcmf_dbg(INFO, "system busy : escan canceled\n");
1046 brcmf_err("error (%d)\n", err);
1055 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1056 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1060 struct brcmf_scan_results *results;
1061 struct escan_info *escan = &cfg->escan_info;
1063 brcmf_dbg(SCAN, "Enter\n");
1065 escan->wiphy = wiphy;
1066 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1067 passive_scan = cfg->active_scan ? 0 : 1;
1068 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1071 brcmf_err("error (%d)\n", err);
1074 brcmf_scan_config_mpc(ifp, 0);
1075 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1076 results->version = 0;
1078 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1080 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
1082 brcmf_scan_config_mpc(ifp, 1);
1087 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1088 struct cfg80211_scan_request *request,
1089 struct cfg80211_ssid *this_ssid)
1091 struct brcmf_if *ifp = vif->ifp;
1092 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1093 struct cfg80211_ssid *ssids;
1094 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
1101 brcmf_dbg(SCAN, "START ESCAN\n");
1103 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1104 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1107 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1108 brcmf_err("Scanning being aborted: status (%lu)\n",
1112 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1113 brcmf_err("Scanning suppressed: status (%lu)\n",
1117 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1118 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1122 /* If scan req comes for p2p0, send it over primary I/F */
1123 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1124 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1129 ssids = request->ssids;
1133 /* we don't do escan in ibss */
1137 cfg->scan_request = request;
1138 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1140 cfg->escan_info.run = brcmf_run_escan;
1141 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1145 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1149 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1150 ssids->ssid, ssids->ssid_len);
1151 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1152 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1153 sr->ssid_le.SSID_len = cpu_to_le32(0);
1156 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1157 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1160 brcmf_dbg(SCAN, "Broadcast scan\n");
1162 passive_scan = cfg->active_scan ? 0 : 1;
1163 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1166 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1169 brcmf_scan_config_mpc(ifp, 0);
1170 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1171 &sr->ssid_le, sizeof(sr->ssid_le));
1174 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1177 brcmf_err("WLC_SCAN error (%d)\n", err);
1179 brcmf_scan_config_mpc(ifp, 1);
1184 /* Arm scan timeout timer */
1185 mod_timer(&cfg->escan_timeout, jiffies +
1186 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1191 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1192 cfg->scan_request = NULL;
1197 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1199 struct brcmf_cfg80211_vif *vif;
1202 brcmf_dbg(TRACE, "Enter\n");
1203 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1204 if (!check_vif_up(vif))
1207 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1210 brcmf_err("scan error (%d)\n", err);
1212 brcmf_dbg(TRACE, "Exit\n");
1216 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1220 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1223 brcmf_err("Error (%d)\n", err);
1228 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1232 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1235 brcmf_err("Error (%d)\n", err);
1240 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1243 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1245 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1247 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1253 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1255 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1256 struct net_device *ndev = cfg_to_ndev(cfg);
1257 struct brcmf_if *ifp = netdev_priv(ndev);
1260 brcmf_dbg(TRACE, "Enter\n");
1261 if (!check_vif_up(ifp->vif))
1264 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1265 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1266 cfg->conf->rts_threshold = wiphy->rts_threshold;
1267 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1271 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1272 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1273 cfg->conf->frag_threshold = wiphy->frag_threshold;
1274 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1278 if (changed & WIPHY_PARAM_RETRY_LONG
1279 && (cfg->conf->retry_long != wiphy->retry_long)) {
1280 cfg->conf->retry_long = wiphy->retry_long;
1281 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1285 if (changed & WIPHY_PARAM_RETRY_SHORT
1286 && (cfg->conf->retry_short != wiphy->retry_short)) {
1287 cfg->conf->retry_short = wiphy->retry_short;
1288 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1294 brcmf_dbg(TRACE, "Exit\n");
1298 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1300 memset(prof, 0, sizeof(*prof));
1303 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1307 switch (e->event_code) {
1308 case BRCMF_E_DEAUTH:
1309 case BRCMF_E_DEAUTH_IND:
1310 case BRCMF_E_DISASSOC_IND:
1321 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1323 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1326 brcmf_dbg(TRACE, "Enter\n");
1328 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1329 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1330 err = brcmf_fil_cmd_data_set(vif->ifp,
1331 BRCMF_C_DISASSOC, NULL, 0);
1333 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1335 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1336 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1340 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1341 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1342 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1343 brcmf_dbg(TRACE, "Exit\n");
1347 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1348 struct cfg80211_ibss_params *params)
1350 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1351 struct brcmf_if *ifp = netdev_priv(ndev);
1352 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1353 struct brcmf_join_params join_params;
1354 size_t join_params_size = 0;
1360 brcmf_dbg(TRACE, "Enter\n");
1361 if (!check_vif_up(ifp->vif))
1365 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1367 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1371 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1374 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1376 brcmf_dbg(CONN, "No BSSID specified\n");
1378 if (params->chandef.chan)
1379 brcmf_dbg(CONN, "channel: %d\n",
1380 params->chandef.chan->center_freq);
1382 brcmf_dbg(CONN, "no channel specified\n");
1384 if (params->channel_fixed)
1385 brcmf_dbg(CONN, "fixed channel required\n");
1387 brcmf_dbg(CONN, "no fixed channel required\n");
1389 if (params->ie && params->ie_len)
1390 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1392 brcmf_dbg(CONN, "no ie specified\n");
1394 if (params->beacon_interval)
1395 brcmf_dbg(CONN, "beacon interval: %d\n",
1396 params->beacon_interval);
1398 brcmf_dbg(CONN, "no beacon interval specified\n");
1400 if (params->basic_rates)
1401 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1403 brcmf_dbg(CONN, "no basic rates specified\n");
1405 if (params->privacy)
1406 brcmf_dbg(CONN, "privacy required\n");
1408 brcmf_dbg(CONN, "no privacy required\n");
1410 /* Configure Privacy for starter */
1411 if (params->privacy)
1412 wsec |= WEP_ENABLED;
1414 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1416 brcmf_err("wsec failed (%d)\n", err);
1420 /* Configure Beacon Interval for starter */
1421 if (params->beacon_interval)
1422 bcnprd = params->beacon_interval;
1426 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1428 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1432 /* Configure required join parameter */
1433 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1436 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1437 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1438 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1439 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1440 join_params_size = sizeof(join_params.ssid_le);
1443 if (params->bssid) {
1444 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1445 join_params_size = sizeof(join_params.ssid_le) +
1446 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1447 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1449 eth_broadcast_addr(join_params.params_le.bssid);
1450 eth_zero_addr(profile->bssid);
1454 if (params->chandef.chan) {
1458 ieee80211_frequency_to_channel(
1459 params->chandef.chan->center_freq);
1460 if (params->channel_fixed) {
1461 /* adding chanspec */
1462 chanspec = chandef_to_chanspec(&cfg->d11inf,
1464 join_params.params_le.chanspec_list[0] =
1465 cpu_to_le16(chanspec);
1466 join_params.params_le.chanspec_num = cpu_to_le32(1);
1467 join_params_size += sizeof(join_params.params_le);
1470 /* set channel for starter */
1471 target_channel = cfg->channel;
1472 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1475 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1481 cfg->ibss_starter = false;
1484 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1485 &join_params, join_params_size);
1487 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1493 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1494 brcmf_dbg(TRACE, "Exit\n");
1499 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1501 struct brcmf_if *ifp = netdev_priv(ndev);
1503 brcmf_dbg(TRACE, "Enter\n");
1504 if (!check_vif_up(ifp->vif))
1507 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1509 brcmf_dbg(TRACE, "Exit\n");
1514 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1515 struct cfg80211_connect_params *sme)
1517 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1518 struct brcmf_cfg80211_security *sec;
1522 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1523 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1524 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1525 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1527 val = WPA_AUTH_DISABLED;
1528 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1529 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1531 brcmf_err("set wpa_auth failed (%d)\n", err);
1534 sec = &profile->sec;
1535 sec->wpa_versions = sme->crypto.wpa_versions;
1539 static s32 brcmf_set_auth_type(struct net_device *ndev,
1540 struct cfg80211_connect_params *sme)
1542 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1543 struct brcmf_cfg80211_security *sec;
1547 switch (sme->auth_type) {
1548 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1550 brcmf_dbg(CONN, "open system\n");
1552 case NL80211_AUTHTYPE_SHARED_KEY:
1554 brcmf_dbg(CONN, "shared key\n");
1556 case NL80211_AUTHTYPE_AUTOMATIC:
1558 brcmf_dbg(CONN, "automatic\n");
1560 case NL80211_AUTHTYPE_NETWORK_EAP:
1561 brcmf_dbg(CONN, "network eap\n");
1564 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1568 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1570 brcmf_err("set auth failed (%d)\n", err);
1573 sec = &profile->sec;
1574 sec->auth_type = sme->auth_type;
1579 brcmf_set_wsec_mode(struct net_device *ndev,
1580 struct cfg80211_connect_params *sme, bool mfp)
1582 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1583 struct brcmf_cfg80211_security *sec;
1589 if (sme->crypto.n_ciphers_pairwise) {
1590 switch (sme->crypto.ciphers_pairwise[0]) {
1591 case WLAN_CIPHER_SUITE_WEP40:
1592 case WLAN_CIPHER_SUITE_WEP104:
1595 case WLAN_CIPHER_SUITE_TKIP:
1596 pval = TKIP_ENABLED;
1598 case WLAN_CIPHER_SUITE_CCMP:
1601 case WLAN_CIPHER_SUITE_AES_CMAC:
1605 brcmf_err("invalid cipher pairwise (%d)\n",
1606 sme->crypto.ciphers_pairwise[0]);
1610 if (sme->crypto.cipher_group) {
1611 switch (sme->crypto.cipher_group) {
1612 case WLAN_CIPHER_SUITE_WEP40:
1613 case WLAN_CIPHER_SUITE_WEP104:
1616 case WLAN_CIPHER_SUITE_TKIP:
1617 gval = TKIP_ENABLED;
1619 case WLAN_CIPHER_SUITE_CCMP:
1622 case WLAN_CIPHER_SUITE_AES_CMAC:
1626 brcmf_err("invalid cipher group (%d)\n",
1627 sme->crypto.cipher_group);
1632 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1633 /* In case of privacy, but no security and WPS then simulate */
1634 /* setting AES. WPS-2.0 allows no security */
1635 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1640 wsec = pval | gval | MFP_CAPABLE;
1643 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1645 brcmf_err("error (%d)\n", err);
1649 sec = &profile->sec;
1650 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1651 sec->cipher_group = sme->crypto.cipher_group;
1657 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1659 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1660 struct brcmf_cfg80211_security *sec;
1664 if (sme->crypto.n_akm_suites) {
1665 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1668 brcmf_err("could not get wpa_auth (%d)\n", err);
1671 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1672 switch (sme->crypto.akm_suites[0]) {
1673 case WLAN_AKM_SUITE_8021X:
1674 val = WPA_AUTH_UNSPECIFIED;
1676 case WLAN_AKM_SUITE_PSK:
1680 brcmf_err("invalid cipher group (%d)\n",
1681 sme->crypto.cipher_group);
1684 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1685 switch (sme->crypto.akm_suites[0]) {
1686 case WLAN_AKM_SUITE_8021X:
1687 val = WPA2_AUTH_UNSPECIFIED;
1689 case WLAN_AKM_SUITE_PSK:
1690 val = WPA2_AUTH_PSK;
1693 brcmf_err("invalid cipher group (%d)\n",
1694 sme->crypto.cipher_group);
1699 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1700 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1703 brcmf_err("could not set wpa_auth (%d)\n", err);
1707 sec = &profile->sec;
1708 sec->wpa_auth = sme->crypto.akm_suites[0];
1714 brcmf_set_sharedkey(struct net_device *ndev,
1715 struct cfg80211_connect_params *sme)
1717 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1718 struct brcmf_cfg80211_security *sec;
1719 struct brcmf_wsec_key key;
1723 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1725 if (sme->key_len == 0)
1728 sec = &profile->sec;
1729 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1730 sec->wpa_versions, sec->cipher_pairwise);
1732 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1735 if (!(sec->cipher_pairwise &
1736 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1739 memset(&key, 0, sizeof(key));
1740 key.len = (u32) sme->key_len;
1741 key.index = (u32) sme->key_idx;
1742 if (key.len > sizeof(key.data)) {
1743 brcmf_err("Too long key length (%u)\n", key.len);
1746 memcpy(key.data, sme->key, key.len);
1747 key.flags = BRCMF_PRIMARY_KEY;
1748 switch (sec->cipher_pairwise) {
1749 case WLAN_CIPHER_SUITE_WEP40:
1750 key.algo = CRYPTO_ALGO_WEP1;
1752 case WLAN_CIPHER_SUITE_WEP104:
1753 key.algo = CRYPTO_ALGO_WEP128;
1756 brcmf_err("Invalid algorithm (%d)\n",
1757 sme->crypto.ciphers_pairwise[0]);
1760 /* Set the new key/index */
1761 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1762 key.len, key.index, key.algo);
1763 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1764 err = send_key_to_dongle(netdev_priv(ndev), &key);
1768 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1769 brcmf_dbg(CONN, "set auth_type to shared key\n");
1770 val = WL_AUTH_SHARED_KEY; /* shared key */
1771 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1773 brcmf_err("set auth failed (%d)\n", err);
1779 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1780 enum nl80211_auth_type type)
1782 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1783 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1784 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1785 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1791 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1792 struct cfg80211_connect_params *sme)
1794 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1795 struct brcmf_if *ifp = netdev_priv(ndev);
1796 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1797 struct ieee80211_channel *chan = sme->channel;
1798 struct brcmf_join_params join_params;
1799 size_t join_params_size;
1800 const struct brcmf_tlv *rsn_ie;
1801 const struct brcmf_vs_tlv *wpa_ie;
1804 struct brcmf_ext_join_params_le *ext_join_params;
1808 brcmf_dbg(TRACE, "Enter\n");
1809 if (!check_vif_up(ifp->vif))
1813 brcmf_err("Invalid ssid\n");
1817 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1818 /* A normal (non P2P) connection request setup. */
1821 /* find the WPA_IE */
1822 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1825 ie_len = wpa_ie->len + TLV_HDR_LEN;
1827 /* find the RSN_IE */
1828 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1833 ie_len = rsn_ie->len + TLV_HDR_LEN;
1836 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1839 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1840 sme->ie, sme->ie_len);
1842 brcmf_err("Set Assoc REQ IE Failed\n");
1844 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1846 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1850 ieee80211_frequency_to_channel(chan->center_freq);
1851 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1852 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1853 cfg->channel, chan->center_freq, chanspec);
1859 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1861 err = brcmf_set_wpa_version(ndev, sme);
1863 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1867 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1868 err = brcmf_set_auth_type(ndev, sme);
1870 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1874 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1876 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1880 err = brcmf_set_key_mgmt(ndev, sme);
1882 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1886 err = brcmf_set_sharedkey(ndev, sme);
1888 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1892 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1893 (u32)sme->ssid_len);
1894 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1895 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1896 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1897 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1898 profile->ssid.SSID_len);
1901 /* Join with specific BSSID and cached SSID
1902 * If SSID is zero join based on BSSID only
1904 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1905 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1907 join_params_size += sizeof(u16);
1908 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1909 if (ext_join_params == NULL) {
1913 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1914 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1915 profile->ssid.SSID_len);
1917 /* Set up join scan parameters */
1918 ext_join_params->scan_le.scan_type = -1;
1919 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1922 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1924 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1927 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1929 ext_join_params->assoc_le.chanspec_list[0] =
1930 cpu_to_le16(chanspec);
1931 /* Increase dwell time to receive probe response or detect
1932 * beacon from target AP at a noisy air only during connect
1935 ext_join_params->scan_le.active_time =
1936 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1937 ext_join_params->scan_le.passive_time =
1938 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1939 /* To sync with presence period of VSDB GO send probe request
1940 * more frequently. Probe request will be stopped when it gets
1941 * probe response from target AP/GO.
1943 ext_join_params->scan_le.nprobes =
1944 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1945 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1947 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1948 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1949 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1952 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1954 kfree(ext_join_params);
1956 /* This is it. join command worked, we are done */
1959 /* join command failed, fallback to set ssid */
1960 memset(&join_params, 0, sizeof(join_params));
1961 join_params_size = sizeof(join_params.ssid_le);
1963 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1964 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1967 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1969 eth_broadcast_addr(join_params.params_le.bssid);
1972 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1973 join_params.params_le.chanspec_num = cpu_to_le32(1);
1974 join_params_size += sizeof(join_params.params_le);
1976 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1977 &join_params, join_params_size);
1979 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1983 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1984 brcmf_dbg(TRACE, "Exit\n");
1989 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1992 struct brcmf_if *ifp = netdev_priv(ndev);
1993 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1994 struct brcmf_scb_val_le scbval;
1997 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1998 if (!check_vif_up(ifp->vif))
2001 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2002 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2003 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2005 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2006 scbval.val = cpu_to_le32(reason_code);
2007 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2008 &scbval, sizeof(scbval));
2010 brcmf_err("error (%d)\n", err);
2012 brcmf_dbg(TRACE, "Exit\n");
2017 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2018 enum nl80211_tx_power_setting type, s32 mbm)
2021 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2022 struct net_device *ndev = cfg_to_ndev(cfg);
2023 struct brcmf_if *ifp = netdev_priv(ndev);
2027 s32 dbm = MBM_TO_DBM(mbm);
2029 brcmf_dbg(TRACE, "Enter\n");
2030 if (!check_vif_up(ifp->vif))
2034 case NL80211_TX_POWER_AUTOMATIC:
2036 case NL80211_TX_POWER_LIMITED:
2037 case NL80211_TX_POWER_FIXED:
2039 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2045 /* Make sure radio is off or on as far as software is concerned */
2046 disable = WL_RADIO_SW_DISABLE << 16;
2047 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2049 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2054 txpwrmw = (u16) dbm;
2055 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
2056 (s32)brcmf_mw_to_qdbm(txpwrmw));
2058 brcmf_err("qtxpower error (%d)\n", err);
2059 cfg->conf->tx_power = dbm;
2062 brcmf_dbg(TRACE, "Exit\n");
2066 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
2067 struct wireless_dev *wdev,
2070 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2071 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2076 brcmf_dbg(TRACE, "Enter\n");
2077 if (!check_vif_up(ifp->vif))
2080 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
2082 brcmf_err("error (%d)\n", err);
2086 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2087 *dbm = (s32) brcmf_qdbm_to_mw(result);
2090 brcmf_dbg(TRACE, "Exit\n");
2095 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2096 u8 key_idx, bool unicast, bool multicast)
2098 struct brcmf_if *ifp = netdev_priv(ndev);
2103 brcmf_dbg(TRACE, "Enter\n");
2104 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2105 if (!check_vif_up(ifp->vif))
2108 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2110 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2114 if (wsec & WEP_ENABLED) {
2115 /* Just select a new current key */
2117 err = brcmf_fil_cmd_int_set(ifp,
2118 BRCMF_C_SET_KEY_PRIMARY, index);
2120 brcmf_err("error (%d)\n", err);
2123 brcmf_dbg(TRACE, "Exit\n");
2128 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2129 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2131 struct brcmf_if *ifp = netdev_priv(ndev);
2132 struct brcmf_wsec_key key;
2136 memset(&key, 0, sizeof(key));
2137 key.index = (u32) key_idx;
2138 /* Instead of bcast for ea address for default wep keys,
2139 driver needs it to be Null */
2140 if (!is_multicast_ether_addr(mac_addr))
2141 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2142 key.len = (u32) params->key_len;
2143 /* check for key index change */
2146 err = send_key_to_dongle(ifp, &key);
2148 brcmf_err("key delete error (%d)\n", err);
2150 if (key.len > sizeof(key.data)) {
2151 brcmf_err("Invalid key length (%d)\n", key.len);
2155 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2156 memcpy(key.data, params->key, key.len);
2158 if (!brcmf_is_apmode(ifp->vif) &&
2159 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2160 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2161 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2162 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2163 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2166 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2167 if (params->seq && params->seq_len == 6) {
2170 ivptr = (u8 *) params->seq;
2171 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2172 (ivptr[3] << 8) | ivptr[2];
2173 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2174 key.iv_initialized = true;
2177 switch (params->cipher) {
2178 case WLAN_CIPHER_SUITE_WEP40:
2179 key.algo = CRYPTO_ALGO_WEP1;
2180 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2182 case WLAN_CIPHER_SUITE_WEP104:
2183 key.algo = CRYPTO_ALGO_WEP128;
2184 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2186 case WLAN_CIPHER_SUITE_TKIP:
2187 key.algo = CRYPTO_ALGO_TKIP;
2188 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2190 case WLAN_CIPHER_SUITE_AES_CMAC:
2191 key.algo = CRYPTO_ALGO_AES_CCM;
2192 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2194 case WLAN_CIPHER_SUITE_CCMP:
2195 key.algo = CRYPTO_ALGO_AES_CCM;
2196 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2199 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2202 err = send_key_to_dongle(ifp, &key);
2204 brcmf_err("wsec_key error (%d)\n", err);
2210 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2211 u8 key_idx, bool pairwise, const u8 *mac_addr,
2212 struct key_params *params)
2214 struct brcmf_if *ifp = netdev_priv(ndev);
2215 struct brcmf_wsec_key *key;
2221 brcmf_dbg(TRACE, "Enter\n");
2222 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2223 if (!check_vif_up(ifp->vif))
2226 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2227 /* we ignore this key index in this case */
2228 brcmf_err("invalid key index (%d)\n", key_idx);
2233 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2234 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2235 brcmf_dbg(TRACE, "Exit");
2236 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2239 key = &ifp->vif->profile.key[key_idx];
2240 memset(key, 0, sizeof(*key));
2242 if (params->key_len > sizeof(key->data)) {
2243 brcmf_err("Too long key length (%u)\n", params->key_len);
2247 key->len = params->key_len;
2248 key->index = key_idx;
2250 memcpy(key->data, params->key, key->len);
2252 key->flags = BRCMF_PRIMARY_KEY;
2253 switch (params->cipher) {
2254 case WLAN_CIPHER_SUITE_WEP40:
2255 key->algo = CRYPTO_ALGO_WEP1;
2257 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2259 case WLAN_CIPHER_SUITE_WEP104:
2260 key->algo = CRYPTO_ALGO_WEP128;
2262 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2264 case WLAN_CIPHER_SUITE_TKIP:
2265 if (!brcmf_is_apmode(ifp->vif)) {
2266 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2267 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2268 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2269 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2271 key->algo = CRYPTO_ALGO_TKIP;
2273 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2275 case WLAN_CIPHER_SUITE_AES_CMAC:
2276 key->algo = CRYPTO_ALGO_AES_CCM;
2278 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2280 case WLAN_CIPHER_SUITE_CCMP:
2281 key->algo = CRYPTO_ALGO_AES_CCM;
2283 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2286 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2291 err = send_key_to_dongle(ifp, key);
2295 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2297 brcmf_err("get wsec error (%d)\n", err);
2301 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2303 brcmf_err("set wsec error (%d)\n", err);
2308 brcmf_dbg(TRACE, "Exit\n");
2313 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2314 u8 key_idx, bool pairwise, const u8 *mac_addr)
2316 struct brcmf_if *ifp = netdev_priv(ndev);
2317 struct brcmf_wsec_key key;
2320 brcmf_dbg(TRACE, "Enter\n");
2321 if (!check_vif_up(ifp->vif))
2324 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2325 /* we ignore this key index in this case */
2329 memset(&key, 0, sizeof(key));
2331 key.index = (u32) key_idx;
2332 key.flags = BRCMF_PRIMARY_KEY;
2333 key.algo = CRYPTO_ALGO_OFF;
2335 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2337 /* Set the new key/index */
2338 err = send_key_to_dongle(ifp, &key);
2340 brcmf_dbg(TRACE, "Exit\n");
2345 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2346 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2347 void (*callback) (void *cookie, struct key_params * params))
2349 struct key_params params;
2350 struct brcmf_if *ifp = netdev_priv(ndev);
2351 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2352 struct brcmf_cfg80211_security *sec;
2356 brcmf_dbg(TRACE, "Enter\n");
2357 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2358 if (!check_vif_up(ifp->vif))
2361 memset(¶ms, 0, sizeof(params));
2363 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2365 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2366 /* Ignore this error, may happen during DISASSOC */
2370 if (wsec & WEP_ENABLED) {
2371 sec = &profile->sec;
2372 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2373 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2374 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2375 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2376 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2377 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2379 } else if (wsec & TKIP_ENABLED) {
2380 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2381 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2382 } else if (wsec & AES_ENABLED) {
2383 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2384 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2386 brcmf_err("Invalid algo (0x%x)\n", wsec);
2390 callback(cookie, ¶ms);
2393 brcmf_dbg(TRACE, "Exit\n");
2398 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2399 struct net_device *ndev, u8 key_idx)
2401 brcmf_dbg(INFO, "Not supported\n");
2407 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2411 struct brcmf_wsec_key *key;
2414 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2415 key = &ifp->vif->profile.key[key_idx];
2416 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2417 (key->algo == CRYPTO_ALGO_WEP128))
2420 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2423 err = send_key_to_dongle(ifp, key);
2425 brcmf_err("Setting WEP key failed (%d)\n", err);
2428 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2430 brcmf_err("get wsec error (%d)\n", err);
2433 wsec |= WEP_ENABLED;
2434 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2436 brcmf_err("set wsec error (%d)\n", err);
2439 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2441 struct nl80211_sta_flag_update *sfu;
2443 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2444 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2445 sfu = &si->sta_flags;
2446 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2447 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2448 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2449 BIT(NL80211_STA_FLAG_AUTHORIZED);
2450 if (fw_sta_flags & BRCMF_STA_WME)
2451 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2452 if (fw_sta_flags & BRCMF_STA_AUTHE)
2453 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2454 if (fw_sta_flags & BRCMF_STA_ASSOC)
2455 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2456 if (fw_sta_flags & BRCMF_STA_AUTHO)
2457 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2460 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2464 struct brcmf_bss_info_le bss_le;
2469 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2473 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2474 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2477 brcmf_err("Failed to get bss info (%d)\n", err);
2480 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2481 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2482 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2483 capability = le16_to_cpu(buf->bss_le.capability);
2484 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2485 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2486 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2487 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2488 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2489 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2493 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2494 const u8 *mac, struct station_info *sinfo)
2496 struct brcmf_if *ifp = netdev_priv(ndev);
2498 struct brcmf_sta_info_le sta_info_le;
2502 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2503 if (!check_vif_up(ifp->vif))
2506 memset(&sta_info_le, 0, sizeof(sta_info_le));
2507 memcpy(&sta_info_le, mac, ETH_ALEN);
2508 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2510 sizeof(sta_info_le));
2511 is_tdls_peer = !err;
2513 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2515 sizeof(sta_info_le));
2517 brcmf_err("GET STA INFO failed, %d\n", err);
2521 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2522 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2523 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2524 sta_flags = le32_to_cpu(sta_info_le.flags);
2525 brcmf_convert_sta_flags(sta_flags, sinfo);
2526 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2528 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2530 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2531 if (sta_flags & BRCMF_STA_ASSOC) {
2532 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2533 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2534 brcmf_fill_bss_param(ifp, sinfo);
2536 if (sta_flags & BRCMF_STA_SCBSTATS) {
2537 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2538 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2539 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2540 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2541 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2542 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2543 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2544 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2545 if (sinfo->tx_packets) {
2546 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2547 sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
2548 sinfo->txrate.legacy /= 100;
2550 if (sinfo->rx_packets) {
2551 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2552 sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
2553 sinfo->rxrate.legacy /= 100;
2555 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2556 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2557 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2558 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2559 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2563 brcmf_dbg(TRACE, "Exit\n");
2568 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2569 bool enabled, s32 timeout)
2573 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2574 struct brcmf_if *ifp = netdev_priv(ndev);
2576 brcmf_dbg(TRACE, "Enter\n");
2579 * Powersave enable/disable request is coming from the
2580 * cfg80211 even before the interface is up. In that
2581 * scenario, driver will be storing the power save
2582 * preference in cfg struct to apply this to
2583 * FW later while initializing the dongle
2585 cfg->pwr_save = enabled;
2586 if (!check_vif_up(ifp->vif)) {
2588 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2592 pm = enabled ? PM_FAST : PM_OFF;
2593 /* Do not enable the power save after assoc if it is a p2p interface */
2594 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2595 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2598 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2600 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2603 brcmf_err("net_device is not ready yet\n");
2605 brcmf_err("error (%d)\n", err);
2608 brcmf_dbg(TRACE, "Exit\n");
2612 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2613 struct brcmf_bss_info_le *bi)
2615 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2616 struct ieee80211_channel *notify_channel;
2617 struct cfg80211_bss *bss;
2618 struct ieee80211_supported_band *band;
2619 struct brcmu_chan ch;
2622 u16 notify_capability;
2623 u16 notify_interval;
2625 size_t notify_ielen;
2628 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2629 brcmf_err("Bss info is larger than buffer. Discarding\n");
2634 ch.chspec = le16_to_cpu(bi->chanspec);
2635 cfg->d11inf.decchspec(&ch);
2636 bi->ctl_ch = ch.chnum;
2638 channel = bi->ctl_ch;
2640 if (channel <= CH_MAX_2G_CHANNEL)
2641 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2643 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2645 freq = ieee80211_channel_to_frequency(channel, band->band);
2646 notify_channel = ieee80211_get_channel(wiphy, freq);
2648 notify_capability = le16_to_cpu(bi->capability);
2649 notify_interval = le16_to_cpu(bi->beacon_period);
2650 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2651 notify_ielen = le32_to_cpu(bi->ie_length);
2652 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2654 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2655 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2656 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2657 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2658 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2660 bss = cfg80211_inform_bss(wiphy, notify_channel,
2661 CFG80211_BSS_FTYPE_UNKNOWN,
2662 (const u8 *)bi->BSSID,
2663 0, notify_capability,
2664 notify_interval, notify_ie,
2665 notify_ielen, notify_signal,
2671 cfg80211_put_bss(wiphy, bss);
2676 static struct brcmf_bss_info_le *
2677 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2680 return list->bss_info_le;
2681 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2682 le32_to_cpu(bss->length));
2685 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2687 struct brcmf_scan_results *bss_list;
2688 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2692 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2693 if (bss_list->count != 0 &&
2694 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2695 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2699 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2700 for (i = 0; i < bss_list->count; i++) {
2701 bi = next_bss_le(bss_list, bi);
2702 err = brcmf_inform_single_bss(cfg, bi);
2709 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2710 struct net_device *ndev, const u8 *bssid)
2712 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2713 struct ieee80211_channel *notify_channel;
2714 struct brcmf_bss_info_le *bi = NULL;
2715 struct ieee80211_supported_band *band;
2716 struct cfg80211_bss *bss;
2717 struct brcmu_chan ch;
2721 u16 notify_capability;
2722 u16 notify_interval;
2724 size_t notify_ielen;
2727 brcmf_dbg(TRACE, "Enter\n");
2729 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2735 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2737 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2738 buf, WL_BSS_INFO_MAX);
2740 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2744 bi = (struct brcmf_bss_info_le *)(buf + 4);
2746 ch.chspec = le16_to_cpu(bi->chanspec);
2747 cfg->d11inf.decchspec(&ch);
2749 if (ch.band == BRCMU_CHAN_BAND_2G)
2750 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2752 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2754 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2755 notify_channel = ieee80211_get_channel(wiphy, freq);
2757 notify_capability = le16_to_cpu(bi->capability);
2758 notify_interval = le16_to_cpu(bi->beacon_period);
2759 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2760 notify_ielen = le32_to_cpu(bi->ie_length);
2761 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2763 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2764 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2765 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2766 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2768 bss = cfg80211_inform_bss(wiphy, notify_channel,
2769 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2770 notify_capability, notify_interval,
2771 notify_ie, notify_ielen, notify_signal,
2779 cfg80211_put_bss(wiphy, bss);
2785 brcmf_dbg(TRACE, "Exit\n");
2790 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2791 struct brcmf_if *ifp)
2793 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2794 struct brcmf_bss_info_le *bi;
2795 struct brcmf_ssid *ssid;
2796 const struct brcmf_tlv *tim;
2797 u16 beacon_interval;
2803 brcmf_dbg(TRACE, "Enter\n");
2804 if (brcmf_is_ibssmode(ifp->vif))
2807 ssid = &profile->ssid;
2809 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2810 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2811 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2813 brcmf_err("Could not get bss info %d\n", err);
2814 goto update_bss_info_out;
2817 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2818 err = brcmf_inform_single_bss(cfg, bi);
2820 goto update_bss_info_out;
2822 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2823 ie_len = le32_to_cpu(bi->ie_length);
2824 beacon_interval = le16_to_cpu(bi->beacon_period);
2826 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2828 dtim_period = tim->data[1];
2831 * active scan was done so we could not get dtim
2832 * information out of probe response.
2833 * so we speficially query dtim information to dongle.
2836 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2838 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2839 goto update_bss_info_out;
2841 dtim_period = (u8)var;
2844 update_bss_info_out:
2845 brcmf_dbg(TRACE, "Exit");
2849 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2851 struct escan_info *escan = &cfg->escan_info;
2853 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2854 if (cfg->scan_request) {
2855 escan->escan_state = WL_ESCAN_STATE_IDLE;
2856 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2858 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2859 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2862 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2864 struct brcmf_cfg80211_info *cfg =
2865 container_of(work, struct brcmf_cfg80211_info,
2866 escan_timeout_work);
2868 brcmf_inform_bss(cfg);
2869 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2872 static void brcmf_escan_timeout(unsigned long data)
2874 struct brcmf_cfg80211_info *cfg =
2875 (struct brcmf_cfg80211_info *)data;
2877 if (cfg->scan_request) {
2878 brcmf_err("timer expired\n");
2879 schedule_work(&cfg->escan_timeout_work);
2884 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2885 struct brcmf_bss_info_le *bss,
2886 struct brcmf_bss_info_le *bss_info_le)
2888 struct brcmu_chan ch_bss, ch_bss_info_le;
2890 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2891 cfg->d11inf.decchspec(&ch_bss);
2892 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2893 cfg->d11inf.decchspec(&ch_bss_info_le);
2895 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2896 ch_bss.band == ch_bss_info_le.band &&
2897 bss_info_le->SSID_len == bss->SSID_len &&
2898 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2899 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2900 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2901 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2902 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2904 /* preserve max RSSI if the measurements are
2905 * both on-channel or both off-channel
2907 if (bss_info_rssi > bss_rssi)
2908 bss->RSSI = bss_info_le->RSSI;
2909 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2910 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2911 /* preserve the on-channel rssi measurement
2912 * if the new measurement is off channel
2914 bss->RSSI = bss_info_le->RSSI;
2915 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2923 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2924 const struct brcmf_event_msg *e, void *data)
2926 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2928 struct brcmf_escan_result_le *escan_result_le;
2929 struct brcmf_bss_info_le *bss_info_le;
2930 struct brcmf_bss_info_le *bss = NULL;
2932 struct brcmf_scan_results *list;
2938 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2939 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2943 if (status == BRCMF_E_STATUS_PARTIAL) {
2944 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2945 escan_result_le = (struct brcmf_escan_result_le *) data;
2946 if (!escan_result_le) {
2947 brcmf_err("Invalid escan result (NULL pointer)\n");
2950 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2951 brcmf_err("Invalid bss_count %d: ignoring\n",
2952 escan_result_le->bss_count);
2955 bss_info_le = &escan_result_le->bss_info_le;
2957 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2960 if (!cfg->scan_request) {
2961 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2965 bi_length = le32_to_cpu(bss_info_le->length);
2966 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2967 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2968 brcmf_err("Invalid bss_info length %d: ignoring\n",
2973 if (!(cfg_to_wiphy(cfg)->interface_modes &
2974 BIT(NL80211_IFTYPE_ADHOC))) {
2975 if (le16_to_cpu(bss_info_le->capability) &
2976 WLAN_CAPABILITY_IBSS) {
2977 brcmf_err("Ignoring IBSS result\n");
2982 list = (struct brcmf_scan_results *)
2983 cfg->escan_info.escan_buf;
2984 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2985 brcmf_err("Buffer is too small: ignoring\n");
2989 for (i = 0; i < list->count; i++) {
2990 bss = bss ? (struct brcmf_bss_info_le *)
2991 ((unsigned char *)bss +
2992 le32_to_cpu(bss->length)) : list->bss_info_le;
2993 if (brcmf_compare_update_same_bss(cfg, bss,
2997 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2998 bss_info_le, bi_length);
2999 list->version = le32_to_cpu(bss_info_le->version);
3000 list->buflen += bi_length;
3003 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3004 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3006 if (cfg->scan_request) {
3007 brcmf_inform_bss(cfg);
3008 aborted = status != BRCMF_E_STATUS_SUCCESS;
3009 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3011 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3018 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3020 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3021 brcmf_cfg80211_escan_handler);
3022 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3023 /* Init scan_timeout timer */
3024 init_timer(&cfg->escan_timeout);
3025 cfg->escan_timeout.data = (unsigned long) cfg;
3026 cfg->escan_timeout.function = brcmf_escan_timeout;
3027 INIT_WORK(&cfg->escan_timeout_work,
3028 brcmf_cfg80211_escan_timeout_worker);
3031 static __always_inline void brcmf_delay(u32 ms)
3033 if (ms < 1000 / HZ) {
3041 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3042 u8 *pattern, u32 patternsize, u8 *mask,
3045 struct brcmf_fil_wowl_pattern_le *filter;
3052 masksize = (patternsize + 7) / 8;
3053 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3055 bufsize = sizeof(*filter) + patternsize + masksize;
3056 buf = kzalloc(bufsize, GFP_KERNEL);
3059 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3061 memcpy(filter->cmd, cmd, 4);
3062 filter->masksize = cpu_to_le32(masksize);
3063 filter->offset = cpu_to_le32(packet_offset);
3064 filter->patternoffset = cpu_to_le32(patternoffset);
3065 filter->patternsize = cpu_to_le32(patternsize);
3066 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3068 if ((mask) && (masksize))
3069 memcpy(buf + sizeof(*filter), mask, masksize);
3070 if ((pattern) && (patternsize))
3071 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3073 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3079 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3081 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3082 struct net_device *ndev = cfg_to_ndev(cfg);
3083 struct brcmf_if *ifp = netdev_priv(ndev);
3085 brcmf_dbg(TRACE, "Enter\n");
3087 if (cfg->wowl_enabled) {
3088 brcmf_configure_arp_offload(ifp, true);
3089 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3090 cfg->pre_wowl_pmmode);
3091 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3092 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3093 cfg->wowl_enabled = false;
3098 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3099 struct brcmf_if *ifp,
3100 struct cfg80211_wowlan *wowl)
3105 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3107 brcmf_configure_arp_offload(ifp, false);
3108 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
3109 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3112 if (wowl->disconnect)
3113 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3114 if (wowl->magic_pkt)
3115 wowl_config |= BRCMF_WOWL_MAGIC;
3116 if ((wowl->patterns) && (wowl->n_patterns)) {
3117 wowl_config |= BRCMF_WOWL_NET;
3118 for (i = 0; i < wowl->n_patterns; i++) {
3119 brcmf_config_wowl_pattern(ifp, "add",
3120 (u8 *)wowl->patterns[i].pattern,
3121 wowl->patterns[i].pattern_len,
3122 (u8 *)wowl->patterns[i].mask,
3123 wowl->patterns[i].pkt_offset);
3126 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3127 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3128 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3129 cfg->wowl_enabled = true;
3132 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3133 struct cfg80211_wowlan *wowl)
3135 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3136 struct net_device *ndev = cfg_to_ndev(cfg);
3137 struct brcmf_if *ifp = netdev_priv(ndev);
3138 struct brcmf_cfg80211_vif *vif;
3140 brcmf_dbg(TRACE, "Enter\n");
3142 /* if the primary net_device is not READY there is nothing
3143 * we can do but pray resume goes smoothly.
3145 if (!check_vif_up(ifp->vif))
3148 /* end any scanning */
3149 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3150 brcmf_abort_scanning(cfg);
3153 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3154 list_for_each_entry(vif, &cfg->vif_list, list) {
3155 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3157 /* While going to suspend if associated with AP
3158 * disassociate from AP to save power while system is
3159 * in suspended state
3161 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3162 /* Make sure WPA_Supplicant receives all the event
3163 * generated due to DISASSOC call to the fw to keep
3164 * the state fw and WPA_Supplicant state consistent
3169 brcmf_set_mpc(ifp, 1);
3172 /* Configure WOWL paramaters */
3173 brcmf_configure_wowl(cfg, ifp, wowl);
3177 brcmf_dbg(TRACE, "Exit\n");
3178 /* clear any scanning activity */
3179 cfg->scan_status = 0;
3184 brcmf_update_pmklist(struct net_device *ndev,
3185 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3190 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3192 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
3193 for (i = 0; i < pmkid_len; i++) {
3194 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
3195 &pmk_list->pmkids.pmkid[i].BSSID);
3196 for (j = 0; j < WLAN_PMKID_LEN; j++)
3197 brcmf_dbg(CONN, "%02x\n",
3198 pmk_list->pmkids.pmkid[i].PMKID[j]);
3202 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
3203 (char *)pmk_list, sizeof(*pmk_list));
3209 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3210 struct cfg80211_pmksa *pmksa)
3212 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3213 struct brcmf_if *ifp = netdev_priv(ndev);
3214 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3218 brcmf_dbg(TRACE, "Enter\n");
3219 if (!check_vif_up(ifp->vif))
3222 pmkid_len = le32_to_cpu(pmkids->npmkid);
3223 for (i = 0; i < pmkid_len; i++)
3224 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3226 if (i < WL_NUM_PMKIDS_MAX) {
3227 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3228 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3229 if (i == pmkid_len) {
3231 pmkids->npmkid = cpu_to_le32(pmkid_len);
3236 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3237 pmkids->pmkid[pmkid_len].BSSID);
3238 for (i = 0; i < WLAN_PMKID_LEN; i++)
3239 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3241 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3243 brcmf_dbg(TRACE, "Exit\n");
3248 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3249 struct cfg80211_pmksa *pmksa)
3251 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3252 struct brcmf_if *ifp = netdev_priv(ndev);
3253 struct pmkid_list pmkid;
3257 brcmf_dbg(TRACE, "Enter\n");
3258 if (!check_vif_up(ifp->vif))
3261 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3262 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3264 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3265 &pmkid.pmkid[0].BSSID);
3266 for (i = 0; i < WLAN_PMKID_LEN; i++)
3267 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
3269 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3270 for (i = 0; i < pmkid_len; i++)
3272 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3277 && (i < pmkid_len)) {
3278 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3279 sizeof(struct pmkid));
3280 for (; i < (pmkid_len - 1); i++) {
3281 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3282 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3284 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3285 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3288 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3292 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3294 brcmf_dbg(TRACE, "Exit\n");
3300 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3302 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3303 struct brcmf_if *ifp = netdev_priv(ndev);
3306 brcmf_dbg(TRACE, "Enter\n");
3307 if (!check_vif_up(ifp->vif))
3310 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3311 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3313 brcmf_dbg(TRACE, "Exit\n");
3319 * PFN result doesn't have all the info which are
3320 * required by the supplicant
3321 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3322 * via wl_inform_single_bss in the required format. Escan does require the
3323 * scan request in the form of cfg80211_scan_request. For timebeing, create
3324 * cfg80211_scan_request one out of the received PNO event.
3327 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3328 const struct brcmf_event_msg *e, void *data)
3330 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3331 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3332 struct cfg80211_scan_request *request = NULL;
3333 struct cfg80211_ssid *ssid = NULL;
3334 struct ieee80211_channel *channel = NULL;
3335 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3337 int channel_req = 0;
3339 struct brcmf_pno_scanresults_le *pfn_result;
3343 brcmf_dbg(SCAN, "Enter\n");
3345 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3346 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3350 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3351 result_count = le32_to_cpu(pfn_result->count);
3352 status = le32_to_cpu(pfn_result->status);
3355 * PFN event is limited to fit 512 bytes so we may get
3356 * multiple NET_FOUND events. For now place a warning here.
3358 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3359 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3360 if (result_count > 0) {
3363 request = kzalloc(sizeof(*request), GFP_KERNEL);
3364 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3365 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3366 if (!request || !ssid || !channel) {
3371 request->wiphy = wiphy;
3372 data += sizeof(struct brcmf_pno_scanresults_le);
3373 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3375 for (i = 0; i < result_count; i++) {
3376 netinfo = &netinfo_start[i];
3378 brcmf_err("Invalid netinfo ptr. index: %d\n",
3384 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3385 netinfo->SSID, netinfo->channel);
3386 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3387 ssid[i].ssid_len = netinfo->SSID_len;
3390 channel_req = netinfo->channel;
3391 if (channel_req <= CH_MAX_2G_CHANNEL)
3392 band = NL80211_BAND_2GHZ;
3394 band = NL80211_BAND_5GHZ;
3395 channel[i].center_freq =
3396 ieee80211_channel_to_frequency(channel_req,
3398 channel[i].band = band;
3399 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3400 request->channels[i] = &channel[i];
3401 request->n_channels++;
3404 /* assign parsed ssid array */
3405 if (request->n_ssids)
3406 request->ssids = &ssid[0];
3408 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3409 /* Abort any on-going scan */
3410 brcmf_abort_scanning(cfg);
3413 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3414 cfg->escan_info.run = brcmf_run_escan;
3415 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3417 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3420 cfg->sched_escan = true;
3421 cfg->scan_request = request;
3423 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3436 cfg80211_sched_scan_stopped(wiphy);
3440 static int brcmf_dev_pno_clean(struct net_device *ndev)
3445 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3448 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3452 brcmf_err("failed code %d\n", ret);
3457 static int brcmf_dev_pno_config(struct net_device *ndev)
3459 struct brcmf_pno_param_le pfn_param;
3461 memset(&pfn_param, 0, sizeof(pfn_param));
3462 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3464 /* set extra pno params */
3465 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3466 pfn_param.repeat = BRCMF_PNO_REPEAT;
3467 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3469 /* set up pno scan fr */
3470 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3472 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3473 &pfn_param, sizeof(pfn_param));
3477 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3478 struct net_device *ndev,
3479 struct cfg80211_sched_scan_request *request)
3481 struct brcmf_if *ifp = netdev_priv(ndev);
3482 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3483 struct brcmf_pno_net_param_le pfn;
3487 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3488 request->n_match_sets, request->n_ssids);
3489 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3490 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3493 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3494 brcmf_err("Scanning suppressed: status (%lu)\n",
3499 if (!request->n_ssids || !request->n_match_sets) {
3500 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3505 if (request->n_ssids > 0) {
3506 for (i = 0; i < request->n_ssids; i++) {
3507 /* Active scan req for ssids */
3508 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3509 request->ssids[i].ssid);
3512 * match_set ssids is a supert set of n_ssid list,
3513 * so we need not add these set seperately.
3518 if (request->n_match_sets > 0) {
3519 /* clean up everything */
3520 ret = brcmf_dev_pno_clean(ndev);
3522 brcmf_err("failed error=%d\n", ret);
3527 ret = brcmf_dev_pno_config(ndev);
3529 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3533 /* configure each match set */
3534 for (i = 0; i < request->n_match_sets; i++) {
3535 struct cfg80211_ssid *ssid;
3538 ssid = &request->match_sets[i].ssid;
3539 ssid_len = ssid->ssid_len;
3542 brcmf_err("skip broadcast ssid\n");
3545 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3546 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3547 pfn.wsec = cpu_to_le32(0);
3548 pfn.infra = cpu_to_le32(1);
3549 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3550 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3551 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3552 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3554 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3555 ret == 0 ? "set" : "failed", ssid->ssid);
3557 /* Enable the PNO */
3558 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3559 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3569 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3570 struct net_device *ndev)
3572 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3574 brcmf_dbg(SCAN, "enter\n");
3575 brcmf_dev_pno_clean(ndev);
3576 if (cfg->sched_escan)
3577 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3581 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3586 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3588 brcmf_err("auth error %d\n", err);
3592 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3594 brcmf_err("wsec error %d\n", err);
3597 /* set upper-layer auth */
3598 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3600 brcmf_err("wpa_auth error %d\n", err);
3607 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3610 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3612 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3616 brcmf_configure_wpaie(struct brcmf_if *ifp,
3617 const struct brcmf_vs_tlv *wpa_ie,
3620 u32 auth = 0; /* d11 open authentication */
3632 u32 wme_bss_disable;
3634 brcmf_dbg(TRACE, "Enter\n");
3638 len = wpa_ie->len + TLV_HDR_LEN;
3639 data = (u8 *)wpa_ie;
3640 offset = TLV_HDR_LEN;
3642 offset += VS_IE_FIXED_HDR_LEN;
3644 offset += WPA_IE_VERSION_LEN;
3646 /* check for multicast cipher suite */
3647 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3649 brcmf_err("no multicast cipher suite\n");
3653 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3655 brcmf_err("ivalid OUI\n");
3658 offset += TLV_OUI_LEN;
3660 /* pick up multicast cipher */
3661 switch (data[offset]) {
3662 case WPA_CIPHER_NONE:
3665 case WPA_CIPHER_WEP_40:
3666 case WPA_CIPHER_WEP_104:
3669 case WPA_CIPHER_TKIP:
3670 gval = TKIP_ENABLED;
3672 case WPA_CIPHER_AES_CCM:
3677 brcmf_err("Invalid multi cast cipher info\n");
3682 /* walk thru unicast cipher list and pick up what we recognize */
3683 count = data[offset] + (data[offset + 1] << 8);
3684 offset += WPA_IE_SUITE_COUNT_LEN;
3685 /* Check for unicast suite(s) */
3686 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3688 brcmf_err("no unicast cipher suite\n");
3691 for (i = 0; i < count; i++) {
3692 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3694 brcmf_err("ivalid OUI\n");
3697 offset += TLV_OUI_LEN;
3698 switch (data[offset]) {
3699 case WPA_CIPHER_NONE:
3701 case WPA_CIPHER_WEP_40:
3702 case WPA_CIPHER_WEP_104:
3703 pval |= WEP_ENABLED;
3705 case WPA_CIPHER_TKIP:
3706 pval |= TKIP_ENABLED;
3708 case WPA_CIPHER_AES_CCM:
3709 pval |= AES_ENABLED;
3712 brcmf_err("Ivalid unicast security info\n");
3716 /* walk thru auth management suite list and pick up what we recognize */
3717 count = data[offset] + (data[offset + 1] << 8);
3718 offset += WPA_IE_SUITE_COUNT_LEN;
3719 /* Check for auth key management suite(s) */
3720 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3722 brcmf_err("no auth key mgmt suite\n");
3725 for (i = 0; i < count; i++) {
3726 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3728 brcmf_err("ivalid OUI\n");
3731 offset += TLV_OUI_LEN;
3732 switch (data[offset]) {
3734 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3735 wpa_auth |= WPA_AUTH_NONE;
3737 case RSN_AKM_UNSPECIFIED:
3738 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3739 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3740 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3743 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3744 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3745 (wpa_auth |= WPA_AUTH_PSK);
3748 brcmf_err("Ivalid key mgmt info\n");
3754 wme_bss_disable = 1;
3755 if ((offset + RSN_CAP_LEN) <= len) {
3756 rsn_cap = data[offset] + (data[offset + 1] << 8);
3757 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3758 wme_bss_disable = 0;
3760 /* set wme_bss_disable to sync RSN Capabilities */
3761 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3764 brcmf_err("wme_bss_disable error %d\n", err);
3768 /* FOR WPS , set SES_OW_ENABLED */
3769 wsec = (pval | gval | SES_OW_ENABLED);
3772 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3774 brcmf_err("auth error %d\n", err);
3778 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3780 brcmf_err("wsec error %d\n", err);
3783 /* set upper-layer auth */
3784 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3786 brcmf_err("wpa_auth error %d\n", err);
3795 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3796 struct parsed_vndr_ies *vndr_ies)
3798 struct brcmf_vs_tlv *vndrie;
3799 struct brcmf_tlv *ie;
3800 struct parsed_vndr_ie_info *parsed_info;
3803 remaining_len = (s32)vndr_ie_len;
3804 memset(vndr_ies, 0, sizeof(*vndr_ies));
3806 ie = (struct brcmf_tlv *)vndr_ie_buf;
3808 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3810 vndrie = (struct brcmf_vs_tlv *)ie;
3811 /* len should be bigger than OUI length + one */
3812 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3813 brcmf_err("invalid vndr ie. length is too small %d\n",
3817 /* if wpa or wme ie, do not add ie */
3818 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3819 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3820 (vndrie->oui_type == WME_OUI_TYPE))) {
3821 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3825 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3827 /* save vndr ie information */
3828 parsed_info->ie_ptr = (char *)vndrie;
3829 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3830 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3834 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3835 parsed_info->vndrie.oui[0],
3836 parsed_info->vndrie.oui[1],
3837 parsed_info->vndrie.oui[2],
3838 parsed_info->vndrie.oui_type);
3840 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3843 remaining_len -= (ie->len + TLV_HDR_LEN);
3844 if (remaining_len <= TLV_HDR_LEN)
3847 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3854 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3857 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3858 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3860 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3862 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3864 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3866 return ie_len + VNDR_IE_HDR_SIZE;
3869 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3870 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3872 struct brcmf_if *ifp;
3873 struct vif_saved_ie *saved_ie;
3877 u8 *mgmt_ie_buf = NULL;
3878 int mgmt_ie_buf_len;
3880 u32 del_add_ie_buf_len = 0;
3881 u32 total_ie_buf_len = 0;
3882 u32 parsed_ie_buf_len = 0;
3883 struct parsed_vndr_ies old_vndr_ies;
3884 struct parsed_vndr_ies new_vndr_ies;
3885 struct parsed_vndr_ie_info *vndrie_info;
3888 int remained_buf_len;
3893 saved_ie = &vif->saved_ie;
3895 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3896 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3899 curr_ie_buf = iovar_ie_buf;
3901 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3902 mgmt_ie_buf = saved_ie->probe_req_ie;
3903 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3904 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3906 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3907 mgmt_ie_buf = saved_ie->probe_res_ie;
3908 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3909 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3911 case BRCMF_VNDR_IE_BEACON_FLAG:
3912 mgmt_ie_buf = saved_ie->beacon_ie;
3913 mgmt_ie_len = &saved_ie->beacon_ie_len;
3914 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3916 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3917 mgmt_ie_buf = saved_ie->assoc_req_ie;
3918 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3919 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3923 brcmf_err("not suitable type\n");
3927 if (vndr_ie_len > mgmt_ie_buf_len) {
3929 brcmf_err("extra IE size too big\n");
3933 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3934 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3936 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3937 for (i = 0; i < new_vndr_ies.count; i++) {
3938 vndrie_info = &new_vndr_ies.ie_info[i];
3939 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3940 vndrie_info->ie_len);
3941 parsed_ie_buf_len += vndrie_info->ie_len;
3945 if (mgmt_ie_buf && *mgmt_ie_len) {
3946 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3947 (memcmp(mgmt_ie_buf, curr_ie_buf,
3948 parsed_ie_buf_len) == 0)) {
3949 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3953 /* parse old vndr_ie */
3954 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3956 /* make a command to delete old ie */
3957 for (i = 0; i < old_vndr_ies.count; i++) {
3958 vndrie_info = &old_vndr_ies.ie_info[i];
3960 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3961 vndrie_info->vndrie.id,
3962 vndrie_info->vndrie.len,
3963 vndrie_info->vndrie.oui[0],
3964 vndrie_info->vndrie.oui[1],
3965 vndrie_info->vndrie.oui[2]);
3967 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3968 vndrie_info->ie_ptr,
3969 vndrie_info->ie_len,
3971 curr_ie_buf += del_add_ie_buf_len;
3972 total_ie_buf_len += del_add_ie_buf_len;
3977 /* Add if there is any extra IE */
3978 if (mgmt_ie_buf && parsed_ie_buf_len) {
3981 remained_buf_len = mgmt_ie_buf_len;
3983 /* make a command to add new ie */
3984 for (i = 0; i < new_vndr_ies.count; i++) {
3985 vndrie_info = &new_vndr_ies.ie_info[i];
3987 /* verify remained buf size before copy data */
3988 if (remained_buf_len < (vndrie_info->vndrie.len +
3989 VNDR_IE_VSIE_OFFSET)) {
3990 brcmf_err("no space in mgmt_ie_buf: len left %d",
3994 remained_buf_len -= (vndrie_info->ie_len +
3995 VNDR_IE_VSIE_OFFSET);
3997 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3998 vndrie_info->vndrie.id,
3999 vndrie_info->vndrie.len,
4000 vndrie_info->vndrie.oui[0],
4001 vndrie_info->vndrie.oui[1],
4002 vndrie_info->vndrie.oui[2]);
4004 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4005 vndrie_info->ie_ptr,
4006 vndrie_info->ie_len,
4009 /* save the parsed IE in wl struct */
4010 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4011 vndrie_info->ie_len);
4012 *mgmt_ie_len += vndrie_info->ie_len;
4014 curr_ie_buf += del_add_ie_buf_len;
4015 total_ie_buf_len += del_add_ie_buf_len;
4018 if (total_ie_buf_len) {
4019 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4022 brcmf_err("vndr ie set error : %d\n", err);
4026 kfree(iovar_ie_buf);
4030 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4033 BRCMF_VNDR_IE_PRBREQ_FLAG,
4034 BRCMF_VNDR_IE_PRBRSP_FLAG,
4035 BRCMF_VNDR_IE_BEACON_FLAG
4039 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4040 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4042 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4047 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4048 struct cfg80211_beacon_data *beacon)
4052 /* Set Beacon IEs to FW */
4053 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4054 beacon->tail, beacon->tail_len);
4056 brcmf_err("Set Beacon IE Failed\n");
4059 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4061 /* Set Probe Response IEs to FW */
4062 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4063 beacon->proberesp_ies,
4064 beacon->proberesp_ies_len);
4066 brcmf_err("Set Probe Resp IE Failed\n");
4068 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4074 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4075 struct cfg80211_ap_settings *settings)
4078 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4079 struct brcmf_if *ifp = netdev_priv(ndev);
4080 const struct brcmf_tlv *ssid_ie;
4081 const struct brcmf_tlv *country_ie;
4082 struct brcmf_ssid_le ssid_le;
4084 const struct brcmf_tlv *rsn_ie;
4085 const struct brcmf_vs_tlv *wpa_ie;
4086 struct brcmf_join_params join_params;
4087 enum nl80211_iftype dev_role;
4088 struct brcmf_fil_bss_enable_le bss_enable;
4093 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4094 settings->chandef.chan->hw_value,
4095 settings->chandef.center_freq1, settings->chandef.width,
4096 settings->beacon_interval, settings->dtim_period);
4097 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4098 settings->ssid, settings->ssid_len, settings->auth_type,
4099 settings->inactivity_timeout);
4100 dev_role = ifp->vif->wdev.iftype;
4101 mbss = ifp->vif->mbss;
4103 /* store current 11d setting */
4104 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4105 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4106 settings->beacon.tail_len,
4108 is_11d = country_ie ? 1 : 0;
4110 memset(&ssid_le, 0, sizeof(ssid_le));
4111 if (settings->ssid == NULL || settings->ssid_len == 0) {
4112 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4113 ssid_ie = brcmf_parse_tlvs(
4114 (u8 *)&settings->beacon.head[ie_offset],
4115 settings->beacon.head_len - ie_offset,
4120 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4121 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4122 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4124 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4125 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4129 brcmf_set_mpc(ifp, 0);
4130 brcmf_configure_arp_offload(ifp, false);
4133 /* find the RSN_IE */
4134 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4135 settings->beacon.tail_len, WLAN_EID_RSN);
4137 /* find the WPA_IE */
4138 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4139 settings->beacon.tail_len);
4141 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4142 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4143 if (wpa_ie != NULL) {
4145 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4149 struct brcmf_vs_tlv *tmp_ie;
4151 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4154 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4159 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4160 brcmf_configure_opensecurity(ifp);
4163 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4166 chanspec = chandef_to_chanspec(&cfg->d11inf,
4167 &settings->chandef);
4168 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4170 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4175 if (is_11d != ifp->vif->is_11d) {
4176 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4179 brcmf_err("Regulatory Set Error, %d\n", err);
4183 if (settings->beacon_interval) {
4184 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4185 settings->beacon_interval);
4187 brcmf_err("Beacon Interval Set Error, %d\n",
4192 if (settings->dtim_period) {
4193 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4194 settings->dtim_period);
4196 brcmf_err("DTIM Interval Set Error, %d\n", err);
4201 if (dev_role == NL80211_IFTYPE_AP) {
4202 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4204 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4207 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4210 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4212 brcmf_err("SET INFRA error %d\n", err);
4215 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4216 /* Multiple-BSS should use same 11d configuration */
4220 if (dev_role == NL80211_IFTYPE_AP) {
4221 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4222 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4224 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4226 brcmf_err("setting AP mode failed %d\n", err);
4229 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4231 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4234 /* On DOWN the firmware removes the WEP keys, reconfigure
4235 * them if they were set.
4237 brcmf_cfg80211_reconfigure_wep(ifp);
4239 memset(&join_params, 0, sizeof(join_params));
4240 /* join parameters starts with ssid */
4241 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4243 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4244 &join_params, sizeof(join_params));
4246 brcmf_err("SET SSID error (%d)\n", err);
4249 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4251 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4254 brcmf_err("setting ssid failed %d\n", err);
4257 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4258 bss_enable.enable = cpu_to_le32(1);
4259 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4260 sizeof(bss_enable));
4262 brcmf_err("bss_enable config failed %d\n", err);
4266 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4268 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4269 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4272 if ((err) && (!mbss)) {
4273 brcmf_set_mpc(ifp, 1);
4274 brcmf_configure_arp_offload(ifp, true);
4279 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4281 struct brcmf_if *ifp = netdev_priv(ndev);
4283 struct brcmf_fil_bss_enable_le bss_enable;
4284 struct brcmf_join_params join_params;
4286 brcmf_dbg(TRACE, "Enter\n");
4288 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4289 /* Due to most likely deauths outstanding we sleep */
4290 /* first to make sure they get processed by fw. */
4293 if (ifp->vif->mbss) {
4294 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4298 memset(&join_params, 0, sizeof(join_params));
4299 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4300 &join_params, sizeof(join_params));
4302 brcmf_err("SET SSID error (%d)\n", err);
4303 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4305 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4306 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4308 brcmf_err("setting AP mode failed %d\n", err);
4309 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4311 brcmf_err("setting INFRA mode failed %d\n", err);
4312 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4313 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4314 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4317 brcmf_err("restoring REGULATORY setting failed %d\n",
4319 /* Bring device back up so it can be used again */
4320 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4322 brcmf_err("BRCMF_C_UP error %d\n", err);
4324 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4325 bss_enable.enable = cpu_to_le32(0);
4326 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4327 sizeof(bss_enable));
4329 brcmf_err("bss_enable config failed %d\n", err);
4331 brcmf_set_mpc(ifp, 1);
4332 brcmf_configure_arp_offload(ifp, true);
4333 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4334 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4340 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4341 struct cfg80211_beacon_data *info)
4343 struct brcmf_if *ifp = netdev_priv(ndev);
4346 brcmf_dbg(TRACE, "Enter\n");
4348 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4354 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4355 struct station_del_parameters *params)
4357 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4358 struct brcmf_scb_val_le scbval;
4359 struct brcmf_if *ifp = netdev_priv(ndev);
4365 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4367 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4368 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4369 if (!check_vif_up(ifp->vif))
4372 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4373 scbval.val = cpu_to_le32(params->reason_code);
4374 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4375 &scbval, sizeof(scbval));
4377 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4379 brcmf_dbg(TRACE, "Exit\n");
4384 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4385 const u8 *mac, struct station_parameters *params)
4387 struct brcmf_if *ifp = netdev_priv(ndev);
4390 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4391 params->sta_flags_mask, params->sta_flags_set);
4393 /* Ignore all 00 MAC */
4394 if (is_zero_ether_addr(mac))
4397 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4400 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4401 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4402 (void *)mac, ETH_ALEN);
4404 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4405 (void *)mac, ETH_ALEN);
4407 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4413 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4414 struct wireless_dev *wdev,
4415 u16 frame_type, bool reg)
4417 struct brcmf_cfg80211_vif *vif;
4420 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4422 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4423 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4425 vif->mgmt_rx_reg |= BIT(mgmt_type);
4427 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4432 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4433 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4435 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4436 struct ieee80211_channel *chan = params->chan;
4437 const u8 *buf = params->buf;
4438 size_t len = params->len;
4439 const struct ieee80211_mgmt *mgmt;
4440 struct brcmf_cfg80211_vif *vif;
4444 struct brcmf_fil_action_frame_le *action_frame;
4445 struct brcmf_fil_af_params_le *af_params;
4450 brcmf_dbg(TRACE, "Enter\n");
4454 mgmt = (const struct ieee80211_mgmt *)buf;
4456 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4457 brcmf_err("Driver only allows MGMT packet type\n");
4461 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4463 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4464 /* Right now the only reason to get a probe response */
4465 /* is for p2p listen response or for p2p GO from */
4466 /* wpa_supplicant. Unfortunately the probe is send */
4467 /* on primary ndev, while dongle wants it on the p2p */
4468 /* vif. Since this is only reason for a probe */
4469 /* response to be sent, the vif is taken from cfg. */
4470 /* If ever desired to send proberesp for non p2p */
4471 /* response then data should be checked for */
4472 /* "DIRECT-". Note in future supplicant will take */
4473 /* dedicated p2p wdev to do this and then this 'hack'*/
4474 /* is not needed anymore. */
4475 ie_offset = DOT11_MGMT_HDR_LEN +
4476 DOT11_BCN_PRB_FIXED_LEN;
4477 ie_len = len - ie_offset;
4478 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4479 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4480 err = brcmf_vif_set_mgmt_ie(vif,
4481 BRCMF_VNDR_IE_PRBRSP_FLAG,
4484 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4486 } else if (ieee80211_is_action(mgmt->frame_control)) {
4487 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4488 if (af_params == NULL) {
4489 brcmf_err("unable to allocate frame\n");
4493 action_frame = &af_params->action_frame;
4494 /* Add the packet Id */
4495 action_frame->packet_id = cpu_to_le32(*cookie);
4497 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4498 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4499 /* Add the length exepted for 802.11 header */
4500 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4501 /* Add the channel. Use the one specified as parameter if any or
4502 * the current one (got from the firmware) otherwise
4505 freq = chan->center_freq;
4507 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4509 chan_nr = ieee80211_frequency_to_channel(freq);
4510 af_params->channel = cpu_to_le32(chan_nr);
4512 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4513 le16_to_cpu(action_frame->len));
4515 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4516 *cookie, le16_to_cpu(action_frame->len), freq);
4518 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4521 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4525 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4526 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4535 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4536 struct wireless_dev *wdev,
4539 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4540 struct brcmf_cfg80211_vif *vif;
4543 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4545 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4547 brcmf_err("No p2p device available for probe response\n");
4551 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4556 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4557 struct wireless_dev *wdev,
4558 enum nl80211_crit_proto_id proto,
4561 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4562 struct brcmf_cfg80211_vif *vif;
4564 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4566 /* only DHCP support for now */
4567 if (proto != NL80211_CRIT_PROTO_DHCP)
4570 /* suppress and abort scanning */
4571 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4572 brcmf_abort_scanning(cfg);
4574 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4577 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4578 struct wireless_dev *wdev)
4580 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4581 struct brcmf_cfg80211_vif *vif;
4583 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4585 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4586 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4590 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4591 const struct brcmf_event_msg *e, void *data)
4593 switch (e->reason) {
4594 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4595 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4597 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4598 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4599 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4601 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4602 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4603 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4610 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4615 case NL80211_TDLS_DISCOVERY_REQ:
4616 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4618 case NL80211_TDLS_SETUP:
4619 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4621 case NL80211_TDLS_TEARDOWN:
4622 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4625 brcmf_err("unsupported operation: %d\n", oper);
4631 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4632 struct net_device *ndev, const u8 *peer,
4633 enum nl80211_tdls_operation oper)
4635 struct brcmf_if *ifp;
4636 struct brcmf_tdls_iovar_le info;
4639 ret = brcmf_convert_nl80211_tdls_oper(oper);
4643 ifp = netdev_priv(ndev);
4644 memset(&info, 0, sizeof(info));
4645 info.mode = (u8)ret;
4647 memcpy(info.ea, peer, ETH_ALEN);
4649 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4650 &info, sizeof(info));
4652 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4657 static struct cfg80211_ops wl_cfg80211_ops = {
4658 .add_virtual_intf = brcmf_cfg80211_add_iface,
4659 .del_virtual_intf = brcmf_cfg80211_del_iface,
4660 .change_virtual_intf = brcmf_cfg80211_change_iface,
4661 .scan = brcmf_cfg80211_scan,
4662 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4663 .join_ibss = brcmf_cfg80211_join_ibss,
4664 .leave_ibss = brcmf_cfg80211_leave_ibss,
4665 .get_station = brcmf_cfg80211_get_station,
4666 .set_tx_power = brcmf_cfg80211_set_tx_power,
4667 .get_tx_power = brcmf_cfg80211_get_tx_power,
4668 .add_key = brcmf_cfg80211_add_key,
4669 .del_key = brcmf_cfg80211_del_key,
4670 .get_key = brcmf_cfg80211_get_key,
4671 .set_default_key = brcmf_cfg80211_config_default_key,
4672 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4673 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4674 .connect = brcmf_cfg80211_connect,
4675 .disconnect = brcmf_cfg80211_disconnect,
4676 .suspend = brcmf_cfg80211_suspend,
4677 .resume = brcmf_cfg80211_resume,
4678 .set_pmksa = brcmf_cfg80211_set_pmksa,
4679 .del_pmksa = brcmf_cfg80211_del_pmksa,
4680 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4681 .start_ap = brcmf_cfg80211_start_ap,
4682 .stop_ap = brcmf_cfg80211_stop_ap,
4683 .change_beacon = brcmf_cfg80211_change_beacon,
4684 .del_station = brcmf_cfg80211_del_station,
4685 .change_station = brcmf_cfg80211_change_station,
4686 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4687 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4688 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4689 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4690 .remain_on_channel = brcmf_p2p_remain_on_channel,
4691 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4692 .start_p2p_device = brcmf_p2p_start_device,
4693 .stop_p2p_device = brcmf_p2p_stop_device,
4694 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4695 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4696 .tdls_oper = brcmf_cfg80211_tdls_oper,
4699 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4700 enum nl80211_iftype type,
4703 struct brcmf_cfg80211_vif *vif_walk;
4704 struct brcmf_cfg80211_vif *vif;
4707 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4709 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4711 return ERR_PTR(-ENOMEM);
4713 vif->wdev.wiphy = cfg->wiphy;
4714 vif->wdev.iftype = type;
4716 vif->pm_block = pm_block;
4719 brcmf_init_prof(&vif->profile);
4721 if (type == NL80211_IFTYPE_AP) {
4723 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4724 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4732 list_add_tail(&vif->list, &cfg->vif_list);
4736 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4738 list_del(&vif->list);
4742 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4744 struct brcmf_cfg80211_vif *vif;
4745 struct brcmf_if *ifp;
4747 ifp = netdev_priv(ndev);
4750 brcmf_free_vif(vif);
4754 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4756 u32 event = e->event_code;
4757 u32 status = e->status;
4759 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4760 brcmf_dbg(CONN, "Processing set ssid\n");
4767 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4769 u32 event = e->event_code;
4770 u16 flags = e->flags;
4772 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4773 (event == BRCMF_E_DISASSOC_IND) ||
4774 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4775 brcmf_dbg(CONN, "Processing link down\n");
4781 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4782 const struct brcmf_event_msg *e)
4784 u32 event = e->event_code;
4785 u32 status = e->status;
4787 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4788 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4789 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4793 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4794 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4801 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4803 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4805 kfree(conn_info->req_ie);
4806 conn_info->req_ie = NULL;
4807 conn_info->req_ie_len = 0;
4808 kfree(conn_info->resp_ie);
4809 conn_info->resp_ie = NULL;
4810 conn_info->resp_ie_len = 0;
4813 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4814 struct brcmf_if *ifp)
4816 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4817 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4822 brcmf_clear_assoc_ies(cfg);
4824 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4825 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4827 brcmf_err("could not get assoc info (%d)\n", err);
4831 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4832 req_len = le32_to_cpu(assoc_info->req_len);
4833 resp_len = le32_to_cpu(assoc_info->resp_len);
4835 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4839 brcmf_err("could not get assoc req (%d)\n", err);
4842 conn_info->req_ie_len = req_len;
4844 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4847 conn_info->req_ie_len = 0;
4848 conn_info->req_ie = NULL;
4851 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4855 brcmf_err("could not get assoc resp (%d)\n", err);
4858 conn_info->resp_ie_len = resp_len;
4859 conn_info->resp_ie =
4860 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4863 conn_info->resp_ie_len = 0;
4864 conn_info->resp_ie = NULL;
4866 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4867 conn_info->req_ie_len, conn_info->resp_ie_len);
4873 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4874 struct net_device *ndev,
4875 const struct brcmf_event_msg *e)
4877 struct brcmf_if *ifp = netdev_priv(ndev);
4878 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4879 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4880 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4881 struct ieee80211_channel *notify_channel = NULL;
4882 struct ieee80211_supported_band *band;
4883 struct brcmf_bss_info_le *bi;
4884 struct brcmu_chan ch;
4889 brcmf_dbg(TRACE, "Enter\n");
4891 brcmf_get_assoc_ies(cfg, ifp);
4892 memcpy(profile->bssid, e->addr, ETH_ALEN);
4893 brcmf_update_bss_info(cfg, ifp);
4895 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4901 /* data sent to dongle has to be little endian */
4902 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4903 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4904 buf, WL_BSS_INFO_MAX);
4909 bi = (struct brcmf_bss_info_le *)(buf + 4);
4910 ch.chspec = le16_to_cpu(bi->chanspec);
4911 cfg->d11inf.decchspec(&ch);
4913 if (ch.band == BRCMU_CHAN_BAND_2G)
4914 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4916 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4918 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4919 notify_channel = ieee80211_get_channel(wiphy, freq);
4923 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4924 conn_info->req_ie, conn_info->req_ie_len,
4925 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4926 brcmf_dbg(CONN, "Report roaming result\n");
4928 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4929 brcmf_dbg(TRACE, "Exit\n");
4934 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4935 struct net_device *ndev, const struct brcmf_event_msg *e,
4938 struct brcmf_if *ifp = netdev_priv(ndev);
4939 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4940 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4942 brcmf_dbg(TRACE, "Enter\n");
4944 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4945 &ifp->vif->sme_state)) {
4947 brcmf_get_assoc_ies(cfg, ifp);
4948 memcpy(profile->bssid, e->addr, ETH_ALEN);
4949 brcmf_update_bss_info(cfg, ifp);
4950 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4951 &ifp->vif->sme_state);
4953 cfg80211_connect_result(ndev,
4954 (u8 *)profile->bssid,
4956 conn_info->req_ie_len,
4958 conn_info->resp_ie_len,
4959 completed ? WLAN_STATUS_SUCCESS :
4960 WLAN_STATUS_AUTH_TIMEOUT,
4962 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4963 completed ? "succeeded" : "failed");
4965 brcmf_dbg(TRACE, "Exit\n");
4970 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4971 struct net_device *ndev,
4972 const struct brcmf_event_msg *e, void *data)
4974 struct brcmf_if *ifp = netdev_priv(ndev);
4975 static int generation;
4976 u32 event = e->event_code;
4977 u32 reason = e->reason;
4978 struct station_info sinfo;
4980 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4981 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4982 ndev != cfg_to_ndev(cfg)) {
4983 brcmf_dbg(CONN, "AP mode link down\n");
4984 complete(&cfg->vif_disabled);
4986 brcmf_remove_interface(ifp->drvr, ifp->bssidx);
4990 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4991 (reason == BRCMF_E_STATUS_SUCCESS)) {
4992 memset(&sinfo, 0, sizeof(sinfo));
4994 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4997 sinfo.assoc_req_ies = data;
4998 sinfo.assoc_req_ies_len = e->datalen;
5000 sinfo.generation = generation;
5001 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5002 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5003 (event == BRCMF_E_DEAUTH_IND) ||
5004 (event == BRCMF_E_DEAUTH)) {
5005 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5011 brcmf_notify_connect_status(struct brcmf_if *ifp,
5012 const struct brcmf_event_msg *e, void *data)
5014 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5015 struct net_device *ndev = ifp->ndev;
5016 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5017 struct ieee80211_channel *chan;
5020 if ((e->event_code == BRCMF_E_DEAUTH) ||
5021 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5022 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5023 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5024 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5027 if (brcmf_is_apmode(ifp->vif)) {
5028 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5029 } else if (brcmf_is_linkup(e)) {
5030 brcmf_dbg(CONN, "Linkup\n");
5031 if (brcmf_is_ibssmode(ifp->vif)) {
5032 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5033 memcpy(profile->bssid, e->addr, ETH_ALEN);
5034 wl_inform_ibss(cfg, ndev, e->addr);
5035 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5036 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5037 &ifp->vif->sme_state);
5038 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5039 &ifp->vif->sme_state);
5041 brcmf_bss_connect_done(cfg, ndev, e, true);
5042 } else if (brcmf_is_linkdown(e)) {
5043 brcmf_dbg(CONN, "Linkdown\n");
5044 if (!brcmf_is_ibssmode(ifp->vif)) {
5045 brcmf_bss_connect_done(cfg, ndev, e, false);
5047 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
5048 brcmf_init_prof(ndev_to_prof(ndev));
5049 if (ndev != cfg_to_ndev(cfg))
5050 complete(&cfg->vif_disabled);
5051 } else if (brcmf_is_nonetwork(cfg, e)) {
5052 if (brcmf_is_ibssmode(ifp->vif))
5053 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5054 &ifp->vif->sme_state);
5056 brcmf_bss_connect_done(cfg, ndev, e, false);
5063 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5064 const struct brcmf_event_msg *e, void *data)
5066 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5067 u32 event = e->event_code;
5068 u32 status = e->status;
5070 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5071 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5072 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5074 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5081 brcmf_notify_mic_status(struct brcmf_if *ifp,
5082 const struct brcmf_event_msg *e, void *data)
5084 u16 flags = e->flags;
5085 enum nl80211_key_type key_type;
5087 if (flags & BRCMF_EVENT_MSG_GROUP)
5088 key_type = NL80211_KEYTYPE_GROUP;
5090 key_type = NL80211_KEYTYPE_PAIRWISE;
5092 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5098 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5099 const struct brcmf_event_msg *e, void *data)
5101 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5102 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5103 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5104 struct brcmf_cfg80211_vif *vif;
5106 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
5107 ifevent->action, ifevent->flags, ifevent->ifidx,
5110 mutex_lock(&event->vif_event_lock);
5111 event->action = ifevent->action;
5114 switch (ifevent->action) {
5115 case BRCMF_E_IF_ADD:
5116 /* waiting process may have timed out */
5117 if (!cfg->vif_event.vif) {
5118 mutex_unlock(&event->vif_event_lock);
5125 vif->wdev.netdev = ifp->ndev;
5126 ifp->ndev->ieee80211_ptr = &vif->wdev;
5127 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5129 mutex_unlock(&event->vif_event_lock);
5130 wake_up(&event->vif_wq);
5133 case BRCMF_E_IF_DEL:
5134 mutex_unlock(&event->vif_event_lock);
5135 /* event may not be upon user request */
5136 if (brcmf_cfg80211_vif_event_armed(cfg))
5137 wake_up(&event->vif_wq);
5140 case BRCMF_E_IF_CHANGE:
5141 mutex_unlock(&event->vif_event_lock);
5142 wake_up(&event->vif_wq);
5146 mutex_unlock(&event->vif_event_lock);
5152 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5154 conf->frag_threshold = (u32)-1;
5155 conf->rts_threshold = (u32)-1;
5156 conf->retry_short = (u32)-1;
5157 conf->retry_long = (u32)-1;
5158 conf->tx_power = -1;
5161 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5163 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5164 brcmf_notify_connect_status);
5165 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5166 brcmf_notify_connect_status);
5167 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5168 brcmf_notify_connect_status);
5169 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5170 brcmf_notify_connect_status);
5171 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5172 brcmf_notify_connect_status);
5173 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5174 brcmf_notify_connect_status);
5175 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5176 brcmf_notify_roaming_status);
5177 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5178 brcmf_notify_mic_status);
5179 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5180 brcmf_notify_connect_status);
5181 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5182 brcmf_notify_sched_scan_results);
5183 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5184 brcmf_notify_vif_event);
5185 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5186 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5187 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5188 brcmf_p2p_notify_listen_complete);
5189 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5190 brcmf_p2p_notify_action_frame_rx);
5191 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5192 brcmf_p2p_notify_action_tx_complete);
5193 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5194 brcmf_p2p_notify_action_tx_complete);
5197 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5201 kfree(cfg->escan_ioctl_buf);
5202 cfg->escan_ioctl_buf = NULL;
5203 kfree(cfg->extra_buf);
5204 cfg->extra_buf = NULL;
5205 kfree(cfg->pmk_list);
5206 cfg->pmk_list = NULL;
5209 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5211 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5213 goto init_priv_mem_out;
5214 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5215 if (!cfg->escan_ioctl_buf)
5216 goto init_priv_mem_out;
5217 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5218 if (!cfg->extra_buf)
5219 goto init_priv_mem_out;
5220 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
5222 goto init_priv_mem_out;
5227 brcmf_deinit_priv_mem(cfg);
5232 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5236 cfg->scan_request = NULL;
5237 cfg->pwr_save = true;
5238 cfg->active_scan = true; /* we do active scan per default */
5239 cfg->dongle_up = false; /* dongle is not up yet */
5240 err = brcmf_init_priv_mem(cfg);
5243 brcmf_register_event_handlers(cfg);
5244 mutex_init(&cfg->usr_sync);
5245 brcmf_init_escan(cfg);
5246 brcmf_init_conf(cfg->conf);
5247 init_completion(&cfg->vif_disabled);
5251 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5253 cfg->dongle_up = false; /* dongle down */
5254 brcmf_abort_scanning(cfg);
5255 brcmf_deinit_priv_mem(cfg);
5258 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5260 init_waitqueue_head(&event->vif_wq);
5261 mutex_init(&event->vif_event_lock);
5265 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5268 __le32 roamtrigger[2];
5269 __le32 roam_delta[2];
5272 * Setup timeout if Beacons are lost and roam is
5273 * off to report link down
5275 if (brcmf_roamoff) {
5276 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5278 brcmf_err("bcn_timeout error (%d)\n", err);
5279 goto dongle_rom_out;
5284 * Enable/Disable built-in roaming to allow supplicant
5285 * to take care of roaming
5287 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5288 brcmf_roamoff ? "Off" : "On");
5289 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5291 brcmf_err("roam_off error (%d)\n", err);
5292 goto dongle_rom_out;
5295 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5296 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5297 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5298 (void *)roamtrigger, sizeof(roamtrigger));
5300 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5301 goto dongle_rom_out;
5304 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5305 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5306 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5307 (void *)roam_delta, sizeof(roam_delta));
5309 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5310 goto dongle_rom_out;
5318 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5319 s32 scan_unassoc_time, s32 scan_passive_time)
5323 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5326 if (err == -EOPNOTSUPP)
5327 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5329 brcmf_err("Scan assoc time error (%d)\n", err);
5330 goto dongle_scantime_out;
5332 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5335 if (err == -EOPNOTSUPP)
5336 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5338 brcmf_err("Scan unassoc time error (%d)\n", err);
5339 goto dongle_scantime_out;
5342 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5345 if (err == -EOPNOTSUPP)
5346 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5348 brcmf_err("Scan passive time error (%d)\n", err);
5349 goto dongle_scantime_out;
5352 dongle_scantime_out:
5356 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5357 struct brcmu_chan *ch)
5361 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5362 if (ch->sb == BRCMU_CHAN_SB_U) {
5363 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5364 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5365 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5367 /* It should be one of
5368 * IEEE80211_CHAN_NO_HT40 or
5369 * IEEE80211_CHAN_NO_HT40PLUS
5371 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5372 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5373 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5377 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5380 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5381 struct ieee80211_supported_band *band;
5382 struct ieee80211_channel *channel;
5383 struct wiphy *wiphy;
5384 struct brcmf_chanspec_list *list;
5385 struct brcmu_chan ch;
5393 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5398 list = (struct brcmf_chanspec_list *)pbuf;
5400 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5403 brcmf_err("get chanspecs error (%d)\n", err);
5407 wiphy = cfg_to_wiphy(cfg);
5408 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5410 for (i = 0; i < band->n_channels; i++)
5411 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5412 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5414 for (i = 0; i < band->n_channels; i++)
5415 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5417 total = le32_to_cpu(list->count);
5418 for (i = 0; i < total; i++) {
5419 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5420 cfg->d11inf.decchspec(&ch);
5422 if (ch.band == BRCMU_CHAN_BAND_2G) {
5423 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5424 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5425 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5427 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5432 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5433 ch.bw == BRCMU_CHAN_BW_40)
5435 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5436 ch.bw == BRCMU_CHAN_BW_80)
5439 channel = band->channels;
5440 index = band->n_channels;
5441 for (j = 0; j < band->n_channels; j++) {
5442 if (channel[j].hw_value == ch.chnum) {
5447 channel[index].center_freq =
5448 ieee80211_channel_to_frequency(ch.chnum, band->band);
5449 channel[index].hw_value = ch.chnum;
5451 /* assuming the chanspecs order is HT20,
5452 * HT40 upper, HT40 lower, and VHT80.
5454 if (ch.bw == BRCMU_CHAN_BW_80) {
5455 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5456 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5457 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5459 /* enable the channel and disable other bandwidths
5460 * for now as mentioned order assure they are enabled
5461 * for subsequent chanspecs.
5463 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5464 IEEE80211_CHAN_NO_80MHZ;
5465 ch.bw = BRCMU_CHAN_BW_20;
5466 cfg->d11inf.encchspec(&ch);
5467 chaninfo = ch.chspec;
5468 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5471 if (chaninfo & WL_CHAN_RADAR)
5472 channel[index].flags |=
5473 (IEEE80211_CHAN_RADAR |
5474 IEEE80211_CHAN_NO_IR);
5475 if (chaninfo & WL_CHAN_PASSIVE)
5476 channel[index].flags |=
5477 IEEE80211_CHAN_NO_IR;
5487 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5489 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5490 struct ieee80211_supported_band *band;
5491 struct brcmf_fil_bwcap_le band_bwcap;
5492 struct brcmf_chanspec_list *list;
5496 struct brcmu_chan ch;
5500 /* verify support for bw_cap command */
5502 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5505 /* only set 2G bandwidth using bw_cap command */
5506 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5507 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5508 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5509 sizeof(band_bwcap));
5511 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5512 val = WLC_N_BW_40ALL;
5513 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5517 /* update channel info in 2G band */
5518 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5523 ch.band = BRCMU_CHAN_BAND_2G;
5524 ch.bw = BRCMU_CHAN_BW_40;
5525 ch.sb = BRCMU_CHAN_SB_NONE;
5527 cfg->d11inf.encchspec(&ch);
5529 /* pass encoded chanspec in query */
5530 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5532 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5535 brcmf_err("get chanspecs error (%d)\n", err);
5540 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5541 list = (struct brcmf_chanspec_list *)pbuf;
5542 num_chan = le32_to_cpu(list->count);
5543 for (i = 0; i < num_chan; i++) {
5544 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5545 cfg->d11inf.decchspec(&ch);
5546 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5548 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5550 for (j = 0; j < band->n_channels; j++) {
5551 if (band->channels[j].hw_value == ch.chnum)
5554 if (WARN_ON(j == band->n_channels))
5557 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5564 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5566 u32 band, mimo_bwcap;
5570 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5572 bw_cap[IEEE80211_BAND_2GHZ] = band;
5574 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5576 bw_cap[IEEE80211_BAND_5GHZ] = band;
5582 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5584 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5586 /* assume 20MHz if firmware does not give a clue */
5587 mimo_bwcap = WLC_N_BW_20ALL;
5589 switch (mimo_bwcap) {
5590 case WLC_N_BW_40ALL:
5591 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5593 case WLC_N_BW_20IN2G_40IN5G:
5594 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5596 case WLC_N_BW_20ALL:
5597 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5598 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5601 brcmf_err("invalid mimo_bw_cap value\n");
5605 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5606 u32 bw_cap[2], u32 nchain)
5608 band->ht_cap.ht_supported = true;
5609 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5610 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5611 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5613 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5614 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5615 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5616 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5617 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5618 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5621 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5626 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5627 mcs_map = (mcs_map << 2) | supp;
5629 return cpu_to_le16(mcs_map);
5632 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5633 u32 bw_cap[2], u32 nchain)
5637 /* not allowed in 2.4G band */
5638 if (band->band == IEEE80211_BAND_2GHZ)
5641 band->vht_cap.vht_supported = true;
5642 /* 80MHz is mandatory */
5643 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5644 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5645 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5646 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5648 /* all support 256-QAM */
5649 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5650 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5651 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5654 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5656 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5657 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5660 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5665 struct ieee80211_supported_band *band;
5667 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5668 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5670 brcmf_err("nmode error (%d)\n", err);
5672 brcmf_get_bwcap(ifp, bw_cap);
5674 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5675 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5676 bw_cap[IEEE80211_BAND_5GHZ]);
5678 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5680 brcmf_err("rxchain error (%d)\n", err);
5683 for (nchain = 0; rxchain; nchain++)
5684 rxchain = rxchain & (rxchain - 1);
5686 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5688 err = brcmf_construct_chaninfo(cfg, bw_cap);
5690 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5694 wiphy = cfg_to_wiphy(cfg);
5695 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5696 band = wiphy->bands[i];
5701 brcmf_update_ht_cap(band, bw_cap, nchain);
5703 brcmf_update_vht_cap(band, bw_cap, nchain);
5709 static const struct ieee80211_txrx_stypes
5710 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5711 [NL80211_IFTYPE_STATION] = {
5713 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5714 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5716 [NL80211_IFTYPE_P2P_CLIENT] = {
5718 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5719 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5721 [NL80211_IFTYPE_P2P_GO] = {
5723 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5724 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5725 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5726 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5727 BIT(IEEE80211_STYPE_AUTH >> 4) |
5728 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5729 BIT(IEEE80211_STYPE_ACTION >> 4)
5731 [NL80211_IFTYPE_P2P_DEVICE] = {
5733 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5734 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5739 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5741 * @wiphy: wiphy object.
5742 * @ifp: interface object needed for feat module api.
5744 * The interface modes and combinations are determined dynamically here
5745 * based on firmware functionality.
5747 * no p2p and no mbss:
5749 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5753 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5754 * #AP <= 4, matching BI, channels = 1, 4 total
5756 * p2p, no mchan, and mbss:
5758 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
5759 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5760 * #AP <= 4, matching BI, channels = 1, 4 total
5762 * p2p, mchan, and mbss:
5764 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
5765 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5766 * #AP <= 4, matching BI, channels = 1, 4 total
5768 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5770 struct ieee80211_iface_combination *combo = NULL;
5771 struct ieee80211_iface_limit *c0_limits = NULL;
5772 struct ieee80211_iface_limit *p2p_limits = NULL;
5773 struct ieee80211_iface_limit *mbss_limits = NULL;
5777 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
5778 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
5780 n_combos = 1 + !!p2p + !!mbss;
5781 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
5785 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
5790 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
5796 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
5801 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5802 BIT(NL80211_IFTYPE_ADHOC) |
5803 BIT(NL80211_IFTYPE_AP);
5807 combo[c].num_different_channels = 1;
5808 c0_limits[i].max = 1;
5809 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5811 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5812 combo[c].num_different_channels = 2;
5813 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5814 BIT(NL80211_IFTYPE_P2P_GO) |
5815 BIT(NL80211_IFTYPE_P2P_DEVICE);
5816 c0_limits[i].max = 1;
5817 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5818 c0_limits[i].max = 1;
5819 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5820 BIT(NL80211_IFTYPE_P2P_GO);
5822 c0_limits[i].max = 1;
5823 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5825 combo[c].max_interfaces = i;
5826 combo[c].n_limits = i;
5827 combo[c].limits = c0_limits;
5832 combo[c].num_different_channels = 1;
5833 p2p_limits[i].max = 1;
5834 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5835 p2p_limits[i].max = 1;
5836 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5837 p2p_limits[i].max = 1;
5838 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
5839 p2p_limits[i].max = 1;
5840 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5841 combo[c].max_interfaces = i;
5842 combo[c].n_limits = i;
5843 combo[c].limits = p2p_limits;
5848 combo[c].beacon_int_infra_match = true;
5849 combo[c].num_different_channels = 1;
5850 mbss_limits[0].max = 4;
5851 mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
5852 combo[c].max_interfaces = 4;
5853 combo[c].n_limits = 1;
5854 combo[c].limits = mbss_limits;
5856 wiphy->n_iface_combinations = n_combos;
5857 wiphy->iface_combinations = combo;
5868 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5870 /* scheduled scan settings */
5871 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5872 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5873 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5874 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5878 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5879 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5880 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5881 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5882 .pattern_min_len = 1,
5883 .max_pkt_offset = 1500,
5887 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5891 wiphy->wowlan = &brcmf_wowlan_support;
5895 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5897 struct brcmf_pub *drvr = ifp->drvr;
5898 const struct ieee80211_iface_combination *combo;
5899 struct ieee80211_supported_band *band;
5900 u16 max_interfaces = 0;
5905 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5906 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5907 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5909 err = brcmf_setup_ifmodes(wiphy, ifp);
5913 for (i = 0, combo = wiphy->iface_combinations;
5914 i < wiphy->n_iface_combinations; i++, combo++) {
5915 max_interfaces = max(max_interfaces, combo->max_interfaces);
5918 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
5920 u8 *addr = drvr->addresses[i].addr;
5922 memcpy(addr, drvr->mac, ETH_ALEN);
5925 addr[ETH_ALEN - 1] ^= i;
5928 wiphy->addresses = drvr->addresses;
5929 wiphy->n_addresses = i;
5931 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5932 wiphy->cipher_suites = __wl_cipher_suites;
5933 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5934 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5935 WIPHY_FLAG_OFFCHAN_TX |
5936 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5937 WIPHY_FLAG_SUPPORTS_TDLS;
5939 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5940 wiphy->mgmt_stypes = brcmf_txrx_stypes;
5941 wiphy->max_remain_on_channel_duration = 5000;
5942 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
5943 brcmf_wiphy_pno_params(wiphy);
5945 /* vendor commands/events support */
5946 wiphy->vendor_commands = brcmf_vendor_cmds;
5947 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5949 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
5950 brcmf_wiphy_wowl_params(wiphy);
5952 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
5955 brcmf_err("could not obtain band info: err=%d\n", err);
5958 /* first entry in bandlist is number of bands */
5959 n_bands = le32_to_cpu(bandlist[0]);
5960 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
5961 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
5962 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5967 band->channels = kmemdup(&__wl_2ghz_channels,
5968 sizeof(__wl_2ghz_channels),
5970 if (!band->channels) {
5975 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
5976 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5978 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
5979 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
5984 band->channels = kmemdup(&__wl_5ghz_channels,
5985 sizeof(__wl_5ghz_channels),
5987 if (!band->channels) {
5992 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
5993 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
5996 err = brcmf_setup_wiphybands(wiphy);
6000 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6002 struct net_device *ndev;
6003 struct wireless_dev *wdev;
6004 struct brcmf_if *ifp;
6011 ndev = cfg_to_ndev(cfg);
6012 wdev = ndev->ieee80211_ptr;
6013 ifp = netdev_priv(ndev);
6015 /* make sure RF is ready for work */
6016 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6018 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
6019 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
6021 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6022 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6024 goto default_conf_out;
6025 brcmf_dbg(INFO, "power save set to %s\n",
6026 (power_mode ? "enabled" : "disabled"));
6028 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
6030 goto default_conf_out;
6031 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6034 goto default_conf_out;
6036 brcmf_configure_arp_offload(ifp, true);
6038 cfg->dongle_up = true;
6045 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6047 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6049 return brcmf_config_dongle(ifp->drvr->config);
6052 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6054 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6057 * While going down, if associated with AP disassociate
6058 * from AP to save power
6060 if (check_vif_up(ifp->vif)) {
6061 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6063 /* Make sure WPA_Supplicant receives all the event
6064 generated due to DISASSOC call to the fw to keep
6065 the state fw and WPA_Supplicant state consistent
6070 brcmf_abort_scanning(cfg);
6071 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6076 s32 brcmf_cfg80211_up(struct net_device *ndev)
6078 struct brcmf_if *ifp = netdev_priv(ndev);
6079 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6082 mutex_lock(&cfg->usr_sync);
6083 err = __brcmf_cfg80211_up(ifp);
6084 mutex_unlock(&cfg->usr_sync);
6089 s32 brcmf_cfg80211_down(struct net_device *ndev)
6091 struct brcmf_if *ifp = netdev_priv(ndev);
6092 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6095 mutex_lock(&cfg->usr_sync);
6096 err = __brcmf_cfg80211_down(ifp);
6097 mutex_unlock(&cfg->usr_sync);
6102 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6104 struct wireless_dev *wdev = &ifp->vif->wdev;
6106 return wdev->iftype;
6109 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6110 unsigned long state)
6112 struct brcmf_cfg80211_vif *vif;
6114 list_for_each_entry(vif, &cfg->vif_list, list) {
6115 if (test_bit(state, &vif->sme_state))
6121 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6126 mutex_lock(&event->vif_event_lock);
6127 evt_action = event->action;
6128 mutex_unlock(&event->vif_event_lock);
6129 return evt_action == action;
6132 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6133 struct brcmf_cfg80211_vif *vif)
6135 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6137 mutex_lock(&event->vif_event_lock);
6140 mutex_unlock(&event->vif_event_lock);
6143 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6145 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6148 mutex_lock(&event->vif_event_lock);
6149 armed = event->vif != NULL;
6150 mutex_unlock(&event->vif_event_lock);
6154 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6155 u8 action, ulong timeout)
6157 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6159 return wait_event_timeout(event->vif_wq,
6160 vif_event_equals(event, action), timeout);
6163 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6164 struct regulatory_request *req)
6166 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6167 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6168 struct brcmf_fil_country_le ccreq;
6171 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6172 req->alpha2[0], req->alpha2[1]);
6174 /* ignore non-ISO3166 country codes */
6175 for (i = 0; i < sizeof(req->alpha2); i++)
6176 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6177 brcmf_err("not a ISO3166 code\n");
6180 memset(&ccreq, 0, sizeof(ccreq));
6181 ccreq.rev = cpu_to_le32(-1);
6182 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6183 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6184 brcmf_err("firmware rejected country setting\n");
6187 brcmf_setup_wiphybands(wiphy);
6190 static void brcmf_free_wiphy(struct wiphy *wiphy)
6197 if (wiphy->iface_combinations) {
6198 for (i = 0; i < wiphy->n_iface_combinations; i++)
6199 kfree(wiphy->iface_combinations[i].limits);
6201 kfree(wiphy->iface_combinations);
6202 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6203 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6204 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6206 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6207 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6208 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6213 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6214 struct device *busdev)
6216 struct net_device *ndev = drvr->iflist[0]->ndev;
6217 struct brcmf_cfg80211_info *cfg;
6218 struct wiphy *wiphy;
6219 struct brcmf_cfg80211_vif *vif;
6220 struct brcmf_if *ifp;
6226 brcmf_err("ndev is invalid\n");
6230 ifp = netdev_priv(ndev);
6231 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6233 brcmf_err("Could not allocate wiphy device\n");
6236 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6237 set_wiphy_dev(wiphy, busdev);
6239 cfg = wiphy_priv(wiphy);
6242 init_vif_event(&cfg->vif_event);
6243 INIT_LIST_HEAD(&cfg->vif_list);
6245 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6250 vif->wdev.netdev = ndev;
6251 ndev->ieee80211_ptr = &vif->wdev;
6252 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6254 err = wl_init_priv(cfg);
6256 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6257 brcmf_free_vif(vif);
6262 /* determine d11 io type before wiphy setup */
6263 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6265 brcmf_err("Failed to get D11 version (%d)\n", err);
6268 cfg->d11inf.io_type = (u8)io_type;
6269 brcmu_d11_attach(&cfg->d11inf);
6271 err = brcmf_setup_wiphy(wiphy, ifp);
6275 brcmf_dbg(INFO, "Registering custom regulatory\n");
6276 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6277 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6278 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6280 /* firmware defaults to 40MHz disabled in 2G band. We signal
6281 * cfg80211 here that we do and have it decide we can enable
6282 * it. But first check if device does support 2G operation.
6284 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6285 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6286 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6288 err = wiphy_register(wiphy);
6290 brcmf_err("Could not register wiphy device (%d)\n", err);
6294 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6295 * setup 40MHz in 2GHz band and enable OBSS scanning.
6297 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6298 err = brcmf_enable_bw40_2g(cfg);
6300 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6301 BRCMF_OBSS_COEX_AUTO);
6303 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6306 err = brcmf_p2p_attach(cfg);
6308 brcmf_err("P2P initilisation failed (%d)\n", err);
6309 goto wiphy_unreg_out;
6311 err = brcmf_btcoex_attach(cfg);
6313 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6314 brcmf_p2p_detach(&cfg->p2p);
6315 goto wiphy_unreg_out;
6318 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6320 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6321 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6323 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6324 brcmf_notify_tdls_peer_event);
6330 wiphy_unregister(cfg->wiphy);
6332 wl_deinit_priv(cfg);
6333 brcmf_free_vif(vif);
6335 brcmf_free_wiphy(wiphy);
6339 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6344 brcmf_btcoex_detach(cfg);
6345 wiphy_unregister(cfg->wiphy);
6346 wl_deinit_priv(cfg);
6347 brcmf_free_wiphy(cfg->wiphy);