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 <net/cfg80211.h>
22 #include <net/netlink.h>
24 #include <brcmu_utils.h>
26 #include <brcmu_wifi.h>
29 #include "tracepoint.h"
30 #include "fwil_types.h"
33 #include "wl_cfg80211.h"
36 #define BRCMF_SCAN_IE_LEN_MAX 2048
37 #define BRCMF_PNO_VERSION 2
38 #define BRCMF_PNO_TIME 30
39 #define BRCMF_PNO_REPEAT 4
40 #define BRCMF_PNO_FREQ_EXPO_MAX 3
41 #define BRCMF_PNO_MAX_PFN_COUNT 16
42 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
43 #define BRCMF_PNO_HIDDEN_BIT 2
44 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
45 #define BRCMF_PNO_SCAN_COMPLETE 1
46 #define BRCMF_PNO_SCAN_INCOMPLETE 0
48 #define BRCMF_IFACE_MAX_CNT 3
50 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
51 #define WPA_OUI_TYPE 1
52 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
53 #define WME_OUI_TYPE 2
54 #define WPS_OUI_TYPE 4
56 #define VS_IE_FIXED_HDR_LEN 6
57 #define WPA_IE_VERSION_LEN 2
58 #define WPA_IE_MIN_OUI_LEN 4
59 #define WPA_IE_SUITE_COUNT_LEN 2
61 #define WPA_CIPHER_NONE 0 /* None */
62 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
63 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
64 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
65 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
67 #define RSN_AKM_NONE 0 /* None (IBSS) */
68 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
69 #define RSN_AKM_PSK 2 /* Pre-shared Key */
70 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
71 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
73 #define VNDR_IE_CMD_LEN 4 /* length of the set command
74 * string :"add", "del" (+ NUL)
76 #define VNDR_IE_COUNT_OFFSET 4
77 #define VNDR_IE_PKTFLAG_OFFSET 8
78 #define VNDR_IE_VSIE_OFFSET 12
79 #define VNDR_IE_HDR_SIZE 12
80 #define VNDR_IE_PARSE_LIMIT 5
82 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
83 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
85 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
86 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
87 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
89 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
90 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
92 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
94 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
95 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
102 #define CHAN2G(_channel, _freq, _flags) { \
103 .band = IEEE80211_BAND_2GHZ, \
104 .center_freq = (_freq), \
105 .hw_value = (_channel), \
107 .max_antenna_gain = 0, \
111 #define CHAN5G(_channel, _flags) { \
112 .band = IEEE80211_BAND_5GHZ, \
113 .center_freq = 5000 + (5 * (_channel)), \
114 .hw_value = (_channel), \
116 .max_antenna_gain = 0, \
120 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
121 #define RATETAB_ENT(_rateid, _flags) \
123 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
124 .hw_value = (_rateid), \
128 static struct ieee80211_rate __wl_rates[] = {
129 RATETAB_ENT(BRCM_RATE_1M, 0),
130 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
133 RATETAB_ENT(BRCM_RATE_6M, 0),
134 RATETAB_ENT(BRCM_RATE_9M, 0),
135 RATETAB_ENT(BRCM_RATE_12M, 0),
136 RATETAB_ENT(BRCM_RATE_18M, 0),
137 RATETAB_ENT(BRCM_RATE_24M, 0),
138 RATETAB_ENT(BRCM_RATE_36M, 0),
139 RATETAB_ENT(BRCM_RATE_48M, 0),
140 RATETAB_ENT(BRCM_RATE_54M, 0),
143 #define wl_a_rates (__wl_rates + 4)
144 #define wl_a_rates_size 8
145 #define wl_g_rates (__wl_rates + 0)
146 #define wl_g_rates_size 12
148 static struct ieee80211_channel __wl_2ghz_channels[] = {
165 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
166 CHAN5G(34, 0), CHAN5G(36, 0),
167 CHAN5G(38, 0), CHAN5G(40, 0),
168 CHAN5G(42, 0), CHAN5G(44, 0),
169 CHAN5G(46, 0), CHAN5G(48, 0),
170 CHAN5G(52, 0), CHAN5G(56, 0),
171 CHAN5G(60, 0), CHAN5G(64, 0),
172 CHAN5G(100, 0), CHAN5G(104, 0),
173 CHAN5G(108, 0), CHAN5G(112, 0),
174 CHAN5G(116, 0), CHAN5G(120, 0),
175 CHAN5G(124, 0), CHAN5G(128, 0),
176 CHAN5G(132, 0), CHAN5G(136, 0),
177 CHAN5G(140, 0), CHAN5G(149, 0),
178 CHAN5G(153, 0), CHAN5G(157, 0),
179 CHAN5G(161, 0), CHAN5G(165, 0),
180 CHAN5G(184, 0), CHAN5G(188, 0),
181 CHAN5G(192, 0), CHAN5G(196, 0),
182 CHAN5G(200, 0), CHAN5G(204, 0),
183 CHAN5G(208, 0), CHAN5G(212, 0),
187 static struct ieee80211_supported_band __wl_band_2ghz = {
188 .band = IEEE80211_BAND_2GHZ,
189 .channels = __wl_2ghz_channels,
190 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
191 .bitrates = wl_g_rates,
192 .n_bitrates = wl_g_rates_size,
195 static struct ieee80211_supported_band __wl_band_5ghz_a = {
196 .band = IEEE80211_BAND_5GHZ,
197 .channels = __wl_5ghz_a_channels,
198 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
199 .bitrates = wl_a_rates,
200 .n_bitrates = wl_a_rates_size,
203 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
204 * By default world regulatory domain defined in reg.c puts the flags
205 * NL80211_RRF_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for
206 * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't
207 * start p2p operations on 5GHz channels. All the changes in world regulatory
208 * domain are to be done here.
210 static const struct ieee80211_regdomain brcmf_regdom = {
214 /* IEEE 802.11b/g, channels 1..11 */
215 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
217 /* IEEE 802.11 channel 14 - Only JP enables
218 * this and for 802.11b only
220 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
221 /* IEEE 802.11a, channel 36..64 */
222 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
223 /* IEEE 802.11a, channel 100..165 */
224 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
227 static const u32 __wl_cipher_suites[] = {
228 WLAN_CIPHER_SUITE_WEP40,
229 WLAN_CIPHER_SUITE_WEP104,
230 WLAN_CIPHER_SUITE_TKIP,
231 WLAN_CIPHER_SUITE_CCMP,
232 WLAN_CIPHER_SUITE_AES_CMAC,
235 /* Vendor specific ie. id = 221, oui and type defines exact ie */
236 struct brcmf_vs_tlv {
243 struct parsed_vndr_ie_info {
245 u32 ie_len; /* total length including id & length field */
246 struct brcmf_vs_tlv vndrie;
249 struct parsed_vndr_ies {
251 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
254 /* Quarter dBm units to mW
255 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
256 * Table is offset so the last entry is largest mW value that fits in
260 #define QDBM_OFFSET 153 /* Offset for first entry */
261 #define QDBM_TABLE_LEN 40 /* Table size */
263 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
264 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
266 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
268 /* Largest mW value that will round down to the last table entry,
269 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
270 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
271 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
273 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
275 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
276 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
277 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
278 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
279 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
280 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
281 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
284 static u16 brcmf_qdbm_to_mw(u8 qdbm)
287 int idx = qdbm - QDBM_OFFSET;
289 if (idx >= QDBM_TABLE_LEN)
290 /* clamp to max u16 mW value */
293 /* scale the qdBm index up to the range of the table 0-40
294 * where an offset of 40 qdBm equals a factor of 10 mW.
301 /* return the mW value scaled down to the correct factor of 10,
302 * adding in factor/2 to get proper rounding.
304 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
307 static u8 brcmf_mw_to_qdbm(u16 mw)
314 /* handle boundary case */
318 offset = QDBM_OFFSET;
320 /* move mw into the range of the table */
321 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
326 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
327 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
328 nqdBm_to_mW_map[qdbm]) / 2;
329 if (mw_uint < boundary)
338 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
339 struct ieee80211_channel *ch)
341 struct brcmu_chan ch_inf;
343 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
344 ch_inf.bw = BRCMU_CHAN_BW_20;
345 d11inf->encchspec(&ch_inf);
347 return ch_inf.chspec;
350 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
351 * triples, returning a pointer to the substring whose first element
354 struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
356 struct brcmf_tlv *elt;
359 elt = (struct brcmf_tlv *)buf;
362 /* find tagged parameter */
363 while (totlen >= TLV_HDR_LEN) {
366 /* validate remaining totlen */
367 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
370 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
371 totlen -= (len + TLV_HDR_LEN);
377 /* Is any of the tlvs the expected entry? If
378 * not update the tlvs buffer pointer/length.
381 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
382 u8 *oui, u32 oui_len, u8 type)
384 /* If the contents match the OUI and the type */
385 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
386 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
387 type == ie[TLV_BODY_OFF + oui_len]) {
393 /* point to the next ie */
394 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
395 /* calculate the length of the rest of the buffer */
396 *tlvs_len -= (int)(ie - *tlvs);
397 /* update the pointer to the start of the buffer */
403 static struct brcmf_vs_tlv *
404 brcmf_find_wpaie(u8 *parse, u32 len)
406 struct brcmf_tlv *ie;
408 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
409 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
410 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
411 return (struct brcmf_vs_tlv *)ie;
416 static struct brcmf_vs_tlv *
417 brcmf_find_wpsie(u8 *parse, u32 len)
419 struct brcmf_tlv *ie;
421 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
422 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
423 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
424 return (struct brcmf_vs_tlv *)ie;
430 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
431 struct brcmf_wsec_key_le *key_le)
433 key_le->index = cpu_to_le32(key->index);
434 key_le->len = cpu_to_le32(key->len);
435 key_le->algo = cpu_to_le32(key->algo);
436 key_le->flags = cpu_to_le32(key->flags);
437 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
438 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
439 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
440 memcpy(key_le->data, key->data, sizeof(key->data));
441 memcpy(key_le->ea, key->ea, sizeof(key->ea));
445 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
448 struct brcmf_wsec_key_le key_le;
450 convert_key_from_CPU(key, &key_le);
452 brcmf_netdev_wait_pend8021x(ndev);
454 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
458 brcmf_err("wsec_key error (%d)\n", err);
463 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
469 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
473 /* Try to set and enable ARP offload feature, this may fail, then it */
474 /* is simply not supported and err 0 will be returned */
475 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
477 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
481 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
483 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
487 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
494 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
496 enum nl80211_iftype type,
498 struct vif_params *params)
500 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
502 case NL80211_IFTYPE_ADHOC:
503 case NL80211_IFTYPE_STATION:
504 case NL80211_IFTYPE_AP:
505 case NL80211_IFTYPE_AP_VLAN:
506 case NL80211_IFTYPE_WDS:
507 case NL80211_IFTYPE_MONITOR:
508 case NL80211_IFTYPE_MESH_POINT:
509 return ERR_PTR(-EOPNOTSUPP);
510 case NL80211_IFTYPE_P2P_CLIENT:
511 case NL80211_IFTYPE_P2P_GO:
512 case NL80211_IFTYPE_P2P_DEVICE:
513 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
514 case NL80211_IFTYPE_UNSPECIFIED:
516 return ERR_PTR(-EINVAL);
520 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
524 if (check_vif_up(ifp->vif)) {
525 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
527 brcmf_err("fail to set mpc\n");
530 brcmf_dbg(INFO, "MPC : %d\n", mpc);
534 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
535 struct brcmf_if *ifp, bool aborted,
538 struct brcmf_scan_params_le params_le;
539 struct cfg80211_scan_request *scan_request;
542 brcmf_dbg(SCAN, "Enter\n");
544 /* clear scan request, because the FW abort can cause a second call */
545 /* to this functon and might cause a double cfg80211_scan_done */
546 scan_request = cfg->scan_request;
547 cfg->scan_request = NULL;
549 if (timer_pending(&cfg->escan_timeout))
550 del_timer_sync(&cfg->escan_timeout);
553 /* Do a scan abort to stop the driver's scan engine */
554 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
555 memset(¶ms_le, 0, sizeof(params_le));
556 memset(params_le.bssid, 0xFF, ETH_ALEN);
557 params_le.bss_type = DOT11_BSSTYPE_ANY;
558 params_le.scan_type = 0;
559 params_le.channel_num = cpu_to_le32(1);
560 params_le.nprobes = cpu_to_le32(1);
561 params_le.active_time = cpu_to_le32(-1);
562 params_le.passive_time = cpu_to_le32(-1);
563 params_le.home_time = cpu_to_le32(-1);
564 /* Scan is aborted by setting channel_list[0] to -1 */
565 params_le.channel_list[0] = cpu_to_le16(-1);
566 /* E-Scan (or anyother type) can be aborted by SCAN */
567 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
568 ¶ms_le, sizeof(params_le));
570 brcmf_err("Scan abort failed\n");
573 * e-scan can be initiated by scheduled scan
574 * which takes precedence.
576 if (cfg->sched_escan) {
577 brcmf_dbg(SCAN, "scheduled scan completed\n");
578 cfg->sched_escan = false;
580 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
581 brcmf_set_mpc(ifp, 1);
582 } else if (scan_request) {
583 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
584 aborted ? "Aborted" : "Done");
585 cfg80211_scan_done(scan_request, aborted);
586 brcmf_set_mpc(ifp, 1);
588 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
589 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
595 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
597 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
598 struct net_device *ndev = wdev->netdev;
600 /* vif event pending in firmware */
601 if (brcmf_cfg80211_vif_event_armed(cfg))
605 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
606 cfg->escan_info.ifp == netdev_priv(ndev))
607 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
610 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
613 switch (wdev->iftype) {
614 case NL80211_IFTYPE_ADHOC:
615 case NL80211_IFTYPE_STATION:
616 case NL80211_IFTYPE_AP:
617 case NL80211_IFTYPE_AP_VLAN:
618 case NL80211_IFTYPE_WDS:
619 case NL80211_IFTYPE_MONITOR:
620 case NL80211_IFTYPE_MESH_POINT:
622 case NL80211_IFTYPE_P2P_CLIENT:
623 case NL80211_IFTYPE_P2P_GO:
624 case NL80211_IFTYPE_P2P_DEVICE:
625 return brcmf_p2p_del_vif(wiphy, wdev);
626 case NL80211_IFTYPE_UNSPECIFIED:
634 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
635 enum nl80211_iftype type, u32 *flags,
636 struct vif_params *params)
638 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
639 struct brcmf_if *ifp = netdev_priv(ndev);
640 struct brcmf_cfg80211_vif *vif = ifp->vif;
645 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
648 case NL80211_IFTYPE_MONITOR:
649 case NL80211_IFTYPE_WDS:
650 brcmf_err("type (%d) : currently we do not support this type\n",
653 case NL80211_IFTYPE_ADHOC:
654 vif->mode = WL_MODE_IBSS;
657 case NL80211_IFTYPE_STATION:
658 /* Ignore change for p2p IF. Unclear why supplicant does this */
659 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
660 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
661 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
662 /* WAR: It is unexpected to get a change of VIF for P2P
663 * IF, but it happens. The request can not be handled
664 * but returning EPERM causes a crash. Returning 0
665 * without setting ieee80211_ptr->iftype causes trace
666 * (WARN_ON) but it works with wpa_supplicant
670 vif->mode = WL_MODE_BSS;
673 case NL80211_IFTYPE_AP:
674 case NL80211_IFTYPE_P2P_GO:
675 vif->mode = WL_MODE_AP;
684 if (type == NL80211_IFTYPE_P2P_GO) {
685 brcmf_dbg(INFO, "IF Type = P2P GO\n");
686 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
689 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
690 brcmf_dbg(INFO, "IF Type = AP\n");
693 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
695 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
699 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
702 ndev->ieee80211_ptr->iftype = type;
705 brcmf_dbg(TRACE, "Exit\n");
710 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
711 struct brcmf_scan_params_le *params_le,
712 struct cfg80211_scan_request *request)
720 struct brcmf_ssid_le ssid_le;
722 memset(params_le->bssid, 0xFF, ETH_ALEN);
723 params_le->bss_type = DOT11_BSSTYPE_ANY;
724 params_le->scan_type = 0;
725 params_le->channel_num = 0;
726 params_le->nprobes = cpu_to_le32(-1);
727 params_le->active_time = cpu_to_le32(-1);
728 params_le->passive_time = cpu_to_le32(-1);
729 params_le->home_time = cpu_to_le32(-1);
730 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
732 /* if request is null exit so it will be all channel broadcast scan */
736 n_ssids = request->n_ssids;
737 n_channels = request->n_channels;
738 /* Copy channel array if applicable */
739 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
741 if (n_channels > 0) {
742 for (i = 0; i < n_channels; i++) {
743 chanspec = channel_to_chanspec(&cfg->d11inf,
744 request->channels[i]);
745 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
746 request->channels[i]->hw_value, chanspec);
747 params_le->channel_list[i] = cpu_to_le16(chanspec);
750 brcmf_dbg(SCAN, "Scanning all channels\n");
752 /* Copy ssid array if applicable */
753 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
755 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
756 n_channels * sizeof(u16);
757 offset = roundup(offset, sizeof(u32));
758 ptr = (char *)params_le + offset;
759 for (i = 0; i < n_ssids; i++) {
760 memset(&ssid_le, 0, sizeof(ssid_le));
762 cpu_to_le32(request->ssids[i].ssid_len);
763 memcpy(ssid_le.SSID, request->ssids[i].ssid,
764 request->ssids[i].ssid_len);
765 if (!ssid_le.SSID_len)
766 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
768 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
769 i, ssid_le.SSID, ssid_le.SSID_len);
770 memcpy(ptr, &ssid_le, sizeof(ssid_le));
771 ptr += sizeof(ssid_le);
774 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
775 if ((request->ssids) && request->ssids->ssid_len) {
776 brcmf_dbg(SCAN, "SSID %s len=%d\n",
777 params_le->ssid_le.SSID,
778 request->ssids->ssid_len);
779 params_le->ssid_le.SSID_len =
780 cpu_to_le32(request->ssids->ssid_len);
781 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
782 request->ssids->ssid_len);
785 /* Adding mask to channel numbers */
786 params_le->channel_num =
787 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
788 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
792 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
793 struct cfg80211_scan_request *request, u16 action)
795 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
796 offsetof(struct brcmf_escan_params_le, params_le);
797 struct brcmf_escan_params_le *params;
800 brcmf_dbg(SCAN, "E-SCAN START\n");
802 if (request != NULL) {
803 /* Allocate space for populating ssids in struct */
804 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
806 /* Allocate space for populating ssids in struct */
807 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
810 params = kzalloc(params_size, GFP_KERNEL);
815 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
816 brcmf_escan_prep(cfg, ¶ms->params_le, request);
817 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
818 params->action = cpu_to_le16(action);
819 params->sync_id = cpu_to_le16(0x1234);
821 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
824 brcmf_dbg(INFO, "system busy : escan canceled\n");
826 brcmf_err("error (%d)\n", err);
835 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
836 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
840 struct brcmf_scan_results *results;
841 struct escan_info *escan = &cfg->escan_info;
843 brcmf_dbg(SCAN, "Enter\n");
845 escan->wiphy = wiphy;
846 escan->escan_state = WL_ESCAN_STATE_SCANNING;
847 passive_scan = cfg->active_scan ? 0 : 1;
848 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
851 brcmf_err("error (%d)\n", err);
854 brcmf_set_mpc(ifp, 0);
855 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
856 results->version = 0;
858 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
860 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
862 brcmf_set_mpc(ifp, 1);
867 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
868 struct cfg80211_scan_request *request,
869 struct cfg80211_ssid *this_ssid)
871 struct brcmf_if *ifp = vif->ifp;
872 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
873 struct cfg80211_ssid *ssids;
874 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
881 brcmf_dbg(SCAN, "START ESCAN\n");
883 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
884 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
887 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
888 brcmf_err("Scanning being aborted: status (%lu)\n",
892 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
893 brcmf_err("Scanning suppressed: status (%lu)\n",
897 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
898 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
902 /* If scan req comes for p2p0, send it over primary I/F */
903 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
904 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
906 /* Arm scan timeout timer */
907 mod_timer(&cfg->escan_timeout, jiffies +
908 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
913 ssids = request->ssids;
917 /* we don't do escan in ibss */
921 cfg->scan_request = request;
922 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
924 cfg->escan_info.run = brcmf_run_escan;
925 err = brcmf_p2p_scan_prep(wiphy, request, vif);
929 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
933 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
934 ssids->ssid, ssids->ssid_len);
935 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
936 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
937 sr->ssid_le.SSID_len = cpu_to_le32(0);
940 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
941 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
944 brcmf_dbg(SCAN, "Broadcast scan\n");
946 passive_scan = cfg->active_scan ? 0 : 1;
947 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
950 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
953 brcmf_set_mpc(ifp, 0);
954 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
955 &sr->ssid_le, sizeof(sr->ssid_le));
958 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
961 brcmf_err("WLC_SCAN error (%d)\n", err);
963 brcmf_set_mpc(ifp, 1);
971 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
972 if (timer_pending(&cfg->escan_timeout))
973 del_timer_sync(&cfg->escan_timeout);
974 cfg->scan_request = NULL;
979 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
981 struct brcmf_cfg80211_vif *vif;
984 brcmf_dbg(TRACE, "Enter\n");
985 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
986 if (!check_vif_up(vif))
989 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
992 brcmf_err("scan error (%d)\n", err);
994 brcmf_dbg(TRACE, "Exit\n");
998 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1002 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1005 brcmf_err("Error (%d)\n", err);
1010 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1014 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1017 brcmf_err("Error (%d)\n", err);
1022 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1025 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1027 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1029 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1035 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1037 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1038 struct net_device *ndev = cfg_to_ndev(cfg);
1039 struct brcmf_if *ifp = netdev_priv(ndev);
1042 brcmf_dbg(TRACE, "Enter\n");
1043 if (!check_vif_up(ifp->vif))
1046 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1047 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1048 cfg->conf->rts_threshold = wiphy->rts_threshold;
1049 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1053 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1054 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1055 cfg->conf->frag_threshold = wiphy->frag_threshold;
1056 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1060 if (changed & WIPHY_PARAM_RETRY_LONG
1061 && (cfg->conf->retry_long != wiphy->retry_long)) {
1062 cfg->conf->retry_long = wiphy->retry_long;
1063 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1067 if (changed & WIPHY_PARAM_RETRY_SHORT
1068 && (cfg->conf->retry_short != wiphy->retry_short)) {
1069 cfg->conf->retry_short = wiphy->retry_short;
1070 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1076 brcmf_dbg(TRACE, "Exit\n");
1080 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1082 memset(prof, 0, sizeof(*prof));
1085 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1087 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1090 brcmf_dbg(TRACE, "Enter\n");
1092 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1093 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1094 err = brcmf_fil_cmd_data_set(vif->ifp,
1095 BRCMF_C_DISASSOC, NULL, 0);
1097 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1098 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1100 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1101 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1102 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1103 brcmf_dbg(TRACE, "Exit\n");
1107 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1108 struct cfg80211_ibss_params *params)
1110 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1111 struct brcmf_if *ifp = netdev_priv(ndev);
1112 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1113 struct brcmf_join_params join_params;
1114 size_t join_params_size = 0;
1120 brcmf_dbg(TRACE, "Enter\n");
1121 if (!check_vif_up(ifp->vif))
1125 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1127 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1131 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1134 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1136 brcmf_dbg(CONN, "No BSSID specified\n");
1138 if (params->chandef.chan)
1139 brcmf_dbg(CONN, "channel: %d\n",
1140 params->chandef.chan->center_freq);
1142 brcmf_dbg(CONN, "no channel specified\n");
1144 if (params->channel_fixed)
1145 brcmf_dbg(CONN, "fixed channel required\n");
1147 brcmf_dbg(CONN, "no fixed channel required\n");
1149 if (params->ie && params->ie_len)
1150 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1152 brcmf_dbg(CONN, "no ie specified\n");
1154 if (params->beacon_interval)
1155 brcmf_dbg(CONN, "beacon interval: %d\n",
1156 params->beacon_interval);
1158 brcmf_dbg(CONN, "no beacon interval specified\n");
1160 if (params->basic_rates)
1161 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1163 brcmf_dbg(CONN, "no basic rates specified\n");
1165 if (params->privacy)
1166 brcmf_dbg(CONN, "privacy required\n");
1168 brcmf_dbg(CONN, "no privacy required\n");
1170 /* Configure Privacy for starter */
1171 if (params->privacy)
1172 wsec |= WEP_ENABLED;
1174 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1176 brcmf_err("wsec failed (%d)\n", err);
1180 /* Configure Beacon Interval for starter */
1181 if (params->beacon_interval)
1182 bcnprd = params->beacon_interval;
1186 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1188 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1192 /* Configure required join parameter */
1193 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1196 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1197 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1198 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1199 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1200 join_params_size = sizeof(join_params.ssid_le);
1203 if (params->bssid) {
1204 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1205 join_params_size = sizeof(join_params.ssid_le) +
1206 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1207 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1209 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1210 memset(profile->bssid, 0, ETH_ALEN);
1214 if (params->chandef.chan) {
1218 ieee80211_frequency_to_channel(
1219 params->chandef.chan->center_freq);
1220 if (params->channel_fixed) {
1221 /* adding chanspec */
1222 chanspec = channel_to_chanspec(&cfg->d11inf,
1223 params->chandef.chan);
1224 join_params.params_le.chanspec_list[0] =
1225 cpu_to_le16(chanspec);
1226 join_params.params_le.chanspec_num = cpu_to_le32(1);
1227 join_params_size += sizeof(join_params.params_le);
1230 /* set channel for starter */
1231 target_channel = cfg->channel;
1232 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1235 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1241 cfg->ibss_starter = false;
1244 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1245 &join_params, join_params_size);
1247 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1253 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1254 brcmf_dbg(TRACE, "Exit\n");
1259 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1261 struct brcmf_if *ifp = netdev_priv(ndev);
1264 brcmf_dbg(TRACE, "Enter\n");
1265 if (!check_vif_up(ifp->vif))
1268 brcmf_link_down(ifp->vif);
1270 brcmf_dbg(TRACE, "Exit\n");
1275 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1276 struct cfg80211_connect_params *sme)
1278 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1279 struct brcmf_cfg80211_security *sec;
1283 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1284 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1285 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1286 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1288 val = WPA_AUTH_DISABLED;
1289 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1290 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1292 brcmf_err("set wpa_auth failed (%d)\n", err);
1295 sec = &profile->sec;
1296 sec->wpa_versions = sme->crypto.wpa_versions;
1300 static s32 brcmf_set_auth_type(struct net_device *ndev,
1301 struct cfg80211_connect_params *sme)
1303 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1304 struct brcmf_cfg80211_security *sec;
1308 switch (sme->auth_type) {
1309 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1311 brcmf_dbg(CONN, "open system\n");
1313 case NL80211_AUTHTYPE_SHARED_KEY:
1315 brcmf_dbg(CONN, "shared key\n");
1317 case NL80211_AUTHTYPE_AUTOMATIC:
1319 brcmf_dbg(CONN, "automatic\n");
1321 case NL80211_AUTHTYPE_NETWORK_EAP:
1322 brcmf_dbg(CONN, "network eap\n");
1325 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1329 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1331 brcmf_err("set auth failed (%d)\n", err);
1334 sec = &profile->sec;
1335 sec->auth_type = sme->auth_type;
1340 brcmf_set_set_cipher(struct net_device *ndev,
1341 struct cfg80211_connect_params *sme)
1343 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1344 struct brcmf_cfg80211_security *sec;
1349 if (sme->crypto.n_ciphers_pairwise) {
1350 switch (sme->crypto.ciphers_pairwise[0]) {
1351 case WLAN_CIPHER_SUITE_WEP40:
1352 case WLAN_CIPHER_SUITE_WEP104:
1355 case WLAN_CIPHER_SUITE_TKIP:
1356 pval = TKIP_ENABLED;
1358 case WLAN_CIPHER_SUITE_CCMP:
1361 case WLAN_CIPHER_SUITE_AES_CMAC:
1365 brcmf_err("invalid cipher pairwise (%d)\n",
1366 sme->crypto.ciphers_pairwise[0]);
1370 if (sme->crypto.cipher_group) {
1371 switch (sme->crypto.cipher_group) {
1372 case WLAN_CIPHER_SUITE_WEP40:
1373 case WLAN_CIPHER_SUITE_WEP104:
1376 case WLAN_CIPHER_SUITE_TKIP:
1377 gval = TKIP_ENABLED;
1379 case WLAN_CIPHER_SUITE_CCMP:
1382 case WLAN_CIPHER_SUITE_AES_CMAC:
1386 brcmf_err("invalid cipher group (%d)\n",
1387 sme->crypto.cipher_group);
1392 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1393 /* In case of privacy, but no security and WPS then simulate */
1394 /* setting AES. WPS-2.0 allows no security */
1395 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1398 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1400 brcmf_err("error (%d)\n", err);
1404 sec = &profile->sec;
1405 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1406 sec->cipher_group = sme->crypto.cipher_group;
1412 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1414 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1415 struct brcmf_cfg80211_security *sec;
1419 if (sme->crypto.n_akm_suites) {
1420 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1423 brcmf_err("could not get wpa_auth (%d)\n", err);
1426 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1427 switch (sme->crypto.akm_suites[0]) {
1428 case WLAN_AKM_SUITE_8021X:
1429 val = WPA_AUTH_UNSPECIFIED;
1431 case WLAN_AKM_SUITE_PSK:
1435 brcmf_err("invalid cipher group (%d)\n",
1436 sme->crypto.cipher_group);
1439 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1440 switch (sme->crypto.akm_suites[0]) {
1441 case WLAN_AKM_SUITE_8021X:
1442 val = WPA2_AUTH_UNSPECIFIED;
1444 case WLAN_AKM_SUITE_PSK:
1445 val = WPA2_AUTH_PSK;
1448 brcmf_err("invalid cipher group (%d)\n",
1449 sme->crypto.cipher_group);
1454 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1455 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1458 brcmf_err("could not set wpa_auth (%d)\n", err);
1462 sec = &profile->sec;
1463 sec->wpa_auth = sme->crypto.akm_suites[0];
1469 brcmf_set_sharedkey(struct net_device *ndev,
1470 struct cfg80211_connect_params *sme)
1472 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1473 struct brcmf_cfg80211_security *sec;
1474 struct brcmf_wsec_key key;
1478 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1480 if (sme->key_len == 0)
1483 sec = &profile->sec;
1484 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1485 sec->wpa_versions, sec->cipher_pairwise);
1487 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1490 if (!(sec->cipher_pairwise &
1491 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1494 memset(&key, 0, sizeof(key));
1495 key.len = (u32) sme->key_len;
1496 key.index = (u32) sme->key_idx;
1497 if (key.len > sizeof(key.data)) {
1498 brcmf_err("Too long key length (%u)\n", key.len);
1501 memcpy(key.data, sme->key, key.len);
1502 key.flags = BRCMF_PRIMARY_KEY;
1503 switch (sec->cipher_pairwise) {
1504 case WLAN_CIPHER_SUITE_WEP40:
1505 key.algo = CRYPTO_ALGO_WEP1;
1507 case WLAN_CIPHER_SUITE_WEP104:
1508 key.algo = CRYPTO_ALGO_WEP128;
1511 brcmf_err("Invalid algorithm (%d)\n",
1512 sme->crypto.ciphers_pairwise[0]);
1515 /* Set the new key/index */
1516 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1517 key.len, key.index, key.algo);
1518 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1519 err = send_key_to_dongle(ndev, &key);
1523 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1524 brcmf_dbg(CONN, "set auth_type to shared key\n");
1525 val = WL_AUTH_SHARED_KEY; /* shared key */
1526 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1528 brcmf_err("set auth failed (%d)\n", err);
1534 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1535 enum nl80211_auth_type type)
1538 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1539 /* shift to ignore chip revision */
1540 ci = brcmf_get_chip_info(ifp) >> 4;
1543 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1544 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1553 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1554 struct cfg80211_connect_params *sme)
1556 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1557 struct brcmf_if *ifp = netdev_priv(ndev);
1558 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1559 struct ieee80211_channel *chan = sme->channel;
1560 struct brcmf_join_params join_params;
1561 size_t join_params_size;
1562 struct brcmf_tlv *rsn_ie;
1563 struct brcmf_vs_tlv *wpa_ie;
1566 struct brcmf_ext_join_params_le *ext_join_params;
1571 brcmf_dbg(TRACE, "Enter\n");
1572 if (!check_vif_up(ifp->vif))
1576 brcmf_err("Invalid ssid\n");
1580 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1581 /* A normal (non P2P) connection request setup. */
1584 /* find the WPA_IE */
1585 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1588 ie_len = wpa_ie->len + TLV_HDR_LEN;
1590 /* find the RSN_IE */
1591 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1595 ie_len = rsn_ie->len + TLV_HDR_LEN;
1598 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1601 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1602 sme->ie, sme->ie_len);
1604 brcmf_err("Set Assoc REQ IE Failed\n");
1606 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1608 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1612 ieee80211_frequency_to_channel(chan->center_freq);
1613 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1614 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1615 cfg->channel, chan->center_freq, chanspec);
1621 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1623 err = brcmf_set_wpa_version(ndev, sme);
1625 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1629 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1630 err = brcmf_set_auth_type(ndev, sme);
1632 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1636 err = brcmf_set_set_cipher(ndev, sme);
1638 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1642 err = brcmf_set_key_mgmt(ndev, sme);
1644 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1648 err = brcmf_set_sharedkey(ndev, sme);
1650 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1654 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1655 (u32)sme->ssid_len);
1656 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1657 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1658 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1659 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1660 profile->ssid.SSID_len);
1663 /* Join with specific BSSID and cached SSID
1664 * If SSID is zero join based on BSSID only
1666 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1667 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1669 join_params_size += sizeof(u16);
1670 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1671 if (ext_join_params == NULL) {
1675 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1676 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1677 profile->ssid.SSID_len);
1678 /*increase dwell time to receive probe response or detect Beacon
1679 * from target AP at a noisy air only during connect command
1681 ext_join_params->scan_le.active_time =
1682 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1683 ext_join_params->scan_le.passive_time =
1684 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1685 /* Set up join scan parameters */
1686 ext_join_params->scan_le.scan_type = -1;
1687 /* to sync with presence period of VSDB GO.
1688 * Send probe request more frequently. Probe request will be stopped
1689 * when it gets probe response from target AP/GO.
1691 ext_join_params->scan_le.nprobes =
1692 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1693 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1694 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1697 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1699 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1702 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1704 ext_join_params->assoc_le.chanspec_list[0] =
1705 cpu_to_le16(chanspec);
1708 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1710 kfree(ext_join_params);
1712 /* This is it. join command worked, we are done */
1715 /* join command failed, fallback to set ssid */
1716 memset(&join_params, 0, sizeof(join_params));
1717 join_params_size = sizeof(join_params.ssid_le);
1719 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1720 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1723 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1725 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1728 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1729 join_params.params_le.chanspec_num = cpu_to_le32(1);
1730 join_params_size += sizeof(join_params.params_le);
1732 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1733 &join_params, join_params_size);
1735 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1739 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1740 brcmf_dbg(TRACE, "Exit\n");
1745 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1748 struct brcmf_if *ifp = netdev_priv(ndev);
1749 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1750 struct brcmf_scb_val_le scbval;
1753 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1754 if (!check_vif_up(ifp->vif))
1757 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1759 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1760 scbval.val = cpu_to_le32(reason_code);
1761 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1762 &scbval, sizeof(scbval));
1764 brcmf_err("error (%d)\n", err);
1766 brcmf_dbg(TRACE, "Exit\n");
1771 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1772 enum nl80211_tx_power_setting type, s32 mbm)
1775 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1776 struct net_device *ndev = cfg_to_ndev(cfg);
1777 struct brcmf_if *ifp = netdev_priv(ndev);
1781 s32 dbm = MBM_TO_DBM(mbm);
1783 brcmf_dbg(TRACE, "Enter\n");
1784 if (!check_vif_up(ifp->vif))
1788 case NL80211_TX_POWER_AUTOMATIC:
1790 case NL80211_TX_POWER_LIMITED:
1791 case NL80211_TX_POWER_FIXED:
1793 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1799 /* Make sure radio is off or on as far as software is concerned */
1800 disable = WL_RADIO_SW_DISABLE << 16;
1801 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1803 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1808 txpwrmw = (u16) dbm;
1809 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1810 (s32)brcmf_mw_to_qdbm(txpwrmw));
1812 brcmf_err("qtxpower error (%d)\n", err);
1813 cfg->conf->tx_power = dbm;
1816 brcmf_dbg(TRACE, "Exit\n");
1820 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1821 struct wireless_dev *wdev,
1824 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1825 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1830 brcmf_dbg(TRACE, "Enter\n");
1831 if (!check_vif_up(ifp->vif))
1834 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1836 brcmf_err("error (%d)\n", err);
1840 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1841 *dbm = (s32) brcmf_qdbm_to_mw(result);
1844 brcmf_dbg(TRACE, "Exit\n");
1849 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1850 u8 key_idx, bool unicast, bool multicast)
1852 struct brcmf_if *ifp = netdev_priv(ndev);
1857 brcmf_dbg(TRACE, "Enter\n");
1858 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1859 if (!check_vif_up(ifp->vif))
1862 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1864 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1868 if (wsec & WEP_ENABLED) {
1869 /* Just select a new current key */
1871 err = brcmf_fil_cmd_int_set(ifp,
1872 BRCMF_C_SET_KEY_PRIMARY, index);
1874 brcmf_err("error (%d)\n", err);
1877 brcmf_dbg(TRACE, "Exit\n");
1882 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1883 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1885 struct brcmf_if *ifp = netdev_priv(ndev);
1886 struct brcmf_wsec_key key;
1890 memset(&key, 0, sizeof(key));
1891 key.index = (u32) key_idx;
1892 /* Instead of bcast for ea address for default wep keys,
1893 driver needs it to be Null */
1894 if (!is_multicast_ether_addr(mac_addr))
1895 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1896 key.len = (u32) params->key_len;
1897 /* check for key index change */
1900 err = send_key_to_dongle(ndev, &key);
1902 brcmf_err("key delete error (%d)\n", err);
1904 if (key.len > sizeof(key.data)) {
1905 brcmf_err("Invalid key length (%d)\n", key.len);
1909 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1910 memcpy(key.data, params->key, key.len);
1912 if ((ifp->vif->mode != WL_MODE_AP) &&
1913 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1914 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1915 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1916 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1917 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1920 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1921 if (params->seq && params->seq_len == 6) {
1924 ivptr = (u8 *) params->seq;
1925 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1926 (ivptr[3] << 8) | ivptr[2];
1927 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1928 key.iv_initialized = true;
1931 switch (params->cipher) {
1932 case WLAN_CIPHER_SUITE_WEP40:
1933 key.algo = CRYPTO_ALGO_WEP1;
1934 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1936 case WLAN_CIPHER_SUITE_WEP104:
1937 key.algo = CRYPTO_ALGO_WEP128;
1938 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1940 case WLAN_CIPHER_SUITE_TKIP:
1941 key.algo = CRYPTO_ALGO_TKIP;
1942 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1944 case WLAN_CIPHER_SUITE_AES_CMAC:
1945 key.algo = CRYPTO_ALGO_AES_CCM;
1946 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1948 case WLAN_CIPHER_SUITE_CCMP:
1949 key.algo = CRYPTO_ALGO_AES_CCM;
1950 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1953 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1956 err = send_key_to_dongle(ndev, &key);
1958 brcmf_err("wsec_key error (%d)\n", err);
1964 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1965 u8 key_idx, bool pairwise, const u8 *mac_addr,
1966 struct key_params *params)
1968 struct brcmf_if *ifp = netdev_priv(ndev);
1969 struct brcmf_wsec_key key;
1975 brcmf_dbg(TRACE, "Enter\n");
1976 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1977 if (!check_vif_up(ifp->vif))
1981 brcmf_dbg(TRACE, "Exit");
1982 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1984 memset(&key, 0, sizeof(key));
1986 key.len = (u32) params->key_len;
1987 key.index = (u32) key_idx;
1989 if (key.len > sizeof(key.data)) {
1990 brcmf_err("Too long key length (%u)\n", key.len);
1994 memcpy(key.data, params->key, key.len);
1996 key.flags = BRCMF_PRIMARY_KEY;
1997 switch (params->cipher) {
1998 case WLAN_CIPHER_SUITE_WEP40:
1999 key.algo = CRYPTO_ALGO_WEP1;
2001 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2003 case WLAN_CIPHER_SUITE_WEP104:
2004 key.algo = CRYPTO_ALGO_WEP128;
2006 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2008 case WLAN_CIPHER_SUITE_TKIP:
2009 if (ifp->vif->mode != WL_MODE_AP) {
2010 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2011 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2012 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2013 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2015 key.algo = CRYPTO_ALGO_TKIP;
2017 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2019 case WLAN_CIPHER_SUITE_AES_CMAC:
2020 key.algo = CRYPTO_ALGO_AES_CCM;
2022 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2024 case WLAN_CIPHER_SUITE_CCMP:
2025 key.algo = CRYPTO_ALGO_AES_CCM;
2027 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2030 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2035 err = send_key_to_dongle(ndev, &key);
2039 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2041 brcmf_err("get wsec error (%d)\n", err);
2045 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2047 brcmf_err("set wsec error (%d)\n", err);
2052 brcmf_dbg(TRACE, "Exit\n");
2057 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2058 u8 key_idx, bool pairwise, const u8 *mac_addr)
2060 struct brcmf_if *ifp = netdev_priv(ndev);
2061 struct brcmf_wsec_key key;
2064 brcmf_dbg(TRACE, "Enter\n");
2065 if (!check_vif_up(ifp->vif))
2068 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2069 /* we ignore this key index in this case */
2070 brcmf_err("invalid key index (%d)\n", key_idx);
2074 memset(&key, 0, sizeof(key));
2076 key.index = (u32) key_idx;
2077 key.flags = BRCMF_PRIMARY_KEY;
2078 key.algo = CRYPTO_ALGO_OFF;
2080 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2082 /* Set the new key/index */
2083 err = send_key_to_dongle(ndev, &key);
2085 brcmf_dbg(TRACE, "Exit\n");
2090 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2091 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2092 void (*callback) (void *cookie, struct key_params * params))
2094 struct key_params params;
2095 struct brcmf_if *ifp = netdev_priv(ndev);
2096 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2097 struct brcmf_cfg80211_security *sec;
2101 brcmf_dbg(TRACE, "Enter\n");
2102 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2103 if (!check_vif_up(ifp->vif))
2106 memset(¶ms, 0, sizeof(params));
2108 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2110 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2111 /* Ignore this error, may happen during DISASSOC */
2115 if (wsec & WEP_ENABLED) {
2116 sec = &profile->sec;
2117 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2118 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2119 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2120 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2121 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2122 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2124 } else if (wsec & TKIP_ENABLED) {
2125 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2126 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2127 } else if (wsec & AES_ENABLED) {
2128 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2129 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2131 brcmf_err("Invalid algo (0x%x)\n", wsec);
2135 callback(cookie, ¶ms);
2138 brcmf_dbg(TRACE, "Exit\n");
2143 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2144 struct net_device *ndev, u8 key_idx)
2146 brcmf_dbg(INFO, "Not supported\n");
2152 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2153 u8 *mac, struct station_info *sinfo)
2155 struct brcmf_if *ifp = netdev_priv(ndev);
2156 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2157 struct brcmf_scb_val_le scb_val;
2161 u8 *bssid = profile->bssid;
2162 struct brcmf_sta_info_le sta_info_le;
2164 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2165 if (!check_vif_up(ifp->vif))
2168 if (ifp->vif->mode == WL_MODE_AP) {
2169 memcpy(&sta_info_le, mac, ETH_ALEN);
2170 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2172 sizeof(sta_info_le));
2174 brcmf_err("GET STA INFO failed, %d\n", err);
2177 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2178 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2179 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2180 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2181 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2183 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2184 sinfo->inactive_time, sinfo->connected_time);
2185 } else if (ifp->vif->mode == WL_MODE_BSS) {
2186 if (memcmp(mac, bssid, ETH_ALEN)) {
2187 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2192 /* Report the current tx rate */
2193 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2195 brcmf_err("Could not get rate (%d)\n", err);
2198 sinfo->filled |= STATION_INFO_TX_BITRATE;
2199 sinfo->txrate.legacy = rate * 5;
2200 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2203 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2204 &ifp->vif->sme_state)) {
2205 memset(&scb_val, 0, sizeof(scb_val));
2206 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2207 &scb_val, sizeof(scb_val));
2209 brcmf_err("Could not get rssi (%d)\n", err);
2212 rssi = le32_to_cpu(scb_val.val);
2213 sinfo->filled |= STATION_INFO_SIGNAL;
2214 sinfo->signal = rssi;
2215 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2221 brcmf_dbg(TRACE, "Exit\n");
2226 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2227 bool enabled, s32 timeout)
2231 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2232 struct brcmf_if *ifp = netdev_priv(ndev);
2234 brcmf_dbg(TRACE, "Enter\n");
2237 * Powersave enable/disable request is coming from the
2238 * cfg80211 even before the interface is up. In that
2239 * scenario, driver will be storing the power save
2240 * preference in cfg struct to apply this to
2241 * FW later while initializing the dongle
2243 cfg->pwr_save = enabled;
2244 if (!check_vif_up(ifp->vif)) {
2246 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2250 pm = enabled ? PM_FAST : PM_OFF;
2251 /* Do not enable the power save after assoc if it is a p2p interface */
2252 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2253 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2256 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2258 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2261 brcmf_err("net_device is not ready yet\n");
2263 brcmf_err("error (%d)\n", err);
2266 brcmf_dbg(TRACE, "Exit\n");
2270 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2271 struct brcmf_bss_info_le *bi)
2273 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2274 struct ieee80211_channel *notify_channel;
2275 struct cfg80211_bss *bss;
2276 struct ieee80211_supported_band *band;
2277 struct brcmu_chan ch;
2281 u16 notify_capability;
2282 u16 notify_interval;
2284 size_t notify_ielen;
2287 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2288 brcmf_err("Bss info is larger than buffer. Discarding\n");
2293 ch.chspec = le16_to_cpu(bi->chanspec);
2294 cfg->d11inf.decchspec(&ch);
2295 bi->ctl_ch = ch.chnum;
2297 channel = bi->ctl_ch;
2299 if (channel <= CH_MAX_2G_CHANNEL)
2300 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2302 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2304 freq = ieee80211_channel_to_frequency(channel, band->band);
2305 notify_channel = ieee80211_get_channel(wiphy, freq);
2307 notify_capability = le16_to_cpu(bi->capability);
2308 notify_interval = le16_to_cpu(bi->beacon_period);
2309 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2310 notify_ielen = le32_to_cpu(bi->ie_length);
2311 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2313 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2314 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2315 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2316 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2317 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2319 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2320 0, notify_capability, notify_interval, notify_ie,
2321 notify_ielen, notify_signal, GFP_KERNEL);
2326 cfg80211_put_bss(wiphy, bss);
2331 static struct brcmf_bss_info_le *
2332 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2335 return list->bss_info_le;
2336 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2337 le32_to_cpu(bss->length));
2340 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2342 struct brcmf_scan_results *bss_list;
2343 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2347 bss_list = cfg->bss_list;
2348 if (bss_list->count != 0 &&
2349 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2350 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2354 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2355 for (i = 0; i < bss_list->count; i++) {
2356 bi = next_bss_le(bss_list, bi);
2357 err = brcmf_inform_single_bss(cfg, bi);
2364 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2365 struct net_device *ndev, const u8 *bssid)
2367 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2368 struct ieee80211_channel *notify_channel;
2369 struct brcmf_bss_info_le *bi = NULL;
2370 struct ieee80211_supported_band *band;
2371 struct cfg80211_bss *bss;
2372 struct brcmu_chan ch;
2376 u16 notify_capability;
2377 u16 notify_interval;
2379 size_t notify_ielen;
2382 brcmf_dbg(TRACE, "Enter\n");
2384 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2390 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2392 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2393 buf, WL_BSS_INFO_MAX);
2395 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2399 bi = (struct brcmf_bss_info_le *)(buf + 4);
2401 ch.chspec = le16_to_cpu(bi->chanspec);
2402 cfg->d11inf.decchspec(&ch);
2404 if (ch.band == BRCMU_CHAN_BAND_2G)
2405 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2407 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2409 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2410 notify_channel = ieee80211_get_channel(wiphy, freq);
2412 notify_capability = le16_to_cpu(bi->capability);
2413 notify_interval = le16_to_cpu(bi->beacon_period);
2414 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2415 notify_ielen = le32_to_cpu(bi->ie_length);
2416 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2418 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2419 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2420 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2421 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2423 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2424 0, notify_capability, notify_interval,
2425 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2432 cfg80211_put_bss(wiphy, bss);
2438 brcmf_dbg(TRACE, "Exit\n");
2443 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2445 return vif->mode == WL_MODE_IBSS;
2448 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2449 struct brcmf_if *ifp)
2451 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2452 struct brcmf_bss_info_le *bi;
2453 struct brcmf_ssid *ssid;
2454 struct brcmf_tlv *tim;
2455 u16 beacon_interval;
2461 brcmf_dbg(TRACE, "Enter\n");
2462 if (brcmf_is_ibssmode(ifp->vif))
2465 ssid = &profile->ssid;
2467 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2468 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2469 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2471 brcmf_err("Could not get bss info %d\n", err);
2472 goto update_bss_info_out;
2475 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2476 err = brcmf_inform_single_bss(cfg, bi);
2478 goto update_bss_info_out;
2480 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2481 ie_len = le32_to_cpu(bi->ie_length);
2482 beacon_interval = le16_to_cpu(bi->beacon_period);
2484 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2486 dtim_period = tim->data[1];
2489 * active scan was done so we could not get dtim
2490 * information out of probe response.
2491 * so we speficially query dtim information to dongle.
2494 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2496 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2497 goto update_bss_info_out;
2499 dtim_period = (u8)var;
2502 update_bss_info_out:
2503 brcmf_dbg(TRACE, "Exit");
2507 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2509 struct escan_info *escan = &cfg->escan_info;
2511 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2512 if (cfg->scan_request) {
2513 escan->escan_state = WL_ESCAN_STATE_IDLE;
2514 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2516 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2517 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2520 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2522 struct brcmf_cfg80211_info *cfg =
2523 container_of(work, struct brcmf_cfg80211_info,
2524 escan_timeout_work);
2526 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2529 static void brcmf_escan_timeout(unsigned long data)
2531 struct brcmf_cfg80211_info *cfg =
2532 (struct brcmf_cfg80211_info *)data;
2534 if (cfg->scan_request) {
2535 brcmf_err("timer expired\n");
2536 schedule_work(&cfg->escan_timeout_work);
2541 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2542 struct brcmf_bss_info_le *bss,
2543 struct brcmf_bss_info_le *bss_info_le)
2545 struct brcmu_chan ch_bss, ch_bss_info_le;
2547 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2548 cfg->d11inf.decchspec(&ch_bss);
2549 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2550 cfg->d11inf.decchspec(&ch_bss_info_le);
2552 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2553 ch_bss.band == ch_bss_info_le.band &&
2554 bss_info_le->SSID_len == bss->SSID_len &&
2555 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2556 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2557 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2558 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2559 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2561 /* preserve max RSSI if the measurements are
2562 * both on-channel or both off-channel
2564 if (bss_info_rssi > bss_rssi)
2565 bss->RSSI = bss_info_le->RSSI;
2566 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2567 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2568 /* preserve the on-channel rssi measurement
2569 * if the new measurement is off channel
2571 bss->RSSI = bss_info_le->RSSI;
2572 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2580 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2581 const struct brcmf_event_msg *e, void *data)
2583 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2586 struct brcmf_escan_result_le *escan_result_le;
2587 struct brcmf_bss_info_le *bss_info_le;
2588 struct brcmf_bss_info_le *bss = NULL;
2590 struct brcmf_scan_results *list;
2596 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2597 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2601 if (status == BRCMF_E_STATUS_PARTIAL) {
2602 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2603 escan_result_le = (struct brcmf_escan_result_le *) data;
2604 if (!escan_result_le) {
2605 brcmf_err("Invalid escan result (NULL pointer)\n");
2608 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2609 brcmf_err("Invalid bss_count %d: ignoring\n",
2610 escan_result_le->bss_count);
2613 bss_info_le = &escan_result_le->bss_info_le;
2615 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2618 if (!cfg->scan_request) {
2619 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2623 bi_length = le32_to_cpu(bss_info_le->length);
2624 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2625 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2626 brcmf_err("Invalid bss_info length %d: ignoring\n",
2631 if (!(cfg_to_wiphy(cfg)->interface_modes &
2632 BIT(NL80211_IFTYPE_ADHOC))) {
2633 if (le16_to_cpu(bss_info_le->capability) &
2634 WLAN_CAPABILITY_IBSS) {
2635 brcmf_err("Ignoring IBSS result\n");
2640 list = (struct brcmf_scan_results *)
2641 cfg->escan_info.escan_buf;
2642 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2643 brcmf_err("Buffer is too small: ignoring\n");
2647 for (i = 0; i < list->count; i++) {
2648 bss = bss ? (struct brcmf_bss_info_le *)
2649 ((unsigned char *)bss +
2650 le32_to_cpu(bss->length)) : list->bss_info_le;
2651 if (brcmf_compare_update_same_bss(cfg, bss,
2655 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2656 bss_info_le, bi_length);
2657 list->version = le32_to_cpu(bss_info_le->version);
2658 list->buflen += bi_length;
2661 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2662 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2664 if (cfg->scan_request) {
2665 cfg->bss_list = (struct brcmf_scan_results *)
2666 cfg->escan_info.escan_buf;
2667 brcmf_inform_bss(cfg);
2668 aborted = status != BRCMF_E_STATUS_SUCCESS;
2669 brcmf_notify_escan_complete(cfg, ifp, aborted,
2672 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2679 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2681 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2682 brcmf_cfg80211_escan_handler);
2683 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2684 /* Init scan_timeout timer */
2685 init_timer(&cfg->escan_timeout);
2686 cfg->escan_timeout.data = (unsigned long) cfg;
2687 cfg->escan_timeout.function = brcmf_escan_timeout;
2688 INIT_WORK(&cfg->escan_timeout_work,
2689 brcmf_cfg80211_escan_timeout_worker);
2692 static __always_inline void brcmf_delay(u32 ms)
2694 if (ms < 1000 / HZ) {
2702 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2704 brcmf_dbg(TRACE, "Enter\n");
2709 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2710 struct cfg80211_wowlan *wow)
2712 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2713 struct net_device *ndev = cfg_to_ndev(cfg);
2714 struct brcmf_cfg80211_vif *vif;
2716 brcmf_dbg(TRACE, "Enter\n");
2719 * if the primary net_device is not READY there is nothing
2720 * we can do but pray resume goes smoothly.
2722 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2723 if (!check_vif_up(vif))
2726 list_for_each_entry(vif, &cfg->vif_list, list) {
2727 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2730 * While going to suspend if associated with AP disassociate
2731 * from AP to save power while system is in suspended state
2733 brcmf_link_down(vif);
2735 /* Make sure WPA_Supplicant receives all the event
2736 * generated due to DISASSOC call to the fw to keep
2737 * the state fw and WPA_Supplicant state consistent
2742 /* end any scanning */
2743 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2744 brcmf_abort_scanning(cfg);
2746 /* Turn off watchdog timer */
2747 brcmf_set_mpc(netdev_priv(ndev), 1);
2750 brcmf_dbg(TRACE, "Exit\n");
2751 /* clear any scanning activity */
2752 cfg->scan_status = 0;
2757 brcmf_update_pmklist(struct net_device *ndev,
2758 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2763 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2765 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2766 for (i = 0; i < pmkid_len; i++) {
2767 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2768 &pmk_list->pmkids.pmkid[i].BSSID);
2769 for (j = 0; j < WLAN_PMKID_LEN; j++)
2770 brcmf_dbg(CONN, "%02x\n",
2771 pmk_list->pmkids.pmkid[i].PMKID[j]);
2775 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2776 (char *)pmk_list, sizeof(*pmk_list));
2782 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2783 struct cfg80211_pmksa *pmksa)
2785 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2786 struct brcmf_if *ifp = netdev_priv(ndev);
2787 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2792 brcmf_dbg(TRACE, "Enter\n");
2793 if (!check_vif_up(ifp->vif))
2796 pmkid_len = le32_to_cpu(pmkids->npmkid);
2797 for (i = 0; i < pmkid_len; i++)
2798 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2800 if (i < WL_NUM_PMKIDS_MAX) {
2801 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2802 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2803 if (i == pmkid_len) {
2805 pmkids->npmkid = cpu_to_le32(pmkid_len);
2810 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2811 pmkids->pmkid[pmkid_len].BSSID);
2812 for (i = 0; i < WLAN_PMKID_LEN; i++)
2813 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2815 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2817 brcmf_dbg(TRACE, "Exit\n");
2822 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2823 struct cfg80211_pmksa *pmksa)
2825 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2826 struct brcmf_if *ifp = netdev_priv(ndev);
2827 struct pmkid_list pmkid;
2831 brcmf_dbg(TRACE, "Enter\n");
2832 if (!check_vif_up(ifp->vif))
2835 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2836 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2838 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2839 &pmkid.pmkid[0].BSSID);
2840 for (i = 0; i < WLAN_PMKID_LEN; i++)
2841 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2843 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2844 for (i = 0; i < pmkid_len; i++)
2846 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2851 && (i < pmkid_len)) {
2852 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2853 sizeof(struct pmkid));
2854 for (; i < (pmkid_len - 1); i++) {
2855 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2856 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2858 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2859 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2862 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2866 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2868 brcmf_dbg(TRACE, "Exit\n");
2874 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2876 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2877 struct brcmf_if *ifp = netdev_priv(ndev);
2880 brcmf_dbg(TRACE, "Enter\n");
2881 if (!check_vif_up(ifp->vif))
2884 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2885 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2887 brcmf_dbg(TRACE, "Exit\n");
2893 * PFN result doesn't have all the info which are
2894 * required by the supplicant
2895 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2896 * via wl_inform_single_bss in the required format. Escan does require the
2897 * scan request in the form of cfg80211_scan_request. For timebeing, create
2898 * cfg80211_scan_request one out of the received PNO event.
2901 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2902 const struct brcmf_event_msg *e, void *data)
2904 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2905 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2906 struct cfg80211_scan_request *request = NULL;
2907 struct cfg80211_ssid *ssid = NULL;
2908 struct ieee80211_channel *channel = NULL;
2909 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2911 int channel_req = 0;
2913 struct brcmf_pno_scanresults_le *pfn_result;
2917 brcmf_dbg(SCAN, "Enter\n");
2919 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2920 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2924 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2925 result_count = le32_to_cpu(pfn_result->count);
2926 status = le32_to_cpu(pfn_result->status);
2929 * PFN event is limited to fit 512 bytes so we may get
2930 * multiple NET_FOUND events. For now place a warning here.
2932 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2933 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2934 if (result_count > 0) {
2937 request = kzalloc(sizeof(*request), GFP_KERNEL);
2938 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2939 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2940 if (!request || !ssid || !channel) {
2945 request->wiphy = wiphy;
2946 data += sizeof(struct brcmf_pno_scanresults_le);
2947 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2949 for (i = 0; i < result_count; i++) {
2950 netinfo = &netinfo_start[i];
2952 brcmf_err("Invalid netinfo ptr. index: %d\n",
2958 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2959 netinfo->SSID, netinfo->channel);
2960 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2961 ssid[i].ssid_len = netinfo->SSID_len;
2964 channel_req = netinfo->channel;
2965 if (channel_req <= CH_MAX_2G_CHANNEL)
2966 band = NL80211_BAND_2GHZ;
2968 band = NL80211_BAND_5GHZ;
2969 channel[i].center_freq =
2970 ieee80211_channel_to_frequency(channel_req,
2972 channel[i].band = band;
2973 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2974 request->channels[i] = &channel[i];
2975 request->n_channels++;
2978 /* assign parsed ssid array */
2979 if (request->n_ssids)
2980 request->ssids = &ssid[0];
2982 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2983 /* Abort any on-going scan */
2984 brcmf_abort_scanning(cfg);
2987 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2988 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2990 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2993 cfg->sched_escan = true;
2994 cfg->scan_request = request;
2996 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3009 cfg80211_sched_scan_stopped(wiphy);
3013 static int brcmf_dev_pno_clean(struct net_device *ndev)
3018 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3021 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3025 brcmf_err("failed code %d\n", ret);
3030 static int brcmf_dev_pno_config(struct net_device *ndev)
3032 struct brcmf_pno_param_le pfn_param;
3034 memset(&pfn_param, 0, sizeof(pfn_param));
3035 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3037 /* set extra pno params */
3038 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3039 pfn_param.repeat = BRCMF_PNO_REPEAT;
3040 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3042 /* set up pno scan fr */
3043 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3045 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3046 &pfn_param, sizeof(pfn_param));
3050 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3051 struct net_device *ndev,
3052 struct cfg80211_sched_scan_request *request)
3054 struct brcmf_if *ifp = netdev_priv(ndev);
3055 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3056 struct brcmf_pno_net_param_le pfn;
3060 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3061 request->n_match_sets, request->n_ssids);
3062 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3063 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3066 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3067 brcmf_err("Scanning suppressed: status (%lu)\n",
3072 if (!request->n_ssids || !request->n_match_sets) {
3073 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3078 if (request->n_ssids > 0) {
3079 for (i = 0; i < request->n_ssids; i++) {
3080 /* Active scan req for ssids */
3081 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3082 request->ssids[i].ssid);
3085 * match_set ssids is a supert set of n_ssid list,
3086 * so we need not add these set seperately.
3091 if (request->n_match_sets > 0) {
3092 /* clean up everything */
3093 ret = brcmf_dev_pno_clean(ndev);
3095 brcmf_err("failed error=%d\n", ret);
3100 ret = brcmf_dev_pno_config(ndev);
3102 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3106 /* configure each match set */
3107 for (i = 0; i < request->n_match_sets; i++) {
3108 struct cfg80211_ssid *ssid;
3111 ssid = &request->match_sets[i].ssid;
3112 ssid_len = ssid->ssid_len;
3115 brcmf_err("skip broadcast ssid\n");
3118 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3119 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3120 pfn.wsec = cpu_to_le32(0);
3121 pfn.infra = cpu_to_le32(1);
3122 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3123 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3124 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3125 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3127 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3128 ret == 0 ? "set" : "failed", ssid->ssid);
3130 /* Enable the PNO */
3131 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3132 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3142 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3143 struct net_device *ndev)
3145 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3147 brcmf_dbg(SCAN, "enter\n");
3148 brcmf_dev_pno_clean(ndev);
3149 if (cfg->sched_escan)
3150 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3154 #ifdef CONFIG_NL80211_TESTMODE
3155 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3157 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3158 struct net_device *ndev = cfg_to_ndev(cfg);
3159 struct brcmf_dcmd *dcmd = data;
3160 struct sk_buff *reply;
3163 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3164 dcmd->buf, dcmd->len);
3167 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3168 dcmd->buf, dcmd->len);
3170 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3171 dcmd->buf, dcmd->len);
3173 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3174 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3175 ret = cfg80211_testmode_reply(reply);
3181 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3186 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3188 brcmf_err("auth error %d\n", err);
3192 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3194 brcmf_err("wsec error %d\n", err);
3197 /* set upper-layer auth */
3198 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3200 brcmf_err("wpa_auth error %d\n", err);
3207 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3210 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3212 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3216 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3219 struct brcmf_if *ifp = netdev_priv(ndev);
3220 u32 auth = 0; /* d11 open authentication */
3232 u32 wme_bss_disable;
3234 brcmf_dbg(TRACE, "Enter\n");
3238 len = wpa_ie->len + TLV_HDR_LEN;
3239 data = (u8 *)wpa_ie;
3240 offset = TLV_HDR_LEN;
3242 offset += VS_IE_FIXED_HDR_LEN;
3244 offset += WPA_IE_VERSION_LEN;
3246 /* check for multicast cipher suite */
3247 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3249 brcmf_err("no multicast cipher suite\n");
3253 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3255 brcmf_err("ivalid OUI\n");
3258 offset += TLV_OUI_LEN;
3260 /* pick up multicast cipher */
3261 switch (data[offset]) {
3262 case WPA_CIPHER_NONE:
3265 case WPA_CIPHER_WEP_40:
3266 case WPA_CIPHER_WEP_104:
3269 case WPA_CIPHER_TKIP:
3270 gval = TKIP_ENABLED;
3272 case WPA_CIPHER_AES_CCM:
3277 brcmf_err("Invalid multi cast cipher info\n");
3282 /* walk thru unicast cipher list and pick up what we recognize */
3283 count = data[offset] + (data[offset + 1] << 8);
3284 offset += WPA_IE_SUITE_COUNT_LEN;
3285 /* Check for unicast suite(s) */
3286 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3288 brcmf_err("no unicast cipher suite\n");
3291 for (i = 0; i < count; i++) {
3292 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3294 brcmf_err("ivalid OUI\n");
3297 offset += TLV_OUI_LEN;
3298 switch (data[offset]) {
3299 case WPA_CIPHER_NONE:
3301 case WPA_CIPHER_WEP_40:
3302 case WPA_CIPHER_WEP_104:
3303 pval |= WEP_ENABLED;
3305 case WPA_CIPHER_TKIP:
3306 pval |= TKIP_ENABLED;
3308 case WPA_CIPHER_AES_CCM:
3309 pval |= AES_ENABLED;
3312 brcmf_err("Ivalid unicast security info\n");
3316 /* walk thru auth management suite list and pick up what we recognize */
3317 count = data[offset] + (data[offset + 1] << 8);
3318 offset += WPA_IE_SUITE_COUNT_LEN;
3319 /* Check for auth key management suite(s) */
3320 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3322 brcmf_err("no auth key mgmt suite\n");
3325 for (i = 0; i < count; i++) {
3326 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3328 brcmf_err("ivalid OUI\n");
3331 offset += TLV_OUI_LEN;
3332 switch (data[offset]) {
3334 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3335 wpa_auth |= WPA_AUTH_NONE;
3337 case RSN_AKM_UNSPECIFIED:
3338 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3339 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3340 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3343 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3344 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3345 (wpa_auth |= WPA_AUTH_PSK);
3348 brcmf_err("Ivalid key mgmt info\n");
3354 wme_bss_disable = 1;
3355 if ((offset + RSN_CAP_LEN) <= len) {
3356 rsn_cap = data[offset] + (data[offset + 1] << 8);
3357 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3358 wme_bss_disable = 0;
3360 /* set wme_bss_disable to sync RSN Capabilities */
3361 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3364 brcmf_err("wme_bss_disable error %d\n", err);
3368 /* FOR WPS , set SES_OW_ENABLED */
3369 wsec = (pval | gval | SES_OW_ENABLED);
3372 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3374 brcmf_err("auth error %d\n", err);
3378 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3380 brcmf_err("wsec error %d\n", err);
3383 /* set upper-layer auth */
3384 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3386 brcmf_err("wpa_auth error %d\n", err);
3395 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3396 struct parsed_vndr_ies *vndr_ies)
3399 struct brcmf_vs_tlv *vndrie;
3400 struct brcmf_tlv *ie;
3401 struct parsed_vndr_ie_info *parsed_info;
3404 remaining_len = (s32)vndr_ie_len;
3405 memset(vndr_ies, 0, sizeof(*vndr_ies));
3407 ie = (struct brcmf_tlv *)vndr_ie_buf;
3409 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3411 vndrie = (struct brcmf_vs_tlv *)ie;
3412 /* len should be bigger than OUI length + one */
3413 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3414 brcmf_err("invalid vndr ie. length is too small %d\n",
3418 /* if wpa or wme ie, do not add ie */
3419 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3420 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3421 (vndrie->oui_type == WME_OUI_TYPE))) {
3422 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3426 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3428 /* save vndr ie information */
3429 parsed_info->ie_ptr = (char *)vndrie;
3430 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3431 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3435 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3436 parsed_info->vndrie.oui[0],
3437 parsed_info->vndrie.oui[1],
3438 parsed_info->vndrie.oui[2],
3439 parsed_info->vndrie.oui_type);
3441 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3444 remaining_len -= (ie->len + TLV_HDR_LEN);
3445 if (remaining_len <= TLV_HDR_LEN)
3448 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3455 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3461 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3462 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3464 iecount_le = cpu_to_le32(1);
3465 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3467 pktflag_le = cpu_to_le32(pktflag);
3468 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3470 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3472 return ie_len + VNDR_IE_HDR_SIZE;
3475 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3476 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3478 struct brcmf_if *ifp;
3479 struct vif_saved_ie *saved_ie;
3483 u8 *mgmt_ie_buf = NULL;
3484 int mgmt_ie_buf_len;
3486 u32 del_add_ie_buf_len = 0;
3487 u32 total_ie_buf_len = 0;
3488 u32 parsed_ie_buf_len = 0;
3489 struct parsed_vndr_ies old_vndr_ies;
3490 struct parsed_vndr_ies new_vndr_ies;
3491 struct parsed_vndr_ie_info *vndrie_info;
3494 int remained_buf_len;
3499 saved_ie = &vif->saved_ie;
3501 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3502 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3505 curr_ie_buf = iovar_ie_buf;
3507 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3508 mgmt_ie_buf = saved_ie->probe_req_ie;
3509 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3510 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3512 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3513 mgmt_ie_buf = saved_ie->probe_res_ie;
3514 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3515 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3517 case BRCMF_VNDR_IE_BEACON_FLAG:
3518 mgmt_ie_buf = saved_ie->beacon_ie;
3519 mgmt_ie_len = &saved_ie->beacon_ie_len;
3520 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3522 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3523 mgmt_ie_buf = saved_ie->assoc_req_ie;
3524 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3525 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3529 brcmf_err("not suitable type\n");
3533 if (vndr_ie_len > mgmt_ie_buf_len) {
3535 brcmf_err("extra IE size too big\n");
3539 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3540 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3542 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3543 for (i = 0; i < new_vndr_ies.count; i++) {
3544 vndrie_info = &new_vndr_ies.ie_info[i];
3545 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3546 vndrie_info->ie_len);
3547 parsed_ie_buf_len += vndrie_info->ie_len;
3551 if (mgmt_ie_buf && *mgmt_ie_len) {
3552 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3553 (memcmp(mgmt_ie_buf, curr_ie_buf,
3554 parsed_ie_buf_len) == 0)) {
3555 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3559 /* parse old vndr_ie */
3560 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3562 /* make a command to delete old ie */
3563 for (i = 0; i < old_vndr_ies.count; i++) {
3564 vndrie_info = &old_vndr_ies.ie_info[i];
3566 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3567 vndrie_info->vndrie.id,
3568 vndrie_info->vndrie.len,
3569 vndrie_info->vndrie.oui[0],
3570 vndrie_info->vndrie.oui[1],
3571 vndrie_info->vndrie.oui[2]);
3573 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3574 vndrie_info->ie_ptr,
3575 vndrie_info->ie_len,
3577 curr_ie_buf += del_add_ie_buf_len;
3578 total_ie_buf_len += del_add_ie_buf_len;
3583 /* Add if there is any extra IE */
3584 if (mgmt_ie_buf && parsed_ie_buf_len) {
3587 remained_buf_len = mgmt_ie_buf_len;
3589 /* make a command to add new ie */
3590 for (i = 0; i < new_vndr_ies.count; i++) {
3591 vndrie_info = &new_vndr_ies.ie_info[i];
3593 /* verify remained buf size before copy data */
3594 if (remained_buf_len < (vndrie_info->vndrie.len +
3595 VNDR_IE_VSIE_OFFSET)) {
3596 brcmf_err("no space in mgmt_ie_buf: len left %d",
3600 remained_buf_len -= (vndrie_info->ie_len +
3601 VNDR_IE_VSIE_OFFSET);
3603 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3604 vndrie_info->vndrie.id,
3605 vndrie_info->vndrie.len,
3606 vndrie_info->vndrie.oui[0],
3607 vndrie_info->vndrie.oui[1],
3608 vndrie_info->vndrie.oui[2]);
3610 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3611 vndrie_info->ie_ptr,
3612 vndrie_info->ie_len,
3615 /* save the parsed IE in wl struct */
3616 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3617 vndrie_info->ie_len);
3618 *mgmt_ie_len += vndrie_info->ie_len;
3620 curr_ie_buf += del_add_ie_buf_len;
3621 total_ie_buf_len += del_add_ie_buf_len;
3624 if (total_ie_buf_len) {
3625 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3628 brcmf_err("vndr ie set error : %d\n", err);
3632 kfree(iovar_ie_buf);
3636 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3639 BRCMF_VNDR_IE_PRBREQ_FLAG,
3640 BRCMF_VNDR_IE_PRBRSP_FLAG,
3641 BRCMF_VNDR_IE_BEACON_FLAG
3645 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3646 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3648 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3653 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3654 struct cfg80211_beacon_data *beacon)
3658 /* Set Beacon IEs to FW */
3659 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3660 beacon->tail, beacon->tail_len);
3662 brcmf_err("Set Beacon IE Failed\n");
3665 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3667 /* Set Probe Response IEs to FW */
3668 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3669 beacon->proberesp_ies,
3670 beacon->proberesp_ies_len);
3672 brcmf_err("Set Probe Resp IE Failed\n");
3674 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3680 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3681 struct brcmf_if *ifp,
3682 struct ieee80211_channel *channel)
3687 brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3688 channel->center_freq);
3690 chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3691 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3697 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3698 struct cfg80211_ap_settings *settings)
3701 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3702 struct brcmf_if *ifp = netdev_priv(ndev);
3703 struct brcmf_tlv *ssid_ie;
3704 struct brcmf_ssid_le ssid_le;
3706 struct brcmf_tlv *rsn_ie;
3707 struct brcmf_vs_tlv *wpa_ie;
3708 struct brcmf_join_params join_params;
3709 enum nl80211_iftype dev_role;
3710 struct brcmf_fil_bss_enable_le bss_enable;
3712 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3713 cfg80211_get_chandef_type(&settings->chandef),
3714 settings->beacon_interval,
3715 settings->dtim_period);
3716 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3717 settings->ssid, settings->ssid_len, settings->auth_type,
3718 settings->inactivity_timeout);
3720 dev_role = ifp->vif->wdev.iftype;
3722 memset(&ssid_le, 0, sizeof(ssid_le));
3723 if (settings->ssid == NULL || settings->ssid_len == 0) {
3724 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3725 ssid_ie = brcmf_parse_tlvs(
3726 (u8 *)&settings->beacon.head[ie_offset],
3727 settings->beacon.head_len - ie_offset,
3732 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3733 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3734 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3736 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3737 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3740 brcmf_set_mpc(ifp, 0);
3741 brcmf_configure_arp_offload(ifp, false);
3743 /* find the RSN_IE */
3744 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3745 settings->beacon.tail_len, WLAN_EID_RSN);
3747 /* find the WPA_IE */
3748 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3749 settings->beacon.tail_len);
3751 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3752 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3753 if (wpa_ie != NULL) {
3755 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3760 err = brcmf_configure_wpaie(ndev,
3761 (struct brcmf_vs_tlv *)rsn_ie, true);
3766 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3767 brcmf_configure_opensecurity(ifp);
3770 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3772 err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
3774 brcmf_err("Set Channel failed, %d\n", err);
3778 if (settings->beacon_interval) {
3779 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3780 settings->beacon_interval);
3782 brcmf_err("Beacon Interval Set Error, %d\n", err);
3786 if (settings->dtim_period) {
3787 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3788 settings->dtim_period);
3790 brcmf_err("DTIM Interval Set Error, %d\n", err);
3795 if (dev_role == NL80211_IFTYPE_AP) {
3796 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3798 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3801 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3804 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3806 brcmf_err("SET INFRA error %d\n", err);
3809 if (dev_role == NL80211_IFTYPE_AP) {
3810 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3812 brcmf_err("setting AP mode failed %d\n", err);
3815 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3817 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3821 memset(&join_params, 0, sizeof(join_params));
3822 /* join parameters starts with ssid */
3823 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3825 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3826 &join_params, sizeof(join_params));
3828 brcmf_err("SET SSID error (%d)\n", err);
3831 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3833 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3836 brcmf_err("setting ssid failed %d\n", err);
3839 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3840 bss_enable.enable = cpu_to_le32(1);
3841 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3842 sizeof(bss_enable));
3844 brcmf_err("bss_enable config failed %d\n", err);
3848 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3850 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3851 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3855 brcmf_set_mpc(ifp, 1);
3856 brcmf_configure_arp_offload(ifp, true);
3861 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3863 struct brcmf_if *ifp = netdev_priv(ndev);
3865 struct brcmf_fil_bss_enable_le bss_enable;
3866 struct brcmf_join_params join_params;
3868 brcmf_dbg(TRACE, "Enter\n");
3870 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3871 /* Due to most likely deauths outstanding we sleep */
3872 /* first to make sure they get processed by fw. */
3875 memset(&join_params, 0, sizeof(join_params));
3876 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3877 &join_params, sizeof(join_params));
3879 brcmf_err("SET SSID error (%d)\n", err);
3880 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3882 brcmf_err("BRCMF_C_UP error %d\n", err);
3883 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3885 brcmf_err("setting AP mode failed %d\n", err);
3886 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3888 brcmf_err("setting INFRA mode failed %d\n", err);
3890 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3891 bss_enable.enable = cpu_to_le32(0);
3892 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3893 sizeof(bss_enable));
3895 brcmf_err("bss_enable config failed %d\n", err);
3897 brcmf_set_mpc(ifp, 1);
3898 brcmf_configure_arp_offload(ifp, true);
3899 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3900 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3906 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3907 struct cfg80211_beacon_data *info)
3909 struct brcmf_if *ifp = netdev_priv(ndev);
3912 brcmf_dbg(TRACE, "Enter\n");
3914 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3920 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3923 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3924 struct brcmf_scb_val_le scbval;
3925 struct brcmf_if *ifp = netdev_priv(ndev);
3931 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3933 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3934 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3935 if (!check_vif_up(ifp->vif))
3938 memcpy(&scbval.ea, mac, ETH_ALEN);
3939 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3940 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3941 &scbval, sizeof(scbval));
3943 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3945 brcmf_dbg(TRACE, "Exit\n");
3951 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3952 struct wireless_dev *wdev,
3953 u16 frame_type, bool reg)
3955 struct brcmf_cfg80211_vif *vif;
3958 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3960 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3961 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3963 vif->mgmt_rx_reg |= BIT(mgmt_type);
3965 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3970 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3971 struct ieee80211_channel *chan, bool offchan,
3972 unsigned int wait, const u8 *buf, size_t len,
3973 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3975 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3976 const struct ieee80211_mgmt *mgmt;
3977 struct brcmf_cfg80211_vif *vif;
3981 struct brcmf_fil_action_frame_le *action_frame;
3982 struct brcmf_fil_af_params_le *af_params;
3987 brcmf_dbg(TRACE, "Enter\n");
3991 mgmt = (const struct ieee80211_mgmt *)buf;
3993 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3994 brcmf_err("Driver only allows MGMT packet type\n");
3998 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4000 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4001 /* Right now the only reason to get a probe response */
4002 /* is for p2p listen response or for p2p GO from */
4003 /* wpa_supplicant. Unfortunately the probe is send */
4004 /* on primary ndev, while dongle wants it on the p2p */
4005 /* vif. Since this is only reason for a probe */
4006 /* response to be sent, the vif is taken from cfg. */
4007 /* If ever desired to send proberesp for non p2p */
4008 /* response then data should be checked for */
4009 /* "DIRECT-". Note in future supplicant will take */
4010 /* dedicated p2p wdev to do this and then this 'hack'*/
4011 /* is not needed anymore. */
4012 ie_offset = DOT11_MGMT_HDR_LEN +
4013 DOT11_BCN_PRB_FIXED_LEN;
4014 ie_len = len - ie_offset;
4015 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4016 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4017 err = brcmf_vif_set_mgmt_ie(vif,
4018 BRCMF_VNDR_IE_PRBRSP_FLAG,
4021 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4023 } else if (ieee80211_is_action(mgmt->frame_control)) {
4024 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4025 if (af_params == NULL) {
4026 brcmf_err("unable to allocate frame\n");
4030 action_frame = &af_params->action_frame;
4031 /* Add the packet Id */
4032 action_frame->packet_id = cpu_to_le32(*cookie);
4034 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4035 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4036 /* Add the length exepted for 802.11 header */
4037 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4038 /* Add the channel. Use the one specified as parameter if any or
4039 * the current one (got from the firmware) otherwise
4042 freq = chan->center_freq;
4044 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4046 chan_nr = ieee80211_frequency_to_channel(freq);
4047 af_params->channel = cpu_to_le32(chan_nr);
4049 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4050 le16_to_cpu(action_frame->len));
4052 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4053 *cookie, le16_to_cpu(action_frame->len), freq);
4055 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4058 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4062 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4063 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4072 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4073 struct wireless_dev *wdev,
4076 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4077 struct brcmf_cfg80211_vif *vif;
4080 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4082 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4084 brcmf_err("No p2p device available for probe response\n");
4088 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4093 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4094 struct wireless_dev *wdev,
4095 enum nl80211_crit_proto_id proto,
4098 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4099 struct brcmf_cfg80211_vif *vif;
4101 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4103 /* only DHCP support for now */
4104 if (proto != NL80211_CRIT_PROTO_DHCP)
4107 /* suppress and abort scanning */
4108 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4109 brcmf_abort_scanning(cfg);
4111 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4114 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4115 struct wireless_dev *wdev)
4117 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4118 struct brcmf_cfg80211_vif *vif;
4120 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4122 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4123 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4126 static struct cfg80211_ops wl_cfg80211_ops = {
4127 .add_virtual_intf = brcmf_cfg80211_add_iface,
4128 .del_virtual_intf = brcmf_cfg80211_del_iface,
4129 .change_virtual_intf = brcmf_cfg80211_change_iface,
4130 .scan = brcmf_cfg80211_scan,
4131 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4132 .join_ibss = brcmf_cfg80211_join_ibss,
4133 .leave_ibss = brcmf_cfg80211_leave_ibss,
4134 .get_station = brcmf_cfg80211_get_station,
4135 .set_tx_power = brcmf_cfg80211_set_tx_power,
4136 .get_tx_power = brcmf_cfg80211_get_tx_power,
4137 .add_key = brcmf_cfg80211_add_key,
4138 .del_key = brcmf_cfg80211_del_key,
4139 .get_key = brcmf_cfg80211_get_key,
4140 .set_default_key = brcmf_cfg80211_config_default_key,
4141 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4142 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4143 .connect = brcmf_cfg80211_connect,
4144 .disconnect = brcmf_cfg80211_disconnect,
4145 .suspend = brcmf_cfg80211_suspend,
4146 .resume = brcmf_cfg80211_resume,
4147 .set_pmksa = brcmf_cfg80211_set_pmksa,
4148 .del_pmksa = brcmf_cfg80211_del_pmksa,
4149 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4150 .start_ap = brcmf_cfg80211_start_ap,
4151 .stop_ap = brcmf_cfg80211_stop_ap,
4152 .change_beacon = brcmf_cfg80211_change_beacon,
4153 .del_station = brcmf_cfg80211_del_station,
4154 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4155 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4156 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4157 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4158 .remain_on_channel = brcmf_p2p_remain_on_channel,
4159 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4160 .start_p2p_device = brcmf_p2p_start_device,
4161 .stop_p2p_device = brcmf_p2p_stop_device,
4162 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4163 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4164 #ifdef CONFIG_NL80211_TESTMODE
4165 .testmode_cmd = brcmf_cfg80211_testmode
4169 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4172 case NL80211_IFTYPE_AP_VLAN:
4173 case NL80211_IFTYPE_WDS:
4174 case NL80211_IFTYPE_MONITOR:
4175 case NL80211_IFTYPE_MESH_POINT:
4177 case NL80211_IFTYPE_ADHOC:
4178 return WL_MODE_IBSS;
4179 case NL80211_IFTYPE_STATION:
4180 case NL80211_IFTYPE_P2P_CLIENT:
4182 case NL80211_IFTYPE_AP:
4183 case NL80211_IFTYPE_P2P_GO:
4185 case NL80211_IFTYPE_P2P_DEVICE:
4187 case NL80211_IFTYPE_UNSPECIFIED:
4195 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4197 /* scheduled scan settings */
4198 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4199 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4200 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4201 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4204 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4207 .types = BIT(NL80211_IFTYPE_STATION) |
4208 BIT(NL80211_IFTYPE_ADHOC) |
4209 BIT(NL80211_IFTYPE_AP)
4213 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4214 BIT(NL80211_IFTYPE_P2P_GO)
4218 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4221 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4223 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4224 .num_different_channels = 2,
4225 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4226 .limits = brcmf_iface_limits
4230 static const struct ieee80211_txrx_stypes
4231 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4232 [NL80211_IFTYPE_STATION] = {
4234 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4235 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4237 [NL80211_IFTYPE_P2P_CLIENT] = {
4239 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4240 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4242 [NL80211_IFTYPE_P2P_GO] = {
4244 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4245 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4246 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4247 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4248 BIT(IEEE80211_STYPE_AUTH >> 4) |
4249 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4250 BIT(IEEE80211_STYPE_ACTION >> 4)
4252 [NL80211_IFTYPE_P2P_DEVICE] = {
4254 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4255 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4259 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4261 struct wiphy *wiphy;
4264 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4266 brcmf_err("Could not allocate wiphy device\n");
4267 return ERR_PTR(-ENOMEM);
4269 set_wiphy_dev(wiphy, phydev);
4270 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4271 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4272 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4273 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4274 BIT(NL80211_IFTYPE_ADHOC) |
4275 BIT(NL80211_IFTYPE_AP) |
4276 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4277 BIT(NL80211_IFTYPE_P2P_GO) |
4278 BIT(NL80211_IFTYPE_P2P_DEVICE);
4279 wiphy->iface_combinations = brcmf_iface_combos;
4280 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4281 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4282 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4283 wiphy->cipher_suites = __wl_cipher_suites;
4284 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4285 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4286 WIPHY_FLAG_OFFCHAN_TX |
4287 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4288 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4289 wiphy->max_remain_on_channel_duration = 5000;
4290 brcmf_wiphy_pno_params(wiphy);
4291 brcmf_dbg(INFO, "Registering custom regulatory\n");
4292 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4293 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4294 err = wiphy_register(wiphy);
4296 brcmf_err("Could not register wiphy device (%d)\n", err);
4298 return ERR_PTR(err);
4303 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4304 enum nl80211_iftype type,
4307 struct brcmf_cfg80211_vif *vif;
4309 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4310 return ERR_PTR(-ENOSPC);
4312 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4314 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4316 return ERR_PTR(-ENOMEM);
4318 vif->wdev.wiphy = cfg->wiphy;
4319 vif->wdev.iftype = type;
4321 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4322 vif->pm_block = pm_block;
4325 brcmf_init_prof(&vif->profile);
4327 list_add_tail(&vif->list, &cfg->vif_list);
4332 void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
4333 struct brcmf_cfg80211_vif *vif)
4335 list_del(&vif->list);
4339 if (!cfg->vif_cnt) {
4340 wiphy_unregister(cfg->wiphy);
4341 wiphy_free(cfg->wiphy);
4345 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4347 u32 event = e->event_code;
4348 u32 status = e->status;
4350 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4351 brcmf_dbg(CONN, "Processing set ssid\n");
4358 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4360 u32 event = e->event_code;
4361 u16 flags = e->flags;
4363 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4364 brcmf_dbg(CONN, "Processing link down\n");
4370 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4371 const struct brcmf_event_msg *e)
4373 u32 event = e->event_code;
4374 u32 status = e->status;
4376 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4377 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4378 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4382 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4383 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4390 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4392 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4394 kfree(conn_info->req_ie);
4395 conn_info->req_ie = NULL;
4396 conn_info->req_ie_len = 0;
4397 kfree(conn_info->resp_ie);
4398 conn_info->resp_ie = NULL;
4399 conn_info->resp_ie_len = 0;
4402 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4403 struct brcmf_if *ifp)
4405 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4406 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4411 brcmf_clear_assoc_ies(cfg);
4413 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4414 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4416 brcmf_err("could not get assoc info (%d)\n", err);
4420 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4421 req_len = le32_to_cpu(assoc_info->req_len);
4422 resp_len = le32_to_cpu(assoc_info->resp_len);
4424 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4428 brcmf_err("could not get assoc req (%d)\n", err);
4431 conn_info->req_ie_len = req_len;
4433 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4436 conn_info->req_ie_len = 0;
4437 conn_info->req_ie = NULL;
4440 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4444 brcmf_err("could not get assoc resp (%d)\n", err);
4447 conn_info->resp_ie_len = resp_len;
4448 conn_info->resp_ie =
4449 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4452 conn_info->resp_ie_len = 0;
4453 conn_info->resp_ie = NULL;
4455 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4456 conn_info->req_ie_len, conn_info->resp_ie_len);
4462 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4463 struct net_device *ndev,
4464 const struct brcmf_event_msg *e)
4466 struct brcmf_if *ifp = netdev_priv(ndev);
4467 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4468 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4469 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4470 struct ieee80211_channel *notify_channel = NULL;
4471 struct ieee80211_supported_band *band;
4472 struct brcmf_bss_info_le *bi;
4473 struct brcmu_chan ch;
4478 brcmf_dbg(TRACE, "Enter\n");
4480 brcmf_get_assoc_ies(cfg, ifp);
4481 memcpy(profile->bssid, e->addr, ETH_ALEN);
4482 brcmf_update_bss_info(cfg, ifp);
4484 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4490 /* data sent to dongle has to be little endian */
4491 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4492 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4493 buf, WL_BSS_INFO_MAX);
4498 bi = (struct brcmf_bss_info_le *)(buf + 4);
4499 ch.chspec = le16_to_cpu(bi->chanspec);
4500 cfg->d11inf.decchspec(&ch);
4502 if (ch.band == BRCMU_CHAN_BAND_2G)
4503 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4505 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4507 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4508 notify_channel = ieee80211_get_channel(wiphy, freq);
4512 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4513 conn_info->req_ie, conn_info->req_ie_len,
4514 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4515 brcmf_dbg(CONN, "Report roaming result\n");
4517 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4518 brcmf_dbg(TRACE, "Exit\n");
4523 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4524 struct net_device *ndev, const struct brcmf_event_msg *e,
4527 struct brcmf_if *ifp = netdev_priv(ndev);
4528 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4529 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4532 brcmf_dbg(TRACE, "Enter\n");
4534 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4535 &ifp->vif->sme_state)) {
4537 brcmf_get_assoc_ies(cfg, ifp);
4538 memcpy(profile->bssid, e->addr, ETH_ALEN);
4539 brcmf_update_bss_info(cfg, ifp);
4540 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4541 &ifp->vif->sme_state);
4543 cfg80211_connect_result(ndev,
4544 (u8 *)profile->bssid,
4546 conn_info->req_ie_len,
4548 conn_info->resp_ie_len,
4549 completed ? WLAN_STATUS_SUCCESS :
4550 WLAN_STATUS_AUTH_TIMEOUT,
4552 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4553 completed ? "succeeded" : "failed");
4555 brcmf_dbg(TRACE, "Exit\n");
4560 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4561 struct net_device *ndev,
4562 const struct brcmf_event_msg *e, void *data)
4564 static int generation;
4565 u32 event = e->event_code;
4566 u32 reason = e->reason;
4567 struct station_info sinfo;
4569 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4570 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4571 ndev != cfg_to_ndev(cfg)) {
4572 brcmf_dbg(CONN, "AP mode link down\n");
4573 complete(&cfg->vif_disabled);
4577 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4578 (reason == BRCMF_E_STATUS_SUCCESS)) {
4579 memset(&sinfo, 0, sizeof(sinfo));
4580 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4582 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4585 sinfo.assoc_req_ies = data;
4586 sinfo.assoc_req_ies_len = e->datalen;
4588 sinfo.generation = generation;
4589 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4590 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4591 (event == BRCMF_E_DEAUTH_IND) ||
4592 (event == BRCMF_E_DEAUTH)) {
4593 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4599 brcmf_notify_connect_status(struct brcmf_if *ifp,
4600 const struct brcmf_event_msg *e, void *data)
4602 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4603 struct net_device *ndev = ifp->ndev;
4604 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4607 if (ifp->vif->mode == WL_MODE_AP) {
4608 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4609 } else if (brcmf_is_linkup(e)) {
4610 brcmf_dbg(CONN, "Linkup\n");
4611 if (brcmf_is_ibssmode(ifp->vif)) {
4612 memcpy(profile->bssid, e->addr, ETH_ALEN);
4613 wl_inform_ibss(cfg, ndev, e->addr);
4614 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4615 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4616 &ifp->vif->sme_state);
4617 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4618 &ifp->vif->sme_state);
4620 brcmf_bss_connect_done(cfg, ndev, e, true);
4621 } else if (brcmf_is_linkdown(e)) {
4622 brcmf_dbg(CONN, "Linkdown\n");
4623 if (!brcmf_is_ibssmode(ifp->vif)) {
4624 brcmf_bss_connect_done(cfg, ndev, e, false);
4625 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4626 &ifp->vif->sme_state))
4627 cfg80211_disconnected(ndev, 0, NULL, 0,
4630 brcmf_link_down(ifp->vif);
4631 brcmf_init_prof(ndev_to_prof(ndev));
4632 if (ndev != cfg_to_ndev(cfg))
4633 complete(&cfg->vif_disabled);
4634 } else if (brcmf_is_nonetwork(cfg, e)) {
4635 if (brcmf_is_ibssmode(ifp->vif))
4636 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4637 &ifp->vif->sme_state);
4639 brcmf_bss_connect_done(cfg, ndev, e, false);
4646 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4647 const struct brcmf_event_msg *e, void *data)
4649 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4651 u32 event = e->event_code;
4652 u32 status = e->status;
4654 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4655 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4656 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4658 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4665 brcmf_notify_mic_status(struct brcmf_if *ifp,
4666 const struct brcmf_event_msg *e, void *data)
4668 u16 flags = e->flags;
4669 enum nl80211_key_type key_type;
4671 if (flags & BRCMF_EVENT_MSG_GROUP)
4672 key_type = NL80211_KEYTYPE_GROUP;
4674 key_type = NL80211_KEYTYPE_PAIRWISE;
4676 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4682 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4683 const struct brcmf_event_msg *e, void *data)
4685 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4686 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4687 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4688 struct brcmf_cfg80211_vif *vif;
4690 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4691 ifevent->action, ifevent->flags, ifevent->ifidx,
4694 mutex_lock(&event->vif_event_lock);
4695 event->action = ifevent->action;
4698 switch (ifevent->action) {
4699 case BRCMF_E_IF_ADD:
4700 /* waiting process may have timed out */
4701 if (!cfg->vif_event.vif) {
4702 mutex_unlock(&event->vif_event_lock);
4709 vif->wdev.netdev = ifp->ndev;
4710 ifp->ndev->ieee80211_ptr = &vif->wdev;
4711 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4713 mutex_unlock(&event->vif_event_lock);
4714 wake_up(&event->vif_wq);
4717 case BRCMF_E_IF_DEL:
4718 mutex_unlock(&event->vif_event_lock);
4719 /* event may not be upon user request */
4720 if (brcmf_cfg80211_vif_event_armed(cfg))
4721 wake_up(&event->vif_wq);
4724 case BRCMF_E_IF_CHANGE:
4725 mutex_unlock(&event->vif_event_lock);
4726 wake_up(&event->vif_wq);
4730 mutex_unlock(&event->vif_event_lock);
4736 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4738 conf->frag_threshold = (u32)-1;
4739 conf->rts_threshold = (u32)-1;
4740 conf->retry_short = (u32)-1;
4741 conf->retry_long = (u32)-1;
4742 conf->tx_power = -1;
4745 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4747 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4748 brcmf_notify_connect_status);
4749 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4750 brcmf_notify_connect_status);
4751 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4752 brcmf_notify_connect_status);
4753 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4754 brcmf_notify_connect_status);
4755 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4756 brcmf_notify_connect_status);
4757 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4758 brcmf_notify_connect_status);
4759 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4760 brcmf_notify_roaming_status);
4761 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4762 brcmf_notify_mic_status);
4763 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4764 brcmf_notify_connect_status);
4765 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4766 brcmf_notify_sched_scan_results);
4767 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4768 brcmf_notify_vif_event);
4769 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4770 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4771 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4772 brcmf_p2p_notify_listen_complete);
4773 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4774 brcmf_p2p_notify_action_frame_rx);
4775 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4776 brcmf_p2p_notify_action_tx_complete);
4777 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4778 brcmf_p2p_notify_action_tx_complete);
4781 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4785 kfree(cfg->escan_ioctl_buf);
4786 cfg->escan_ioctl_buf = NULL;
4787 kfree(cfg->extra_buf);
4788 cfg->extra_buf = NULL;
4789 kfree(cfg->pmk_list);
4790 cfg->pmk_list = NULL;
4793 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4795 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4797 goto init_priv_mem_out;
4798 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4799 if (!cfg->escan_ioctl_buf)
4800 goto init_priv_mem_out;
4801 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4802 if (!cfg->extra_buf)
4803 goto init_priv_mem_out;
4804 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4806 goto init_priv_mem_out;
4811 brcmf_deinit_priv_mem(cfg);
4816 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4820 cfg->scan_request = NULL;
4821 cfg->pwr_save = true;
4822 cfg->roam_on = true; /* roam on & off switch.
4823 we enable roam per default */
4824 cfg->active_scan = true; /* we do active scan for
4825 specific scan per default */
4826 cfg->dongle_up = false; /* dongle is not up yet */
4827 err = brcmf_init_priv_mem(cfg);
4830 brcmf_register_event_handlers(cfg);
4831 mutex_init(&cfg->usr_sync);
4832 brcmf_init_escan(cfg);
4833 brcmf_init_conf(cfg->conf);
4834 init_completion(&cfg->vif_disabled);
4838 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4840 cfg->dongle_up = false; /* dongle down */
4841 brcmf_abort_scanning(cfg);
4842 brcmf_deinit_priv_mem(cfg);
4845 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4847 init_waitqueue_head(&event->vif_wq);
4848 mutex_init(&event->vif_event_lock);
4851 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4852 struct device *busdev)
4854 struct net_device *ndev = drvr->iflist[0]->ndev;
4855 struct brcmf_cfg80211_info *cfg;
4856 struct wiphy *wiphy;
4857 struct brcmf_cfg80211_vif *vif;
4858 struct brcmf_if *ifp;
4863 brcmf_err("ndev is invalid\n");
4867 ifp = netdev_priv(ndev);
4868 wiphy = brcmf_setup_wiphy(busdev);
4872 cfg = wiphy_priv(wiphy);
4875 init_vif_event(&cfg->vif_event);
4876 INIT_LIST_HEAD(&cfg->vif_list);
4878 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4885 vif->wdev.netdev = ndev;
4886 ndev->ieee80211_ptr = &vif->wdev;
4887 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4889 err = wl_init_priv(cfg);
4891 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4892 goto cfg80211_attach_out;
4896 err = brcmf_p2p_attach(cfg);
4898 brcmf_err("P2P initilisation failed (%d)\n", err);
4899 goto cfg80211_p2p_attach_out;
4901 err = brcmf_btcoex_attach(cfg);
4903 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4904 brcmf_p2p_detach(&cfg->p2p);
4905 goto cfg80211_p2p_attach_out;
4908 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4911 brcmf_err("Failed to get D11 version (%d)\n", err);
4912 goto cfg80211_p2p_attach_out;
4914 cfg->d11inf.io_type = (u8)io_type;
4915 brcmu_d11_attach(&cfg->d11inf);
4919 cfg80211_p2p_attach_out:
4920 wl_deinit_priv(cfg);
4922 cfg80211_attach_out:
4923 brcmf_free_vif(cfg, vif);
4927 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4929 struct brcmf_cfg80211_vif *vif;
4930 struct brcmf_cfg80211_vif *tmp;
4932 wl_deinit_priv(cfg);
4933 brcmf_btcoex_detach(cfg);
4934 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4935 brcmf_free_vif(cfg, vif);
4940 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4943 __le32 roamtrigger[2];
4944 __le32 roam_delta[2];
4947 * Setup timeout if Beacons are lost and roam is
4948 * off to report link down
4951 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4953 brcmf_err("bcn_timeout error (%d)\n", err);
4954 goto dongle_rom_out;
4959 * Enable/Disable built-in roaming to allow supplicant
4960 * to take care of roaming
4962 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4963 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4965 brcmf_err("roam_off error (%d)\n", err);
4966 goto dongle_rom_out;
4969 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4970 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4971 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4972 (void *)roamtrigger, sizeof(roamtrigger));
4974 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4975 goto dongle_rom_out;
4978 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4979 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4980 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4981 (void *)roam_delta, sizeof(roam_delta));
4983 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4984 goto dongle_rom_out;
4992 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4993 s32 scan_unassoc_time, s32 scan_passive_time)
4997 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5000 if (err == -EOPNOTSUPP)
5001 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5003 brcmf_err("Scan assoc time error (%d)\n", err);
5004 goto dongle_scantime_out;
5006 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5009 if (err == -EOPNOTSUPP)
5010 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5012 brcmf_err("Scan unassoc time error (%d)\n", err);
5013 goto dongle_scantime_out;
5016 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5019 if (err == -EOPNOTSUPP)
5020 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5022 brcmf_err("Scan passive time error (%d)\n", err);
5023 goto dongle_scantime_out;
5026 dongle_scantime_out:
5031 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5033 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5034 struct ieee80211_channel *band_chan_arr;
5035 struct brcmf_chanspec_list *list;
5036 struct brcmu_chan ch;
5041 enum ieee80211_band band;
5050 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5055 list = (struct brcmf_chanspec_list *)pbuf;
5057 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5060 brcmf_err("get chanspecs error (%d)\n", err);
5064 __wl_band_2ghz.n_channels = 0;
5065 __wl_band_5ghz_a.n_channels = 0;
5067 total = le32_to_cpu(list->count);
5068 for (i = 0; i < total; i++) {
5069 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5070 cfg->d11inf.decchspec(&ch);
5072 if (ch.band == BRCMU_CHAN_BAND_2G) {
5073 band_chan_arr = __wl_2ghz_channels;
5074 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5075 n_cnt = &__wl_band_2ghz.n_channels;
5076 band = IEEE80211_BAND_2GHZ;
5077 ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
5078 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5079 band_chan_arr = __wl_5ghz_a_channels;
5080 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5081 n_cnt = &__wl_band_5ghz_a.n_channels;
5082 band = IEEE80211_BAND_5GHZ;
5083 ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
5085 brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec);
5088 if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40)
5091 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5092 if (band_chan_arr[j].hw_value == ch.chnum) {
5101 if (index < array_size) {
5102 band_chan_arr[index].center_freq =
5103 ieee80211_channel_to_frequency(ch.chnum, band);
5104 band_chan_arr[index].hw_value = ch.chnum;
5106 if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) {
5107 /* assuming the order is HT20, HT40 Upper,
5108 * HT40 lower from chanspecs
5110 ht40_flag = band_chan_arr[index].flags &
5111 IEEE80211_CHAN_NO_HT40;
5112 if (ch.sb == BRCMU_CHAN_SB_U) {
5113 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5114 band_chan_arr[index].flags &=
5115 ~IEEE80211_CHAN_NO_HT40;
5116 band_chan_arr[index].flags |=
5117 IEEE80211_CHAN_NO_HT40PLUS;
5119 /* It should be one of
5120 * IEEE80211_CHAN_NO_HT40 or
5121 * IEEE80211_CHAN_NO_HT40PLUS
5123 band_chan_arr[index].flags &=
5124 ~IEEE80211_CHAN_NO_HT40;
5125 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5126 band_chan_arr[index].flags |=
5127 IEEE80211_CHAN_NO_HT40MINUS;
5130 band_chan_arr[index].flags =
5131 IEEE80211_CHAN_NO_HT40;
5132 ch.bw = BRCMU_CHAN_BW_20;
5133 cfg->d11inf.encchspec(&ch);
5134 channel = ch.chspec;
5135 err = brcmf_fil_bsscfg_int_get(ifp,
5139 if (channel & WL_CHAN_RADAR)
5140 band_chan_arr[index].flags |=
5141 (IEEE80211_CHAN_RADAR |
5142 IEEE80211_CHAN_NO_IBSS);
5143 if (channel & WL_CHAN_PASSIVE)
5144 band_chan_arr[index].flags |=
5145 IEEE80211_CHAN_PASSIVE_SCAN;
5158 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5160 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5161 struct wiphy *wiphy;
5170 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
5173 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5174 &phy_list, sizeof(phy_list));
5176 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5180 phy = ((char *)&phy_list)[0];
5181 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5184 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5185 &band_list, sizeof(band_list));
5187 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5190 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5191 band_list[0], band_list[1], band_list[2]);
5193 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5195 brcmf_err("nmode error (%d)\n", err);
5197 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap);
5199 brcmf_err("mimo_bw_cap error (%d)\n", err);
5201 brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap);
5203 err = brcmf_construct_reginfo(cfg, bw_cap);
5205 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5209 nband = band_list[0];
5210 memset(bands, 0, sizeof(bands));
5212 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5214 if ((band_list[i] == WLC_BAND_5G) &&
5215 (__wl_band_5ghz_a.n_channels > 0)) {
5216 index = IEEE80211_BAND_5GHZ;
5217 bands[index] = &__wl_band_5ghz_a;
5218 if ((bw_cap == WLC_N_BW_40ALL) ||
5219 (bw_cap == WLC_N_BW_20IN2G_40IN5G))
5220 bands[index]->ht_cap.cap |=
5221 IEEE80211_HT_CAP_SGI_40;
5222 } else if ((band_list[i] == WLC_BAND_2G) &&
5223 (__wl_band_2ghz.n_channels > 0)) {
5224 index = IEEE80211_BAND_2GHZ;
5225 bands[index] = &__wl_band_2ghz;
5226 if (bw_cap == WLC_N_BW_40ALL)
5227 bands[index]->ht_cap.cap |=
5228 IEEE80211_HT_CAP_SGI_40;
5231 if ((index >= 0) && nmode) {
5232 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5233 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5234 bands[index]->ht_cap.ht_supported = true;
5235 bands[index]->ht_cap.ampdu_factor =
5236 IEEE80211_HT_MAX_AMPDU_64K;
5237 bands[index]->ht_cap.ampdu_density =
5238 IEEE80211_HT_MPDU_DENSITY_16;
5239 /* An HT shall support all EQM rates for one spatial
5242 bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5246 wiphy = cfg_to_wiphy(cfg);
5247 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5248 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5249 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5255 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5257 return brcmf_update_wiphybands(cfg);
5260 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5262 struct net_device *ndev;
5263 struct wireless_dev *wdev;
5264 struct brcmf_if *ifp;
5271 ndev = cfg_to_ndev(cfg);
5272 wdev = ndev->ieee80211_ptr;
5273 ifp = netdev_priv(ndev);
5275 /* make sure RF is ready for work */
5276 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5278 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5279 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5281 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5282 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5284 goto default_conf_out;
5285 brcmf_dbg(INFO, "power save set to %s\n",
5286 (power_mode ? "enabled" : "disabled"));
5288 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5290 goto default_conf_out;
5291 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5294 goto default_conf_out;
5295 err = brcmf_dongle_probecap(cfg);
5297 goto default_conf_out;
5299 brcmf_configure_arp_offload(ifp, true);
5301 cfg->dongle_up = true;
5308 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5310 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5312 return brcmf_config_dongle(ifp->drvr->config);
5315 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5317 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5320 * While going down, if associated with AP disassociate
5321 * from AP to save power
5323 if (check_vif_up(ifp->vif)) {
5324 brcmf_link_down(ifp->vif);
5326 /* Make sure WPA_Supplicant receives all the event
5327 generated due to DISASSOC call to the fw to keep
5328 the state fw and WPA_Supplicant state consistent
5333 brcmf_abort_scanning(cfg);
5334 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5339 s32 brcmf_cfg80211_up(struct net_device *ndev)
5341 struct brcmf_if *ifp = netdev_priv(ndev);
5342 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5345 mutex_lock(&cfg->usr_sync);
5346 err = __brcmf_cfg80211_up(ifp);
5347 mutex_unlock(&cfg->usr_sync);
5352 s32 brcmf_cfg80211_down(struct net_device *ndev)
5354 struct brcmf_if *ifp = netdev_priv(ndev);
5355 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5358 mutex_lock(&cfg->usr_sync);
5359 err = __brcmf_cfg80211_down(ifp);
5360 mutex_unlock(&cfg->usr_sync);
5365 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5367 struct wireless_dev *wdev = &ifp->vif->wdev;
5369 return wdev->iftype;
5372 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5374 struct brcmf_cfg80211_vif *vif;
5377 list_for_each_entry(vif, &cfg->vif_list, list) {
5378 if (test_bit(state, &vif->sme_state))
5384 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5389 mutex_lock(&event->vif_event_lock);
5390 evt_action = event->action;
5391 mutex_unlock(&event->vif_event_lock);
5392 return evt_action == action;
5395 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5396 struct brcmf_cfg80211_vif *vif)
5398 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5400 mutex_lock(&event->vif_event_lock);
5403 mutex_unlock(&event->vif_event_lock);
5406 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5408 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5411 mutex_lock(&event->vif_event_lock);
5412 armed = event->vif != NULL;
5413 mutex_unlock(&event->vif_event_lock);
5417 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5418 u8 action, ulong timeout)
5420 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5422 return wait_event_timeout(event->vif_wq,
5423 vif_event_equals(event, action), timeout);