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);
462 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
464 enum nl80211_iftype type,
466 struct vif_params *params)
468 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
470 case NL80211_IFTYPE_ADHOC:
471 case NL80211_IFTYPE_STATION:
472 case NL80211_IFTYPE_AP:
473 case NL80211_IFTYPE_AP_VLAN:
474 case NL80211_IFTYPE_WDS:
475 case NL80211_IFTYPE_MONITOR:
476 case NL80211_IFTYPE_MESH_POINT:
477 return ERR_PTR(-EOPNOTSUPP);
478 case NL80211_IFTYPE_P2P_CLIENT:
479 case NL80211_IFTYPE_P2P_GO:
480 case NL80211_IFTYPE_P2P_DEVICE:
481 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
482 case NL80211_IFTYPE_UNSPECIFIED:
484 return ERR_PTR(-EINVAL);
488 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
492 if (check_vif_up(ifp->vif)) {
493 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
495 brcmf_err("fail to set mpc\n");
498 brcmf_dbg(INFO, "MPC : %d\n", mpc);
502 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
503 struct brcmf_if *ifp, bool aborted,
506 struct brcmf_scan_params_le params_le;
507 struct cfg80211_scan_request *scan_request;
510 brcmf_dbg(SCAN, "Enter\n");
512 /* clear scan request, because the FW abort can cause a second call */
513 /* to this functon and might cause a double cfg80211_scan_done */
514 scan_request = cfg->scan_request;
515 cfg->scan_request = NULL;
517 if (timer_pending(&cfg->escan_timeout))
518 del_timer_sync(&cfg->escan_timeout);
521 /* Do a scan abort to stop the driver's scan engine */
522 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
523 memset(¶ms_le, 0, sizeof(params_le));
524 memset(params_le.bssid, 0xFF, ETH_ALEN);
525 params_le.bss_type = DOT11_BSSTYPE_ANY;
526 params_le.scan_type = 0;
527 params_le.channel_num = cpu_to_le32(1);
528 params_le.nprobes = cpu_to_le32(1);
529 params_le.active_time = cpu_to_le32(-1);
530 params_le.passive_time = cpu_to_le32(-1);
531 params_le.home_time = cpu_to_le32(-1);
532 /* Scan is aborted by setting channel_list[0] to -1 */
533 params_le.channel_list[0] = cpu_to_le16(-1);
534 /* E-Scan (or anyother type) can be aborted by SCAN */
535 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
536 ¶ms_le, sizeof(params_le));
538 brcmf_err("Scan abort failed\n");
541 * e-scan can be initiated by scheduled scan
542 * which takes precedence.
544 if (cfg->sched_escan) {
545 brcmf_dbg(SCAN, "scheduled scan completed\n");
546 cfg->sched_escan = false;
548 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
549 brcmf_set_mpc(ifp, 1);
550 } else if (scan_request) {
551 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
552 aborted ? "Aborted" : "Done");
553 cfg80211_scan_done(scan_request, aborted);
554 brcmf_set_mpc(ifp, 1);
556 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
557 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
563 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
565 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
566 struct net_device *ndev = wdev->netdev;
568 /* vif event pending in firmware */
569 if (brcmf_cfg80211_vif_event_armed(cfg))
573 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
574 cfg->escan_info.ifp == netdev_priv(ndev))
575 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
578 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
581 switch (wdev->iftype) {
582 case NL80211_IFTYPE_ADHOC:
583 case NL80211_IFTYPE_STATION:
584 case NL80211_IFTYPE_AP:
585 case NL80211_IFTYPE_AP_VLAN:
586 case NL80211_IFTYPE_WDS:
587 case NL80211_IFTYPE_MONITOR:
588 case NL80211_IFTYPE_MESH_POINT:
590 case NL80211_IFTYPE_P2P_CLIENT:
591 case NL80211_IFTYPE_P2P_GO:
592 case NL80211_IFTYPE_P2P_DEVICE:
593 return brcmf_p2p_del_vif(wiphy, wdev);
594 case NL80211_IFTYPE_UNSPECIFIED:
602 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
603 enum nl80211_iftype type, u32 *flags,
604 struct vif_params *params)
606 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
607 struct brcmf_if *ifp = netdev_priv(ndev);
608 struct brcmf_cfg80211_vif *vif = ifp->vif;
613 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
616 case NL80211_IFTYPE_MONITOR:
617 case NL80211_IFTYPE_WDS:
618 brcmf_err("type (%d) : currently we do not support this type\n",
621 case NL80211_IFTYPE_ADHOC:
622 vif->mode = WL_MODE_IBSS;
625 case NL80211_IFTYPE_STATION:
626 /* Ignore change for p2p IF. Unclear why supplicant does this */
627 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
628 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
629 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
630 /* WAR: It is unexpected to get a change of VIF for P2P
631 * IF, but it happens. The request can not be handled
632 * but returning EPERM causes a crash. Returning 0
633 * without setting ieee80211_ptr->iftype causes trace
634 * (WARN_ON) but it works with wpa_supplicant
638 vif->mode = WL_MODE_BSS;
641 case NL80211_IFTYPE_AP:
642 case NL80211_IFTYPE_P2P_GO:
643 vif->mode = WL_MODE_AP;
652 if (type == NL80211_IFTYPE_P2P_GO) {
653 brcmf_dbg(INFO, "IF Type = P2P GO\n");
654 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
657 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
658 brcmf_dbg(INFO, "IF Type = AP\n");
661 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
663 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
667 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
670 ndev->ieee80211_ptr->iftype = type;
673 brcmf_dbg(TRACE, "Exit\n");
678 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
679 struct brcmf_scan_params_le *params_le,
680 struct cfg80211_scan_request *request)
688 struct brcmf_ssid_le ssid_le;
690 memset(params_le->bssid, 0xFF, ETH_ALEN);
691 params_le->bss_type = DOT11_BSSTYPE_ANY;
692 params_le->scan_type = 0;
693 params_le->channel_num = 0;
694 params_le->nprobes = cpu_to_le32(-1);
695 params_le->active_time = cpu_to_le32(-1);
696 params_le->passive_time = cpu_to_le32(-1);
697 params_le->home_time = cpu_to_le32(-1);
698 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
700 /* if request is null exit so it will be all channel broadcast scan */
704 n_ssids = request->n_ssids;
705 n_channels = request->n_channels;
706 /* Copy channel array if applicable */
707 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
709 if (n_channels > 0) {
710 for (i = 0; i < n_channels; i++) {
711 chanspec = channel_to_chanspec(&cfg->d11inf,
712 request->channels[i]);
713 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
714 request->channels[i]->hw_value, chanspec);
715 params_le->channel_list[i] = cpu_to_le16(chanspec);
718 brcmf_dbg(SCAN, "Scanning all channels\n");
720 /* Copy ssid array if applicable */
721 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
723 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
724 n_channels * sizeof(u16);
725 offset = roundup(offset, sizeof(u32));
726 ptr = (char *)params_le + offset;
727 for (i = 0; i < n_ssids; i++) {
728 memset(&ssid_le, 0, sizeof(ssid_le));
730 cpu_to_le32(request->ssids[i].ssid_len);
731 memcpy(ssid_le.SSID, request->ssids[i].ssid,
732 request->ssids[i].ssid_len);
733 if (!ssid_le.SSID_len)
734 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
736 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
737 i, ssid_le.SSID, ssid_le.SSID_len);
738 memcpy(ptr, &ssid_le, sizeof(ssid_le));
739 ptr += sizeof(ssid_le);
742 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
743 if ((request->ssids) && request->ssids->ssid_len) {
744 brcmf_dbg(SCAN, "SSID %s len=%d\n",
745 params_le->ssid_le.SSID,
746 request->ssids->ssid_len);
747 params_le->ssid_le.SSID_len =
748 cpu_to_le32(request->ssids->ssid_len);
749 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
750 request->ssids->ssid_len);
753 /* Adding mask to channel numbers */
754 params_le->channel_num =
755 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
756 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
760 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
761 struct cfg80211_scan_request *request, u16 action)
763 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
764 offsetof(struct brcmf_escan_params_le, params_le);
765 struct brcmf_escan_params_le *params;
768 brcmf_dbg(SCAN, "E-SCAN START\n");
770 if (request != NULL) {
771 /* Allocate space for populating ssids in struct */
772 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
774 /* Allocate space for populating ssids in struct */
775 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
778 params = kzalloc(params_size, GFP_KERNEL);
783 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
784 brcmf_escan_prep(cfg, ¶ms->params_le, request);
785 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
786 params->action = cpu_to_le16(action);
787 params->sync_id = cpu_to_le16(0x1234);
789 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
792 brcmf_dbg(INFO, "system busy : escan canceled\n");
794 brcmf_err("error (%d)\n", err);
803 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
804 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
808 struct brcmf_scan_results *results;
809 struct escan_info *escan = &cfg->escan_info;
811 brcmf_dbg(SCAN, "Enter\n");
813 escan->wiphy = wiphy;
814 escan->escan_state = WL_ESCAN_STATE_SCANNING;
815 passive_scan = cfg->active_scan ? 0 : 1;
816 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
819 brcmf_err("error (%d)\n", err);
822 brcmf_set_mpc(ifp, 0);
823 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
824 results->version = 0;
826 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
828 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
830 brcmf_set_mpc(ifp, 1);
835 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
836 struct cfg80211_scan_request *request,
837 struct cfg80211_ssid *this_ssid)
839 struct brcmf_if *ifp = vif->ifp;
840 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
841 struct cfg80211_ssid *ssids;
842 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
849 brcmf_dbg(SCAN, "START ESCAN\n");
851 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
852 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
855 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
856 brcmf_err("Scanning being aborted: status (%lu)\n",
860 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
861 brcmf_err("Scanning suppressed: status (%lu)\n",
865 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
866 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
870 /* If scan req comes for p2p0, send it over primary I/F */
871 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
872 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
874 /* Arm scan timeout timer */
875 mod_timer(&cfg->escan_timeout, jiffies +
876 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
881 ssids = request->ssids;
885 /* we don't do escan in ibss */
889 cfg->scan_request = request;
890 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
892 cfg->escan_info.run = brcmf_run_escan;
893 err = brcmf_p2p_scan_prep(wiphy, request, vif);
897 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
901 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
902 ssids->ssid, ssids->ssid_len);
903 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
904 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
905 sr->ssid_le.SSID_len = cpu_to_le32(0);
908 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
909 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
912 brcmf_dbg(SCAN, "Broadcast scan\n");
914 passive_scan = cfg->active_scan ? 0 : 1;
915 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
918 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
921 brcmf_set_mpc(ifp, 0);
922 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
923 &sr->ssid_le, sizeof(sr->ssid_le));
926 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
929 brcmf_err("WLC_SCAN error (%d)\n", err);
931 brcmf_set_mpc(ifp, 1);
939 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
940 if (timer_pending(&cfg->escan_timeout))
941 del_timer_sync(&cfg->escan_timeout);
942 cfg->scan_request = NULL;
947 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
949 struct brcmf_cfg80211_vif *vif;
952 brcmf_dbg(TRACE, "Enter\n");
953 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
954 if (!check_vif_up(vif))
957 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
960 brcmf_err("scan error (%d)\n", err);
962 brcmf_dbg(TRACE, "Exit\n");
966 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
970 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
973 brcmf_err("Error (%d)\n", err);
978 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
982 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
985 brcmf_err("Error (%d)\n", err);
990 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
993 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
995 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
997 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1003 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1005 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1006 struct net_device *ndev = cfg_to_ndev(cfg);
1007 struct brcmf_if *ifp = netdev_priv(ndev);
1010 brcmf_dbg(TRACE, "Enter\n");
1011 if (!check_vif_up(ifp->vif))
1014 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1015 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1016 cfg->conf->rts_threshold = wiphy->rts_threshold;
1017 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1021 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1022 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1023 cfg->conf->frag_threshold = wiphy->frag_threshold;
1024 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1028 if (changed & WIPHY_PARAM_RETRY_LONG
1029 && (cfg->conf->retry_long != wiphy->retry_long)) {
1030 cfg->conf->retry_long = wiphy->retry_long;
1031 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1035 if (changed & WIPHY_PARAM_RETRY_SHORT
1036 && (cfg->conf->retry_short != wiphy->retry_short)) {
1037 cfg->conf->retry_short = wiphy->retry_short;
1038 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1044 brcmf_dbg(TRACE, "Exit\n");
1048 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1050 memset(prof, 0, sizeof(*prof));
1053 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1055 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1058 brcmf_dbg(TRACE, "Enter\n");
1060 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1061 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1062 err = brcmf_fil_cmd_data_set(vif->ifp,
1063 BRCMF_C_DISASSOC, NULL, 0);
1065 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1066 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1068 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1069 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1070 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1071 brcmf_dbg(TRACE, "Exit\n");
1075 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1076 struct cfg80211_ibss_params *params)
1078 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1079 struct brcmf_if *ifp = netdev_priv(ndev);
1080 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1081 struct brcmf_join_params join_params;
1082 size_t join_params_size = 0;
1088 brcmf_dbg(TRACE, "Enter\n");
1089 if (!check_vif_up(ifp->vif))
1093 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1095 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1099 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1102 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1104 brcmf_dbg(CONN, "No BSSID specified\n");
1106 if (params->chandef.chan)
1107 brcmf_dbg(CONN, "channel: %d\n",
1108 params->chandef.chan->center_freq);
1110 brcmf_dbg(CONN, "no channel specified\n");
1112 if (params->channel_fixed)
1113 brcmf_dbg(CONN, "fixed channel required\n");
1115 brcmf_dbg(CONN, "no fixed channel required\n");
1117 if (params->ie && params->ie_len)
1118 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1120 brcmf_dbg(CONN, "no ie specified\n");
1122 if (params->beacon_interval)
1123 brcmf_dbg(CONN, "beacon interval: %d\n",
1124 params->beacon_interval);
1126 brcmf_dbg(CONN, "no beacon interval specified\n");
1128 if (params->basic_rates)
1129 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1131 brcmf_dbg(CONN, "no basic rates specified\n");
1133 if (params->privacy)
1134 brcmf_dbg(CONN, "privacy required\n");
1136 brcmf_dbg(CONN, "no privacy required\n");
1138 /* Configure Privacy for starter */
1139 if (params->privacy)
1140 wsec |= WEP_ENABLED;
1142 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1144 brcmf_err("wsec failed (%d)\n", err);
1148 /* Configure Beacon Interval for starter */
1149 if (params->beacon_interval)
1150 bcnprd = params->beacon_interval;
1154 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1156 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1160 /* Configure required join parameter */
1161 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1164 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1165 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1166 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1167 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1168 join_params_size = sizeof(join_params.ssid_le);
1171 if (params->bssid) {
1172 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1173 join_params_size = sizeof(join_params.ssid_le) +
1174 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1175 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1177 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1178 memset(profile->bssid, 0, ETH_ALEN);
1182 if (params->chandef.chan) {
1186 ieee80211_frequency_to_channel(
1187 params->chandef.chan->center_freq);
1188 if (params->channel_fixed) {
1189 /* adding chanspec */
1190 chanspec = channel_to_chanspec(&cfg->d11inf,
1191 params->chandef.chan);
1192 join_params.params_le.chanspec_list[0] =
1193 cpu_to_le16(chanspec);
1194 join_params.params_le.chanspec_num = cpu_to_le32(1);
1195 join_params_size += sizeof(join_params.params_le);
1198 /* set channel for starter */
1199 target_channel = cfg->channel;
1200 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1203 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1209 cfg->ibss_starter = false;
1212 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1213 &join_params, join_params_size);
1215 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1221 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1222 brcmf_dbg(TRACE, "Exit\n");
1227 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1229 struct brcmf_if *ifp = netdev_priv(ndev);
1232 brcmf_dbg(TRACE, "Enter\n");
1233 if (!check_vif_up(ifp->vif))
1236 brcmf_link_down(ifp->vif);
1238 brcmf_dbg(TRACE, "Exit\n");
1243 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1244 struct cfg80211_connect_params *sme)
1246 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1247 struct brcmf_cfg80211_security *sec;
1251 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1252 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1253 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1254 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1256 val = WPA_AUTH_DISABLED;
1257 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1258 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1260 brcmf_err("set wpa_auth failed (%d)\n", err);
1263 sec = &profile->sec;
1264 sec->wpa_versions = sme->crypto.wpa_versions;
1268 static s32 brcmf_set_auth_type(struct net_device *ndev,
1269 struct cfg80211_connect_params *sme)
1271 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1272 struct brcmf_cfg80211_security *sec;
1276 switch (sme->auth_type) {
1277 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1279 brcmf_dbg(CONN, "open system\n");
1281 case NL80211_AUTHTYPE_SHARED_KEY:
1283 brcmf_dbg(CONN, "shared key\n");
1285 case NL80211_AUTHTYPE_AUTOMATIC:
1287 brcmf_dbg(CONN, "automatic\n");
1289 case NL80211_AUTHTYPE_NETWORK_EAP:
1290 brcmf_dbg(CONN, "network eap\n");
1293 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1297 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1299 brcmf_err("set auth failed (%d)\n", err);
1302 sec = &profile->sec;
1303 sec->auth_type = sme->auth_type;
1308 brcmf_set_set_cipher(struct net_device *ndev,
1309 struct cfg80211_connect_params *sme)
1311 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1312 struct brcmf_cfg80211_security *sec;
1317 if (sme->crypto.n_ciphers_pairwise) {
1318 switch (sme->crypto.ciphers_pairwise[0]) {
1319 case WLAN_CIPHER_SUITE_WEP40:
1320 case WLAN_CIPHER_SUITE_WEP104:
1323 case WLAN_CIPHER_SUITE_TKIP:
1324 pval = TKIP_ENABLED;
1326 case WLAN_CIPHER_SUITE_CCMP:
1329 case WLAN_CIPHER_SUITE_AES_CMAC:
1333 brcmf_err("invalid cipher pairwise (%d)\n",
1334 sme->crypto.ciphers_pairwise[0]);
1338 if (sme->crypto.cipher_group) {
1339 switch (sme->crypto.cipher_group) {
1340 case WLAN_CIPHER_SUITE_WEP40:
1341 case WLAN_CIPHER_SUITE_WEP104:
1344 case WLAN_CIPHER_SUITE_TKIP:
1345 gval = TKIP_ENABLED;
1347 case WLAN_CIPHER_SUITE_CCMP:
1350 case WLAN_CIPHER_SUITE_AES_CMAC:
1354 brcmf_err("invalid cipher group (%d)\n",
1355 sme->crypto.cipher_group);
1360 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1361 /* In case of privacy, but no security and WPS then simulate */
1362 /* setting AES. WPS-2.0 allows no security */
1363 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1366 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1368 brcmf_err("error (%d)\n", err);
1372 sec = &profile->sec;
1373 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1374 sec->cipher_group = sme->crypto.cipher_group;
1380 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1382 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1383 struct brcmf_cfg80211_security *sec;
1387 if (sme->crypto.n_akm_suites) {
1388 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1391 brcmf_err("could not get wpa_auth (%d)\n", err);
1394 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1395 switch (sme->crypto.akm_suites[0]) {
1396 case WLAN_AKM_SUITE_8021X:
1397 val = WPA_AUTH_UNSPECIFIED;
1399 case WLAN_AKM_SUITE_PSK:
1403 brcmf_err("invalid cipher group (%d)\n",
1404 sme->crypto.cipher_group);
1407 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1408 switch (sme->crypto.akm_suites[0]) {
1409 case WLAN_AKM_SUITE_8021X:
1410 val = WPA2_AUTH_UNSPECIFIED;
1412 case WLAN_AKM_SUITE_PSK:
1413 val = WPA2_AUTH_PSK;
1416 brcmf_err("invalid cipher group (%d)\n",
1417 sme->crypto.cipher_group);
1422 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1423 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1426 brcmf_err("could not set wpa_auth (%d)\n", err);
1430 sec = &profile->sec;
1431 sec->wpa_auth = sme->crypto.akm_suites[0];
1437 brcmf_set_sharedkey(struct net_device *ndev,
1438 struct cfg80211_connect_params *sme)
1440 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1441 struct brcmf_cfg80211_security *sec;
1442 struct brcmf_wsec_key key;
1446 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1448 if (sme->key_len == 0)
1451 sec = &profile->sec;
1452 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1453 sec->wpa_versions, sec->cipher_pairwise);
1455 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1458 if (!(sec->cipher_pairwise &
1459 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1462 memset(&key, 0, sizeof(key));
1463 key.len = (u32) sme->key_len;
1464 key.index = (u32) sme->key_idx;
1465 if (key.len > sizeof(key.data)) {
1466 brcmf_err("Too long key length (%u)\n", key.len);
1469 memcpy(key.data, sme->key, key.len);
1470 key.flags = BRCMF_PRIMARY_KEY;
1471 switch (sec->cipher_pairwise) {
1472 case WLAN_CIPHER_SUITE_WEP40:
1473 key.algo = CRYPTO_ALGO_WEP1;
1475 case WLAN_CIPHER_SUITE_WEP104:
1476 key.algo = CRYPTO_ALGO_WEP128;
1479 brcmf_err("Invalid algorithm (%d)\n",
1480 sme->crypto.ciphers_pairwise[0]);
1483 /* Set the new key/index */
1484 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1485 key.len, key.index, key.algo);
1486 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1487 err = send_key_to_dongle(ndev, &key);
1491 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1492 brcmf_dbg(CONN, "set auth_type to shared key\n");
1493 val = WL_AUTH_SHARED_KEY; /* shared key */
1494 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1496 brcmf_err("set auth failed (%d)\n", err);
1502 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1503 enum nl80211_auth_type type)
1506 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1507 /* shift to ignore chip revision */
1508 ci = brcmf_get_chip_info(ifp) >> 4;
1511 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1512 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1521 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1522 struct cfg80211_connect_params *sme)
1524 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1525 struct brcmf_if *ifp = netdev_priv(ndev);
1526 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1527 struct ieee80211_channel *chan = sme->channel;
1528 struct brcmf_join_params join_params;
1529 size_t join_params_size;
1530 struct brcmf_tlv *rsn_ie;
1531 struct brcmf_vs_tlv *wpa_ie;
1534 struct brcmf_ext_join_params_le *ext_join_params;
1539 brcmf_dbg(TRACE, "Enter\n");
1540 if (!check_vif_up(ifp->vif))
1544 brcmf_err("Invalid ssid\n");
1548 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1549 /* A normal (non P2P) connection request setup. */
1552 /* find the WPA_IE */
1553 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1556 ie_len = wpa_ie->len + TLV_HDR_LEN;
1558 /* find the RSN_IE */
1559 rsn_ie = brcmf_parse_tlvs((u8 *)sme->ie, sme->ie_len,
1563 ie_len = rsn_ie->len + TLV_HDR_LEN;
1566 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1569 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1570 sme->ie, sme->ie_len);
1572 brcmf_err("Set Assoc REQ IE Failed\n");
1574 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1576 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1580 ieee80211_frequency_to_channel(chan->center_freq);
1581 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1582 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1583 cfg->channel, chan->center_freq, chanspec);
1589 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1591 err = brcmf_set_wpa_version(ndev, sme);
1593 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1597 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1598 err = brcmf_set_auth_type(ndev, sme);
1600 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1604 err = brcmf_set_set_cipher(ndev, sme);
1606 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1610 err = brcmf_set_key_mgmt(ndev, sme);
1612 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1616 err = brcmf_set_sharedkey(ndev, sme);
1618 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1622 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1623 (u32)sme->ssid_len);
1624 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1625 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1626 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1627 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1628 profile->ssid.SSID_len);
1631 /* Join with specific BSSID and cached SSID
1632 * If SSID is zero join based on BSSID only
1634 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1635 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1637 join_params_size += sizeof(u16);
1638 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1639 if (ext_join_params == NULL) {
1643 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1644 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1645 profile->ssid.SSID_len);
1646 /*increase dwell time to receive probe response or detect Beacon
1647 * from target AP at a noisy air only during connect command
1649 ext_join_params->scan_le.active_time =
1650 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1651 ext_join_params->scan_le.passive_time =
1652 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1653 /* Set up join scan parameters */
1654 ext_join_params->scan_le.scan_type = -1;
1655 /* to sync with presence period of VSDB GO.
1656 * Send probe request more frequently. Probe request will be stopped
1657 * when it gets probe response from target AP/GO.
1659 ext_join_params->scan_le.nprobes =
1660 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1661 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1662 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1665 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1667 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1670 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1672 ext_join_params->assoc_le.chanspec_list[0] =
1673 cpu_to_le16(chanspec);
1676 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1678 kfree(ext_join_params);
1680 /* This is it. join command worked, we are done */
1683 /* join command failed, fallback to set ssid */
1684 memset(&join_params, 0, sizeof(join_params));
1685 join_params_size = sizeof(join_params.ssid_le);
1687 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1688 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1691 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1693 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1696 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1697 join_params.params_le.chanspec_num = cpu_to_le32(1);
1698 join_params_size += sizeof(join_params.params_le);
1700 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1701 &join_params, join_params_size);
1703 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1707 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1708 brcmf_dbg(TRACE, "Exit\n");
1713 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1716 struct brcmf_if *ifp = netdev_priv(ndev);
1717 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1718 struct brcmf_scb_val_le scbval;
1721 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1722 if (!check_vif_up(ifp->vif))
1725 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1727 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1728 scbval.val = cpu_to_le32(reason_code);
1729 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1730 &scbval, sizeof(scbval));
1732 brcmf_err("error (%d)\n", err);
1734 brcmf_dbg(TRACE, "Exit\n");
1739 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1740 enum nl80211_tx_power_setting type, s32 mbm)
1743 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1744 struct net_device *ndev = cfg_to_ndev(cfg);
1745 struct brcmf_if *ifp = netdev_priv(ndev);
1749 s32 dbm = MBM_TO_DBM(mbm);
1751 brcmf_dbg(TRACE, "Enter\n");
1752 if (!check_vif_up(ifp->vif))
1756 case NL80211_TX_POWER_AUTOMATIC:
1758 case NL80211_TX_POWER_LIMITED:
1759 case NL80211_TX_POWER_FIXED:
1761 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1767 /* Make sure radio is off or on as far as software is concerned */
1768 disable = WL_RADIO_SW_DISABLE << 16;
1769 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1771 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1776 txpwrmw = (u16) dbm;
1777 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1778 (s32)brcmf_mw_to_qdbm(txpwrmw));
1780 brcmf_err("qtxpower error (%d)\n", err);
1781 cfg->conf->tx_power = dbm;
1784 brcmf_dbg(TRACE, "Exit\n");
1788 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1789 struct wireless_dev *wdev,
1792 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1793 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1798 brcmf_dbg(TRACE, "Enter\n");
1799 if (!check_vif_up(ifp->vif))
1802 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1804 brcmf_err("error (%d)\n", err);
1808 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1809 *dbm = (s32) brcmf_qdbm_to_mw(result);
1812 brcmf_dbg(TRACE, "Exit\n");
1817 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1818 u8 key_idx, bool unicast, bool multicast)
1820 struct brcmf_if *ifp = netdev_priv(ndev);
1825 brcmf_dbg(TRACE, "Enter\n");
1826 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1827 if (!check_vif_up(ifp->vif))
1830 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1832 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1836 if (wsec & WEP_ENABLED) {
1837 /* Just select a new current key */
1839 err = brcmf_fil_cmd_int_set(ifp,
1840 BRCMF_C_SET_KEY_PRIMARY, index);
1842 brcmf_err("error (%d)\n", err);
1845 brcmf_dbg(TRACE, "Exit\n");
1850 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1851 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1853 struct brcmf_if *ifp = netdev_priv(ndev);
1854 struct brcmf_wsec_key key;
1858 memset(&key, 0, sizeof(key));
1859 key.index = (u32) key_idx;
1860 /* Instead of bcast for ea address for default wep keys,
1861 driver needs it to be Null */
1862 if (!is_multicast_ether_addr(mac_addr))
1863 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1864 key.len = (u32) params->key_len;
1865 /* check for key index change */
1868 err = send_key_to_dongle(ndev, &key);
1870 brcmf_err("key delete error (%d)\n", err);
1872 if (key.len > sizeof(key.data)) {
1873 brcmf_err("Invalid key length (%d)\n", key.len);
1877 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1878 memcpy(key.data, params->key, key.len);
1880 if ((ifp->vif->mode != WL_MODE_AP) &&
1881 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1882 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1883 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1884 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1885 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1888 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1889 if (params->seq && params->seq_len == 6) {
1892 ivptr = (u8 *) params->seq;
1893 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1894 (ivptr[3] << 8) | ivptr[2];
1895 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1896 key.iv_initialized = true;
1899 switch (params->cipher) {
1900 case WLAN_CIPHER_SUITE_WEP40:
1901 key.algo = CRYPTO_ALGO_WEP1;
1902 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1904 case WLAN_CIPHER_SUITE_WEP104:
1905 key.algo = CRYPTO_ALGO_WEP128;
1906 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1908 case WLAN_CIPHER_SUITE_TKIP:
1909 key.algo = CRYPTO_ALGO_TKIP;
1910 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1912 case WLAN_CIPHER_SUITE_AES_CMAC:
1913 key.algo = CRYPTO_ALGO_AES_CCM;
1914 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1916 case WLAN_CIPHER_SUITE_CCMP:
1917 key.algo = CRYPTO_ALGO_AES_CCM;
1918 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1921 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1924 err = send_key_to_dongle(ndev, &key);
1926 brcmf_err("wsec_key error (%d)\n", err);
1932 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1933 u8 key_idx, bool pairwise, const u8 *mac_addr,
1934 struct key_params *params)
1936 struct brcmf_if *ifp = netdev_priv(ndev);
1937 struct brcmf_wsec_key key;
1943 brcmf_dbg(TRACE, "Enter\n");
1944 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1945 if (!check_vif_up(ifp->vif))
1949 brcmf_dbg(TRACE, "Exit");
1950 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1952 memset(&key, 0, sizeof(key));
1954 key.len = (u32) params->key_len;
1955 key.index = (u32) key_idx;
1957 if (key.len > sizeof(key.data)) {
1958 brcmf_err("Too long key length (%u)\n", key.len);
1962 memcpy(key.data, params->key, key.len);
1964 key.flags = BRCMF_PRIMARY_KEY;
1965 switch (params->cipher) {
1966 case WLAN_CIPHER_SUITE_WEP40:
1967 key.algo = CRYPTO_ALGO_WEP1;
1969 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1971 case WLAN_CIPHER_SUITE_WEP104:
1972 key.algo = CRYPTO_ALGO_WEP128;
1974 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1976 case WLAN_CIPHER_SUITE_TKIP:
1977 if (ifp->vif->mode != WL_MODE_AP) {
1978 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1979 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1980 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1981 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1983 key.algo = CRYPTO_ALGO_TKIP;
1985 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1987 case WLAN_CIPHER_SUITE_AES_CMAC:
1988 key.algo = CRYPTO_ALGO_AES_CCM;
1990 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1992 case WLAN_CIPHER_SUITE_CCMP:
1993 key.algo = CRYPTO_ALGO_AES_CCM;
1995 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1998 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2003 err = send_key_to_dongle(ndev, &key);
2007 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2009 brcmf_err("get wsec error (%d)\n", err);
2013 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2015 brcmf_err("set wsec error (%d)\n", err);
2020 brcmf_dbg(TRACE, "Exit\n");
2025 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2026 u8 key_idx, bool pairwise, const u8 *mac_addr)
2028 struct brcmf_if *ifp = netdev_priv(ndev);
2029 struct brcmf_wsec_key key;
2032 brcmf_dbg(TRACE, "Enter\n");
2033 if (!check_vif_up(ifp->vif))
2036 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2037 /* we ignore this key index in this case */
2038 brcmf_err("invalid key index (%d)\n", key_idx);
2042 memset(&key, 0, sizeof(key));
2044 key.index = (u32) key_idx;
2045 key.flags = BRCMF_PRIMARY_KEY;
2046 key.algo = CRYPTO_ALGO_OFF;
2048 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2050 /* Set the new key/index */
2051 err = send_key_to_dongle(ndev, &key);
2053 brcmf_dbg(TRACE, "Exit\n");
2058 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2059 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2060 void (*callback) (void *cookie, struct key_params * params))
2062 struct key_params params;
2063 struct brcmf_if *ifp = netdev_priv(ndev);
2064 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2065 struct brcmf_cfg80211_security *sec;
2069 brcmf_dbg(TRACE, "Enter\n");
2070 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2071 if (!check_vif_up(ifp->vif))
2074 memset(¶ms, 0, sizeof(params));
2076 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2078 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2079 /* Ignore this error, may happen during DISASSOC */
2083 if (wsec & WEP_ENABLED) {
2084 sec = &profile->sec;
2085 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2086 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2087 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2088 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2089 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2090 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2092 } else if (wsec & TKIP_ENABLED) {
2093 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2094 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2095 } else if (wsec & AES_ENABLED) {
2096 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2097 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2099 brcmf_err("Invalid algo (0x%x)\n", wsec);
2103 callback(cookie, ¶ms);
2106 brcmf_dbg(TRACE, "Exit\n");
2111 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2112 struct net_device *ndev, u8 key_idx)
2114 brcmf_dbg(INFO, "Not supported\n");
2120 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2121 u8 *mac, struct station_info *sinfo)
2123 struct brcmf_if *ifp = netdev_priv(ndev);
2124 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2125 struct brcmf_scb_val_le scb_val;
2129 u8 *bssid = profile->bssid;
2130 struct brcmf_sta_info_le sta_info_le;
2132 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2133 if (!check_vif_up(ifp->vif))
2136 if (ifp->vif->mode == WL_MODE_AP) {
2137 memcpy(&sta_info_le, mac, ETH_ALEN);
2138 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2140 sizeof(sta_info_le));
2142 brcmf_err("GET STA INFO failed, %d\n", err);
2145 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2146 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2147 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2148 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2149 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2151 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2152 sinfo->inactive_time, sinfo->connected_time);
2153 } else if (ifp->vif->mode == WL_MODE_BSS) {
2154 if (memcmp(mac, bssid, ETH_ALEN)) {
2155 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2160 /* Report the current tx rate */
2161 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2163 brcmf_err("Could not get rate (%d)\n", err);
2166 sinfo->filled |= STATION_INFO_TX_BITRATE;
2167 sinfo->txrate.legacy = rate * 5;
2168 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2171 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2172 &ifp->vif->sme_state)) {
2173 memset(&scb_val, 0, sizeof(scb_val));
2174 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2175 &scb_val, sizeof(scb_val));
2177 brcmf_err("Could not get rssi (%d)\n", err);
2180 rssi = le32_to_cpu(scb_val.val);
2181 sinfo->filled |= STATION_INFO_SIGNAL;
2182 sinfo->signal = rssi;
2183 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2189 brcmf_dbg(TRACE, "Exit\n");
2194 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2195 bool enabled, s32 timeout)
2199 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2200 struct brcmf_if *ifp = netdev_priv(ndev);
2202 brcmf_dbg(TRACE, "Enter\n");
2205 * Powersave enable/disable request is coming from the
2206 * cfg80211 even before the interface is up. In that
2207 * scenario, driver will be storing the power save
2208 * preference in cfg struct to apply this to
2209 * FW later while initializing the dongle
2211 cfg->pwr_save = enabled;
2212 if (!check_vif_up(ifp->vif)) {
2214 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2218 pm = enabled ? PM_FAST : PM_OFF;
2219 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2221 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2224 brcmf_err("net_device is not ready yet\n");
2226 brcmf_err("error (%d)\n", err);
2229 brcmf_dbg(TRACE, "Exit\n");
2233 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2234 struct brcmf_bss_info_le *bi)
2236 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2237 struct ieee80211_channel *notify_channel;
2238 struct cfg80211_bss *bss;
2239 struct ieee80211_supported_band *band;
2240 struct brcmu_chan ch;
2244 u16 notify_capability;
2245 u16 notify_interval;
2247 size_t notify_ielen;
2250 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2251 brcmf_err("Bss info is larger than buffer. Discarding\n");
2256 ch.chspec = le16_to_cpu(bi->chanspec);
2257 cfg->d11inf.decchspec(&ch);
2258 bi->ctl_ch = ch.chnum;
2260 channel = bi->ctl_ch;
2262 if (channel <= CH_MAX_2G_CHANNEL)
2263 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2265 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2267 freq = ieee80211_channel_to_frequency(channel, band->band);
2268 notify_channel = ieee80211_get_channel(wiphy, freq);
2270 notify_capability = le16_to_cpu(bi->capability);
2271 notify_interval = le16_to_cpu(bi->beacon_period);
2272 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2273 notify_ielen = le32_to_cpu(bi->ie_length);
2274 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2276 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2277 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2278 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2279 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2280 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2282 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2283 0, notify_capability, notify_interval, notify_ie,
2284 notify_ielen, notify_signal, GFP_KERNEL);
2289 cfg80211_put_bss(wiphy, bss);
2294 static struct brcmf_bss_info_le *
2295 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2298 return list->bss_info_le;
2299 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2300 le32_to_cpu(bss->length));
2303 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2305 struct brcmf_scan_results *bss_list;
2306 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2310 bss_list = cfg->bss_list;
2311 if (bss_list->count != 0 &&
2312 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2313 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2317 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2318 for (i = 0; i < bss_list->count; i++) {
2319 bi = next_bss_le(bss_list, bi);
2320 err = brcmf_inform_single_bss(cfg, bi);
2327 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2328 struct net_device *ndev, const u8 *bssid)
2330 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2331 struct ieee80211_channel *notify_channel;
2332 struct brcmf_bss_info_le *bi = NULL;
2333 struct ieee80211_supported_band *band;
2334 struct cfg80211_bss *bss;
2335 struct brcmu_chan ch;
2339 u16 notify_capability;
2340 u16 notify_interval;
2342 size_t notify_ielen;
2345 brcmf_dbg(TRACE, "Enter\n");
2347 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2353 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2355 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2356 buf, WL_BSS_INFO_MAX);
2358 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2362 bi = (struct brcmf_bss_info_le *)(buf + 4);
2364 ch.chspec = le16_to_cpu(bi->chanspec);
2365 cfg->d11inf.decchspec(&ch);
2367 if (ch.band == BRCMU_CHAN_BAND_2G)
2368 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2370 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2372 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2373 notify_channel = ieee80211_get_channel(wiphy, freq);
2375 notify_capability = le16_to_cpu(bi->capability);
2376 notify_interval = le16_to_cpu(bi->beacon_period);
2377 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2378 notify_ielen = le32_to_cpu(bi->ie_length);
2379 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2381 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2382 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2383 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2384 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2386 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2387 0, notify_capability, notify_interval,
2388 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2395 cfg80211_put_bss(wiphy, bss);
2401 brcmf_dbg(TRACE, "Exit\n");
2406 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2408 return vif->mode == WL_MODE_IBSS;
2411 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2412 struct brcmf_if *ifp)
2414 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2415 struct brcmf_bss_info_le *bi;
2416 struct brcmf_ssid *ssid;
2417 struct brcmf_tlv *tim;
2418 u16 beacon_interval;
2424 brcmf_dbg(TRACE, "Enter\n");
2425 if (brcmf_is_ibssmode(ifp->vif))
2428 ssid = &profile->ssid;
2430 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2431 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2432 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2434 brcmf_err("Could not get bss info %d\n", err);
2435 goto update_bss_info_out;
2438 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2439 err = brcmf_inform_single_bss(cfg, bi);
2441 goto update_bss_info_out;
2443 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2444 ie_len = le32_to_cpu(bi->ie_length);
2445 beacon_interval = le16_to_cpu(bi->beacon_period);
2447 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2449 dtim_period = tim->data[1];
2452 * active scan was done so we could not get dtim
2453 * information out of probe response.
2454 * so we speficially query dtim information to dongle.
2457 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2459 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2460 goto update_bss_info_out;
2462 dtim_period = (u8)var;
2465 update_bss_info_out:
2466 brcmf_dbg(TRACE, "Exit");
2470 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2472 struct escan_info *escan = &cfg->escan_info;
2474 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2475 if (cfg->scan_request) {
2476 escan->escan_state = WL_ESCAN_STATE_IDLE;
2477 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2479 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2480 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2483 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2485 struct brcmf_cfg80211_info *cfg =
2486 container_of(work, struct brcmf_cfg80211_info,
2487 escan_timeout_work);
2489 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2492 static void brcmf_escan_timeout(unsigned long data)
2494 struct brcmf_cfg80211_info *cfg =
2495 (struct brcmf_cfg80211_info *)data;
2497 if (cfg->scan_request) {
2498 brcmf_err("timer expired\n");
2499 schedule_work(&cfg->escan_timeout_work);
2504 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2505 struct brcmf_bss_info_le *bss,
2506 struct brcmf_bss_info_le *bss_info_le)
2508 struct brcmu_chan ch_bss, ch_bss_info_le;
2510 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2511 cfg->d11inf.decchspec(&ch_bss);
2512 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2513 cfg->d11inf.decchspec(&ch_bss_info_le);
2515 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2516 ch_bss.band == ch_bss_info_le.band &&
2517 bss_info_le->SSID_len == bss->SSID_len &&
2518 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2519 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2520 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2521 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2522 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2524 /* preserve max RSSI if the measurements are
2525 * both on-channel or both off-channel
2527 if (bss_info_rssi > bss_rssi)
2528 bss->RSSI = bss_info_le->RSSI;
2529 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2530 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2531 /* preserve the on-channel rssi measurement
2532 * if the new measurement is off channel
2534 bss->RSSI = bss_info_le->RSSI;
2535 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2543 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2544 const struct brcmf_event_msg *e, void *data)
2546 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2549 struct brcmf_escan_result_le *escan_result_le;
2550 struct brcmf_bss_info_le *bss_info_le;
2551 struct brcmf_bss_info_le *bss = NULL;
2553 struct brcmf_scan_results *list;
2559 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2560 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2564 if (status == BRCMF_E_STATUS_PARTIAL) {
2565 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2566 escan_result_le = (struct brcmf_escan_result_le *) data;
2567 if (!escan_result_le) {
2568 brcmf_err("Invalid escan result (NULL pointer)\n");
2571 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2572 brcmf_err("Invalid bss_count %d: ignoring\n",
2573 escan_result_le->bss_count);
2576 bss_info_le = &escan_result_le->bss_info_le;
2578 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2581 if (!cfg->scan_request) {
2582 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2586 bi_length = le32_to_cpu(bss_info_le->length);
2587 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2588 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2589 brcmf_err("Invalid bss_info length %d: ignoring\n",
2594 if (!(cfg_to_wiphy(cfg)->interface_modes &
2595 BIT(NL80211_IFTYPE_ADHOC))) {
2596 if (le16_to_cpu(bss_info_le->capability) &
2597 WLAN_CAPABILITY_IBSS) {
2598 brcmf_err("Ignoring IBSS result\n");
2603 list = (struct brcmf_scan_results *)
2604 cfg->escan_info.escan_buf;
2605 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2606 brcmf_err("Buffer is too small: ignoring\n");
2610 for (i = 0; i < list->count; i++) {
2611 bss = bss ? (struct brcmf_bss_info_le *)
2612 ((unsigned char *)bss +
2613 le32_to_cpu(bss->length)) : list->bss_info_le;
2614 if (brcmf_compare_update_same_bss(cfg, bss,
2618 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2619 bss_info_le, bi_length);
2620 list->version = le32_to_cpu(bss_info_le->version);
2621 list->buflen += bi_length;
2624 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2625 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2627 if (cfg->scan_request) {
2628 cfg->bss_list = (struct brcmf_scan_results *)
2629 cfg->escan_info.escan_buf;
2630 brcmf_inform_bss(cfg);
2631 aborted = status != BRCMF_E_STATUS_SUCCESS;
2632 brcmf_notify_escan_complete(cfg, ifp, aborted,
2635 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2642 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2644 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2645 brcmf_cfg80211_escan_handler);
2646 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2647 /* Init scan_timeout timer */
2648 init_timer(&cfg->escan_timeout);
2649 cfg->escan_timeout.data = (unsigned long) cfg;
2650 cfg->escan_timeout.function = brcmf_escan_timeout;
2651 INIT_WORK(&cfg->escan_timeout_work,
2652 brcmf_cfg80211_escan_timeout_worker);
2655 static __always_inline void brcmf_delay(u32 ms)
2657 if (ms < 1000 / HZ) {
2665 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2667 brcmf_dbg(TRACE, "Enter\n");
2672 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2673 struct cfg80211_wowlan *wow)
2675 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2676 struct net_device *ndev = cfg_to_ndev(cfg);
2677 struct brcmf_cfg80211_vif *vif;
2679 brcmf_dbg(TRACE, "Enter\n");
2682 * if the primary net_device is not READY there is nothing
2683 * we can do but pray resume goes smoothly.
2685 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2686 if (!check_vif_up(vif))
2689 list_for_each_entry(vif, &cfg->vif_list, list) {
2690 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2693 * While going to suspend if associated with AP disassociate
2694 * from AP to save power while system is in suspended state
2696 brcmf_link_down(vif);
2698 /* Make sure WPA_Supplicant receives all the event
2699 * generated due to DISASSOC call to the fw to keep
2700 * the state fw and WPA_Supplicant state consistent
2705 /* end any scanning */
2706 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2707 brcmf_abort_scanning(cfg);
2709 /* Turn off watchdog timer */
2710 brcmf_set_mpc(netdev_priv(ndev), 1);
2713 brcmf_dbg(TRACE, "Exit\n");
2714 /* clear any scanning activity */
2715 cfg->scan_status = 0;
2720 brcmf_update_pmklist(struct net_device *ndev,
2721 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2726 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2728 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2729 for (i = 0; i < pmkid_len; i++) {
2730 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2731 &pmk_list->pmkids.pmkid[i].BSSID);
2732 for (j = 0; j < WLAN_PMKID_LEN; j++)
2733 brcmf_dbg(CONN, "%02x\n",
2734 pmk_list->pmkids.pmkid[i].PMKID[j]);
2738 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2739 (char *)pmk_list, sizeof(*pmk_list));
2745 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2746 struct cfg80211_pmksa *pmksa)
2748 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2749 struct brcmf_if *ifp = netdev_priv(ndev);
2750 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2755 brcmf_dbg(TRACE, "Enter\n");
2756 if (!check_vif_up(ifp->vif))
2759 pmkid_len = le32_to_cpu(pmkids->npmkid);
2760 for (i = 0; i < pmkid_len; i++)
2761 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2763 if (i < WL_NUM_PMKIDS_MAX) {
2764 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2765 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2766 if (i == pmkid_len) {
2768 pmkids->npmkid = cpu_to_le32(pmkid_len);
2773 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2774 pmkids->pmkid[pmkid_len].BSSID);
2775 for (i = 0; i < WLAN_PMKID_LEN; i++)
2776 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2778 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2780 brcmf_dbg(TRACE, "Exit\n");
2785 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2786 struct cfg80211_pmksa *pmksa)
2788 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2789 struct brcmf_if *ifp = netdev_priv(ndev);
2790 struct pmkid_list pmkid;
2794 brcmf_dbg(TRACE, "Enter\n");
2795 if (!check_vif_up(ifp->vif))
2798 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2799 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2801 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2802 &pmkid.pmkid[0].BSSID);
2803 for (i = 0; i < WLAN_PMKID_LEN; i++)
2804 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2806 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2807 for (i = 0; i < pmkid_len; i++)
2809 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2814 && (i < pmkid_len)) {
2815 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2816 sizeof(struct pmkid));
2817 for (; i < (pmkid_len - 1); i++) {
2818 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2819 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2821 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2822 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2825 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2829 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2831 brcmf_dbg(TRACE, "Exit\n");
2837 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2839 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2840 struct brcmf_if *ifp = netdev_priv(ndev);
2843 brcmf_dbg(TRACE, "Enter\n");
2844 if (!check_vif_up(ifp->vif))
2847 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2848 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2850 brcmf_dbg(TRACE, "Exit\n");
2856 * PFN result doesn't have all the info which are
2857 * required by the supplicant
2858 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2859 * via wl_inform_single_bss in the required format. Escan does require the
2860 * scan request in the form of cfg80211_scan_request. For timebeing, create
2861 * cfg80211_scan_request one out of the received PNO event.
2864 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2865 const struct brcmf_event_msg *e, void *data)
2867 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2868 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2869 struct cfg80211_scan_request *request = NULL;
2870 struct cfg80211_ssid *ssid = NULL;
2871 struct ieee80211_channel *channel = NULL;
2872 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2874 int channel_req = 0;
2876 struct brcmf_pno_scanresults_le *pfn_result;
2880 brcmf_dbg(SCAN, "Enter\n");
2882 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2883 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2887 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2888 result_count = le32_to_cpu(pfn_result->count);
2889 status = le32_to_cpu(pfn_result->status);
2892 * PFN event is limited to fit 512 bytes so we may get
2893 * multiple NET_FOUND events. For now place a warning here.
2895 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2896 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2897 if (result_count > 0) {
2900 request = kzalloc(sizeof(*request), GFP_KERNEL);
2901 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2902 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2903 if (!request || !ssid || !channel) {
2908 request->wiphy = wiphy;
2909 data += sizeof(struct brcmf_pno_scanresults_le);
2910 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2912 for (i = 0; i < result_count; i++) {
2913 netinfo = &netinfo_start[i];
2915 brcmf_err("Invalid netinfo ptr. index: %d\n",
2921 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2922 netinfo->SSID, netinfo->channel);
2923 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2924 ssid[i].ssid_len = netinfo->SSID_len;
2927 channel_req = netinfo->channel;
2928 if (channel_req <= CH_MAX_2G_CHANNEL)
2929 band = NL80211_BAND_2GHZ;
2931 band = NL80211_BAND_5GHZ;
2932 channel[i].center_freq =
2933 ieee80211_channel_to_frequency(channel_req,
2935 channel[i].band = band;
2936 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2937 request->channels[i] = &channel[i];
2938 request->n_channels++;
2941 /* assign parsed ssid array */
2942 if (request->n_ssids)
2943 request->ssids = &ssid[0];
2945 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2946 /* Abort any on-going scan */
2947 brcmf_abort_scanning(cfg);
2950 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2951 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2953 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2956 cfg->sched_escan = true;
2957 cfg->scan_request = request;
2959 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2972 cfg80211_sched_scan_stopped(wiphy);
2976 static int brcmf_dev_pno_clean(struct net_device *ndev)
2981 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2984 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2988 brcmf_err("failed code %d\n", ret);
2993 static int brcmf_dev_pno_config(struct net_device *ndev)
2995 struct brcmf_pno_param_le pfn_param;
2997 memset(&pfn_param, 0, sizeof(pfn_param));
2998 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3000 /* set extra pno params */
3001 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3002 pfn_param.repeat = BRCMF_PNO_REPEAT;
3003 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3005 /* set up pno scan fr */
3006 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3008 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3009 &pfn_param, sizeof(pfn_param));
3013 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3014 struct net_device *ndev,
3015 struct cfg80211_sched_scan_request *request)
3017 struct brcmf_if *ifp = netdev_priv(ndev);
3018 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3019 struct brcmf_pno_net_param_le pfn;
3023 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3024 request->n_match_sets, request->n_ssids);
3025 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3026 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3029 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3030 brcmf_err("Scanning suppressed: status (%lu)\n",
3035 if (!request->n_ssids || !request->n_match_sets) {
3036 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3041 if (request->n_ssids > 0) {
3042 for (i = 0; i < request->n_ssids; i++) {
3043 /* Active scan req for ssids */
3044 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3045 request->ssids[i].ssid);
3048 * match_set ssids is a supert set of n_ssid list,
3049 * so we need not add these set seperately.
3054 if (request->n_match_sets > 0) {
3055 /* clean up everything */
3056 ret = brcmf_dev_pno_clean(ndev);
3058 brcmf_err("failed error=%d\n", ret);
3063 ret = brcmf_dev_pno_config(ndev);
3065 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3069 /* configure each match set */
3070 for (i = 0; i < request->n_match_sets; i++) {
3071 struct cfg80211_ssid *ssid;
3074 ssid = &request->match_sets[i].ssid;
3075 ssid_len = ssid->ssid_len;
3078 brcmf_err("skip broadcast ssid\n");
3081 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3082 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3083 pfn.wsec = cpu_to_le32(0);
3084 pfn.infra = cpu_to_le32(1);
3085 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3086 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3087 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3088 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3090 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3091 ret == 0 ? "set" : "failed", ssid->ssid);
3093 /* Enable the PNO */
3094 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3095 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3105 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3106 struct net_device *ndev)
3108 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3110 brcmf_dbg(SCAN, "enter\n");
3111 brcmf_dev_pno_clean(ndev);
3112 if (cfg->sched_escan)
3113 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3117 #ifdef CONFIG_NL80211_TESTMODE
3118 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3120 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3121 struct net_device *ndev = cfg_to_ndev(cfg);
3122 struct brcmf_dcmd *dcmd = data;
3123 struct sk_buff *reply;
3126 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3127 dcmd->buf, dcmd->len);
3130 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3131 dcmd->buf, dcmd->len);
3133 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3134 dcmd->buf, dcmd->len);
3136 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3137 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3138 ret = cfg80211_testmode_reply(reply);
3144 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3149 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3151 brcmf_err("auth error %d\n", err);
3155 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3157 brcmf_err("wsec error %d\n", err);
3160 /* set upper-layer auth */
3161 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3163 brcmf_err("wpa_auth error %d\n", err);
3170 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3173 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3175 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3179 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3182 struct brcmf_if *ifp = netdev_priv(ndev);
3183 u32 auth = 0; /* d11 open authentication */
3195 u32 wme_bss_disable;
3197 brcmf_dbg(TRACE, "Enter\n");
3201 len = wpa_ie->len + TLV_HDR_LEN;
3202 data = (u8 *)wpa_ie;
3203 offset = TLV_HDR_LEN;
3205 offset += VS_IE_FIXED_HDR_LEN;
3207 offset += WPA_IE_VERSION_LEN;
3209 /* check for multicast cipher suite */
3210 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3212 brcmf_err("no multicast cipher suite\n");
3216 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3218 brcmf_err("ivalid OUI\n");
3221 offset += TLV_OUI_LEN;
3223 /* pick up multicast cipher */
3224 switch (data[offset]) {
3225 case WPA_CIPHER_NONE:
3228 case WPA_CIPHER_WEP_40:
3229 case WPA_CIPHER_WEP_104:
3232 case WPA_CIPHER_TKIP:
3233 gval = TKIP_ENABLED;
3235 case WPA_CIPHER_AES_CCM:
3240 brcmf_err("Invalid multi cast cipher info\n");
3245 /* walk thru unicast cipher list and pick up what we recognize */
3246 count = data[offset] + (data[offset + 1] << 8);
3247 offset += WPA_IE_SUITE_COUNT_LEN;
3248 /* Check for unicast suite(s) */
3249 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3251 brcmf_err("no unicast cipher suite\n");
3254 for (i = 0; i < count; i++) {
3255 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3257 brcmf_err("ivalid OUI\n");
3260 offset += TLV_OUI_LEN;
3261 switch (data[offset]) {
3262 case WPA_CIPHER_NONE:
3264 case WPA_CIPHER_WEP_40:
3265 case WPA_CIPHER_WEP_104:
3266 pval |= WEP_ENABLED;
3268 case WPA_CIPHER_TKIP:
3269 pval |= TKIP_ENABLED;
3271 case WPA_CIPHER_AES_CCM:
3272 pval |= AES_ENABLED;
3275 brcmf_err("Ivalid unicast security info\n");
3279 /* walk thru auth management suite list and pick up what we recognize */
3280 count = data[offset] + (data[offset + 1] << 8);
3281 offset += WPA_IE_SUITE_COUNT_LEN;
3282 /* Check for auth key management suite(s) */
3283 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3285 brcmf_err("no auth key mgmt suite\n");
3288 for (i = 0; i < count; i++) {
3289 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3291 brcmf_err("ivalid OUI\n");
3294 offset += TLV_OUI_LEN;
3295 switch (data[offset]) {
3297 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3298 wpa_auth |= WPA_AUTH_NONE;
3300 case RSN_AKM_UNSPECIFIED:
3301 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3302 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3303 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3306 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3307 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3308 (wpa_auth |= WPA_AUTH_PSK);
3311 brcmf_err("Ivalid key mgmt info\n");
3317 wme_bss_disable = 1;
3318 if ((offset + RSN_CAP_LEN) <= len) {
3319 rsn_cap = data[offset] + (data[offset + 1] << 8);
3320 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3321 wme_bss_disable = 0;
3323 /* set wme_bss_disable to sync RSN Capabilities */
3324 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3327 brcmf_err("wme_bss_disable error %d\n", err);
3331 /* FOR WPS , set SES_OW_ENABLED */
3332 wsec = (pval | gval | SES_OW_ENABLED);
3335 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3337 brcmf_err("auth error %d\n", err);
3341 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3343 brcmf_err("wsec error %d\n", err);
3346 /* set upper-layer auth */
3347 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3349 brcmf_err("wpa_auth error %d\n", err);
3358 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3359 struct parsed_vndr_ies *vndr_ies)
3362 struct brcmf_vs_tlv *vndrie;
3363 struct brcmf_tlv *ie;
3364 struct parsed_vndr_ie_info *parsed_info;
3367 remaining_len = (s32)vndr_ie_len;
3368 memset(vndr_ies, 0, sizeof(*vndr_ies));
3370 ie = (struct brcmf_tlv *)vndr_ie_buf;
3372 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3374 vndrie = (struct brcmf_vs_tlv *)ie;
3375 /* len should be bigger than OUI length + one */
3376 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3377 brcmf_err("invalid vndr ie. length is too small %d\n",
3381 /* if wpa or wme ie, do not add ie */
3382 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3383 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3384 (vndrie->oui_type == WME_OUI_TYPE))) {
3385 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3389 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3391 /* save vndr ie information */
3392 parsed_info->ie_ptr = (char *)vndrie;
3393 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3394 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3398 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3399 parsed_info->vndrie.oui[0],
3400 parsed_info->vndrie.oui[1],
3401 parsed_info->vndrie.oui[2],
3402 parsed_info->vndrie.oui_type);
3404 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3407 remaining_len -= (ie->len + TLV_HDR_LEN);
3408 if (remaining_len <= TLV_HDR_LEN)
3411 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3418 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3424 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3425 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3427 iecount_le = cpu_to_le32(1);
3428 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3430 pktflag_le = cpu_to_le32(pktflag);
3431 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3433 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3435 return ie_len + VNDR_IE_HDR_SIZE;
3438 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3439 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3441 struct brcmf_if *ifp;
3442 struct vif_saved_ie *saved_ie;
3446 u8 *mgmt_ie_buf = NULL;
3447 int mgmt_ie_buf_len;
3449 u32 del_add_ie_buf_len = 0;
3450 u32 total_ie_buf_len = 0;
3451 u32 parsed_ie_buf_len = 0;
3452 struct parsed_vndr_ies old_vndr_ies;
3453 struct parsed_vndr_ies new_vndr_ies;
3454 struct parsed_vndr_ie_info *vndrie_info;
3457 int remained_buf_len;
3462 saved_ie = &vif->saved_ie;
3464 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3465 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3468 curr_ie_buf = iovar_ie_buf;
3470 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3471 mgmt_ie_buf = saved_ie->probe_req_ie;
3472 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3473 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3475 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3476 mgmt_ie_buf = saved_ie->probe_res_ie;
3477 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3478 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3480 case BRCMF_VNDR_IE_BEACON_FLAG:
3481 mgmt_ie_buf = saved_ie->beacon_ie;
3482 mgmt_ie_len = &saved_ie->beacon_ie_len;
3483 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3485 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3486 mgmt_ie_buf = saved_ie->assoc_req_ie;
3487 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3488 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3492 brcmf_err("not suitable type\n");
3496 if (vndr_ie_len > mgmt_ie_buf_len) {
3498 brcmf_err("extra IE size too big\n");
3502 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3503 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3505 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3506 for (i = 0; i < new_vndr_ies.count; i++) {
3507 vndrie_info = &new_vndr_ies.ie_info[i];
3508 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3509 vndrie_info->ie_len);
3510 parsed_ie_buf_len += vndrie_info->ie_len;
3514 if (mgmt_ie_buf && *mgmt_ie_len) {
3515 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3516 (memcmp(mgmt_ie_buf, curr_ie_buf,
3517 parsed_ie_buf_len) == 0)) {
3518 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3522 /* parse old vndr_ie */
3523 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3525 /* make a command to delete old ie */
3526 for (i = 0; i < old_vndr_ies.count; i++) {
3527 vndrie_info = &old_vndr_ies.ie_info[i];
3529 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3530 vndrie_info->vndrie.id,
3531 vndrie_info->vndrie.len,
3532 vndrie_info->vndrie.oui[0],
3533 vndrie_info->vndrie.oui[1],
3534 vndrie_info->vndrie.oui[2]);
3536 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3537 vndrie_info->ie_ptr,
3538 vndrie_info->ie_len,
3540 curr_ie_buf += del_add_ie_buf_len;
3541 total_ie_buf_len += del_add_ie_buf_len;
3546 /* Add if there is any extra IE */
3547 if (mgmt_ie_buf && parsed_ie_buf_len) {
3550 remained_buf_len = mgmt_ie_buf_len;
3552 /* make a command to add new ie */
3553 for (i = 0; i < new_vndr_ies.count; i++) {
3554 vndrie_info = &new_vndr_ies.ie_info[i];
3556 /* verify remained buf size before copy data */
3557 if (remained_buf_len < (vndrie_info->vndrie.len +
3558 VNDR_IE_VSIE_OFFSET)) {
3559 brcmf_err("no space in mgmt_ie_buf: len left %d",
3563 remained_buf_len -= (vndrie_info->ie_len +
3564 VNDR_IE_VSIE_OFFSET);
3566 brcmf_dbg(TRACE, "ADDED 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,
3578 /* save the parsed IE in wl struct */
3579 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3580 vndrie_info->ie_len);
3581 *mgmt_ie_len += vndrie_info->ie_len;
3583 curr_ie_buf += del_add_ie_buf_len;
3584 total_ie_buf_len += del_add_ie_buf_len;
3587 if (total_ie_buf_len) {
3588 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3591 brcmf_err("vndr ie set error : %d\n", err);
3595 kfree(iovar_ie_buf);
3599 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3602 BRCMF_VNDR_IE_PRBREQ_FLAG,
3603 BRCMF_VNDR_IE_PRBRSP_FLAG,
3604 BRCMF_VNDR_IE_BEACON_FLAG
3608 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3609 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3611 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3616 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3617 struct cfg80211_beacon_data *beacon)
3621 /* Set Beacon IEs to FW */
3622 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3623 beacon->tail, beacon->tail_len);
3625 brcmf_err("Set Beacon IE Failed\n");
3628 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3630 /* Set Probe Response IEs to FW */
3631 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3632 beacon->proberesp_ies,
3633 beacon->proberesp_ies_len);
3635 brcmf_err("Set Probe Resp IE Failed\n");
3637 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3643 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3644 struct cfg80211_ap_settings *settings)
3647 struct brcmf_if *ifp = netdev_priv(ndev);
3648 struct brcmf_tlv *ssid_ie;
3649 struct brcmf_ssid_le ssid_le;
3651 struct brcmf_tlv *rsn_ie;
3652 struct brcmf_vs_tlv *wpa_ie;
3653 struct brcmf_join_params join_params;
3654 enum nl80211_iftype dev_role;
3655 struct brcmf_fil_bss_enable_le bss_enable;
3657 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3658 cfg80211_get_chandef_type(&settings->chandef),
3659 settings->beacon_interval,
3660 settings->dtim_period);
3661 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3662 settings->ssid, settings->ssid_len, settings->auth_type,
3663 settings->inactivity_timeout);
3665 dev_role = ifp->vif->wdev.iftype;
3667 memset(&ssid_le, 0, sizeof(ssid_le));
3668 if (settings->ssid == NULL || settings->ssid_len == 0) {
3669 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3670 ssid_ie = brcmf_parse_tlvs(
3671 (u8 *)&settings->beacon.head[ie_offset],
3672 settings->beacon.head_len - ie_offset,
3677 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3678 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3679 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3681 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3682 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3685 brcmf_set_mpc(ifp, 0);
3687 /* find the RSN_IE */
3688 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3689 settings->beacon.tail_len, WLAN_EID_RSN);
3691 /* find the WPA_IE */
3692 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3693 settings->beacon.tail_len);
3695 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3696 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3697 if (wpa_ie != NULL) {
3699 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3704 err = brcmf_configure_wpaie(ndev,
3705 (struct brcmf_vs_tlv *)rsn_ie, true);
3710 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3711 brcmf_configure_opensecurity(ifp);
3714 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3716 if (settings->beacon_interval) {
3717 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3718 settings->beacon_interval);
3720 brcmf_err("Beacon Interval Set Error, %d\n", err);
3724 if (settings->dtim_period) {
3725 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3726 settings->dtim_period);
3728 brcmf_err("DTIM Interval Set Error, %d\n", err);
3733 if (dev_role == NL80211_IFTYPE_AP) {
3734 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3736 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3739 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3742 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3744 brcmf_err("SET INFRA error %d\n", err);
3747 if (dev_role == NL80211_IFTYPE_AP) {
3748 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3750 brcmf_err("setting AP mode failed %d\n", err);
3753 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3755 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3759 memset(&join_params, 0, sizeof(join_params));
3760 /* join parameters starts with ssid */
3761 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3763 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3764 &join_params, sizeof(join_params));
3766 brcmf_err("SET SSID error (%d)\n", err);
3769 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3771 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3774 brcmf_err("setting ssid failed %d\n", err);
3777 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3778 bss_enable.enable = cpu_to_le32(1);
3779 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3780 sizeof(bss_enable));
3782 brcmf_err("bss_enable config failed %d\n", err);
3786 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3788 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3789 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3793 brcmf_set_mpc(ifp, 1);
3797 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3799 struct brcmf_if *ifp = netdev_priv(ndev);
3801 struct brcmf_fil_bss_enable_le bss_enable;
3802 struct brcmf_join_params join_params;
3804 brcmf_dbg(TRACE, "Enter\n");
3806 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3807 /* Due to most likely deauths outstanding we sleep */
3808 /* first to make sure they get processed by fw. */
3811 memset(&join_params, 0, sizeof(join_params));
3812 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3813 &join_params, sizeof(join_params));
3815 brcmf_err("SET SSID error (%d)\n", err);
3816 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3818 brcmf_err("BRCMF_C_UP error %d\n", err);
3819 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3821 brcmf_err("setting AP mode failed %d\n", err);
3822 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3824 brcmf_err("setting INFRA mode failed %d\n", err);
3826 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3827 bss_enable.enable = cpu_to_le32(0);
3828 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3829 sizeof(bss_enable));
3831 brcmf_err("bss_enable config failed %d\n", err);
3833 brcmf_set_mpc(ifp, 1);
3834 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3835 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3841 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3842 struct cfg80211_beacon_data *info)
3844 struct brcmf_if *ifp = netdev_priv(ndev);
3847 brcmf_dbg(TRACE, "Enter\n");
3849 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3855 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3858 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3859 struct brcmf_scb_val_le scbval;
3860 struct brcmf_if *ifp = netdev_priv(ndev);
3866 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3868 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3869 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3870 if (!check_vif_up(ifp->vif))
3873 memcpy(&scbval.ea, mac, ETH_ALEN);
3874 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3875 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3876 &scbval, sizeof(scbval));
3878 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3880 brcmf_dbg(TRACE, "Exit\n");
3886 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3887 struct wireless_dev *wdev,
3888 u16 frame_type, bool reg)
3890 struct brcmf_cfg80211_vif *vif;
3893 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3895 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3896 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3898 vif->mgmt_rx_reg |= BIT(mgmt_type);
3900 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3905 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3906 struct ieee80211_channel *chan, bool offchan,
3907 unsigned int wait, const u8 *buf, size_t len,
3908 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
3910 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3911 const struct ieee80211_mgmt *mgmt;
3912 struct brcmf_cfg80211_vif *vif;
3916 struct brcmf_fil_action_frame_le *action_frame;
3917 struct brcmf_fil_af_params_le *af_params;
3921 brcmf_dbg(TRACE, "Enter\n");
3925 mgmt = (const struct ieee80211_mgmt *)buf;
3927 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
3928 brcmf_err("Driver only allows MGMT packet type\n");
3932 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
3933 /* Right now the only reason to get a probe response */
3934 /* is for p2p listen response or for p2p GO from */
3935 /* wpa_supplicant. Unfortunately the probe is send */
3936 /* on primary ndev, while dongle wants it on the p2p */
3937 /* vif. Since this is only reason for a probe */
3938 /* response to be sent, the vif is taken from cfg. */
3939 /* If ever desired to send proberesp for non p2p */
3940 /* response then data should be checked for */
3941 /* "DIRECT-". Note in future supplicant will take */
3942 /* dedicated p2p wdev to do this and then this 'hack'*/
3943 /* is not needed anymore. */
3944 ie_offset = DOT11_MGMT_HDR_LEN +
3945 DOT11_BCN_PRB_FIXED_LEN;
3946 ie_len = len - ie_offset;
3947 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3948 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
3949 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
3950 err = brcmf_vif_set_mgmt_ie(vif,
3951 BRCMF_VNDR_IE_PRBRSP_FLAG,
3954 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
3956 } else if (ieee80211_is_action(mgmt->frame_control)) {
3957 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
3958 if (af_params == NULL) {
3959 brcmf_err("unable to allocate frame\n");
3963 action_frame = &af_params->action_frame;
3964 /* Add the packet Id */
3965 action_frame->packet_id = cpu_to_le32(*cookie);
3967 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
3968 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
3969 /* Add the length exepted for 802.11 header */
3970 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
3971 /* Add the channel */
3972 chan_nr = ieee80211_frequency_to_channel(chan->center_freq);
3973 af_params->channel = cpu_to_le32(chan_nr);
3975 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
3976 le16_to_cpu(action_frame->len));
3978 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
3979 *cookie, le16_to_cpu(action_frame->len),
3982 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
3985 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
3989 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
3990 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
3999 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4000 struct wireless_dev *wdev,
4003 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4004 struct brcmf_cfg80211_vif *vif;
4007 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4009 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4011 brcmf_err("No p2p device available for probe response\n");
4015 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4020 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4021 struct wireless_dev *wdev,
4022 enum nl80211_crit_proto_id proto,
4025 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4026 struct brcmf_cfg80211_vif *vif;
4028 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4030 /* only DHCP support for now */
4031 if (proto != NL80211_CRIT_PROTO_DHCP)
4034 /* suppress and abort scanning */
4035 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4036 brcmf_abort_scanning(cfg);
4038 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4041 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4042 struct wireless_dev *wdev)
4044 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4045 struct brcmf_cfg80211_vif *vif;
4047 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4049 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4050 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4053 static struct cfg80211_ops wl_cfg80211_ops = {
4054 .add_virtual_intf = brcmf_cfg80211_add_iface,
4055 .del_virtual_intf = brcmf_cfg80211_del_iface,
4056 .change_virtual_intf = brcmf_cfg80211_change_iface,
4057 .scan = brcmf_cfg80211_scan,
4058 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4059 .join_ibss = brcmf_cfg80211_join_ibss,
4060 .leave_ibss = brcmf_cfg80211_leave_ibss,
4061 .get_station = brcmf_cfg80211_get_station,
4062 .set_tx_power = brcmf_cfg80211_set_tx_power,
4063 .get_tx_power = brcmf_cfg80211_get_tx_power,
4064 .add_key = brcmf_cfg80211_add_key,
4065 .del_key = brcmf_cfg80211_del_key,
4066 .get_key = brcmf_cfg80211_get_key,
4067 .set_default_key = brcmf_cfg80211_config_default_key,
4068 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4069 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4070 .connect = brcmf_cfg80211_connect,
4071 .disconnect = brcmf_cfg80211_disconnect,
4072 .suspend = brcmf_cfg80211_suspend,
4073 .resume = brcmf_cfg80211_resume,
4074 .set_pmksa = brcmf_cfg80211_set_pmksa,
4075 .del_pmksa = brcmf_cfg80211_del_pmksa,
4076 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4077 .start_ap = brcmf_cfg80211_start_ap,
4078 .stop_ap = brcmf_cfg80211_stop_ap,
4079 .change_beacon = brcmf_cfg80211_change_beacon,
4080 .del_station = brcmf_cfg80211_del_station,
4081 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4082 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4083 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4084 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4085 .remain_on_channel = brcmf_p2p_remain_on_channel,
4086 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4087 .start_p2p_device = brcmf_p2p_start_device,
4088 .stop_p2p_device = brcmf_p2p_stop_device,
4089 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4090 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4091 #ifdef CONFIG_NL80211_TESTMODE
4092 .testmode_cmd = brcmf_cfg80211_testmode
4096 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4099 case NL80211_IFTYPE_AP_VLAN:
4100 case NL80211_IFTYPE_WDS:
4101 case NL80211_IFTYPE_MONITOR:
4102 case NL80211_IFTYPE_MESH_POINT:
4104 case NL80211_IFTYPE_ADHOC:
4105 return WL_MODE_IBSS;
4106 case NL80211_IFTYPE_STATION:
4107 case NL80211_IFTYPE_P2P_CLIENT:
4109 case NL80211_IFTYPE_AP:
4110 case NL80211_IFTYPE_P2P_GO:
4112 case NL80211_IFTYPE_P2P_DEVICE:
4114 case NL80211_IFTYPE_UNSPECIFIED:
4122 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4124 /* scheduled scan settings */
4125 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4126 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4127 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4128 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4131 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4134 .types = BIT(NL80211_IFTYPE_STATION) |
4135 BIT(NL80211_IFTYPE_ADHOC) |
4136 BIT(NL80211_IFTYPE_AP)
4140 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4141 BIT(NL80211_IFTYPE_P2P_GO)
4144 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4146 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4147 .num_different_channels = 1, /* no multi-channel for now */
4148 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4149 .limits = brcmf_iface_limits
4153 static const struct ieee80211_txrx_stypes
4154 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4155 [NL80211_IFTYPE_STATION] = {
4157 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4158 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4160 [NL80211_IFTYPE_P2P_CLIENT] = {
4162 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4163 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4165 [NL80211_IFTYPE_P2P_GO] = {
4167 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4168 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4169 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4170 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4171 BIT(IEEE80211_STYPE_AUTH >> 4) |
4172 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4173 BIT(IEEE80211_STYPE_ACTION >> 4)
4175 [NL80211_IFTYPE_P2P_DEVICE] = {
4177 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4178 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4182 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4184 struct wiphy *wiphy;
4187 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4189 brcmf_err("Could not allocate wiphy device\n");
4190 return ERR_PTR(-ENOMEM);
4192 set_wiphy_dev(wiphy, phydev);
4193 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4194 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4195 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4196 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4197 BIT(NL80211_IFTYPE_ADHOC) |
4198 BIT(NL80211_IFTYPE_AP) |
4199 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4200 BIT(NL80211_IFTYPE_P2P_GO);
4201 wiphy->iface_combinations = brcmf_iface_combos;
4202 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4203 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4204 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4205 wiphy->cipher_suites = __wl_cipher_suites;
4206 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4207 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4208 WIPHY_FLAG_OFFCHAN_TX |
4209 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
4210 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4211 wiphy->max_remain_on_channel_duration = 5000;
4212 brcmf_wiphy_pno_params(wiphy);
4213 brcmf_dbg(INFO, "Registering custom regulatory\n");
4214 wiphy->flags |= WIPHY_FLAG_CUSTOM_REGULATORY;
4215 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4216 err = wiphy_register(wiphy);
4218 brcmf_err("Could not register wiphy device (%d)\n", err);
4220 return ERR_PTR(err);
4225 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4226 enum nl80211_iftype type,
4229 struct brcmf_cfg80211_vif *vif;
4231 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4232 return ERR_PTR(-ENOSPC);
4234 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4236 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4238 return ERR_PTR(-ENOMEM);
4240 vif->wdev.wiphy = cfg->wiphy;
4241 vif->wdev.iftype = type;
4243 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4244 vif->pm_block = pm_block;
4247 brcmf_init_prof(&vif->profile);
4249 list_add_tail(&vif->list, &cfg->vif_list);
4254 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4256 struct brcmf_cfg80211_info *cfg;
4257 struct wiphy *wiphy;
4259 wiphy = vif->wdev.wiphy;
4260 cfg = wiphy_priv(wiphy);
4261 list_del(&vif->list);
4265 if (!cfg->vif_cnt) {
4266 wiphy_unregister(wiphy);
4271 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4273 u32 event = e->event_code;
4274 u32 status = e->status;
4276 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4277 brcmf_dbg(CONN, "Processing set ssid\n");
4284 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4286 u32 event = e->event_code;
4287 u16 flags = e->flags;
4289 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4290 brcmf_dbg(CONN, "Processing link down\n");
4296 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4297 const struct brcmf_event_msg *e)
4299 u32 event = e->event_code;
4300 u32 status = e->status;
4302 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4303 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4304 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4308 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4309 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4316 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4318 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4320 kfree(conn_info->req_ie);
4321 conn_info->req_ie = NULL;
4322 conn_info->req_ie_len = 0;
4323 kfree(conn_info->resp_ie);
4324 conn_info->resp_ie = NULL;
4325 conn_info->resp_ie_len = 0;
4328 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4329 struct brcmf_if *ifp)
4331 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4332 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4337 brcmf_clear_assoc_ies(cfg);
4339 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4340 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4342 brcmf_err("could not get assoc info (%d)\n", err);
4346 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4347 req_len = le32_to_cpu(assoc_info->req_len);
4348 resp_len = le32_to_cpu(assoc_info->resp_len);
4350 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4354 brcmf_err("could not get assoc req (%d)\n", err);
4357 conn_info->req_ie_len = req_len;
4359 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4362 conn_info->req_ie_len = 0;
4363 conn_info->req_ie = NULL;
4366 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4370 brcmf_err("could not get assoc resp (%d)\n", err);
4373 conn_info->resp_ie_len = resp_len;
4374 conn_info->resp_ie =
4375 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4378 conn_info->resp_ie_len = 0;
4379 conn_info->resp_ie = NULL;
4381 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4382 conn_info->req_ie_len, conn_info->resp_ie_len);
4388 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4389 struct net_device *ndev,
4390 const struct brcmf_event_msg *e)
4392 struct brcmf_if *ifp = netdev_priv(ndev);
4393 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4394 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4395 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4396 struct ieee80211_channel *notify_channel = NULL;
4397 struct ieee80211_supported_band *band;
4398 struct brcmf_bss_info_le *bi;
4399 struct brcmu_chan ch;
4404 brcmf_dbg(TRACE, "Enter\n");
4406 brcmf_get_assoc_ies(cfg, ifp);
4407 memcpy(profile->bssid, e->addr, ETH_ALEN);
4408 brcmf_update_bss_info(cfg, ifp);
4410 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4416 /* data sent to dongle has to be little endian */
4417 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4418 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4419 buf, WL_BSS_INFO_MAX);
4424 bi = (struct brcmf_bss_info_le *)(buf + 4);
4425 ch.chspec = le16_to_cpu(bi->chanspec);
4426 cfg->d11inf.decchspec(&ch);
4428 if (ch.band == BRCMU_CHAN_BAND_2G)
4429 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4431 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4433 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4434 notify_channel = ieee80211_get_channel(wiphy, freq);
4438 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4439 conn_info->req_ie, conn_info->req_ie_len,
4440 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4441 brcmf_dbg(CONN, "Report roaming result\n");
4443 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4444 brcmf_dbg(TRACE, "Exit\n");
4449 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4450 struct net_device *ndev, const struct brcmf_event_msg *e,
4453 struct brcmf_if *ifp = netdev_priv(ndev);
4454 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4455 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4458 brcmf_dbg(TRACE, "Enter\n");
4460 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4461 &ifp->vif->sme_state)) {
4463 brcmf_get_assoc_ies(cfg, ifp);
4464 memcpy(profile->bssid, e->addr, ETH_ALEN);
4465 brcmf_update_bss_info(cfg, ifp);
4466 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4467 &ifp->vif->sme_state);
4469 cfg80211_connect_result(ndev,
4470 (u8 *)profile->bssid,
4472 conn_info->req_ie_len,
4474 conn_info->resp_ie_len,
4475 completed ? WLAN_STATUS_SUCCESS :
4476 WLAN_STATUS_AUTH_TIMEOUT,
4478 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4479 completed ? "succeeded" : "failed");
4481 brcmf_dbg(TRACE, "Exit\n");
4486 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4487 struct net_device *ndev,
4488 const struct brcmf_event_msg *e, void *data)
4490 static int generation;
4491 u32 event = e->event_code;
4492 u32 reason = e->reason;
4493 struct station_info sinfo;
4495 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4496 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4497 ndev != cfg_to_ndev(cfg)) {
4498 brcmf_dbg(CONN, "AP mode link down\n");
4499 complete(&cfg->vif_disabled);
4503 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4504 (reason == BRCMF_E_STATUS_SUCCESS)) {
4505 memset(&sinfo, 0, sizeof(sinfo));
4506 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4508 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4511 sinfo.assoc_req_ies = data;
4512 sinfo.assoc_req_ies_len = e->datalen;
4514 sinfo.generation = generation;
4515 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4516 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4517 (event == BRCMF_E_DEAUTH_IND) ||
4518 (event == BRCMF_E_DEAUTH)) {
4519 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4525 brcmf_notify_connect_status(struct brcmf_if *ifp,
4526 const struct brcmf_event_msg *e, void *data)
4528 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4529 struct net_device *ndev = ifp->ndev;
4530 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4533 if (ifp->vif->mode == WL_MODE_AP) {
4534 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4535 } else if (brcmf_is_linkup(e)) {
4536 brcmf_dbg(CONN, "Linkup\n");
4537 if (brcmf_is_ibssmode(ifp->vif)) {
4538 memcpy(profile->bssid, e->addr, ETH_ALEN);
4539 wl_inform_ibss(cfg, ndev, e->addr);
4540 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4541 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4542 &ifp->vif->sme_state);
4543 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4544 &ifp->vif->sme_state);
4546 brcmf_bss_connect_done(cfg, ndev, e, true);
4547 } else if (brcmf_is_linkdown(e)) {
4548 brcmf_dbg(CONN, "Linkdown\n");
4549 if (!brcmf_is_ibssmode(ifp->vif)) {
4550 brcmf_bss_connect_done(cfg, ndev, e, false);
4551 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4552 &ifp->vif->sme_state))
4553 cfg80211_disconnected(ndev, 0, NULL, 0,
4556 brcmf_link_down(ifp->vif);
4557 brcmf_init_prof(ndev_to_prof(ndev));
4558 if (ndev != cfg_to_ndev(cfg))
4559 complete(&cfg->vif_disabled);
4560 } else if (brcmf_is_nonetwork(cfg, e)) {
4561 if (brcmf_is_ibssmode(ifp->vif))
4562 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4563 &ifp->vif->sme_state);
4565 brcmf_bss_connect_done(cfg, ndev, e, false);
4572 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4573 const struct brcmf_event_msg *e, void *data)
4575 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4577 u32 event = e->event_code;
4578 u32 status = e->status;
4580 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4581 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4582 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4584 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4591 brcmf_notify_mic_status(struct brcmf_if *ifp,
4592 const struct brcmf_event_msg *e, void *data)
4594 u16 flags = e->flags;
4595 enum nl80211_key_type key_type;
4597 if (flags & BRCMF_EVENT_MSG_GROUP)
4598 key_type = NL80211_KEYTYPE_GROUP;
4600 key_type = NL80211_KEYTYPE_PAIRWISE;
4602 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4608 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4609 const struct brcmf_event_msg *e, void *data)
4611 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4612 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4613 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4614 struct brcmf_cfg80211_vif *vif;
4616 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4617 ifevent->action, ifevent->flags, ifevent->ifidx,
4620 mutex_lock(&event->vif_event_lock);
4621 event->action = ifevent->action;
4624 switch (ifevent->action) {
4625 case BRCMF_E_IF_ADD:
4626 /* waiting process may have timed out */
4627 if (!cfg->vif_event.vif) {
4628 mutex_unlock(&event->vif_event_lock);
4635 vif->wdev.netdev = ifp->ndev;
4636 ifp->ndev->ieee80211_ptr = &vif->wdev;
4637 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4639 mutex_unlock(&event->vif_event_lock);
4640 wake_up(&event->vif_wq);
4643 case BRCMF_E_IF_DEL:
4645 mutex_unlock(&event->vif_event_lock);
4646 /* event may not be upon user request */
4647 if (brcmf_cfg80211_vif_event_armed(cfg))
4648 wake_up(&event->vif_wq);
4651 case BRCMF_E_IF_CHANGE:
4652 mutex_unlock(&event->vif_event_lock);
4653 wake_up(&event->vif_wq);
4657 mutex_unlock(&event->vif_event_lock);
4663 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4665 conf->frag_threshold = (u32)-1;
4666 conf->rts_threshold = (u32)-1;
4667 conf->retry_short = (u32)-1;
4668 conf->retry_long = (u32)-1;
4669 conf->tx_power = -1;
4672 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4674 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4675 brcmf_notify_connect_status);
4676 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4677 brcmf_notify_connect_status);
4678 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4679 brcmf_notify_connect_status);
4680 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4681 brcmf_notify_connect_status);
4682 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4683 brcmf_notify_connect_status);
4684 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4685 brcmf_notify_connect_status);
4686 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4687 brcmf_notify_roaming_status);
4688 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4689 brcmf_notify_mic_status);
4690 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4691 brcmf_notify_connect_status);
4692 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4693 brcmf_notify_sched_scan_results);
4694 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4695 brcmf_notify_vif_event);
4696 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4697 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4698 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4699 brcmf_p2p_notify_listen_complete);
4700 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4701 brcmf_p2p_notify_action_frame_rx);
4702 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4703 brcmf_p2p_notify_action_tx_complete);
4704 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4705 brcmf_p2p_notify_action_tx_complete);
4708 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4712 kfree(cfg->escan_ioctl_buf);
4713 cfg->escan_ioctl_buf = NULL;
4714 kfree(cfg->extra_buf);
4715 cfg->extra_buf = NULL;
4716 kfree(cfg->pmk_list);
4717 cfg->pmk_list = NULL;
4720 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4722 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4724 goto init_priv_mem_out;
4725 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4726 if (!cfg->escan_ioctl_buf)
4727 goto init_priv_mem_out;
4728 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4729 if (!cfg->extra_buf)
4730 goto init_priv_mem_out;
4731 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4733 goto init_priv_mem_out;
4738 brcmf_deinit_priv_mem(cfg);
4743 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4747 cfg->scan_request = NULL;
4748 cfg->pwr_save = true;
4749 cfg->roam_on = true; /* roam on & off switch.
4750 we enable roam per default */
4751 cfg->active_scan = true; /* we do active scan for
4752 specific scan per default */
4753 cfg->dongle_up = false; /* dongle is not up yet */
4754 err = brcmf_init_priv_mem(cfg);
4757 brcmf_register_event_handlers(cfg);
4758 mutex_init(&cfg->usr_sync);
4759 brcmf_init_escan(cfg);
4760 brcmf_init_conf(cfg->conf);
4761 init_completion(&cfg->vif_disabled);
4765 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4767 cfg->dongle_up = false; /* dongle down */
4768 brcmf_abort_scanning(cfg);
4769 brcmf_deinit_priv_mem(cfg);
4772 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4774 init_waitqueue_head(&event->vif_wq);
4775 mutex_init(&event->vif_event_lock);
4778 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4779 struct device *busdev)
4781 struct net_device *ndev = drvr->iflist[0]->ndev;
4782 struct brcmf_cfg80211_info *cfg;
4783 struct wiphy *wiphy;
4784 struct brcmf_cfg80211_vif *vif;
4785 struct brcmf_if *ifp;
4790 brcmf_err("ndev is invalid\n");
4794 ifp = netdev_priv(ndev);
4795 wiphy = brcmf_setup_wiphy(busdev);
4799 cfg = wiphy_priv(wiphy);
4802 init_vif_event(&cfg->vif_event);
4803 INIT_LIST_HEAD(&cfg->vif_list);
4805 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4812 vif->wdev.netdev = ndev;
4813 ndev->ieee80211_ptr = &vif->wdev;
4814 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4816 err = wl_init_priv(cfg);
4818 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4819 goto cfg80211_attach_out;
4823 err = brcmf_p2p_attach(cfg);
4825 brcmf_err("P2P initilisation failed (%d)\n", err);
4826 goto cfg80211_p2p_attach_out;
4828 err = brcmf_btcoex_attach(cfg);
4830 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4831 brcmf_p2p_detach(&cfg->p2p);
4832 goto cfg80211_p2p_attach_out;
4835 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4838 brcmf_err("Failed to get D11 version (%d)\n", err);
4839 goto cfg80211_p2p_attach_out;
4841 cfg->d11inf.io_type = (u8)io_type;
4842 brcmu_d11_attach(&cfg->d11inf);
4846 cfg80211_p2p_attach_out:
4847 wl_deinit_priv(cfg);
4849 cfg80211_attach_out:
4850 brcmf_free_vif(vif);
4855 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4857 struct brcmf_cfg80211_vif *vif;
4858 struct brcmf_cfg80211_vif *tmp;
4860 wl_deinit_priv(cfg);
4861 brcmf_btcoex_detach(cfg);
4862 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4863 brcmf_free_vif(vif);
4868 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
4871 __le32 roamtrigger[2];
4872 __le32 roam_delta[2];
4875 * Setup timeout if Beacons are lost and roam is
4876 * off to report link down
4879 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4881 brcmf_err("bcn_timeout error (%d)\n", err);
4882 goto dongle_rom_out;
4887 * Enable/Disable built-in roaming to allow supplicant
4888 * to take care of roaming
4890 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4891 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4893 brcmf_err("roam_off error (%d)\n", err);
4894 goto dongle_rom_out;
4897 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4898 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4899 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4900 (void *)roamtrigger, sizeof(roamtrigger));
4902 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4903 goto dongle_rom_out;
4906 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4907 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4908 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4909 (void *)roam_delta, sizeof(roam_delta));
4911 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4912 goto dongle_rom_out;
4920 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
4921 s32 scan_unassoc_time, s32 scan_passive_time)
4925 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4928 if (err == -EOPNOTSUPP)
4929 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4931 brcmf_err("Scan assoc time error (%d)\n", err);
4932 goto dongle_scantime_out;
4934 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4937 if (err == -EOPNOTSUPP)
4938 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4940 brcmf_err("Scan unassoc time error (%d)\n", err);
4941 goto dongle_scantime_out;
4944 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4947 if (err == -EOPNOTSUPP)
4948 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4950 brcmf_err("Scan passive time error (%d)\n", err);
4951 goto dongle_scantime_out;
4954 dongle_scantime_out:
4959 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg, u32 bw_cap)
4961 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4962 struct ieee80211_channel *band_chan_arr;
4963 struct brcmf_chanspec_list *list;
4964 struct brcmu_chan ch;
4969 enum ieee80211_band band;
4978 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4983 list = (struct brcmf_chanspec_list *)pbuf;
4985 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
4988 brcmf_err("get chanspecs error (%d)\n", err);
4992 __wl_band_2ghz.n_channels = 0;
4993 __wl_band_5ghz_a.n_channels = 0;
4995 total = le32_to_cpu(list->count);
4996 for (i = 0; i < total; i++) {
4997 ch.chspec = (u16)le32_to_cpu(list->element[i]);
4998 cfg->d11inf.decchspec(&ch);
5000 if (ch.band == BRCMU_CHAN_BAND_2G) {
5001 band_chan_arr = __wl_2ghz_channels;
5002 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5003 n_cnt = &__wl_band_2ghz.n_channels;
5004 band = IEEE80211_BAND_2GHZ;
5005 ht40_allowed = (bw_cap == WLC_N_BW_40ALL);
5006 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5007 band_chan_arr = __wl_5ghz_a_channels;
5008 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5009 n_cnt = &__wl_band_5ghz_a.n_channels;
5010 band = IEEE80211_BAND_5GHZ;
5011 ht40_allowed = !(bw_cap == WLC_N_BW_20ALL);
5013 brcmf_err("Invalid channel Sepc. 0x%x.\n", ch.chspec);
5016 if (!ht40_allowed && ch.bw == BRCMU_CHAN_BW_40)
5019 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5020 if (band_chan_arr[j].hw_value == ch.chnum) {
5029 if (index < array_size) {
5030 band_chan_arr[index].center_freq =
5031 ieee80211_channel_to_frequency(ch.chnum, band);
5032 band_chan_arr[index].hw_value = ch.chnum;
5034 if (ch.bw == BRCMU_CHAN_BW_40 && ht40_allowed) {
5035 /* assuming the order is HT20, HT40 Upper,
5036 * HT40 lower from chanspecs
5038 ht40_flag = band_chan_arr[index].flags &
5039 IEEE80211_CHAN_NO_HT40;
5040 if (ch.sb == BRCMU_CHAN_SB_U) {
5041 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5042 band_chan_arr[index].flags &=
5043 ~IEEE80211_CHAN_NO_HT40;
5044 band_chan_arr[index].flags |=
5045 IEEE80211_CHAN_NO_HT40PLUS;
5047 /* It should be one of
5048 * IEEE80211_CHAN_NO_HT40 or
5049 * IEEE80211_CHAN_NO_HT40PLUS
5051 band_chan_arr[index].flags &=
5052 ~IEEE80211_CHAN_NO_HT40;
5053 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5054 band_chan_arr[index].flags |=
5055 IEEE80211_CHAN_NO_HT40MINUS;
5058 band_chan_arr[index].flags =
5059 IEEE80211_CHAN_NO_HT40;
5060 ch.bw = BRCMU_CHAN_BW_20;
5061 cfg->d11inf.encchspec(&ch);
5062 channel = ch.chspec;
5063 err = brcmf_fil_bsscfg_int_get(ifp,
5067 if (channel & WL_CHAN_RADAR)
5068 band_chan_arr[index].flags |=
5069 (IEEE80211_CHAN_RADAR |
5070 IEEE80211_CHAN_NO_IBSS);
5071 if (channel & WL_CHAN_PASSIVE)
5072 band_chan_arr[index].flags |=
5073 IEEE80211_CHAN_PASSIVE_SCAN;
5086 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5088 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5089 struct wiphy *wiphy;
5098 struct ieee80211_supported_band *bands[IEEE80211_NUM_BANDS];
5101 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5102 &phy_list, sizeof(phy_list));
5104 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5108 phy = ((char *)&phy_list)[0];
5109 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5112 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5113 &band_list, sizeof(band_list));
5115 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5118 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5119 band_list[0], band_list[1], band_list[2]);
5121 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5123 brcmf_err("nmode error (%d)\n", err);
5125 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &bw_cap);
5127 brcmf_err("mimo_bw_cap error (%d)\n", err);
5129 brcmf_dbg(INFO, "nmode=%d, mimo_bw_cap=%d\n", nmode, bw_cap);
5131 err = brcmf_construct_reginfo(cfg, bw_cap);
5133 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5137 nband = band_list[0];
5138 memset(bands, 0, sizeof(bands));
5140 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5142 if ((band_list[i] == WLC_BAND_5G) &&
5143 (__wl_band_5ghz_a.n_channels > 0)) {
5144 index = IEEE80211_BAND_5GHZ;
5145 bands[index] = &__wl_band_5ghz_a;
5146 if ((bw_cap == WLC_N_BW_40ALL) ||
5147 (bw_cap == WLC_N_BW_20IN2G_40IN5G))
5148 bands[index]->ht_cap.cap |=
5149 IEEE80211_HT_CAP_SGI_40;
5150 } else if ((band_list[i] == WLC_BAND_2G) &&
5151 (__wl_band_2ghz.n_channels > 0)) {
5152 index = IEEE80211_BAND_2GHZ;
5153 bands[index] = &__wl_band_2ghz;
5154 if (bw_cap == WLC_N_BW_40ALL)
5155 bands[index]->ht_cap.cap |=
5156 IEEE80211_HT_CAP_SGI_40;
5159 if ((index >= 0) && nmode) {
5160 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5161 bands[index]->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5162 bands[index]->ht_cap.ht_supported = true;
5163 bands[index]->ht_cap.ampdu_factor =
5164 IEEE80211_HT_MAX_AMPDU_64K;
5165 bands[index]->ht_cap.ampdu_density =
5166 IEEE80211_HT_MPDU_DENSITY_16;
5167 /* An HT shall support all EQM rates for one spatial
5170 bands[index]->ht_cap.mcs.rx_mask[0] = 0xff;
5174 wiphy = cfg_to_wiphy(cfg);
5175 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5176 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5177 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5183 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5185 return brcmf_update_wiphybands(cfg);
5188 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5190 struct net_device *ndev;
5191 struct wireless_dev *wdev;
5192 struct brcmf_if *ifp;
5199 ndev = cfg_to_ndev(cfg);
5200 wdev = ndev->ieee80211_ptr;
5201 ifp = netdev_priv(ndev);
5203 /* make sure RF is ready for work */
5204 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5206 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5207 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5209 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5210 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5212 goto default_conf_out;
5213 brcmf_dbg(INFO, "power save set to %s\n",
5214 (power_mode ? "enabled" : "disabled"));
5216 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5218 goto default_conf_out;
5219 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5222 goto default_conf_out;
5223 err = brcmf_dongle_probecap(cfg);
5225 goto default_conf_out;
5227 cfg->dongle_up = true;
5234 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5236 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5238 return brcmf_config_dongle(ifp->drvr->config);
5241 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5243 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5246 * While going down, if associated with AP disassociate
5247 * from AP to save power
5249 if (check_vif_up(ifp->vif)) {
5250 brcmf_link_down(ifp->vif);
5252 /* Make sure WPA_Supplicant receives all the event
5253 generated due to DISASSOC call to the fw to keep
5254 the state fw and WPA_Supplicant state consistent
5259 brcmf_abort_scanning(cfg);
5260 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5265 s32 brcmf_cfg80211_up(struct net_device *ndev)
5267 struct brcmf_if *ifp = netdev_priv(ndev);
5268 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5271 mutex_lock(&cfg->usr_sync);
5272 err = __brcmf_cfg80211_up(ifp);
5273 mutex_unlock(&cfg->usr_sync);
5278 s32 brcmf_cfg80211_down(struct net_device *ndev)
5280 struct brcmf_if *ifp = netdev_priv(ndev);
5281 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5284 mutex_lock(&cfg->usr_sync);
5285 err = __brcmf_cfg80211_down(ifp);
5286 mutex_unlock(&cfg->usr_sync);
5291 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5293 struct wireless_dev *wdev = &ifp->vif->wdev;
5295 return wdev->iftype;
5298 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5300 struct brcmf_cfg80211_vif *vif;
5303 list_for_each_entry(vif, &cfg->vif_list, list) {
5304 if (test_bit(state, &vif->sme_state))
5310 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5315 mutex_lock(&event->vif_event_lock);
5316 evt_action = event->action;
5317 mutex_unlock(&event->vif_event_lock);
5318 return evt_action == action;
5321 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5322 struct brcmf_cfg80211_vif *vif)
5324 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5326 mutex_lock(&event->vif_event_lock);
5329 mutex_unlock(&event->vif_event_lock);
5332 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5334 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5337 mutex_lock(&event->vif_event_lock);
5338 armed = event->vif != NULL;
5339 mutex_unlock(&event->vif_event_lock);
5343 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5344 u8 action, ulong timeout)
5346 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5348 return wait_event_timeout(event->vif_wq,
5349 vif_event_equals(event, action), timeout);