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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 #include <net/netlink.h>
33 #include <brcmu_utils.h>
35 #include <brcmu_wifi.h>
37 #include "wl_cfg80211.h"
39 #define BRCMF_SCAN_IE_LEN_MAX 2048
40 #define BRCMF_PNO_VERSION 2
41 #define BRCMF_PNO_TIME 30
42 #define BRCMF_PNO_REPEAT 4
43 #define BRCMF_PNO_FREQ_EXPO_MAX 3
44 #define BRCMF_PNO_MAX_PFN_COUNT 16
45 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
46 #define BRCMF_PNO_HIDDEN_BIT 2
47 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
48 #define BRCMF_PNO_SCAN_COMPLETE 1
49 #define BRCMF_PNO_SCAN_INCOMPLETE 0
51 #define TLV_LEN_OFF 1 /* length offset */
52 #define TLV_HDR_LEN 2 /* header length */
53 #define TLV_BODY_OFF 2 /* body offset */
54 #define TLV_OUI_LEN 3 /* oui id length */
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
60 #define VS_IE_FIXED_HDR_LEN 6
61 #define WPA_IE_VERSION_LEN 2
62 #define WPA_IE_MIN_OUI_LEN 4
63 #define WPA_IE_SUITE_COUNT_LEN 2
65 #define WPA_CIPHER_NONE 0 /* None */
66 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
67 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
68 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
69 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
71 #define RSN_AKM_NONE 0 /* None (IBSS) */
72 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
73 #define RSN_AKM_PSK 2 /* Pre-shared Key */
74 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
75 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
77 #define VNDR_IE_CMD_LEN 4 /* length of the set command
78 * string :"add", "del" (+ NUL)
80 #define VNDR_IE_COUNT_OFFSET 4
81 #define VNDR_IE_PKTFLAG_OFFSET 8
82 #define VNDR_IE_VSIE_OFFSET 12
83 #define VNDR_IE_HDR_SIZE 12
84 #define VNDR_IE_BEACON_FLAG 0x1
85 #define VNDR_IE_PRBRSP_FLAG 0x2
86 #define MAX_VNDR_IE_NUMBER 5
88 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
89 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
91 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
92 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
94 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
96 static u32 brcmf_dbg_level = WL_DBG_ERR;
98 static bool check_sys_up(struct wiphy *wiphy)
100 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
101 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
102 WL_INFO("device is not ready : status (%d)\n",
109 #define CHAN2G(_channel, _freq, _flags) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (_freq), \
112 .hw_value = (_channel), \
114 .max_antenna_gain = 0, \
118 #define CHAN5G(_channel, _flags) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = 5000 + (5 * (_channel)), \
121 .hw_value = (_channel), \
123 .max_antenna_gain = 0, \
127 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
128 #define RATETAB_ENT(_rateid, _flags) \
130 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
131 .hw_value = (_rateid), \
135 static struct ieee80211_rate __wl_rates[] = {
136 RATETAB_ENT(BRCM_RATE_1M, 0),
137 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
138 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
139 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
140 RATETAB_ENT(BRCM_RATE_6M, 0),
141 RATETAB_ENT(BRCM_RATE_9M, 0),
142 RATETAB_ENT(BRCM_RATE_12M, 0),
143 RATETAB_ENT(BRCM_RATE_18M, 0),
144 RATETAB_ENT(BRCM_RATE_24M, 0),
145 RATETAB_ENT(BRCM_RATE_36M, 0),
146 RATETAB_ENT(BRCM_RATE_48M, 0),
147 RATETAB_ENT(BRCM_RATE_54M, 0),
150 #define wl_a_rates (__wl_rates + 4)
151 #define wl_a_rates_size 8
152 #define wl_g_rates (__wl_rates + 0)
153 #define wl_g_rates_size 12
155 static struct ieee80211_channel __wl_2ghz_channels[] = {
172 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
173 CHAN5G(34, 0), CHAN5G(36, 0),
174 CHAN5G(38, 0), CHAN5G(40, 0),
175 CHAN5G(42, 0), CHAN5G(44, 0),
176 CHAN5G(46, 0), CHAN5G(48, 0),
177 CHAN5G(52, 0), CHAN5G(56, 0),
178 CHAN5G(60, 0), CHAN5G(64, 0),
179 CHAN5G(100, 0), CHAN5G(104, 0),
180 CHAN5G(108, 0), CHAN5G(112, 0),
181 CHAN5G(116, 0), CHAN5G(120, 0),
182 CHAN5G(124, 0), CHAN5G(128, 0),
183 CHAN5G(132, 0), CHAN5G(136, 0),
184 CHAN5G(140, 0), CHAN5G(149, 0),
185 CHAN5G(153, 0), CHAN5G(157, 0),
186 CHAN5G(161, 0), CHAN5G(165, 0),
187 CHAN5G(184, 0), CHAN5G(188, 0),
188 CHAN5G(192, 0), CHAN5G(196, 0),
189 CHAN5G(200, 0), CHAN5G(204, 0),
190 CHAN5G(208, 0), CHAN5G(212, 0),
194 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
195 CHAN5G(32, 0), CHAN5G(34, 0),
196 CHAN5G(36, 0), CHAN5G(38, 0),
197 CHAN5G(40, 0), CHAN5G(42, 0),
198 CHAN5G(44, 0), CHAN5G(46, 0),
199 CHAN5G(48, 0), CHAN5G(50, 0),
200 CHAN5G(52, 0), CHAN5G(54, 0),
201 CHAN5G(56, 0), CHAN5G(58, 0),
202 CHAN5G(60, 0), CHAN5G(62, 0),
203 CHAN5G(64, 0), CHAN5G(66, 0),
204 CHAN5G(68, 0), CHAN5G(70, 0),
205 CHAN5G(72, 0), CHAN5G(74, 0),
206 CHAN5G(76, 0), CHAN5G(78, 0),
207 CHAN5G(80, 0), CHAN5G(82, 0),
208 CHAN5G(84, 0), CHAN5G(86, 0),
209 CHAN5G(88, 0), CHAN5G(90, 0),
210 CHAN5G(92, 0), CHAN5G(94, 0),
211 CHAN5G(96, 0), CHAN5G(98, 0),
212 CHAN5G(100, 0), CHAN5G(102, 0),
213 CHAN5G(104, 0), CHAN5G(106, 0),
214 CHAN5G(108, 0), CHAN5G(110, 0),
215 CHAN5G(112, 0), CHAN5G(114, 0),
216 CHAN5G(116, 0), CHAN5G(118, 0),
217 CHAN5G(120, 0), CHAN5G(122, 0),
218 CHAN5G(124, 0), CHAN5G(126, 0),
219 CHAN5G(128, 0), CHAN5G(130, 0),
220 CHAN5G(132, 0), CHAN5G(134, 0),
221 CHAN5G(136, 0), CHAN5G(138, 0),
222 CHAN5G(140, 0), CHAN5G(142, 0),
223 CHAN5G(144, 0), CHAN5G(145, 0),
224 CHAN5G(146, 0), CHAN5G(147, 0),
225 CHAN5G(148, 0), CHAN5G(149, 0),
226 CHAN5G(150, 0), CHAN5G(151, 0),
227 CHAN5G(152, 0), CHAN5G(153, 0),
228 CHAN5G(154, 0), CHAN5G(155, 0),
229 CHAN5G(156, 0), CHAN5G(157, 0),
230 CHAN5G(158, 0), CHAN5G(159, 0),
231 CHAN5G(160, 0), CHAN5G(161, 0),
232 CHAN5G(162, 0), CHAN5G(163, 0),
233 CHAN5G(164, 0), CHAN5G(165, 0),
234 CHAN5G(166, 0), CHAN5G(168, 0),
235 CHAN5G(170, 0), CHAN5G(172, 0),
236 CHAN5G(174, 0), CHAN5G(176, 0),
237 CHAN5G(178, 0), CHAN5G(180, 0),
238 CHAN5G(182, 0), CHAN5G(184, 0),
239 CHAN5G(186, 0), CHAN5G(188, 0),
240 CHAN5G(190, 0), CHAN5G(192, 0),
241 CHAN5G(194, 0), CHAN5G(196, 0),
242 CHAN5G(198, 0), CHAN5G(200, 0),
243 CHAN5G(202, 0), CHAN5G(204, 0),
244 CHAN5G(206, 0), CHAN5G(208, 0),
245 CHAN5G(210, 0), CHAN5G(212, 0),
246 CHAN5G(214, 0), CHAN5G(216, 0),
247 CHAN5G(218, 0), CHAN5G(220, 0),
248 CHAN5G(222, 0), CHAN5G(224, 0),
249 CHAN5G(226, 0), CHAN5G(228, 0),
252 static struct ieee80211_supported_band __wl_band_2ghz = {
253 .band = IEEE80211_BAND_2GHZ,
254 .channels = __wl_2ghz_channels,
255 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
256 .bitrates = wl_g_rates,
257 .n_bitrates = wl_g_rates_size,
260 static struct ieee80211_supported_band __wl_band_5ghz_a = {
261 .band = IEEE80211_BAND_5GHZ,
262 .channels = __wl_5ghz_a_channels,
263 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
264 .bitrates = wl_a_rates,
265 .n_bitrates = wl_a_rates_size,
268 static struct ieee80211_supported_band __wl_band_5ghz_n = {
269 .band = IEEE80211_BAND_5GHZ,
270 .channels = __wl_5ghz_n_channels,
271 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
272 .bitrates = wl_a_rates,
273 .n_bitrates = wl_a_rates_size,
276 static const u32 __wl_cipher_suites[] = {
277 WLAN_CIPHER_SUITE_WEP40,
278 WLAN_CIPHER_SUITE_WEP104,
279 WLAN_CIPHER_SUITE_TKIP,
280 WLAN_CIPHER_SUITE_CCMP,
281 WLAN_CIPHER_SUITE_AES_CMAC,
284 /* tag_ID/length/value_buffer tuple */
291 /* Vendor specific ie. id = 221, oui and type defines exact ie */
292 struct brcmf_vs_tlv {
299 struct parsed_vndr_ie_info {
301 u32 ie_len; /* total length including id & length field */
302 struct brcmf_vs_tlv vndrie;
305 struct parsed_vndr_ies {
307 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
310 /* Quarter dBm units to mW
311 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
312 * Table is offset so the last entry is largest mW value that fits in
316 #define QDBM_OFFSET 153 /* Offset for first entry */
317 #define QDBM_TABLE_LEN 40 /* Table size */
319 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
320 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
322 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
324 /* Largest mW value that will round down to the last table entry,
325 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
326 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
327 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
329 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
331 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
332 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
333 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
334 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
335 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
336 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
337 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
340 static u16 brcmf_qdbm_to_mw(u8 qdbm)
343 int idx = qdbm - QDBM_OFFSET;
345 if (idx >= QDBM_TABLE_LEN)
346 /* clamp to max u16 mW value */
349 /* scale the qdBm index up to the range of the table 0-40
350 * where an offset of 40 qdBm equals a factor of 10 mW.
357 /* return the mW value scaled down to the correct factor of 10,
358 * adding in factor/2 to get proper rounding.
360 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
363 static u8 brcmf_mw_to_qdbm(u16 mw)
370 /* handle boundary case */
374 offset = QDBM_OFFSET;
376 /* move mw into the range of the table */
377 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
382 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
383 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
384 nqdBm_to_mW_map[qdbm]) / 2;
385 if (mw_uint < boundary)
394 /* function for reading/writing a single u32 from/to the dongle */
396 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
399 __le32 par_le = cpu_to_le32(*par);
401 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
402 *par = le32_to_cpu(par_le);
408 brcmf_dev_iovar_setbuf_bsscfg(struct net_device *ndev, s8 *name,
409 void *param, s32 paramlen,
410 void *buf, s32 buflen, s32 bssidx)
415 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
416 buf, buflen, bssidx);
419 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
421 WL_ERR("error (%d)\n", err);
427 brcmf_dev_iovar_getbuf_bsscfg(struct net_device *ndev, s8 *name,
428 void *param, s32 paramlen,
429 void *buf, s32 buflen, s32 bssidx)
434 len = brcmf_c_mkiovar_bsscfg(name, param, paramlen,
435 buf, buflen, bssidx);
438 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, buf, len);
440 WL_ERR("error (%d)\n", err);
445 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
446 struct brcmf_wsec_key_le *key_le)
448 key_le->index = cpu_to_le32(key->index);
449 key_le->len = cpu_to_le32(key->len);
450 key_le->algo = cpu_to_le32(key->algo);
451 key_le->flags = cpu_to_le32(key->flags);
452 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
453 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
454 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
455 memcpy(key_le->data, key->data, sizeof(key->data));
456 memcpy(key_le->ea, key->ea, sizeof(key->ea));
460 send_key_to_dongle(struct brcmf_cfg80211_info *cfg, s32 bssidx,
461 struct net_device *ndev, struct brcmf_wsec_key *key)
464 struct brcmf_wsec_key_le key_le;
466 convert_key_from_CPU(key, &key_le);
468 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
471 WL_EXTRA_BUF_MAX, bssidx);
474 WL_ERR("wsec_key error (%d)\n", err);
479 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
480 enum nl80211_iftype type, u32 *flags,
481 struct vif_params *params)
483 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
488 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev, type);
491 case NL80211_IFTYPE_MONITOR:
492 case NL80211_IFTYPE_WDS:
493 WL_ERR("type (%d) : currently we do not support this type\n",
496 case NL80211_IFTYPE_ADHOC:
497 cfg->conf->mode = WL_MODE_IBSS;
500 case NL80211_IFTYPE_STATION:
501 cfg->conf->mode = WL_MODE_BSS;
504 case NL80211_IFTYPE_AP:
505 cfg->conf->mode = WL_MODE_AP;
514 set_bit(WL_STATUS_AP_CREATING, &cfg->status);
516 cfg->ap_info = kzalloc(sizeof(*cfg->ap_info),
522 WL_INFO("IF Type = AP\n");
524 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
526 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
530 WL_INFO("IF Type = %s\n",
531 (cfg->conf->mode == WL_MODE_IBSS) ?
534 ndev->ieee80211_ptr->iftype = type;
542 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
544 s8 buf[BRCMF_DCMD_SMLEN];
549 val_le = cpu_to_le32(val);
550 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
554 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
556 WL_ERR("error (%d)\n", err);
562 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
565 s8 buf[BRCMF_DCMD_SMLEN];
573 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
576 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
578 WL_ERR("error (%d)\n", err);
580 *retval = le32_to_cpu(var.val);
586 brcmf_dev_intvar_set_bsscfg(struct net_device *ndev, s8 *name, u32 val,
589 s8 buf[BRCMF_DCMD_SMLEN];
592 val_le = cpu_to_le32(val);
594 return brcmf_dev_iovar_setbuf_bsscfg(ndev, name, &val_le,
595 sizeof(val_le), buf, sizeof(buf),
600 brcmf_dev_intvar_get_bsscfg(struct net_device *ndev, s8 *name, s32 *val,
603 s8 buf[BRCMF_DCMD_SMLEN];
607 memset(buf, 0, sizeof(buf));
608 err = brcmf_dev_iovar_getbuf_bsscfg(ndev, name, val, sizeof(*val), buf,
609 sizeof(buf), bssidx);
611 memcpy(&val_le, buf, sizeof(val_le));
612 *val = le32_to_cpu(val_le);
619 * For now brcmf_find_bssidx will return 0. Once p2p gets implemented this
620 * should return the ndev matching bssidx.
623 brcmf_find_bssidx(struct brcmf_cfg80211_info *cfg, struct net_device *ndev)
628 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
631 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
633 if (test_bit(WL_STATUS_READY, &cfg->status)) {
634 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
636 WL_ERR("fail to set mpc\n");
639 WL_INFO("MPC : %d\n", mpc);
643 static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
644 struct brcmf_ssid *ssid)
646 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
647 params_le->bss_type = DOT11_BSSTYPE_ANY;
648 params_le->scan_type = 0;
649 params_le->channel_num = 0;
650 params_le->nprobes = cpu_to_le32(-1);
651 params_le->active_time = cpu_to_le32(-1);
652 params_le->passive_time = cpu_to_le32(-1);
653 params_le->home_time = cpu_to_le32(-1);
654 if (ssid && ssid->SSID_len) {
655 params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
656 memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
661 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
662 s32 paramlen, void *bufptr, s32 buflen)
666 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
669 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
673 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
674 s32 paramlen, void *bufptr, s32 buflen)
678 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
681 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
685 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
686 struct brcmf_ssid *ssid, u16 action)
688 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
689 offsetof(struct brcmf_iscan_params_le, params_le);
690 struct brcmf_iscan_params_le *params;
693 if (ssid && ssid->SSID_len)
694 params_size += sizeof(struct brcmf_ssid);
695 params = kzalloc(params_size, GFP_KERNEL);
698 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
700 brcmf_iscan_prep(¶ms->params_le, ssid);
702 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
703 params->action = cpu_to_le16(action);
704 params->scan_duration = cpu_to_le16(0);
706 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
707 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
710 WL_INFO("system busy : iscan canceled\n");
712 WL_ERR("error (%d)\n", err);
719 static s32 brcmf_do_iscan(struct brcmf_cfg80211_info *cfg)
721 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
722 struct net_device *ndev = cfg_to_ndev(cfg);
723 struct brcmf_ssid ssid;
727 /* Broadcast scan by default */
728 memset(&ssid, 0, sizeof(ssid));
730 iscan->state = WL_ISCAN_STATE_SCANING;
732 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
733 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_SET_PASSIVE_SCAN,
734 &passive_scan, sizeof(passive_scan));
736 WL_ERR("error (%d)\n", err);
739 brcmf_set_mpc(ndev, 0);
740 cfg->iscan_kickstart = true;
741 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
743 brcmf_set_mpc(ndev, 1);
744 cfg->iscan_kickstart = false;
747 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
753 brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
754 struct cfg80211_scan_request *request,
755 struct cfg80211_ssid *this_ssid)
757 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
758 struct cfg80211_ssid *ssids;
759 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
766 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
767 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
770 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
771 WL_ERR("Scanning being aborted : status (%lu)\n",
775 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
776 WL_ERR("Connecting : status (%lu)\n",
785 ssids = request->ssids;
786 if (cfg->iscan_on && (!ssids || !ssids->ssid_len))
790 /* we don't do iscan in ibss */
794 cfg->scan_request = request;
795 set_bit(WL_STATUS_SCANNING, &cfg->status);
797 err = brcmf_do_iscan(cfg);
803 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
804 ssids->ssid, ssids->ssid_len);
805 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
806 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
807 sr->ssid_le.SSID_len = cpu_to_le32(0);
809 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
810 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
813 WL_SCAN("Broadcast scan\n");
816 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
817 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
818 &passive_scan, sizeof(passive_scan));
820 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
823 brcmf_set_mpc(ndev, 0);
824 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
825 sizeof(sr->ssid_le));
828 WL_INFO("system busy : scan for \"%s\" "
829 "canceled\n", sr->ssid_le.SSID);
831 WL_ERR("WLC_SCAN error (%d)\n", err);
833 brcmf_set_mpc(ndev, 1);
841 clear_bit(WL_STATUS_SCANNING, &cfg->status);
842 cfg->scan_request = NULL;
846 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
847 struct cfg80211_scan_request *request)
855 struct ieee80211_channel *req_channel;
857 struct brcmf_ssid_le ssid_le;
859 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
860 params_le->bss_type = DOT11_BSSTYPE_ANY;
861 params_le->scan_type = 0;
862 params_le->channel_num = 0;
863 params_le->nprobes = cpu_to_le32(-1);
864 params_le->active_time = cpu_to_le32(-1);
865 params_le->passive_time = cpu_to_le32(-1);
866 params_le->home_time = cpu_to_le32(-1);
867 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
869 /* if request is null exit so it will be all channel broadcast scan */
873 n_ssids = request->n_ssids;
874 n_channels = request->n_channels;
875 /* Copy channel array if applicable */
876 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
877 if (n_channels > 0) {
878 for (i = 0; i < n_channels; i++) {
880 req_channel = request->channels[i];
881 channel = ieee80211_frequency_to_channel(
882 req_channel->center_freq);
883 if (req_channel->band == IEEE80211_BAND_2GHZ)
884 chanspec |= WL_CHANSPEC_BAND_2G;
886 chanspec |= WL_CHANSPEC_BAND_5G;
888 if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
889 chanspec |= WL_CHANSPEC_BW_20;
890 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
892 chanspec |= WL_CHANSPEC_BW_40;
893 if (req_channel->flags &
894 IEEE80211_CHAN_NO_HT40PLUS)
895 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
897 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
900 chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
901 WL_SCAN("Chan : %d, Channel spec: %x\n",
903 params_le->channel_list[i] = cpu_to_le16(chanspec);
906 WL_SCAN("Scanning all channels\n");
908 /* Copy ssid array if applicable */
909 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
911 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
912 n_channels * sizeof(u16);
913 offset = roundup(offset, sizeof(u32));
914 ptr = (char *)params_le + offset;
915 for (i = 0; i < n_ssids; i++) {
916 memset(&ssid_le, 0, sizeof(ssid_le));
918 cpu_to_le32(request->ssids[i].ssid_len);
919 memcpy(ssid_le.SSID, request->ssids[i].ssid,
920 request->ssids[i].ssid_len);
921 if (!ssid_le.SSID_len)
922 WL_SCAN("%d: Broadcast scan\n", i);
924 WL_SCAN("%d: scan for %s size =%d\n", i,
925 ssid_le.SSID, ssid_le.SSID_len);
926 memcpy(ptr, &ssid_le, sizeof(ssid_le));
927 ptr += sizeof(ssid_le);
930 WL_SCAN("Broadcast scan %p\n", request->ssids);
931 if ((request->ssids) && request->ssids->ssid_len) {
932 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
933 request->ssids->ssid_len);
934 params_le->ssid_le.SSID_len =
935 cpu_to_le32(request->ssids->ssid_len);
936 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
937 request->ssids->ssid_len);
940 /* Adding mask to channel numbers */
941 params_le->channel_num =
942 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
943 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
947 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
948 struct net_device *ndev,
949 bool aborted, bool fw_abort)
951 struct brcmf_scan_params_le params_le;
952 struct cfg80211_scan_request *scan_request;
957 /* clear scan request, because the FW abort can cause a second call */
958 /* to this functon and might cause a double cfg80211_scan_done */
959 scan_request = cfg->scan_request;
960 cfg->scan_request = NULL;
962 if (timer_pending(&cfg->escan_timeout))
963 del_timer_sync(&cfg->escan_timeout);
966 /* Do a scan abort to stop the driver's scan engine */
967 WL_SCAN("ABORT scan in firmware\n");
968 memset(¶ms_le, 0, sizeof(params_le));
969 memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
970 params_le.bss_type = DOT11_BSSTYPE_ANY;
971 params_le.scan_type = 0;
972 params_le.channel_num = cpu_to_le32(1);
973 params_le.nprobes = cpu_to_le32(1);
974 params_le.active_time = cpu_to_le32(-1);
975 params_le.passive_time = cpu_to_le32(-1);
976 params_le.home_time = cpu_to_le32(-1);
977 /* Scan is aborted by setting channel_list[0] to -1 */
978 params_le.channel_list[0] = cpu_to_le16(-1);
979 /* E-Scan (or anyother type) can be aborted by SCAN */
980 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, ¶ms_le,
983 WL_ERR("Scan abort failed\n");
986 * e-scan can be initiated by scheduled scan
987 * which takes precedence.
989 if (cfg->sched_escan) {
990 WL_SCAN("scheduled scan completed\n");
991 cfg->sched_escan = false;
993 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
994 brcmf_set_mpc(ndev, 1);
995 } else if (scan_request) {
996 WL_SCAN("ESCAN Completed scan: %s\n",
997 aborted ? "Aborted" : "Done");
998 cfg80211_scan_done(scan_request, aborted);
999 brcmf_set_mpc(ndev, 1);
1001 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
1002 WL_ERR("Scan complete while device not scanning\n");
1010 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
1011 struct cfg80211_scan_request *request, u16 action)
1013 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
1014 offsetof(struct brcmf_escan_params_le, params_le);
1015 struct brcmf_escan_params_le *params;
1018 WL_SCAN("E-SCAN START\n");
1020 if (request != NULL) {
1021 /* Allocate space for populating ssids in struct */
1022 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1024 /* Allocate space for populating ssids in struct */
1025 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
1028 params = kzalloc(params_size, GFP_KERNEL);
1033 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1034 brcmf_escan_prep(¶ms->params_le, request);
1035 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1036 params->action = cpu_to_le16(action);
1037 params->sync_id = cpu_to_le16(0x1234);
1039 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
1040 cfg->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
1043 WL_INFO("system busy : escan canceled\n");
1045 WL_ERR("error (%d)\n", err);
1054 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1055 struct net_device *ndev, struct cfg80211_scan_request *request)
1058 __le32 passive_scan;
1059 struct brcmf_scan_results *results;
1062 cfg->escan_info.ndev = ndev;
1063 cfg->escan_info.wiphy = wiphy;
1064 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
1065 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1066 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1067 &passive_scan, sizeof(passive_scan));
1069 WL_ERR("error (%d)\n", err);
1072 brcmf_set_mpc(ndev, 0);
1073 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1074 results->version = 0;
1076 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1078 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
1080 brcmf_set_mpc(ndev, 1);
1085 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
1086 struct cfg80211_scan_request *request,
1087 struct cfg80211_ssid *this_ssid)
1089 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1090 struct cfg80211_ssid *ssids;
1091 struct brcmf_cfg80211_scan_req *sr = cfg->scan_req_int;
1092 __le32 passive_scan;
1098 WL_SCAN("START ESCAN\n");
1100 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
1101 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
1104 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg->status)) {
1105 WL_ERR("Scanning being aborted : status (%lu)\n",
1109 if (test_bit(WL_STATUS_CONNECTING, &cfg->status)) {
1110 WL_ERR("Connecting : status (%lu)\n",
1115 /* Arm scan timeout timer */
1116 mod_timer(&cfg->escan_timeout, jiffies +
1117 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1122 ssids = request->ssids;
1126 /* we don't do escan in ibss */
1130 cfg->scan_request = request;
1131 set_bit(WL_STATUS_SCANNING, &cfg->status);
1133 err = brcmf_do_escan(cfg, wiphy, ndev, request);
1139 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
1140 ssids->ssid, ssids->ssid_len);
1141 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1142 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1143 sr->ssid_le.SSID_len = cpu_to_le32(0);
1146 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1147 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1150 WL_SCAN("Broadcast scan\n");
1152 passive_scan = cfg->active_scan ? 0 : cpu_to_le32(1);
1153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
1154 &passive_scan, sizeof(passive_scan));
1156 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1159 brcmf_set_mpc(ndev, 0);
1160 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
1161 sizeof(sr->ssid_le));
1164 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1167 WL_ERR("WLC_SCAN error (%d)\n", err);
1169 brcmf_set_mpc(ndev, 1);
1177 clear_bit(WL_STATUS_SCANNING, &cfg->status);
1178 if (timer_pending(&cfg->escan_timeout))
1179 del_timer_sync(&cfg->escan_timeout);
1180 cfg->scan_request = NULL;
1185 brcmf_cfg80211_scan(struct wiphy *wiphy,
1186 struct cfg80211_scan_request *request)
1188 struct net_device *ndev = request->wdev->netdev;
1189 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1192 WL_TRACE("Enter\n");
1194 if (!check_sys_up(wiphy))
1198 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1199 else if (cfg->escan_on)
1200 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1203 WL_ERR("scan error (%d)\n", err);
1209 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1213 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
1215 WL_ERR("Error (%d)\n", err);
1220 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1224 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
1226 WL_ERR("Error (%d)\n", err);
1231 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1234 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
1236 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
1238 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
1244 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1246 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1247 struct net_device *ndev = cfg_to_ndev(cfg);
1250 WL_TRACE("Enter\n");
1251 if (!check_sys_up(wiphy))
1254 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1255 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1256 cfg->conf->rts_threshold = wiphy->rts_threshold;
1257 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1261 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1262 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1263 cfg->conf->frag_threshold = wiphy->frag_threshold;
1264 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1268 if (changed & WIPHY_PARAM_RETRY_LONG
1269 && (cfg->conf->retry_long != wiphy->retry_long)) {
1270 cfg->conf->retry_long = wiphy->retry_long;
1271 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1275 if (changed & WIPHY_PARAM_RETRY_SHORT
1276 && (cfg->conf->retry_short != wiphy->retry_short)) {
1277 cfg->conf->retry_short = wiphy->retry_short;
1278 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1288 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1290 memset(prof, 0, sizeof(*prof));
1293 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
1294 size_t *join_params_size)
1299 if (ch <= CH_MAX_2G_CHANNEL)
1300 chanspec |= WL_CHANSPEC_BAND_2G;
1302 chanspec |= WL_CHANSPEC_BAND_5G;
1304 chanspec |= WL_CHANSPEC_BW_20;
1305 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
1307 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
1310 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
1311 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1312 join_params->params_le.chanspec_num = cpu_to_le32(1);
1314 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
1315 "channel %d, chanspec %#X\n",
1316 chanspec, ch, chanspec);
1320 static void brcmf_link_down(struct brcmf_cfg80211_info *cfg)
1322 struct net_device *ndev = NULL;
1325 WL_TRACE("Enter\n");
1328 ndev = cfg_to_ndev(cfg);
1329 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1330 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
1332 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
1333 cfg->link_up = false;
1339 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1340 struct cfg80211_ibss_params *params)
1342 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1343 struct brcmf_cfg80211_profile *profile = cfg->profile;
1344 struct brcmf_join_params join_params;
1345 size_t join_params_size = 0;
1350 WL_TRACE("Enter\n");
1351 if (!check_sys_up(wiphy))
1355 WL_CONN("SSID: %s\n", params->ssid);
1357 WL_CONN("SSID: NULL, Not supported\n");
1361 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1364 WL_CONN("BSSID: %pM\n", params->bssid);
1366 WL_CONN("No BSSID specified\n");
1368 if (params->channel)
1369 WL_CONN("channel: %d\n", params->channel->center_freq);
1371 WL_CONN("no channel specified\n");
1373 if (params->channel_fixed)
1374 WL_CONN("fixed channel required\n");
1376 WL_CONN("no fixed channel required\n");
1378 if (params->ie && params->ie_len)
1379 WL_CONN("ie len: %d\n", params->ie_len);
1381 WL_CONN("no ie specified\n");
1383 if (params->beacon_interval)
1384 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1386 WL_CONN("no beacon interval specified\n");
1388 if (params->basic_rates)
1389 WL_CONN("basic rates: %08X\n", params->basic_rates);
1391 WL_CONN("no basic rates specified\n");
1393 if (params->privacy)
1394 WL_CONN("privacy required\n");
1396 WL_CONN("no privacy required\n");
1398 /* Configure Privacy for starter */
1399 if (params->privacy)
1400 wsec |= WEP_ENABLED;
1402 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1404 WL_ERR("wsec failed (%d)\n", err);
1408 /* Configure Beacon Interval for starter */
1409 if (params->beacon_interval)
1410 bcnprd = params->beacon_interval;
1414 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
1416 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1420 /* Configure required join parameter */
1421 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1424 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1425 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1426 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1427 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1428 join_params_size = sizeof(join_params.ssid_le);
1431 if (params->bssid) {
1432 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1433 join_params_size = sizeof(join_params.ssid_le) +
1434 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1435 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1437 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1438 memset(profile->bssid, 0, ETH_ALEN);
1442 if (params->channel) {
1446 ieee80211_frequency_to_channel(
1447 params->channel->center_freq);
1448 if (params->channel_fixed) {
1449 /* adding chanspec */
1450 brcmf_ch_to_chanspec(cfg->channel,
1451 &join_params, &join_params_size);
1454 /* set channel for starter */
1455 target_channel = cfg->channel;
1456 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1459 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1465 cfg->ibss_starter = false;
1468 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1469 &join_params, join_params_size);
1471 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1477 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1483 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1485 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1488 WL_TRACE("Enter\n");
1489 if (!check_sys_up(wiphy))
1492 brcmf_link_down(cfg);
1499 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1500 struct cfg80211_connect_params *sme)
1502 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1503 struct brcmf_cfg80211_profile *profile = cfg->profile;
1504 struct brcmf_cfg80211_security *sec;
1508 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1509 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1510 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1511 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1513 val = WPA_AUTH_DISABLED;
1514 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1515 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1517 WL_ERR("set wpa_auth failed (%d)\n", err);
1520 sec = &profile->sec;
1521 sec->wpa_versions = sme->crypto.wpa_versions;
1525 static s32 brcmf_set_auth_type(struct net_device *ndev,
1526 struct cfg80211_connect_params *sme)
1528 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1529 struct brcmf_cfg80211_profile *profile = cfg->profile;
1530 struct brcmf_cfg80211_security *sec;
1534 switch (sme->auth_type) {
1535 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1537 WL_CONN("open system\n");
1539 case NL80211_AUTHTYPE_SHARED_KEY:
1541 WL_CONN("shared key\n");
1543 case NL80211_AUTHTYPE_AUTOMATIC:
1545 WL_CONN("automatic\n");
1547 case NL80211_AUTHTYPE_NETWORK_EAP:
1548 WL_CONN("network eap\n");
1551 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1555 err = brcmf_dev_intvar_set(ndev, "auth", val);
1557 WL_ERR("set auth failed (%d)\n", err);
1560 sec = &profile->sec;
1561 sec->auth_type = sme->auth_type;
1566 brcmf_set_set_cipher(struct net_device *ndev,
1567 struct cfg80211_connect_params *sme)
1569 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1570 struct brcmf_cfg80211_profile *profile = cfg->profile;
1571 struct brcmf_cfg80211_security *sec;
1576 if (sme->crypto.n_ciphers_pairwise) {
1577 switch (sme->crypto.ciphers_pairwise[0]) {
1578 case WLAN_CIPHER_SUITE_WEP40:
1579 case WLAN_CIPHER_SUITE_WEP104:
1582 case WLAN_CIPHER_SUITE_TKIP:
1583 pval = TKIP_ENABLED;
1585 case WLAN_CIPHER_SUITE_CCMP:
1588 case WLAN_CIPHER_SUITE_AES_CMAC:
1592 WL_ERR("invalid cipher pairwise (%d)\n",
1593 sme->crypto.ciphers_pairwise[0]);
1597 if (sme->crypto.cipher_group) {
1598 switch (sme->crypto.cipher_group) {
1599 case WLAN_CIPHER_SUITE_WEP40:
1600 case WLAN_CIPHER_SUITE_WEP104:
1603 case WLAN_CIPHER_SUITE_TKIP:
1604 gval = TKIP_ENABLED;
1606 case WLAN_CIPHER_SUITE_CCMP:
1609 case WLAN_CIPHER_SUITE_AES_CMAC:
1613 WL_ERR("invalid cipher group (%d)\n",
1614 sme->crypto.cipher_group);
1619 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1620 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1622 WL_ERR("error (%d)\n", err);
1626 sec = &profile->sec;
1627 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1628 sec->cipher_group = sme->crypto.cipher_group;
1634 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1636 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1637 struct brcmf_cfg80211_profile *profile = cfg->profile;
1638 struct brcmf_cfg80211_security *sec;
1642 if (sme->crypto.n_akm_suites) {
1643 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1645 WL_ERR("could not get wpa_auth (%d)\n", err);
1648 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1649 switch (sme->crypto.akm_suites[0]) {
1650 case WLAN_AKM_SUITE_8021X:
1651 val = WPA_AUTH_UNSPECIFIED;
1653 case WLAN_AKM_SUITE_PSK:
1657 WL_ERR("invalid cipher group (%d)\n",
1658 sme->crypto.cipher_group);
1661 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1662 switch (sme->crypto.akm_suites[0]) {
1663 case WLAN_AKM_SUITE_8021X:
1664 val = WPA2_AUTH_UNSPECIFIED;
1666 case WLAN_AKM_SUITE_PSK:
1667 val = WPA2_AUTH_PSK;
1670 WL_ERR("invalid cipher group (%d)\n",
1671 sme->crypto.cipher_group);
1676 WL_CONN("setting wpa_auth to %d\n", val);
1677 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1679 WL_ERR("could not set wpa_auth (%d)\n", err);
1683 sec = &profile->sec;
1684 sec->wpa_auth = sme->crypto.akm_suites[0];
1690 brcmf_set_sharedkey(struct net_device *ndev,
1691 struct cfg80211_connect_params *sme)
1693 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
1694 struct brcmf_cfg80211_profile *profile = cfg->profile;
1695 struct brcmf_cfg80211_security *sec;
1696 struct brcmf_wsec_key key;
1701 WL_CONN("key len (%d)\n", sme->key_len);
1703 if (sme->key_len == 0)
1706 sec = &profile->sec;
1707 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1708 sec->wpa_versions, sec->cipher_pairwise);
1710 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1713 if (!(sec->cipher_pairwise &
1714 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1717 memset(&key, 0, sizeof(key));
1718 key.len = (u32) sme->key_len;
1719 key.index = (u32) sme->key_idx;
1720 if (key.len > sizeof(key.data)) {
1721 WL_ERR("Too long key length (%u)\n", key.len);
1724 memcpy(key.data, sme->key, key.len);
1725 key.flags = BRCMF_PRIMARY_KEY;
1726 switch (sec->cipher_pairwise) {
1727 case WLAN_CIPHER_SUITE_WEP40:
1728 key.algo = CRYPTO_ALGO_WEP1;
1730 case WLAN_CIPHER_SUITE_WEP104:
1731 key.algo = CRYPTO_ALGO_WEP128;
1734 WL_ERR("Invalid algorithm (%d)\n",
1735 sme->crypto.ciphers_pairwise[0]);
1738 /* Set the new key/index */
1739 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1740 key.len, key.index, key.algo);
1741 WL_CONN("key \"%s\"\n", key.data);
1742 bssidx = brcmf_find_bssidx(cfg, ndev);
1743 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
1747 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1748 WL_CONN("set auth_type to shared key\n");
1749 val = WL_AUTH_SHARED_KEY; /* shared key */
1750 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", val, bssidx);
1752 WL_ERR("set auth failed (%d)\n", err);
1758 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1759 struct cfg80211_connect_params *sme)
1761 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1762 struct brcmf_cfg80211_profile *profile = cfg->profile;
1763 struct ieee80211_channel *chan = sme->channel;
1764 struct brcmf_join_params join_params;
1765 size_t join_params_size;
1766 struct brcmf_ssid ssid;
1770 WL_TRACE("Enter\n");
1771 if (!check_sys_up(wiphy))
1775 WL_ERR("Invalid ssid\n");
1779 set_bit(WL_STATUS_CONNECTING, &cfg->status);
1783 ieee80211_frequency_to_channel(chan->center_freq);
1784 WL_CONN("channel (%d), center_req (%d)\n",
1785 cfg->channel, chan->center_freq);
1789 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1791 err = brcmf_set_wpa_version(ndev, sme);
1793 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1797 err = brcmf_set_auth_type(ndev, sme);
1799 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1803 err = brcmf_set_set_cipher(ndev, sme);
1805 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1809 err = brcmf_set_key_mgmt(ndev, sme);
1811 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1815 err = brcmf_set_sharedkey(ndev, sme);
1817 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err);
1821 memset(&join_params, 0, sizeof(join_params));
1822 join_params_size = sizeof(join_params.ssid_le);
1824 profile->ssid.SSID_len = min_t(u32,
1825 sizeof(ssid.SSID), (u32)sme->ssid_len);
1826 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1827 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1828 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1830 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1832 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1833 WL_CONN("ssid \"%s\", len (%d)\n",
1834 ssid.SSID, ssid.SSID_len);
1836 brcmf_ch_to_chanspec(cfg->channel,
1837 &join_params, &join_params_size);
1838 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1839 &join_params, join_params_size);
1841 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1845 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
1851 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1855 struct brcmf_cfg80211_profile *profile = cfg->profile;
1856 struct brcmf_scb_val_le scbval;
1859 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1860 if (!check_sys_up(wiphy))
1863 clear_bit(WL_STATUS_CONNECTED, &cfg->status);
1865 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1866 scbval.val = cpu_to_le32(reason_code);
1867 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1868 sizeof(struct brcmf_scb_val_le));
1870 WL_ERR("error (%d)\n", err);
1872 cfg->link_up = false;
1879 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1880 enum nl80211_tx_power_setting type, s32 mbm)
1883 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1884 struct net_device *ndev = cfg_to_ndev(cfg);
1888 s32 dbm = MBM_TO_DBM(mbm);
1890 WL_TRACE("Enter\n");
1891 if (!check_sys_up(wiphy))
1895 case NL80211_TX_POWER_AUTOMATIC:
1897 case NL80211_TX_POWER_LIMITED:
1898 case NL80211_TX_POWER_FIXED:
1900 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1906 /* Make sure radio is off or on as far as software is concerned */
1907 disable = WL_RADIO_SW_DISABLE << 16;
1908 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1910 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1915 txpwrmw = (u16) dbm;
1916 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1917 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1919 WL_ERR("qtxpower error (%d)\n", err);
1920 cfg->conf->tx_power = dbm;
1927 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1929 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1930 struct net_device *ndev = cfg_to_ndev(cfg);
1935 WL_TRACE("Enter\n");
1936 if (!check_sys_up(wiphy))
1939 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1941 WL_ERR("error (%d)\n", err);
1945 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1946 *dbm = (s32) brcmf_qdbm_to_mw(result);
1954 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1955 u8 key_idx, bool unicast, bool multicast)
1957 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1963 WL_TRACE("Enter\n");
1964 WL_CONN("key index (%d)\n", key_idx);
1965 if (!check_sys_up(wiphy))
1968 bssidx = brcmf_find_bssidx(cfg, ndev);
1969 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
1971 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1975 if (wsec & WEP_ENABLED) {
1976 /* Just select a new current key */
1978 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1981 WL_ERR("error (%d)\n", err);
1989 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1990 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1992 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1993 struct brcmf_wsec_key key;
1994 struct brcmf_wsec_key_le key_le;
1998 memset(&key, 0, sizeof(key));
1999 key.index = (u32) key_idx;
2000 /* Instead of bcast for ea address for default wep keys,
2001 driver needs it to be Null */
2002 if (!is_multicast_ether_addr(mac_addr))
2003 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2004 key.len = (u32) params->key_len;
2005 bssidx = brcmf_find_bssidx(cfg, ndev);
2006 /* check for key index change */
2009 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2011 WL_ERR("key delete error (%d)\n", err);
2013 if (key.len > sizeof(key.data)) {
2014 WL_ERR("Invalid key length (%d)\n", key.len);
2018 WL_CONN("Setting the key index %d\n", key.index);
2019 memcpy(key.data, params->key, key.len);
2021 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
2023 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2024 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2025 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2028 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2029 if (params->seq && params->seq_len == 6) {
2032 ivptr = (u8 *) params->seq;
2033 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2034 (ivptr[3] << 8) | ivptr[2];
2035 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2036 key.iv_initialized = true;
2039 switch (params->cipher) {
2040 case WLAN_CIPHER_SUITE_WEP40:
2041 key.algo = CRYPTO_ALGO_WEP1;
2042 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2044 case WLAN_CIPHER_SUITE_WEP104:
2045 key.algo = CRYPTO_ALGO_WEP128;
2046 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2048 case WLAN_CIPHER_SUITE_TKIP:
2049 key.algo = CRYPTO_ALGO_TKIP;
2050 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2052 case WLAN_CIPHER_SUITE_AES_CMAC:
2053 key.algo = CRYPTO_ALGO_AES_CCM;
2054 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2056 case WLAN_CIPHER_SUITE_CCMP:
2057 key.algo = CRYPTO_ALGO_AES_CCM;
2058 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2061 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
2064 convert_key_from_CPU(&key, &key_le);
2066 brcmf_netdev_wait_pend8021x(ndev);
2067 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "wsec_key", &key_le,
2070 WL_EXTRA_BUF_MAX, bssidx);
2072 WL_ERR("wsec_key error (%d)\n", err);
2078 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2079 u8 key_idx, bool pairwise, const u8 *mac_addr,
2080 struct key_params *params)
2082 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2083 struct brcmf_wsec_key key;
2090 WL_TRACE("Enter\n");
2091 WL_CONN("key index (%d)\n", key_idx);
2092 if (!check_sys_up(wiphy))
2097 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2099 memset(&key, 0, sizeof(key));
2101 key.len = (u32) params->key_len;
2102 key.index = (u32) key_idx;
2104 if (key.len > sizeof(key.data)) {
2105 WL_ERR("Too long key length (%u)\n", key.len);
2109 memcpy(key.data, params->key, key.len);
2111 key.flags = BRCMF_PRIMARY_KEY;
2112 switch (params->cipher) {
2113 case WLAN_CIPHER_SUITE_WEP40:
2114 key.algo = CRYPTO_ALGO_WEP1;
2116 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2118 case WLAN_CIPHER_SUITE_WEP104:
2119 key.algo = CRYPTO_ALGO_WEP128;
2121 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2123 case WLAN_CIPHER_SUITE_TKIP:
2124 if (cfg->conf->mode != WL_MODE_AP) {
2125 WL_CONN("Swapping key\n");
2126 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2127 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2128 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2130 key.algo = CRYPTO_ALGO_TKIP;
2132 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2134 case WLAN_CIPHER_SUITE_AES_CMAC:
2135 key.algo = CRYPTO_ALGO_AES_CCM;
2137 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2139 case WLAN_CIPHER_SUITE_CCMP:
2140 key.algo = CRYPTO_ALGO_AES_CCM;
2142 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2145 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
2150 bssidx = brcmf_find_bssidx(cfg, ndev);
2151 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2155 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2157 WL_ERR("get wsec error (%d)\n", err);
2161 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
2163 WL_ERR("set wsec error (%d)\n", err);
2173 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2174 u8 key_idx, bool pairwise, const u8 *mac_addr)
2176 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2177 struct brcmf_wsec_key key;
2181 WL_TRACE("Enter\n");
2182 if (!check_sys_up(wiphy))
2185 memset(&key, 0, sizeof(key));
2187 key.index = (u32) key_idx;
2188 key.flags = BRCMF_PRIMARY_KEY;
2189 key.algo = CRYPTO_ALGO_OFF;
2191 WL_CONN("key index (%d)\n", key_idx);
2193 /* Set the new key/index */
2194 bssidx = brcmf_find_bssidx(cfg, ndev);
2195 err = send_key_to_dongle(cfg, bssidx, ndev, &key);
2197 if (err == -EINVAL) {
2198 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
2199 /* we ignore this key index in this case */
2200 WL_ERR("invalid key index (%d)\n", key_idx);
2202 /* Ignore this error, may happen during DISASSOC */
2211 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2212 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2213 void (*callback) (void *cookie, struct key_params * params))
2215 struct key_params params;
2216 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2217 struct brcmf_cfg80211_profile *profile = cfg->profile;
2218 struct brcmf_cfg80211_security *sec;
2223 WL_TRACE("Enter\n");
2224 WL_CONN("key index (%d)\n", key_idx);
2225 if (!check_sys_up(wiphy))
2228 memset(¶ms, 0, sizeof(params));
2230 bssidx = brcmf_find_bssidx(cfg, ndev);
2231 err = brcmf_dev_intvar_get_bsscfg(ndev, "wsec", &wsec, bssidx);
2233 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
2234 /* Ignore this error, may happen during DISASSOC */
2238 switch (wsec & ~SES_OW_ENABLED) {
2240 sec = &profile->sec;
2241 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2242 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2243 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2244 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2245 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2246 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2250 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2251 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2254 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2255 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2258 WL_ERR("Invalid algo (0x%x)\n", wsec);
2262 callback(cookie, ¶ms);
2270 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2271 struct net_device *ndev, u8 key_idx)
2273 WL_INFO("Not supported\n");
2279 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2280 u8 *mac, struct station_info *sinfo)
2282 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2283 struct brcmf_cfg80211_profile *profile = cfg->profile;
2284 struct brcmf_scb_val_le scb_val;
2288 u8 *bssid = profile->bssid;
2289 struct brcmf_sta_info_le *sta_info_le;
2291 WL_TRACE("Enter, MAC %pM\n", mac);
2292 if (!check_sys_up(wiphy))
2295 if (cfg->conf->mode == WL_MODE_AP) {
2296 err = brcmf_dev_iovar_getbuf(ndev, "sta_info", mac, ETH_ALEN,
2300 WL_ERR("GET STA INFO failed, %d\n", err);
2303 sta_info_le = (struct brcmf_sta_info_le *)cfg->dcmd_buf;
2305 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2306 sinfo->inactive_time = le32_to_cpu(sta_info_le->idle) * 1000;
2307 if (le32_to_cpu(sta_info_le->flags) & BRCMF_STA_ASSOC) {
2308 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2309 sinfo->connected_time = le32_to_cpu(sta_info_le->in);
2311 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2312 sinfo->inactive_time, sinfo->connected_time);
2313 } else if (cfg->conf->mode == WL_MODE_BSS) {
2314 if (memcmp(mac, bssid, ETH_ALEN)) {
2315 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2320 /* Report the current tx rate */
2321 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
2323 WL_ERR("Could not get rate (%d)\n", err);
2326 sinfo->filled |= STATION_INFO_TX_BITRATE;
2327 sinfo->txrate.legacy = rate * 5;
2328 WL_CONN("Rate %d Mbps\n", rate / 2);
2331 if (test_bit(WL_STATUS_CONNECTED, &cfg->status)) {
2332 memset(&scb_val, 0, sizeof(scb_val));
2333 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2336 WL_ERR("Could not get rssi (%d)\n", err);
2339 rssi = le32_to_cpu(scb_val.val);
2340 sinfo->filled |= STATION_INFO_SIGNAL;
2341 sinfo->signal = rssi;
2342 WL_CONN("RSSI %d dBm\n", rssi);
2353 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2354 bool enabled, s32 timeout)
2358 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2360 WL_TRACE("Enter\n");
2363 * Powersave enable/disable request is coming from the
2364 * cfg80211 even before the interface is up. In that
2365 * scenario, driver will be storing the power save
2366 * preference in cfg struct to apply this to
2367 * FW later while initializing the dongle
2369 cfg->pwr_save = enabled;
2370 if (!test_bit(WL_STATUS_READY, &cfg->status)) {
2372 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2376 pm = enabled ? PM_FAST : PM_OFF;
2377 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
2379 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
2382 WL_ERR("net_device is not ready yet\n");
2384 WL_ERR("error (%d)\n", err);
2392 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2394 const struct cfg80211_bitrate_mask *mask)
2396 struct brcm_rateset_le rateset_le;
2404 WL_TRACE("Enter\n");
2405 if (!check_sys_up(wiphy))
2408 /* addr param is always NULL. ignore it */
2409 /* Get current rateset */
2410 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
2411 sizeof(rateset_le));
2413 WL_ERR("could not get current rateset (%d)\n", err);
2417 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2419 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2422 val = wl_g_rates[legacy - 1].bitrate * 100000;
2424 if (val < le32_to_cpu(rateset_le.count))
2425 /* Select rate by rateset index */
2426 rate = rateset_le.rates[val] & 0x7f;
2428 /* Specified rate in bps */
2429 rate = val / 500000;
2431 WL_CONN("rate %d mbps\n", rate / 2);
2435 * Set rate override,
2436 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2438 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
2439 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
2440 if (err_bg && err_a) {
2441 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2442 err = err_bg | err_a;
2450 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2451 struct brcmf_bss_info_le *bi)
2453 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2454 struct ieee80211_channel *notify_channel;
2455 struct cfg80211_bss *bss;
2456 struct ieee80211_supported_band *band;
2460 u16 notify_capability;
2461 u16 notify_interval;
2463 size_t notify_ielen;
2466 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2467 WL_ERR("Bss info is larger than buffer. Discarding\n");
2471 channel = bi->ctl_ch ? bi->ctl_ch :
2472 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2474 if (channel <= CH_MAX_2G_CHANNEL)
2475 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2477 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2479 freq = ieee80211_channel_to_frequency(channel, band->band);
2480 notify_channel = ieee80211_get_channel(wiphy, freq);
2482 notify_capability = le16_to_cpu(bi->capability);
2483 notify_interval = le16_to_cpu(bi->beacon_period);
2484 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2485 notify_ielen = le32_to_cpu(bi->ie_length);
2486 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2488 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2489 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2490 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2491 WL_CONN("Channel: %d(%d)\n", channel, freq);
2492 WL_CONN("Capability: %X\n", notify_capability);
2493 WL_CONN("Beacon interval: %d\n", notify_interval);
2494 WL_CONN("Signal: %d\n", notify_signal);
2496 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2497 0, notify_capability, notify_interval, notify_ie,
2498 notify_ielen, notify_signal, GFP_KERNEL);
2503 cfg80211_put_bss(bss);
2508 static struct brcmf_bss_info_le *
2509 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2512 return list->bss_info_le;
2513 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2514 le32_to_cpu(bss->length));
2517 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2519 struct brcmf_scan_results *bss_list;
2520 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2524 bss_list = cfg->bss_list;
2525 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2526 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2530 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2531 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2532 bi = next_bss_le(bss_list, bi);
2533 err = brcmf_inform_single_bss(cfg, bi);
2540 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2541 struct net_device *ndev, const u8 *bssid)
2543 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2544 struct ieee80211_channel *notify_channel;
2545 struct brcmf_bss_info_le *bi = NULL;
2546 struct ieee80211_supported_band *band;
2547 struct cfg80211_bss *bss;
2552 u16 notify_capability;
2553 u16 notify_interval;
2555 size_t notify_ielen;
2558 WL_TRACE("Enter\n");
2560 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2566 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2568 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2570 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2574 bi = (struct brcmf_bss_info_le *)(buf + 4);
2576 channel = bi->ctl_ch ? bi->ctl_ch :
2577 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2579 if (channel <= CH_MAX_2G_CHANNEL)
2580 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2582 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2584 freq = ieee80211_channel_to_frequency(channel, band->band);
2585 notify_channel = ieee80211_get_channel(wiphy, freq);
2587 notify_capability = le16_to_cpu(bi->capability);
2588 notify_interval = le16_to_cpu(bi->beacon_period);
2589 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2590 notify_ielen = le32_to_cpu(bi->ie_length);
2591 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2593 WL_CONN("channel: %d(%d)\n", channel, freq);
2594 WL_CONN("capability: %X\n", notify_capability);
2595 WL_CONN("beacon interval: %d\n", notify_interval);
2596 WL_CONN("signal: %d\n", notify_signal);
2598 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2599 0, notify_capability, notify_interval,
2600 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2607 cfg80211_put_bss(bss);
2618 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info *cfg)
2620 return cfg->conf->mode == WL_MODE_IBSS;
2624 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2625 * triples, returning a pointer to the substring whose first element
2628 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2630 struct brcmf_tlv *elt;
2633 elt = (struct brcmf_tlv *) buf;
2636 /* find tagged parameter */
2637 while (totlen >= TLV_HDR_LEN) {
2640 /* validate remaining totlen */
2641 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2644 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2645 totlen -= (len + TLV_HDR_LEN);
2651 /* Is any of the tlvs the expected entry? If
2652 * not update the tlvs buffer pointer/length.
2655 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2656 u8 *oui, u32 oui_len, u8 type)
2658 /* If the contents match the OUI and the type */
2659 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2660 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2661 type == ie[TLV_BODY_OFF + oui_len]) {
2667 /* point to the next ie */
2668 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2669 /* calculate the length of the rest of the buffer */
2670 *tlvs_len -= (int)(ie - *tlvs);
2671 /* update the pointer to the start of the buffer */
2677 struct brcmf_vs_tlv *
2678 brcmf_find_wpaie(u8 *parse, u32 len)
2680 struct brcmf_tlv *ie;
2682 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_WPA))) {
2683 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2684 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2685 return (struct brcmf_vs_tlv *)ie;
2690 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2692 struct brcmf_cfg80211_profile *profile = cfg->profile;
2693 struct brcmf_bss_info_le *bi;
2694 struct brcmf_ssid *ssid;
2695 struct brcmf_tlv *tim;
2696 u16 beacon_interval;
2702 WL_TRACE("Enter\n");
2703 if (brcmf_is_ibssmode(cfg))
2706 ssid = &profile->ssid;
2708 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2709 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCMF_C_GET_BSS_INFO,
2710 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2712 WL_ERR("Could not get bss info %d\n", err);
2713 goto update_bss_info_out;
2716 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2717 err = brcmf_inform_single_bss(cfg, bi);
2719 goto update_bss_info_out;
2721 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2722 ie_len = le32_to_cpu(bi->ie_length);
2723 beacon_interval = le16_to_cpu(bi->beacon_period);
2725 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2727 dtim_period = tim->data[1];
2730 * active scan was done so we could not get dtim
2731 * information out of probe response.
2732 * so we speficially query dtim information to dongle.
2735 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg),
2736 "dtim_assoc", &var);
2738 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2739 goto update_bss_info_out;
2741 dtim_period = (u8)var;
2744 profile->beacon_interval = beacon_interval;
2745 profile->dtim_period = dtim_period;
2747 update_bss_info_out:
2752 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2754 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2755 struct escan_info *escan = &cfg->escan_info;
2756 struct brcmf_ssid ssid;
2758 set_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2759 if (cfg->iscan_on) {
2760 iscan->state = WL_ISCAN_STATE_IDLE;
2762 if (iscan->timer_on) {
2763 del_timer_sync(&iscan->timer);
2764 iscan->timer_on = 0;
2767 cancel_work_sync(&iscan->work);
2769 /* Abort iscan running in FW */
2770 memset(&ssid, 0, sizeof(ssid));
2771 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2773 if (cfg->scan_request) {
2774 /* Indidate scan abort to cfg80211 layer */
2775 WL_INFO("Terminating scan in progress\n");
2776 cfg80211_scan_done(cfg->scan_request, true);
2777 cfg->scan_request = NULL;
2780 if (cfg->escan_on && cfg->scan_request) {
2781 escan->escan_state = WL_ESCAN_STATE_IDLE;
2782 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2784 clear_bit(WL_STATUS_SCANNING, &cfg->status);
2785 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg->status);
2788 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2791 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2792 struct net_device *ndev = cfg_to_ndev(cfg);
2794 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
2795 WL_ERR("Scan complete while device not scanning\n");
2798 if (cfg->scan_request) {
2799 WL_SCAN("ISCAN Completed scan: %s\n",
2800 aborted ? "Aborted" : "Done");
2801 cfg80211_scan_done(cfg->scan_request, aborted);
2802 brcmf_set_mpc(ndev, 1);
2803 cfg->scan_request = NULL;
2805 cfg->iscan_kickstart = false;
2808 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2810 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2811 WL_SCAN("wake up iscan\n");
2812 schedule_work(&iscan->work);
2820 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2821 struct brcmf_scan_results **bss_list)
2823 struct brcmf_iscan_results list;
2824 struct brcmf_scan_results *results;
2825 struct brcmf_scan_results_le *results_le;
2826 struct brcmf_iscan_results *list_buf;
2829 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2830 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2831 results = &list_buf->results;
2832 results_le = &list_buf->results_le;
2833 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2834 results->version = 0;
2837 memset(&list, 0, sizeof(list));
2838 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2839 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2840 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2841 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2843 WL_ERR("error (%d)\n", err);
2846 results->buflen = le32_to_cpu(results_le->buflen);
2847 results->version = le32_to_cpu(results_le->version);
2848 results->count = le32_to_cpu(results_le->count);
2849 WL_SCAN("results->count = %d\n", results_le->count);
2850 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2851 *status = le32_to_cpu(list_buf->status_le);
2852 WL_SCAN("status = %d\n", *status);
2853 *bss_list = results;
2858 static s32 brcmf_iscan_done(struct brcmf_cfg80211_info *cfg)
2860 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2863 iscan->state = WL_ISCAN_STATE_IDLE;
2864 brcmf_inform_bss(cfg);
2865 brcmf_notify_iscan_complete(iscan, false);
2870 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_info *cfg)
2872 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2875 /* Reschedule the timer */
2876 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2877 iscan->timer_on = 1;
2882 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_info *cfg)
2884 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2887 brcmf_inform_bss(cfg);
2888 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2889 /* Reschedule the timer */
2890 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2891 iscan->timer_on = 1;
2896 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_info *cfg)
2898 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg->iscan;
2901 iscan->state = WL_ISCAN_STATE_IDLE;
2902 brcmf_notify_iscan_complete(iscan, true);
2907 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2909 struct brcmf_cfg80211_iscan_ctrl *iscan =
2910 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2912 struct brcmf_cfg80211_info *cfg = iscan_to_cfg(iscan);
2913 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2914 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2916 if (iscan->timer_on) {
2917 del_timer_sync(&iscan->timer);
2918 iscan->timer_on = 0;
2921 if (brcmf_get_iscan_results(iscan, &status, &cfg->bss_list)) {
2922 status = BRCMF_SCAN_RESULTS_ABORTED;
2923 WL_ERR("Abort iscan\n");
2926 el->handler[status](cfg);
2929 static void brcmf_iscan_timer(unsigned long data)
2931 struct brcmf_cfg80211_iscan_ctrl *iscan =
2932 (struct brcmf_cfg80211_iscan_ctrl *)data;
2935 iscan->timer_on = 0;
2936 WL_SCAN("timer expired\n");
2937 brcmf_wakeup_iscan(iscan);
2941 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_info *cfg)
2943 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2945 if (cfg->iscan_on) {
2946 iscan->state = WL_ISCAN_STATE_IDLE;
2947 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2953 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2955 memset(el, 0, sizeof(*el));
2956 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2957 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2958 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2959 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2960 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2963 static s32 brcmf_init_iscan(struct brcmf_cfg80211_info *cfg)
2965 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg);
2968 if (cfg->iscan_on) {
2969 iscan->ndev = cfg_to_ndev(cfg);
2970 brcmf_init_iscan_eloop(&iscan->el);
2971 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2972 init_timer(&iscan->timer);
2973 iscan->timer.data = (unsigned long) iscan;
2974 iscan->timer.function = brcmf_iscan_timer;
2975 err = brcmf_invoke_iscan(cfg);
2983 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2985 struct brcmf_cfg80211_info *cfg =
2986 container_of(work, struct brcmf_cfg80211_info,
2987 escan_timeout_work);
2989 brcmf_notify_escan_complete(cfg,
2990 cfg->escan_info.ndev, true, true);
2993 static void brcmf_escan_timeout(unsigned long data)
2995 struct brcmf_cfg80211_info *cfg =
2996 (struct brcmf_cfg80211_info *)data;
2998 if (cfg->scan_request) {
2999 WL_ERR("timer expired\n");
3001 schedule_work(&cfg->escan_timeout_work);
3006 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
3007 struct brcmf_bss_info_le *bss_info_le)
3009 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3010 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
3011 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
3012 bss_info_le->SSID_len == bss->SSID_len &&
3013 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3014 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
3015 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
3016 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3017 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3019 /* preserve max RSSI if the measurements are
3020 * both on-channel or both off-channel
3022 if (bss_info_rssi > bss_rssi)
3023 bss->RSSI = bss_info_le->RSSI;
3024 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
3025 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
3026 /* preserve the on-channel rssi measurement
3027 * if the new measurement is off channel
3029 bss->RSSI = bss_info_le->RSSI;
3030 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
3038 brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info *cfg,
3039 struct net_device *ndev,
3040 const struct brcmf_event_msg *e, void *data)
3044 struct brcmf_escan_result_le *escan_result_le;
3045 struct brcmf_bss_info_le *bss_info_le;
3046 struct brcmf_bss_info_le *bss = NULL;
3048 struct brcmf_scan_results *list;
3052 status = be32_to_cpu(e->status);
3054 if (!ndev || !cfg->escan_on ||
3055 !test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3056 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
3057 ndev, cfg->escan_on,
3058 !test_bit(WL_STATUS_SCANNING, &cfg->status));
3062 if (status == BRCMF_E_STATUS_PARTIAL) {
3063 WL_SCAN("ESCAN Partial result\n");
3064 escan_result_le = (struct brcmf_escan_result_le *) data;
3065 if (!escan_result_le) {
3066 WL_ERR("Invalid escan result (NULL pointer)\n");
3069 if (!cfg->scan_request) {
3070 WL_SCAN("result without cfg80211 request\n");
3074 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3075 WL_ERR("Invalid bss_count %d: ignoring\n",
3076 escan_result_le->bss_count);
3079 bss_info_le = &escan_result_le->bss_info_le;
3081 bi_length = le32_to_cpu(bss_info_le->length);
3082 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
3083 WL_ESCAN_RESULTS_FIXED_SIZE)) {
3084 WL_ERR("Invalid bss_info length %d: ignoring\n",
3089 if (!(cfg_to_wiphy(cfg)->interface_modes &
3090 BIT(NL80211_IFTYPE_ADHOC))) {
3091 if (le16_to_cpu(bss_info_le->capability) &
3092 WLAN_CAPABILITY_IBSS) {
3093 WL_ERR("Ignoring IBSS result\n");
3098 list = (struct brcmf_scan_results *)
3099 cfg->escan_info.escan_buf;
3100 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
3101 WL_ERR("Buffer is too small: ignoring\n");
3105 for (i = 0; i < list->count; i++) {
3106 bss = bss ? (struct brcmf_bss_info_le *)
3107 ((unsigned char *)bss +
3108 le32_to_cpu(bss->length)) : list->bss_info_le;
3109 if (brcmf_compare_update_same_bss(bss, bss_info_le))
3112 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3113 bss_info_le, bi_length);
3114 list->version = le32_to_cpu(bss_info_le->version);
3115 list->buflen += bi_length;
3118 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3119 if (cfg->scan_request) {
3120 cfg->bss_list = (struct brcmf_scan_results *)
3121 cfg->escan_info.escan_buf;
3122 brcmf_inform_bss(cfg);
3123 aborted = status != BRCMF_E_STATUS_SUCCESS;
3124 brcmf_notify_escan_complete(cfg, ndev, aborted,
3127 WL_ERR("Unexpected scan result 0x%x\n", status);
3133 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3136 if (cfg->escan_on) {
3137 cfg->el.handler[BRCMF_E_ESCAN_RESULT] =
3138 brcmf_cfg80211_escan_handler;
3139 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3140 /* Init scan_timeout timer */
3141 init_timer(&cfg->escan_timeout);
3142 cfg->escan_timeout.data = (unsigned long) cfg;
3143 cfg->escan_timeout.function = brcmf_escan_timeout;
3144 INIT_WORK(&cfg->escan_timeout_work,
3145 brcmf_cfg80211_escan_timeout_worker);
3149 static __always_inline void brcmf_delay(u32 ms)
3151 if (ms < 1000 / HZ) {
3159 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3161 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3164 * Check for WL_STATUS_READY before any function call which
3165 * could result is bus access. Don't block the resume for
3166 * any driver error conditions
3168 WL_TRACE("Enter\n");
3170 if (test_bit(WL_STATUS_READY, &cfg->status))
3171 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
3177 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3178 struct cfg80211_wowlan *wow)
3180 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3181 struct net_device *ndev = cfg_to_ndev(cfg);
3183 WL_TRACE("Enter\n");
3186 * Check for WL_STATUS_READY before any function call which
3187 * could result is bus access. Don't block the suspend for
3188 * any driver error conditions
3192 * While going to suspend if associated with AP disassociate
3193 * from AP to save power while system is in suspended state
3195 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
3196 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
3197 test_bit(WL_STATUS_READY, &cfg->status)) {
3198 WL_INFO("Disassociating from AP"
3199 " while entering suspend state\n");
3200 brcmf_link_down(cfg);
3203 * Make sure WPA_Supplicant receives all the event
3204 * generated due to DISASSOC call to the fw to keep
3205 * the state fw and WPA_Supplicant state consistent
3210 if (test_bit(WL_STATUS_READY, &cfg->status))
3211 brcmf_abort_scanning(cfg);
3213 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3215 /* Turn off watchdog timer */
3216 if (test_bit(WL_STATUS_READY, &cfg->status))
3217 brcmf_set_mpc(ndev, 1);
3225 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
3227 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3230 buflen = brcmf_c_mkiovar(name, buf, len, cfg->dcmd_buf,
3234 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg->dcmd_buf,
3239 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
3242 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
3246 len = brcmf_c_mkiovar(name, NULL, 0, cfg->dcmd_buf,
3249 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg->dcmd_buf,
3252 WL_ERR("error (%d)\n", err);
3255 memcpy(buf, cfg->dcmd_buf, buf_len);
3261 brcmf_update_pmklist(struct net_device *ndev,
3262 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3267 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3269 WL_CONN("No of elements %d\n", pmkid_len);
3270 for (i = 0; i < pmkid_len; i++) {
3271 WL_CONN("PMKID[%d]: %pM =\n", i,
3272 &pmk_list->pmkids.pmkid[i].BSSID);
3273 for (j = 0; j < WLAN_PMKID_LEN; j++)
3274 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
3278 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
3285 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3286 struct cfg80211_pmksa *pmksa)
3288 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3289 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3294 WL_TRACE("Enter\n");
3295 if (!check_sys_up(wiphy))
3298 pmkid_len = le32_to_cpu(pmkids->npmkid);
3299 for (i = 0; i < pmkid_len; i++)
3300 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3302 if (i < WL_NUM_PMKIDS_MAX) {
3303 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3304 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3305 if (i == pmkid_len) {
3307 pmkids->npmkid = cpu_to_le32(pmkid_len);
3312 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3313 pmkids->pmkid[pmkid_len].BSSID);
3314 for (i = 0; i < WLAN_PMKID_LEN; i++)
3315 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3317 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3324 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3325 struct cfg80211_pmksa *pmksa)
3327 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3328 struct pmkid_list pmkid;
3332 WL_TRACE("Enter\n");
3333 if (!check_sys_up(wiphy))
3336 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3337 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3339 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3340 &pmkid.pmkid[0].BSSID);
3341 for (i = 0; i < WLAN_PMKID_LEN; i++)
3342 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
3344 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3345 for (i = 0; i < pmkid_len; i++)
3347 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3352 && (i < pmkid_len)) {
3353 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3354 sizeof(struct pmkid));
3355 for (; i < (pmkid_len - 1); i++) {
3356 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3357 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3359 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3360 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3363 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3367 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3375 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3377 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3380 WL_TRACE("Enter\n");
3381 if (!check_sys_up(wiphy))
3384 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3385 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3393 * PFN result doesn't have all the info which are
3394 * required by the supplicant
3395 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3396 * via wl_inform_single_bss in the required format. Escan does require the
3397 * scan request in the form of cfg80211_scan_request. For timebeing, create
3398 * cfg80211_scan_request one out of the received PNO event.
3401 brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info *cfg,
3402 struct net_device *ndev,
3403 const struct brcmf_event_msg *e, void *data)
3405 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3406 struct cfg80211_scan_request *request = NULL;
3407 struct cfg80211_ssid *ssid = NULL;
3408 struct ieee80211_channel *channel = NULL;
3409 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3411 int channel_req = 0;
3413 struct brcmf_pno_scanresults_le *pfn_result;
3419 if (e->event_type == cpu_to_be32(BRCMF_E_PFN_NET_LOST)) {
3420 WL_SCAN("PFN NET LOST event. Do Nothing\n");
3424 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3425 result_count = le32_to_cpu(pfn_result->count);
3426 status = le32_to_cpu(pfn_result->status);
3429 * PFN event is limited to fit 512 bytes so we may get
3430 * multiple NET_FOUND events. For now place a warning here.
3432 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3433 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count);
3434 if (result_count > 0) {
3437 request = kzalloc(sizeof(*request), GFP_KERNEL);
3438 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3439 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3440 if (!request || !ssid || !channel) {
3445 request->wiphy = wiphy;
3446 data += sizeof(struct brcmf_pno_scanresults_le);
3447 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3449 for (i = 0; i < result_count; i++) {
3450 netinfo = &netinfo_start[i];
3452 WL_ERR("Invalid netinfo ptr. index: %d\n", i);
3457 WL_SCAN("SSID:%s Channel:%d\n",
3458 netinfo->SSID, netinfo->channel);
3459 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3460 ssid[i].ssid_len = netinfo->SSID_len;
3463 channel_req = netinfo->channel;
3464 if (channel_req <= CH_MAX_2G_CHANNEL)
3465 band = NL80211_BAND_2GHZ;
3467 band = NL80211_BAND_5GHZ;
3468 channel[i].center_freq =
3469 ieee80211_channel_to_frequency(channel_req,
3471 channel[i].band = band;
3472 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3473 request->channels[i] = &channel[i];
3474 request->n_channels++;
3477 /* assign parsed ssid array */
3478 if (request->n_ssids)
3479 request->ssids = &ssid[0];
3481 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3482 /* Abort any on-going scan */
3483 brcmf_abort_scanning(cfg);
3486 set_bit(WL_STATUS_SCANNING, &cfg->status);
3487 err = brcmf_do_escan(cfg, wiphy, ndev, request);
3489 clear_bit(WL_STATUS_SCANNING, &cfg->status);
3492 cfg->sched_escan = true;
3493 cfg->scan_request = request;
3495 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3508 cfg80211_sched_scan_stopped(wiphy);
3512 #ifndef CONFIG_BRCMISCAN
3513 static int brcmf_dev_pno_clean(struct net_device *ndev)
3519 ret = brcmf_dev_intvar_set(ndev, "pfn", 0);
3522 ret = brcmf_dev_iovar_setbuf(ndev, "pfnclear", NULL, 0,
3523 iovbuf, sizeof(iovbuf));
3526 WL_ERR("failed code %d\n", ret);
3531 static int brcmf_dev_pno_config(struct net_device *ndev)
3533 struct brcmf_pno_param_le pfn_param;
3536 memset(&pfn_param, 0, sizeof(pfn_param));
3537 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3539 /* set extra pno params */
3540 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3541 pfn_param.repeat = BRCMF_PNO_REPEAT;
3542 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3544 /* set up pno scan fr */
3545 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3547 return brcmf_dev_iovar_setbuf(ndev, "pfn_set",
3548 &pfn_param, sizeof(pfn_param),
3549 iovbuf, sizeof(iovbuf));
3553 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3554 struct net_device *ndev,
3555 struct cfg80211_sched_scan_request *request)
3558 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3559 struct brcmf_pno_net_param_le pfn;
3563 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3564 request->n_match_sets, request->n_ssids);
3565 if (test_bit(WL_STATUS_SCANNING, &cfg->status)) {
3566 WL_ERR("Scanning already : status (%lu)\n", cfg->status);
3570 if (!request || !request->n_ssids || !request->n_match_sets) {
3571 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
3576 if (request->n_ssids > 0) {
3577 for (i = 0; i < request->n_ssids; i++) {
3578 /* Active scan req for ssids */
3579 WL_SCAN(">>> Active scan req for ssid (%s)\n",
3580 request->ssids[i].ssid);
3583 * match_set ssids is a supert set of n_ssid list,
3584 * so we need not add these set seperately.
3589 if (request->n_match_sets > 0) {
3590 /* clean up everything */
3591 ret = brcmf_dev_pno_clean(ndev);
3593 WL_ERR("failed error=%d\n", ret);
3598 ret = brcmf_dev_pno_config(ndev);
3600 WL_ERR("PNO setup failed!! ret=%d\n", ret);
3604 /* configure each match set */
3605 for (i = 0; i < request->n_match_sets; i++) {
3606 struct cfg80211_ssid *ssid;
3609 ssid = &request->match_sets[i].ssid;
3610 ssid_len = ssid->ssid_len;
3613 WL_ERR("skip broadcast ssid\n");
3616 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3617 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3618 pfn.wsec = cpu_to_le32(0);
3619 pfn.infra = cpu_to_le32(1);
3620 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3621 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3622 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3623 ret = brcmf_dev_iovar_setbuf(ndev, "pfn_add",
3625 iovbuf, sizeof(iovbuf));
3626 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
3627 ret == 0 ? "set" : "failed",
3630 /* Enable the PNO */
3631 if (brcmf_dev_intvar_set(ndev, "pfn", 1) < 0) {
3632 WL_ERR("PNO enable failed!! ret=%d\n", ret);
3642 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3643 struct net_device *ndev)
3645 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3648 brcmf_dev_pno_clean(ndev);
3649 if (cfg->sched_escan)
3650 brcmf_notify_escan_complete(cfg, ndev, true, true);
3653 #endif /* CONFIG_BRCMISCAN */
3655 #ifdef CONFIG_NL80211_TESTMODE
3656 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3658 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3659 struct net_device *ndev = cfg->wdev->netdev;
3660 struct brcmf_dcmd *dcmd = data;
3661 struct sk_buff *reply;
3664 ret = brcmf_netlink_dcmd(ndev, dcmd);
3666 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3667 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3668 ret = cfg80211_testmode_reply(reply);
3674 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3679 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", 0, bssidx);
3681 WL_ERR("auth error %d\n", err);
3685 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", 0, bssidx);
3687 WL_ERR("wsec error %d\n", err);
3690 /* set upper-layer auth */
3691 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth",
3692 WPA_AUTH_NONE, bssidx);
3694 WL_ERR("wpa_auth error %d\n", err);
3701 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3704 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3706 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3710 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3711 bool is_rsn_ie, s32 bssidx)
3713 u32 auth = 0; /* d11 open authentication */
3725 u32 wme_bss_disable;
3727 WL_TRACE("Enter\n");
3731 len = wpa_ie->len + TLV_HDR_LEN;
3732 data = (u8 *)wpa_ie;
3735 offset += VS_IE_FIXED_HDR_LEN;
3736 offset += WPA_IE_VERSION_LEN;
3738 /* check for multicast cipher suite */
3739 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3741 WL_ERR("no multicast cipher suite\n");
3745 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3747 WL_ERR("ivalid OUI\n");
3750 offset += TLV_OUI_LEN;
3752 /* pick up multicast cipher */
3753 switch (data[offset]) {
3754 case WPA_CIPHER_NONE:
3757 case WPA_CIPHER_WEP_40:
3758 case WPA_CIPHER_WEP_104:
3761 case WPA_CIPHER_TKIP:
3762 gval = TKIP_ENABLED;
3764 case WPA_CIPHER_AES_CCM:
3769 WL_ERR("Invalid multi cast cipher info\n");
3774 /* walk thru unicast cipher list and pick up what we recognize */
3775 count = data[offset] + (data[offset + 1] << 8);
3776 offset += WPA_IE_SUITE_COUNT_LEN;
3777 /* Check for unicast suite(s) */
3778 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3780 WL_ERR("no unicast cipher suite\n");
3783 for (i = 0; i < count; i++) {
3784 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3786 WL_ERR("ivalid OUI\n");
3789 offset += TLV_OUI_LEN;
3790 switch (data[offset]) {
3791 case WPA_CIPHER_NONE:
3793 case WPA_CIPHER_WEP_40:
3794 case WPA_CIPHER_WEP_104:
3795 pval |= WEP_ENABLED;
3797 case WPA_CIPHER_TKIP:
3798 pval |= TKIP_ENABLED;
3800 case WPA_CIPHER_AES_CCM:
3801 pval |= AES_ENABLED;
3804 WL_ERR("Ivalid unicast security info\n");
3808 /* walk thru auth management suite list and pick up what we recognize */
3809 count = data[offset] + (data[offset + 1] << 8);
3810 offset += WPA_IE_SUITE_COUNT_LEN;
3811 /* Check for auth key management suite(s) */
3812 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3814 WL_ERR("no auth key mgmt suite\n");
3817 for (i = 0; i < count; i++) {
3818 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3820 WL_ERR("ivalid OUI\n");
3823 offset += TLV_OUI_LEN;
3824 switch (data[offset]) {
3826 WL_TRACE("RSN_AKM_NONE\n");
3827 wpa_auth |= WPA_AUTH_NONE;
3829 case RSN_AKM_UNSPECIFIED:
3830 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3831 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3832 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3835 WL_TRACE("RSN_AKM_PSK\n");
3836 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3837 (wpa_auth |= WPA_AUTH_PSK);
3840 WL_ERR("Ivalid key mgmt info\n");
3846 wme_bss_disable = 1;
3847 if ((offset + RSN_CAP_LEN) <= len) {
3848 rsn_cap = data[offset] + (data[offset + 1] << 8);
3849 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3850 wme_bss_disable = 0;
3852 /* set wme_bss_disable to sync RSN Capabilities */
3853 err = brcmf_dev_intvar_set_bsscfg(ndev, "wme_bss_disable",
3854 wme_bss_disable, bssidx);
3856 WL_ERR("wme_bss_disable error %d\n", err);
3860 /* FOR WPS , set SES_OW_ENABLED */
3861 wsec = (pval | gval | SES_OW_ENABLED);
3864 err = brcmf_dev_intvar_set_bsscfg(ndev, "auth", auth, bssidx);
3866 WL_ERR("auth error %d\n", err);
3870 err = brcmf_dev_intvar_set_bsscfg(ndev, "wsec", wsec, bssidx);
3872 WL_ERR("wsec error %d\n", err);
3875 /* set upper-layer auth */
3876 err = brcmf_dev_intvar_set_bsscfg(ndev, "wpa_auth", wpa_auth, bssidx);
3878 WL_ERR("wpa_auth error %d\n", err);
3887 brcmf_parse_vndr_ies(u8 *vndr_ie_buf, u32 vndr_ie_len,
3888 struct parsed_vndr_ies *vndr_ies)
3891 struct brcmf_vs_tlv *vndrie;
3892 struct brcmf_tlv *ie;
3893 struct parsed_vndr_ie_info *parsed_info;
3896 remaining_len = (s32)vndr_ie_len;
3897 memset(vndr_ies, 0, sizeof(*vndr_ies));
3899 ie = (struct brcmf_tlv *)vndr_ie_buf;
3901 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3903 vndrie = (struct brcmf_vs_tlv *)ie;
3904 /* len should be bigger than OUI length + one */
3905 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3906 WL_ERR("invalid vndr ie. length is too small %d\n",
3910 /* if wpa or wme ie, do not add ie */
3911 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3912 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3913 (vndrie->oui_type == WME_OUI_TYPE))) {
3914 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3918 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3920 /* save vndr ie information */
3921 parsed_info->ie_ptr = (char *)vndrie;
3922 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3923 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3927 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3928 parsed_info->vndrie.oui[0],
3929 parsed_info->vndrie.oui[1],
3930 parsed_info->vndrie.oui[2],
3931 parsed_info->vndrie.oui_type);
3933 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3936 remaining_len -= ie->len;
3937 if (remaining_len <= 2)
3940 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len);
3946 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3952 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3953 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3955 iecount_le = cpu_to_le32(1);
3956 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3958 pktflag_le = cpu_to_le32(pktflag);
3959 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3961 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3963 return ie_len + VNDR_IE_HDR_SIZE;
3967 brcmf_set_management_ie(struct brcmf_cfg80211_info *cfg,
3968 struct net_device *ndev, s32 bssidx, s32 pktflag,
3969 u8 *vndr_ie_buf, u32 vndr_ie_len)
3974 u8 *mgmt_ie_buf = NULL;
3975 u32 mgmt_ie_buf_len = 0;
3976 u32 *mgmt_ie_len = 0;
3977 u32 del_add_ie_buf_len = 0;
3978 u32 total_ie_buf_len = 0;
3979 u32 parsed_ie_buf_len = 0;
3980 struct parsed_vndr_ies old_vndr_ies;
3981 struct parsed_vndr_ies new_vndr_ies;
3982 struct parsed_vndr_ie_info *vndrie_info;
3985 u32 remained_buf_len;
3987 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx, pktflag);
3988 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3991 curr_ie_buf = iovar_ie_buf;
3992 if (test_bit(WL_STATUS_AP_CREATING, &cfg->status) ||
3993 test_bit(WL_STATUS_AP_CREATED, &cfg->status)) {
3995 case VNDR_IE_PRBRSP_FLAG:
3996 mgmt_ie_buf = cfg->ap_info->probe_res_ie;
3997 mgmt_ie_len = &cfg->ap_info->probe_res_ie_len;
3999 sizeof(cfg->ap_info->probe_res_ie);
4001 case VNDR_IE_BEACON_FLAG:
4002 mgmt_ie_buf = cfg->ap_info->beacon_ie;
4003 mgmt_ie_len = &cfg->ap_info->beacon_ie_len;
4004 mgmt_ie_buf_len = sizeof(cfg->ap_info->beacon_ie);
4008 WL_ERR("not suitable type\n");
4014 WL_ERR("not suitable type\n");
4018 if (vndr_ie_len > mgmt_ie_buf_len) {
4020 WL_ERR("extra IE size too big\n");
4024 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4025 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4027 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4028 for (i = 0; i < new_vndr_ies.count; i++) {
4029 vndrie_info = &new_vndr_ies.ie_info[i];
4030 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4031 vndrie_info->ie_len);
4032 parsed_ie_buf_len += vndrie_info->ie_len;
4036 if (mgmt_ie_buf != NULL) {
4037 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4038 (memcmp(mgmt_ie_buf, curr_ie_buf,
4039 parsed_ie_buf_len) == 0)) {
4040 WL_TRACE("Previous mgmt IE is equals to current IE");
4044 /* parse old vndr_ie */
4045 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4047 /* make a command to delete old ie */
4048 for (i = 0; i < old_vndr_ies.count; i++) {
4049 vndrie_info = &old_vndr_ies.ie_info[i];
4051 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4052 vndrie_info->vndrie.id,
4053 vndrie_info->vndrie.len,
4054 vndrie_info->vndrie.oui[0],
4055 vndrie_info->vndrie.oui[1],
4056 vndrie_info->vndrie.oui[2]);
4058 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4059 vndrie_info->ie_ptr,
4060 vndrie_info->ie_len,
4062 curr_ie_buf += del_add_ie_buf_len;
4063 total_ie_buf_len += del_add_ie_buf_len;
4068 /* Add if there is any extra IE */
4069 if (mgmt_ie_buf && parsed_ie_buf_len) {
4072 remained_buf_len = mgmt_ie_buf_len;
4074 /* make a command to add new ie */
4075 for (i = 0; i < new_vndr_ies.count; i++) {
4076 vndrie_info = &new_vndr_ies.ie_info[i];
4078 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4079 vndrie_info->vndrie.id,
4080 vndrie_info->vndrie.len,
4081 vndrie_info->vndrie.oui[0],
4082 vndrie_info->vndrie.oui[1],
4083 vndrie_info->vndrie.oui[2]);
4085 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4086 vndrie_info->ie_ptr,
4087 vndrie_info->ie_len,
4089 /* verify remained buf size before copy data */
4090 remained_buf_len -= vndrie_info->ie_len;
4091 if (remained_buf_len < 0) {
4092 WL_ERR("no space in mgmt_ie_buf: len left %d",
4097 /* save the parsed IE in wl struct */
4098 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4099 vndrie_info->ie_len);
4100 *mgmt_ie_len += vndrie_info->ie_len;
4102 curr_ie_buf += del_add_ie_buf_len;
4103 total_ie_buf_len += del_add_ie_buf_len;
4106 if (total_ie_buf_len) {
4107 err = brcmf_dev_iovar_setbuf_bsscfg(ndev, "vndr_ie",
4111 WL_EXTRA_BUF_MAX, bssidx);
4113 WL_ERR("vndr ie set error : %d\n", err);
4117 kfree(iovar_ie_buf);
4122 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4123 struct cfg80211_ap_settings *settings)
4126 struct brcmf_tlv *ssid_ie;
4127 struct brcmf_ssid_le ssid_le;
4130 struct brcmf_tlv *rsn_ie;
4131 struct brcmf_vs_tlv *wpa_ie;
4132 struct brcmf_join_params join_params;
4133 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4136 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
4137 settings->channel_type, settings->beacon_interval,
4138 settings->dtim_period);
4139 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
4140 settings->ssid, settings->ssid_len, settings->auth_type,
4141 settings->inactivity_timeout);
4143 if (!test_bit(WL_STATUS_AP_CREATING, &cfg->status)) {
4144 WL_ERR("Not in AP creation mode\n");
4148 memset(&ssid_le, 0, sizeof(ssid_le));
4149 if (settings->ssid == NULL || settings->ssid_len == 0) {
4150 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4151 ssid_ie = brcmf_parse_tlvs(
4152 (u8 *)&settings->beacon.head[ie_offset],
4153 settings->beacon.head_len - ie_offset,
4158 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4159 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4160 WL_TRACE("SSID is (%s) in Head\n", ssid_le.SSID);
4162 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4163 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4166 brcmf_set_mpc(ndev, 0);
4168 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_DOWN, &ioctl_value);
4170 WL_ERR("BRCMF_C_DOWN error %d\n", err);
4174 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &ioctl_value);
4176 WL_ERR("SET INFRA error %d\n", err);
4180 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4182 WL_ERR("setting AP mode failed %d\n", err);
4186 /* find the RSN_IE */
4187 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4188 settings->beacon.tail_len, WLAN_EID_RSN);
4190 /* find the WPA_IE */
4191 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4192 settings->beacon.tail_len);
4194 kfree(cfg->ap_info->rsn_ie);
4195 cfg->ap_info->rsn_ie = NULL;
4196 kfree(cfg->ap_info->wpa_ie);
4197 cfg->ap_info->wpa_ie = NULL;
4199 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4200 WL_TRACE("WPA(2) IE is found\n");
4201 if (wpa_ie != NULL) {
4203 err = brcmf_configure_wpaie(ndev, wpa_ie, false,
4207 cfg->ap_info->wpa_ie = kmemdup(wpa_ie,
4213 err = brcmf_configure_wpaie(ndev,
4214 (struct brcmf_vs_tlv *)rsn_ie, true, bssidx);
4217 cfg->ap_info->rsn_ie = kmemdup(rsn_ie,
4222 cfg->ap_info->security_mode = true;
4224 WL_TRACE("No WPA(2) IEs found\n");
4225 brcmf_configure_opensecurity(ndev, bssidx);
4226 cfg->ap_info->security_mode = false;
4228 /* Set Beacon IEs to FW */
4229 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4230 VNDR_IE_BEACON_FLAG,
4231 (u8 *)settings->beacon.tail,
4232 settings->beacon.tail_len);
4234 WL_ERR("Set Beacon IE Failed\n");
4236 WL_TRACE("Applied Vndr IEs for Beacon\n");
4238 /* Set Probe Response IEs to FW */
4239 err = brcmf_set_management_ie(cfg, ndev, bssidx,
4240 VNDR_IE_PRBRSP_FLAG,
4241 (u8 *)settings->beacon.proberesp_ies,
4242 settings->beacon.proberesp_ies_len);
4244 WL_ERR("Set Probe Resp IE Failed\n");
4246 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4248 if (settings->beacon_interval) {
4249 ioctl_value = settings->beacon_interval;
4250 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_BCNPRD,
4253 WL_ERR("Beacon Interval Set Error, %d\n", err);
4257 if (settings->dtim_period) {
4258 ioctl_value = settings->dtim_period;
4259 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_DTIMPRD,
4262 WL_ERR("DTIM Interval Set Error, %d\n", err);
4267 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4269 WL_ERR("BRCMF_C_UP error (%d)\n", err);
4273 memset(&join_params, 0, sizeof(join_params));
4274 /* join parameters starts with ssid */
4275 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4277 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID, &join_params,
4278 sizeof(join_params));
4280 WL_ERR("SET SSID error (%d)\n", err);
4283 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4284 set_bit(WL_STATUS_AP_CREATED, &cfg->status);
4288 brcmf_set_mpc(ndev, 1);
4292 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4294 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4298 WL_TRACE("Enter\n");
4300 if (cfg->conf->mode == WL_MODE_AP) {
4301 /* Due to most likely deauths outstanding we sleep */
4302 /* first to make sure they get processed by fw. */
4305 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AP, &ioctl_value);
4307 WL_ERR("setting AP mode failed %d\n", err);
4311 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_UP, &ioctl_value);
4313 WL_ERR("BRCMF_C_UP error %d\n", err);
4316 brcmf_set_mpc(ndev, 1);
4317 clear_bit(WL_STATUS_AP_CREATING, &cfg->status);
4318 clear_bit(WL_STATUS_AP_CREATED, &cfg->status);
4325 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4328 struct brcmf_scb_val_le scbval;
4334 WL_TRACE("Enter %pM\n", mac);
4336 if (!check_sys_up(wiphy))
4339 memcpy(&scbval.ea, mac, ETH_ALEN);
4340 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
4341 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4342 &scbval, sizeof(scbval));
4344 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4350 static struct cfg80211_ops wl_cfg80211_ops = {
4351 .change_virtual_intf = brcmf_cfg80211_change_iface,
4352 .scan = brcmf_cfg80211_scan,
4353 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4354 .join_ibss = brcmf_cfg80211_join_ibss,
4355 .leave_ibss = brcmf_cfg80211_leave_ibss,
4356 .get_station = brcmf_cfg80211_get_station,
4357 .set_tx_power = brcmf_cfg80211_set_tx_power,
4358 .get_tx_power = brcmf_cfg80211_get_tx_power,
4359 .add_key = brcmf_cfg80211_add_key,
4360 .del_key = brcmf_cfg80211_del_key,
4361 .get_key = brcmf_cfg80211_get_key,
4362 .set_default_key = brcmf_cfg80211_config_default_key,
4363 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4364 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4365 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
4366 .connect = brcmf_cfg80211_connect,
4367 .disconnect = brcmf_cfg80211_disconnect,
4368 .suspend = brcmf_cfg80211_suspend,
4369 .resume = brcmf_cfg80211_resume,
4370 .set_pmksa = brcmf_cfg80211_set_pmksa,
4371 .del_pmksa = brcmf_cfg80211_del_pmksa,
4372 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4373 .start_ap = brcmf_cfg80211_start_ap,
4374 .stop_ap = brcmf_cfg80211_stop_ap,
4375 .del_station = brcmf_cfg80211_del_station,
4376 #ifndef CONFIG_BRCMISCAN
4377 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4378 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4379 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4381 #ifdef CONFIG_NL80211_TESTMODE
4382 .testmode_cmd = brcmf_cfg80211_testmode
4386 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
4392 return NL80211_IFTYPE_STATION;
4394 return NL80211_IFTYPE_ADHOC;
4396 return NL80211_IFTYPE_UNSPECIFIED;
4402 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4404 #ifndef CONFIG_BRCMFISCAN
4405 /* scheduled scan settings */
4406 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4407 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4408 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4409 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4413 static struct wireless_dev *brcmf_alloc_wdev(struct device *ndev)
4415 struct wireless_dev *wdev;
4418 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
4420 return ERR_PTR(-ENOMEM);
4422 wdev->wiphy = wiphy_new(&wl_cfg80211_ops,
4423 sizeof(struct brcmf_cfg80211_info));
4425 WL_ERR("Could not allocate wiphy device\n");
4429 set_wiphy_dev(wdev->wiphy, ndev);
4430 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4431 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4432 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4433 BIT(NL80211_IFTYPE_ADHOC) |
4434 BIT(NL80211_IFTYPE_AP);
4435 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4436 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
4437 * it as 11a by default.
4438 * This will be updated with
4441 * if phy has 11n capability
4443 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4444 wdev->wiphy->cipher_suites = __wl_cipher_suites;
4445 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4446 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
4450 brcmf_wiphy_pno_params(wdev->wiphy);
4451 err = wiphy_register(wdev->wiphy);
4453 WL_ERR("Could not register wiphy device (%d)\n", err);
4454 goto wiphy_register_out;
4459 wiphy_free(wdev->wiphy);
4464 return ERR_PTR(err);
4467 static void brcmf_free_wdev(struct brcmf_cfg80211_info *cfg)
4469 struct wireless_dev *wdev = cfg->wdev;
4472 WL_ERR("wdev is invalid\n");
4475 wiphy_unregister(wdev->wiphy);
4476 wiphy_free(wdev->wiphy);
4481 static bool brcmf_is_linkup(struct brcmf_cfg80211_info *cfg,
4482 const struct brcmf_event_msg *e)
4484 u32 event = be32_to_cpu(e->event_type);
4485 u32 status = be32_to_cpu(e->status);
4487 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4488 WL_CONN("Processing set ssid\n");
4489 cfg->link_up = true;
4496 static bool brcmf_is_linkdown(struct brcmf_cfg80211_info *cfg,
4497 const struct brcmf_event_msg *e)
4499 u32 event = be32_to_cpu(e->event_type);
4500 u16 flags = be16_to_cpu(e->flags);
4502 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4503 WL_CONN("Processing link down\n");
4509 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4510 const struct brcmf_event_msg *e)
4512 u32 event = be32_to_cpu(e->event_type);
4513 u32 status = be32_to_cpu(e->status);
4515 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4516 WL_CONN("Processing Link %s & no network found\n",
4517 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
4522 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4523 WL_CONN("Processing connecting & no network found\n");
4530 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4532 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4534 kfree(conn_info->req_ie);
4535 conn_info->req_ie = NULL;
4536 conn_info->req_ie_len = 0;
4537 kfree(conn_info->resp_ie);
4538 conn_info->resp_ie = NULL;
4539 conn_info->resp_ie_len = 0;
4542 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
4544 struct net_device *ndev = cfg_to_ndev(cfg);
4545 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4546 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4551 brcmf_clear_assoc_ies(cfg);
4553 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg->extra_buf,
4556 WL_ERR("could not get assoc info (%d)\n", err);
4560 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4561 req_len = le32_to_cpu(assoc_info->req_len);
4562 resp_len = le32_to_cpu(assoc_info->resp_len);
4564 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
4568 WL_ERR("could not get assoc req (%d)\n", err);
4571 conn_info->req_ie_len = req_len;
4573 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4576 conn_info->req_ie_len = 0;
4577 conn_info->req_ie = NULL;
4580 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
4584 WL_ERR("could not get assoc resp (%d)\n", err);
4587 conn_info->resp_ie_len = resp_len;
4588 conn_info->resp_ie =
4589 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4592 conn_info->resp_ie_len = 0;
4593 conn_info->resp_ie = NULL;
4595 WL_CONN("req len (%d) resp len (%d)\n",
4596 conn_info->req_ie_len, conn_info->resp_ie_len);
4602 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4603 struct net_device *ndev,
4604 const struct brcmf_event_msg *e)
4606 struct brcmf_cfg80211_profile *profile = cfg->profile;
4607 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4608 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4609 struct brcmf_channel_info_le channel_le;
4610 struct ieee80211_channel *notify_channel;
4611 struct ieee80211_supported_band *band;
4616 WL_TRACE("Enter\n");
4618 brcmf_get_assoc_ies(cfg);
4619 memcpy(profile->bssid, e->addr, ETH_ALEN);
4620 brcmf_update_bss_info(cfg);
4622 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
4623 sizeof(channel_le));
4625 target_channel = le32_to_cpu(channel_le.target_channel);
4626 WL_CONN("Roamed to channel %d\n", target_channel);
4628 if (target_channel <= CH_MAX_2G_CHANNEL)
4629 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4631 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4633 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4634 notify_channel = ieee80211_get_channel(wiphy, freq);
4636 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4637 conn_info->req_ie, conn_info->req_ie_len,
4638 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4639 WL_CONN("Report roaming result\n");
4641 set_bit(WL_STATUS_CONNECTED, &cfg->status);
4647 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4648 struct net_device *ndev, const struct brcmf_event_msg *e,
4651 struct brcmf_cfg80211_profile *profile = cfg->profile;
4652 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4655 WL_TRACE("Enter\n");
4657 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg->status)) {
4659 brcmf_get_assoc_ies(cfg);
4660 memcpy(profile->bssid, e->addr, ETH_ALEN);
4661 brcmf_update_bss_info(cfg);
4663 cfg80211_connect_result(ndev,
4664 (u8 *)profile->bssid,
4666 conn_info->req_ie_len,
4668 conn_info->resp_ie_len,
4669 completed ? WLAN_STATUS_SUCCESS :
4670 WLAN_STATUS_AUTH_TIMEOUT,
4673 set_bit(WL_STATUS_CONNECTED, &cfg->status);
4674 WL_CONN("Report connect result - connection %s\n",
4675 completed ? "succeeded" : "failed");
4682 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4683 struct net_device *ndev,
4684 const struct brcmf_event_msg *e, void *data)
4687 u32 event = be32_to_cpu(e->event_type);
4688 u32 reason = be32_to_cpu(e->reason);
4689 u32 len = be32_to_cpu(e->datalen);
4690 static int generation;
4692 struct station_info sinfo;
4694 WL_CONN("event %d, reason %d\n", event, reason);
4695 memset(&sinfo, 0, sizeof(sinfo));
4698 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4699 reason == BRCMF_E_STATUS_SUCCESS) {
4700 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4702 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4705 sinfo.assoc_req_ies = data;
4706 sinfo.assoc_req_ies_len = len;
4708 sinfo.generation = generation;
4709 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4710 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4711 (event == BRCMF_E_DEAUTH_IND) ||
4712 (event == BRCMF_E_DEAUTH)) {
4714 sinfo.generation = generation;
4715 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4721 brcmf_notify_connect_status(struct brcmf_cfg80211_info *cfg,
4722 struct net_device *ndev,
4723 const struct brcmf_event_msg *e, void *data)
4725 struct brcmf_cfg80211_profile *profile = cfg->profile;
4728 if (cfg->conf->mode == WL_MODE_AP) {
4729 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4730 } else if (brcmf_is_linkup(cfg, e)) {
4731 WL_CONN("Linkup\n");
4732 if (brcmf_is_ibssmode(cfg)) {
4733 memcpy(profile->bssid, e->addr, ETH_ALEN);
4734 wl_inform_ibss(cfg, ndev, e->addr);
4735 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4736 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
4737 set_bit(WL_STATUS_CONNECTED, &cfg->status);
4739 brcmf_bss_connect_done(cfg, ndev, e, true);
4740 } else if (brcmf_is_linkdown(cfg, e)) {
4741 WL_CONN("Linkdown\n");
4742 if (brcmf_is_ibssmode(cfg)) {
4743 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
4744 if (test_and_clear_bit(WL_STATUS_CONNECTED,
4746 brcmf_link_down(cfg);
4748 brcmf_bss_connect_done(cfg, ndev, e, false);
4749 if (test_and_clear_bit(WL_STATUS_CONNECTED,
4751 cfg80211_disconnected(ndev, 0, NULL, 0,
4753 brcmf_link_down(cfg);
4756 brcmf_init_prof(cfg->profile);
4757 } else if (brcmf_is_nonetwork(cfg, e)) {
4758 if (brcmf_is_ibssmode(cfg))
4759 clear_bit(WL_STATUS_CONNECTING, &cfg->status);
4761 brcmf_bss_connect_done(cfg, ndev, e, false);
4768 brcmf_notify_roaming_status(struct brcmf_cfg80211_info *cfg,
4769 struct net_device *ndev,
4770 const struct brcmf_event_msg *e, void *data)
4773 u32 event = be32_to_cpu(e->event_type);
4774 u32 status = be32_to_cpu(e->status);
4776 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4777 if (test_bit(WL_STATUS_CONNECTED, &cfg->status))
4778 brcmf_bss_roaming_done(cfg, ndev, e);
4780 brcmf_bss_connect_done(cfg, ndev, e, true);
4787 brcmf_notify_mic_status(struct brcmf_cfg80211_info *cfg,
4788 struct net_device *ndev,
4789 const struct brcmf_event_msg *e, void *data)
4791 u16 flags = be16_to_cpu(e->flags);
4792 enum nl80211_key_type key_type;
4794 if (flags & BRCMF_EVENT_MSG_GROUP)
4795 key_type = NL80211_KEYTYPE_GROUP;
4797 key_type = NL80211_KEYTYPE_PAIRWISE;
4799 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
4806 brcmf_notify_scan_status(struct brcmf_cfg80211_info *cfg,
4807 struct net_device *ndev,
4808 const struct brcmf_event_msg *e, void *data)
4810 struct brcmf_channel_info_le channel_inform_le;
4811 struct brcmf_scan_results_le *bss_list_le;
4812 u32 len = WL_SCAN_BUF_MAX;
4814 bool scan_abort = false;
4817 WL_TRACE("Enter\n");
4819 if (cfg->iscan_on && cfg->iscan_kickstart) {
4821 return brcmf_wakeup_iscan(cfg_to_iscan(cfg));
4824 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg->status)) {
4825 WL_ERR("Scan complete while device not scanning\n");
4831 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
4832 sizeof(channel_inform_le));
4834 WL_ERR("scan busy (%d)\n", err);
4838 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
4840 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
4841 cfg->bss_list = cfg->scan_results;
4842 bss_list_le = (struct brcmf_scan_results_le *) cfg->bss_list;
4844 memset(cfg->scan_results, 0, len);
4845 bss_list_le->buflen = cpu_to_le32(len);
4846 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
4847 cfg->scan_results, len);
4849 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
4854 cfg->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
4855 cfg->scan_results->version = le32_to_cpu(bss_list_le->version);
4856 cfg->scan_results->count = le32_to_cpu(bss_list_le->count);
4858 err = brcmf_inform_bss(cfg);
4863 if (cfg->scan_request) {
4864 WL_SCAN("calling cfg80211_scan_done\n");
4865 cfg80211_scan_done(cfg->scan_request, scan_abort);
4866 brcmf_set_mpc(ndev, 1);
4867 cfg->scan_request = NULL;
4875 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4877 conf->mode = (u32)-1;
4878 conf->frag_threshold = (u32)-1;
4879 conf->rts_threshold = (u32)-1;
4880 conf->retry_short = (u32)-1;
4881 conf->retry_long = (u32)-1;
4882 conf->tx_power = -1;
4885 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
4887 memset(el, 0, sizeof(*el));
4888 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
4889 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
4890 el->handler[BRCMF_E_DEAUTH_IND] = brcmf_notify_connect_status;
4891 el->handler[BRCMF_E_DEAUTH] = brcmf_notify_connect_status;
4892 el->handler[BRCMF_E_DISASSOC_IND] = brcmf_notify_connect_status;
4893 el->handler[BRCMF_E_ASSOC_IND] = brcmf_notify_connect_status;
4894 el->handler[BRCMF_E_REASSOC_IND] = brcmf_notify_connect_status;
4895 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
4896 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
4897 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
4898 el->handler[BRCMF_E_PFN_NET_FOUND] = brcmf_notify_sched_scan_results;
4901 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4903 kfree(cfg->scan_results);
4904 cfg->scan_results = NULL;
4905 kfree(cfg->bss_info);
4906 cfg->bss_info = NULL;
4909 kfree(cfg->profile);
4910 cfg->profile = NULL;
4911 kfree(cfg->scan_req_int);
4912 cfg->scan_req_int = NULL;
4913 kfree(cfg->escan_ioctl_buf);
4914 cfg->escan_ioctl_buf = NULL;
4915 kfree(cfg->dcmd_buf);
4916 cfg->dcmd_buf = NULL;
4917 kfree(cfg->extra_buf);
4918 cfg->extra_buf = NULL;
4921 kfree(cfg->pmk_list);
4922 cfg->pmk_list = NULL;
4924 kfree(cfg->ap_info->wpa_ie);
4925 kfree(cfg->ap_info->rsn_ie);
4926 kfree(cfg->ap_info);
4927 cfg->ap_info = NULL;
4931 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4933 cfg->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
4934 if (!cfg->scan_results)
4935 goto init_priv_mem_out;
4936 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4938 goto init_priv_mem_out;
4939 cfg->profile = kzalloc(sizeof(*cfg->profile), GFP_KERNEL);
4941 goto init_priv_mem_out;
4942 cfg->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4944 goto init_priv_mem_out;
4945 cfg->scan_req_int = kzalloc(sizeof(*cfg->scan_req_int),
4947 if (!cfg->scan_req_int)
4948 goto init_priv_mem_out;
4949 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4950 if (!cfg->escan_ioctl_buf)
4951 goto init_priv_mem_out;
4952 cfg->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
4954 goto init_priv_mem_out;
4955 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4956 if (!cfg->extra_buf)
4957 goto init_priv_mem_out;
4958 cfg->iscan = kzalloc(sizeof(*cfg->iscan), GFP_KERNEL);
4960 goto init_priv_mem_out;
4961 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4963 goto init_priv_mem_out;
4968 brcmf_deinit_priv_mem(cfg);
4974 * retrieve first queued event from head
4977 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
4978 struct brcmf_cfg80211_info *cfg)
4980 struct brcmf_cfg80211_event_q *e = NULL;
4982 spin_lock_irq(&cfg->evt_q_lock);
4983 if (!list_empty(&cfg->evt_q_list)) {
4984 e = list_first_entry(&cfg->evt_q_list,
4985 struct brcmf_cfg80211_event_q, evt_q_list);
4986 list_del(&e->evt_q_list);
4988 spin_unlock_irq(&cfg->evt_q_lock);
4994 * push event to tail of the queue
4996 * remark: this function may not sleep as it is called in atomic context.
5000 brcmf_enq_event(struct brcmf_cfg80211_info *cfg, u32 event,
5001 const struct brcmf_event_msg *msg, void *data)
5003 struct brcmf_cfg80211_event_q *e;
5009 total_len = sizeof(struct brcmf_cfg80211_event_q);
5011 data_len = be32_to_cpu(msg->datalen);
5014 total_len += data_len;
5015 e = kzalloc(total_len, GFP_ATOMIC);
5020 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
5022 memcpy(&e->edata, data, data_len);
5024 spin_lock_irqsave(&cfg->evt_q_lock, flags);
5025 list_add_tail(&e->evt_q_list, &cfg->evt_q_list);
5026 spin_unlock_irqrestore(&cfg->evt_q_lock, flags);
5031 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
5036 static void brcmf_cfg80211_event_handler(struct work_struct *work)
5038 struct brcmf_cfg80211_info *cfg =
5039 container_of(work, struct brcmf_cfg80211_info,
5041 struct brcmf_cfg80211_event_q *e;
5043 e = brcmf_deq_event(cfg);
5045 WL_ERR("event queue empty...\n");
5050 WL_INFO("event type (%d)\n", e->etype);
5051 if (cfg->el.handler[e->etype])
5052 cfg->el.handler[e->etype](cfg,
5054 &e->emsg, e->edata);
5056 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
5058 } while ((e = brcmf_deq_event(cfg)));
5062 static void brcmf_init_eq(struct brcmf_cfg80211_info *cfg)
5064 spin_lock_init(&cfg->evt_q_lock);
5065 INIT_LIST_HEAD(&cfg->evt_q_list);
5068 static void brcmf_flush_eq(struct brcmf_cfg80211_info *cfg)
5070 struct brcmf_cfg80211_event_q *e;
5072 spin_lock_irq(&cfg->evt_q_lock);
5073 while (!list_empty(&cfg->evt_q_list)) {
5074 e = list_first_entry(&cfg->evt_q_list,
5075 struct brcmf_cfg80211_event_q, evt_q_list);
5076 list_del(&e->evt_q_list);
5079 spin_unlock_irq(&cfg->evt_q_lock);
5082 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5086 cfg->scan_request = NULL;
5087 cfg->pwr_save = true;
5088 #ifdef CONFIG_BRCMISCAN
5089 cfg->iscan_on = true; /* iscan on & off switch.
5090 we enable iscan per default */
5091 cfg->escan_on = false; /* escan on & off switch.
5092 we disable escan per default */
5094 cfg->iscan_on = false; /* iscan on & off switch.
5095 we disable iscan per default */
5096 cfg->escan_on = true; /* escan on & off switch.
5097 we enable escan per default */
5099 cfg->roam_on = true; /* roam on & off switch.
5100 we enable roam per default */
5102 cfg->iscan_kickstart = false;
5103 cfg->active_scan = true; /* we do active scan for
5104 specific scan per default */
5105 cfg->dongle_up = false; /* dongle is not up yet */
5107 err = brcmf_init_priv_mem(cfg);
5110 INIT_WORK(&cfg->event_work, brcmf_cfg80211_event_handler);
5111 brcmf_init_eloop_handler(&cfg->el);
5112 mutex_init(&cfg->usr_sync);
5113 err = brcmf_init_iscan(cfg);
5116 brcmf_init_escan(cfg);
5117 brcmf_init_conf(cfg->conf);
5118 brcmf_init_prof(cfg->profile);
5119 brcmf_link_down(cfg);
5124 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5126 cancel_work_sync(&cfg->event_work);
5127 cfg->dongle_up = false; /* dongle down */
5128 brcmf_flush_eq(cfg);
5129 brcmf_link_down(cfg);
5130 brcmf_abort_scanning(cfg);
5131 brcmf_deinit_priv_mem(cfg);
5134 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct net_device *ndev,
5135 struct device *busdev,
5136 struct brcmf_pub *drvr)
5138 struct wireless_dev *wdev;
5139 struct brcmf_cfg80211_info *cfg;
5143 WL_ERR("ndev is invalid\n");
5147 wdev = brcmf_alloc_wdev(busdev);
5152 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
5153 cfg = wdev_to_cfg(wdev);
5156 ndev->ieee80211_ptr = wdev;
5157 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
5158 wdev->netdev = ndev;
5159 err = wl_init_priv(cfg);
5161 WL_ERR("Failed to init iwm_priv (%d)\n", err);
5162 goto cfg80211_attach_out;
5167 cfg80211_attach_out:
5168 brcmf_free_wdev(cfg);
5172 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
5174 wl_deinit_priv(cfg);
5175 brcmf_free_wdev(cfg);
5179 brcmf_cfg80211_event(struct net_device *ndev,
5180 const struct brcmf_event_msg *e, void *data)
5182 u32 event_type = be32_to_cpu(e->event_type);
5183 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
5185 if (!brcmf_enq_event(cfg, event_type, e, data))
5186 schedule_work(&cfg->event_work);
5189 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
5195 case NL80211_IFTYPE_MONITOR:
5196 case NL80211_IFTYPE_WDS:
5197 WL_ERR("type (%d) : currently we do not support this mode\n",
5201 case NL80211_IFTYPE_ADHOC:
5204 case NL80211_IFTYPE_STATION:
5207 case NL80211_IFTYPE_AP:
5212 WL_ERR("invalid type (%d)\n", iftype);
5215 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
5217 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
5224 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
5226 /* Room for "event_msgs" + '\0' + bitvec */
5227 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
5228 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
5231 WL_TRACE("Enter\n");
5233 /* Setup event_msgs */
5234 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
5235 iovbuf, sizeof(iovbuf));
5236 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
5238 WL_ERR("Get event_msgs error (%d)\n", err);
5239 goto dongle_eventmsg_out;
5241 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
5243 setbit(eventmask, BRCMF_E_SET_SSID);
5244 setbit(eventmask, BRCMF_E_ROAM);
5245 setbit(eventmask, BRCMF_E_PRUNE);
5246 setbit(eventmask, BRCMF_E_AUTH);
5247 setbit(eventmask, BRCMF_E_REASSOC);
5248 setbit(eventmask, BRCMF_E_REASSOC_IND);
5249 setbit(eventmask, BRCMF_E_DEAUTH_IND);
5250 setbit(eventmask, BRCMF_E_DISASSOC_IND);
5251 setbit(eventmask, BRCMF_E_DISASSOC);
5252 setbit(eventmask, BRCMF_E_JOIN);
5253 setbit(eventmask, BRCMF_E_ASSOC_IND);
5254 setbit(eventmask, BRCMF_E_PSK_SUP);
5255 setbit(eventmask, BRCMF_E_LINK);
5256 setbit(eventmask, BRCMF_E_NDIS_LINK);
5257 setbit(eventmask, BRCMF_E_MIC_ERROR);
5258 setbit(eventmask, BRCMF_E_PMKID_CACHE);
5259 setbit(eventmask, BRCMF_E_TXFAIL);
5260 setbit(eventmask, BRCMF_E_JOIN_START);
5261 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
5262 setbit(eventmask, BRCMF_E_ESCAN_RESULT);
5263 setbit(eventmask, BRCMF_E_PFN_NET_FOUND);
5265 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
5266 iovbuf, sizeof(iovbuf));
5267 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
5269 WL_ERR("Set event_msgs error (%d)\n", err);
5270 goto dongle_eventmsg_out;
5273 dongle_eventmsg_out:
5279 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
5283 __le32 roamtrigger[2];
5284 __le32 roam_delta[2];
5289 * Setup timeout if Beacons are lost and roam is
5290 * off to report link down
5293 bcn_to_le = cpu_to_le32(bcn_timeout);
5294 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
5295 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
5296 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
5297 iovbuf, sizeof(iovbuf));
5299 WL_ERR("bcn_timeout error (%d)\n", err);
5300 goto dongle_rom_out;
5305 * Enable/Disable built-in roaming to allow supplicant
5306 * to take care of roaming
5308 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
5309 roamvar_le = cpu_to_le32(roamvar);
5310 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
5311 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
5312 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
5314 WL_ERR("roam_off error (%d)\n", err);
5315 goto dongle_rom_out;
5318 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5319 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5320 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
5321 (void *)roamtrigger, sizeof(roamtrigger));
5323 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5324 goto dongle_rom_out;
5327 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5328 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5329 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
5330 (void *)roam_delta, sizeof(roam_delta));
5332 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
5333 goto dongle_rom_out;
5341 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
5342 s32 scan_unassoc_time, s32 scan_passive_time)
5345 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
5346 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
5347 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
5349 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5350 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
5352 if (err == -EOPNOTSUPP)
5353 WL_INFO("Scan assoc time is not supported\n");
5355 WL_ERR("Scan assoc time error (%d)\n", err);
5356 goto dongle_scantime_out;
5358 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5359 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
5361 if (err == -EOPNOTSUPP)
5362 WL_INFO("Scan unassoc time is not supported\n");
5364 WL_ERR("Scan unassoc time error (%d)\n", err);
5365 goto dongle_scantime_out;
5368 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5369 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
5371 if (err == -EOPNOTSUPP)
5372 WL_INFO("Scan passive time is not supported\n");
5374 WL_ERR("Scan passive time error (%d)\n", err);
5375 goto dongle_scantime_out;
5378 dongle_scantime_out:
5382 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5384 struct wiphy *wiphy;
5389 err = brcmf_exec_dcmd(cfg_to_ndev(cfg), BRCM_GET_PHYLIST,
5390 &phy_list, sizeof(phy_list));
5392 WL_ERR("error (%d)\n", err);
5396 phy = ((char *)&phy_list)[0];
5397 WL_INFO("%c phy\n", phy);
5398 if (phy == 'n' || phy == 'a') {
5399 wiphy = cfg_to_wiphy(cfg);
5400 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
5406 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5408 return wl_update_wiphybands(cfg);
5411 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5413 struct net_device *ndev;
5414 struct wireless_dev *wdev;
5421 ndev = cfg_to_ndev(cfg);
5422 wdev = ndev->ieee80211_ptr;
5424 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
5425 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5427 err = brcmf_dongle_eventmsg(ndev);
5429 goto default_conf_out;
5431 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5432 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
5434 goto default_conf_out;
5435 WL_INFO("power save set to %s\n",
5436 (power_mode ? "enabled" : "disabled"));
5438 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
5441 goto default_conf_out;
5442 err = brcmf_dongle_mode(ndev, wdev->iftype);
5443 if (err && err != -EINPROGRESS)
5444 goto default_conf_out;
5445 err = brcmf_dongle_probecap(cfg);
5447 goto default_conf_out;
5449 /* -EINPROGRESS: Call commit handler */
5453 cfg->dongle_up = true;
5459 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info *cfg)
5461 char buf[10+IFNAMSIZ];
5465 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg)->name);
5466 cfg->debugfsdir = debugfs_create_dir(buf,
5467 cfg_to_wiphy(cfg)->debugfsdir);
5469 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg->debugfsdir,
5470 (u16 *)&cfg->profile->beacon_interval);
5476 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg->debugfsdir,
5477 (u8 *)&cfg->profile->dtim_period);
5487 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info *cfg)
5489 debugfs_remove_recursive(cfg->debugfsdir);
5490 cfg->debugfsdir = NULL;
5493 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
5497 set_bit(WL_STATUS_READY, &cfg->status);
5499 brcmf_debugfs_add_netdev_params(cfg);
5501 err = brcmf_config_dongle(cfg);
5505 brcmf_invoke_iscan(cfg);
5510 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
5513 * While going down, if associated with AP disassociate
5514 * from AP to save power
5516 if ((test_bit(WL_STATUS_CONNECTED, &cfg->status) ||
5517 test_bit(WL_STATUS_CONNECTING, &cfg->status)) &&
5518 test_bit(WL_STATUS_READY, &cfg->status)) {
5519 WL_INFO("Disassociating from AP");
5520 brcmf_link_down(cfg);
5522 /* Make sure WPA_Supplicant receives all the event
5523 generated due to DISASSOC call to the fw to keep
5524 the state fw and WPA_Supplicant state consistent
5529 brcmf_abort_scanning(cfg);
5530 clear_bit(WL_STATUS_READY, &cfg->status);
5532 brcmf_debugfs_remove_netdev(cfg);
5537 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_info *cfg)
5541 mutex_lock(&cfg->usr_sync);
5542 err = __brcmf_cfg80211_up(cfg);
5543 mutex_unlock(&cfg->usr_sync);
5548 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_info *cfg)
5552 mutex_lock(&cfg->usr_sync);
5553 err = __brcmf_cfg80211_down(cfg);
5554 mutex_unlock(&cfg->usr_sync);