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_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206 * With respect to these flags, wpa_supplicant doesn't * start p2p
207 * 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 const struct brcmf_tlv *
355 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
357 const struct brcmf_tlv *elt = buf;
360 /* find tagged parameter */
361 while (totlen >= TLV_HDR_LEN) {
364 /* validate remaining totlen */
365 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
368 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
369 totlen -= (len + TLV_HDR_LEN);
375 /* Is any of the tlvs the expected entry? If
376 * not update the tlvs buffer pointer/length.
379 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
380 const u8 *oui, u32 oui_len, u8 type)
382 /* If the contents match the OUI and the type */
383 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
384 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
385 type == ie[TLV_BODY_OFF + oui_len]) {
391 /* point to the next ie */
392 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
393 /* calculate the length of the rest of the buffer */
394 *tlvs_len -= (int)(ie - *tlvs);
395 /* update the pointer to the start of the buffer */
401 static struct brcmf_vs_tlv *
402 brcmf_find_wpaie(const u8 *parse, u32 len)
404 const struct brcmf_tlv *ie;
406 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
407 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
408 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
409 return (struct brcmf_vs_tlv *)ie;
414 static struct brcmf_vs_tlv *
415 brcmf_find_wpsie(const u8 *parse, u32 len)
417 const struct brcmf_tlv *ie;
419 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
420 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
421 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
422 return (struct brcmf_vs_tlv *)ie;
428 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
429 struct brcmf_wsec_key_le *key_le)
431 key_le->index = cpu_to_le32(key->index);
432 key_le->len = cpu_to_le32(key->len);
433 key_le->algo = cpu_to_le32(key->algo);
434 key_le->flags = cpu_to_le32(key->flags);
435 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
436 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
437 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
438 memcpy(key_le->data, key->data, sizeof(key->data));
439 memcpy(key_le->ea, key->ea, sizeof(key->ea));
443 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
446 struct brcmf_wsec_key_le key_le;
448 convert_key_from_CPU(key, &key_le);
450 brcmf_netdev_wait_pend8021x(ndev);
452 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
456 brcmf_err("wsec_key error (%d)\n", err);
461 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
467 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
471 /* Try to set and enable ARP offload feature, this may fail, then it */
472 /* is simply not supported and err 0 will be returned */
473 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
475 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
479 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
481 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
485 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
492 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
494 enum nl80211_iftype type,
496 struct vif_params *params)
498 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
500 case NL80211_IFTYPE_ADHOC:
501 case NL80211_IFTYPE_STATION:
502 case NL80211_IFTYPE_AP:
503 case NL80211_IFTYPE_AP_VLAN:
504 case NL80211_IFTYPE_WDS:
505 case NL80211_IFTYPE_MONITOR:
506 case NL80211_IFTYPE_MESH_POINT:
507 return ERR_PTR(-EOPNOTSUPP);
508 case NL80211_IFTYPE_P2P_CLIENT:
509 case NL80211_IFTYPE_P2P_GO:
510 case NL80211_IFTYPE_P2P_DEVICE:
511 return brcmf_p2p_add_vif(wiphy, name, type, flags, params);
512 case NL80211_IFTYPE_UNSPECIFIED:
514 return ERR_PTR(-EINVAL);
518 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
522 if (check_vif_up(ifp->vif)) {
523 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
525 brcmf_err("fail to set mpc\n");
528 brcmf_dbg(INFO, "MPC : %d\n", mpc);
532 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
533 struct brcmf_if *ifp, bool aborted,
536 struct brcmf_scan_params_le params_le;
537 struct cfg80211_scan_request *scan_request;
540 brcmf_dbg(SCAN, "Enter\n");
542 /* clear scan request, because the FW abort can cause a second call */
543 /* to this functon and might cause a double cfg80211_scan_done */
544 scan_request = cfg->scan_request;
545 cfg->scan_request = NULL;
547 if (timer_pending(&cfg->escan_timeout))
548 del_timer_sync(&cfg->escan_timeout);
551 /* Do a scan abort to stop the driver's scan engine */
552 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
553 memset(¶ms_le, 0, sizeof(params_le));
554 memset(params_le.bssid, 0xFF, ETH_ALEN);
555 params_le.bss_type = DOT11_BSSTYPE_ANY;
556 params_le.scan_type = 0;
557 params_le.channel_num = cpu_to_le32(1);
558 params_le.nprobes = cpu_to_le32(1);
559 params_le.active_time = cpu_to_le32(-1);
560 params_le.passive_time = cpu_to_le32(-1);
561 params_le.home_time = cpu_to_le32(-1);
562 /* Scan is aborted by setting channel_list[0] to -1 */
563 params_le.channel_list[0] = cpu_to_le16(-1);
564 /* E-Scan (or anyother type) can be aborted by SCAN */
565 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
566 ¶ms_le, sizeof(params_le));
568 brcmf_err("Scan abort failed\n");
571 * e-scan can be initiated by scheduled scan
572 * which takes precedence.
574 if (cfg->sched_escan) {
575 brcmf_dbg(SCAN, "scheduled scan completed\n");
576 cfg->sched_escan = false;
578 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
579 brcmf_set_mpc(ifp, 1);
580 } else if (scan_request) {
581 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
582 aborted ? "Aborted" : "Done");
583 cfg80211_scan_done(scan_request, aborted);
584 brcmf_set_mpc(ifp, 1);
586 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
587 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
593 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
595 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
596 struct net_device *ndev = wdev->netdev;
598 /* vif event pending in firmware */
599 if (brcmf_cfg80211_vif_event_armed(cfg))
603 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
604 cfg->escan_info.ifp == netdev_priv(ndev))
605 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
608 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
611 switch (wdev->iftype) {
612 case NL80211_IFTYPE_ADHOC:
613 case NL80211_IFTYPE_STATION:
614 case NL80211_IFTYPE_AP:
615 case NL80211_IFTYPE_AP_VLAN:
616 case NL80211_IFTYPE_WDS:
617 case NL80211_IFTYPE_MONITOR:
618 case NL80211_IFTYPE_MESH_POINT:
620 case NL80211_IFTYPE_P2P_CLIENT:
621 case NL80211_IFTYPE_P2P_GO:
622 case NL80211_IFTYPE_P2P_DEVICE:
623 return brcmf_p2p_del_vif(wiphy, wdev);
624 case NL80211_IFTYPE_UNSPECIFIED:
632 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
633 enum nl80211_iftype type, u32 *flags,
634 struct vif_params *params)
636 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
637 struct brcmf_if *ifp = netdev_priv(ndev);
638 struct brcmf_cfg80211_vif *vif = ifp->vif;
643 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
646 case NL80211_IFTYPE_MONITOR:
647 case NL80211_IFTYPE_WDS:
648 brcmf_err("type (%d) : currently we do not support this type\n",
651 case NL80211_IFTYPE_ADHOC:
652 vif->mode = WL_MODE_IBSS;
655 case NL80211_IFTYPE_STATION:
656 /* Ignore change for p2p IF. Unclear why supplicant does this */
657 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
658 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
659 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
660 /* WAR: It is unexpected to get a change of VIF for P2P
661 * IF, but it happens. The request can not be handled
662 * but returning EPERM causes a crash. Returning 0
663 * without setting ieee80211_ptr->iftype causes trace
664 * (WARN_ON) but it works with wpa_supplicant
668 vif->mode = WL_MODE_BSS;
671 case NL80211_IFTYPE_AP:
672 case NL80211_IFTYPE_P2P_GO:
673 vif->mode = WL_MODE_AP;
682 if (type == NL80211_IFTYPE_P2P_GO) {
683 brcmf_dbg(INFO, "IF Type = P2P GO\n");
684 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
687 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
688 brcmf_dbg(INFO, "IF Type = AP\n");
691 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
693 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
697 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
700 ndev->ieee80211_ptr->iftype = type;
703 brcmf_dbg(TRACE, "Exit\n");
708 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
709 struct brcmf_scan_params_le *params_le,
710 struct cfg80211_scan_request *request)
718 struct brcmf_ssid_le ssid_le;
720 memset(params_le->bssid, 0xFF, ETH_ALEN);
721 params_le->bss_type = DOT11_BSSTYPE_ANY;
722 params_le->scan_type = 0;
723 params_le->channel_num = 0;
724 params_le->nprobes = cpu_to_le32(-1);
725 params_le->active_time = cpu_to_le32(-1);
726 params_le->passive_time = cpu_to_le32(-1);
727 params_le->home_time = cpu_to_le32(-1);
728 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
730 /* if request is null exit so it will be all channel broadcast scan */
734 n_ssids = request->n_ssids;
735 n_channels = request->n_channels;
736 /* Copy channel array if applicable */
737 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
739 if (n_channels > 0) {
740 for (i = 0; i < n_channels; i++) {
741 chanspec = channel_to_chanspec(&cfg->d11inf,
742 request->channels[i]);
743 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
744 request->channels[i]->hw_value, chanspec);
745 params_le->channel_list[i] = cpu_to_le16(chanspec);
748 brcmf_dbg(SCAN, "Scanning all channels\n");
750 /* Copy ssid array if applicable */
751 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
753 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
754 n_channels * sizeof(u16);
755 offset = roundup(offset, sizeof(u32));
756 ptr = (char *)params_le + offset;
757 for (i = 0; i < n_ssids; i++) {
758 memset(&ssid_le, 0, sizeof(ssid_le));
760 cpu_to_le32(request->ssids[i].ssid_len);
761 memcpy(ssid_le.SSID, request->ssids[i].ssid,
762 request->ssids[i].ssid_len);
763 if (!ssid_le.SSID_len)
764 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
766 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
767 i, ssid_le.SSID, ssid_le.SSID_len);
768 memcpy(ptr, &ssid_le, sizeof(ssid_le));
769 ptr += sizeof(ssid_le);
772 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
773 if ((request->ssids) && request->ssids->ssid_len) {
774 brcmf_dbg(SCAN, "SSID %s len=%d\n",
775 params_le->ssid_le.SSID,
776 request->ssids->ssid_len);
777 params_le->ssid_le.SSID_len =
778 cpu_to_le32(request->ssids->ssid_len);
779 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
780 request->ssids->ssid_len);
783 /* Adding mask to channel numbers */
784 params_le->channel_num =
785 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
786 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
790 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
791 struct cfg80211_scan_request *request, u16 action)
793 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
794 offsetof(struct brcmf_escan_params_le, params_le);
795 struct brcmf_escan_params_le *params;
798 brcmf_dbg(SCAN, "E-SCAN START\n");
800 if (request != NULL) {
801 /* Allocate space for populating ssids in struct */
802 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
804 /* Allocate space for populating ssids in struct */
805 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
808 params = kzalloc(params_size, GFP_KERNEL);
813 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
814 brcmf_escan_prep(cfg, ¶ms->params_le, request);
815 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
816 params->action = cpu_to_le16(action);
817 params->sync_id = cpu_to_le16(0x1234);
819 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
822 brcmf_dbg(INFO, "system busy : escan canceled\n");
824 brcmf_err("error (%d)\n", err);
833 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
834 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
838 struct brcmf_scan_results *results;
839 struct escan_info *escan = &cfg->escan_info;
841 brcmf_dbg(SCAN, "Enter\n");
843 escan->wiphy = wiphy;
844 escan->escan_state = WL_ESCAN_STATE_SCANNING;
845 passive_scan = cfg->active_scan ? 0 : 1;
846 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
849 brcmf_err("error (%d)\n", err);
852 brcmf_set_mpc(ifp, 0);
853 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
854 results->version = 0;
856 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
858 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
860 brcmf_set_mpc(ifp, 1);
865 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
866 struct cfg80211_scan_request *request,
867 struct cfg80211_ssid *this_ssid)
869 struct brcmf_if *ifp = vif->ifp;
870 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
871 struct cfg80211_ssid *ssids;
872 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
879 brcmf_dbg(SCAN, "START ESCAN\n");
881 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
882 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
885 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
886 brcmf_err("Scanning being aborted: status (%lu)\n",
890 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
891 brcmf_err("Scanning suppressed: status (%lu)\n",
895 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
896 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
900 /* If scan req comes for p2p0, send it over primary I/F */
901 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
902 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
904 /* Arm scan timeout timer */
905 mod_timer(&cfg->escan_timeout, jiffies +
906 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
911 ssids = request->ssids;
915 /* we don't do escan in ibss */
919 cfg->scan_request = request;
920 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
922 cfg->escan_info.run = brcmf_run_escan;
923 err = brcmf_p2p_scan_prep(wiphy, request, vif);
927 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
931 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
932 ssids->ssid, ssids->ssid_len);
933 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
934 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
935 sr->ssid_le.SSID_len = cpu_to_le32(0);
938 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
939 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
942 brcmf_dbg(SCAN, "Broadcast scan\n");
944 passive_scan = cfg->active_scan ? 0 : 1;
945 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
948 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
951 brcmf_set_mpc(ifp, 0);
952 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
953 &sr->ssid_le, sizeof(sr->ssid_le));
956 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
959 brcmf_err("WLC_SCAN error (%d)\n", err);
961 brcmf_set_mpc(ifp, 1);
969 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
970 if (timer_pending(&cfg->escan_timeout))
971 del_timer_sync(&cfg->escan_timeout);
972 cfg->scan_request = NULL;
977 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
979 struct brcmf_cfg80211_vif *vif;
982 brcmf_dbg(TRACE, "Enter\n");
983 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
984 if (!check_vif_up(vif))
987 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
990 brcmf_err("scan error (%d)\n", err);
992 brcmf_dbg(TRACE, "Exit\n");
996 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1000 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1003 brcmf_err("Error (%d)\n", err);
1008 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1012 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1015 brcmf_err("Error (%d)\n", err);
1020 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1023 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1025 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1027 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1033 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1035 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1036 struct net_device *ndev = cfg_to_ndev(cfg);
1037 struct brcmf_if *ifp = netdev_priv(ndev);
1040 brcmf_dbg(TRACE, "Enter\n");
1041 if (!check_vif_up(ifp->vif))
1044 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1045 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1046 cfg->conf->rts_threshold = wiphy->rts_threshold;
1047 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1051 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1052 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1053 cfg->conf->frag_threshold = wiphy->frag_threshold;
1054 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1058 if (changed & WIPHY_PARAM_RETRY_LONG
1059 && (cfg->conf->retry_long != wiphy->retry_long)) {
1060 cfg->conf->retry_long = wiphy->retry_long;
1061 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1065 if (changed & WIPHY_PARAM_RETRY_SHORT
1066 && (cfg->conf->retry_short != wiphy->retry_short)) {
1067 cfg->conf->retry_short = wiphy->retry_short;
1068 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1074 brcmf_dbg(TRACE, "Exit\n");
1078 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1080 memset(prof, 0, sizeof(*prof));
1083 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
1085 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1088 brcmf_dbg(TRACE, "Enter\n");
1090 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1091 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1092 err = brcmf_fil_cmd_data_set(vif->ifp,
1093 BRCMF_C_DISASSOC, NULL, 0);
1095 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1097 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1098 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1101 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1102 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1103 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1104 brcmf_dbg(TRACE, "Exit\n");
1108 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1109 struct cfg80211_ibss_params *params)
1111 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1112 struct brcmf_if *ifp = netdev_priv(ndev);
1113 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1114 struct brcmf_join_params join_params;
1115 size_t join_params_size = 0;
1121 brcmf_dbg(TRACE, "Enter\n");
1122 if (!check_vif_up(ifp->vif))
1126 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1128 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1132 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1135 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1137 brcmf_dbg(CONN, "No BSSID specified\n");
1139 if (params->chandef.chan)
1140 brcmf_dbg(CONN, "channel: %d\n",
1141 params->chandef.chan->center_freq);
1143 brcmf_dbg(CONN, "no channel specified\n");
1145 if (params->channel_fixed)
1146 brcmf_dbg(CONN, "fixed channel required\n");
1148 brcmf_dbg(CONN, "no fixed channel required\n");
1150 if (params->ie && params->ie_len)
1151 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1153 brcmf_dbg(CONN, "no ie specified\n");
1155 if (params->beacon_interval)
1156 brcmf_dbg(CONN, "beacon interval: %d\n",
1157 params->beacon_interval);
1159 brcmf_dbg(CONN, "no beacon interval specified\n");
1161 if (params->basic_rates)
1162 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1164 brcmf_dbg(CONN, "no basic rates specified\n");
1166 if (params->privacy)
1167 brcmf_dbg(CONN, "privacy required\n");
1169 brcmf_dbg(CONN, "no privacy required\n");
1171 /* Configure Privacy for starter */
1172 if (params->privacy)
1173 wsec |= WEP_ENABLED;
1175 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1177 brcmf_err("wsec failed (%d)\n", err);
1181 /* Configure Beacon Interval for starter */
1182 if (params->beacon_interval)
1183 bcnprd = params->beacon_interval;
1187 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1189 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1193 /* Configure required join parameter */
1194 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1197 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1198 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1199 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1200 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1201 join_params_size = sizeof(join_params.ssid_le);
1204 if (params->bssid) {
1205 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1206 join_params_size = sizeof(join_params.ssid_le) +
1207 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1208 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1210 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1211 memset(profile->bssid, 0, ETH_ALEN);
1215 if (params->chandef.chan) {
1219 ieee80211_frequency_to_channel(
1220 params->chandef.chan->center_freq);
1221 if (params->channel_fixed) {
1222 /* adding chanspec */
1223 chanspec = channel_to_chanspec(&cfg->d11inf,
1224 params->chandef.chan);
1225 join_params.params_le.chanspec_list[0] =
1226 cpu_to_le16(chanspec);
1227 join_params.params_le.chanspec_num = cpu_to_le32(1);
1228 join_params_size += sizeof(join_params.params_le);
1231 /* set channel for starter */
1232 target_channel = cfg->channel;
1233 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1236 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1242 cfg->ibss_starter = false;
1245 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1246 &join_params, join_params_size);
1248 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1254 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1255 brcmf_dbg(TRACE, "Exit\n");
1260 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1262 struct brcmf_if *ifp = netdev_priv(ndev);
1265 brcmf_dbg(TRACE, "Enter\n");
1266 if (!check_vif_up(ifp->vif))
1269 brcmf_link_down(ifp->vif);
1271 brcmf_dbg(TRACE, "Exit\n");
1276 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1277 struct cfg80211_connect_params *sme)
1279 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1280 struct brcmf_cfg80211_security *sec;
1284 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1285 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1286 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1287 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1289 val = WPA_AUTH_DISABLED;
1290 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1291 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1293 brcmf_err("set wpa_auth failed (%d)\n", err);
1296 sec = &profile->sec;
1297 sec->wpa_versions = sme->crypto.wpa_versions;
1301 static s32 brcmf_set_auth_type(struct net_device *ndev,
1302 struct cfg80211_connect_params *sme)
1304 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1305 struct brcmf_cfg80211_security *sec;
1309 switch (sme->auth_type) {
1310 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1312 brcmf_dbg(CONN, "open system\n");
1314 case NL80211_AUTHTYPE_SHARED_KEY:
1316 brcmf_dbg(CONN, "shared key\n");
1318 case NL80211_AUTHTYPE_AUTOMATIC:
1320 brcmf_dbg(CONN, "automatic\n");
1322 case NL80211_AUTHTYPE_NETWORK_EAP:
1323 brcmf_dbg(CONN, "network eap\n");
1326 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1330 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1332 brcmf_err("set auth failed (%d)\n", err);
1335 sec = &profile->sec;
1336 sec->auth_type = sme->auth_type;
1341 brcmf_set_set_cipher(struct net_device *ndev,
1342 struct cfg80211_connect_params *sme)
1344 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1345 struct brcmf_cfg80211_security *sec;
1350 if (sme->crypto.n_ciphers_pairwise) {
1351 switch (sme->crypto.ciphers_pairwise[0]) {
1352 case WLAN_CIPHER_SUITE_WEP40:
1353 case WLAN_CIPHER_SUITE_WEP104:
1356 case WLAN_CIPHER_SUITE_TKIP:
1357 pval = TKIP_ENABLED;
1359 case WLAN_CIPHER_SUITE_CCMP:
1362 case WLAN_CIPHER_SUITE_AES_CMAC:
1366 brcmf_err("invalid cipher pairwise (%d)\n",
1367 sme->crypto.ciphers_pairwise[0]);
1371 if (sme->crypto.cipher_group) {
1372 switch (sme->crypto.cipher_group) {
1373 case WLAN_CIPHER_SUITE_WEP40:
1374 case WLAN_CIPHER_SUITE_WEP104:
1377 case WLAN_CIPHER_SUITE_TKIP:
1378 gval = TKIP_ENABLED;
1380 case WLAN_CIPHER_SUITE_CCMP:
1383 case WLAN_CIPHER_SUITE_AES_CMAC:
1387 brcmf_err("invalid cipher group (%d)\n",
1388 sme->crypto.cipher_group);
1393 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1394 /* In case of privacy, but no security and WPS then simulate */
1395 /* setting AES. WPS-2.0 allows no security */
1396 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1399 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", pval | gval);
1401 brcmf_err("error (%d)\n", err);
1405 sec = &profile->sec;
1406 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1407 sec->cipher_group = sme->crypto.cipher_group;
1413 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1415 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1416 struct brcmf_cfg80211_security *sec;
1420 if (sme->crypto.n_akm_suites) {
1421 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1424 brcmf_err("could not get wpa_auth (%d)\n", err);
1427 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1428 switch (sme->crypto.akm_suites[0]) {
1429 case WLAN_AKM_SUITE_8021X:
1430 val = WPA_AUTH_UNSPECIFIED;
1432 case WLAN_AKM_SUITE_PSK:
1436 brcmf_err("invalid cipher group (%d)\n",
1437 sme->crypto.cipher_group);
1440 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1441 switch (sme->crypto.akm_suites[0]) {
1442 case WLAN_AKM_SUITE_8021X:
1443 val = WPA2_AUTH_UNSPECIFIED;
1445 case WLAN_AKM_SUITE_PSK:
1446 val = WPA2_AUTH_PSK;
1449 brcmf_err("invalid cipher group (%d)\n",
1450 sme->crypto.cipher_group);
1455 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1456 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1459 brcmf_err("could not set wpa_auth (%d)\n", err);
1463 sec = &profile->sec;
1464 sec->wpa_auth = sme->crypto.akm_suites[0];
1470 brcmf_set_sharedkey(struct net_device *ndev,
1471 struct cfg80211_connect_params *sme)
1473 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1474 struct brcmf_cfg80211_security *sec;
1475 struct brcmf_wsec_key key;
1479 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1481 if (sme->key_len == 0)
1484 sec = &profile->sec;
1485 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1486 sec->wpa_versions, sec->cipher_pairwise);
1488 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1491 if (!(sec->cipher_pairwise &
1492 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1495 memset(&key, 0, sizeof(key));
1496 key.len = (u32) sme->key_len;
1497 key.index = (u32) sme->key_idx;
1498 if (key.len > sizeof(key.data)) {
1499 brcmf_err("Too long key length (%u)\n", key.len);
1502 memcpy(key.data, sme->key, key.len);
1503 key.flags = BRCMF_PRIMARY_KEY;
1504 switch (sec->cipher_pairwise) {
1505 case WLAN_CIPHER_SUITE_WEP40:
1506 key.algo = CRYPTO_ALGO_WEP1;
1508 case WLAN_CIPHER_SUITE_WEP104:
1509 key.algo = CRYPTO_ALGO_WEP128;
1512 brcmf_err("Invalid algorithm (%d)\n",
1513 sme->crypto.ciphers_pairwise[0]);
1516 /* Set the new key/index */
1517 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1518 key.len, key.index, key.algo);
1519 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1520 err = send_key_to_dongle(ndev, &key);
1524 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1525 brcmf_dbg(CONN, "set auth_type to shared key\n");
1526 val = WL_AUTH_SHARED_KEY; /* shared key */
1527 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1529 brcmf_err("set auth failed (%d)\n", err);
1535 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1536 enum nl80211_auth_type type)
1539 if (type == NL80211_AUTHTYPE_AUTOMATIC) {
1540 /* shift to ignore chip revision */
1541 ci = brcmf_get_chip_info(ifp) >> 4;
1544 brcmf_dbg(CONN, "43236 WAR: use OPEN instead of AUTO\n");
1545 return NL80211_AUTHTYPE_OPEN_SYSTEM;
1554 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1555 struct cfg80211_connect_params *sme)
1557 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1558 struct brcmf_if *ifp = netdev_priv(ndev);
1559 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1560 struct ieee80211_channel *chan = sme->channel;
1561 struct brcmf_join_params join_params;
1562 size_t join_params_size;
1563 const struct brcmf_tlv *rsn_ie;
1564 const struct brcmf_vs_tlv *wpa_ie;
1567 struct brcmf_ext_join_params_le *ext_join_params;
1572 brcmf_dbg(TRACE, "Enter\n");
1573 if (!check_vif_up(ifp->vif))
1577 brcmf_err("Invalid ssid\n");
1581 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1582 /* A normal (non P2P) connection request setup. */
1585 /* find the WPA_IE */
1586 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1589 ie_len = wpa_ie->len + TLV_HDR_LEN;
1591 /* find the RSN_IE */
1592 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1597 ie_len = rsn_ie->len + TLV_HDR_LEN;
1600 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1603 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1604 sme->ie, sme->ie_len);
1606 brcmf_err("Set Assoc REQ IE Failed\n");
1608 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1610 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1614 ieee80211_frequency_to_channel(chan->center_freq);
1615 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1616 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1617 cfg->channel, chan->center_freq, chanspec);
1623 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1625 err = brcmf_set_wpa_version(ndev, sme);
1627 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1631 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1632 err = brcmf_set_auth_type(ndev, sme);
1634 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1638 err = brcmf_set_set_cipher(ndev, sme);
1640 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1644 err = brcmf_set_key_mgmt(ndev, sme);
1646 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1650 err = brcmf_set_sharedkey(ndev, sme);
1652 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1656 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1657 (u32)sme->ssid_len);
1658 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1659 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1660 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1661 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1662 profile->ssid.SSID_len);
1665 /* Join with specific BSSID and cached SSID
1666 * If SSID is zero join based on BSSID only
1668 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1669 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1671 join_params_size += sizeof(u16);
1672 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1673 if (ext_join_params == NULL) {
1677 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1678 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1679 profile->ssid.SSID_len);
1680 /*increase dwell time to receive probe response or detect Beacon
1681 * from target AP at a noisy air only during connect command
1683 ext_join_params->scan_le.active_time =
1684 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1685 ext_join_params->scan_le.passive_time =
1686 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1687 /* Set up join scan parameters */
1688 ext_join_params->scan_le.scan_type = -1;
1689 /* to sync with presence period of VSDB GO.
1690 * Send probe request more frequently. Probe request will be stopped
1691 * when it gets probe response from target AP/GO.
1693 ext_join_params->scan_le.nprobes =
1694 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1695 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1696 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1699 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1701 memset(&ext_join_params->assoc_le.bssid, 0xFF, ETH_ALEN);
1704 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1706 ext_join_params->assoc_le.chanspec_list[0] =
1707 cpu_to_le16(chanspec);
1710 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1712 kfree(ext_join_params);
1714 /* This is it. join command worked, we are done */
1717 /* join command failed, fallback to set ssid */
1718 memset(&join_params, 0, sizeof(join_params));
1719 join_params_size = sizeof(join_params.ssid_le);
1721 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1722 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1725 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1727 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1730 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1731 join_params.params_le.chanspec_num = cpu_to_le32(1);
1732 join_params_size += sizeof(join_params.params_le);
1734 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1735 &join_params, join_params_size);
1737 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1741 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1742 brcmf_dbg(TRACE, "Exit\n");
1747 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1750 struct brcmf_if *ifp = netdev_priv(ndev);
1751 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1752 struct brcmf_scb_val_le scbval;
1755 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1756 if (!check_vif_up(ifp->vif))
1759 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1760 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1762 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1763 scbval.val = cpu_to_le32(reason_code);
1764 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1765 &scbval, sizeof(scbval));
1767 brcmf_err("error (%d)\n", err);
1769 brcmf_dbg(TRACE, "Exit\n");
1774 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1775 enum nl80211_tx_power_setting type, s32 mbm)
1778 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1779 struct net_device *ndev = cfg_to_ndev(cfg);
1780 struct brcmf_if *ifp = netdev_priv(ndev);
1784 s32 dbm = MBM_TO_DBM(mbm);
1786 brcmf_dbg(TRACE, "Enter\n");
1787 if (!check_vif_up(ifp->vif))
1791 case NL80211_TX_POWER_AUTOMATIC:
1793 case NL80211_TX_POWER_LIMITED:
1794 case NL80211_TX_POWER_FIXED:
1796 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1802 /* Make sure radio is off or on as far as software is concerned */
1803 disable = WL_RADIO_SW_DISABLE << 16;
1804 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1806 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1811 txpwrmw = (u16) dbm;
1812 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1813 (s32)brcmf_mw_to_qdbm(txpwrmw));
1815 brcmf_err("qtxpower error (%d)\n", err);
1816 cfg->conf->tx_power = dbm;
1819 brcmf_dbg(TRACE, "Exit\n");
1823 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1824 struct wireless_dev *wdev,
1827 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1828 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1833 brcmf_dbg(TRACE, "Enter\n");
1834 if (!check_vif_up(ifp->vif))
1837 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1839 brcmf_err("error (%d)\n", err);
1843 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1844 *dbm = (s32) brcmf_qdbm_to_mw(result);
1847 brcmf_dbg(TRACE, "Exit\n");
1852 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1853 u8 key_idx, bool unicast, bool multicast)
1855 struct brcmf_if *ifp = netdev_priv(ndev);
1860 brcmf_dbg(TRACE, "Enter\n");
1861 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1862 if (!check_vif_up(ifp->vif))
1865 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1867 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1871 if (wsec & WEP_ENABLED) {
1872 /* Just select a new current key */
1874 err = brcmf_fil_cmd_int_set(ifp,
1875 BRCMF_C_SET_KEY_PRIMARY, index);
1877 brcmf_err("error (%d)\n", err);
1880 brcmf_dbg(TRACE, "Exit\n");
1885 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1886 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1888 struct brcmf_if *ifp = netdev_priv(ndev);
1889 struct brcmf_wsec_key key;
1893 memset(&key, 0, sizeof(key));
1894 key.index = (u32) key_idx;
1895 /* Instead of bcast for ea address for default wep keys,
1896 driver needs it to be Null */
1897 if (!is_multicast_ether_addr(mac_addr))
1898 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1899 key.len = (u32) params->key_len;
1900 /* check for key index change */
1903 err = send_key_to_dongle(ndev, &key);
1905 brcmf_err("key delete error (%d)\n", err);
1907 if (key.len > sizeof(key.data)) {
1908 brcmf_err("Invalid key length (%d)\n", key.len);
1912 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1913 memcpy(key.data, params->key, key.len);
1915 if ((ifp->vif->mode != WL_MODE_AP) &&
1916 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1917 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1918 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1919 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1920 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1923 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1924 if (params->seq && params->seq_len == 6) {
1927 ivptr = (u8 *) params->seq;
1928 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1929 (ivptr[3] << 8) | ivptr[2];
1930 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1931 key.iv_initialized = true;
1934 switch (params->cipher) {
1935 case WLAN_CIPHER_SUITE_WEP40:
1936 key.algo = CRYPTO_ALGO_WEP1;
1937 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1939 case WLAN_CIPHER_SUITE_WEP104:
1940 key.algo = CRYPTO_ALGO_WEP128;
1941 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1943 case WLAN_CIPHER_SUITE_TKIP:
1944 key.algo = CRYPTO_ALGO_TKIP;
1945 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1947 case WLAN_CIPHER_SUITE_AES_CMAC:
1948 key.algo = CRYPTO_ALGO_AES_CCM;
1949 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1951 case WLAN_CIPHER_SUITE_CCMP:
1952 key.algo = CRYPTO_ALGO_AES_CCM;
1953 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1956 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1959 err = send_key_to_dongle(ndev, &key);
1961 brcmf_err("wsec_key error (%d)\n", err);
1967 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1968 u8 key_idx, bool pairwise, const u8 *mac_addr,
1969 struct key_params *params)
1971 struct brcmf_if *ifp = netdev_priv(ndev);
1972 struct brcmf_wsec_key key;
1978 brcmf_dbg(TRACE, "Enter\n");
1979 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1980 if (!check_vif_up(ifp->vif))
1984 brcmf_dbg(TRACE, "Exit");
1985 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1987 memset(&key, 0, sizeof(key));
1989 key.len = (u32) params->key_len;
1990 key.index = (u32) key_idx;
1992 if (key.len > sizeof(key.data)) {
1993 brcmf_err("Too long key length (%u)\n", key.len);
1997 memcpy(key.data, params->key, key.len);
1999 key.flags = BRCMF_PRIMARY_KEY;
2000 switch (params->cipher) {
2001 case WLAN_CIPHER_SUITE_WEP40:
2002 key.algo = CRYPTO_ALGO_WEP1;
2004 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2006 case WLAN_CIPHER_SUITE_WEP104:
2007 key.algo = CRYPTO_ALGO_WEP128;
2009 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2011 case WLAN_CIPHER_SUITE_TKIP:
2012 if (ifp->vif->mode != WL_MODE_AP) {
2013 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2014 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2015 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2016 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2018 key.algo = CRYPTO_ALGO_TKIP;
2020 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2022 case WLAN_CIPHER_SUITE_AES_CMAC:
2023 key.algo = CRYPTO_ALGO_AES_CCM;
2025 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2027 case WLAN_CIPHER_SUITE_CCMP:
2028 key.algo = CRYPTO_ALGO_AES_CCM;
2030 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2033 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2038 err = send_key_to_dongle(ndev, &key);
2042 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2044 brcmf_err("get wsec error (%d)\n", err);
2048 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2050 brcmf_err("set wsec error (%d)\n", err);
2055 brcmf_dbg(TRACE, "Exit\n");
2060 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2061 u8 key_idx, bool pairwise, const u8 *mac_addr)
2063 struct brcmf_if *ifp = netdev_priv(ndev);
2064 struct brcmf_wsec_key key;
2067 brcmf_dbg(TRACE, "Enter\n");
2068 if (!check_vif_up(ifp->vif))
2071 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2072 /* we ignore this key index in this case */
2073 brcmf_err("invalid key index (%d)\n", key_idx);
2077 memset(&key, 0, sizeof(key));
2079 key.index = (u32) key_idx;
2080 key.flags = BRCMF_PRIMARY_KEY;
2081 key.algo = CRYPTO_ALGO_OFF;
2083 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2085 /* Set the new key/index */
2086 err = send_key_to_dongle(ndev, &key);
2088 brcmf_dbg(TRACE, "Exit\n");
2093 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2094 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2095 void (*callback) (void *cookie, struct key_params * params))
2097 struct key_params params;
2098 struct brcmf_if *ifp = netdev_priv(ndev);
2099 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2100 struct brcmf_cfg80211_security *sec;
2104 brcmf_dbg(TRACE, "Enter\n");
2105 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2106 if (!check_vif_up(ifp->vif))
2109 memset(¶ms, 0, sizeof(params));
2111 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2113 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2114 /* Ignore this error, may happen during DISASSOC */
2118 if (wsec & WEP_ENABLED) {
2119 sec = &profile->sec;
2120 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2121 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2122 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2123 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2124 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2125 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2127 } else if (wsec & TKIP_ENABLED) {
2128 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2129 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2130 } else if (wsec & AES_ENABLED) {
2131 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2132 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2134 brcmf_err("Invalid algo (0x%x)\n", wsec);
2138 callback(cookie, ¶ms);
2141 brcmf_dbg(TRACE, "Exit\n");
2146 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2147 struct net_device *ndev, u8 key_idx)
2149 brcmf_dbg(INFO, "Not supported\n");
2155 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2156 u8 *mac, struct station_info *sinfo)
2158 struct brcmf_if *ifp = netdev_priv(ndev);
2159 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2160 struct brcmf_scb_val_le scb_val;
2164 u8 *bssid = profile->bssid;
2165 struct brcmf_sta_info_le sta_info_le;
2169 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2170 if (!check_vif_up(ifp->vif))
2173 if (ifp->vif->mode == WL_MODE_AP) {
2174 memcpy(&sta_info_le, mac, ETH_ALEN);
2175 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2177 sizeof(sta_info_le));
2179 brcmf_err("GET STA INFO failed, %d\n", err);
2182 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2183 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2184 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2185 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2186 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2188 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2189 sinfo->inactive_time, sinfo->connected_time);
2190 } else if (ifp->vif->mode == WL_MODE_BSS) {
2191 if (memcmp(mac, bssid, ETH_ALEN)) {
2192 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2197 /* Report the current tx rate */
2198 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2200 brcmf_err("Could not get rate (%d)\n", err);
2203 sinfo->filled |= STATION_INFO_TX_BITRATE;
2204 sinfo->txrate.legacy = rate * 5;
2205 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2208 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2209 &ifp->vif->sme_state)) {
2210 memset(&scb_val, 0, sizeof(scb_val));
2211 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2212 &scb_val, sizeof(scb_val));
2214 brcmf_err("Could not get rssi (%d)\n", err);
2217 rssi = le32_to_cpu(scb_val.val);
2218 sinfo->filled |= STATION_INFO_SIGNAL;
2219 sinfo->signal = rssi;
2220 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2222 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_BCNPRD,
2225 brcmf_err("Could not get beacon period (%d)\n",
2229 sinfo->bss_param.beacon_interval =
2231 brcmf_dbg(CONN, "Beacon peroid %d\n",
2234 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_DTIMPRD,
2237 brcmf_err("Could not get DTIM period (%d)\n",
2241 sinfo->bss_param.dtim_period = dtim_period;
2242 brcmf_dbg(CONN, "DTIM peroid %d\n",
2245 sinfo->filled |= STATION_INFO_BSS_PARAM;
2250 brcmf_dbg(TRACE, "Exit\n");
2255 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2256 bool enabled, s32 timeout)
2260 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2261 struct brcmf_if *ifp = netdev_priv(ndev);
2263 brcmf_dbg(TRACE, "Enter\n");
2266 * Powersave enable/disable request is coming from the
2267 * cfg80211 even before the interface is up. In that
2268 * scenario, driver will be storing the power save
2269 * preference in cfg struct to apply this to
2270 * FW later while initializing the dongle
2272 cfg->pwr_save = enabled;
2273 if (!check_vif_up(ifp->vif)) {
2275 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2279 pm = enabled ? PM_FAST : PM_OFF;
2280 /* Do not enable the power save after assoc if it is a p2p interface */
2281 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2282 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2285 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2287 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2290 brcmf_err("net_device is not ready yet\n");
2292 brcmf_err("error (%d)\n", err);
2295 brcmf_dbg(TRACE, "Exit\n");
2299 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2300 struct brcmf_bss_info_le *bi)
2302 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2303 struct ieee80211_channel *notify_channel;
2304 struct cfg80211_bss *bss;
2305 struct ieee80211_supported_band *band;
2306 struct brcmu_chan ch;
2310 u16 notify_capability;
2311 u16 notify_interval;
2313 size_t notify_ielen;
2316 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2317 brcmf_err("Bss info is larger than buffer. Discarding\n");
2322 ch.chspec = le16_to_cpu(bi->chanspec);
2323 cfg->d11inf.decchspec(&ch);
2324 bi->ctl_ch = ch.chnum;
2326 channel = bi->ctl_ch;
2328 if (channel <= CH_MAX_2G_CHANNEL)
2329 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2331 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2333 freq = ieee80211_channel_to_frequency(channel, band->band);
2334 notify_channel = ieee80211_get_channel(wiphy, freq);
2336 notify_capability = le16_to_cpu(bi->capability);
2337 notify_interval = le16_to_cpu(bi->beacon_period);
2338 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2339 notify_ielen = le32_to_cpu(bi->ie_length);
2340 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2342 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2343 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2344 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2345 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2346 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2348 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2349 0, notify_capability, notify_interval, notify_ie,
2350 notify_ielen, notify_signal, GFP_KERNEL);
2355 cfg80211_put_bss(wiphy, bss);
2360 static struct brcmf_bss_info_le *
2361 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2364 return list->bss_info_le;
2365 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2366 le32_to_cpu(bss->length));
2369 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2371 struct brcmf_scan_results *bss_list;
2372 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2376 bss_list = cfg->bss_list;
2377 if (bss_list->count != 0 &&
2378 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2379 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2383 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2384 for (i = 0; i < bss_list->count; i++) {
2385 bi = next_bss_le(bss_list, bi);
2386 err = brcmf_inform_single_bss(cfg, bi);
2393 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2394 struct net_device *ndev, const u8 *bssid)
2396 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2397 struct ieee80211_channel *notify_channel;
2398 struct brcmf_bss_info_le *bi = NULL;
2399 struct ieee80211_supported_band *band;
2400 struct cfg80211_bss *bss;
2401 struct brcmu_chan ch;
2405 u16 notify_capability;
2406 u16 notify_interval;
2408 size_t notify_ielen;
2411 brcmf_dbg(TRACE, "Enter\n");
2413 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2419 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2421 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2422 buf, WL_BSS_INFO_MAX);
2424 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2428 bi = (struct brcmf_bss_info_le *)(buf + 4);
2430 ch.chspec = le16_to_cpu(bi->chanspec);
2431 cfg->d11inf.decchspec(&ch);
2433 if (ch.band == BRCMU_CHAN_BAND_2G)
2434 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2436 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2438 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2439 notify_channel = ieee80211_get_channel(wiphy, freq);
2441 notify_capability = le16_to_cpu(bi->capability);
2442 notify_interval = le16_to_cpu(bi->beacon_period);
2443 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2444 notify_ielen = le32_to_cpu(bi->ie_length);
2445 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2447 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2448 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2449 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2450 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2452 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2453 0, notify_capability, notify_interval,
2454 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2461 cfg80211_put_bss(wiphy, bss);
2467 brcmf_dbg(TRACE, "Exit\n");
2472 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2474 return vif->mode == WL_MODE_IBSS;
2477 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2478 struct brcmf_if *ifp)
2480 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2481 struct brcmf_bss_info_le *bi;
2482 struct brcmf_ssid *ssid;
2483 const struct brcmf_tlv *tim;
2484 u16 beacon_interval;
2490 brcmf_dbg(TRACE, "Enter\n");
2491 if (brcmf_is_ibssmode(ifp->vif))
2494 ssid = &profile->ssid;
2496 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2497 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2498 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2500 brcmf_err("Could not get bss info %d\n", err);
2501 goto update_bss_info_out;
2504 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2505 err = brcmf_inform_single_bss(cfg, bi);
2507 goto update_bss_info_out;
2509 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2510 ie_len = le32_to_cpu(bi->ie_length);
2511 beacon_interval = le16_to_cpu(bi->beacon_period);
2513 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2515 dtim_period = tim->data[1];
2518 * active scan was done so we could not get dtim
2519 * information out of probe response.
2520 * so we speficially query dtim information to dongle.
2523 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2525 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2526 goto update_bss_info_out;
2528 dtim_period = (u8)var;
2531 update_bss_info_out:
2532 brcmf_dbg(TRACE, "Exit");
2536 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2538 struct escan_info *escan = &cfg->escan_info;
2540 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2541 if (cfg->scan_request) {
2542 escan->escan_state = WL_ESCAN_STATE_IDLE;
2543 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2545 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2546 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2549 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2551 struct brcmf_cfg80211_info *cfg =
2552 container_of(work, struct brcmf_cfg80211_info,
2553 escan_timeout_work);
2555 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2558 static void brcmf_escan_timeout(unsigned long data)
2560 struct brcmf_cfg80211_info *cfg =
2561 (struct brcmf_cfg80211_info *)data;
2563 if (cfg->scan_request) {
2564 brcmf_err("timer expired\n");
2565 schedule_work(&cfg->escan_timeout_work);
2570 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2571 struct brcmf_bss_info_le *bss,
2572 struct brcmf_bss_info_le *bss_info_le)
2574 struct brcmu_chan ch_bss, ch_bss_info_le;
2576 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2577 cfg->d11inf.decchspec(&ch_bss);
2578 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2579 cfg->d11inf.decchspec(&ch_bss_info_le);
2581 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2582 ch_bss.band == ch_bss_info_le.band &&
2583 bss_info_le->SSID_len == bss->SSID_len &&
2584 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2585 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2586 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2587 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2588 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2590 /* preserve max RSSI if the measurements are
2591 * both on-channel or both off-channel
2593 if (bss_info_rssi > bss_rssi)
2594 bss->RSSI = bss_info_le->RSSI;
2595 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2596 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2597 /* preserve the on-channel rssi measurement
2598 * if the new measurement is off channel
2600 bss->RSSI = bss_info_le->RSSI;
2601 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2609 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2610 const struct brcmf_event_msg *e, void *data)
2612 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2615 struct brcmf_escan_result_le *escan_result_le;
2616 struct brcmf_bss_info_le *bss_info_le;
2617 struct brcmf_bss_info_le *bss = NULL;
2619 struct brcmf_scan_results *list;
2625 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2626 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2630 if (status == BRCMF_E_STATUS_PARTIAL) {
2631 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2632 escan_result_le = (struct brcmf_escan_result_le *) data;
2633 if (!escan_result_le) {
2634 brcmf_err("Invalid escan result (NULL pointer)\n");
2637 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2638 brcmf_err("Invalid bss_count %d: ignoring\n",
2639 escan_result_le->bss_count);
2642 bss_info_le = &escan_result_le->bss_info_le;
2644 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2647 if (!cfg->scan_request) {
2648 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2652 bi_length = le32_to_cpu(bss_info_le->length);
2653 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2654 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2655 brcmf_err("Invalid bss_info length %d: ignoring\n",
2660 if (!(cfg_to_wiphy(cfg)->interface_modes &
2661 BIT(NL80211_IFTYPE_ADHOC))) {
2662 if (le16_to_cpu(bss_info_le->capability) &
2663 WLAN_CAPABILITY_IBSS) {
2664 brcmf_err("Ignoring IBSS result\n");
2669 list = (struct brcmf_scan_results *)
2670 cfg->escan_info.escan_buf;
2671 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2672 brcmf_err("Buffer is too small: ignoring\n");
2676 for (i = 0; i < list->count; i++) {
2677 bss = bss ? (struct brcmf_bss_info_le *)
2678 ((unsigned char *)bss +
2679 le32_to_cpu(bss->length)) : list->bss_info_le;
2680 if (brcmf_compare_update_same_bss(cfg, bss,
2684 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2685 bss_info_le, bi_length);
2686 list->version = le32_to_cpu(bss_info_le->version);
2687 list->buflen += bi_length;
2690 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2691 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2693 if (cfg->scan_request) {
2694 cfg->bss_list = (struct brcmf_scan_results *)
2695 cfg->escan_info.escan_buf;
2696 brcmf_inform_bss(cfg);
2697 aborted = status != BRCMF_E_STATUS_SUCCESS;
2698 brcmf_notify_escan_complete(cfg, ifp, aborted,
2701 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2708 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2710 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2711 brcmf_cfg80211_escan_handler);
2712 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2713 /* Init scan_timeout timer */
2714 init_timer(&cfg->escan_timeout);
2715 cfg->escan_timeout.data = (unsigned long) cfg;
2716 cfg->escan_timeout.function = brcmf_escan_timeout;
2717 INIT_WORK(&cfg->escan_timeout_work,
2718 brcmf_cfg80211_escan_timeout_worker);
2721 static __always_inline void brcmf_delay(u32 ms)
2723 if (ms < 1000 / HZ) {
2731 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2733 brcmf_dbg(TRACE, "Enter\n");
2738 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2739 struct cfg80211_wowlan *wow)
2741 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2742 struct net_device *ndev = cfg_to_ndev(cfg);
2743 struct brcmf_cfg80211_vif *vif;
2745 brcmf_dbg(TRACE, "Enter\n");
2748 * if the primary net_device is not READY there is nothing
2749 * we can do but pray resume goes smoothly.
2751 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2752 if (!check_vif_up(vif))
2755 list_for_each_entry(vif, &cfg->vif_list, list) {
2756 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2759 * While going to suspend if associated with AP disassociate
2760 * from AP to save power while system is in suspended state
2762 brcmf_link_down(vif);
2764 /* Make sure WPA_Supplicant receives all the event
2765 * generated due to DISASSOC call to the fw to keep
2766 * the state fw and WPA_Supplicant state consistent
2771 /* end any scanning */
2772 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2773 brcmf_abort_scanning(cfg);
2775 /* Turn off watchdog timer */
2776 brcmf_set_mpc(netdev_priv(ndev), 1);
2779 brcmf_dbg(TRACE, "Exit\n");
2780 /* clear any scanning activity */
2781 cfg->scan_status = 0;
2786 brcmf_update_pmklist(struct net_device *ndev,
2787 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2792 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2794 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2795 for (i = 0; i < pmkid_len; i++) {
2796 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2797 &pmk_list->pmkids.pmkid[i].BSSID);
2798 for (j = 0; j < WLAN_PMKID_LEN; j++)
2799 brcmf_dbg(CONN, "%02x\n",
2800 pmk_list->pmkids.pmkid[i].PMKID[j]);
2804 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2805 (char *)pmk_list, sizeof(*pmk_list));
2811 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2812 struct cfg80211_pmksa *pmksa)
2814 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2815 struct brcmf_if *ifp = netdev_priv(ndev);
2816 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2821 brcmf_dbg(TRACE, "Enter\n");
2822 if (!check_vif_up(ifp->vif))
2825 pmkid_len = le32_to_cpu(pmkids->npmkid);
2826 for (i = 0; i < pmkid_len; i++)
2827 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2829 if (i < WL_NUM_PMKIDS_MAX) {
2830 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2831 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2832 if (i == pmkid_len) {
2834 pmkids->npmkid = cpu_to_le32(pmkid_len);
2839 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2840 pmkids->pmkid[pmkid_len].BSSID);
2841 for (i = 0; i < WLAN_PMKID_LEN; i++)
2842 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2844 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2846 brcmf_dbg(TRACE, "Exit\n");
2851 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2852 struct cfg80211_pmksa *pmksa)
2854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2855 struct brcmf_if *ifp = netdev_priv(ndev);
2856 struct pmkid_list pmkid;
2860 brcmf_dbg(TRACE, "Enter\n");
2861 if (!check_vif_up(ifp->vif))
2864 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2865 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2867 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2868 &pmkid.pmkid[0].BSSID);
2869 for (i = 0; i < WLAN_PMKID_LEN; i++)
2870 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2872 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2873 for (i = 0; i < pmkid_len; i++)
2875 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2880 && (i < pmkid_len)) {
2881 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2882 sizeof(struct pmkid));
2883 for (; i < (pmkid_len - 1); i++) {
2884 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2885 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2887 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2888 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2891 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2895 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2897 brcmf_dbg(TRACE, "Exit\n");
2903 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2905 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2906 struct brcmf_if *ifp = netdev_priv(ndev);
2909 brcmf_dbg(TRACE, "Enter\n");
2910 if (!check_vif_up(ifp->vif))
2913 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2914 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2916 brcmf_dbg(TRACE, "Exit\n");
2922 * PFN result doesn't have all the info which are
2923 * required by the supplicant
2924 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2925 * via wl_inform_single_bss in the required format. Escan does require the
2926 * scan request in the form of cfg80211_scan_request. For timebeing, create
2927 * cfg80211_scan_request one out of the received PNO event.
2930 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2931 const struct brcmf_event_msg *e, void *data)
2933 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2934 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2935 struct cfg80211_scan_request *request = NULL;
2936 struct cfg80211_ssid *ssid = NULL;
2937 struct ieee80211_channel *channel = NULL;
2938 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2940 int channel_req = 0;
2942 struct brcmf_pno_scanresults_le *pfn_result;
2946 brcmf_dbg(SCAN, "Enter\n");
2948 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2949 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2953 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2954 result_count = le32_to_cpu(pfn_result->count);
2955 status = le32_to_cpu(pfn_result->status);
2958 * PFN event is limited to fit 512 bytes so we may get
2959 * multiple NET_FOUND events. For now place a warning here.
2961 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2962 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2963 if (result_count > 0) {
2966 request = kzalloc(sizeof(*request), GFP_KERNEL);
2967 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2968 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2969 if (!request || !ssid || !channel) {
2974 request->wiphy = wiphy;
2975 data += sizeof(struct brcmf_pno_scanresults_le);
2976 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2978 for (i = 0; i < result_count; i++) {
2979 netinfo = &netinfo_start[i];
2981 brcmf_err("Invalid netinfo ptr. index: %d\n",
2987 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2988 netinfo->SSID, netinfo->channel);
2989 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2990 ssid[i].ssid_len = netinfo->SSID_len;
2993 channel_req = netinfo->channel;
2994 if (channel_req <= CH_MAX_2G_CHANNEL)
2995 band = NL80211_BAND_2GHZ;
2997 band = NL80211_BAND_5GHZ;
2998 channel[i].center_freq =
2999 ieee80211_channel_to_frequency(channel_req,
3001 channel[i].band = band;
3002 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3003 request->channels[i] = &channel[i];
3004 request->n_channels++;
3007 /* assign parsed ssid array */
3008 if (request->n_ssids)
3009 request->ssids = &ssid[0];
3011 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3012 /* Abort any on-going scan */
3013 brcmf_abort_scanning(cfg);
3016 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3017 cfg->escan_info.run = brcmf_run_escan;
3018 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3020 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3023 cfg->sched_escan = true;
3024 cfg->scan_request = request;
3026 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3039 cfg80211_sched_scan_stopped(wiphy);
3043 static int brcmf_dev_pno_clean(struct net_device *ndev)
3048 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3051 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3055 brcmf_err("failed code %d\n", ret);
3060 static int brcmf_dev_pno_config(struct net_device *ndev)
3062 struct brcmf_pno_param_le pfn_param;
3064 memset(&pfn_param, 0, sizeof(pfn_param));
3065 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3067 /* set extra pno params */
3068 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3069 pfn_param.repeat = BRCMF_PNO_REPEAT;
3070 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3072 /* set up pno scan fr */
3073 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3075 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3076 &pfn_param, sizeof(pfn_param));
3080 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3081 struct net_device *ndev,
3082 struct cfg80211_sched_scan_request *request)
3084 struct brcmf_if *ifp = netdev_priv(ndev);
3085 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3086 struct brcmf_pno_net_param_le pfn;
3090 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3091 request->n_match_sets, request->n_ssids);
3092 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3093 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3096 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3097 brcmf_err("Scanning suppressed: status (%lu)\n",
3102 if (!request->n_ssids || !request->n_match_sets) {
3103 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3108 if (request->n_ssids > 0) {
3109 for (i = 0; i < request->n_ssids; i++) {
3110 /* Active scan req for ssids */
3111 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3112 request->ssids[i].ssid);
3115 * match_set ssids is a supert set of n_ssid list,
3116 * so we need not add these set seperately.
3121 if (request->n_match_sets > 0) {
3122 /* clean up everything */
3123 ret = brcmf_dev_pno_clean(ndev);
3125 brcmf_err("failed error=%d\n", ret);
3130 ret = brcmf_dev_pno_config(ndev);
3132 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3136 /* configure each match set */
3137 for (i = 0; i < request->n_match_sets; i++) {
3138 struct cfg80211_ssid *ssid;
3141 ssid = &request->match_sets[i].ssid;
3142 ssid_len = ssid->ssid_len;
3145 brcmf_err("skip broadcast ssid\n");
3148 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3149 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3150 pfn.wsec = cpu_to_le32(0);
3151 pfn.infra = cpu_to_le32(1);
3152 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3153 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3154 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3155 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3157 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3158 ret == 0 ? "set" : "failed", ssid->ssid);
3160 /* Enable the PNO */
3161 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3162 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3172 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3173 struct net_device *ndev)
3175 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3177 brcmf_dbg(SCAN, "enter\n");
3178 brcmf_dev_pno_clean(ndev);
3179 if (cfg->sched_escan)
3180 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3184 #ifdef CONFIG_NL80211_TESTMODE
3185 static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3186 struct wireless_dev *wdev,
3187 void *data, int len)
3189 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3190 struct net_device *ndev = cfg_to_ndev(cfg);
3191 struct brcmf_dcmd *dcmd = data;
3192 struct sk_buff *reply;
3195 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3196 dcmd->buf, dcmd->len);
3199 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3200 dcmd->buf, dcmd->len);
3202 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3203 dcmd->buf, dcmd->len);
3205 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3206 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3207 ret = cfg80211_testmode_reply(reply);
3213 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3218 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3220 brcmf_err("auth error %d\n", err);
3224 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3226 brcmf_err("wsec error %d\n", err);
3229 /* set upper-layer auth */
3230 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3232 brcmf_err("wpa_auth error %d\n", err);
3239 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3242 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3244 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3248 brcmf_configure_wpaie(struct net_device *ndev,
3249 const struct brcmf_vs_tlv *wpa_ie,
3252 struct brcmf_if *ifp = netdev_priv(ndev);
3253 u32 auth = 0; /* d11 open authentication */
3265 u32 wme_bss_disable;
3267 brcmf_dbg(TRACE, "Enter\n");
3271 len = wpa_ie->len + TLV_HDR_LEN;
3272 data = (u8 *)wpa_ie;
3273 offset = TLV_HDR_LEN;
3275 offset += VS_IE_FIXED_HDR_LEN;
3277 offset += WPA_IE_VERSION_LEN;
3279 /* check for multicast cipher suite */
3280 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3282 brcmf_err("no multicast cipher suite\n");
3286 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3288 brcmf_err("ivalid OUI\n");
3291 offset += TLV_OUI_LEN;
3293 /* pick up multicast cipher */
3294 switch (data[offset]) {
3295 case WPA_CIPHER_NONE:
3298 case WPA_CIPHER_WEP_40:
3299 case WPA_CIPHER_WEP_104:
3302 case WPA_CIPHER_TKIP:
3303 gval = TKIP_ENABLED;
3305 case WPA_CIPHER_AES_CCM:
3310 brcmf_err("Invalid multi cast cipher info\n");
3315 /* walk thru unicast cipher list and pick up what we recognize */
3316 count = data[offset] + (data[offset + 1] << 8);
3317 offset += WPA_IE_SUITE_COUNT_LEN;
3318 /* Check for unicast suite(s) */
3319 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3321 brcmf_err("no unicast cipher suite\n");
3324 for (i = 0; i < count; i++) {
3325 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3327 brcmf_err("ivalid OUI\n");
3330 offset += TLV_OUI_LEN;
3331 switch (data[offset]) {
3332 case WPA_CIPHER_NONE:
3334 case WPA_CIPHER_WEP_40:
3335 case WPA_CIPHER_WEP_104:
3336 pval |= WEP_ENABLED;
3338 case WPA_CIPHER_TKIP:
3339 pval |= TKIP_ENABLED;
3341 case WPA_CIPHER_AES_CCM:
3342 pval |= AES_ENABLED;
3345 brcmf_err("Ivalid unicast security info\n");
3349 /* walk thru auth management suite list and pick up what we recognize */
3350 count = data[offset] + (data[offset + 1] << 8);
3351 offset += WPA_IE_SUITE_COUNT_LEN;
3352 /* Check for auth key management suite(s) */
3353 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3355 brcmf_err("no auth key mgmt suite\n");
3358 for (i = 0; i < count; i++) {
3359 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3361 brcmf_err("ivalid OUI\n");
3364 offset += TLV_OUI_LEN;
3365 switch (data[offset]) {
3367 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3368 wpa_auth |= WPA_AUTH_NONE;
3370 case RSN_AKM_UNSPECIFIED:
3371 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3372 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3373 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3376 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3377 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3378 (wpa_auth |= WPA_AUTH_PSK);
3381 brcmf_err("Ivalid key mgmt info\n");
3387 wme_bss_disable = 1;
3388 if ((offset + RSN_CAP_LEN) <= len) {
3389 rsn_cap = data[offset] + (data[offset + 1] << 8);
3390 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3391 wme_bss_disable = 0;
3393 /* set wme_bss_disable to sync RSN Capabilities */
3394 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3397 brcmf_err("wme_bss_disable error %d\n", err);
3401 /* FOR WPS , set SES_OW_ENABLED */
3402 wsec = (pval | gval | SES_OW_ENABLED);
3405 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3407 brcmf_err("auth error %d\n", err);
3411 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3413 brcmf_err("wsec error %d\n", err);
3416 /* set upper-layer auth */
3417 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3419 brcmf_err("wpa_auth error %d\n", err);
3428 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3429 struct parsed_vndr_ies *vndr_ies)
3432 struct brcmf_vs_tlv *vndrie;
3433 struct brcmf_tlv *ie;
3434 struct parsed_vndr_ie_info *parsed_info;
3437 remaining_len = (s32)vndr_ie_len;
3438 memset(vndr_ies, 0, sizeof(*vndr_ies));
3440 ie = (struct brcmf_tlv *)vndr_ie_buf;
3442 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3444 vndrie = (struct brcmf_vs_tlv *)ie;
3445 /* len should be bigger than OUI length + one */
3446 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3447 brcmf_err("invalid vndr ie. length is too small %d\n",
3451 /* if wpa or wme ie, do not add ie */
3452 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3453 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3454 (vndrie->oui_type == WME_OUI_TYPE))) {
3455 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3459 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3461 /* save vndr ie information */
3462 parsed_info->ie_ptr = (char *)vndrie;
3463 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3464 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3468 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3469 parsed_info->vndrie.oui[0],
3470 parsed_info->vndrie.oui[1],
3471 parsed_info->vndrie.oui[2],
3472 parsed_info->vndrie.oui_type);
3474 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3477 remaining_len -= (ie->len + TLV_HDR_LEN);
3478 if (remaining_len <= TLV_HDR_LEN)
3481 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3488 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3494 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3495 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3497 iecount_le = cpu_to_le32(1);
3498 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3500 pktflag_le = cpu_to_le32(pktflag);
3501 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3503 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3505 return ie_len + VNDR_IE_HDR_SIZE;
3508 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3509 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3511 struct brcmf_if *ifp;
3512 struct vif_saved_ie *saved_ie;
3516 u8 *mgmt_ie_buf = NULL;
3517 int mgmt_ie_buf_len;
3519 u32 del_add_ie_buf_len = 0;
3520 u32 total_ie_buf_len = 0;
3521 u32 parsed_ie_buf_len = 0;
3522 struct parsed_vndr_ies old_vndr_ies;
3523 struct parsed_vndr_ies new_vndr_ies;
3524 struct parsed_vndr_ie_info *vndrie_info;
3527 int remained_buf_len;
3532 saved_ie = &vif->saved_ie;
3534 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3535 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3538 curr_ie_buf = iovar_ie_buf;
3540 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3541 mgmt_ie_buf = saved_ie->probe_req_ie;
3542 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3543 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3545 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3546 mgmt_ie_buf = saved_ie->probe_res_ie;
3547 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3548 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3550 case BRCMF_VNDR_IE_BEACON_FLAG:
3551 mgmt_ie_buf = saved_ie->beacon_ie;
3552 mgmt_ie_len = &saved_ie->beacon_ie_len;
3553 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3555 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3556 mgmt_ie_buf = saved_ie->assoc_req_ie;
3557 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3558 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3562 brcmf_err("not suitable type\n");
3566 if (vndr_ie_len > mgmt_ie_buf_len) {
3568 brcmf_err("extra IE size too big\n");
3572 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3573 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3575 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3576 for (i = 0; i < new_vndr_ies.count; i++) {
3577 vndrie_info = &new_vndr_ies.ie_info[i];
3578 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3579 vndrie_info->ie_len);
3580 parsed_ie_buf_len += vndrie_info->ie_len;
3584 if (mgmt_ie_buf && *mgmt_ie_len) {
3585 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3586 (memcmp(mgmt_ie_buf, curr_ie_buf,
3587 parsed_ie_buf_len) == 0)) {
3588 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3592 /* parse old vndr_ie */
3593 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3595 /* make a command to delete old ie */
3596 for (i = 0; i < old_vndr_ies.count; i++) {
3597 vndrie_info = &old_vndr_ies.ie_info[i];
3599 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3600 vndrie_info->vndrie.id,
3601 vndrie_info->vndrie.len,
3602 vndrie_info->vndrie.oui[0],
3603 vndrie_info->vndrie.oui[1],
3604 vndrie_info->vndrie.oui[2]);
3606 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3607 vndrie_info->ie_ptr,
3608 vndrie_info->ie_len,
3610 curr_ie_buf += del_add_ie_buf_len;
3611 total_ie_buf_len += del_add_ie_buf_len;
3616 /* Add if there is any extra IE */
3617 if (mgmt_ie_buf && parsed_ie_buf_len) {
3620 remained_buf_len = mgmt_ie_buf_len;
3622 /* make a command to add new ie */
3623 for (i = 0; i < new_vndr_ies.count; i++) {
3624 vndrie_info = &new_vndr_ies.ie_info[i];
3626 /* verify remained buf size before copy data */
3627 if (remained_buf_len < (vndrie_info->vndrie.len +
3628 VNDR_IE_VSIE_OFFSET)) {
3629 brcmf_err("no space in mgmt_ie_buf: len left %d",
3633 remained_buf_len -= (vndrie_info->ie_len +
3634 VNDR_IE_VSIE_OFFSET);
3636 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3637 vndrie_info->vndrie.id,
3638 vndrie_info->vndrie.len,
3639 vndrie_info->vndrie.oui[0],
3640 vndrie_info->vndrie.oui[1],
3641 vndrie_info->vndrie.oui[2]);
3643 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3644 vndrie_info->ie_ptr,
3645 vndrie_info->ie_len,
3648 /* save the parsed IE in wl struct */
3649 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3650 vndrie_info->ie_len);
3651 *mgmt_ie_len += vndrie_info->ie_len;
3653 curr_ie_buf += del_add_ie_buf_len;
3654 total_ie_buf_len += del_add_ie_buf_len;
3657 if (total_ie_buf_len) {
3658 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3661 brcmf_err("vndr ie set error : %d\n", err);
3665 kfree(iovar_ie_buf);
3669 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3672 BRCMF_VNDR_IE_PRBREQ_FLAG,
3673 BRCMF_VNDR_IE_PRBRSP_FLAG,
3674 BRCMF_VNDR_IE_BEACON_FLAG
3678 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3679 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3681 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3686 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3687 struct cfg80211_beacon_data *beacon)
3691 /* Set Beacon IEs to FW */
3692 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3693 beacon->tail, beacon->tail_len);
3695 brcmf_err("Set Beacon IE Failed\n");
3698 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3700 /* Set Probe Response IEs to FW */
3701 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3702 beacon->proberesp_ies,
3703 beacon->proberesp_ies_len);
3705 brcmf_err("Set Probe Resp IE Failed\n");
3707 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3713 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3714 struct brcmf_if *ifp,
3715 struct ieee80211_channel *channel)
3720 brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3721 channel->center_freq);
3723 chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3724 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3730 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3731 struct cfg80211_ap_settings *settings)
3734 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3735 struct brcmf_if *ifp = netdev_priv(ndev);
3736 const struct brcmf_tlv *ssid_ie;
3737 struct brcmf_ssid_le ssid_le;
3739 const struct brcmf_tlv *rsn_ie;
3740 const struct brcmf_vs_tlv *wpa_ie;
3741 struct brcmf_join_params join_params;
3742 enum nl80211_iftype dev_role;
3743 struct brcmf_fil_bss_enable_le bss_enable;
3745 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3746 cfg80211_get_chandef_type(&settings->chandef),
3747 settings->beacon_interval,
3748 settings->dtim_period);
3749 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3750 settings->ssid, settings->ssid_len, settings->auth_type,
3751 settings->inactivity_timeout);
3753 dev_role = ifp->vif->wdev.iftype;
3755 memset(&ssid_le, 0, sizeof(ssid_le));
3756 if (settings->ssid == NULL || settings->ssid_len == 0) {
3757 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3758 ssid_ie = brcmf_parse_tlvs(
3759 (u8 *)&settings->beacon.head[ie_offset],
3760 settings->beacon.head_len - ie_offset,
3765 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3766 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3767 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3769 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3770 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3773 brcmf_set_mpc(ifp, 0);
3774 brcmf_configure_arp_offload(ifp, false);
3776 /* find the RSN_IE */
3777 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3778 settings->beacon.tail_len, WLAN_EID_RSN);
3780 /* find the WPA_IE */
3781 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3782 settings->beacon.tail_len);
3784 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3785 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3786 if (wpa_ie != NULL) {
3788 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3793 err = brcmf_configure_wpaie(ndev,
3794 (struct brcmf_vs_tlv *)rsn_ie, true);
3799 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3800 brcmf_configure_opensecurity(ifp);
3803 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3805 err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
3807 brcmf_err("Set Channel failed, %d\n", err);
3811 if (settings->beacon_interval) {
3812 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3813 settings->beacon_interval);
3815 brcmf_err("Beacon Interval Set Error, %d\n", err);
3819 if (settings->dtim_period) {
3820 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3821 settings->dtim_period);
3823 brcmf_err("DTIM Interval Set Error, %d\n", err);
3828 if (dev_role == NL80211_IFTYPE_AP) {
3829 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3831 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3834 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3837 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3839 brcmf_err("SET INFRA error %d\n", err);
3842 if (dev_role == NL80211_IFTYPE_AP) {
3843 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3845 brcmf_err("setting AP mode failed %d\n", err);
3848 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3850 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3854 memset(&join_params, 0, sizeof(join_params));
3855 /* join parameters starts with ssid */
3856 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3858 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3859 &join_params, sizeof(join_params));
3861 brcmf_err("SET SSID error (%d)\n", err);
3864 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3866 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3869 brcmf_err("setting ssid failed %d\n", err);
3872 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3873 bss_enable.enable = cpu_to_le32(1);
3874 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3875 sizeof(bss_enable));
3877 brcmf_err("bss_enable config failed %d\n", err);
3881 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3883 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3884 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3888 brcmf_set_mpc(ifp, 1);
3889 brcmf_configure_arp_offload(ifp, true);
3894 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3896 struct brcmf_if *ifp = netdev_priv(ndev);
3898 struct brcmf_fil_bss_enable_le bss_enable;
3899 struct brcmf_join_params join_params;
3901 brcmf_dbg(TRACE, "Enter\n");
3903 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3904 /* Due to most likely deauths outstanding we sleep */
3905 /* first to make sure they get processed by fw. */
3908 memset(&join_params, 0, sizeof(join_params));
3909 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3910 &join_params, sizeof(join_params));
3912 brcmf_err("SET SSID error (%d)\n", err);
3913 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3915 brcmf_err("BRCMF_C_UP error %d\n", err);
3916 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3918 brcmf_err("setting AP mode failed %d\n", err);
3919 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3921 brcmf_err("setting INFRA mode failed %d\n", err);
3923 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3924 bss_enable.enable = cpu_to_le32(0);
3925 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3926 sizeof(bss_enable));
3928 brcmf_err("bss_enable config failed %d\n", err);
3930 brcmf_set_mpc(ifp, 1);
3931 brcmf_configure_arp_offload(ifp, true);
3932 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3933 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3939 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3940 struct cfg80211_beacon_data *info)
3942 struct brcmf_if *ifp = netdev_priv(ndev);
3945 brcmf_dbg(TRACE, "Enter\n");
3947 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3953 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3956 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3957 struct brcmf_scb_val_le scbval;
3958 struct brcmf_if *ifp = netdev_priv(ndev);
3964 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3966 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3967 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3968 if (!check_vif_up(ifp->vif))
3971 memcpy(&scbval.ea, mac, ETH_ALEN);
3972 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3973 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3974 &scbval, sizeof(scbval));
3976 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3978 brcmf_dbg(TRACE, "Exit\n");
3984 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3985 struct wireless_dev *wdev,
3986 u16 frame_type, bool reg)
3988 struct brcmf_cfg80211_vif *vif;
3991 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3993 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3994 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3996 vif->mgmt_rx_reg |= BIT(mgmt_type);
3998 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4003 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4004 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4006 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4007 struct ieee80211_channel *chan = params->chan;
4008 const u8 *buf = params->buf;
4009 size_t len = params->len;
4010 const struct ieee80211_mgmt *mgmt;
4011 struct brcmf_cfg80211_vif *vif;
4015 struct brcmf_fil_action_frame_le *action_frame;
4016 struct brcmf_fil_af_params_le *af_params;
4021 brcmf_dbg(TRACE, "Enter\n");
4025 mgmt = (const struct ieee80211_mgmt *)buf;
4027 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4028 brcmf_err("Driver only allows MGMT packet type\n");
4032 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4034 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4035 /* Right now the only reason to get a probe response */
4036 /* is for p2p listen response or for p2p GO from */
4037 /* wpa_supplicant. Unfortunately the probe is send */
4038 /* on primary ndev, while dongle wants it on the p2p */
4039 /* vif. Since this is only reason for a probe */
4040 /* response to be sent, the vif is taken from cfg. */
4041 /* If ever desired to send proberesp for non p2p */
4042 /* response then data should be checked for */
4043 /* "DIRECT-". Note in future supplicant will take */
4044 /* dedicated p2p wdev to do this and then this 'hack'*/
4045 /* is not needed anymore. */
4046 ie_offset = DOT11_MGMT_HDR_LEN +
4047 DOT11_BCN_PRB_FIXED_LEN;
4048 ie_len = len - ie_offset;
4049 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4050 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4051 err = brcmf_vif_set_mgmt_ie(vif,
4052 BRCMF_VNDR_IE_PRBRSP_FLAG,
4055 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4057 } else if (ieee80211_is_action(mgmt->frame_control)) {
4058 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4059 if (af_params == NULL) {
4060 brcmf_err("unable to allocate frame\n");
4064 action_frame = &af_params->action_frame;
4065 /* Add the packet Id */
4066 action_frame->packet_id = cpu_to_le32(*cookie);
4068 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4069 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4070 /* Add the length exepted for 802.11 header */
4071 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4072 /* Add the channel. Use the one specified as parameter if any or
4073 * the current one (got from the firmware) otherwise
4076 freq = chan->center_freq;
4078 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4080 chan_nr = ieee80211_frequency_to_channel(freq);
4081 af_params->channel = cpu_to_le32(chan_nr);
4083 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4084 le16_to_cpu(action_frame->len));
4086 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4087 *cookie, le16_to_cpu(action_frame->len), freq);
4089 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4092 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4096 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4097 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4106 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4107 struct wireless_dev *wdev,
4110 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4111 struct brcmf_cfg80211_vif *vif;
4114 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4116 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4118 brcmf_err("No p2p device available for probe response\n");
4122 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4127 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4128 struct wireless_dev *wdev,
4129 enum nl80211_crit_proto_id proto,
4132 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4133 struct brcmf_cfg80211_vif *vif;
4135 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4137 /* only DHCP support for now */
4138 if (proto != NL80211_CRIT_PROTO_DHCP)
4141 /* suppress and abort scanning */
4142 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4143 brcmf_abort_scanning(cfg);
4145 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4148 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4149 struct wireless_dev *wdev)
4151 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4152 struct brcmf_cfg80211_vif *vif;
4154 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4156 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4157 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4160 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4165 case NL80211_TDLS_DISCOVERY_REQ:
4166 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4168 case NL80211_TDLS_SETUP:
4169 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4171 case NL80211_TDLS_TEARDOWN:
4172 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4175 brcmf_err("unsupported operation: %d\n", oper);
4181 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4182 struct net_device *ndev, u8 *peer,
4183 enum nl80211_tdls_operation oper)
4185 struct brcmf_if *ifp;
4186 struct brcmf_tdls_iovar_le info;
4189 ret = brcmf_convert_nl80211_tdls_oper(oper);
4193 ifp = netdev_priv(ndev);
4194 memset(&info, 0, sizeof(info));
4195 info.mode = (u8)ret;
4197 memcpy(info.ea, peer, ETH_ALEN);
4199 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4200 &info, sizeof(info));
4202 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4207 static struct cfg80211_ops wl_cfg80211_ops = {
4208 .add_virtual_intf = brcmf_cfg80211_add_iface,
4209 .del_virtual_intf = brcmf_cfg80211_del_iface,
4210 .change_virtual_intf = brcmf_cfg80211_change_iface,
4211 .scan = brcmf_cfg80211_scan,
4212 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4213 .join_ibss = brcmf_cfg80211_join_ibss,
4214 .leave_ibss = brcmf_cfg80211_leave_ibss,
4215 .get_station = brcmf_cfg80211_get_station,
4216 .set_tx_power = brcmf_cfg80211_set_tx_power,
4217 .get_tx_power = brcmf_cfg80211_get_tx_power,
4218 .add_key = brcmf_cfg80211_add_key,
4219 .del_key = brcmf_cfg80211_del_key,
4220 .get_key = brcmf_cfg80211_get_key,
4221 .set_default_key = brcmf_cfg80211_config_default_key,
4222 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4223 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4224 .connect = brcmf_cfg80211_connect,
4225 .disconnect = brcmf_cfg80211_disconnect,
4226 .suspend = brcmf_cfg80211_suspend,
4227 .resume = brcmf_cfg80211_resume,
4228 .set_pmksa = brcmf_cfg80211_set_pmksa,
4229 .del_pmksa = brcmf_cfg80211_del_pmksa,
4230 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4231 .start_ap = brcmf_cfg80211_start_ap,
4232 .stop_ap = brcmf_cfg80211_stop_ap,
4233 .change_beacon = brcmf_cfg80211_change_beacon,
4234 .del_station = brcmf_cfg80211_del_station,
4235 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4236 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4237 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4238 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4239 .remain_on_channel = brcmf_p2p_remain_on_channel,
4240 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4241 .start_p2p_device = brcmf_p2p_start_device,
4242 .stop_p2p_device = brcmf_p2p_stop_device,
4243 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4244 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4245 .tdls_oper = brcmf_cfg80211_tdls_oper,
4246 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4249 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4252 case NL80211_IFTYPE_AP_VLAN:
4253 case NL80211_IFTYPE_WDS:
4254 case NL80211_IFTYPE_MONITOR:
4255 case NL80211_IFTYPE_MESH_POINT:
4257 case NL80211_IFTYPE_ADHOC:
4258 return WL_MODE_IBSS;
4259 case NL80211_IFTYPE_STATION:
4260 case NL80211_IFTYPE_P2P_CLIENT:
4262 case NL80211_IFTYPE_AP:
4263 case NL80211_IFTYPE_P2P_GO:
4265 case NL80211_IFTYPE_P2P_DEVICE:
4267 case NL80211_IFTYPE_UNSPECIFIED:
4275 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4277 /* scheduled scan settings */
4278 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4279 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4280 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4281 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4284 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4287 .types = BIT(NL80211_IFTYPE_STATION) |
4288 BIT(NL80211_IFTYPE_ADHOC) |
4289 BIT(NL80211_IFTYPE_AP)
4293 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4294 BIT(NL80211_IFTYPE_P2P_GO)
4298 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4301 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4303 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4304 .num_different_channels = 2,
4305 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4306 .limits = brcmf_iface_limits
4310 static const struct ieee80211_txrx_stypes
4311 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4312 [NL80211_IFTYPE_STATION] = {
4314 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4315 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4317 [NL80211_IFTYPE_P2P_CLIENT] = {
4319 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4320 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4322 [NL80211_IFTYPE_P2P_GO] = {
4324 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4325 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4326 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4327 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4328 BIT(IEEE80211_STYPE_AUTH >> 4) |
4329 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4330 BIT(IEEE80211_STYPE_ACTION >> 4)
4332 [NL80211_IFTYPE_P2P_DEVICE] = {
4334 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4335 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4339 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4341 struct wiphy *wiphy;
4344 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4346 brcmf_err("Could not allocate wiphy device\n");
4347 return ERR_PTR(-ENOMEM);
4349 set_wiphy_dev(wiphy, phydev);
4350 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4351 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4352 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4353 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4354 BIT(NL80211_IFTYPE_ADHOC) |
4355 BIT(NL80211_IFTYPE_AP) |
4356 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4357 BIT(NL80211_IFTYPE_P2P_GO) |
4358 BIT(NL80211_IFTYPE_P2P_DEVICE);
4359 wiphy->iface_combinations = brcmf_iface_combos;
4360 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4361 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4362 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4363 wiphy->cipher_suites = __wl_cipher_suites;
4364 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4365 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4366 WIPHY_FLAG_OFFCHAN_TX |
4367 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4368 WIPHY_FLAG_SUPPORTS_TDLS;
4369 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4370 wiphy->max_remain_on_channel_duration = 5000;
4371 brcmf_wiphy_pno_params(wiphy);
4372 brcmf_dbg(INFO, "Registering custom regulatory\n");
4373 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4374 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4375 err = wiphy_register(wiphy);
4377 brcmf_err("Could not register wiphy device (%d)\n", err);
4379 return ERR_PTR(err);
4384 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4385 enum nl80211_iftype type,
4388 struct brcmf_cfg80211_vif *vif;
4390 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4392 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4394 return ERR_PTR(-ENOMEM);
4396 vif->wdev.wiphy = cfg->wiphy;
4397 vif->wdev.iftype = type;
4399 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4400 vif->pm_block = pm_block;
4403 brcmf_init_prof(&vif->profile);
4405 list_add_tail(&vif->list, &cfg->vif_list);
4409 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4411 list_del(&vif->list);
4415 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4417 struct brcmf_cfg80211_vif *vif;
4418 struct brcmf_if *ifp;
4420 ifp = netdev_priv(ndev);
4423 brcmf_free_vif(vif);
4427 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4429 u32 event = e->event_code;
4430 u32 status = e->status;
4432 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4433 brcmf_dbg(CONN, "Processing set ssid\n");
4440 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4442 u32 event = e->event_code;
4443 u16 flags = e->flags;
4445 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4446 brcmf_dbg(CONN, "Processing link down\n");
4452 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4453 const struct brcmf_event_msg *e)
4455 u32 event = e->event_code;
4456 u32 status = e->status;
4458 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4459 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4460 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4464 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4465 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4472 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4474 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4476 kfree(conn_info->req_ie);
4477 conn_info->req_ie = NULL;
4478 conn_info->req_ie_len = 0;
4479 kfree(conn_info->resp_ie);
4480 conn_info->resp_ie = NULL;
4481 conn_info->resp_ie_len = 0;
4484 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4485 struct brcmf_if *ifp)
4487 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4488 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4493 brcmf_clear_assoc_ies(cfg);
4495 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4496 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4498 brcmf_err("could not get assoc info (%d)\n", err);
4502 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4503 req_len = le32_to_cpu(assoc_info->req_len);
4504 resp_len = le32_to_cpu(assoc_info->resp_len);
4506 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4510 brcmf_err("could not get assoc req (%d)\n", err);
4513 conn_info->req_ie_len = req_len;
4515 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4518 conn_info->req_ie_len = 0;
4519 conn_info->req_ie = NULL;
4522 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4526 brcmf_err("could not get assoc resp (%d)\n", err);
4529 conn_info->resp_ie_len = resp_len;
4530 conn_info->resp_ie =
4531 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4534 conn_info->resp_ie_len = 0;
4535 conn_info->resp_ie = NULL;
4537 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4538 conn_info->req_ie_len, conn_info->resp_ie_len);
4544 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4545 struct net_device *ndev,
4546 const struct brcmf_event_msg *e)
4548 struct brcmf_if *ifp = netdev_priv(ndev);
4549 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4550 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4551 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4552 struct ieee80211_channel *notify_channel = NULL;
4553 struct ieee80211_supported_band *band;
4554 struct brcmf_bss_info_le *bi;
4555 struct brcmu_chan ch;
4560 brcmf_dbg(TRACE, "Enter\n");
4562 brcmf_get_assoc_ies(cfg, ifp);
4563 memcpy(profile->bssid, e->addr, ETH_ALEN);
4564 brcmf_update_bss_info(cfg, ifp);
4566 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4572 /* data sent to dongle has to be little endian */
4573 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4574 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4575 buf, WL_BSS_INFO_MAX);
4580 bi = (struct brcmf_bss_info_le *)(buf + 4);
4581 ch.chspec = le16_to_cpu(bi->chanspec);
4582 cfg->d11inf.decchspec(&ch);
4584 if (ch.band == BRCMU_CHAN_BAND_2G)
4585 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4587 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4589 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4590 notify_channel = ieee80211_get_channel(wiphy, freq);
4594 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4595 conn_info->req_ie, conn_info->req_ie_len,
4596 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4597 brcmf_dbg(CONN, "Report roaming result\n");
4599 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4600 brcmf_dbg(TRACE, "Exit\n");
4605 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4606 struct net_device *ndev, const struct brcmf_event_msg *e,
4609 struct brcmf_if *ifp = netdev_priv(ndev);
4610 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4611 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4614 brcmf_dbg(TRACE, "Enter\n");
4616 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4617 &ifp->vif->sme_state)) {
4619 brcmf_get_assoc_ies(cfg, ifp);
4620 memcpy(profile->bssid, e->addr, ETH_ALEN);
4621 brcmf_update_bss_info(cfg, ifp);
4622 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4623 &ifp->vif->sme_state);
4625 cfg80211_connect_result(ndev,
4626 (u8 *)profile->bssid,
4628 conn_info->req_ie_len,
4630 conn_info->resp_ie_len,
4631 completed ? WLAN_STATUS_SUCCESS :
4632 WLAN_STATUS_AUTH_TIMEOUT,
4634 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4635 completed ? "succeeded" : "failed");
4637 brcmf_dbg(TRACE, "Exit\n");
4642 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4643 struct net_device *ndev,
4644 const struct brcmf_event_msg *e, void *data)
4646 static int generation;
4647 u32 event = e->event_code;
4648 u32 reason = e->reason;
4649 struct station_info sinfo;
4651 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4652 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4653 ndev != cfg_to_ndev(cfg)) {
4654 brcmf_dbg(CONN, "AP mode link down\n");
4655 complete(&cfg->vif_disabled);
4659 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4660 (reason == BRCMF_E_STATUS_SUCCESS)) {
4661 memset(&sinfo, 0, sizeof(sinfo));
4662 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4664 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4667 sinfo.assoc_req_ies = data;
4668 sinfo.assoc_req_ies_len = e->datalen;
4670 sinfo.generation = generation;
4671 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4672 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4673 (event == BRCMF_E_DEAUTH_IND) ||
4674 (event == BRCMF_E_DEAUTH)) {
4675 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4681 brcmf_notify_connect_status(struct brcmf_if *ifp,
4682 const struct brcmf_event_msg *e, void *data)
4684 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4685 struct net_device *ndev = ifp->ndev;
4686 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4687 struct ieee80211_channel *chan;
4690 if (ifp->vif->mode == WL_MODE_AP) {
4691 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4692 } else if (brcmf_is_linkup(e)) {
4693 brcmf_dbg(CONN, "Linkup\n");
4694 if (brcmf_is_ibssmode(ifp->vif)) {
4695 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4696 memcpy(profile->bssid, e->addr, ETH_ALEN);
4697 wl_inform_ibss(cfg, ndev, e->addr);
4698 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4699 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4700 &ifp->vif->sme_state);
4701 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4702 &ifp->vif->sme_state);
4704 brcmf_bss_connect_done(cfg, ndev, e, true);
4705 } else if (brcmf_is_linkdown(e)) {
4706 brcmf_dbg(CONN, "Linkdown\n");
4707 if (!brcmf_is_ibssmode(ifp->vif)) {
4708 brcmf_bss_connect_done(cfg, ndev, e, false);
4709 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4710 &ifp->vif->sme_state))
4711 cfg80211_disconnected(ndev, 0, NULL, 0,
4714 brcmf_link_down(ifp->vif);
4715 brcmf_init_prof(ndev_to_prof(ndev));
4716 if (ndev != cfg_to_ndev(cfg))
4717 complete(&cfg->vif_disabled);
4718 } else if (brcmf_is_nonetwork(cfg, e)) {
4719 if (brcmf_is_ibssmode(ifp->vif))
4720 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4721 &ifp->vif->sme_state);
4723 brcmf_bss_connect_done(cfg, ndev, e, false);
4730 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4731 const struct brcmf_event_msg *e, void *data)
4733 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4735 u32 event = e->event_code;
4736 u32 status = e->status;
4738 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4739 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4740 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4742 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4749 brcmf_notify_mic_status(struct brcmf_if *ifp,
4750 const struct brcmf_event_msg *e, void *data)
4752 u16 flags = e->flags;
4753 enum nl80211_key_type key_type;
4755 if (flags & BRCMF_EVENT_MSG_GROUP)
4756 key_type = NL80211_KEYTYPE_GROUP;
4758 key_type = NL80211_KEYTYPE_PAIRWISE;
4760 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4766 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4767 const struct brcmf_event_msg *e, void *data)
4769 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4770 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4771 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4772 struct brcmf_cfg80211_vif *vif;
4774 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4775 ifevent->action, ifevent->flags, ifevent->ifidx,
4778 mutex_lock(&event->vif_event_lock);
4779 event->action = ifevent->action;
4782 switch (ifevent->action) {
4783 case BRCMF_E_IF_ADD:
4784 /* waiting process may have timed out */
4785 if (!cfg->vif_event.vif) {
4786 mutex_unlock(&event->vif_event_lock);
4793 vif->wdev.netdev = ifp->ndev;
4794 ifp->ndev->ieee80211_ptr = &vif->wdev;
4795 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4797 mutex_unlock(&event->vif_event_lock);
4798 wake_up(&event->vif_wq);
4801 case BRCMF_E_IF_DEL:
4802 mutex_unlock(&event->vif_event_lock);
4803 /* event may not be upon user request */
4804 if (brcmf_cfg80211_vif_event_armed(cfg))
4805 wake_up(&event->vif_wq);
4808 case BRCMF_E_IF_CHANGE:
4809 mutex_unlock(&event->vif_event_lock);
4810 wake_up(&event->vif_wq);
4814 mutex_unlock(&event->vif_event_lock);
4820 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4822 conf->frag_threshold = (u32)-1;
4823 conf->rts_threshold = (u32)-1;
4824 conf->retry_short = (u32)-1;
4825 conf->retry_long = (u32)-1;
4826 conf->tx_power = -1;
4829 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4831 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4832 brcmf_notify_connect_status);
4833 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4834 brcmf_notify_connect_status);
4835 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4836 brcmf_notify_connect_status);
4837 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4838 brcmf_notify_connect_status);
4839 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4840 brcmf_notify_connect_status);
4841 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4842 brcmf_notify_connect_status);
4843 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4844 brcmf_notify_roaming_status);
4845 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4846 brcmf_notify_mic_status);
4847 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4848 brcmf_notify_connect_status);
4849 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4850 brcmf_notify_sched_scan_results);
4851 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4852 brcmf_notify_vif_event);
4853 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4854 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4855 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4856 brcmf_p2p_notify_listen_complete);
4857 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4858 brcmf_p2p_notify_action_frame_rx);
4859 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4860 brcmf_p2p_notify_action_tx_complete);
4861 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4862 brcmf_p2p_notify_action_tx_complete);
4865 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4869 kfree(cfg->escan_ioctl_buf);
4870 cfg->escan_ioctl_buf = NULL;
4871 kfree(cfg->extra_buf);
4872 cfg->extra_buf = NULL;
4873 kfree(cfg->pmk_list);
4874 cfg->pmk_list = NULL;
4877 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4879 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4881 goto init_priv_mem_out;
4882 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4883 if (!cfg->escan_ioctl_buf)
4884 goto init_priv_mem_out;
4885 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4886 if (!cfg->extra_buf)
4887 goto init_priv_mem_out;
4888 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4890 goto init_priv_mem_out;
4895 brcmf_deinit_priv_mem(cfg);
4900 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4904 cfg->scan_request = NULL;
4905 cfg->pwr_save = true;
4906 cfg->roam_on = true; /* roam on & off switch.
4907 we enable roam per default */
4908 cfg->active_scan = true; /* we do active scan for
4909 specific scan per default */
4910 cfg->dongle_up = false; /* dongle is not up yet */
4911 err = brcmf_init_priv_mem(cfg);
4914 brcmf_register_event_handlers(cfg);
4915 mutex_init(&cfg->usr_sync);
4916 brcmf_init_escan(cfg);
4917 brcmf_init_conf(cfg->conf);
4918 init_completion(&cfg->vif_disabled);
4922 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4924 cfg->dongle_up = false; /* dongle down */
4925 brcmf_abort_scanning(cfg);
4926 brcmf_deinit_priv_mem(cfg);
4929 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4931 init_waitqueue_head(&event->vif_wq);
4932 mutex_init(&event->vif_event_lock);
4935 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4936 struct device *busdev)
4938 struct net_device *ndev = drvr->iflist[0]->ndev;
4939 struct brcmf_cfg80211_info *cfg;
4940 struct wiphy *wiphy;
4941 struct brcmf_cfg80211_vif *vif;
4942 struct brcmf_if *ifp;
4947 brcmf_err("ndev is invalid\n");
4951 ifp = netdev_priv(ndev);
4952 wiphy = brcmf_setup_wiphy(busdev);
4956 cfg = wiphy_priv(wiphy);
4959 init_vif_event(&cfg->vif_event);
4960 INIT_LIST_HEAD(&cfg->vif_list);
4962 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4969 vif->wdev.netdev = ndev;
4970 ndev->ieee80211_ptr = &vif->wdev;
4971 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4973 err = wl_init_priv(cfg);
4975 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4976 goto cfg80211_attach_out;
4980 err = brcmf_p2p_attach(cfg);
4982 brcmf_err("P2P initilisation failed (%d)\n", err);
4983 goto cfg80211_p2p_attach_out;
4985 err = brcmf_btcoex_attach(cfg);
4987 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4988 brcmf_p2p_detach(&cfg->p2p);
4989 goto cfg80211_p2p_attach_out;
4992 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4994 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
4995 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
4998 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
5001 brcmf_err("Failed to get D11 version (%d)\n", err);
5002 goto cfg80211_p2p_attach_out;
5004 cfg->d11inf.io_type = (u8)io_type;
5005 brcmu_d11_attach(&cfg->d11inf);
5009 cfg80211_p2p_attach_out:
5010 wl_deinit_priv(cfg);
5012 cfg80211_attach_out:
5013 brcmf_free_vif(vif);
5017 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5022 WARN_ON(!list_empty(&cfg->vif_list));
5023 wiphy_unregister(cfg->wiphy);
5024 brcmf_btcoex_detach(cfg);
5025 wl_deinit_priv(cfg);
5026 wiphy_free(cfg->wiphy);
5030 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5033 __le32 roamtrigger[2];
5034 __le32 roam_delta[2];
5037 * Setup timeout if Beacons are lost and roam is
5038 * off to report link down
5041 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5043 brcmf_err("bcn_timeout error (%d)\n", err);
5044 goto dongle_rom_out;
5049 * Enable/Disable built-in roaming to allow supplicant
5050 * to take care of roaming
5052 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
5053 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
5055 brcmf_err("roam_off error (%d)\n", err);
5056 goto dongle_rom_out;
5059 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5060 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5061 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5062 (void *)roamtrigger, sizeof(roamtrigger));
5064 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5065 goto dongle_rom_out;
5068 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5069 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5070 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5071 (void *)roam_delta, sizeof(roam_delta));
5073 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5074 goto dongle_rom_out;
5082 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5083 s32 scan_unassoc_time, s32 scan_passive_time)
5087 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5090 if (err == -EOPNOTSUPP)
5091 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5093 brcmf_err("Scan assoc time error (%d)\n", err);
5094 goto dongle_scantime_out;
5096 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5099 if (err == -EOPNOTSUPP)
5100 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5102 brcmf_err("Scan unassoc time error (%d)\n", err);
5103 goto dongle_scantime_out;
5106 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5109 if (err == -EOPNOTSUPP)
5110 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5112 brcmf_err("Scan passive time error (%d)\n", err);
5113 goto dongle_scantime_out;
5116 dongle_scantime_out:
5121 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5124 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5125 struct ieee80211_channel *band_chan_arr;
5126 struct brcmf_chanspec_list *list;
5127 struct brcmu_chan ch;
5132 enum ieee80211_band band;
5140 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5145 list = (struct brcmf_chanspec_list *)pbuf;
5147 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5150 brcmf_err("get chanspecs error (%d)\n", err);
5154 __wl_band_2ghz.n_channels = 0;
5155 __wl_band_5ghz_a.n_channels = 0;
5157 total = le32_to_cpu(list->count);
5158 for (i = 0; i < total; i++) {
5159 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5160 cfg->d11inf.decchspec(&ch);
5162 if (ch.band == BRCMU_CHAN_BAND_2G) {
5163 band_chan_arr = __wl_2ghz_channels;
5164 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5165 n_cnt = &__wl_band_2ghz.n_channels;
5166 band = IEEE80211_BAND_2GHZ;
5167 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5168 band_chan_arr = __wl_5ghz_a_channels;
5169 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5170 n_cnt = &__wl_band_5ghz_a.n_channels;
5171 band = IEEE80211_BAND_5GHZ;
5173 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5176 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5177 ch.bw == BRCMU_CHAN_BW_40)
5180 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5181 if (band_chan_arr[j].hw_value == ch.chnum) {
5190 if (index < array_size) {
5191 band_chan_arr[index].center_freq =
5192 ieee80211_channel_to_frequency(ch.chnum, band);
5193 band_chan_arr[index].hw_value = ch.chnum;
5195 brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5196 ch.chnum, band_chan_arr[index].center_freq,
5198 if (ch.bw == BRCMU_CHAN_BW_40) {
5199 /* assuming the order is HT20, HT40 Upper,
5200 * HT40 lower from chanspecs
5202 ht40_flag = band_chan_arr[index].flags &
5203 IEEE80211_CHAN_NO_HT40;
5204 if (ch.sb == BRCMU_CHAN_SB_U) {
5205 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5206 band_chan_arr[index].flags &=
5207 ~IEEE80211_CHAN_NO_HT40;
5208 band_chan_arr[index].flags |=
5209 IEEE80211_CHAN_NO_HT40PLUS;
5211 /* It should be one of
5212 * IEEE80211_CHAN_NO_HT40 or
5213 * IEEE80211_CHAN_NO_HT40PLUS
5215 band_chan_arr[index].flags &=
5216 ~IEEE80211_CHAN_NO_HT40;
5217 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5218 band_chan_arr[index].flags |=
5219 IEEE80211_CHAN_NO_HT40MINUS;
5222 band_chan_arr[index].flags =
5223 IEEE80211_CHAN_NO_HT40;
5224 ch.bw = BRCMU_CHAN_BW_20;
5225 cfg->d11inf.encchspec(&ch);
5226 channel = ch.chspec;
5227 err = brcmf_fil_bsscfg_int_get(ifp,
5231 if (channel & WL_CHAN_RADAR)
5232 band_chan_arr[index].flags |=
5233 (IEEE80211_CHAN_RADAR |
5234 IEEE80211_CHAN_NO_IR);
5235 if (channel & WL_CHAN_PASSIVE)
5236 band_chan_arr[index].flags |=
5237 IEEE80211_CHAN_NO_IR;
5249 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5251 u32 band, mimo_bwcap;
5255 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5257 bw_cap[IEEE80211_BAND_2GHZ] = band;
5259 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5261 bw_cap[IEEE80211_BAND_5GHZ] = band;
5267 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5269 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5271 /* assume 20MHz if firmware does not give a clue */
5272 mimo_bwcap = WLC_N_BW_20ALL;
5274 switch (mimo_bwcap) {
5275 case WLC_N_BW_40ALL:
5276 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5278 case WLC_N_BW_20IN2G_40IN5G:
5279 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5281 case WLC_N_BW_20ALL:
5282 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5283 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5286 brcmf_err("invalid mimo_bw_cap value\n");
5290 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5292 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5293 struct wiphy *wiphy;
5297 u32 bw_cap[2] = { 0, 0 };
5302 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5303 struct ieee80211_supported_band *band;
5305 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5306 &phy_list, sizeof(phy_list));
5308 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5312 phy = ((char *)&phy_list)[0];
5313 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5316 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5317 &band_list, sizeof(band_list));
5319 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5322 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5323 band_list[0], band_list[1], band_list[2]);
5325 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5327 brcmf_err("nmode error (%d)\n", err);
5329 brcmf_get_bwcap(ifp, bw_cap);
5331 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5332 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5334 err = brcmf_construct_reginfo(cfg, bw_cap);
5336 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5340 nband = band_list[0];
5342 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5344 if ((band_list[i] == WLC_BAND_5G) &&
5345 (__wl_band_5ghz_a.n_channels > 0))
5346 band = &__wl_band_5ghz_a;
5347 else if ((band_list[i] == WLC_BAND_2G) &&
5348 (__wl_band_2ghz.n_channels > 0))
5349 band = &__wl_band_2ghz;
5353 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5354 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5355 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5357 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5358 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5359 band->ht_cap.ht_supported = true;
5360 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5361 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5362 /* An HT shall support all EQM rates for one spatial
5365 band->ht_cap.mcs.rx_mask[0] = 0xff;
5366 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5367 bands[band->band] = band;
5370 wiphy = cfg_to_wiphy(cfg);
5371 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5372 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5373 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5379 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5381 return brcmf_update_wiphybands(cfg);
5384 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5386 struct net_device *ndev;
5387 struct wireless_dev *wdev;
5388 struct brcmf_if *ifp;
5395 ndev = cfg_to_ndev(cfg);
5396 wdev = ndev->ieee80211_ptr;
5397 ifp = netdev_priv(ndev);
5399 /* make sure RF is ready for work */
5400 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5402 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5403 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5405 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5406 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5408 goto default_conf_out;
5409 brcmf_dbg(INFO, "power save set to %s\n",
5410 (power_mode ? "enabled" : "disabled"));
5412 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5414 goto default_conf_out;
5415 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5418 goto default_conf_out;
5419 err = brcmf_dongle_probecap(cfg);
5421 goto default_conf_out;
5423 brcmf_configure_arp_offload(ifp, true);
5425 cfg->dongle_up = true;
5432 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5434 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5436 return brcmf_config_dongle(ifp->drvr->config);
5439 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5441 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5444 * While going down, if associated with AP disassociate
5445 * from AP to save power
5447 if (check_vif_up(ifp->vif)) {
5448 brcmf_link_down(ifp->vif);
5450 /* Make sure WPA_Supplicant receives all the event
5451 generated due to DISASSOC call to the fw to keep
5452 the state fw and WPA_Supplicant state consistent
5457 brcmf_abort_scanning(cfg);
5458 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5463 s32 brcmf_cfg80211_up(struct net_device *ndev)
5465 struct brcmf_if *ifp = netdev_priv(ndev);
5466 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5469 mutex_lock(&cfg->usr_sync);
5470 err = __brcmf_cfg80211_up(ifp);
5471 mutex_unlock(&cfg->usr_sync);
5476 s32 brcmf_cfg80211_down(struct net_device *ndev)
5478 struct brcmf_if *ifp = netdev_priv(ndev);
5479 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5482 mutex_lock(&cfg->usr_sync);
5483 err = __brcmf_cfg80211_down(ifp);
5484 mutex_unlock(&cfg->usr_sync);
5489 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5491 struct wireless_dev *wdev = &ifp->vif->wdev;
5493 return wdev->iftype;
5496 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5498 struct brcmf_cfg80211_vif *vif;
5501 list_for_each_entry(vif, &cfg->vif_list, list) {
5502 if (test_bit(state, &vif->sme_state))
5508 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5513 mutex_lock(&event->vif_event_lock);
5514 evt_action = event->action;
5515 mutex_unlock(&event->vif_event_lock);
5516 return evt_action == action;
5519 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5520 struct brcmf_cfg80211_vif *vif)
5522 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5524 mutex_lock(&event->vif_event_lock);
5527 mutex_unlock(&event->vif_event_lock);
5530 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5532 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5535 mutex_lock(&event->vif_event_lock);
5536 armed = event->vif != NULL;
5537 mutex_unlock(&event->vif_event_lock);
5541 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5542 u8 action, ulong timeout)
5544 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5546 return wait_event_timeout(event->vif_wq,
5547 vif_event_equals(event, action), timeout);