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>
32 #include <brcmu_utils.h>
34 #include <brcmu_wifi.h>
36 #include "wl_cfg80211.h"
38 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
39 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
41 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
43 static u32 brcmf_dbg_level = WL_DBG_ERR;
45 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
47 dev->driver_data = data;
50 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
55 data = dev->driver_data;
60 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
62 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
66 static bool check_sys_up(struct wiphy *wiphy)
68 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
69 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
70 WL_INFO("device is not ready : status (%d)\n",
71 (int)cfg_priv->status);
77 #define CHAN2G(_channel, _freq, _flags) { \
78 .band = IEEE80211_BAND_2GHZ, \
79 .center_freq = (_freq), \
80 .hw_value = (_channel), \
82 .max_antenna_gain = 0, \
86 #define CHAN5G(_channel, _flags) { \
87 .band = IEEE80211_BAND_5GHZ, \
88 .center_freq = 5000 + (5 * (_channel)), \
89 .hw_value = (_channel), \
91 .max_antenna_gain = 0, \
95 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
96 #define RATETAB_ENT(_rateid, _flags) \
98 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
99 .hw_value = (_rateid), \
103 static struct ieee80211_rate __wl_rates[] = {
104 RATETAB_ENT(BRCM_RATE_1M, 0),
105 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
106 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
107 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
108 RATETAB_ENT(BRCM_RATE_6M, 0),
109 RATETAB_ENT(BRCM_RATE_9M, 0),
110 RATETAB_ENT(BRCM_RATE_12M, 0),
111 RATETAB_ENT(BRCM_RATE_18M, 0),
112 RATETAB_ENT(BRCM_RATE_24M, 0),
113 RATETAB_ENT(BRCM_RATE_36M, 0),
114 RATETAB_ENT(BRCM_RATE_48M, 0),
115 RATETAB_ENT(BRCM_RATE_54M, 0),
118 #define wl_a_rates (__wl_rates + 4)
119 #define wl_a_rates_size 8
120 #define wl_g_rates (__wl_rates + 0)
121 #define wl_g_rates_size 12
123 static struct ieee80211_channel __wl_2ghz_channels[] = {
140 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
141 CHAN5G(34, 0), CHAN5G(36, 0),
142 CHAN5G(38, 0), CHAN5G(40, 0),
143 CHAN5G(42, 0), CHAN5G(44, 0),
144 CHAN5G(46, 0), CHAN5G(48, 0),
145 CHAN5G(52, 0), CHAN5G(56, 0),
146 CHAN5G(60, 0), CHAN5G(64, 0),
147 CHAN5G(100, 0), CHAN5G(104, 0),
148 CHAN5G(108, 0), CHAN5G(112, 0),
149 CHAN5G(116, 0), CHAN5G(120, 0),
150 CHAN5G(124, 0), CHAN5G(128, 0),
151 CHAN5G(132, 0), CHAN5G(136, 0),
152 CHAN5G(140, 0), CHAN5G(149, 0),
153 CHAN5G(153, 0), CHAN5G(157, 0),
154 CHAN5G(161, 0), CHAN5G(165, 0),
155 CHAN5G(184, 0), CHAN5G(188, 0),
156 CHAN5G(192, 0), CHAN5G(196, 0),
157 CHAN5G(200, 0), CHAN5G(204, 0),
158 CHAN5G(208, 0), CHAN5G(212, 0),
162 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
163 CHAN5G(32, 0), CHAN5G(34, 0),
164 CHAN5G(36, 0), CHAN5G(38, 0),
165 CHAN5G(40, 0), CHAN5G(42, 0),
166 CHAN5G(44, 0), CHAN5G(46, 0),
167 CHAN5G(48, 0), CHAN5G(50, 0),
168 CHAN5G(52, 0), CHAN5G(54, 0),
169 CHAN5G(56, 0), CHAN5G(58, 0),
170 CHAN5G(60, 0), CHAN5G(62, 0),
171 CHAN5G(64, 0), CHAN5G(66, 0),
172 CHAN5G(68, 0), CHAN5G(70, 0),
173 CHAN5G(72, 0), CHAN5G(74, 0),
174 CHAN5G(76, 0), CHAN5G(78, 0),
175 CHAN5G(80, 0), CHAN5G(82, 0),
176 CHAN5G(84, 0), CHAN5G(86, 0),
177 CHAN5G(88, 0), CHAN5G(90, 0),
178 CHAN5G(92, 0), CHAN5G(94, 0),
179 CHAN5G(96, 0), CHAN5G(98, 0),
180 CHAN5G(100, 0), CHAN5G(102, 0),
181 CHAN5G(104, 0), CHAN5G(106, 0),
182 CHAN5G(108, 0), CHAN5G(110, 0),
183 CHAN5G(112, 0), CHAN5G(114, 0),
184 CHAN5G(116, 0), CHAN5G(118, 0),
185 CHAN5G(120, 0), CHAN5G(122, 0),
186 CHAN5G(124, 0), CHAN5G(126, 0),
187 CHAN5G(128, 0), CHAN5G(130, 0),
188 CHAN5G(132, 0), CHAN5G(134, 0),
189 CHAN5G(136, 0), CHAN5G(138, 0),
190 CHAN5G(140, 0), CHAN5G(142, 0),
191 CHAN5G(144, 0), CHAN5G(145, 0),
192 CHAN5G(146, 0), CHAN5G(147, 0),
193 CHAN5G(148, 0), CHAN5G(149, 0),
194 CHAN5G(150, 0), CHAN5G(151, 0),
195 CHAN5G(152, 0), CHAN5G(153, 0),
196 CHAN5G(154, 0), CHAN5G(155, 0),
197 CHAN5G(156, 0), CHAN5G(157, 0),
198 CHAN5G(158, 0), CHAN5G(159, 0),
199 CHAN5G(160, 0), CHAN5G(161, 0),
200 CHAN5G(162, 0), CHAN5G(163, 0),
201 CHAN5G(164, 0), CHAN5G(165, 0),
202 CHAN5G(166, 0), CHAN5G(168, 0),
203 CHAN5G(170, 0), CHAN5G(172, 0),
204 CHAN5G(174, 0), CHAN5G(176, 0),
205 CHAN5G(178, 0), CHAN5G(180, 0),
206 CHAN5G(182, 0), CHAN5G(184, 0),
207 CHAN5G(186, 0), CHAN5G(188, 0),
208 CHAN5G(190, 0), CHAN5G(192, 0),
209 CHAN5G(194, 0), CHAN5G(196, 0),
210 CHAN5G(198, 0), CHAN5G(200, 0),
211 CHAN5G(202, 0), CHAN5G(204, 0),
212 CHAN5G(206, 0), CHAN5G(208, 0),
213 CHAN5G(210, 0), CHAN5G(212, 0),
214 CHAN5G(214, 0), CHAN5G(216, 0),
215 CHAN5G(218, 0), CHAN5G(220, 0),
216 CHAN5G(222, 0), CHAN5G(224, 0),
217 CHAN5G(226, 0), CHAN5G(228, 0),
220 static struct ieee80211_supported_band __wl_band_2ghz = {
221 .band = IEEE80211_BAND_2GHZ,
222 .channels = __wl_2ghz_channels,
223 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
224 .bitrates = wl_g_rates,
225 .n_bitrates = wl_g_rates_size,
228 static struct ieee80211_supported_band __wl_band_5ghz_a = {
229 .band = IEEE80211_BAND_5GHZ,
230 .channels = __wl_5ghz_a_channels,
231 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
232 .bitrates = wl_a_rates,
233 .n_bitrates = wl_a_rates_size,
236 static struct ieee80211_supported_band __wl_band_5ghz_n = {
237 .band = IEEE80211_BAND_5GHZ,
238 .channels = __wl_5ghz_n_channels,
239 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
240 .bitrates = wl_a_rates,
241 .n_bitrates = wl_a_rates_size,
244 static const u32 __wl_cipher_suites[] = {
245 WLAN_CIPHER_SUITE_WEP40,
246 WLAN_CIPHER_SUITE_WEP104,
247 WLAN_CIPHER_SUITE_TKIP,
248 WLAN_CIPHER_SUITE_CCMP,
249 WLAN_CIPHER_SUITE_AES_CMAC,
252 /* tag_ID/length/value_buffer tuple */
259 /* Quarter dBm units to mW
260 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
261 * Table is offset so the last entry is largest mW value that fits in
265 #define QDBM_OFFSET 153 /* Offset for first entry */
266 #define QDBM_TABLE_LEN 40 /* Table size */
268 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
269 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
271 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
273 /* Largest mW value that will round down to the last table entry,
274 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
275 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
276 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
278 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
280 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
281 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
282 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
283 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
284 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
285 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
286 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
289 static u16 brcmf_qdbm_to_mw(u8 qdbm)
292 int idx = qdbm - QDBM_OFFSET;
294 if (idx >= QDBM_TABLE_LEN)
295 /* clamp to max u16 mW value */
298 /* scale the qdBm index up to the range of the table 0-40
299 * where an offset of 40 qdBm equals a factor of 10 mW.
306 /* return the mW value scaled down to the correct factor of 10,
307 * adding in factor/2 to get proper rounding.
309 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
312 static u8 brcmf_mw_to_qdbm(u16 mw)
319 /* handle boundary case */
323 offset = QDBM_OFFSET;
325 /* move mw into the range of the table */
326 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
331 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
332 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
333 nqdBm_to_mW_map[qdbm]) / 2;
334 if (mw_uint < boundary)
343 /* function for reading/writing a single u32 from/to the dongle */
345 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
348 __le32 par_le = cpu_to_le32(*par);
350 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
351 *par = le32_to_cpu(par_le);
356 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
357 struct brcmf_wsec_key_le *key_le)
359 key_le->index = cpu_to_le32(key->index);
360 key_le->len = cpu_to_le32(key->len);
361 key_le->algo = cpu_to_le32(key->algo);
362 key_le->flags = cpu_to_le32(key->flags);
363 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
364 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
365 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
366 memcpy(key_le->data, key->data, sizeof(key->data));
367 memcpy(key_le->ea, key->ea, sizeof(key->ea));
370 static int send_key_to_dongle(struct net_device *ndev,
371 struct brcmf_wsec_key *key)
374 struct brcmf_wsec_key_le key_le;
376 convert_key_from_CPU(key, &key_le);
377 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
379 WL_ERR("WLC_SET_KEY error (%d)\n", err);
384 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
385 enum nl80211_iftype type, u32 *flags,
386 struct vif_params *params)
388 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
389 struct wireless_dev *wdev;
394 if (!check_sys_up(wiphy))
398 case NL80211_IFTYPE_MONITOR:
399 case NL80211_IFTYPE_WDS:
400 WL_ERR("type (%d) : currently we do not support this type\n",
403 case NL80211_IFTYPE_ADHOC:
404 cfg_priv->conf->mode = WL_MODE_IBSS;
407 case NL80211_IFTYPE_STATION:
408 cfg_priv->conf->mode = WL_MODE_BSS;
416 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
418 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
421 wdev = ndev->ieee80211_ptr;
425 WL_INFO("IF Type = %s\n",
426 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
434 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
436 s8 buf[BRCMF_DCMD_SMLEN];
441 val_le = cpu_to_le32(val);
442 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
446 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
448 WL_ERR("error (%d)\n", err);
454 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
457 s8 buf[BRCMF_DCMD_SMLEN];
465 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
468 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
470 WL_ERR("error (%d)\n", err);
472 *retval = le32_to_cpu(var.val);
477 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
480 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
482 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
483 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
485 WL_ERR("fail to set mpc\n");
488 WL_INFO("MPC : %d\n", mpc);
492 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
493 struct brcmf_ssid *ssid)
495 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
496 params_le->bss_type = DOT11_BSSTYPE_ANY;
497 params_le->scan_type = 0;
498 params_le->channel_num = 0;
499 params_le->nprobes = cpu_to_le32(-1);
500 params_le->active_time = cpu_to_le32(-1);
501 params_le->passive_time = cpu_to_le32(-1);
502 params_le->home_time = cpu_to_le32(-1);
503 if (ssid && ssid->SSID_len) {
504 params_le->ssid_le.SSID_len = cpu_to_le32(ssid->SSID_len);
505 memcpy(¶ms_le->ssid_le.SSID, ssid->SSID, ssid->SSID_len);
510 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
511 s32 paramlen, void *bufptr, s32 buflen)
515 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
518 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
522 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
523 s32 paramlen, void *bufptr, s32 buflen)
527 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
530 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
534 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
535 struct brcmf_ssid *ssid, u16 action)
537 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
538 offsetof(struct brcmf_iscan_params_le, params_le);
539 struct brcmf_iscan_params_le *params;
542 if (ssid && ssid->SSID_len)
543 params_size += sizeof(struct brcmf_ssid);
544 params = kzalloc(params_size, GFP_KERNEL);
547 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
549 wl_iscan_prep(¶ms->params_le, ssid);
551 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
552 params->action = cpu_to_le16(action);
553 params->scan_duration = cpu_to_le16(0);
555 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
556 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
559 WL_INFO("system busy : iscan canceled\n");
561 WL_ERR("error (%d)\n", err);
568 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
570 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
571 struct net_device *ndev = cfg_to_ndev(cfg_priv);
572 struct brcmf_ssid ssid;
576 /* Broadcast scan by default */
577 memset(&ssid, 0, sizeof(ssid));
579 iscan->state = WL_ISCAN_STATE_SCANING;
581 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
582 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
583 &passive_scan, sizeof(passive_scan));
585 WL_ERR("error (%d)\n", err);
588 brcmf_set_mpc(ndev, 0);
589 cfg_priv->iscan_kickstart = true;
590 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
592 brcmf_set_mpc(ndev, 1);
593 cfg_priv->iscan_kickstart = false;
596 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
602 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
603 struct cfg80211_scan_request *request,
604 struct cfg80211_ssid *this_ssid)
606 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
607 struct cfg80211_ssid *ssids;
608 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
615 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
616 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
619 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
620 WL_ERR("Scanning being aborted : status (%lu)\n",
624 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
625 WL_ERR("Connecting : status (%lu)\n",
634 ssids = request->ssids;
635 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
639 /* we don't do iscan in ibss */
643 cfg_priv->scan_request = request;
644 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
646 err = brcmf_do_iscan(cfg_priv);
652 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
653 ssids->ssid, ssids->ssid_len);
654 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
655 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
656 sr->ssid_le.SSID_len = cpu_to_le32(0);
658 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
659 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
662 WL_SCAN("Broadcast scan\n");
665 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
666 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
667 &passive_scan, sizeof(passive_scan));
669 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
672 brcmf_set_mpc(ndev, 0);
673 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
674 sizeof(sr->ssid_le));
677 WL_INFO("system busy : scan for \"%s\" "
678 "canceled\n", sr->ssid_le.SSID);
680 WL_ERR("WLC_SCAN error (%d)\n", err);
682 brcmf_set_mpc(ndev, 1);
690 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
691 cfg_priv->scan_request = NULL;
696 brcmf_cfg80211_scan(struct wiphy *wiphy,
697 struct cfg80211_scan_request *request)
699 struct net_device *ndev = request->wdev->netdev;
704 if (!check_sys_up(wiphy))
707 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
709 WL_ERR("scan error (%d)\n", err);
715 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
719 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
721 WL_ERR("Error (%d)\n", err);
726 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
730 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
732 WL_ERR("Error (%d)\n", err);
737 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
740 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
742 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
744 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
750 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
752 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
753 struct net_device *ndev = cfg_to_ndev(cfg_priv);
757 if (!check_sys_up(wiphy))
760 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
761 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
762 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
763 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
767 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
768 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
769 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
770 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
774 if (changed & WIPHY_PARAM_RETRY_LONG
775 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
776 cfg_priv->conf->retry_long = wiphy->retry_long;
777 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
781 if (changed & WIPHY_PARAM_RETRY_SHORT
782 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
783 cfg_priv->conf->retry_short = wiphy->retry_short;
784 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
794 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
798 return &cfg_priv->profile->sec;
800 return &cfg_priv->profile->bssid;
802 return &cfg_priv->profile->ssid;
804 WL_ERR("invalid item (%d)\n", item);
809 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
810 const struct brcmf_event_msg *e, void *data, s32 item)
813 struct brcmf_ssid *ssid;
817 ssid = (struct brcmf_ssid *) data;
818 memset(cfg_priv->profile->ssid.SSID, 0,
819 sizeof(cfg_priv->profile->ssid.SSID));
820 memcpy(cfg_priv->profile->ssid.SSID,
821 ssid->SSID, ssid->SSID_len);
822 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
826 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
828 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
831 memcpy(&cfg_priv->profile->sec, data,
832 sizeof(cfg_priv->profile->sec));
834 case WL_PROF_BEACONINT:
835 cfg_priv->profile->beacon_interval = *(u16 *)data;
837 case WL_PROF_DTIMPERIOD:
838 cfg_priv->profile->dtim_period = *(u8 *)data;
841 WL_ERR("unsupported item (%d)\n", item);
849 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
851 memset(prof, 0, sizeof(*prof));
854 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
855 size_t *join_params_size)
860 if (ch <= CH_MAX_2G_CHANNEL)
861 chanspec |= WL_CHANSPEC_BAND_2G;
863 chanspec |= WL_CHANSPEC_BAND_5G;
865 chanspec |= WL_CHANSPEC_BW_20;
866 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
868 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
871 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
872 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
873 join_params->params_le.chanspec_num = cpu_to_le32(1);
875 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
876 "channel %d, chanspec %#X\n",
877 chanspec, ch, chanspec);
881 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
883 struct net_device *ndev = NULL;
888 if (cfg_priv->link_up) {
889 ndev = cfg_to_ndev(cfg_priv);
890 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
891 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
893 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
894 cfg_priv->link_up = false;
900 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
901 struct cfg80211_ibss_params *params)
903 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
904 struct brcmf_join_params join_params;
905 size_t join_params_size = 0;
909 struct brcmf_ssid ssid;
912 if (!check_sys_up(wiphy))
916 WL_CONN("SSID: %s\n", params->ssid);
918 WL_CONN("SSID: NULL, Not supported\n");
922 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
925 WL_CONN("BSSID: %pM\n", params->bssid);
927 WL_CONN("No BSSID specified\n");
930 WL_CONN("channel: %d\n", params->channel->center_freq);
932 WL_CONN("no channel specified\n");
934 if (params->channel_fixed)
935 WL_CONN("fixed channel required\n");
937 WL_CONN("no fixed channel required\n");
939 if (params->ie && params->ie_len)
940 WL_CONN("ie len: %d\n", params->ie_len);
942 WL_CONN("no ie specified\n");
944 if (params->beacon_interval)
945 WL_CONN("beacon interval: %d\n", params->beacon_interval);
947 WL_CONN("no beacon interval specified\n");
949 if (params->basic_rates)
950 WL_CONN("basic rates: %08X\n", params->basic_rates);
952 WL_CONN("no basic rates specified\n");
955 WL_CONN("privacy required\n");
957 WL_CONN("no privacy required\n");
959 /* Configure Privacy for starter */
963 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
965 WL_ERR("wsec failed (%d)\n", err);
969 /* Configure Beacon Interval for starter */
970 if (params->beacon_interval)
971 bcnprd = params->beacon_interval;
975 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
977 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
981 /* Configure required join parameter */
982 memset(&join_params, 0, sizeof(struct brcmf_join_params));
985 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
986 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
987 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
988 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
989 join_params_size = sizeof(join_params.ssid_le);
990 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
994 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
995 join_params_size = sizeof(join_params.ssid_le) +
996 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
998 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1001 brcmf_update_prof(cfg_priv, NULL,
1002 &join_params.params_le.bssid, WL_PROF_BSSID);
1005 if (params->channel) {
1009 ieee80211_frequency_to_channel(
1010 params->channel->center_freq);
1011 if (params->channel_fixed) {
1012 /* adding chanspec */
1013 brcmf_ch_to_chanspec(cfg_priv->channel,
1014 &join_params, &join_params_size);
1017 /* set channel for starter */
1018 target_channel = cfg_priv->channel;
1019 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1022 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1026 cfg_priv->channel = 0;
1028 cfg_priv->ibss_starter = false;
1031 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1032 &join_params, join_params_size);
1034 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1040 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1046 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1048 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1051 WL_TRACE("Enter\n");
1052 if (!check_sys_up(wiphy))
1055 brcmf_link_down(cfg_priv);
1062 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1063 struct cfg80211_connect_params *sme)
1065 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1066 struct brcmf_cfg80211_security *sec;
1070 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1071 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1072 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1073 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1075 val = WPA_AUTH_DISABLED;
1076 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1077 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1079 WL_ERR("set wpa_auth failed (%d)\n", err);
1082 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1083 sec->wpa_versions = sme->crypto.wpa_versions;
1087 static s32 brcmf_set_auth_type(struct net_device *ndev,
1088 struct cfg80211_connect_params *sme)
1090 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1091 struct brcmf_cfg80211_security *sec;
1095 switch (sme->auth_type) {
1096 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1098 WL_CONN("open system\n");
1100 case NL80211_AUTHTYPE_SHARED_KEY:
1102 WL_CONN("shared key\n");
1104 case NL80211_AUTHTYPE_AUTOMATIC:
1106 WL_CONN("automatic\n");
1108 case NL80211_AUTHTYPE_NETWORK_EAP:
1109 WL_CONN("network eap\n");
1112 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1116 err = brcmf_dev_intvar_set(ndev, "auth", val);
1118 WL_ERR("set auth failed (%d)\n", err);
1121 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1122 sec->auth_type = sme->auth_type;
1127 brcmf_set_set_cipher(struct net_device *ndev,
1128 struct cfg80211_connect_params *sme)
1130 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1131 struct brcmf_cfg80211_security *sec;
1136 if (sme->crypto.n_ciphers_pairwise) {
1137 switch (sme->crypto.ciphers_pairwise[0]) {
1138 case WLAN_CIPHER_SUITE_WEP40:
1139 case WLAN_CIPHER_SUITE_WEP104:
1142 case WLAN_CIPHER_SUITE_TKIP:
1143 pval = TKIP_ENABLED;
1145 case WLAN_CIPHER_SUITE_CCMP:
1148 case WLAN_CIPHER_SUITE_AES_CMAC:
1152 WL_ERR("invalid cipher pairwise (%d)\n",
1153 sme->crypto.ciphers_pairwise[0]);
1157 if (sme->crypto.cipher_group) {
1158 switch (sme->crypto.cipher_group) {
1159 case WLAN_CIPHER_SUITE_WEP40:
1160 case WLAN_CIPHER_SUITE_WEP104:
1163 case WLAN_CIPHER_SUITE_TKIP:
1164 gval = TKIP_ENABLED;
1166 case WLAN_CIPHER_SUITE_CCMP:
1169 case WLAN_CIPHER_SUITE_AES_CMAC:
1173 WL_ERR("invalid cipher group (%d)\n",
1174 sme->crypto.cipher_group);
1179 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1180 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1182 WL_ERR("error (%d)\n", err);
1186 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1187 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1188 sec->cipher_group = sme->crypto.cipher_group;
1194 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1196 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1197 struct brcmf_cfg80211_security *sec;
1201 if (sme->crypto.n_akm_suites) {
1202 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1204 WL_ERR("could not get wpa_auth (%d)\n", err);
1207 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1208 switch (sme->crypto.akm_suites[0]) {
1209 case WLAN_AKM_SUITE_8021X:
1210 val = WPA_AUTH_UNSPECIFIED;
1212 case WLAN_AKM_SUITE_PSK:
1216 WL_ERR("invalid cipher group (%d)\n",
1217 sme->crypto.cipher_group);
1220 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1221 switch (sme->crypto.akm_suites[0]) {
1222 case WLAN_AKM_SUITE_8021X:
1223 val = WPA2_AUTH_UNSPECIFIED;
1225 case WLAN_AKM_SUITE_PSK:
1226 val = WPA2_AUTH_PSK;
1229 WL_ERR("invalid cipher group (%d)\n",
1230 sme->crypto.cipher_group);
1235 WL_CONN("setting wpa_auth to %d\n", val);
1236 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1238 WL_ERR("could not set wpa_auth (%d)\n", err);
1242 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1243 sec->wpa_auth = sme->crypto.akm_suites[0];
1249 brcmf_set_wep_sharedkey(struct net_device *ndev,
1250 struct cfg80211_connect_params *sme)
1252 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1253 struct brcmf_cfg80211_security *sec;
1254 struct brcmf_wsec_key key;
1258 WL_CONN("key len (%d)\n", sme->key_len);
1260 if (sme->key_len == 0)
1263 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1264 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1265 sec->wpa_versions, sec->cipher_pairwise);
1267 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1270 if (sec->cipher_pairwise &
1271 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1272 memset(&key, 0, sizeof(key));
1273 key.len = (u32) sme->key_len;
1274 key.index = (u32) sme->key_idx;
1275 if (key.len > sizeof(key.data)) {
1276 WL_ERR("Too long key length (%u)\n", key.len);
1279 memcpy(key.data, sme->key, key.len);
1280 key.flags = BRCMF_PRIMARY_KEY;
1281 switch (sec->cipher_pairwise) {
1282 case WLAN_CIPHER_SUITE_WEP40:
1283 key.algo = CRYPTO_ALGO_WEP1;
1285 case WLAN_CIPHER_SUITE_WEP104:
1286 key.algo = CRYPTO_ALGO_WEP128;
1289 WL_ERR("Invalid algorithm (%d)\n",
1290 sme->crypto.ciphers_pairwise[0]);
1293 /* Set the new key/index */
1294 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1295 key.len, key.index, key.algo);
1296 WL_CONN("key \"%s\"\n", key.data);
1297 err = send_key_to_dongle(ndev, &key);
1301 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1302 WL_CONN("set auth_type to shared key\n");
1303 val = 1; /* shared key */
1304 err = brcmf_dev_intvar_set(ndev, "auth", val);
1306 WL_ERR("set auth failed (%d)\n", err);
1315 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1316 struct cfg80211_connect_params *sme)
1318 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1319 struct ieee80211_channel *chan = sme->channel;
1320 struct brcmf_join_params join_params;
1321 size_t join_params_size;
1322 struct brcmf_ssid ssid;
1326 WL_TRACE("Enter\n");
1327 if (!check_sys_up(wiphy))
1331 WL_ERR("Invalid ssid\n");
1335 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1339 ieee80211_frequency_to_channel(chan->center_freq);
1340 WL_CONN("channel (%d), center_req (%d)\n",
1341 cfg_priv->channel, chan->center_freq);
1343 cfg_priv->channel = 0;
1345 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1347 err = brcmf_set_wpa_version(ndev, sme);
1349 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1353 err = brcmf_set_auth_type(ndev, sme);
1355 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1359 err = brcmf_set_set_cipher(ndev, sme);
1361 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1365 err = brcmf_set_key_mgmt(ndev, sme);
1367 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1371 err = brcmf_set_wep_sharedkey(ndev, sme);
1373 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1377 memset(&join_params, 0, sizeof(join_params));
1378 join_params_size = sizeof(join_params.ssid_le);
1380 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1381 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1382 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1383 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1384 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1386 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1388 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1389 WL_CONN("ssid \"%s\", len (%d)\n",
1390 ssid.SSID, ssid.SSID_len);
1392 brcmf_ch_to_chanspec(cfg_priv->channel,
1393 &join_params, &join_params_size);
1394 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1395 &join_params, join_params_size);
1397 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1401 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1407 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1410 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1411 struct brcmf_scb_val_le scbval;
1414 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1415 if (!check_sys_up(wiphy))
1418 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1420 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1421 scbval.val = cpu_to_le32(reason_code);
1422 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1423 sizeof(struct brcmf_scb_val_le));
1425 WL_ERR("error (%d)\n", err);
1427 cfg_priv->link_up = false;
1434 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1435 enum nl80211_tx_power_setting type, s32 mbm)
1438 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1439 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1443 s32 dbm = MBM_TO_DBM(mbm);
1445 WL_TRACE("Enter\n");
1446 if (!check_sys_up(wiphy))
1450 case NL80211_TX_POWER_AUTOMATIC:
1452 case NL80211_TX_POWER_LIMITED:
1453 case NL80211_TX_POWER_FIXED:
1455 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1461 /* Make sure radio is off or on as far as software is concerned */
1462 disable = WL_RADIO_SW_DISABLE << 16;
1463 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1465 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1470 txpwrmw = (u16) dbm;
1471 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1472 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1474 WL_ERR("qtxpower error (%d)\n", err);
1475 cfg_priv->conf->tx_power = dbm;
1482 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1484 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1485 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1490 WL_TRACE("Enter\n");
1491 if (!check_sys_up(wiphy))
1494 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1496 WL_ERR("error (%d)\n", err);
1500 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1501 *dbm = (s32) brcmf_qdbm_to_mw(result);
1509 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1510 u8 key_idx, bool unicast, bool multicast)
1516 WL_TRACE("Enter\n");
1517 WL_CONN("key index (%d)\n", key_idx);
1518 if (!check_sys_up(wiphy))
1521 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1523 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1527 if (wsec & WEP_ENABLED) {
1528 /* Just select a new current key */
1530 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1533 WL_ERR("error (%d)\n", err);
1541 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1542 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1544 struct brcmf_wsec_key key;
1545 struct brcmf_wsec_key_le key_le;
1548 memset(&key, 0, sizeof(key));
1549 key.index = (u32) key_idx;
1550 /* Instead of bcast for ea address for default wep keys,
1551 driver needs it to be Null */
1552 if (!is_multicast_ether_addr(mac_addr))
1553 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1554 key.len = (u32) params->key_len;
1555 /* check for key index change */
1558 err = send_key_to_dongle(ndev, &key);
1562 if (key.len > sizeof(key.data)) {
1563 WL_ERR("Invalid key length (%d)\n", key.len);
1567 WL_CONN("Setting the key index %d\n", key.index);
1568 memcpy(key.data, params->key, key.len);
1570 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1572 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1573 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1574 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1577 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1578 if (params->seq && params->seq_len == 6) {
1581 ivptr = (u8 *) params->seq;
1582 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1583 (ivptr[3] << 8) | ivptr[2];
1584 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1585 key.iv_initialized = true;
1588 switch (params->cipher) {
1589 case WLAN_CIPHER_SUITE_WEP40:
1590 key.algo = CRYPTO_ALGO_WEP1;
1591 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1593 case WLAN_CIPHER_SUITE_WEP104:
1594 key.algo = CRYPTO_ALGO_WEP128;
1595 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1597 case WLAN_CIPHER_SUITE_TKIP:
1598 key.algo = CRYPTO_ALGO_TKIP;
1599 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1601 case WLAN_CIPHER_SUITE_AES_CMAC:
1602 key.algo = CRYPTO_ALGO_AES_CCM;
1603 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1605 case WLAN_CIPHER_SUITE_CCMP:
1606 key.algo = CRYPTO_ALGO_AES_CCM;
1607 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1610 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1613 convert_key_from_CPU(&key, &key_le);
1615 brcmf_netdev_wait_pend8021x(ndev);
1616 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1619 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1627 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1628 u8 key_idx, bool pairwise, const u8 *mac_addr,
1629 struct key_params *params)
1631 struct brcmf_wsec_key key;
1637 WL_TRACE("Enter\n");
1638 WL_CONN("key index (%d)\n", key_idx);
1639 if (!check_sys_up(wiphy))
1644 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1646 memset(&key, 0, sizeof(key));
1648 key.len = (u32) params->key_len;
1649 key.index = (u32) key_idx;
1651 if (key.len > sizeof(key.data)) {
1652 WL_ERR("Too long key length (%u)\n", key.len);
1656 memcpy(key.data, params->key, key.len);
1658 key.flags = BRCMF_PRIMARY_KEY;
1659 switch (params->cipher) {
1660 case WLAN_CIPHER_SUITE_WEP40:
1661 key.algo = CRYPTO_ALGO_WEP1;
1662 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1664 case WLAN_CIPHER_SUITE_WEP104:
1665 key.algo = CRYPTO_ALGO_WEP128;
1666 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1668 case WLAN_CIPHER_SUITE_TKIP:
1669 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1670 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1671 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1672 key.algo = CRYPTO_ALGO_TKIP;
1673 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1675 case WLAN_CIPHER_SUITE_AES_CMAC:
1676 key.algo = CRYPTO_ALGO_AES_CCM;
1677 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1679 case WLAN_CIPHER_SUITE_CCMP:
1680 key.algo = CRYPTO_ALGO_AES_CCM;
1681 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1684 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1689 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1694 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1696 WL_ERR("get wsec error (%d)\n", err);
1699 wsec &= ~(WEP_ENABLED);
1701 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1703 WL_ERR("set wsec error (%d)\n", err);
1707 val = 1; /* assume shared key. otherwise 0 */
1708 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1710 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1717 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1718 u8 key_idx, bool pairwise, const u8 *mac_addr)
1720 struct brcmf_wsec_key key;
1725 WL_TRACE("Enter\n");
1726 if (!check_sys_up(wiphy))
1729 memset(&key, 0, sizeof(key));
1731 key.index = (u32) key_idx;
1732 key.flags = BRCMF_PRIMARY_KEY;
1733 key.algo = CRYPTO_ALGO_OFF;
1735 WL_CONN("key index (%d)\n", key_idx);
1737 /* Set the new key/index */
1738 err = send_key_to_dongle(ndev, &key);
1740 if (err == -EINVAL) {
1741 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1742 /* we ignore this key index in this case */
1743 WL_ERR("invalid key index (%d)\n", key_idx);
1745 /* Ignore this error, may happen during DISASSOC */
1751 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1753 WL_ERR("get wsec error (%d)\n", err);
1754 /* Ignore this error, may happen during DISASSOC */
1758 wsec &= ~(WEP_ENABLED);
1760 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1762 WL_ERR("set wsec error (%d)\n", err);
1763 /* Ignore this error, may happen during DISASSOC */
1768 val = 0; /* assume open key. otherwise 1 */
1769 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1771 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1772 /* Ignore this error, may happen during DISASSOC */
1781 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1782 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1783 void (*callback) (void *cookie, struct key_params * params))
1785 struct key_params params;
1786 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1787 struct brcmf_cfg80211_security *sec;
1791 WL_TRACE("Enter\n");
1792 WL_CONN("key index (%d)\n", key_idx);
1793 if (!check_sys_up(wiphy))
1796 memset(¶ms, 0, sizeof(params));
1798 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1800 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1801 /* Ignore this error, may happen during DISASSOC */
1807 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1808 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1809 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1810 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1811 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1812 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1813 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1817 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1818 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1821 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1822 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1825 WL_ERR("Invalid algo (0x%x)\n", wsec);
1829 callback(cookie, ¶ms);
1837 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1838 struct net_device *ndev, u8 key_idx)
1840 WL_INFO("Not supported\n");
1846 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1847 u8 *mac, struct station_info *sinfo)
1849 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1850 struct brcmf_scb_val_le scb_val;
1854 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1856 WL_TRACE("Enter\n");
1857 if (!check_sys_up(wiphy))
1860 if (memcmp(mac, bssid, ETH_ALEN)) {
1861 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1862 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1863 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1864 bssid[0], bssid[1], bssid[2], bssid[3],
1865 bssid[4], bssid[5]);
1870 /* Report the current tx rate */
1871 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1873 WL_ERR("Could not get rate (%d)\n", err);
1875 sinfo->filled |= STATION_INFO_TX_BITRATE;
1876 sinfo->txrate.legacy = rate * 5;
1877 WL_CONN("Rate %d Mbps\n", rate / 2);
1880 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1881 memset(&scb_val, 0, sizeof(scb_val));
1882 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1883 sizeof(struct brcmf_scb_val_le));
1885 WL_ERR("Could not get rssi (%d)\n", err);
1887 rssi = le32_to_cpu(scb_val.val);
1888 sinfo->filled |= STATION_INFO_SIGNAL;
1889 sinfo->signal = rssi;
1890 WL_CONN("RSSI %d dBm\n", rssi);
1900 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1901 bool enabled, s32 timeout)
1905 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1907 WL_TRACE("Enter\n");
1910 * Powersave enable/disable request is coming from the
1911 * cfg80211 even before the interface is up. In that
1912 * scenario, driver will be storing the power save
1913 * preference in cfg_priv struct to apply this to
1914 * FW later while initializing the dongle
1916 cfg_priv->pwr_save = enabled;
1917 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1919 WL_INFO("Device is not ready,"
1920 "storing the value in cfg_priv struct\n");
1924 pm = enabled ? PM_FAST : PM_OFF;
1925 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1927 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1930 WL_ERR("net_device is not ready yet\n");
1932 WL_ERR("error (%d)\n", err);
1940 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1942 const struct cfg80211_bitrate_mask *mask)
1944 struct brcm_rateset_le rateset_le;
1952 WL_TRACE("Enter\n");
1953 if (!check_sys_up(wiphy))
1956 /* addr param is always NULL. ignore it */
1957 /* Get current rateset */
1958 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1959 sizeof(rateset_le));
1961 WL_ERR("could not get current rateset (%d)\n", err);
1965 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1967 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1970 val = wl_g_rates[legacy - 1].bitrate * 100000;
1972 if (val < le32_to_cpu(rateset_le.count))
1973 /* Select rate by rateset index */
1974 rate = rateset_le.rates[val] & 0x7f;
1976 /* Specified rate in bps */
1977 rate = val / 500000;
1979 WL_CONN("rate %d mbps\n", rate / 2);
1983 * Set rate override,
1984 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1986 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1987 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1988 if (err_bg && err_a) {
1989 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1990 err = err_bg | err_a;
1998 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1999 struct brcmf_bss_info_le *bi)
2001 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2002 struct ieee80211_channel *notify_channel;
2003 struct cfg80211_bss *bss;
2004 struct ieee80211_supported_band *band;
2008 u16 notify_capability;
2009 u16 notify_interval;
2011 size_t notify_ielen;
2014 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2015 WL_ERR("Bss info is larger than buffer. Discarding\n");
2019 channel = bi->ctl_ch ? bi->ctl_ch :
2020 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2022 if (channel <= CH_MAX_2G_CHANNEL)
2023 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2025 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2027 freq = ieee80211_channel_to_frequency(channel, band->band);
2028 notify_channel = ieee80211_get_channel(wiphy, freq);
2030 notify_capability = le16_to_cpu(bi->capability);
2031 notify_interval = le16_to_cpu(bi->beacon_period);
2032 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2033 notify_ielen = le32_to_cpu(bi->ie_length);
2034 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2036 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2037 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2038 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2039 WL_CONN("Channel: %d(%d)\n", channel, freq);
2040 WL_CONN("Capability: %X\n", notify_capability);
2041 WL_CONN("Beacon interval: %d\n", notify_interval);
2042 WL_CONN("Signal: %d\n", notify_signal);
2044 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2045 0, notify_capability, notify_interval, notify_ie,
2046 notify_ielen, notify_signal, GFP_KERNEL);
2051 cfg80211_put_bss(bss);
2056 static struct brcmf_bss_info_le *
2057 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2060 return list->bss_info_le;
2061 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2062 le32_to_cpu(bss->length));
2065 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2067 struct brcmf_scan_results *bss_list;
2068 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2072 bss_list = cfg_priv->bss_list;
2073 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2074 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2078 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2079 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2080 bi = next_bss_le(bss_list, bi);
2081 err = brcmf_inform_single_bss(cfg_priv, bi);
2088 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2089 struct net_device *ndev, const u8 *bssid)
2091 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2092 struct ieee80211_channel *notify_channel;
2093 struct brcmf_bss_info_le *bi = NULL;
2094 struct ieee80211_supported_band *band;
2095 struct cfg80211_bss *bss;
2100 u16 notify_capability;
2101 u16 notify_interval;
2103 size_t notify_ielen;
2106 WL_TRACE("Enter\n");
2108 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2114 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2116 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2118 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2122 bi = (struct brcmf_bss_info_le *)(buf + 4);
2124 channel = bi->ctl_ch ? bi->ctl_ch :
2125 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2127 if (channel <= CH_MAX_2G_CHANNEL)
2128 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2130 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2132 freq = ieee80211_channel_to_frequency(channel, band->band);
2133 notify_channel = ieee80211_get_channel(wiphy, freq);
2135 notify_capability = le16_to_cpu(bi->capability);
2136 notify_interval = le16_to_cpu(bi->beacon_period);
2137 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2138 notify_ielen = le32_to_cpu(bi->ie_length);
2139 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2141 WL_CONN("channel: %d(%d)\n", channel, freq);
2142 WL_CONN("capability: %X\n", notify_capability);
2143 WL_CONN("beacon interval: %d\n", notify_interval);
2144 WL_CONN("signal: %d\n", notify_signal);
2146 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2147 0, notify_capability, notify_interval,
2148 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2155 cfg80211_put_bss(bss);
2166 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2168 return cfg_priv->conf->mode == WL_MODE_IBSS;
2172 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2173 * triples, returning a pointer to the substring whose first element
2176 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2178 struct brcmf_tlv *elt;
2181 elt = (struct brcmf_tlv *) buf;
2184 /* find tagged parameter */
2185 while (totlen >= 2) {
2188 /* validate remaining totlen */
2189 if ((elt->id == key) && (totlen >= (len + 2)))
2192 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2193 totlen -= (len + 2);
2199 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2201 struct brcmf_bss_info_le *bi;
2202 struct brcmf_ssid *ssid;
2203 struct brcmf_tlv *tim;
2204 u16 beacon_interval;
2210 WL_TRACE("Enter\n");
2211 if (brcmf_is_ibssmode(cfg_priv))
2214 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2216 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2217 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2218 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2220 WL_ERR("Could not get bss info %d\n", err);
2221 goto update_bss_info_out;
2224 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2225 err = brcmf_inform_single_bss(cfg_priv, bi);
2227 goto update_bss_info_out;
2229 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2230 ie_len = le32_to_cpu(bi->ie_length);
2231 beacon_interval = le16_to_cpu(bi->beacon_period);
2233 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2235 dtim_period = tim->data[1];
2238 * active scan was done so we could not get dtim
2239 * information out of probe response.
2240 * so we speficially query dtim information to dongle.
2243 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2244 "dtim_assoc", &var);
2246 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2247 goto update_bss_info_out;
2249 dtim_period = (u8)var;
2252 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2253 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2255 update_bss_info_out:
2260 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2262 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2263 struct brcmf_ssid ssid;
2265 if (cfg_priv->iscan_on) {
2266 iscan->state = WL_ISCAN_STATE_IDLE;
2268 if (iscan->timer_on) {
2269 del_timer_sync(&iscan->timer);
2270 iscan->timer_on = 0;
2273 cancel_work_sync(&iscan->work);
2275 /* Abort iscan running in FW */
2276 memset(&ssid, 0, sizeof(ssid));
2277 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2281 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2284 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2285 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2287 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2288 WL_ERR("Scan complete while device not scanning\n");
2291 if (cfg_priv->scan_request) {
2292 WL_SCAN("ISCAN Completed scan: %s\n",
2293 aborted ? "Aborted" : "Done");
2294 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2295 brcmf_set_mpc(ndev, 1);
2296 cfg_priv->scan_request = NULL;
2298 cfg_priv->iscan_kickstart = false;
2301 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2303 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2304 WL_SCAN("wake up iscan\n");
2305 schedule_work(&iscan->work);
2313 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2314 struct brcmf_scan_results **bss_list)
2316 struct brcmf_iscan_results list;
2317 struct brcmf_scan_results *results;
2318 struct brcmf_scan_results_le *results_le;
2319 struct brcmf_iscan_results *list_buf;
2322 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2323 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2324 results = &list_buf->results;
2325 results_le = &list_buf->results_le;
2326 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2327 results->version = 0;
2330 memset(&list, 0, sizeof(list));
2331 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2332 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2333 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2334 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2336 WL_ERR("error (%d)\n", err);
2339 results->buflen = le32_to_cpu(results_le->buflen);
2340 results->version = le32_to_cpu(results_le->version);
2341 results->count = le32_to_cpu(results_le->count);
2342 WL_SCAN("results->count = %d\n", results_le->count);
2343 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2344 *status = le32_to_cpu(list_buf->status_le);
2345 WL_SCAN("status = %d\n", *status);
2346 *bss_list = results;
2351 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2353 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2356 iscan->state = WL_ISCAN_STATE_IDLE;
2357 brcmf_inform_bss(cfg_priv);
2358 brcmf_notify_iscan_complete(iscan, false);
2363 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2365 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2368 /* Reschedule the timer */
2369 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2370 iscan->timer_on = 1;
2375 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2377 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2380 brcmf_inform_bss(cfg_priv);
2381 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2382 /* Reschedule the timer */
2383 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2384 iscan->timer_on = 1;
2389 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2391 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2394 iscan->state = WL_ISCAN_STATE_IDLE;
2395 brcmf_notify_iscan_complete(iscan, true);
2400 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2402 struct brcmf_cfg80211_iscan_ctrl *iscan =
2403 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2405 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2406 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2407 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2409 if (iscan->timer_on) {
2410 del_timer_sync(&iscan->timer);
2411 iscan->timer_on = 0;
2414 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2415 status = BRCMF_SCAN_RESULTS_ABORTED;
2416 WL_ERR("Abort iscan\n");
2419 el->handler[status](cfg_priv);
2422 static void brcmf_iscan_timer(unsigned long data)
2424 struct brcmf_cfg80211_iscan_ctrl *iscan =
2425 (struct brcmf_cfg80211_iscan_ctrl *)data;
2428 iscan->timer_on = 0;
2429 WL_SCAN("timer expired\n");
2430 brcmf_wakeup_iscan(iscan);
2434 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2436 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2438 if (cfg_priv->iscan_on) {
2439 iscan->state = WL_ISCAN_STATE_IDLE;
2440 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2446 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2448 memset(el, 0, sizeof(*el));
2449 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2450 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2451 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2452 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2453 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2456 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2458 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2461 if (cfg_priv->iscan_on) {
2462 iscan->ndev = cfg_to_ndev(cfg_priv);
2463 brcmf_init_iscan_eloop(&iscan->el);
2464 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2465 init_timer(&iscan->timer);
2466 iscan->timer.data = (unsigned long) iscan;
2467 iscan->timer.function = brcmf_iscan_timer;
2468 err = brcmf_invoke_iscan(cfg_priv);
2470 iscan->data = cfg_priv;
2476 static __always_inline void brcmf_delay(u32 ms)
2478 if (ms < 1000 / HZ) {
2486 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2488 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2491 * Check for WL_STATUS_READY before any function call which
2492 * could result is bus access. Don't block the resume for
2493 * any driver error conditions
2495 WL_TRACE("Enter\n");
2497 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2498 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2504 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2505 struct cfg80211_wowlan *wow)
2507 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2508 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2510 WL_TRACE("Enter\n");
2513 * Check for WL_STATUS_READY before any function call which
2514 * could result is bus access. Don't block the suspend for
2515 * any driver error conditions
2519 * While going to suspend if associated with AP disassociate
2520 * from AP to save power while system is in suspended state
2522 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2523 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2524 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2525 WL_INFO("Disassociating from AP"
2526 " while entering suspend state\n");
2527 brcmf_link_down(cfg_priv);
2530 * Make sure WPA_Supplicant receives all the event
2531 * generated due to DISASSOC call to the fw to keep
2532 * the state fw and WPA_Supplicant state consistent
2537 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2538 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2539 brcmf_term_iscan(cfg_priv);
2541 if (cfg_priv->scan_request) {
2542 /* Indidate scan abort to cfg80211 layer */
2543 WL_INFO("Terminating scan in progress\n");
2544 cfg80211_scan_done(cfg_priv->scan_request, true);
2545 cfg_priv->scan_request = NULL;
2547 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2548 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2550 /* Turn off watchdog timer */
2551 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2552 WL_INFO("Enable MPC\n");
2553 brcmf_set_mpc(ndev, 1);
2562 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2564 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2567 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2571 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2576 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2579 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2583 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2586 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2589 WL_ERR("error (%d)\n", err);
2592 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2598 brcmf_update_pmklist(struct net_device *ndev,
2599 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2604 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2606 WL_CONN("No of elements %d\n", pmkid_len);
2607 for (i = 0; i < pmkid_len; i++) {
2608 WL_CONN("PMKID[%d]: %pM =\n", i,
2609 &pmk_list->pmkids.pmkid[i].BSSID);
2610 for (j = 0; j < WLAN_PMKID_LEN; j++)
2611 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2615 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2622 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2623 struct cfg80211_pmksa *pmksa)
2625 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2626 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2631 WL_TRACE("Enter\n");
2632 if (!check_sys_up(wiphy))
2635 pmkid_len = le32_to_cpu(pmkids->npmkid);
2636 for (i = 0; i < pmkid_len; i++)
2637 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2639 if (i < WL_NUM_PMKIDS_MAX) {
2640 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2641 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2642 if (i == pmkid_len) {
2644 pmkids->npmkid = cpu_to_le32(pmkid_len);
2649 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2650 pmkids->pmkid[pmkid_len].BSSID);
2651 for (i = 0; i < WLAN_PMKID_LEN; i++)
2652 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2654 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2661 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2662 struct cfg80211_pmksa *pmksa)
2664 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2665 struct pmkid_list pmkid;
2669 WL_TRACE("Enter\n");
2670 if (!check_sys_up(wiphy))
2673 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2674 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2676 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2677 &pmkid.pmkid[0].BSSID);
2678 for (i = 0; i < WLAN_PMKID_LEN; i++)
2679 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2681 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2682 for (i = 0; i < pmkid_len; i++)
2684 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2689 && (i < pmkid_len)) {
2690 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2691 sizeof(struct pmkid));
2692 for (; i < (pmkid_len - 1); i++) {
2693 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2694 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2696 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2697 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2700 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2704 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2712 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2714 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2717 WL_TRACE("Enter\n");
2718 if (!check_sys_up(wiphy))
2721 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2722 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2729 static struct cfg80211_ops wl_cfg80211_ops = {
2730 .change_virtual_intf = brcmf_cfg80211_change_iface,
2731 .scan = brcmf_cfg80211_scan,
2732 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2733 .join_ibss = brcmf_cfg80211_join_ibss,
2734 .leave_ibss = brcmf_cfg80211_leave_ibss,
2735 .get_station = brcmf_cfg80211_get_station,
2736 .set_tx_power = brcmf_cfg80211_set_tx_power,
2737 .get_tx_power = brcmf_cfg80211_get_tx_power,
2738 .add_key = brcmf_cfg80211_add_key,
2739 .del_key = brcmf_cfg80211_del_key,
2740 .get_key = brcmf_cfg80211_get_key,
2741 .set_default_key = brcmf_cfg80211_config_default_key,
2742 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2743 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2744 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2745 .connect = brcmf_cfg80211_connect,
2746 .disconnect = brcmf_cfg80211_disconnect,
2747 .suspend = brcmf_cfg80211_suspend,
2748 .resume = brcmf_cfg80211_resume,
2749 .set_pmksa = brcmf_cfg80211_set_pmksa,
2750 .del_pmksa = brcmf_cfg80211_del_pmksa,
2751 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2754 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2760 return NL80211_IFTYPE_STATION;
2762 return NL80211_IFTYPE_ADHOC;
2764 return NL80211_IFTYPE_UNSPECIFIED;
2770 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2771 struct device *ndev)
2773 struct wireless_dev *wdev;
2776 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2778 return ERR_PTR(-ENOMEM);
2781 wiphy_new(&wl_cfg80211_ops,
2782 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2784 WL_ERR("Could not allocate wiphy device\n");
2788 set_wiphy_dev(wdev->wiphy, ndev);
2789 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2790 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2791 wdev->wiphy->interface_modes =
2792 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2793 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2794 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2795 * it as 11a by default.
2796 * This will be updated with
2799 * if phy has 11n capability
2801 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2802 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2803 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2804 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2808 err = wiphy_register(wdev->wiphy);
2810 WL_ERR("Could not register wiphy device (%d)\n", err);
2811 goto wiphy_register_out;
2816 wiphy_free(wdev->wiphy);
2821 return ERR_PTR(err);
2824 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2826 struct wireless_dev *wdev = cfg_priv->wdev;
2829 WL_ERR("wdev is invalid\n");
2832 wiphy_unregister(wdev->wiphy);
2833 wiphy_free(wdev->wiphy);
2835 cfg_priv->wdev = NULL;
2838 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2839 const struct brcmf_event_msg *e)
2841 u32 event = be32_to_cpu(e->event_type);
2842 u32 status = be32_to_cpu(e->status);
2844 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2845 WL_CONN("Processing set ssid\n");
2846 cfg_priv->link_up = true;
2853 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2854 const struct brcmf_event_msg *e)
2856 u32 event = be32_to_cpu(e->event_type);
2857 u16 flags = be16_to_cpu(e->flags);
2859 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2860 WL_CONN("Processing link down\n");
2866 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2867 const struct brcmf_event_msg *e)
2869 u32 event = be32_to_cpu(e->event_type);
2870 u32 status = be32_to_cpu(e->status);
2872 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2873 WL_CONN("Processing Link %s & no network found\n",
2874 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2879 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2880 WL_CONN("Processing connecting & no network found\n");
2887 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2889 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2891 kfree(conn_info->req_ie);
2892 conn_info->req_ie = NULL;
2893 conn_info->req_ie_len = 0;
2894 kfree(conn_info->resp_ie);
2895 conn_info->resp_ie = NULL;
2896 conn_info->resp_ie_len = 0;
2899 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2901 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2902 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2903 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2908 brcmf_clear_assoc_ies(cfg_priv);
2910 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2913 WL_ERR("could not get assoc info (%d)\n", err);
2917 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2918 req_len = le32_to_cpu(assoc_info->req_len);
2919 resp_len = le32_to_cpu(assoc_info->resp_len);
2921 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2922 cfg_priv->extra_buf,
2925 WL_ERR("could not get assoc req (%d)\n", err);
2928 conn_info->req_ie_len = req_len;
2930 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2933 conn_info->req_ie_len = 0;
2934 conn_info->req_ie = NULL;
2937 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2938 cfg_priv->extra_buf,
2941 WL_ERR("could not get assoc resp (%d)\n", err);
2944 conn_info->resp_ie_len = resp_len;
2945 conn_info->resp_ie =
2946 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2949 conn_info->resp_ie_len = 0;
2950 conn_info->resp_ie = NULL;
2952 WL_CONN("req len (%d) resp len (%d)\n",
2953 conn_info->req_ie_len, conn_info->resp_ie_len);
2959 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2960 struct net_device *ndev,
2961 const struct brcmf_event_msg *e)
2963 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2964 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2965 struct brcmf_channel_info_le channel_le;
2966 struct ieee80211_channel *notify_channel;
2967 struct ieee80211_supported_band *band;
2972 WL_TRACE("Enter\n");
2974 brcmf_get_assoc_ies(cfg_priv);
2975 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2976 brcmf_update_bss_info(cfg_priv);
2978 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2979 sizeof(channel_le));
2981 target_channel = le32_to_cpu(channel_le.target_channel);
2982 WL_CONN("Roamed to channel %d\n", target_channel);
2984 if (target_channel <= CH_MAX_2G_CHANNEL)
2985 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2987 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2989 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2990 notify_channel = ieee80211_get_channel(wiphy, freq);
2992 cfg80211_roamed(ndev, notify_channel,
2993 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2994 conn_info->req_ie, conn_info->req_ie_len,
2995 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2996 WL_CONN("Report roaming result\n");
2998 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3004 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3005 struct net_device *ndev, const struct brcmf_event_msg *e,
3008 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3011 WL_TRACE("Enter\n");
3013 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3015 brcmf_get_assoc_ies(cfg_priv);
3016 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3018 brcmf_update_bss_info(cfg_priv);
3020 cfg80211_connect_result(ndev,
3021 (u8 *)brcmf_read_prof(cfg_priv,
3024 conn_info->req_ie_len,
3026 conn_info->resp_ie_len,
3027 completed ? WLAN_STATUS_SUCCESS :
3028 WLAN_STATUS_AUTH_TIMEOUT,
3031 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3032 WL_CONN("Report connect result - connection %s\n",
3033 completed ? "succeeded" : "failed");
3040 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3041 struct net_device *ndev,
3042 const struct brcmf_event_msg *e, void *data)
3046 if (brcmf_is_linkup(cfg_priv, e)) {
3047 WL_CONN("Linkup\n");
3048 if (brcmf_is_ibssmode(cfg_priv)) {
3049 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3051 wl_inform_ibss(cfg_priv, ndev, e->addr);
3052 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3053 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3054 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3056 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3057 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3058 WL_CONN("Linkdown\n");
3059 if (brcmf_is_ibssmode(cfg_priv)) {
3060 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3061 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3063 brcmf_link_down(cfg_priv);
3065 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3066 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3067 &cfg_priv->status)) {
3068 cfg80211_disconnected(ndev, 0, NULL, 0,
3070 brcmf_link_down(cfg_priv);
3073 brcmf_init_prof(cfg_priv->profile);
3074 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3075 if (brcmf_is_ibssmode(cfg_priv))
3076 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3078 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3085 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3086 struct net_device *ndev,
3087 const struct brcmf_event_msg *e, void *data)
3090 u32 event = be32_to_cpu(e->event_type);
3091 u32 status = be32_to_cpu(e->status);
3093 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3094 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3095 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3097 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3104 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3105 struct net_device *ndev,
3106 const struct brcmf_event_msg *e, void *data)
3108 u16 flags = be16_to_cpu(e->flags);
3109 enum nl80211_key_type key_type;
3111 if (flags & BRCMF_EVENT_MSG_GROUP)
3112 key_type = NL80211_KEYTYPE_GROUP;
3114 key_type = NL80211_KEYTYPE_PAIRWISE;
3116 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3123 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3124 struct net_device *ndev,
3125 const struct brcmf_event_msg *e, void *data)
3127 struct brcmf_channel_info_le channel_inform_le;
3128 struct brcmf_scan_results_le *bss_list_le;
3129 u32 len = WL_SCAN_BUF_MAX;
3131 bool scan_abort = false;
3134 WL_TRACE("Enter\n");
3136 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3138 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3141 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3142 WL_ERR("Scan complete while device not scanning\n");
3148 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3149 sizeof(channel_inform_le));
3151 WL_ERR("scan busy (%d)\n", err);
3155 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3157 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3158 cfg_priv->bss_list = cfg_priv->scan_results;
3159 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3161 memset(cfg_priv->scan_results, 0, len);
3162 bss_list_le->buflen = cpu_to_le32(len);
3163 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3164 cfg_priv->scan_results, len);
3166 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3171 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3172 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3173 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3175 err = brcmf_inform_bss(cfg_priv);
3182 if (cfg_priv->scan_request) {
3183 WL_SCAN("calling cfg80211_scan_done\n");
3184 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3185 brcmf_set_mpc(ndev, 1);
3186 cfg_priv->scan_request = NULL;
3194 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3196 conf->mode = (u32)-1;
3197 conf->frag_threshold = (u32)-1;
3198 conf->rts_threshold = (u32)-1;
3199 conf->retry_short = (u32)-1;
3200 conf->retry_long = (u32)-1;
3201 conf->tx_power = -1;
3204 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3206 memset(el, 0, sizeof(*el));
3207 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3208 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3209 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3210 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3211 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3214 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3216 kfree(cfg_priv->scan_results);
3217 cfg_priv->scan_results = NULL;
3218 kfree(cfg_priv->bss_info);
3219 cfg_priv->bss_info = NULL;
3220 kfree(cfg_priv->conf);
3221 cfg_priv->conf = NULL;
3222 kfree(cfg_priv->profile);
3223 cfg_priv->profile = NULL;
3224 kfree(cfg_priv->scan_req_int);
3225 cfg_priv->scan_req_int = NULL;
3226 kfree(cfg_priv->dcmd_buf);
3227 cfg_priv->dcmd_buf = NULL;
3228 kfree(cfg_priv->extra_buf);
3229 cfg_priv->extra_buf = NULL;
3230 kfree(cfg_priv->iscan);
3231 cfg_priv->iscan = NULL;
3232 kfree(cfg_priv->pmk_list);
3233 cfg_priv->pmk_list = NULL;
3236 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3238 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3239 if (!cfg_priv->scan_results)
3240 goto init_priv_mem_out;
3241 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3242 if (!cfg_priv->conf)
3243 goto init_priv_mem_out;
3244 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3245 if (!cfg_priv->profile)
3246 goto init_priv_mem_out;
3247 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3248 if (!cfg_priv->bss_info)
3249 goto init_priv_mem_out;
3250 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3252 if (!cfg_priv->scan_req_int)
3253 goto init_priv_mem_out;
3254 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3255 if (!cfg_priv->dcmd_buf)
3256 goto init_priv_mem_out;
3257 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3258 if (!cfg_priv->extra_buf)
3259 goto init_priv_mem_out;
3260 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3261 if (!cfg_priv->iscan)
3262 goto init_priv_mem_out;
3263 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3264 if (!cfg_priv->pmk_list)
3265 goto init_priv_mem_out;
3270 brcmf_deinit_priv_mem(cfg_priv);
3276 * retrieve first queued event from head
3279 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3280 struct brcmf_cfg80211_priv *cfg_priv)
3282 struct brcmf_cfg80211_event_q *e = NULL;
3284 spin_lock_irq(&cfg_priv->evt_q_lock);
3285 if (!list_empty(&cfg_priv->evt_q_list)) {
3286 e = list_first_entry(&cfg_priv->evt_q_list,
3287 struct brcmf_cfg80211_event_q, evt_q_list);
3288 list_del(&e->evt_q_list);
3290 spin_unlock_irq(&cfg_priv->evt_q_lock);
3296 * push event to tail of the queue
3298 * remark: this function may not sleep as it is called in atomic context.
3302 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3303 const struct brcmf_event_msg *msg)
3305 struct brcmf_cfg80211_event_q *e;
3309 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
3314 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3316 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3317 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3318 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3323 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3328 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3330 struct brcmf_cfg80211_priv *cfg_priv =
3331 container_of(work, struct brcmf_cfg80211_priv,
3333 struct brcmf_cfg80211_event_q *e;
3335 e = brcmf_deq_event(cfg_priv);
3337 WL_ERR("event queue empty...\n");
3342 WL_INFO("event type (%d)\n", e->etype);
3343 if (cfg_priv->el.handler[e->etype])
3344 cfg_priv->el.handler[e->etype](cfg_priv,
3345 cfg_to_ndev(cfg_priv),
3346 &e->emsg, e->edata);
3348 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3350 } while ((e = brcmf_deq_event(cfg_priv)));
3354 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3356 spin_lock_init(&cfg_priv->evt_q_lock);
3357 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3360 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3362 struct brcmf_cfg80211_event_q *e;
3364 spin_lock_irq(&cfg_priv->evt_q_lock);
3365 while (!list_empty(&cfg_priv->evt_q_list)) {
3366 e = list_first_entry(&cfg_priv->evt_q_list,
3367 struct brcmf_cfg80211_event_q, evt_q_list);
3368 list_del(&e->evt_q_list);
3371 spin_unlock_irq(&cfg_priv->evt_q_lock);
3374 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3378 cfg_priv->scan_request = NULL;
3379 cfg_priv->pwr_save = true;
3380 cfg_priv->iscan_on = true; /* iscan on & off switch.
3381 we enable iscan per default */
3382 cfg_priv->roam_on = true; /* roam on & off switch.
3383 we enable roam per default */
3385 cfg_priv->iscan_kickstart = false;
3386 cfg_priv->active_scan = true; /* we do active scan for
3387 specific scan per default */
3388 cfg_priv->dongle_up = false; /* dongle is not up yet */
3389 brcmf_init_eq(cfg_priv);
3390 err = brcmf_init_priv_mem(cfg_priv);
3393 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3394 brcmf_init_eloop_handler(&cfg_priv->el);
3395 mutex_init(&cfg_priv->usr_sync);
3396 err = brcmf_init_iscan(cfg_priv);
3399 brcmf_init_conf(cfg_priv->conf);
3400 brcmf_init_prof(cfg_priv->profile);
3401 brcmf_link_down(cfg_priv);
3406 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3408 cancel_work_sync(&cfg_priv->event_work);
3409 cfg_priv->dongle_up = false; /* dongle down */
3410 brcmf_flush_eq(cfg_priv);
3411 brcmf_link_down(cfg_priv);
3412 brcmf_term_iscan(cfg_priv);
3413 brcmf_deinit_priv_mem(cfg_priv);
3416 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3417 struct device *busdev,
3420 struct wireless_dev *wdev;
3421 struct brcmf_cfg80211_priv *cfg_priv;
3422 struct brcmf_cfg80211_iface *ci;
3423 struct brcmf_cfg80211_dev *cfg_dev;
3427 WL_ERR("ndev is invalid\n");
3430 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3434 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3440 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3441 cfg_priv = wdev_to_cfg(wdev);
3442 cfg_priv->wdev = wdev;
3443 cfg_priv->pub = data;
3444 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3445 ci->cfg_priv = cfg_priv;
3446 ndev->ieee80211_ptr = wdev;
3447 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3448 wdev->netdev = ndev;
3449 err = wl_init_priv(cfg_priv);
3451 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3452 goto cfg80211_attach_out;
3454 brcmf_set_drvdata(cfg_dev, ci);
3458 cfg80211_attach_out:
3459 brcmf_free_wdev(cfg_priv);
3464 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3466 struct brcmf_cfg80211_priv *cfg_priv;
3468 cfg_priv = brcmf_priv_get(cfg_dev);
3470 wl_deinit_priv(cfg_priv);
3471 brcmf_free_wdev(cfg_priv);
3472 brcmf_set_drvdata(cfg_dev, NULL);
3477 brcmf_cfg80211_event(struct net_device *ndev,
3478 const struct brcmf_event_msg *e, void *data)
3480 u32 event_type = be32_to_cpu(e->event_type);
3481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3483 if (!brcmf_enq_event(cfg_priv, event_type, e))
3484 schedule_work(&cfg_priv->event_work);
3487 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3493 case NL80211_IFTYPE_MONITOR:
3494 case NL80211_IFTYPE_WDS:
3495 WL_ERR("type (%d) : currently we do not support this mode\n",
3499 case NL80211_IFTYPE_ADHOC:
3502 case NL80211_IFTYPE_STATION:
3507 WL_ERR("invalid type (%d)\n", iftype);
3510 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3512 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3519 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3521 /* Room for "event_msgs" + '\0' + bitvec */
3522 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3523 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3526 WL_TRACE("Enter\n");
3528 /* Setup event_msgs */
3529 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3530 iovbuf, sizeof(iovbuf));
3531 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3533 WL_ERR("Get event_msgs error (%d)\n", err);
3534 goto dongle_eventmsg_out;
3536 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3538 setbit(eventmask, BRCMF_E_SET_SSID);
3539 setbit(eventmask, BRCMF_E_ROAM);
3540 setbit(eventmask, BRCMF_E_PRUNE);
3541 setbit(eventmask, BRCMF_E_AUTH);
3542 setbit(eventmask, BRCMF_E_REASSOC);
3543 setbit(eventmask, BRCMF_E_REASSOC_IND);
3544 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3545 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3546 setbit(eventmask, BRCMF_E_DISASSOC);
3547 setbit(eventmask, BRCMF_E_JOIN);
3548 setbit(eventmask, BRCMF_E_ASSOC_IND);
3549 setbit(eventmask, BRCMF_E_PSK_SUP);
3550 setbit(eventmask, BRCMF_E_LINK);
3551 setbit(eventmask, BRCMF_E_NDIS_LINK);
3552 setbit(eventmask, BRCMF_E_MIC_ERROR);
3553 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3554 setbit(eventmask, BRCMF_E_TXFAIL);
3555 setbit(eventmask, BRCMF_E_JOIN_START);
3556 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3558 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3559 iovbuf, sizeof(iovbuf));
3560 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3562 WL_ERR("Set event_msgs error (%d)\n", err);
3563 goto dongle_eventmsg_out;
3566 dongle_eventmsg_out:
3572 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3576 __le32 roamtrigger[2];
3577 __le32 roam_delta[2];
3582 * Setup timeout if Beacons are lost and roam is
3583 * off to report link down
3586 bcn_to_le = cpu_to_le32(bcn_timeout);
3587 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3588 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3589 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3590 iovbuf, sizeof(iovbuf));
3592 WL_ERR("bcn_timeout error (%d)\n", err);
3593 goto dongle_rom_out;
3598 * Enable/Disable built-in roaming to allow supplicant
3599 * to take care of roaming
3601 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3602 roamvar_le = cpu_to_le32(roamvar);
3603 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3604 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3605 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3607 WL_ERR("roam_off error (%d)\n", err);
3608 goto dongle_rom_out;
3611 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3612 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3613 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3614 (void *)roamtrigger, sizeof(roamtrigger));
3616 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3617 goto dongle_rom_out;
3620 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3621 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3622 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3623 (void *)roam_delta, sizeof(roam_delta));
3625 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3626 goto dongle_rom_out;
3634 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3635 s32 scan_unassoc_time, s32 scan_passive_time)
3638 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3639 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3640 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3642 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3643 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3645 if (err == -EOPNOTSUPP)
3646 WL_INFO("Scan assoc time is not supported\n");
3648 WL_ERR("Scan assoc time error (%d)\n", err);
3649 goto dongle_scantime_out;
3651 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3652 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3654 if (err == -EOPNOTSUPP)
3655 WL_INFO("Scan unassoc time is not supported\n");
3657 WL_ERR("Scan unassoc time error (%d)\n", err);
3658 goto dongle_scantime_out;
3661 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3662 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3664 if (err == -EOPNOTSUPP)
3665 WL_INFO("Scan passive time is not supported\n");
3667 WL_ERR("Scan passive time error (%d)\n", err);
3668 goto dongle_scantime_out;
3671 dongle_scantime_out:
3675 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3677 struct wiphy *wiphy;
3682 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3683 &phy_list, sizeof(phy_list));
3685 WL_ERR("error (%d)\n", err);
3689 phy = ((char *)&phy_list)[1];
3690 WL_INFO("%c phy\n", phy);
3691 if (phy == 'n' || phy == 'a') {
3692 wiphy = cfg_to_wiphy(cfg_priv);
3693 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3699 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3701 return wl_update_wiphybands(cfg_priv);
3704 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3706 struct net_device *ndev;
3707 struct wireless_dev *wdev;
3711 if (cfg_priv->dongle_up)
3714 ndev = cfg_to_ndev(cfg_priv);
3715 wdev = ndev->ieee80211_ptr;
3717 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3718 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3720 err = brcmf_dongle_eventmsg(ndev);
3722 goto default_conf_out;
3724 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3725 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3727 goto default_conf_out;
3728 WL_INFO("power save set to %s\n",
3729 (power_mode ? "enabled" : "disabled"));
3731 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3734 goto default_conf_out;
3735 err = brcmf_dongle_mode(ndev, wdev->iftype);
3736 if (err && err != -EINPROGRESS)
3737 goto default_conf_out;
3738 err = brcmf_dongle_probecap(cfg_priv);
3740 goto default_conf_out;
3742 /* -EINPROGRESS: Call commit handler */
3746 cfg_priv->dongle_up = true;
3752 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3754 char buf[10+IFNAMSIZ];
3758 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3759 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3760 cfg_to_wiphy(cfg_priv)->debugfsdir);
3762 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3763 (u16 *)&cfg_priv->profile->beacon_interval);
3769 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3770 (u8 *)&cfg_priv->profile->dtim_period);
3780 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3782 debugfs_remove_recursive(cfg_priv->debugfsdir);
3783 cfg_priv->debugfsdir = NULL;
3786 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3790 set_bit(WL_STATUS_READY, &cfg_priv->status);
3792 brcmf_debugfs_add_netdev_params(cfg_priv);
3794 err = brcmf_config_dongle(cfg_priv);
3798 brcmf_invoke_iscan(cfg_priv);
3803 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3806 * While going down, if associated with AP disassociate
3807 * from AP to save power
3809 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3810 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3811 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3812 WL_INFO("Disassociating from AP");
3813 brcmf_link_down(cfg_priv);
3815 /* Make sure WPA_Supplicant receives all the event
3816 generated due to DISASSOC call to the fw to keep
3817 the state fw and WPA_Supplicant state consistent
3822 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3823 brcmf_term_iscan(cfg_priv);
3824 if (cfg_priv->scan_request) {
3825 cfg80211_scan_done(cfg_priv->scan_request, true);
3826 /* May need to perform this to cover rmmod */
3827 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3828 cfg_priv->scan_request = NULL;
3830 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3831 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3832 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3834 brcmf_debugfs_remove_netdev(cfg_priv);
3839 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3841 struct brcmf_cfg80211_priv *cfg_priv;
3844 cfg_priv = brcmf_priv_get(cfg_dev);
3845 mutex_lock(&cfg_priv->usr_sync);
3846 err = __brcmf_cfg80211_up(cfg_priv);
3847 mutex_unlock(&cfg_priv->usr_sync);
3852 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3854 struct brcmf_cfg80211_priv *cfg_priv;
3857 cfg_priv = brcmf_priv_get(cfg_dev);
3858 mutex_lock(&cfg_priv->usr_sync);
3859 err = __brcmf_cfg80211_down(cfg_priv);
3860 mutex_unlock(&cfg_priv->usr_sync);
3865 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3868 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3871 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3872 WL_ERR("ei crosses buffer boundary\n");
3875 ie->buf[ie->offset] = t;
3876 ie->buf[ie->offset + 1] = l;
3877 memcpy(&ie->buf[ie->offset + 2], v, l);
3878 ie->offset += l + 2;