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;
3986 brcmf_dbg(TRACE, "Enter\n");
3990 mgmt = (const struct ieee80211_mgmt *)buf;
3992 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3993 brcmf_err("Driver only allows MGMT packet type\n");
3997 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3998 /* Right now the only reason to get a probe response */
3999 /* is for p2p listen response or for p2p GO from */
4000 /* wpa_supplicant. Unfortunately the probe is send */
4001 /* on primary ndev, while dongle wants it on the p2p */
4002 /* vif. Since this is only reason for a probe */
4003 /* response to be sent, the vif is taken from cfg. */
4004 /* If ever desired to send proberesp for non p2p */
4005 /* response then data should be checked for */
4006 /* "DIRECT-". Note in future supplicant will take */
4007 /* dedicated p2p wdev to do this and then this 'hack'*/
4008 /* is not needed anymore. */
4009 ie_offset = DOT11_MGMT_HDR_LEN +
4010 DOT11_BCN_PRB_FIXED_LEN;
4011 ie_len = len - ie_offset;
4012 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4013 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4014 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4015 err = brcmf_vif_set_mgmt_ie(vif,
4016 BRCMF_VNDR_IE_PRBRSP_FLAG,
4019 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4021 } else if (ieee80211_is_action(mgmt->frame_control)) {
4022 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4023 if (af_params == NULL) {
4024 brcmf_err("unable to allocate frame\n");
4028 action_frame = &af_params->action_frame;
4029 /* Add the packet Id */
4030 action_frame->packet_id = cpu_to_le32(*cookie);
4032 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4033 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4034 /* Add the length exepted for 802.11 header */
4035 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4036 /* Add the channel */
4037 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
4038 af_params->channel = cpu_to_le32(chan_nr);
4040 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4041 le16_to_cpu(action_frame->len));
4043 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4044 *cookie, le16_to_cpu(action_frame->len),
4047 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4050 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4054 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4055 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4064 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4065 struct wireless_dev *wdev,
4068 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4069 struct brcmf_cfg80211_vif *vif;
4072 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4074 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4076 brcmf_err("No p2p device available for probe response\n");
4080 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4085 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4086 struct wireless_dev *wdev,
4087 enum nl80211_crit_proto_id proto,
4090 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4091 struct brcmf_cfg80211_vif *vif;
4093 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4095 /* only DHCP support for now */
4096 if (proto != NL80211_CRIT_PROTO_DHCP)
4099 /* suppress and abort scanning */
4100 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4101 brcmf_abort_scanning(cfg);
4103 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4106 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4107 struct wireless_dev *wdev)
4109 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4110 struct brcmf_cfg80211_vif *vif;
4112 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4114 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4115 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4118 static struct cfg80211_ops wl_cfg80211_ops = {
4119 .add_virtual_intf = brcmf_cfg80211_add_iface,
4120 .del_virtual_intf = brcmf_cfg80211_del_iface,
4121 .change_virtual_intf = brcmf_cfg80211_change_iface,
4122 .scan = brcmf_cfg80211_scan,
4123 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4124 .join_ibss = brcmf_cfg80211_join_ibss,
4125 .leave_ibss = brcmf_cfg80211_leave_ibss,
4126 .get_station = brcmf_cfg80211_get_station,
4127 .set_tx_power = brcmf_cfg80211_set_tx_power,
4128 .get_tx_power = brcmf_cfg80211_get_tx_power,
4129 .add_key = brcmf_cfg80211_add_key,
4130 .del_key = brcmf_cfg80211_del_key,
4131 .get_key = brcmf_cfg80211_get_key,
4132 .set_default_key = brcmf_cfg80211_config_default_key,
4133 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4134 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4135 .connect = brcmf_cfg80211_connect,
4136 .disconnect = brcmf_cfg80211_disconnect,
4137 .suspend = brcmf_cfg80211_suspend,
4138 .resume = brcmf_cfg80211_resume,
4139 .set_pmksa = brcmf_cfg80211_set_pmksa,
4140 .del_pmksa = brcmf_cfg80211_del_pmksa,
4141 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4142 .start_ap = brcmf_cfg80211_start_ap,
4143 .stop_ap = brcmf_cfg80211_stop_ap,
4144 .change_beacon = brcmf_cfg80211_change_beacon,
4145 .del_station = brcmf_cfg80211_del_station,
4146 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4147 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4148 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4149 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4150 .remain_on_channel = brcmf_p2p_remain_on_channel,
4151 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4152 .start_p2p_device = brcmf_p2p_start_device,
4153 .stop_p2p_device = brcmf_p2p_stop_device,
4154 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4155 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4156 #ifdef CONFIG_NL80211_TESTMODE
4157 .testmode_cmd = brcmf_cfg80211_testmode
4161 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4164 case NL80211_IFTYPE_AP_VLAN:
4165 case NL80211_IFTYPE_WDS:
4166 case NL80211_IFTYPE_MONITOR:
4167 case NL80211_IFTYPE_MESH_POINT:
4169 case NL80211_IFTYPE_ADHOC:
4170 return WL_MODE_IBSS;
4171 case NL80211_IFTYPE_STATION:
4172 case NL80211_IFTYPE_P2P_CLIENT:
4174 case NL80211_IFTYPE_AP:
4175 case NL80211_IFTYPE_P2P_GO:
4177 case NL80211_IFTYPE_P2P_DEVICE:
4179 case NL80211_IFTYPE_UNSPECIFIED:
4187 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4189 /* scheduled scan settings */
4190 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4191 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4192 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4193 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4196 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4199 .types = BIT(NL80211_IFTYPE_STATION) |
4200 BIT(NL80211_IFTYPE_ADHOC) |
4201 BIT(NL80211_IFTYPE_AP)
4205 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4206 BIT(NL80211_IFTYPE_P2P_GO)
4210 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4213 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4215 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4216 .num_different_channels = 2,
4217 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4218 .limits = brcmf_iface_limits
4222 static const struct ieee80211_txrx_stypes
4223 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4224 [NL80211_IFTYPE_STATION] = {
4226 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4227 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4229 [NL80211_IFTYPE_P2P_CLIENT] = {
4231 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4232 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4234 [NL80211_IFTYPE_P2P_GO] = {
4236 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4237 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4238 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4239 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4240 BIT(IEEE80211_STYPE_AUTH >> 4) |
4241 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4242 BIT(IEEE80211_STYPE_ACTION >> 4)
4244 [NL80211_IFTYPE_P2P_DEVICE] = {
4246 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4247 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4251 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4253 struct wiphy *wiphy;
4256 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4258 brcmf_err("Could not allocate wiphy device\n");
4259 return ERR_PTR(-ENOMEM);
4261 set_wiphy_dev(wiphy, phydev);
4262 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4263 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4264 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4265 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4266 BIT(NL80211_IFTYPE_ADHOC) |
4267 BIT(NL80211_IFTYPE_AP) |
4268 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4269 BIT(NL80211_IFTYPE_P2P_GO) |
4270 BIT(NL80211_IFTYPE_P2P_DEVICE);
4271 wiphy->iface_combinations = brcmf_iface_combos;
4272 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4273 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4274 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4275 wiphy->cipher_suites = __wl_cipher_suites;
4276 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4277 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4278 WIPHY_FLAG_OFFCHAN_TX |
4279 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4280 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4281 wiphy->max_remain_on_channel_duration = 5000;
4282 brcmf_wiphy_pno_params(wiphy);
4283 brcmf_dbg(INFO, "Registering custom regulatory\n");
4284 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4285 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4286 err = wiphy_register(wiphy);
4288 brcmf_err("Could not register wiphy device (%d)\n", err);
4290 return ERR_PTR(err);
4295 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4296 enum nl80211_iftype type,
4299 struct brcmf_cfg80211_vif *vif;
4301 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4302 return ERR_PTR(-ENOSPC);
4304 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4306 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4308 return ERR_PTR(-ENOMEM);
4310 vif->wdev.wiphy = cfg->wiphy;
4311 vif->wdev.iftype = type;
4313 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4314 vif->pm_block = pm_block;
4317 brcmf_init_prof(&vif->profile);
4319 list_add_tail(&vif->list, &cfg->vif_list);
4324 void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
4325 struct brcmf_cfg80211_vif *vif)
4327 list_del(&vif->list);
4331 if (!cfg->vif_cnt) {
4332 wiphy_unregister(cfg->wiphy);
4333 wiphy_free(cfg->wiphy);
4337 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4339 u32 event = e->event_code;
4340 u32 status = e->status;
4342 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4343 brcmf_dbg(CONN, "Processing set ssid\n");
4350 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4352 u32 event = e->event_code;
4353 u16 flags = e->flags;
4355 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4356 brcmf_dbg(CONN, "Processing link down\n");
4362 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4363 const struct brcmf_event_msg *e)
4365 u32 event = e->event_code;
4366 u32 status = e->status;
4368 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4369 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4370 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4374 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4375 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4382 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4384 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4386 kfree(conn_info->req_ie);
4387 conn_info->req_ie = NULL;
4388 conn_info->req_ie_len = 0;
4389 kfree(conn_info->resp_ie);
4390 conn_info->resp_ie = NULL;
4391 conn_info->resp_ie_len = 0;
4394 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4395 struct brcmf_if *ifp)
4397 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4398 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4403 brcmf_clear_assoc_ies(cfg);
4405 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4406 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4408 brcmf_err("could not get assoc info (%d)\n", err);
4412 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4413 req_len = le32_to_cpu(assoc_info->req_len);
4414 resp_len = le32_to_cpu(assoc_info->resp_len);
4416 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4420 brcmf_err("could not get assoc req (%d)\n", err);
4423 conn_info->req_ie_len = req_len;
4425 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4428 conn_info->req_ie_len = 0;
4429 conn_info->req_ie = NULL;
4432 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4436 brcmf_err("could not get assoc resp (%d)\n", err);
4439 conn_info->resp_ie_len = resp_len;
4440 conn_info->resp_ie =
4441 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4444 conn_info->resp_ie_len = 0;
4445 conn_info->resp_ie = NULL;
4447 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4448 conn_info->req_ie_len, conn_info->resp_ie_len);
4454 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4455 struct net_device *ndev,
4456 const struct brcmf_event_msg *e)
4458 struct brcmf_if *ifp = netdev_priv(ndev);
4459 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4460 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4461 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4462 struct ieee80211_channel *notify_channel = NULL;
4463 struct ieee80211_supported_band *band;
4464 struct brcmf_bss_info_le *bi;
4465 struct brcmu_chan ch;
4470 brcmf_dbg(TRACE, "Enter\n");
4472 brcmf_get_assoc_ies(cfg, ifp);
4473 memcpy(profile->bssid, e->addr, ETH_ALEN);
4474 brcmf_update_bss_info(cfg, ifp);
4476 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4482 /* data sent to dongle has to be little endian */
4483 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4484 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4485 buf, WL_BSS_INFO_MAX);
4490 bi = (struct brcmf_bss_info_le *)(buf + 4);
4491 ch.chspec = le16_to_cpu(bi->chanspec);
4492 cfg->d11inf.decchspec(&ch);
4494 if (ch.band == BRCMU_CHAN_BAND_2G)
4495 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4497 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4499 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4500 notify_channel = ieee80211_get_channel(wiphy, freq);
4504 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4505 conn_info->req_ie, conn_info->req_ie_len,
4506 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4507 brcmf_dbg(CONN, "Report roaming result\n");
4509 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4510 brcmf_dbg(TRACE, "Exit\n");
4515 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4516 struct net_device *ndev, const struct brcmf_event_msg *e,
4519 struct brcmf_if *ifp = netdev_priv(ndev);
4520 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4521 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4524 brcmf_dbg(TRACE, "Enter\n");
4526 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4527 &ifp->vif->sme_state)) {
4529 brcmf_get_assoc_ies(cfg, ifp);
4530 memcpy(profile->bssid, e->addr, ETH_ALEN);
4531 brcmf_update_bss_info(cfg, ifp);
4532 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4533 &ifp->vif->sme_state);
4535 cfg80211_connect_result(ndev,
4536 (u8 *)profile->bssid,
4538 conn_info->req_ie_len,
4540 conn_info->resp_ie_len,
4541 completed ? WLAN_STATUS_SUCCESS :
4542 WLAN_STATUS_AUTH_TIMEOUT,
4544 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4545 completed ? "succeeded" : "failed");
4547 brcmf_dbg(TRACE, "Exit\n");
4552 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4553 struct net_device *ndev,
4554 const struct brcmf_event_msg *e, void *data)
4556 static int generation;
4557 u32 event = e->event_code;
4558 u32 reason = e->reason;
4559 struct station_info sinfo;
4561 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4562 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4563 ndev != cfg_to_ndev(cfg)) {
4564 brcmf_dbg(CONN, "AP mode link down\n");
4565 complete(&cfg->vif_disabled);
4569 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4570 (reason == BRCMF_E_STATUS_SUCCESS)) {
4571 memset(&sinfo, 0, sizeof(sinfo));
4572 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4574 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4577 sinfo.assoc_req_ies = data;
4578 sinfo.assoc_req_ies_len = e->datalen;
4580 sinfo.generation = generation;
4581 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4582 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4583 (event == BRCMF_E_DEAUTH_IND) ||
4584 (event == BRCMF_E_DEAUTH)) {
4585 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4591 brcmf_notify_connect_status(struct brcmf_if *ifp,
4592 const struct brcmf_event_msg *e, void *data)
4594 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4595 struct net_device *ndev = ifp->ndev;
4596 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4599 if (ifp->vif->mode == WL_MODE_AP) {
4600 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4601 } else if (brcmf_is_linkup(e)) {
4602 brcmf_dbg(CONN, "Linkup\n");
4603 if (brcmf_is_ibssmode(ifp->vif)) {
4604 memcpy(profile->bssid, e->addr, ETH_ALEN);
4605 wl_inform_ibss(cfg, ndev, e->addr);
4606 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4607 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4608 &ifp->vif->sme_state);
4609 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4610 &ifp->vif->sme_state);
4612 brcmf_bss_connect_done(cfg, ndev, e, true);
4613 } else if (brcmf_is_linkdown(e)) {
4614 brcmf_dbg(CONN, "Linkdown\n");
4615 if (!brcmf_is_ibssmode(ifp->vif)) {
4616 brcmf_bss_connect_done(cfg, ndev, e, false);
4617 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4618 &ifp->vif->sme_state))
4619 cfg80211_disconnected(ndev, 0, NULL, 0,
4622 brcmf_link_down(ifp->vif);
4623 brcmf_init_prof(ndev_to_prof(ndev));
4624 if (ndev != cfg_to_ndev(cfg))
4625 complete(&cfg->vif_disabled);
4626 } else if (brcmf_is_nonetwork(cfg, e)) {
4627 if (brcmf_is_ibssmode(ifp->vif))
4628 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4629 &ifp->vif->sme_state);
4631 brcmf_bss_connect_done(cfg, ndev, e, false);
4638 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4639 const struct brcmf_event_msg *e, void *data)
4641 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4643 u32 event = e->event_code;
4644 u32 status = e->status;
4646 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4647 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4648 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4650 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4657 brcmf_notify_mic_status(struct brcmf_if *ifp,
4658 const struct brcmf_event_msg *e, void *data)
4660 u16 flags = e->flags;
4661 enum nl80211_key_type key_type;
4663 if (flags & BRCMF_EVENT_MSG_GROUP)
4664 key_type = NL80211_KEYTYPE_GROUP;
4666 key_type = NL80211_KEYTYPE_PAIRWISE;
4668 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4674 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4675 const struct brcmf_event_msg *e, void *data)
4677 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4678 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4679 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4680 struct brcmf_cfg80211_vif *vif;
4682 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4683 ifevent->action, ifevent->flags, ifevent->ifidx,
4686 mutex_lock(&event->vif_event_lock);
4687 event->action = ifevent->action;
4690 switch (ifevent->action) {
4691 case BRCMF_E_IF_ADD:
4692 /* waiting process may have timed out */
4693 if (!cfg->vif_event.vif) {
4694 mutex_unlock(&event->vif_event_lock);
4701 vif->wdev.netdev = ifp->ndev;
4702 ifp->ndev->ieee80211_ptr = &vif->wdev;
4703 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4705 mutex_unlock(&event->vif_event_lock);
4706 wake_up(&event->vif_wq);
4709 case BRCMF_E_IF_DEL:
4710 mutex_unlock(&event->vif_event_lock);
4711 /* event may not be upon user request */
4712 if (brcmf_cfg80211_vif_event_armed(cfg))
4713 wake_up(&event->vif_wq);
4716 case BRCMF_E_IF_CHANGE:
4717 mutex_unlock(&event->vif_event_lock);
4718 wake_up(&event->vif_wq);
4722 mutex_unlock(&event->vif_event_lock);
4728 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4730 conf->frag_threshold = (u32)-1;
4731 conf->rts_threshold = (u32)-1;
4732 conf->retry_short = (u32)-1;
4733 conf->retry_long = (u32)-1;
4734 conf->tx_power = -1;
4737 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4739 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4740 brcmf_notify_connect_status);
4741 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4742 brcmf_notify_connect_status);
4743 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4744 brcmf_notify_connect_status);
4745 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4746 brcmf_notify_connect_status);
4747 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4748 brcmf_notify_connect_status);
4749 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4750 brcmf_notify_connect_status);
4751 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4752 brcmf_notify_roaming_status);
4753 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4754 brcmf_notify_mic_status);
4755 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4756 brcmf_notify_connect_status);
4757 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4758 brcmf_notify_sched_scan_results);
4759 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4760 brcmf_notify_vif_event);
4761 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4762 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4763 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4764 brcmf_p2p_notify_listen_complete);
4765 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4766 brcmf_p2p_notify_action_frame_rx);
4767 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4768 brcmf_p2p_notify_action_tx_complete);
4769 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4770 brcmf_p2p_notify_action_tx_complete);
4773 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4777 kfree(cfg->escan_ioctl_buf);
4778 cfg->escan_ioctl_buf = NULL;
4779 kfree(cfg->extra_buf);
4780 cfg->extra_buf = NULL;
4781 kfree(cfg->pmk_list);
4782 cfg->pmk_list = NULL;
4785 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4787 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4789 goto init_priv_mem_out;
4790 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4791 if (!cfg->escan_ioctl_buf)
4792 goto init_priv_mem_out;
4793 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4794 if (!cfg->extra_buf)
4795 goto init_priv_mem_out;
4796 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4798 goto init_priv_mem_out;
4803 brcmf_deinit_priv_mem(cfg);
4808 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4812 cfg->scan_request = NULL;
4813 cfg->pwr_save = true;
4814 cfg->roam_on = true; /* roam on & off switch.
4815 we enable roam per default */
4816 cfg->active_scan = true; /* we do active scan for
4817 specific scan per default */
4818 cfg->dongle_up = false; /* dongle is not up yet */
4819 err = brcmf_init_priv_mem(cfg);
4822 brcmf_register_event_handlers(cfg);
4823 mutex_init(&cfg->usr_sync);
4824 brcmf_init_escan(cfg);
4825 brcmf_init_conf(cfg->conf);
4826 init_completion(&cfg->vif_disabled);
4830 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4832 cfg->dongle_up = false; /* dongle down */
4833 brcmf_abort_scanning(cfg);
4834 brcmf_deinit_priv_mem(cfg);
4837 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4839 init_waitqueue_head(&event->vif_wq);
4840 mutex_init(&event->vif_event_lock);
4843 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4844 struct device *busdev)
4846 struct net_device *ndev = drvr->iflist[0]->ndev;
4847 struct brcmf_cfg80211_info *cfg;
4848 struct wiphy *wiphy;
4849 struct brcmf_cfg80211_vif *vif;
4850 struct brcmf_if *ifp;
4855 brcmf_err("ndev is invalid\n");
4859 ifp = netdev_priv(ndev);
4860 wiphy = brcmf_setup_wiphy(busdev);
4864 cfg = wiphy_priv(wiphy);
4867 init_vif_event(&cfg->vif_event);
4868 INIT_LIST_HEAD(&cfg->vif_list);
4870 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4877 vif->wdev.netdev = ndev;
4878 ndev->ieee80211_ptr = &vif->wdev;
4879 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4881 err = wl_init_priv(cfg);
4883 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4884 goto cfg80211_attach_out;
4888 err = brcmf_p2p_attach(cfg);
4890 brcmf_err("P2P initilisation failed (%d)\n", err);
4891 goto cfg80211_p2p_attach_out;
4893 err = brcmf_btcoex_attach(cfg);
4895 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4896 brcmf_p2p_detach(&cfg->p2p);
4897 goto cfg80211_p2p_attach_out;
4900 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4903 brcmf_err("Failed to get D11 version (%d)\n", err);
4904 goto cfg80211_p2p_attach_out;
4906 cfg->d11inf.io_type = (u8)io_type;
4907 brcmu_d11_attach(&cfg->d11inf);
4911 cfg80211_p2p_attach_out:
4912 wl_deinit_priv(cfg);
4914 cfg80211_attach_out:
4915 brcmf_free_vif(cfg, vif);
4919 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4921 struct brcmf_cfg80211_vif *vif;
4922 struct brcmf_cfg80211_vif *tmp;
4924 wl_deinit_priv(cfg);
4925 brcmf_btcoex_detach(cfg);
4926 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4927 brcmf_free_vif(cfg, vif);
4932 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4935 __le32 roamtrigger[2];
4936 __le32 roam_delta[2];
4939 * Setup timeout if Beacons are lost and roam is
4940 * off to report link down
4943 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4945 brcmf_err("bcn_timeout error (%d)\n", err);
4946 goto dongle_rom_out;
4951 * Enable/Disable built-in roaming to allow supplicant
4952 * to take care of roaming
4954 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4955 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4957 brcmf_err("roam_off error (%d)\n", err);
4958 goto dongle_rom_out;
4961 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4962 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4963 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4964 (void *)roamtrigger, sizeof(roamtrigger));
4966 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4967 goto dongle_rom_out;
4970 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4971 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4972 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4973 (void *)roam_delta, sizeof(roam_delta));
4975 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4976 goto dongle_rom_out;
4984 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4985 s32 scan_unassoc_time, s32 scan_passive_time)
4989 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4992 if (err == -EOPNOTSUPP)
4993 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4995 brcmf_err("Scan assoc time error (%d)\n", err);
4996 goto dongle_scantime_out;
4998 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5001 if (err == -EOPNOTSUPP)
5002 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5004 brcmf_err("Scan unassoc time error (%d)\n", err);
5005 goto dongle_scantime_out;
5008 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5011 if (err == -EOPNOTSUPP)
5012 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5014 brcmf_err("Scan passive time error (%d)\n", err);
5015 goto dongle_scantime_out;
5018 dongle_scantime_out:
5023 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
5025 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5026 struct ieee80211_channel *band_chan_arr;
5027 struct brcmf_chanspec_list *list;
5028 struct brcmu_chan ch;
5033 enum ieee80211_band band;
5042 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5047 list = (struct brcmf_chanspec_list *)pbuf;
5049 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5052 brcmf_err("get chanspecs error (%d)\n", err);
5056 __wl_band_2ghz.n_channels = 0;
5057 __wl_band_5ghz_a.n_channels = 0;
5059 total = le32_to_cpu(list->count);
5060 for (i = 0; i < total; i++) {
5061 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5062 cfg->d11inf.decchspec(&ch);
5064 if (ch.band == BRCMU_CHAN_BAND_2G) {
5065 band_chan_arr = __wl_2ghz_channels;
5066 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5067 n_cnt = &__wl_band_2ghz.n_channels;
5068 band = IEEE80211_BAND_2GHZ;
5069 ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
5070 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5071 band_chan_arr = __wl_5ghz_a_channels;
5072 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5073 n_cnt = &__wl_band_5ghz_a.n_channels;
5074 band = IEEE80211_BAND_5GHZ;
5075 ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
5077 brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec);
5080 if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40)
5083 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5084 if (band_chan_arr[j].hw_value == ch.chnum) {
5093 if (index < array_size) {
5094 band_chan_arr[index].center_freq =
5095 ieee80211_channel_to_frequency(ch.chnum, band);
5096 band_chan_arr[index].hw_value = ch.chnum;
5098 if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) {
5099 /* assuming the order is HT20, HT40 Upper,
5100 * HT40 lower from chanspecs
5102 ht40_flag = band_chan_arr[index].flags &
5103 IEEE80211_CHAN_NO_HT40;
5104 if (ch.sb == BRCMU_CHAN_SB_U) {
5105 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5106 band_chan_arr[index].flags &=
5107 ~IEEE80211_CHAN_NO_HT40;
5108 band_chan_arr[index].flags |=
5109 IEEE80211_CHAN_NO_HT40PLUS;
5111 /* It should be one of
5112 * IEEE80211_CHAN_NO_HT40 or
5113 * IEEE80211_CHAN_NO_HT40PLUS
5115 band_chan_arr[index].flags &=
5116 ~IEEE80211_CHAN_NO_HT40;
5117 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5118 band_chan_arr[index].flags |=
5119 IEEE80211_CHAN_NO_HT40MINUS;
5122 band_chan_arr[index].flags =
5123 IEEE80211_CHAN_NO_HT40;
5124 ch.bw = BRCMU_CHAN_BW_20;
5125 cfg->d11inf.encchspec(&ch);
5126 channel = ch.chspec;
5127 err = brcmf_fil_bsscfg_int_get(ifp,
5131 if (channel & WL_CHAN_RADAR)
5132 band_chan_arr[index].flags |=
5133 (IEEE80211_CHAN_RADAR |
5134 IEEE80211_CHAN_NO_IBSS);
5135 if (channel & WL_CHAN_PASSIVE)
5136 band_chan_arr[index].flags |=
5137 IEEE80211_CHAN_PASSIVE_SCAN;
5150 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5152 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5153 struct wiphy *wiphy;
5162 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
5165 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5166 &phy_list, sizeof(phy_list));
5168 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5172 phy = ((char *)&phy_list)[0];
5173 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5176 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5177 &band_list, sizeof(band_list));
5179 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5182 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5183 band_list[0], band_list[1], band_list[2]);
5185 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5187 brcmf_err("nmode error (%d)\n", err);
5189 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap);
5191 brcmf_err("mimo_bw_cap error (%d)\n", err);
5193 brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap);
5195 err = brcmf_construct_reginfo(cfg, bw_cap);
5197 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5201 nband = band_list[0];
5202 memset(bands, 0, sizeof(bands));
5204 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5206 if ((band_list[i] == WLC_BAND_5G) &&
5207 (__wl_band_5ghz_a.n_channels > 0)) {
5208 index = IEEE80211_BAND_5GHZ;
5209 bands[index] = &__wl_band_5ghz_a;
5210 if ((bw_cap == WLC_N_BW_40ALL) ||
5211 (bw_cap == WLC_N_BW_20IN2G_40IN5G))
5212 bands[index]->ht_cap.cap |=
5213 IEEE80211_HT_CAP_SGI_40;
5214 } else if ((band_list[i] == WLC_BAND_2G) &&
5215 (__wl_band_2ghz.n_channels > 0)) {
5216 index = IEEE80211_BAND_2GHZ;
5217 bands[index] = &__wl_band_2ghz;
5218 if (bw_cap == WLC_N_BW_40ALL)
5219 bands[index]->ht_cap.cap |=
5220 IEEE80211_HT_CAP_SGI_40;
5223 if ((index >= 0) && nmode) {
5224 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5225 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5226 bands[index]->ht_cap.ht_supported = true;
5227 bands[index]->ht_cap.ampdu_factor =
5228 IEEE80211_HT_MAX_AMPDU_64K;
5229 bands[index]->ht_cap.ampdu_density =
5230 IEEE80211_HT_MPDU_DENSITY_16;
5231 /* An HT shall support all EQM rates for one spatial
5234 bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5238 wiphy = cfg_to_wiphy(cfg);
5239 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5240 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5241 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5247 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5249 return brcmf_update_wiphybands(cfg);
5252 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5254 struct net_device *ndev;
5255 struct wireless_dev *wdev;
5256 struct brcmf_if *ifp;
5263 ndev = cfg_to_ndev(cfg);
5264 wdev = ndev->ieee80211_ptr;
5265 ifp = netdev_priv(ndev);
5267 /* make sure RF is ready for work */
5268 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5270 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5271 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5273 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5274 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5276 goto default_conf_out;
5277 brcmf_dbg(INFO, "power save set to %s\n",
5278 (power_mode ? "enabled" : "disabled"));
5280 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5282 goto default_conf_out;
5283 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5286 goto default_conf_out;
5287 err = brcmf_dongle_probecap(cfg);
5289 goto default_conf_out;
5291 brcmf_configure_arp_offload(ifp, true);
5293 cfg->dongle_up = true;
5300 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5302 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5304 return brcmf_config_dongle(ifp->drvr->config);
5307 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5309 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5312 * While going down, if associated with AP disassociate
5313 * from AP to save power
5315 if (check_vif_up(ifp->vif)) {
5316 brcmf_link_down(ifp->vif);
5318 /* Make sure WPA_Supplicant receives all the event
5319 generated due to DISASSOC call to the fw to keep
5320 the state fw and WPA_Supplicant state consistent
5325 brcmf_abort_scanning(cfg);
5326 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5331 s32 brcmf_cfg80211_up(struct net_device *ndev)
5333 struct brcmf_if *ifp = netdev_priv(ndev);
5334 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5337 mutex_lock(&cfg->usr_sync);
5338 err = __brcmf_cfg80211_up(ifp);
5339 mutex_unlock(&cfg->usr_sync);
5344 s32 brcmf_cfg80211_down(struct net_device *ndev)
5346 struct brcmf_if *ifp = netdev_priv(ndev);
5347 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5350 mutex_lock(&cfg->usr_sync);
5351 err = __brcmf_cfg80211_down(ifp);
5352 mutex_unlock(&cfg->usr_sync);
5357 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5359 struct wireless_dev *wdev = &ifp->vif->wdev;
5361 return wdev->iftype;
5364 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5366 struct brcmf_cfg80211_vif *vif;
5369 list_for_each_entry(vif, &cfg->vif_list, list) {
5370 if (test_bit(state, &vif->sme_state))
5376 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5381 mutex_lock(&event->vif_event_lock);
5382 evt_action = event->action;
5383 mutex_unlock(&event->vif_event_lock);
5384 return evt_action == action;
5387 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5388 struct brcmf_cfg80211_vif *vif)
5390 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5392 mutex_lock(&event->vif_event_lock);
5395 mutex_unlock(&event->vif_event_lock);
5398 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5400 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5403 mutex_lock(&event->vif_event_lock);
5404 armed = event->vif != NULL;
5405 mutex_unlock(&event->vif_event_lock);
5409 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5410 u8 action, ulong timeout)
5412 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5414 return wait_event_timeout(event->vif_wq,
5415 vif_event_equals(event, action), timeout);