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 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
508 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
509 s32 paramlen, void *bufptr, s32 buflen)
513 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
516 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
520 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
521 s32 paramlen, void *bufptr, s32 buflen)
525 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
528 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
532 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
533 struct brcmf_ssid *ssid, u16 action)
535 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
536 offsetof(struct brcmf_iscan_params_le, params_le);
537 struct brcmf_iscan_params_le *params;
540 if (ssid && ssid->SSID_len)
541 params_size += sizeof(struct brcmf_ssid);
542 params = kzalloc(params_size, GFP_KERNEL);
545 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
547 wl_iscan_prep(¶ms->params_le, ssid);
549 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
550 params->action = cpu_to_le16(action);
551 params->scan_duration = cpu_to_le16(0);
553 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
554 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
557 WL_INFO("system busy : iscan canceled\n");
559 WL_ERR("error (%d)\n", err);
566 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
568 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
569 struct net_device *ndev = cfg_to_ndev(cfg_priv);
570 struct brcmf_ssid ssid;
574 /* Broadcast scan by default */
575 memset(&ssid, 0, sizeof(ssid));
577 iscan->state = WL_ISCAN_STATE_SCANING;
579 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
580 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
581 &passive_scan, sizeof(passive_scan));
583 WL_ERR("error (%d)\n", err);
586 brcmf_set_mpc(ndev, 0);
587 cfg_priv->iscan_kickstart = true;
588 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
590 brcmf_set_mpc(ndev, 1);
591 cfg_priv->iscan_kickstart = false;
594 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
600 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
601 struct cfg80211_scan_request *request,
602 struct cfg80211_ssid *this_ssid)
604 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
605 struct cfg80211_ssid *ssids;
606 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
613 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
614 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
617 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
618 WL_ERR("Scanning being aborted : status (%lu)\n",
622 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
623 WL_ERR("Connecting : status (%lu)\n",
632 ssids = request->ssids;
633 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
637 /* we don't do iscan in ibss */
641 cfg_priv->scan_request = request;
642 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
644 err = brcmf_do_iscan(cfg_priv);
650 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
651 ssids->ssid, ssids->ssid_len);
652 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
653 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
654 sr->ssid_le.SSID_len = cpu_to_le32(0);
656 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
657 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
660 WL_SCAN("Broadcast scan\n");
663 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
664 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
665 &passive_scan, sizeof(passive_scan));
667 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
670 brcmf_set_mpc(ndev, 0);
671 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
672 sizeof(sr->ssid_le));
675 WL_INFO("system busy : scan for \"%s\" "
676 "canceled\n", sr->ssid_le.SSID);
678 WL_ERR("WLC_SCAN error (%d)\n", err);
680 brcmf_set_mpc(ndev, 1);
688 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
689 cfg_priv->scan_request = NULL;
694 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
695 struct cfg80211_scan_request *request)
701 if (!check_sys_up(wiphy))
704 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
706 WL_ERR("scan error (%d)\n", err);
712 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
716 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
718 WL_ERR("Error (%d)\n", err);
723 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
727 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
729 WL_ERR("Error (%d)\n", err);
734 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
737 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
739 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
741 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
747 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
749 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
750 struct net_device *ndev = cfg_to_ndev(cfg_priv);
754 if (!check_sys_up(wiphy))
757 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
758 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
759 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
760 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
764 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
765 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
766 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
767 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
771 if (changed & WIPHY_PARAM_RETRY_LONG
772 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
773 cfg_priv->conf->retry_long = wiphy->retry_long;
774 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
778 if (changed & WIPHY_PARAM_RETRY_SHORT
779 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
780 cfg_priv->conf->retry_short = wiphy->retry_short;
781 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
791 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
795 return &cfg_priv->profile->sec;
797 return &cfg_priv->profile->bssid;
799 return &cfg_priv->profile->ssid;
801 WL_ERR("invalid item (%d)\n", item);
806 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
807 const struct brcmf_event_msg *e, void *data, s32 item)
810 struct brcmf_ssid *ssid;
814 ssid = (struct brcmf_ssid *) data;
815 memset(cfg_priv->profile->ssid.SSID, 0,
816 sizeof(cfg_priv->profile->ssid.SSID));
817 memcpy(cfg_priv->profile->ssid.SSID,
818 ssid->SSID, ssid->SSID_len);
819 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
823 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
825 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
828 memcpy(&cfg_priv->profile->sec, data,
829 sizeof(cfg_priv->profile->sec));
831 case WL_PROF_BEACONINT:
832 cfg_priv->profile->beacon_interval = *(u16 *)data;
834 case WL_PROF_DTIMPERIOD:
835 cfg_priv->profile->dtim_period = *(u8 *)data;
838 WL_ERR("unsupported item (%d)\n", item);
846 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
848 memset(prof, 0, sizeof(*prof));
851 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
852 size_t *join_params_size)
857 if (ch <= CH_MAX_2G_CHANNEL)
858 chanspec |= WL_CHANSPEC_BAND_2G;
860 chanspec |= WL_CHANSPEC_BAND_5G;
862 chanspec |= WL_CHANSPEC_BW_20;
863 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
865 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
868 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
869 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
870 join_params->params_le.chanspec_num = cpu_to_le32(1);
872 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
873 "channel %d, chanspec %#X\n",
874 chanspec, ch, chanspec);
878 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
880 struct net_device *ndev = NULL;
885 if (cfg_priv->link_up) {
886 ndev = cfg_to_ndev(cfg_priv);
887 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
888 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
890 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
891 cfg_priv->link_up = false;
897 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
898 struct cfg80211_ibss_params *params)
900 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
901 struct brcmf_join_params join_params;
902 size_t join_params_size = 0;
906 struct brcmf_ssid ssid;
909 if (!check_sys_up(wiphy))
913 WL_CONN("SSID: %s\n", params->ssid);
915 WL_CONN("SSID: NULL, Not supported\n");
919 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
922 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
923 params->bssid[0], params->bssid[1], params->bssid[2],
924 params->bssid[3], params->bssid[4], params->bssid[5]);
926 WL_CONN("No BSSID specified\n");
929 WL_CONN("channel: %d\n", params->channel->center_freq);
931 WL_CONN("no channel specified\n");
933 if (params->channel_fixed)
934 WL_CONN("fixed channel required\n");
936 WL_CONN("no fixed channel required\n");
938 if (params->ie && params->ie_len)
939 WL_CONN("ie len: %d\n", params->ie_len);
941 WL_CONN("no ie specified\n");
943 if (params->beacon_interval)
944 WL_CONN("beacon interval: %d\n", params->beacon_interval);
946 WL_CONN("no beacon interval specified\n");
948 if (params->basic_rates)
949 WL_CONN("basic rates: %08X\n", params->basic_rates);
951 WL_CONN("no basic rates specified\n");
954 WL_CONN("privacy required\n");
956 WL_CONN("no privacy required\n");
958 /* Configure Privacy for starter */
962 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
964 WL_ERR("wsec failed (%d)\n", err);
968 /* Configure Beacon Interval for starter */
969 if (params->beacon_interval)
970 bcnprd = params->beacon_interval;
974 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
976 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
980 /* Configure required join parameter */
981 memset(&join_params, 0, sizeof(struct brcmf_join_params));
984 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
985 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
986 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
987 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
988 join_params_size = sizeof(join_params.ssid_le);
989 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
993 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
994 join_params_size = sizeof(join_params.ssid_le) +
995 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
997 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1000 brcmf_update_prof(cfg_priv, NULL,
1001 &join_params.params_le.bssid, WL_PROF_BSSID);
1004 if (params->channel) {
1008 ieee80211_frequency_to_channel(
1009 params->channel->center_freq);
1010 if (params->channel_fixed) {
1011 /* adding chanspec */
1012 brcmf_ch_to_chanspec(cfg_priv->channel,
1013 &join_params, &join_params_size);
1016 /* set channel for starter */
1017 target_channel = cfg_priv->channel;
1018 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1021 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1025 cfg_priv->channel = 0;
1027 cfg_priv->ibss_starter = false;
1030 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1031 &join_params, join_params_size);
1033 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1039 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1045 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1047 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1050 WL_TRACE("Enter\n");
1051 if (!check_sys_up(wiphy))
1054 brcmf_link_down(cfg_priv);
1061 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1062 struct cfg80211_connect_params *sme)
1064 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1065 struct brcmf_cfg80211_security *sec;
1069 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1070 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1071 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1072 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1074 val = WPA_AUTH_DISABLED;
1075 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1076 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1078 WL_ERR("set wpa_auth failed (%d)\n", err);
1081 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1082 sec->wpa_versions = sme->crypto.wpa_versions;
1086 static s32 brcmf_set_auth_type(struct net_device *ndev,
1087 struct cfg80211_connect_params *sme)
1089 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1090 struct brcmf_cfg80211_security *sec;
1094 switch (sme->auth_type) {
1095 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1097 WL_CONN("open system\n");
1099 case NL80211_AUTHTYPE_SHARED_KEY:
1101 WL_CONN("shared key\n");
1103 case NL80211_AUTHTYPE_AUTOMATIC:
1105 WL_CONN("automatic\n");
1107 case NL80211_AUTHTYPE_NETWORK_EAP:
1108 WL_CONN("network eap\n");
1111 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1115 err = brcmf_dev_intvar_set(ndev, "auth", val);
1117 WL_ERR("set auth failed (%d)\n", err);
1120 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1121 sec->auth_type = sme->auth_type;
1126 brcmf_set_set_cipher(struct net_device *ndev,
1127 struct cfg80211_connect_params *sme)
1129 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1130 struct brcmf_cfg80211_security *sec;
1135 if (sme->crypto.n_ciphers_pairwise) {
1136 switch (sme->crypto.ciphers_pairwise[0]) {
1137 case WLAN_CIPHER_SUITE_WEP40:
1138 case WLAN_CIPHER_SUITE_WEP104:
1141 case WLAN_CIPHER_SUITE_TKIP:
1142 pval = TKIP_ENABLED;
1144 case WLAN_CIPHER_SUITE_CCMP:
1147 case WLAN_CIPHER_SUITE_AES_CMAC:
1151 WL_ERR("invalid cipher pairwise (%d)\n",
1152 sme->crypto.ciphers_pairwise[0]);
1156 if (sme->crypto.cipher_group) {
1157 switch (sme->crypto.cipher_group) {
1158 case WLAN_CIPHER_SUITE_WEP40:
1159 case WLAN_CIPHER_SUITE_WEP104:
1162 case WLAN_CIPHER_SUITE_TKIP:
1163 gval = TKIP_ENABLED;
1165 case WLAN_CIPHER_SUITE_CCMP:
1168 case WLAN_CIPHER_SUITE_AES_CMAC:
1172 WL_ERR("invalid cipher group (%d)\n",
1173 sme->crypto.cipher_group);
1178 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1179 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1181 WL_ERR("error (%d)\n", err);
1185 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1186 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1187 sec->cipher_group = sme->crypto.cipher_group;
1193 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1195 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1196 struct brcmf_cfg80211_security *sec;
1200 if (sme->crypto.n_akm_suites) {
1201 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1203 WL_ERR("could not get wpa_auth (%d)\n", err);
1206 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1207 switch (sme->crypto.akm_suites[0]) {
1208 case WLAN_AKM_SUITE_8021X:
1209 val = WPA_AUTH_UNSPECIFIED;
1211 case WLAN_AKM_SUITE_PSK:
1215 WL_ERR("invalid cipher group (%d)\n",
1216 sme->crypto.cipher_group);
1219 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1220 switch (sme->crypto.akm_suites[0]) {
1221 case WLAN_AKM_SUITE_8021X:
1222 val = WPA2_AUTH_UNSPECIFIED;
1224 case WLAN_AKM_SUITE_PSK:
1225 val = WPA2_AUTH_PSK;
1228 WL_ERR("invalid cipher group (%d)\n",
1229 sme->crypto.cipher_group);
1234 WL_CONN("setting wpa_auth to %d\n", val);
1235 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1237 WL_ERR("could not set wpa_auth (%d)\n", err);
1241 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1242 sec->wpa_auth = sme->crypto.akm_suites[0];
1248 brcmf_set_wep_sharedkey(struct net_device *ndev,
1249 struct cfg80211_connect_params *sme)
1251 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1252 struct brcmf_cfg80211_security *sec;
1253 struct brcmf_wsec_key key;
1257 WL_CONN("key len (%d)\n", sme->key_len);
1259 if (sme->key_len == 0)
1262 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1263 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1264 sec->wpa_versions, sec->cipher_pairwise);
1266 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1269 if (sec->cipher_pairwise &
1270 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1271 memset(&key, 0, sizeof(key));
1272 key.len = (u32) sme->key_len;
1273 key.index = (u32) sme->key_idx;
1274 if (key.len > sizeof(key.data)) {
1275 WL_ERR("Too long key length (%u)\n", key.len);
1278 memcpy(key.data, sme->key, key.len);
1279 key.flags = BRCMF_PRIMARY_KEY;
1280 switch (sec->cipher_pairwise) {
1281 case WLAN_CIPHER_SUITE_WEP40:
1282 key.algo = CRYPTO_ALGO_WEP1;
1284 case WLAN_CIPHER_SUITE_WEP104:
1285 key.algo = CRYPTO_ALGO_WEP128;
1288 WL_ERR("Invalid algorithm (%d)\n",
1289 sme->crypto.ciphers_pairwise[0]);
1292 /* Set the new key/index */
1293 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1294 key.len, key.index, key.algo);
1295 WL_CONN("key \"%s\"\n", key.data);
1296 err = send_key_to_dongle(ndev, &key);
1300 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1301 WL_CONN("set auth_type to shared key\n");
1302 val = 1; /* shared key */
1303 err = brcmf_dev_intvar_set(ndev, "auth", val);
1305 WL_ERR("set auth failed (%d)\n", err);
1314 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1315 struct cfg80211_connect_params *sme)
1317 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1318 struct ieee80211_channel *chan = sme->channel;
1319 struct brcmf_join_params join_params;
1320 size_t join_params_size;
1321 struct brcmf_ssid ssid;
1325 WL_TRACE("Enter\n");
1326 if (!check_sys_up(wiphy))
1330 WL_ERR("Invalid ssid\n");
1334 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1338 ieee80211_frequency_to_channel(chan->center_freq);
1339 WL_CONN("channel (%d), center_req (%d)\n",
1340 cfg_priv->channel, chan->center_freq);
1342 cfg_priv->channel = 0;
1344 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1346 err = brcmf_set_wpa_version(ndev, sme);
1348 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1352 err = brcmf_set_auth_type(ndev, sme);
1354 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1358 err = brcmf_set_set_cipher(ndev, sme);
1360 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1364 err = brcmf_set_key_mgmt(ndev, sme);
1366 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1370 err = brcmf_set_wep_sharedkey(ndev, sme);
1372 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1376 memset(&join_params, 0, sizeof(join_params));
1377 join_params_size = sizeof(join_params.ssid_le);
1379 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1380 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1381 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1382 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1383 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1385 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1387 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1388 WL_CONN("ssid \"%s\", len (%d)\n",
1389 ssid.SSID, ssid.SSID_len);
1391 brcmf_ch_to_chanspec(cfg_priv->channel,
1392 &join_params, &join_params_size);
1393 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1394 &join_params, join_params_size);
1396 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1400 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1406 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1409 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1410 struct brcmf_scb_val_le scbval;
1413 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1414 if (!check_sys_up(wiphy))
1417 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1419 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1420 scbval.val = cpu_to_le32(reason_code);
1421 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1422 sizeof(struct brcmf_scb_val_le));
1424 WL_ERR("error (%d)\n", err);
1426 cfg_priv->link_up = false;
1433 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1434 enum nl80211_tx_power_setting type, s32 mbm)
1437 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1438 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1442 s32 dbm = MBM_TO_DBM(mbm);
1444 WL_TRACE("Enter\n");
1445 if (!check_sys_up(wiphy))
1449 case NL80211_TX_POWER_AUTOMATIC:
1451 case NL80211_TX_POWER_LIMITED:
1452 case NL80211_TX_POWER_FIXED:
1454 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1460 /* Make sure radio is off or on as far as software is concerned */
1461 disable = WL_RADIO_SW_DISABLE << 16;
1462 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1464 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1469 txpwrmw = (u16) dbm;
1470 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1471 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1473 WL_ERR("qtxpower error (%d)\n", err);
1474 cfg_priv->conf->tx_power = dbm;
1481 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1483 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1484 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1489 WL_TRACE("Enter\n");
1490 if (!check_sys_up(wiphy))
1493 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1495 WL_ERR("error (%d)\n", err);
1499 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1500 *dbm = (s32) brcmf_qdbm_to_mw(result);
1508 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1509 u8 key_idx, bool unicast, bool multicast)
1515 WL_TRACE("Enter\n");
1516 WL_CONN("key index (%d)\n", key_idx);
1517 if (!check_sys_up(wiphy))
1520 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1522 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1526 if (wsec & WEP_ENABLED) {
1527 /* Just select a new current key */
1529 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1532 WL_ERR("error (%d)\n", err);
1540 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1541 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1543 struct brcmf_wsec_key key;
1544 struct brcmf_wsec_key_le key_le;
1547 memset(&key, 0, sizeof(key));
1548 key.index = (u32) key_idx;
1549 /* Instead of bcast for ea address for default wep keys,
1550 driver needs it to be Null */
1551 if (!is_multicast_ether_addr(mac_addr))
1552 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1553 key.len = (u32) params->key_len;
1554 /* check for key index change */
1557 err = send_key_to_dongle(ndev, &key);
1561 if (key.len > sizeof(key.data)) {
1562 WL_ERR("Invalid key length (%d)\n", key.len);
1566 WL_CONN("Setting the key index %d\n", key.index);
1567 memcpy(key.data, params->key, key.len);
1569 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1571 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1572 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1573 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1576 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1577 if (params->seq && params->seq_len == 6) {
1580 ivptr = (u8 *) params->seq;
1581 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1582 (ivptr[3] << 8) | ivptr[2];
1583 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1584 key.iv_initialized = true;
1587 switch (params->cipher) {
1588 case WLAN_CIPHER_SUITE_WEP40:
1589 key.algo = CRYPTO_ALGO_WEP1;
1590 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1592 case WLAN_CIPHER_SUITE_WEP104:
1593 key.algo = CRYPTO_ALGO_WEP128;
1594 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1596 case WLAN_CIPHER_SUITE_TKIP:
1597 key.algo = CRYPTO_ALGO_TKIP;
1598 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1600 case WLAN_CIPHER_SUITE_AES_CMAC:
1601 key.algo = CRYPTO_ALGO_AES_CCM;
1602 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1604 case WLAN_CIPHER_SUITE_CCMP:
1605 key.algo = CRYPTO_ALGO_AES_CCM;
1606 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1609 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1612 convert_key_from_CPU(&key, &key_le);
1614 brcmf_netdev_wait_pend8021x(ndev);
1615 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1618 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1626 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1627 u8 key_idx, bool pairwise, const u8 *mac_addr,
1628 struct key_params *params)
1630 struct brcmf_wsec_key key;
1636 WL_TRACE("Enter\n");
1637 WL_CONN("key index (%d)\n", key_idx);
1638 if (!check_sys_up(wiphy))
1643 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1645 memset(&key, 0, sizeof(key));
1647 key.len = (u32) params->key_len;
1648 key.index = (u32) key_idx;
1650 if (key.len > sizeof(key.data)) {
1651 WL_ERR("Too long key length (%u)\n", key.len);
1655 memcpy(key.data, params->key, key.len);
1657 key.flags = BRCMF_PRIMARY_KEY;
1658 switch (params->cipher) {
1659 case WLAN_CIPHER_SUITE_WEP40:
1660 key.algo = CRYPTO_ALGO_WEP1;
1661 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1663 case WLAN_CIPHER_SUITE_WEP104:
1664 key.algo = CRYPTO_ALGO_WEP128;
1665 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1667 case WLAN_CIPHER_SUITE_TKIP:
1668 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1669 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1670 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1671 key.algo = CRYPTO_ALGO_TKIP;
1672 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1674 case WLAN_CIPHER_SUITE_AES_CMAC:
1675 key.algo = CRYPTO_ALGO_AES_CCM;
1676 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1678 case WLAN_CIPHER_SUITE_CCMP:
1679 key.algo = CRYPTO_ALGO_AES_CCM;
1680 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1683 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1688 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1693 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1695 WL_ERR("get wsec error (%d)\n", err);
1698 wsec &= ~(WEP_ENABLED);
1700 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1702 WL_ERR("set wsec error (%d)\n", err);
1706 val = 1; /* assume shared key. otherwise 0 */
1707 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1709 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1716 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1717 u8 key_idx, bool pairwise, const u8 *mac_addr)
1719 struct brcmf_wsec_key key;
1724 WL_TRACE("Enter\n");
1725 if (!check_sys_up(wiphy))
1728 memset(&key, 0, sizeof(key));
1730 key.index = (u32) key_idx;
1731 key.flags = BRCMF_PRIMARY_KEY;
1732 key.algo = CRYPTO_ALGO_OFF;
1734 WL_CONN("key index (%d)\n", key_idx);
1736 /* Set the new key/index */
1737 err = send_key_to_dongle(ndev, &key);
1739 if (err == -EINVAL) {
1740 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1741 /* we ignore this key index in this case */
1742 WL_ERR("invalid key index (%d)\n", key_idx);
1744 /* Ignore this error, may happen during DISASSOC */
1750 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1752 WL_ERR("get wsec error (%d)\n", err);
1753 /* Ignore this error, may happen during DISASSOC */
1757 wsec &= ~(WEP_ENABLED);
1759 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1761 WL_ERR("set wsec error (%d)\n", err);
1762 /* Ignore this error, may happen during DISASSOC */
1767 val = 0; /* assume open key. otherwise 1 */
1768 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1770 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1771 /* Ignore this error, may happen during DISASSOC */
1780 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1781 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1782 void (*callback) (void *cookie, struct key_params * params))
1784 struct key_params params;
1785 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1786 struct brcmf_cfg80211_security *sec;
1790 WL_TRACE("Enter\n");
1791 WL_CONN("key index (%d)\n", key_idx);
1792 if (!check_sys_up(wiphy))
1795 memset(¶ms, 0, sizeof(params));
1797 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1799 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1800 /* Ignore this error, may happen during DISASSOC */
1806 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1807 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1808 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1809 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1810 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1811 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1812 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1816 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1817 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1820 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1821 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1824 WL_ERR("Invalid algo (0x%x)\n", wsec);
1828 callback(cookie, ¶ms);
1836 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1837 struct net_device *ndev, u8 key_idx)
1839 WL_INFO("Not supported\n");
1845 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1846 u8 *mac, struct station_info *sinfo)
1848 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1849 struct brcmf_scb_val_le scb_val;
1853 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1855 WL_TRACE("Enter\n");
1856 if (!check_sys_up(wiphy))
1859 if (memcmp(mac, bssid, ETH_ALEN)) {
1860 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1861 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1862 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1863 bssid[0], bssid[1], bssid[2], bssid[3],
1864 bssid[4], bssid[5]);
1869 /* Report the current tx rate */
1870 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1872 WL_ERR("Could not get rate (%d)\n", err);
1874 sinfo->filled |= STATION_INFO_TX_BITRATE;
1875 sinfo->txrate.legacy = rate * 5;
1876 WL_CONN("Rate %d Mbps\n", rate / 2);
1879 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1880 scb_val.val = cpu_to_le32(0);
1881 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1882 sizeof(struct brcmf_scb_val_le));
1884 WL_ERR("Could not get rssi (%d)\n", err);
1886 rssi = le32_to_cpu(scb_val.val);
1887 sinfo->filled |= STATION_INFO_SIGNAL;
1888 sinfo->signal = rssi;
1889 WL_CONN("RSSI %d dBm\n", rssi);
1898 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1899 bool enabled, s32 timeout)
1903 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1905 WL_TRACE("Enter\n");
1908 * Powersave enable/disable request is coming from the
1909 * cfg80211 even before the interface is up. In that
1910 * scenario, driver will be storing the power save
1911 * preference in cfg_priv struct to apply this to
1912 * FW later while initializing the dongle
1914 cfg_priv->pwr_save = enabled;
1915 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1917 WL_INFO("Device is not ready,"
1918 "storing the value in cfg_priv struct\n");
1922 pm = enabled ? PM_FAST : PM_OFF;
1923 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1925 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1928 WL_ERR("net_device is not ready yet\n");
1930 WL_ERR("error (%d)\n", err);
1938 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1940 const struct cfg80211_bitrate_mask *mask)
1942 struct brcm_rateset_le rateset_le;
1950 WL_TRACE("Enter\n");
1951 if (!check_sys_up(wiphy))
1954 /* addr param is always NULL. ignore it */
1955 /* Get current rateset */
1956 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1957 sizeof(rateset_le));
1959 WL_ERR("could not get current rateset (%d)\n", err);
1963 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1965 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1968 val = wl_g_rates[legacy - 1].bitrate * 100000;
1970 if (val < le32_to_cpu(rateset_le.count))
1971 /* Select rate by rateset index */
1972 rate = rateset_le.rates[val] & 0x7f;
1974 /* Specified rate in bps */
1975 rate = val / 500000;
1977 WL_CONN("rate %d mbps\n", rate / 2);
1981 * Set rate override,
1982 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1984 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1985 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1986 if (err_bg && err_a) {
1987 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1988 err = err_bg | err_a;
1996 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1997 struct brcmf_bss_info_le *bi)
1999 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2000 struct ieee80211_channel *notify_channel;
2001 struct cfg80211_bss *bss;
2002 struct ieee80211_supported_band *band;
2006 u16 notify_capability;
2007 u16 notify_interval;
2009 size_t notify_ielen;
2012 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2013 WL_ERR("Bss info is larger than buffer. Discarding\n");
2017 channel = bi->ctl_ch ? bi->ctl_ch :
2018 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2020 if (channel <= CH_MAX_2G_CHANNEL)
2021 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2023 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2025 freq = ieee80211_channel_to_frequency(channel, band->band);
2026 notify_channel = ieee80211_get_channel(wiphy, freq);
2028 notify_capability = le16_to_cpu(bi->capability);
2029 notify_interval = le16_to_cpu(bi->beacon_period);
2030 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2031 notify_ielen = le32_to_cpu(bi->ie_length);
2032 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2034 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2035 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2036 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2037 WL_CONN("Channel: %d(%d)\n", channel, freq);
2038 WL_CONN("Capability: %X\n", notify_capability);
2039 WL_CONN("Beacon interval: %d\n", notify_interval);
2040 WL_CONN("Signal: %d\n", notify_signal);
2042 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2043 0, notify_capability, notify_interval, notify_ie,
2044 notify_ielen, notify_signal, GFP_KERNEL);
2049 cfg80211_put_bss(bss);
2054 static struct brcmf_bss_info_le *
2055 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2058 return list->bss_info_le;
2059 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2060 le32_to_cpu(bss->length));
2063 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2065 struct brcmf_scan_results *bss_list;
2066 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2070 bss_list = cfg_priv->bss_list;
2071 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2072 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2076 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2077 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2078 bi = next_bss_le(bss_list, bi);
2079 err = brcmf_inform_single_bss(cfg_priv, bi);
2086 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2087 struct net_device *ndev, const u8 *bssid)
2089 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2090 struct ieee80211_channel *notify_channel;
2091 struct brcmf_bss_info_le *bi = NULL;
2092 struct ieee80211_supported_band *band;
2093 struct cfg80211_bss *bss;
2098 u16 notify_capability;
2099 u16 notify_interval;
2101 size_t notify_ielen;
2104 WL_TRACE("Enter\n");
2106 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2112 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2114 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2116 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2120 bi = (struct brcmf_bss_info_le *)(buf + 4);
2122 channel = bi->ctl_ch ? bi->ctl_ch :
2123 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2125 if (channel <= CH_MAX_2G_CHANNEL)
2126 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2128 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2130 freq = ieee80211_channel_to_frequency(channel, band->band);
2131 notify_channel = ieee80211_get_channel(wiphy, freq);
2133 notify_capability = le16_to_cpu(bi->capability);
2134 notify_interval = le16_to_cpu(bi->beacon_period);
2135 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2136 notify_ielen = le32_to_cpu(bi->ie_length);
2137 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2139 WL_CONN("channel: %d(%d)\n", channel, freq);
2140 WL_CONN("capability: %X\n", notify_capability);
2141 WL_CONN("beacon interval: %d\n", notify_interval);
2142 WL_CONN("signal: %d\n", notify_signal);
2144 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2145 0, notify_capability, notify_interval,
2146 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2153 cfg80211_put_bss(bss);
2164 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2166 return cfg_priv->conf->mode == WL_MODE_IBSS;
2170 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2171 * triples, returning a pointer to the substring whose first element
2174 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2176 struct brcmf_tlv *elt;
2179 elt = (struct brcmf_tlv *) buf;
2182 /* find tagged parameter */
2183 while (totlen >= 2) {
2186 /* validate remaining totlen */
2187 if ((elt->id == key) && (totlen >= (len + 2)))
2190 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2191 totlen -= (len + 2);
2197 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2199 struct brcmf_bss_info_le *bi;
2200 struct brcmf_ssid *ssid;
2201 struct brcmf_tlv *tim;
2202 u16 beacon_interval;
2208 WL_TRACE("Enter\n");
2209 if (brcmf_is_ibssmode(cfg_priv))
2212 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2214 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2215 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2216 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2218 WL_ERR("Could not get bss info %d\n", err);
2219 goto update_bss_info_out;
2222 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2223 err = brcmf_inform_single_bss(cfg_priv, bi);
2225 goto update_bss_info_out;
2227 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2228 ie_len = le32_to_cpu(bi->ie_length);
2229 beacon_interval = le16_to_cpu(bi->beacon_period);
2231 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2233 dtim_period = tim->data[1];
2236 * active scan was done so we could not get dtim
2237 * information out of probe response.
2238 * so we speficially query dtim information to dongle.
2241 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2242 "dtim_assoc", &var);
2244 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2245 goto update_bss_info_out;
2247 dtim_period = (u8)var;
2250 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2251 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2253 update_bss_info_out:
2258 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2260 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2261 struct brcmf_ssid ssid;
2263 if (cfg_priv->iscan_on) {
2264 iscan->state = WL_ISCAN_STATE_IDLE;
2266 if (iscan->timer_on) {
2267 del_timer_sync(&iscan->timer);
2268 iscan->timer_on = 0;
2271 cancel_work_sync(&iscan->work);
2273 /* Abort iscan running in FW */
2274 memset(&ssid, 0, sizeof(ssid));
2275 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2279 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2282 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2283 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2285 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2286 WL_ERR("Scan complete while device not scanning\n");
2289 if (cfg_priv->scan_request) {
2290 WL_SCAN("ISCAN Completed scan: %s\n",
2291 aborted ? "Aborted" : "Done");
2292 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2293 brcmf_set_mpc(ndev, 1);
2294 cfg_priv->scan_request = NULL;
2296 cfg_priv->iscan_kickstart = false;
2299 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2301 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2302 WL_SCAN("wake up iscan\n");
2303 schedule_work(&iscan->work);
2311 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2312 struct brcmf_scan_results **bss_list)
2314 struct brcmf_iscan_results list;
2315 struct brcmf_scan_results *results;
2316 struct brcmf_scan_results_le *results_le;
2317 struct brcmf_iscan_results *list_buf;
2320 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2321 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2322 results = &list_buf->results;
2323 results_le = &list_buf->results_le;
2324 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2325 results->version = 0;
2328 memset(&list, 0, sizeof(list));
2329 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2330 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2331 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2332 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2334 WL_ERR("error (%d)\n", err);
2337 results->buflen = le32_to_cpu(results_le->buflen);
2338 results->version = le32_to_cpu(results_le->version);
2339 results->count = le32_to_cpu(results_le->count);
2340 WL_SCAN("results->count = %d\n", results_le->count);
2341 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2342 *status = le32_to_cpu(list_buf->status_le);
2343 WL_SCAN("status = %d\n", *status);
2344 *bss_list = results;
2349 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2351 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2354 iscan->state = WL_ISCAN_STATE_IDLE;
2355 brcmf_inform_bss(cfg_priv);
2356 brcmf_notify_iscan_complete(iscan, false);
2361 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2363 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2366 /* Reschedule the timer */
2367 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2368 iscan->timer_on = 1;
2373 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2375 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2378 brcmf_inform_bss(cfg_priv);
2379 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2380 /* Reschedule the timer */
2381 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2382 iscan->timer_on = 1;
2387 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2389 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2392 iscan->state = WL_ISCAN_STATE_IDLE;
2393 brcmf_notify_iscan_complete(iscan, true);
2398 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2400 struct brcmf_cfg80211_iscan_ctrl *iscan =
2401 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2403 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2404 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2405 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2407 if (iscan->timer_on) {
2408 del_timer_sync(&iscan->timer);
2409 iscan->timer_on = 0;
2412 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2413 status = BRCMF_SCAN_RESULTS_ABORTED;
2414 WL_ERR("Abort iscan\n");
2417 el->handler[status](cfg_priv);
2420 static void brcmf_iscan_timer(unsigned long data)
2422 struct brcmf_cfg80211_iscan_ctrl *iscan =
2423 (struct brcmf_cfg80211_iscan_ctrl *)data;
2426 iscan->timer_on = 0;
2427 WL_SCAN("timer expired\n");
2428 brcmf_wakeup_iscan(iscan);
2432 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2434 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2436 if (cfg_priv->iscan_on) {
2437 iscan->state = WL_ISCAN_STATE_IDLE;
2438 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2444 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2446 memset(el, 0, sizeof(*el));
2447 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2448 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2449 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2450 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2451 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2454 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2456 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2459 if (cfg_priv->iscan_on) {
2460 iscan->ndev = cfg_to_ndev(cfg_priv);
2461 brcmf_init_iscan_eloop(&iscan->el);
2462 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2463 init_timer(&iscan->timer);
2464 iscan->timer.data = (unsigned long) iscan;
2465 iscan->timer.function = brcmf_iscan_timer;
2466 err = brcmf_invoke_iscan(cfg_priv);
2468 iscan->data = cfg_priv;
2474 static __always_inline void brcmf_delay(u32 ms)
2476 if (ms < 1000 / HZ) {
2484 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2486 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2489 * Check for WL_STATUS_READY before any function call which
2490 * could result is bus access. Don't block the resume for
2491 * any driver error conditions
2493 WL_TRACE("Enter\n");
2495 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2496 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2502 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2503 struct cfg80211_wowlan *wow)
2505 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2506 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2508 WL_TRACE("Enter\n");
2511 * Check for WL_STATUS_READY before any function call which
2512 * could result is bus access. Don't block the suspend for
2513 * any driver error conditions
2517 * While going to suspend if associated with AP disassociate
2518 * from AP to save power while system is in suspended state
2520 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2521 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2522 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2523 WL_INFO("Disassociating from AP"
2524 " while entering suspend state\n");
2525 brcmf_link_down(cfg_priv);
2528 * Make sure WPA_Supplicant receives all the event
2529 * generated due to DISASSOC call to the fw to keep
2530 * the state fw and WPA_Supplicant state consistent
2535 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2536 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2537 brcmf_term_iscan(cfg_priv);
2539 if (cfg_priv->scan_request) {
2540 /* Indidate scan abort to cfg80211 layer */
2541 WL_INFO("Terminating scan in progress\n");
2542 cfg80211_scan_done(cfg_priv->scan_request, true);
2543 cfg_priv->scan_request = NULL;
2545 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2546 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2548 /* Turn off watchdog timer */
2549 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2550 WL_INFO("Enable MPC\n");
2551 brcmf_set_mpc(ndev, 1);
2560 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2562 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2565 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2569 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2574 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2577 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2581 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2584 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2587 WL_ERR("error (%d)\n", err);
2590 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2596 brcmf_update_pmklist(struct net_device *ndev,
2597 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2602 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2604 WL_CONN("No of elements %d\n", pmkid_len);
2605 for (i = 0; i < pmkid_len; i++) {
2606 WL_CONN("PMKID[%d]: %pM =\n", i,
2607 &pmk_list->pmkids.pmkid[i].BSSID);
2608 for (j = 0; j < WLAN_PMKID_LEN; j++)
2609 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2613 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2620 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2621 struct cfg80211_pmksa *pmksa)
2623 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2624 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2629 WL_TRACE("Enter\n");
2630 if (!check_sys_up(wiphy))
2633 pmkid_len = le32_to_cpu(pmkids->npmkid);
2634 for (i = 0; i < pmkid_len; i++)
2635 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2637 if (i < WL_NUM_PMKIDS_MAX) {
2638 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2639 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2640 if (i == pmkid_len) {
2642 pmkids->npmkid = cpu_to_le32(pmkid_len);
2647 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2648 pmkids->pmkid[pmkid_len].BSSID);
2649 for (i = 0; i < WLAN_PMKID_LEN; i++)
2650 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2652 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2659 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2660 struct cfg80211_pmksa *pmksa)
2662 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2663 struct pmkid_list pmkid;
2667 WL_TRACE("Enter\n");
2668 if (!check_sys_up(wiphy))
2671 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2672 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2674 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2675 &pmkid.pmkid[0].BSSID);
2676 for (i = 0; i < WLAN_PMKID_LEN; i++)
2677 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2679 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2680 for (i = 0; i < pmkid_len; i++)
2682 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2687 && (i < pmkid_len)) {
2688 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2689 sizeof(struct pmkid));
2690 for (; i < (pmkid_len - 1); i++) {
2691 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2692 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2694 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2695 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2698 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2702 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2710 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2712 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2715 WL_TRACE("Enter\n");
2716 if (!check_sys_up(wiphy))
2719 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2720 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2727 static struct cfg80211_ops wl_cfg80211_ops = {
2728 .change_virtual_intf = brcmf_cfg80211_change_iface,
2729 .scan = brcmf_cfg80211_scan,
2730 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2731 .join_ibss = brcmf_cfg80211_join_ibss,
2732 .leave_ibss = brcmf_cfg80211_leave_ibss,
2733 .get_station = brcmf_cfg80211_get_station,
2734 .set_tx_power = brcmf_cfg80211_set_tx_power,
2735 .get_tx_power = brcmf_cfg80211_get_tx_power,
2736 .add_key = brcmf_cfg80211_add_key,
2737 .del_key = brcmf_cfg80211_del_key,
2738 .get_key = brcmf_cfg80211_get_key,
2739 .set_default_key = brcmf_cfg80211_config_default_key,
2740 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2741 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2742 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2743 .connect = brcmf_cfg80211_connect,
2744 .disconnect = brcmf_cfg80211_disconnect,
2745 .suspend = brcmf_cfg80211_suspend,
2746 .resume = brcmf_cfg80211_resume,
2747 .set_pmksa = brcmf_cfg80211_set_pmksa,
2748 .del_pmksa = brcmf_cfg80211_del_pmksa,
2749 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2752 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2758 return NL80211_IFTYPE_STATION;
2760 return NL80211_IFTYPE_ADHOC;
2762 return NL80211_IFTYPE_UNSPECIFIED;
2768 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2769 struct device *ndev)
2771 struct wireless_dev *wdev;
2774 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2776 return ERR_PTR(-ENOMEM);
2779 wiphy_new(&wl_cfg80211_ops,
2780 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2782 WL_ERR("Could not allocate wiphy device\n");
2786 set_wiphy_dev(wdev->wiphy, ndev);
2787 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2788 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2789 wdev->wiphy->interface_modes =
2790 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2791 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2792 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2793 * it as 11a by default.
2794 * This will be updated with
2797 * if phy has 11n capability
2799 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2800 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2801 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2802 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2806 err = wiphy_register(wdev->wiphy);
2808 WL_ERR("Could not register wiphy device (%d)\n", err);
2809 goto wiphy_register_out;
2814 wiphy_free(wdev->wiphy);
2819 return ERR_PTR(err);
2822 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2824 struct wireless_dev *wdev = cfg_priv->wdev;
2827 WL_ERR("wdev is invalid\n");
2830 wiphy_unregister(wdev->wiphy);
2831 wiphy_free(wdev->wiphy);
2833 cfg_priv->wdev = NULL;
2836 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2837 const struct brcmf_event_msg *e)
2839 u32 event = be32_to_cpu(e->event_type);
2840 u32 status = be32_to_cpu(e->status);
2842 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2843 WL_CONN("Processing set ssid\n");
2844 cfg_priv->link_up = true;
2851 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2852 const struct brcmf_event_msg *e)
2854 u32 event = be32_to_cpu(e->event_type);
2855 u16 flags = be16_to_cpu(e->flags);
2857 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2858 WL_CONN("Processing link down\n");
2864 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2865 const struct brcmf_event_msg *e)
2867 u32 event = be32_to_cpu(e->event_type);
2868 u32 status = be32_to_cpu(e->status);
2870 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2871 WL_CONN("Processing Link %s & no network found\n",
2872 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2877 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2878 WL_CONN("Processing connecting & no network found\n");
2885 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2887 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2889 kfree(conn_info->req_ie);
2890 conn_info->req_ie = NULL;
2891 conn_info->req_ie_len = 0;
2892 kfree(conn_info->resp_ie);
2893 conn_info->resp_ie = NULL;
2894 conn_info->resp_ie_len = 0;
2897 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2899 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2900 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2901 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2906 brcmf_clear_assoc_ies(cfg_priv);
2908 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2911 WL_ERR("could not get assoc info (%d)\n", err);
2915 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2916 req_len = le32_to_cpu(assoc_info->req_len);
2917 resp_len = le32_to_cpu(assoc_info->resp_len);
2919 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2920 cfg_priv->extra_buf,
2923 WL_ERR("could not get assoc req (%d)\n", err);
2926 conn_info->req_ie_len = req_len;
2928 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2931 conn_info->req_ie_len = 0;
2932 conn_info->req_ie = NULL;
2935 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2936 cfg_priv->extra_buf,
2939 WL_ERR("could not get assoc resp (%d)\n", err);
2942 conn_info->resp_ie_len = resp_len;
2943 conn_info->resp_ie =
2944 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2947 conn_info->resp_ie_len = 0;
2948 conn_info->resp_ie = NULL;
2950 WL_CONN("req len (%d) resp len (%d)\n",
2951 conn_info->req_ie_len, conn_info->resp_ie_len);
2957 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2958 struct net_device *ndev,
2959 const struct brcmf_event_msg *e)
2961 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2962 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2963 struct brcmf_channel_info_le channel_le;
2964 struct ieee80211_channel *notify_channel;
2965 struct ieee80211_supported_band *band;
2970 WL_TRACE("Enter\n");
2972 brcmf_get_assoc_ies(cfg_priv);
2973 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2974 brcmf_update_bss_info(cfg_priv);
2976 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2977 sizeof(channel_le));
2979 target_channel = le32_to_cpu(channel_le.target_channel);
2980 WL_CONN("Roamed to channel %d\n", target_channel);
2982 if (target_channel <= CH_MAX_2G_CHANNEL)
2983 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2985 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2987 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2988 notify_channel = ieee80211_get_channel(wiphy, freq);
2990 cfg80211_roamed(ndev, notify_channel,
2991 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2992 conn_info->req_ie, conn_info->req_ie_len,
2993 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2994 WL_CONN("Report roaming result\n");
2996 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3002 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3003 struct net_device *ndev, const struct brcmf_event_msg *e,
3006 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3009 WL_TRACE("Enter\n");
3011 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3013 brcmf_get_assoc_ies(cfg_priv);
3014 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3016 brcmf_update_bss_info(cfg_priv);
3018 cfg80211_connect_result(ndev,
3019 (u8 *)brcmf_read_prof(cfg_priv,
3022 conn_info->req_ie_len,
3024 conn_info->resp_ie_len,
3025 completed ? WLAN_STATUS_SUCCESS :
3026 WLAN_STATUS_AUTH_TIMEOUT,
3029 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3030 WL_CONN("Report connect result - connection %s\n",
3031 completed ? "succeeded" : "failed");
3038 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3039 struct net_device *ndev,
3040 const struct brcmf_event_msg *e, void *data)
3044 if (brcmf_is_linkup(cfg_priv, e)) {
3045 WL_CONN("Linkup\n");
3046 if (brcmf_is_ibssmode(cfg_priv)) {
3047 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3049 wl_inform_ibss(cfg_priv, ndev, e->addr);
3050 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3051 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3052 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3054 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3055 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3056 WL_CONN("Linkdown\n");
3057 if (brcmf_is_ibssmode(cfg_priv)) {
3058 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3059 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3061 brcmf_link_down(cfg_priv);
3063 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3064 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3065 &cfg_priv->status)) {
3066 cfg80211_disconnected(ndev, 0, NULL, 0,
3068 brcmf_link_down(cfg_priv);
3071 brcmf_init_prof(cfg_priv->profile);
3072 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3073 if (brcmf_is_ibssmode(cfg_priv))
3074 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3076 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3083 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3084 struct net_device *ndev,
3085 const struct brcmf_event_msg *e, void *data)
3088 u32 event = be32_to_cpu(e->event_type);
3089 u32 status = be32_to_cpu(e->status);
3091 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3092 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3093 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3095 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3102 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3103 struct net_device *ndev,
3104 const struct brcmf_event_msg *e, void *data)
3106 u16 flags = be16_to_cpu(e->flags);
3107 enum nl80211_key_type key_type;
3109 if (flags & BRCMF_EVENT_MSG_GROUP)
3110 key_type = NL80211_KEYTYPE_GROUP;
3112 key_type = NL80211_KEYTYPE_PAIRWISE;
3114 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3121 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3122 struct net_device *ndev,
3123 const struct brcmf_event_msg *e, void *data)
3125 struct brcmf_channel_info_le channel_inform_le;
3126 struct brcmf_scan_results_le *bss_list_le;
3127 u32 len = WL_SCAN_BUF_MAX;
3129 bool scan_abort = false;
3132 WL_TRACE("Enter\n");
3134 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3136 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3139 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3140 WL_ERR("Scan complete while device not scanning\n");
3146 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3147 sizeof(channel_inform_le));
3149 WL_ERR("scan busy (%d)\n", err);
3153 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3155 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3156 cfg_priv->bss_list = cfg_priv->scan_results;
3157 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3159 memset(cfg_priv->scan_results, 0, len);
3160 bss_list_le->buflen = cpu_to_le32(len);
3161 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3162 cfg_priv->scan_results, len);
3164 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3169 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3170 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3171 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3173 err = brcmf_inform_bss(cfg_priv);
3180 if (cfg_priv->scan_request) {
3181 WL_SCAN("calling cfg80211_scan_done\n");
3182 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3183 brcmf_set_mpc(ndev, 1);
3184 cfg_priv->scan_request = NULL;
3192 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3194 conf->mode = (u32)-1;
3195 conf->frag_threshold = (u32)-1;
3196 conf->rts_threshold = (u32)-1;
3197 conf->retry_short = (u32)-1;
3198 conf->retry_long = (u32)-1;
3199 conf->tx_power = -1;
3202 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3204 memset(el, 0, sizeof(*el));
3205 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3206 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3207 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3208 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3209 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3212 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3214 kfree(cfg_priv->scan_results);
3215 cfg_priv->scan_results = NULL;
3216 kfree(cfg_priv->bss_info);
3217 cfg_priv->bss_info = NULL;
3218 kfree(cfg_priv->conf);
3219 cfg_priv->conf = NULL;
3220 kfree(cfg_priv->profile);
3221 cfg_priv->profile = NULL;
3222 kfree(cfg_priv->scan_req_int);
3223 cfg_priv->scan_req_int = NULL;
3224 kfree(cfg_priv->dcmd_buf);
3225 cfg_priv->dcmd_buf = NULL;
3226 kfree(cfg_priv->extra_buf);
3227 cfg_priv->extra_buf = NULL;
3228 kfree(cfg_priv->iscan);
3229 cfg_priv->iscan = NULL;
3230 kfree(cfg_priv->pmk_list);
3231 cfg_priv->pmk_list = NULL;
3234 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3236 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3237 if (!cfg_priv->scan_results)
3238 goto init_priv_mem_out;
3239 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3240 if (!cfg_priv->conf)
3241 goto init_priv_mem_out;
3242 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3243 if (!cfg_priv->profile)
3244 goto init_priv_mem_out;
3245 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3246 if (!cfg_priv->bss_info)
3247 goto init_priv_mem_out;
3248 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3250 if (!cfg_priv->scan_req_int)
3251 goto init_priv_mem_out;
3252 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3253 if (!cfg_priv->dcmd_buf)
3254 goto init_priv_mem_out;
3255 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3256 if (!cfg_priv->extra_buf)
3257 goto init_priv_mem_out;
3258 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3259 if (!cfg_priv->iscan)
3260 goto init_priv_mem_out;
3261 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3262 if (!cfg_priv->pmk_list)
3263 goto init_priv_mem_out;
3268 brcmf_deinit_priv_mem(cfg_priv);
3274 * retrieve first queued event from head
3277 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3278 struct brcmf_cfg80211_priv *cfg_priv)
3280 struct brcmf_cfg80211_event_q *e = NULL;
3282 spin_lock_irq(&cfg_priv->evt_q_lock);
3283 if (!list_empty(&cfg_priv->evt_q_list)) {
3284 e = list_first_entry(&cfg_priv->evt_q_list,
3285 struct brcmf_cfg80211_event_q, evt_q_list);
3286 list_del(&e->evt_q_list);
3288 spin_unlock_irq(&cfg_priv->evt_q_lock);
3294 * push event to tail of the queue
3296 * remark: this function may not sleep as it is called in atomic context.
3300 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3301 const struct brcmf_event_msg *msg)
3303 struct brcmf_cfg80211_event_q *e;
3307 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
3312 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3314 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3315 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3316 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3321 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3326 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3328 struct brcmf_cfg80211_priv *cfg_priv =
3329 container_of(work, struct brcmf_cfg80211_priv,
3331 struct brcmf_cfg80211_event_q *e;
3333 e = brcmf_deq_event(cfg_priv);
3335 WL_ERR("event queue empty...\n");
3340 WL_INFO("event type (%d)\n", e->etype);
3341 if (cfg_priv->el.handler[e->etype])
3342 cfg_priv->el.handler[e->etype](cfg_priv,
3343 cfg_to_ndev(cfg_priv),
3344 &e->emsg, e->edata);
3346 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3348 } while ((e = brcmf_deq_event(cfg_priv)));
3352 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3354 spin_lock_init(&cfg_priv->evt_q_lock);
3355 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3358 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3360 struct brcmf_cfg80211_event_q *e;
3362 spin_lock_irq(&cfg_priv->evt_q_lock);
3363 while (!list_empty(&cfg_priv->evt_q_list)) {
3364 e = list_first_entry(&cfg_priv->evt_q_list,
3365 struct brcmf_cfg80211_event_q, evt_q_list);
3366 list_del(&e->evt_q_list);
3369 spin_unlock_irq(&cfg_priv->evt_q_lock);
3372 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3376 cfg_priv->scan_request = NULL;
3377 cfg_priv->pwr_save = true;
3378 cfg_priv->iscan_on = true; /* iscan on & off switch.
3379 we enable iscan per default */
3380 cfg_priv->roam_on = true; /* roam on & off switch.
3381 we enable roam per default */
3383 cfg_priv->iscan_kickstart = false;
3384 cfg_priv->active_scan = true; /* we do active scan for
3385 specific scan per default */
3386 cfg_priv->dongle_up = false; /* dongle is not up yet */
3387 brcmf_init_eq(cfg_priv);
3388 err = brcmf_init_priv_mem(cfg_priv);
3391 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3392 brcmf_init_eloop_handler(&cfg_priv->el);
3393 mutex_init(&cfg_priv->usr_sync);
3394 err = brcmf_init_iscan(cfg_priv);
3397 brcmf_init_conf(cfg_priv->conf);
3398 brcmf_init_prof(cfg_priv->profile);
3399 brcmf_link_down(cfg_priv);
3404 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3406 cancel_work_sync(&cfg_priv->event_work);
3407 cfg_priv->dongle_up = false; /* dongle down */
3408 brcmf_flush_eq(cfg_priv);
3409 brcmf_link_down(cfg_priv);
3410 brcmf_term_iscan(cfg_priv);
3411 brcmf_deinit_priv_mem(cfg_priv);
3414 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3415 struct device *busdev,
3418 struct wireless_dev *wdev;
3419 struct brcmf_cfg80211_priv *cfg_priv;
3420 struct brcmf_cfg80211_iface *ci;
3421 struct brcmf_cfg80211_dev *cfg_dev;
3425 WL_ERR("ndev is invalid\n");
3428 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3432 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3438 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3439 cfg_priv = wdev_to_cfg(wdev);
3440 cfg_priv->wdev = wdev;
3441 cfg_priv->pub = data;
3442 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3443 ci->cfg_priv = cfg_priv;
3444 ndev->ieee80211_ptr = wdev;
3445 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3446 wdev->netdev = ndev;
3447 err = wl_init_priv(cfg_priv);
3449 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3450 goto cfg80211_attach_out;
3452 brcmf_set_drvdata(cfg_dev, ci);
3456 cfg80211_attach_out:
3457 brcmf_free_wdev(cfg_priv);
3462 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3464 struct brcmf_cfg80211_priv *cfg_priv;
3466 cfg_priv = brcmf_priv_get(cfg_dev);
3468 wl_deinit_priv(cfg_priv);
3469 brcmf_free_wdev(cfg_priv);
3470 brcmf_set_drvdata(cfg_dev, NULL);
3475 brcmf_cfg80211_event(struct net_device *ndev,
3476 const struct brcmf_event_msg *e, void *data)
3478 u32 event_type = be32_to_cpu(e->event_type);
3479 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3481 if (!brcmf_enq_event(cfg_priv, event_type, e))
3482 schedule_work(&cfg_priv->event_work);
3485 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3491 case NL80211_IFTYPE_MONITOR:
3492 case NL80211_IFTYPE_WDS:
3493 WL_ERR("type (%d) : currently we do not support this mode\n",
3497 case NL80211_IFTYPE_ADHOC:
3500 case NL80211_IFTYPE_STATION:
3505 WL_ERR("invalid type (%d)\n", iftype);
3508 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3510 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3517 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3519 /* Room for "event_msgs" + '\0' + bitvec */
3520 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3521 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3524 WL_TRACE("Enter\n");
3526 /* Setup event_msgs */
3527 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3528 iovbuf, sizeof(iovbuf));
3529 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3531 WL_ERR("Get event_msgs error (%d)\n", err);
3532 goto dongle_eventmsg_out;
3534 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3536 setbit(eventmask, BRCMF_E_SET_SSID);
3537 setbit(eventmask, BRCMF_E_ROAM);
3538 setbit(eventmask, BRCMF_E_PRUNE);
3539 setbit(eventmask, BRCMF_E_AUTH);
3540 setbit(eventmask, BRCMF_E_REASSOC);
3541 setbit(eventmask, BRCMF_E_REASSOC_IND);
3542 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3543 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3544 setbit(eventmask, BRCMF_E_DISASSOC);
3545 setbit(eventmask, BRCMF_E_JOIN);
3546 setbit(eventmask, BRCMF_E_ASSOC_IND);
3547 setbit(eventmask, BRCMF_E_PSK_SUP);
3548 setbit(eventmask, BRCMF_E_LINK);
3549 setbit(eventmask, BRCMF_E_NDIS_LINK);
3550 setbit(eventmask, BRCMF_E_MIC_ERROR);
3551 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3552 setbit(eventmask, BRCMF_E_TXFAIL);
3553 setbit(eventmask, BRCMF_E_JOIN_START);
3554 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3556 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3557 iovbuf, sizeof(iovbuf));
3558 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3560 WL_ERR("Set event_msgs error (%d)\n", err);
3561 goto dongle_eventmsg_out;
3564 dongle_eventmsg_out:
3570 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3574 __le32 roamtrigger[2];
3575 __le32 roam_delta[2];
3580 * Setup timeout if Beacons are lost and roam is
3581 * off to report link down
3584 bcn_to_le = cpu_to_le32(bcn_timeout);
3585 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3586 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3587 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3588 iovbuf, sizeof(iovbuf));
3590 WL_ERR("bcn_timeout error (%d)\n", err);
3591 goto dongle_rom_out;
3596 * Enable/Disable built-in roaming to allow supplicant
3597 * to take care of roaming
3599 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3600 roamvar_le = cpu_to_le32(roamvar);
3601 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3602 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3603 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3605 WL_ERR("roam_off error (%d)\n", err);
3606 goto dongle_rom_out;
3609 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3610 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3611 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3612 (void *)roamtrigger, sizeof(roamtrigger));
3614 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3615 goto dongle_rom_out;
3618 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3619 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3620 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3621 (void *)roam_delta, sizeof(roam_delta));
3623 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3624 goto dongle_rom_out;
3632 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3633 s32 scan_unassoc_time, s32 scan_passive_time)
3636 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3637 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3638 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3640 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3641 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3643 if (err == -EOPNOTSUPP)
3644 WL_INFO("Scan assoc time is not supported\n");
3646 WL_ERR("Scan assoc time error (%d)\n", err);
3647 goto dongle_scantime_out;
3649 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3650 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3652 if (err == -EOPNOTSUPP)
3653 WL_INFO("Scan unassoc time is not supported\n");
3655 WL_ERR("Scan unassoc time error (%d)\n", err);
3656 goto dongle_scantime_out;
3659 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3660 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3662 if (err == -EOPNOTSUPP)
3663 WL_INFO("Scan passive time is not supported\n");
3665 WL_ERR("Scan passive time error (%d)\n", err);
3666 goto dongle_scantime_out;
3669 dongle_scantime_out:
3673 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3675 struct wiphy *wiphy;
3680 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3681 &phy_list, sizeof(phy_list));
3683 WL_ERR("error (%d)\n", err);
3687 phy = ((char *)&phy_list)[1];
3688 WL_INFO("%c phy\n", phy);
3689 if (phy == 'n' || phy == 'a') {
3690 wiphy = cfg_to_wiphy(cfg_priv);
3691 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3697 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3699 return wl_update_wiphybands(cfg_priv);
3702 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3704 struct net_device *ndev;
3705 struct wireless_dev *wdev;
3709 if (cfg_priv->dongle_up)
3712 ndev = cfg_to_ndev(cfg_priv);
3713 wdev = ndev->ieee80211_ptr;
3715 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3716 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3718 err = brcmf_dongle_eventmsg(ndev);
3720 goto default_conf_out;
3722 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3723 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3725 goto default_conf_out;
3726 WL_INFO("power save set to %s\n",
3727 (power_mode ? "enabled" : "disabled"));
3729 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3732 goto default_conf_out;
3733 err = brcmf_dongle_mode(ndev, wdev->iftype);
3734 if (err && err != -EINPROGRESS)
3735 goto default_conf_out;
3736 err = brcmf_dongle_probecap(cfg_priv);
3738 goto default_conf_out;
3740 /* -EINPROGRESS: Call commit handler */
3744 cfg_priv->dongle_up = true;
3750 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3752 char buf[10+IFNAMSIZ];
3756 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3757 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3758 cfg_to_wiphy(cfg_priv)->debugfsdir);
3760 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3761 (u16 *)&cfg_priv->profile->beacon_interval);
3767 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3768 (u8 *)&cfg_priv->profile->dtim_period);
3778 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3780 debugfs_remove_recursive(cfg_priv->debugfsdir);
3781 cfg_priv->debugfsdir = NULL;
3784 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3788 set_bit(WL_STATUS_READY, &cfg_priv->status);
3790 brcmf_debugfs_add_netdev_params(cfg_priv);
3792 err = brcmf_config_dongle(cfg_priv);
3796 brcmf_invoke_iscan(cfg_priv);
3801 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3804 * While going down, if associated with AP disassociate
3805 * from AP to save power
3807 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3808 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3809 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3810 WL_INFO("Disassociating from AP");
3811 brcmf_link_down(cfg_priv);
3813 /* Make sure WPA_Supplicant receives all the event
3814 generated due to DISASSOC call to the fw to keep
3815 the state fw and WPA_Supplicant state consistent
3820 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3821 brcmf_term_iscan(cfg_priv);
3822 if (cfg_priv->scan_request) {
3823 cfg80211_scan_done(cfg_priv->scan_request, true);
3824 /* May need to perform this to cover rmmod */
3825 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3826 cfg_priv->scan_request = NULL;
3828 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3829 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3830 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3832 brcmf_debugfs_remove_netdev(cfg_priv);
3837 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3839 struct brcmf_cfg80211_priv *cfg_priv;
3842 cfg_priv = brcmf_priv_get(cfg_dev);
3843 mutex_lock(&cfg_priv->usr_sync);
3844 err = __brcmf_cfg80211_up(cfg_priv);
3845 mutex_unlock(&cfg_priv->usr_sync);
3850 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3852 struct brcmf_cfg80211_priv *cfg_priv;
3855 cfg_priv = brcmf_priv_get(cfg_dev);
3856 mutex_lock(&cfg_priv->usr_sync);
3857 err = __brcmf_cfg80211_down(cfg_priv);
3858 mutex_unlock(&cfg_priv->usr_sync);
3863 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3866 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3869 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3870 WL_ERR("ei crosses buffer boundary\n");
3873 ie->buf[ie->offset] = t;
3874 ie->buf[ie->offset + 1] = l;
3875 memcpy(&ie->buf[ie->offset + 2], v, l);
3876 ie->offset += l + 2;