2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 #include <net/netlink.h>
33 #include <brcmu_utils.h>
35 #include <brcmu_wifi.h>
37 #include "wl_cfg80211.h"
39 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
40 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
42 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
44 static u32 brcmf_dbg_level = WL_DBG_ERR;
46 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
48 dev->driver_data = data;
51 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
56 data = dev->driver_data;
61 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
63 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
67 static bool check_sys_up(struct wiphy *wiphy)
69 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
70 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
71 WL_INFO("device is not ready : status (%d)\n",
72 (int)cfg_priv->status);
78 #define CHAN2G(_channel, _freq, _flags) { \
79 .band = IEEE80211_BAND_2GHZ, \
80 .center_freq = (_freq), \
81 .hw_value = (_channel), \
83 .max_antenna_gain = 0, \
87 #define CHAN5G(_channel, _flags) { \
88 .band = IEEE80211_BAND_5GHZ, \
89 .center_freq = 5000 + (5 * (_channel)), \
90 .hw_value = (_channel), \
92 .max_antenna_gain = 0, \
96 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
97 #define RATETAB_ENT(_rateid, _flags) \
99 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
100 .hw_value = (_rateid), \
104 static struct ieee80211_rate __wl_rates[] = {
105 RATETAB_ENT(BRCM_RATE_1M, 0),
106 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
107 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
108 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
109 RATETAB_ENT(BRCM_RATE_6M, 0),
110 RATETAB_ENT(BRCM_RATE_9M, 0),
111 RATETAB_ENT(BRCM_RATE_12M, 0),
112 RATETAB_ENT(BRCM_RATE_18M, 0),
113 RATETAB_ENT(BRCM_RATE_24M, 0),
114 RATETAB_ENT(BRCM_RATE_36M, 0),
115 RATETAB_ENT(BRCM_RATE_48M, 0),
116 RATETAB_ENT(BRCM_RATE_54M, 0),
119 #define wl_a_rates (__wl_rates + 4)
120 #define wl_a_rates_size 8
121 #define wl_g_rates (__wl_rates + 0)
122 #define wl_g_rates_size 12
124 static struct ieee80211_channel __wl_2ghz_channels[] = {
141 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
142 CHAN5G(34, 0), CHAN5G(36, 0),
143 CHAN5G(38, 0), CHAN5G(40, 0),
144 CHAN5G(42, 0), CHAN5G(44, 0),
145 CHAN5G(46, 0), CHAN5G(48, 0),
146 CHAN5G(52, 0), CHAN5G(56, 0),
147 CHAN5G(60, 0), CHAN5G(64, 0),
148 CHAN5G(100, 0), CHAN5G(104, 0),
149 CHAN5G(108, 0), CHAN5G(112, 0),
150 CHAN5G(116, 0), CHAN5G(120, 0),
151 CHAN5G(124, 0), CHAN5G(128, 0),
152 CHAN5G(132, 0), CHAN5G(136, 0),
153 CHAN5G(140, 0), CHAN5G(149, 0),
154 CHAN5G(153, 0), CHAN5G(157, 0),
155 CHAN5G(161, 0), CHAN5G(165, 0),
156 CHAN5G(184, 0), CHAN5G(188, 0),
157 CHAN5G(192, 0), CHAN5G(196, 0),
158 CHAN5G(200, 0), CHAN5G(204, 0),
159 CHAN5G(208, 0), CHAN5G(212, 0),
163 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
164 CHAN5G(32, 0), CHAN5G(34, 0),
165 CHAN5G(36, 0), CHAN5G(38, 0),
166 CHAN5G(40, 0), CHAN5G(42, 0),
167 CHAN5G(44, 0), CHAN5G(46, 0),
168 CHAN5G(48, 0), CHAN5G(50, 0),
169 CHAN5G(52, 0), CHAN5G(54, 0),
170 CHAN5G(56, 0), CHAN5G(58, 0),
171 CHAN5G(60, 0), CHAN5G(62, 0),
172 CHAN5G(64, 0), CHAN5G(66, 0),
173 CHAN5G(68, 0), CHAN5G(70, 0),
174 CHAN5G(72, 0), CHAN5G(74, 0),
175 CHAN5G(76, 0), CHAN5G(78, 0),
176 CHAN5G(80, 0), CHAN5G(82, 0),
177 CHAN5G(84, 0), CHAN5G(86, 0),
178 CHAN5G(88, 0), CHAN5G(90, 0),
179 CHAN5G(92, 0), CHAN5G(94, 0),
180 CHAN5G(96, 0), CHAN5G(98, 0),
181 CHAN5G(100, 0), CHAN5G(102, 0),
182 CHAN5G(104, 0), CHAN5G(106, 0),
183 CHAN5G(108, 0), CHAN5G(110, 0),
184 CHAN5G(112, 0), CHAN5G(114, 0),
185 CHAN5G(116, 0), CHAN5G(118, 0),
186 CHAN5G(120, 0), CHAN5G(122, 0),
187 CHAN5G(124, 0), CHAN5G(126, 0),
188 CHAN5G(128, 0), CHAN5G(130, 0),
189 CHAN5G(132, 0), CHAN5G(134, 0),
190 CHAN5G(136, 0), CHAN5G(138, 0),
191 CHAN5G(140, 0), CHAN5G(142, 0),
192 CHAN5G(144, 0), CHAN5G(145, 0),
193 CHAN5G(146, 0), CHAN5G(147, 0),
194 CHAN5G(148, 0), CHAN5G(149, 0),
195 CHAN5G(150, 0), CHAN5G(151, 0),
196 CHAN5G(152, 0), CHAN5G(153, 0),
197 CHAN5G(154, 0), CHAN5G(155, 0),
198 CHAN5G(156, 0), CHAN5G(157, 0),
199 CHAN5G(158, 0), CHAN5G(159, 0),
200 CHAN5G(160, 0), CHAN5G(161, 0),
201 CHAN5G(162, 0), CHAN5G(163, 0),
202 CHAN5G(164, 0), CHAN5G(165, 0),
203 CHAN5G(166, 0), CHAN5G(168, 0),
204 CHAN5G(170, 0), CHAN5G(172, 0),
205 CHAN5G(174, 0), CHAN5G(176, 0),
206 CHAN5G(178, 0), CHAN5G(180, 0),
207 CHAN5G(182, 0), CHAN5G(184, 0),
208 CHAN5G(186, 0), CHAN5G(188, 0),
209 CHAN5G(190, 0), CHAN5G(192, 0),
210 CHAN5G(194, 0), CHAN5G(196, 0),
211 CHAN5G(198, 0), CHAN5G(200, 0),
212 CHAN5G(202, 0), CHAN5G(204, 0),
213 CHAN5G(206, 0), CHAN5G(208, 0),
214 CHAN5G(210, 0), CHAN5G(212, 0),
215 CHAN5G(214, 0), CHAN5G(216, 0),
216 CHAN5G(218, 0), CHAN5G(220, 0),
217 CHAN5G(222, 0), CHAN5G(224, 0),
218 CHAN5G(226, 0), CHAN5G(228, 0),
221 static struct ieee80211_supported_band __wl_band_2ghz = {
222 .band = IEEE80211_BAND_2GHZ,
223 .channels = __wl_2ghz_channels,
224 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
225 .bitrates = wl_g_rates,
226 .n_bitrates = wl_g_rates_size,
229 static struct ieee80211_supported_band __wl_band_5ghz_a = {
230 .band = IEEE80211_BAND_5GHZ,
231 .channels = __wl_5ghz_a_channels,
232 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
233 .bitrates = wl_a_rates,
234 .n_bitrates = wl_a_rates_size,
237 static struct ieee80211_supported_band __wl_band_5ghz_n = {
238 .band = IEEE80211_BAND_5GHZ,
239 .channels = __wl_5ghz_n_channels,
240 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
241 .bitrates = wl_a_rates,
242 .n_bitrates = wl_a_rates_size,
245 static const u32 __wl_cipher_suites[] = {
246 WLAN_CIPHER_SUITE_WEP40,
247 WLAN_CIPHER_SUITE_WEP104,
248 WLAN_CIPHER_SUITE_TKIP,
249 WLAN_CIPHER_SUITE_CCMP,
250 WLAN_CIPHER_SUITE_AES_CMAC,
253 /* tag_ID/length/value_buffer tuple */
260 /* Quarter dBm units to mW
261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
262 * Table is offset so the last entry is largest mW value that fits in
266 #define QDBM_OFFSET 153 /* Offset for first entry */
267 #define QDBM_TABLE_LEN 40 /* Table size */
269 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
270 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
272 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
274 /* Largest mW value that will round down to the last table entry,
275 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
276 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
277 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
279 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
281 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
282 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
283 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
284 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
285 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
286 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
287 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
290 static u16 brcmf_qdbm_to_mw(u8 qdbm)
293 int idx = qdbm - QDBM_OFFSET;
295 if (idx >= QDBM_TABLE_LEN)
296 /* clamp to max u16 mW value */
299 /* scale the qdBm index up to the range of the table 0-40
300 * where an offset of 40 qdBm equals a factor of 10 mW.
307 /* return the mW value scaled down to the correct factor of 10,
308 * adding in factor/2 to get proper rounding.
310 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
313 static u8 brcmf_mw_to_qdbm(u16 mw)
320 /* handle boundary case */
324 offset = QDBM_OFFSET;
326 /* move mw into the range of the table */
327 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
332 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
333 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
334 nqdBm_to_mW_map[qdbm]) / 2;
335 if (mw_uint < boundary)
344 /* function for reading/writing a single u32 from/to the dongle */
346 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
349 __le32 par_le = cpu_to_le32(*par);
351 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
352 *par = le32_to_cpu(par_le);
357 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
358 struct brcmf_wsec_key_le *key_le)
360 key_le->index = cpu_to_le32(key->index);
361 key_le->len = cpu_to_le32(key->len);
362 key_le->algo = cpu_to_le32(key->algo);
363 key_le->flags = cpu_to_le32(key->flags);
364 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
365 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
366 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
367 memcpy(key_le->data, key->data, sizeof(key->data));
368 memcpy(key_le->ea, key->ea, sizeof(key->ea));
371 static int send_key_to_dongle(struct net_device *ndev,
372 struct brcmf_wsec_key *key)
375 struct brcmf_wsec_key_le key_le;
377 convert_key_from_CPU(key, &key_le);
378 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
380 WL_ERR("WLC_SET_KEY error (%d)\n", err);
385 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
386 enum nl80211_iftype type, u32 *flags,
387 struct vif_params *params)
389 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
390 struct wireless_dev *wdev;
395 if (!check_sys_up(wiphy))
399 case NL80211_IFTYPE_MONITOR:
400 case NL80211_IFTYPE_WDS:
401 WL_ERR("type (%d) : currently we do not support this type\n",
404 case NL80211_IFTYPE_ADHOC:
405 cfg_priv->conf->mode = WL_MODE_IBSS;
408 case NL80211_IFTYPE_STATION:
409 cfg_priv->conf->mode = WL_MODE_BSS;
417 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
419 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
422 wdev = ndev->ieee80211_ptr;
426 WL_INFO("IF Type = %s\n",
427 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
435 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
437 s8 buf[BRCMF_DCMD_SMLEN];
442 val_le = cpu_to_le32(val);
443 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
447 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
449 WL_ERR("error (%d)\n", err);
455 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
458 s8 buf[BRCMF_DCMD_SMLEN];
466 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
469 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
471 WL_ERR("error (%d)\n", err);
473 *retval = le32_to_cpu(var.val);
478 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
483 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
484 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
486 WL_ERR("fail to set mpc\n");
489 WL_INFO("MPC : %d\n", mpc);
493 static void brcmf_iscan_prep(struct brcmf_scan_params_le *params_le,
494 struct brcmf_ssid *ssid)
496 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
497 params_le->bss_type = DOT11_BSSTYPE_ANY;
498 params_le->scan_type = 0;
499 params_le->channel_num = 0;
500 params_le->nprobes = cpu_to_le32(-1);
501 params_le->active_time = cpu_to_le32(-1);
502 params_le->passive_time = cpu_to_le32(-1);
503 params_le->home_time = cpu_to_le32(-1);
504 if (ssid && ssid->SSID_len)
505 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
509 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
510 s32 paramlen, void *bufptr, s32 buflen)
514 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
517 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
521 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
522 s32 paramlen, void *bufptr, s32 buflen)
526 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
529 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
533 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
534 struct brcmf_ssid *ssid, u16 action)
536 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
537 offsetof(struct brcmf_iscan_params_le, params_le);
538 struct brcmf_iscan_params_le *params;
541 if (ssid && ssid->SSID_len)
542 params_size += sizeof(struct brcmf_ssid);
543 params = kzalloc(params_size, GFP_KERNEL);
546 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
548 brcmf_iscan_prep(¶ms->params_le, ssid);
550 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
551 params->action = cpu_to_le16(action);
552 params->scan_duration = cpu_to_le16(0);
554 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
555 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
558 WL_INFO("system busy : iscan canceled\n");
560 WL_ERR("error (%d)\n", err);
567 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
569 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
570 struct net_device *ndev = cfg_to_ndev(cfg_priv);
571 struct brcmf_ssid ssid;
575 /* Broadcast scan by default */
576 memset(&ssid, 0, sizeof(ssid));
578 iscan->state = WL_ISCAN_STATE_SCANING;
580 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
581 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
582 &passive_scan, sizeof(passive_scan));
584 WL_ERR("error (%d)\n", err);
587 brcmf_set_mpc(ndev, 0);
588 cfg_priv->iscan_kickstart = true;
589 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
591 brcmf_set_mpc(ndev, 1);
592 cfg_priv->iscan_kickstart = false;
595 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
601 brcmf_cfg80211_iscan(struct wiphy *wiphy, struct net_device *ndev,
602 struct cfg80211_scan_request *request,
603 struct cfg80211_ssid *this_ssid)
605 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
606 struct cfg80211_ssid *ssids;
607 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
614 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
615 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
618 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
619 WL_ERR("Scanning being aborted : status (%lu)\n",
623 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
624 WL_ERR("Connecting : status (%lu)\n",
633 ssids = request->ssids;
634 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
638 /* we don't do iscan in ibss */
642 cfg_priv->scan_request = request;
643 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
645 err = brcmf_do_iscan(cfg_priv);
651 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
652 ssids->ssid, ssids->ssid_len);
653 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
654 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
655 sr->ssid_le.SSID_len = cpu_to_le32(0);
657 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
658 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
661 WL_SCAN("Broadcast scan\n");
664 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
665 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
666 &passive_scan, sizeof(passive_scan));
668 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
671 brcmf_set_mpc(ndev, 0);
672 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
673 sizeof(sr->ssid_le));
676 WL_INFO("system busy : scan for \"%s\" "
677 "canceled\n", sr->ssid_le.SSID);
679 WL_ERR("WLC_SCAN error (%d)\n", err);
681 brcmf_set_mpc(ndev, 1);
689 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
690 cfg_priv->scan_request = NULL;
694 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
695 struct cfg80211_scan_request *request)
703 struct ieee80211_channel *req_channel;
705 struct brcmf_ssid_le ssid_le;
707 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
708 params_le->bss_type = DOT11_BSSTYPE_ANY;
709 params_le->scan_type = 0;
710 params_le->channel_num = 0;
711 params_le->nprobes = cpu_to_le32(-1);
712 params_le->active_time = cpu_to_le32(-1);
713 params_le->passive_time = cpu_to_le32(-1);
714 params_le->home_time = cpu_to_le32(-1);
715 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
717 /* if request is null exit so it will be all channel broadcast scan */
721 n_ssids = request->n_ssids;
722 n_channels = request->n_channels;
723 /* Copy channel array if applicable */
724 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels);
725 if (n_channels > 0) {
726 for (i = 0; i < n_channels; i++) {
728 req_channel = request->channels[i];
729 channel = ieee80211_frequency_to_channel(
730 req_channel->center_freq);
731 if (req_channel->band == IEEE80211_BAND_2GHZ)
732 chanspec |= WL_CHANSPEC_BAND_2G;
734 chanspec |= WL_CHANSPEC_BAND_5G;
736 if (req_channel->flags & IEEE80211_CHAN_NO_HT40) {
737 chanspec |= WL_CHANSPEC_BW_20;
738 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
740 chanspec |= WL_CHANSPEC_BW_40;
741 if (req_channel->flags &
742 IEEE80211_CHAN_NO_HT40PLUS)
743 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
745 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
748 chanspec |= (channel & WL_CHANSPEC_CHAN_MASK);
749 WL_SCAN("Chan : %d, Channel spec: %x\n",
751 params_le->channel_list[i] = cpu_to_le16(chanspec);
754 WL_SCAN("Scanning all channels\n");
756 /* Copy ssid array if applicable */
757 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids);
759 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
760 n_channels * sizeof(u16);
761 offset = roundup(offset, sizeof(u32));
762 ptr = (char *)params_le + offset;
763 for (i = 0; i < n_ssids; i++) {
764 memset(&ssid_le, 0, sizeof(ssid_le));
766 cpu_to_le32(request->ssids[i].ssid_len);
767 memcpy(ssid_le.SSID, request->ssids[i].ssid,
768 request->ssids[i].ssid_len);
769 if (!ssid_le.SSID_len)
770 WL_SCAN("%d: Broadcast scan\n", i);
772 WL_SCAN("%d: scan for %s size =%d\n", i,
773 ssid_le.SSID, ssid_le.SSID_len);
774 memcpy(ptr, &ssid_le, sizeof(ssid_le));
775 ptr += sizeof(ssid_le);
778 WL_SCAN("Broadcast scan %p\n", request->ssids);
779 if ((request->ssids) && request->ssids->ssid_len) {
780 WL_SCAN("SSID %s len=%d\n", params_le->ssid_le.SSID,
781 request->ssids->ssid_len);
782 params_le->ssid_le.SSID_len =
783 cpu_to_le32(request->ssids->ssid_len);
784 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
785 request->ssids->ssid_len);
788 /* Adding mask to channel numbers */
789 params_le->channel_num =
790 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
791 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
795 brcmf_notify_escan_complete(struct brcmf_cfg80211_priv *cfg_priv,
796 struct net_device *ndev,
797 bool aborted, bool fw_abort)
799 struct brcmf_scan_params_le params_le;
800 struct cfg80211_scan_request *scan_request;
805 /* clear scan request, because the FW abort can cause a second call */
806 /* to this functon and might cause a double cfg80211_scan_done */
807 scan_request = cfg_priv->scan_request;
808 cfg_priv->scan_request = NULL;
810 if (timer_pending(&cfg_priv->escan_timeout))
811 del_timer_sync(&cfg_priv->escan_timeout);
814 /* Do a scan abort to stop the driver's scan engine */
815 WL_SCAN("ABORT scan in firmware\n");
816 memset(¶ms_le, 0, sizeof(params_le));
817 memcpy(params_le.bssid, ether_bcast, ETH_ALEN);
818 params_le.bss_type = DOT11_BSSTYPE_ANY;
819 params_le.scan_type = 0;
820 params_le.channel_num = cpu_to_le32(1);
821 params_le.nprobes = cpu_to_le32(1);
822 params_le.active_time = cpu_to_le32(-1);
823 params_le.passive_time = cpu_to_le32(-1);
824 params_le.home_time = cpu_to_le32(-1);
825 /* Scan is aborted by setting channel_list[0] to -1 */
826 params_le.channel_list[0] = cpu_to_le16(-1);
827 /* E-Scan (or anyother type) can be aborted by SCAN */
828 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, ¶ms_le,
831 WL_ERR("Scan abort failed\n");
834 WL_SCAN("ESCAN Completed scan: %s\n",
835 aborted ? "Aborted" : "Done");
836 cfg80211_scan_done(scan_request, aborted);
837 brcmf_set_mpc(ndev, 1);
839 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
840 WL_ERR("Scan complete while device not scanning\n");
848 brcmf_run_escan(struct brcmf_cfg80211_priv *cfg_priv, struct net_device *ndev,
849 struct cfg80211_scan_request *request, u16 action)
851 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
852 offsetof(struct brcmf_escan_params_le, params_le);
853 struct brcmf_escan_params_le *params;
856 WL_SCAN("E-SCAN START\n");
858 if (request != NULL) {
859 /* Allocate space for populating ssids in struct */
860 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
862 /* Allocate space for populating ssids in struct */
863 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
866 params = kzalloc(params_size, GFP_KERNEL);
871 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
872 brcmf_escan_prep(¶ms->params_le, request);
873 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
874 params->action = cpu_to_le16(action);
875 params->sync_id = cpu_to_le16(0x1234);
877 err = brcmf_dev_iovar_setbuf(ndev, "escan", params, params_size,
878 cfg_priv->escan_ioctl_buf, BRCMF_DCMD_MEDLEN);
881 WL_INFO("system busy : escan canceled\n");
883 WL_ERR("error (%d)\n", err);
892 brcmf_do_escan(struct brcmf_cfg80211_priv *cfg_priv, struct wiphy *wiphy,
893 struct net_device *ndev, struct cfg80211_scan_request *request)
897 struct brcmf_scan_results *results;
900 cfg_priv->escan_info.ndev = ndev;
901 cfg_priv->escan_info.wiphy = wiphy;
902 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
903 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
904 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
905 &passive_scan, sizeof(passive_scan));
907 WL_ERR("error (%d)\n", err);
910 brcmf_set_mpc(ndev, 0);
911 results = (struct brcmf_scan_results *)cfg_priv->escan_info.escan_buf;
912 results->version = 0;
914 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
916 err = brcmf_run_escan(cfg_priv, ndev, request, WL_ESCAN_ACTION_START);
918 brcmf_set_mpc(ndev, 1);
923 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
924 struct cfg80211_scan_request *request,
925 struct cfg80211_ssid *this_ssid)
927 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
928 struct cfg80211_ssid *ssids;
929 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
936 WL_SCAN("START ESCAN\n");
938 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
939 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
942 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
943 WL_ERR("Scanning being aborted : status (%lu)\n",
947 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
948 WL_ERR("Connecting : status (%lu)\n",
953 /* Arm scan timeout timer */
954 mod_timer(&cfg_priv->escan_timeout, jiffies +
955 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
960 ssids = request->ssids;
964 /* we don't do escan in ibss */
968 cfg_priv->scan_request = request;
969 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
971 err = brcmf_do_escan(cfg_priv, wiphy, ndev, request);
977 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
978 ssids->ssid, ssids->ssid_len);
979 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
980 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
981 sr->ssid_le.SSID_len = cpu_to_le32(0);
984 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
985 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
988 WL_SCAN("Broadcast scan\n");
990 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
991 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
992 &passive_scan, sizeof(passive_scan));
994 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
997 brcmf_set_mpc(ndev, 0);
998 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
999 sizeof(sr->ssid_le));
1002 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1005 WL_ERR("WLC_SCAN error (%d)\n", err);
1007 brcmf_set_mpc(ndev, 1);
1015 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
1016 if (timer_pending(&cfg_priv->escan_timeout))
1017 del_timer_sync(&cfg_priv->escan_timeout);
1018 cfg_priv->scan_request = NULL;
1023 brcmf_cfg80211_scan(struct wiphy *wiphy,
1024 struct cfg80211_scan_request *request)
1026 struct net_device *ndev = request->wdev->netdev;
1027 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1030 WL_TRACE("Enter\n");
1032 if (!check_sys_up(wiphy))
1035 if (cfg_priv->iscan_on)
1036 err = brcmf_cfg80211_iscan(wiphy, ndev, request, NULL);
1037 else if (cfg_priv->escan_on)
1038 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
1041 WL_ERR("scan error (%d)\n", err);
1047 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1051 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
1053 WL_ERR("Error (%d)\n", err);
1058 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1062 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
1064 WL_ERR("Error (%d)\n", err);
1069 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1072 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
1074 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
1076 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
1082 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1084 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1085 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1088 WL_TRACE("Enter\n");
1089 if (!check_sys_up(wiphy))
1092 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1093 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
1094 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
1095 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
1099 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1100 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
1101 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
1102 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
1106 if (changed & WIPHY_PARAM_RETRY_LONG
1107 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
1108 cfg_priv->conf->retry_long = wiphy->retry_long;
1109 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
1113 if (changed & WIPHY_PARAM_RETRY_SHORT
1114 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
1115 cfg_priv->conf->retry_short = wiphy->retry_short;
1116 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
1126 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
1130 return &cfg_priv->profile->sec;
1132 return &cfg_priv->profile->bssid;
1134 return &cfg_priv->profile->ssid;
1136 WL_ERR("invalid item (%d)\n", item);
1141 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
1142 const struct brcmf_event_msg *e, void *data, s32 item)
1145 struct brcmf_ssid *ssid;
1149 ssid = (struct brcmf_ssid *) data;
1150 memset(cfg_priv->profile->ssid.SSID, 0,
1151 sizeof(cfg_priv->profile->ssid.SSID));
1152 memcpy(cfg_priv->profile->ssid.SSID,
1153 ssid->SSID, ssid->SSID_len);
1154 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
1158 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
1160 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
1163 memcpy(&cfg_priv->profile->sec, data,
1164 sizeof(cfg_priv->profile->sec));
1166 case WL_PROF_BEACONINT:
1167 cfg_priv->profile->beacon_interval = *(u16 *)data;
1169 case WL_PROF_DTIMPERIOD:
1170 cfg_priv->profile->dtim_period = *(u8 *)data;
1173 WL_ERR("unsupported item (%d)\n", item);
1181 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1183 memset(prof, 0, sizeof(*prof));
1186 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
1187 size_t *join_params_size)
1192 if (ch <= CH_MAX_2G_CHANNEL)
1193 chanspec |= WL_CHANSPEC_BAND_2G;
1195 chanspec |= WL_CHANSPEC_BAND_5G;
1197 chanspec |= WL_CHANSPEC_BW_20;
1198 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
1200 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
1203 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
1204 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1205 join_params->params_le.chanspec_num = cpu_to_le32(1);
1207 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
1208 "channel %d, chanspec %#X\n",
1209 chanspec, ch, chanspec);
1213 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
1215 struct net_device *ndev = NULL;
1218 WL_TRACE("Enter\n");
1220 if (cfg_priv->link_up) {
1221 ndev = cfg_to_ndev(cfg_priv);
1222 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1223 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
1225 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
1226 cfg_priv->link_up = false;
1232 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1233 struct cfg80211_ibss_params *params)
1235 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1236 struct brcmf_join_params join_params;
1237 size_t join_params_size = 0;
1241 struct brcmf_ssid ssid;
1243 WL_TRACE("Enter\n");
1244 if (!check_sys_up(wiphy))
1248 WL_CONN("SSID: %s\n", params->ssid);
1250 WL_CONN("SSID: NULL, Not supported\n");
1254 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1257 WL_CONN("BSSID: %pM\n", params->bssid);
1259 WL_CONN("No BSSID specified\n");
1261 if (params->channel)
1262 WL_CONN("channel: %d\n", params->channel->center_freq);
1264 WL_CONN("no channel specified\n");
1266 if (params->channel_fixed)
1267 WL_CONN("fixed channel required\n");
1269 WL_CONN("no fixed channel required\n");
1271 if (params->ie && params->ie_len)
1272 WL_CONN("ie len: %d\n", params->ie_len);
1274 WL_CONN("no ie specified\n");
1276 if (params->beacon_interval)
1277 WL_CONN("beacon interval: %d\n", params->beacon_interval);
1279 WL_CONN("no beacon interval specified\n");
1281 if (params->basic_rates)
1282 WL_CONN("basic rates: %08X\n", params->basic_rates);
1284 WL_CONN("no basic rates specified\n");
1286 if (params->privacy)
1287 WL_CONN("privacy required\n");
1289 WL_CONN("no privacy required\n");
1291 /* Configure Privacy for starter */
1292 if (params->privacy)
1293 wsec |= WEP_ENABLED;
1295 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1297 WL_ERR("wsec failed (%d)\n", err);
1301 /* Configure Beacon Interval for starter */
1302 if (params->beacon_interval)
1303 bcnprd = params->beacon_interval;
1307 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
1309 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
1313 /* Configure required join parameter */
1314 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1317 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1318 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
1319 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
1320 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1321 join_params_size = sizeof(join_params.ssid_le);
1322 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1325 if (params->bssid) {
1326 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1327 join_params_size = sizeof(join_params.ssid_le) +
1328 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1330 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1333 brcmf_update_prof(cfg_priv, NULL,
1334 &join_params.params_le.bssid, WL_PROF_BSSID);
1337 if (params->channel) {
1341 ieee80211_frequency_to_channel(
1342 params->channel->center_freq);
1343 if (params->channel_fixed) {
1344 /* adding chanspec */
1345 brcmf_ch_to_chanspec(cfg_priv->channel,
1346 &join_params, &join_params_size);
1349 /* set channel for starter */
1350 target_channel = cfg_priv->channel;
1351 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1354 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1358 cfg_priv->channel = 0;
1360 cfg_priv->ibss_starter = false;
1363 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1364 &join_params, join_params_size);
1366 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1372 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1378 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1380 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1383 WL_TRACE("Enter\n");
1384 if (!check_sys_up(wiphy))
1387 brcmf_link_down(cfg_priv);
1394 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1395 struct cfg80211_connect_params *sme)
1397 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1398 struct brcmf_cfg80211_security *sec;
1402 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1403 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1404 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1405 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1407 val = WPA_AUTH_DISABLED;
1408 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1409 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1411 WL_ERR("set wpa_auth failed (%d)\n", err);
1414 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1415 sec->wpa_versions = sme->crypto.wpa_versions;
1419 static s32 brcmf_set_auth_type(struct net_device *ndev,
1420 struct cfg80211_connect_params *sme)
1422 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1423 struct brcmf_cfg80211_security *sec;
1427 switch (sme->auth_type) {
1428 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1430 WL_CONN("open system\n");
1432 case NL80211_AUTHTYPE_SHARED_KEY:
1434 WL_CONN("shared key\n");
1436 case NL80211_AUTHTYPE_AUTOMATIC:
1438 WL_CONN("automatic\n");
1440 case NL80211_AUTHTYPE_NETWORK_EAP:
1441 WL_CONN("network eap\n");
1444 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1448 err = brcmf_dev_intvar_set(ndev, "auth", val);
1450 WL_ERR("set auth failed (%d)\n", err);
1453 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1454 sec->auth_type = sme->auth_type;
1459 brcmf_set_set_cipher(struct net_device *ndev,
1460 struct cfg80211_connect_params *sme)
1462 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1463 struct brcmf_cfg80211_security *sec;
1468 if (sme->crypto.n_ciphers_pairwise) {
1469 switch (sme->crypto.ciphers_pairwise[0]) {
1470 case WLAN_CIPHER_SUITE_WEP40:
1471 case WLAN_CIPHER_SUITE_WEP104:
1474 case WLAN_CIPHER_SUITE_TKIP:
1475 pval = TKIP_ENABLED;
1477 case WLAN_CIPHER_SUITE_CCMP:
1480 case WLAN_CIPHER_SUITE_AES_CMAC:
1484 WL_ERR("invalid cipher pairwise (%d)\n",
1485 sme->crypto.ciphers_pairwise[0]);
1489 if (sme->crypto.cipher_group) {
1490 switch (sme->crypto.cipher_group) {
1491 case WLAN_CIPHER_SUITE_WEP40:
1492 case WLAN_CIPHER_SUITE_WEP104:
1495 case WLAN_CIPHER_SUITE_TKIP:
1496 gval = TKIP_ENABLED;
1498 case WLAN_CIPHER_SUITE_CCMP:
1501 case WLAN_CIPHER_SUITE_AES_CMAC:
1505 WL_ERR("invalid cipher group (%d)\n",
1506 sme->crypto.cipher_group);
1511 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1512 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1514 WL_ERR("error (%d)\n", err);
1518 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1519 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1520 sec->cipher_group = sme->crypto.cipher_group;
1526 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1528 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1529 struct brcmf_cfg80211_security *sec;
1533 if (sme->crypto.n_akm_suites) {
1534 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1536 WL_ERR("could not get wpa_auth (%d)\n", err);
1539 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1540 switch (sme->crypto.akm_suites[0]) {
1541 case WLAN_AKM_SUITE_8021X:
1542 val = WPA_AUTH_UNSPECIFIED;
1544 case WLAN_AKM_SUITE_PSK:
1548 WL_ERR("invalid cipher group (%d)\n",
1549 sme->crypto.cipher_group);
1552 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1553 switch (sme->crypto.akm_suites[0]) {
1554 case WLAN_AKM_SUITE_8021X:
1555 val = WPA2_AUTH_UNSPECIFIED;
1557 case WLAN_AKM_SUITE_PSK:
1558 val = WPA2_AUTH_PSK;
1561 WL_ERR("invalid cipher group (%d)\n",
1562 sme->crypto.cipher_group);
1567 WL_CONN("setting wpa_auth to %d\n", val);
1568 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1570 WL_ERR("could not set wpa_auth (%d)\n", err);
1574 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1575 sec->wpa_auth = sme->crypto.akm_suites[0];
1581 brcmf_set_wep_sharedkey(struct net_device *ndev,
1582 struct cfg80211_connect_params *sme)
1584 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1585 struct brcmf_cfg80211_security *sec;
1586 struct brcmf_wsec_key key;
1590 WL_CONN("key len (%d)\n", sme->key_len);
1592 if (sme->key_len == 0)
1595 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1596 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1597 sec->wpa_versions, sec->cipher_pairwise);
1599 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1602 if (sec->cipher_pairwise &
1603 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1604 memset(&key, 0, sizeof(key));
1605 key.len = (u32) sme->key_len;
1606 key.index = (u32) sme->key_idx;
1607 if (key.len > sizeof(key.data)) {
1608 WL_ERR("Too long key length (%u)\n", key.len);
1611 memcpy(key.data, sme->key, key.len);
1612 key.flags = BRCMF_PRIMARY_KEY;
1613 switch (sec->cipher_pairwise) {
1614 case WLAN_CIPHER_SUITE_WEP40:
1615 key.algo = CRYPTO_ALGO_WEP1;
1617 case WLAN_CIPHER_SUITE_WEP104:
1618 key.algo = CRYPTO_ALGO_WEP128;
1621 WL_ERR("Invalid algorithm (%d)\n",
1622 sme->crypto.ciphers_pairwise[0]);
1625 /* Set the new key/index */
1626 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1627 key.len, key.index, key.algo);
1628 WL_CONN("key \"%s\"\n", key.data);
1629 err = send_key_to_dongle(ndev, &key);
1633 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1634 WL_CONN("set auth_type to shared key\n");
1635 val = 1; /* shared key */
1636 err = brcmf_dev_intvar_set(ndev, "auth", val);
1638 WL_ERR("set auth failed (%d)\n", err);
1647 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1648 struct cfg80211_connect_params *sme)
1650 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1651 struct ieee80211_channel *chan = sme->channel;
1652 struct brcmf_join_params join_params;
1653 size_t join_params_size;
1654 struct brcmf_ssid ssid;
1658 WL_TRACE("Enter\n");
1659 if (!check_sys_up(wiphy))
1663 WL_ERR("Invalid ssid\n");
1667 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1671 ieee80211_frequency_to_channel(chan->center_freq);
1672 WL_CONN("channel (%d), center_req (%d)\n",
1673 cfg_priv->channel, chan->center_freq);
1675 cfg_priv->channel = 0;
1677 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1679 err = brcmf_set_wpa_version(ndev, sme);
1681 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1685 err = brcmf_set_auth_type(ndev, sme);
1687 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1691 err = brcmf_set_set_cipher(ndev, sme);
1693 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1697 err = brcmf_set_key_mgmt(ndev, sme);
1699 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1703 err = brcmf_set_wep_sharedkey(ndev, sme);
1705 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1709 memset(&join_params, 0, sizeof(join_params));
1710 join_params_size = sizeof(join_params.ssid_le);
1712 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1713 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1714 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1715 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1716 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1718 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1720 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1721 WL_CONN("ssid \"%s\", len (%d)\n",
1722 ssid.SSID, ssid.SSID_len);
1724 brcmf_ch_to_chanspec(cfg_priv->channel,
1725 &join_params, &join_params_size);
1726 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1727 &join_params, join_params_size);
1729 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1733 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1739 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1742 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1743 struct brcmf_scb_val_le scbval;
1746 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1747 if (!check_sys_up(wiphy))
1750 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1752 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1753 scbval.val = cpu_to_le32(reason_code);
1754 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1755 sizeof(struct brcmf_scb_val_le));
1757 WL_ERR("error (%d)\n", err);
1759 cfg_priv->link_up = false;
1766 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1767 enum nl80211_tx_power_setting type, s32 mbm)
1770 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1771 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1775 s32 dbm = MBM_TO_DBM(mbm);
1777 WL_TRACE("Enter\n");
1778 if (!check_sys_up(wiphy))
1782 case NL80211_TX_POWER_AUTOMATIC:
1784 case NL80211_TX_POWER_LIMITED:
1785 case NL80211_TX_POWER_FIXED:
1787 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1793 /* Make sure radio is off or on as far as software is concerned */
1794 disable = WL_RADIO_SW_DISABLE << 16;
1795 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1797 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1802 txpwrmw = (u16) dbm;
1803 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1804 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1806 WL_ERR("qtxpower error (%d)\n", err);
1807 cfg_priv->conf->tx_power = dbm;
1814 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1816 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1817 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1822 WL_TRACE("Enter\n");
1823 if (!check_sys_up(wiphy))
1826 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1828 WL_ERR("error (%d)\n", err);
1832 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1833 *dbm = (s32) brcmf_qdbm_to_mw(result);
1841 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1842 u8 key_idx, bool unicast, bool multicast)
1848 WL_TRACE("Enter\n");
1849 WL_CONN("key index (%d)\n", key_idx);
1850 if (!check_sys_up(wiphy))
1853 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1855 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1859 if (wsec & WEP_ENABLED) {
1860 /* Just select a new current key */
1862 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1865 WL_ERR("error (%d)\n", err);
1873 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1874 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1876 struct brcmf_wsec_key key;
1877 struct brcmf_wsec_key_le key_le;
1880 memset(&key, 0, sizeof(key));
1881 key.index = (u32) key_idx;
1882 /* Instead of bcast for ea address for default wep keys,
1883 driver needs it to be Null */
1884 if (!is_multicast_ether_addr(mac_addr))
1885 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1886 key.len = (u32) params->key_len;
1887 /* check for key index change */
1890 err = send_key_to_dongle(ndev, &key);
1894 if (key.len > sizeof(key.data)) {
1895 WL_ERR("Invalid key length (%d)\n", key.len);
1899 WL_CONN("Setting the key index %d\n", key.index);
1900 memcpy(key.data, params->key, key.len);
1902 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1904 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1905 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1906 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1909 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1910 if (params->seq && params->seq_len == 6) {
1913 ivptr = (u8 *) params->seq;
1914 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1915 (ivptr[3] << 8) | ivptr[2];
1916 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1917 key.iv_initialized = true;
1920 switch (params->cipher) {
1921 case WLAN_CIPHER_SUITE_WEP40:
1922 key.algo = CRYPTO_ALGO_WEP1;
1923 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1925 case WLAN_CIPHER_SUITE_WEP104:
1926 key.algo = CRYPTO_ALGO_WEP128;
1927 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1929 case WLAN_CIPHER_SUITE_TKIP:
1930 key.algo = CRYPTO_ALGO_TKIP;
1931 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1933 case WLAN_CIPHER_SUITE_AES_CMAC:
1934 key.algo = CRYPTO_ALGO_AES_CCM;
1935 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1937 case WLAN_CIPHER_SUITE_CCMP:
1938 key.algo = CRYPTO_ALGO_AES_CCM;
1939 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1942 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1945 convert_key_from_CPU(&key, &key_le);
1947 brcmf_netdev_wait_pend8021x(ndev);
1948 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1951 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1959 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1960 u8 key_idx, bool pairwise, const u8 *mac_addr,
1961 struct key_params *params)
1963 struct brcmf_wsec_key key;
1969 WL_TRACE("Enter\n");
1970 WL_CONN("key index (%d)\n", key_idx);
1971 if (!check_sys_up(wiphy))
1976 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1978 memset(&key, 0, sizeof(key));
1980 key.len = (u32) params->key_len;
1981 key.index = (u32) key_idx;
1983 if (key.len > sizeof(key.data)) {
1984 WL_ERR("Too long key length (%u)\n", key.len);
1988 memcpy(key.data, params->key, key.len);
1990 key.flags = BRCMF_PRIMARY_KEY;
1991 switch (params->cipher) {
1992 case WLAN_CIPHER_SUITE_WEP40:
1993 key.algo = CRYPTO_ALGO_WEP1;
1994 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1996 case WLAN_CIPHER_SUITE_WEP104:
1997 key.algo = CRYPTO_ALGO_WEP128;
1998 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2000 case WLAN_CIPHER_SUITE_TKIP:
2001 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2002 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2003 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2004 key.algo = CRYPTO_ALGO_TKIP;
2005 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2007 case WLAN_CIPHER_SUITE_AES_CMAC:
2008 key.algo = CRYPTO_ALGO_AES_CCM;
2009 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2011 case WLAN_CIPHER_SUITE_CCMP:
2012 key.algo = CRYPTO_ALGO_AES_CCM;
2013 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2016 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
2021 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
2026 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
2028 WL_ERR("get wsec error (%d)\n", err);
2031 wsec &= ~(WEP_ENABLED);
2033 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
2035 WL_ERR("set wsec error (%d)\n", err);
2039 val = 1; /* assume shared key. otherwise 0 */
2040 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
2042 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
2049 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2050 u8 key_idx, bool pairwise, const u8 *mac_addr)
2052 struct brcmf_wsec_key key;
2057 WL_TRACE("Enter\n");
2058 if (!check_sys_up(wiphy))
2061 memset(&key, 0, sizeof(key));
2063 key.index = (u32) key_idx;
2064 key.flags = BRCMF_PRIMARY_KEY;
2065 key.algo = CRYPTO_ALGO_OFF;
2067 WL_CONN("key index (%d)\n", key_idx);
2069 /* Set the new key/index */
2070 err = send_key_to_dongle(ndev, &key);
2072 if (err == -EINVAL) {
2073 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
2074 /* we ignore this key index in this case */
2075 WL_ERR("invalid key index (%d)\n", key_idx);
2077 /* Ignore this error, may happen during DISASSOC */
2083 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
2085 WL_ERR("get wsec error (%d)\n", err);
2086 /* Ignore this error, may happen during DISASSOC */
2090 wsec &= ~(WEP_ENABLED);
2092 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
2094 WL_ERR("set wsec error (%d)\n", err);
2095 /* Ignore this error, may happen during DISASSOC */
2100 val = 0; /* assume open key. otherwise 1 */
2101 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
2103 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
2104 /* Ignore this error, may happen during DISASSOC */
2113 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2114 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2115 void (*callback) (void *cookie, struct key_params * params))
2117 struct key_params params;
2118 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2119 struct brcmf_cfg80211_security *sec;
2123 WL_TRACE("Enter\n");
2124 WL_CONN("key index (%d)\n", key_idx);
2125 if (!check_sys_up(wiphy))
2128 memset(¶ms, 0, sizeof(params));
2130 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
2132 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
2133 /* Ignore this error, may happen during DISASSOC */
2139 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
2140 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2141 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2142 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2143 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2144 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2145 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2149 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2150 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2153 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2154 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2157 WL_ERR("Invalid algo (0x%x)\n", wsec);
2161 callback(cookie, ¶ms);
2169 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2170 struct net_device *ndev, u8 key_idx)
2172 WL_INFO("Not supported\n");
2178 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2179 u8 *mac, struct station_info *sinfo)
2181 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2182 struct brcmf_scb_val_le scb_val;
2186 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
2188 WL_TRACE("Enter\n");
2189 if (!check_sys_up(wiphy))
2192 if (memcmp(mac, bssid, ETH_ALEN)) {
2193 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
2194 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
2195 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
2196 bssid[0], bssid[1], bssid[2], bssid[3],
2197 bssid[4], bssid[5]);
2202 /* Report the current tx rate */
2203 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
2205 WL_ERR("Could not get rate (%d)\n", err);
2207 sinfo->filled |= STATION_INFO_TX_BITRATE;
2208 sinfo->txrate.legacy = rate * 5;
2209 WL_CONN("Rate %d Mbps\n", rate / 2);
2212 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
2213 memset(&scb_val, 0, sizeof(scb_val));
2214 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
2215 sizeof(struct brcmf_scb_val_le));
2217 WL_ERR("Could not get rssi (%d)\n", err);
2219 rssi = le32_to_cpu(scb_val.val);
2220 sinfo->filled |= STATION_INFO_SIGNAL;
2221 sinfo->signal = rssi;
2222 WL_CONN("RSSI %d dBm\n", rssi);
2232 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2233 bool enabled, s32 timeout)
2237 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2239 WL_TRACE("Enter\n");
2242 * Powersave enable/disable request is coming from the
2243 * cfg80211 even before the interface is up. In that
2244 * scenario, driver will be storing the power save
2245 * preference in cfg_priv struct to apply this to
2246 * FW later while initializing the dongle
2248 cfg_priv->pwr_save = enabled;
2249 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2251 WL_INFO("Device is not ready,"
2252 "storing the value in cfg_priv struct\n");
2256 pm = enabled ? PM_FAST : PM_OFF;
2257 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
2259 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
2262 WL_ERR("net_device is not ready yet\n");
2264 WL_ERR("error (%d)\n", err);
2272 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2274 const struct cfg80211_bitrate_mask *mask)
2276 struct brcm_rateset_le rateset_le;
2284 WL_TRACE("Enter\n");
2285 if (!check_sys_up(wiphy))
2288 /* addr param is always NULL. ignore it */
2289 /* Get current rateset */
2290 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
2291 sizeof(rateset_le));
2293 WL_ERR("could not get current rateset (%d)\n", err);
2297 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2299 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2302 val = wl_g_rates[legacy - 1].bitrate * 100000;
2304 if (val < le32_to_cpu(rateset_le.count))
2305 /* Select rate by rateset index */
2306 rate = rateset_le.rates[val] & 0x7f;
2308 /* Specified rate in bps */
2309 rate = val / 500000;
2311 WL_CONN("rate %d mbps\n", rate / 2);
2315 * Set rate override,
2316 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2318 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
2319 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
2320 if (err_bg && err_a) {
2321 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
2322 err = err_bg | err_a;
2330 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2331 struct brcmf_bss_info_le *bi)
2333 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2334 struct ieee80211_channel *notify_channel;
2335 struct cfg80211_bss *bss;
2336 struct ieee80211_supported_band *band;
2340 u16 notify_capability;
2341 u16 notify_interval;
2343 size_t notify_ielen;
2346 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2347 WL_ERR("Bss info is larger than buffer. Discarding\n");
2351 channel = bi->ctl_ch ? bi->ctl_ch :
2352 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2354 if (channel <= CH_MAX_2G_CHANNEL)
2355 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2357 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2359 freq = ieee80211_channel_to_frequency(channel, band->band);
2360 notify_channel = ieee80211_get_channel(wiphy, freq);
2362 notify_capability = le16_to_cpu(bi->capability);
2363 notify_interval = le16_to_cpu(bi->beacon_period);
2364 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2365 notify_ielen = le32_to_cpu(bi->ie_length);
2366 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2368 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2369 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2370 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2371 WL_CONN("Channel: %d(%d)\n", channel, freq);
2372 WL_CONN("Capability: %X\n", notify_capability);
2373 WL_CONN("Beacon interval: %d\n", notify_interval);
2374 WL_CONN("Signal: %d\n", notify_signal);
2376 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2377 0, notify_capability, notify_interval, notify_ie,
2378 notify_ielen, notify_signal, GFP_KERNEL);
2383 cfg80211_put_bss(bss);
2388 static struct brcmf_bss_info_le *
2389 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2392 return list->bss_info_le;
2393 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2394 le32_to_cpu(bss->length));
2397 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2399 struct brcmf_scan_results *bss_list;
2400 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2404 bss_list = cfg_priv->bss_list;
2405 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2406 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2410 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2411 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2412 bi = next_bss_le(bss_list, bi);
2413 err = brcmf_inform_single_bss(cfg_priv, bi);
2420 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2421 struct net_device *ndev, const u8 *bssid)
2423 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2424 struct ieee80211_channel *notify_channel;
2425 struct brcmf_bss_info_le *bi = NULL;
2426 struct ieee80211_supported_band *band;
2427 struct cfg80211_bss *bss;
2432 u16 notify_capability;
2433 u16 notify_interval;
2435 size_t notify_ielen;
2438 WL_TRACE("Enter\n");
2440 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2446 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2448 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2450 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2454 bi = (struct brcmf_bss_info_le *)(buf + 4);
2456 channel = bi->ctl_ch ? bi->ctl_ch :
2457 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2459 if (channel <= CH_MAX_2G_CHANNEL)
2460 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2462 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2464 freq = ieee80211_channel_to_frequency(channel, band->band);
2465 notify_channel = ieee80211_get_channel(wiphy, freq);
2467 notify_capability = le16_to_cpu(bi->capability);
2468 notify_interval = le16_to_cpu(bi->beacon_period);
2469 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2470 notify_ielen = le32_to_cpu(bi->ie_length);
2471 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2473 WL_CONN("channel: %d(%d)\n", channel, freq);
2474 WL_CONN("capability: %X\n", notify_capability);
2475 WL_CONN("beacon interval: %d\n", notify_interval);
2476 WL_CONN("signal: %d\n", notify_signal);
2478 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2479 0, notify_capability, notify_interval,
2480 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2487 cfg80211_put_bss(bss);
2498 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2500 return cfg_priv->conf->mode == WL_MODE_IBSS;
2504 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2505 * triples, returning a pointer to the substring whose first element
2508 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2510 struct brcmf_tlv *elt;
2513 elt = (struct brcmf_tlv *) buf;
2516 /* find tagged parameter */
2517 while (totlen >= 2) {
2520 /* validate remaining totlen */
2521 if ((elt->id == key) && (totlen >= (len + 2)))
2524 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2525 totlen -= (len + 2);
2531 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2533 struct brcmf_bss_info_le *bi;
2534 struct brcmf_ssid *ssid;
2535 struct brcmf_tlv *tim;
2536 u16 beacon_interval;
2542 WL_TRACE("Enter\n");
2543 if (brcmf_is_ibssmode(cfg_priv))
2546 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2548 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2549 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2550 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2552 WL_ERR("Could not get bss info %d\n", err);
2553 goto update_bss_info_out;
2556 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2557 err = brcmf_inform_single_bss(cfg_priv, bi);
2559 goto update_bss_info_out;
2561 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2562 ie_len = le32_to_cpu(bi->ie_length);
2563 beacon_interval = le16_to_cpu(bi->beacon_period);
2565 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2567 dtim_period = tim->data[1];
2570 * active scan was done so we could not get dtim
2571 * information out of probe response.
2572 * so we speficially query dtim information to dongle.
2575 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2576 "dtim_assoc", &var);
2578 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2579 goto update_bss_info_out;
2581 dtim_period = (u8)var;
2584 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2585 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2587 update_bss_info_out:
2592 static void brcmf_abort_scanning(struct brcmf_cfg80211_priv *cfg_priv)
2594 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2595 struct escan_info *escan = &cfg_priv->escan_info;
2596 struct brcmf_ssid ssid;
2598 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2599 if (cfg_priv->iscan_on) {
2600 iscan->state = WL_ISCAN_STATE_IDLE;
2602 if (iscan->timer_on) {
2603 del_timer_sync(&iscan->timer);
2604 iscan->timer_on = 0;
2607 cancel_work_sync(&iscan->work);
2609 /* Abort iscan running in FW */
2610 memset(&ssid, 0, sizeof(ssid));
2611 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2613 if (cfg_priv->scan_request) {
2614 /* Indidate scan abort to cfg80211 layer */
2615 WL_INFO("Terminating scan in progress\n");
2616 cfg80211_scan_done(cfg_priv->scan_request, true);
2617 cfg_priv->scan_request = NULL;
2620 if (cfg_priv->escan_on && cfg_priv->scan_request) {
2621 escan->escan_state = WL_ESCAN_STATE_IDLE;
2622 brcmf_notify_escan_complete(cfg_priv, escan->ndev, true, true);
2624 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2625 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2628 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2631 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2632 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2634 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2635 WL_ERR("Scan complete while device not scanning\n");
2638 if (cfg_priv->scan_request) {
2639 WL_SCAN("ISCAN Completed scan: %s\n",
2640 aborted ? "Aborted" : "Done");
2641 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2642 brcmf_set_mpc(ndev, 1);
2643 cfg_priv->scan_request = NULL;
2645 cfg_priv->iscan_kickstart = false;
2648 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2650 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2651 WL_SCAN("wake up iscan\n");
2652 schedule_work(&iscan->work);
2660 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2661 struct brcmf_scan_results **bss_list)
2663 struct brcmf_iscan_results list;
2664 struct brcmf_scan_results *results;
2665 struct brcmf_scan_results_le *results_le;
2666 struct brcmf_iscan_results *list_buf;
2669 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2670 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2671 results = &list_buf->results;
2672 results_le = &list_buf->results_le;
2673 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2674 results->version = 0;
2677 memset(&list, 0, sizeof(list));
2678 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2679 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2680 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2681 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2683 WL_ERR("error (%d)\n", err);
2686 results->buflen = le32_to_cpu(results_le->buflen);
2687 results->version = le32_to_cpu(results_le->version);
2688 results->count = le32_to_cpu(results_le->count);
2689 WL_SCAN("results->count = %d\n", results_le->count);
2690 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2691 *status = le32_to_cpu(list_buf->status_le);
2692 WL_SCAN("status = %d\n", *status);
2693 *bss_list = results;
2698 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2700 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2703 iscan->state = WL_ISCAN_STATE_IDLE;
2704 brcmf_inform_bss(cfg_priv);
2705 brcmf_notify_iscan_complete(iscan, false);
2710 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2712 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2715 /* Reschedule the timer */
2716 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2717 iscan->timer_on = 1;
2722 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2724 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2727 brcmf_inform_bss(cfg_priv);
2728 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2729 /* Reschedule the timer */
2730 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2731 iscan->timer_on = 1;
2736 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2738 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2741 iscan->state = WL_ISCAN_STATE_IDLE;
2742 brcmf_notify_iscan_complete(iscan, true);
2747 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2749 struct brcmf_cfg80211_iscan_ctrl *iscan =
2750 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2752 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2753 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2754 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2756 if (iscan->timer_on) {
2757 del_timer_sync(&iscan->timer);
2758 iscan->timer_on = 0;
2761 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2762 status = BRCMF_SCAN_RESULTS_ABORTED;
2763 WL_ERR("Abort iscan\n");
2766 el->handler[status](cfg_priv);
2769 static void brcmf_iscan_timer(unsigned long data)
2771 struct brcmf_cfg80211_iscan_ctrl *iscan =
2772 (struct brcmf_cfg80211_iscan_ctrl *)data;
2775 iscan->timer_on = 0;
2776 WL_SCAN("timer expired\n");
2777 brcmf_wakeup_iscan(iscan);
2781 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2783 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2785 if (cfg_priv->iscan_on) {
2786 iscan->state = WL_ISCAN_STATE_IDLE;
2787 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2793 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2795 memset(el, 0, sizeof(*el));
2796 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2797 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2798 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2799 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2800 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2803 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2805 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2808 if (cfg_priv->iscan_on) {
2809 iscan->ndev = cfg_to_ndev(cfg_priv);
2810 brcmf_init_iscan_eloop(&iscan->el);
2811 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2812 init_timer(&iscan->timer);
2813 iscan->timer.data = (unsigned long) iscan;
2814 iscan->timer.function = brcmf_iscan_timer;
2815 err = brcmf_invoke_iscan(cfg_priv);
2817 iscan->data = cfg_priv;
2823 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2825 struct brcmf_cfg80211_priv *cfg_priv =
2826 container_of(work, struct brcmf_cfg80211_priv,
2827 escan_timeout_work);
2829 brcmf_notify_escan_complete(cfg_priv,
2830 cfg_priv->escan_info.ndev, true, true);
2833 static void brcmf_escan_timeout(unsigned long data)
2835 struct brcmf_cfg80211_priv *cfg_priv =
2836 (struct brcmf_cfg80211_priv *)data;
2838 if (cfg_priv->scan_request) {
2839 WL_ERR("timer expired\n");
2840 if (cfg_priv->escan_on)
2841 schedule_work(&cfg_priv->escan_timeout_work);
2846 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2847 struct brcmf_bss_info_le *bss_info_le)
2849 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2850 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2851 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2852 bss_info_le->SSID_len == bss->SSID_len &&
2853 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2854 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2855 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2856 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2857 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2859 /* preserve max RSSI if the measurements are
2860 * both on-channel or both off-channel
2862 if (bss_info_rssi > bss_rssi)
2863 bss->RSSI = bss_info_le->RSSI;
2864 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2865 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2866 /* preserve the on-channel rssi measurement
2867 * if the new measurement is off channel
2869 bss->RSSI = bss_info_le->RSSI;
2870 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2878 brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv *cfg_priv,
2879 struct net_device *ndev,
2880 const struct brcmf_event_msg *e, void *data)
2884 struct brcmf_escan_result_le *escan_result_le;
2885 struct brcmf_bss_info_le *bss_info_le;
2886 struct brcmf_bss_info_le *bss = NULL;
2888 struct brcmf_scan_results *list;
2892 status = be32_to_cpu(e->status);
2894 if (!ndev || !cfg_priv->escan_on ||
2895 !test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2896 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
2897 ndev, cfg_priv->escan_on,
2898 !test_bit(WL_STATUS_SCANNING, &cfg_priv->status));
2902 if (status == BRCMF_E_STATUS_PARTIAL) {
2903 WL_SCAN("ESCAN Partial result\n");
2904 escan_result_le = (struct brcmf_escan_result_le *) data;
2905 if (!escan_result_le) {
2906 WL_ERR("Invalid escan result (NULL pointer)\n");
2909 if (!cfg_priv->scan_request) {
2910 WL_SCAN("result without cfg80211 request\n");
2914 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2915 WL_ERR("Invalid bss_count %d: ignoring\n",
2916 escan_result_le->bss_count);
2919 bss_info_le = &escan_result_le->bss_info_le;
2921 bi_length = le32_to_cpu(bss_info_le->length);
2922 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2923 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2924 WL_ERR("Invalid bss_info length %d: ignoring\n",
2929 if (!(cfg_to_wiphy(cfg_priv)->interface_modes &
2930 BIT(NL80211_IFTYPE_ADHOC))) {
2931 if (le16_to_cpu(bss_info_le->capability) &
2932 WLAN_CAPABILITY_IBSS) {
2933 WL_ERR("Ignoring IBSS result\n");
2938 list = (struct brcmf_scan_results *)
2939 cfg_priv->escan_info.escan_buf;
2940 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2941 WL_ERR("Buffer is too small: ignoring\n");
2945 for (i = 0; i < list->count; i++) {
2946 bss = bss ? (struct brcmf_bss_info_le *)
2947 ((unsigned char *)bss +
2948 le32_to_cpu(bss->length)) : list->bss_info_le;
2949 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2952 memcpy(&(cfg_priv->escan_info.escan_buf[list->buflen]),
2953 bss_info_le, bi_length);
2954 list->version = le32_to_cpu(bss_info_le->version);
2955 list->buflen += bi_length;
2958 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2959 if (cfg_priv->scan_request) {
2960 cfg_priv->bss_list = (struct brcmf_scan_results *)
2961 cfg_priv->escan_info.escan_buf;
2962 brcmf_inform_bss(cfg_priv);
2963 aborted = status != BRCMF_E_STATUS_SUCCESS;
2964 brcmf_notify_escan_complete(cfg_priv, ndev, aborted,
2967 WL_ERR("Unexpected scan result 0x%x\n", status);
2973 static void brcmf_init_escan(struct brcmf_cfg80211_priv *cfg_priv)
2976 if (cfg_priv->escan_on) {
2977 cfg_priv->el.handler[BRCMF_E_ESCAN_RESULT] =
2978 brcmf_cfg80211_escan_handler;
2979 cfg_priv->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2980 /* Init scan_timeout timer */
2981 init_timer(&cfg_priv->escan_timeout);
2982 cfg_priv->escan_timeout.data = (unsigned long) cfg_priv;
2983 cfg_priv->escan_timeout.function = brcmf_escan_timeout;
2984 INIT_WORK(&cfg_priv->escan_timeout_work,
2985 brcmf_cfg80211_escan_timeout_worker);
2989 static __always_inline void brcmf_delay(u32 ms)
2991 if (ms < 1000 / HZ) {
2999 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3001 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3004 * Check for WL_STATUS_READY before any function call which
3005 * could result is bus access. Don't block the resume for
3006 * any driver error conditions
3008 WL_TRACE("Enter\n");
3010 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
3011 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
3017 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3018 struct cfg80211_wowlan *wow)
3020 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3021 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3023 WL_TRACE("Enter\n");
3026 * Check for WL_STATUS_READY before any function call which
3027 * could result is bus access. Don't block the suspend for
3028 * any driver error conditions
3032 * While going to suspend if associated with AP disassociate
3033 * from AP to save power while system is in suspended state
3035 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3036 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3037 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3038 WL_INFO("Disassociating from AP"
3039 " while entering suspend state\n");
3040 brcmf_link_down(cfg_priv);
3043 * Make sure WPA_Supplicant receives all the event
3044 * generated due to DISASSOC call to the fw to keep
3045 * the state fw and WPA_Supplicant state consistent
3050 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
3051 brcmf_abort_scanning(cfg_priv);
3053 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3055 /* Turn off watchdog timer */
3056 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
3057 brcmf_set_mpc(ndev, 1);
3065 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
3067 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3070 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
3074 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
3079 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
3082 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3086 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
3089 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
3092 WL_ERR("error (%d)\n", err);
3095 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
3101 brcmf_update_pmklist(struct net_device *ndev,
3102 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3107 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3109 WL_CONN("No of elements %d\n", pmkid_len);
3110 for (i = 0; i < pmkid_len; i++) {
3111 WL_CONN("PMKID[%d]: %pM =\n", i,
3112 &pmk_list->pmkids.pmkid[i].BSSID);
3113 for (j = 0; j < WLAN_PMKID_LEN; j++)
3114 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
3118 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
3125 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3126 struct cfg80211_pmksa *pmksa)
3128 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3129 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
3134 WL_TRACE("Enter\n");
3135 if (!check_sys_up(wiphy))
3138 pmkid_len = le32_to_cpu(pmkids->npmkid);
3139 for (i = 0; i < pmkid_len; i++)
3140 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3142 if (i < WL_NUM_PMKIDS_MAX) {
3143 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3144 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3145 if (i == pmkid_len) {
3147 pmkids->npmkid = cpu_to_le32(pmkid_len);
3152 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3153 pmkids->pmkid[pmkid_len].BSSID);
3154 for (i = 0; i < WLAN_PMKID_LEN; i++)
3155 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3157 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
3164 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3165 struct cfg80211_pmksa *pmksa)
3167 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3168 struct pmkid_list pmkid;
3172 WL_TRACE("Enter\n");
3173 if (!check_sys_up(wiphy))
3176 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3177 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3179 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3180 &pmkid.pmkid[0].BSSID);
3181 for (i = 0; i < WLAN_PMKID_LEN; i++)
3182 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
3184 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
3185 for (i = 0; i < pmkid_len; i++)
3187 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
3192 && (i < pmkid_len)) {
3193 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
3194 sizeof(struct pmkid));
3195 for (; i < (pmkid_len - 1); i++) {
3196 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
3197 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
3199 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
3200 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
3203 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3207 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
3215 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3217 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3220 WL_TRACE("Enter\n");
3221 if (!check_sys_up(wiphy))
3224 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
3225 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
3232 #ifdef CONFIG_NL80211_TESTMODE
3233 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3235 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
3236 struct net_device *ndev = cfg_priv->wdev->netdev;
3237 struct brcmf_dcmd *dcmd = data;
3238 struct sk_buff *reply;
3241 ret = brcmf_netlink_dcmd(ndev, dcmd);
3243 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3244 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3245 ret = cfg80211_testmode_reply(reply);
3251 static struct cfg80211_ops wl_cfg80211_ops = {
3252 .change_virtual_intf = brcmf_cfg80211_change_iface,
3253 .scan = brcmf_cfg80211_scan,
3254 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3255 .join_ibss = brcmf_cfg80211_join_ibss,
3256 .leave_ibss = brcmf_cfg80211_leave_ibss,
3257 .get_station = brcmf_cfg80211_get_station,
3258 .set_tx_power = brcmf_cfg80211_set_tx_power,
3259 .get_tx_power = brcmf_cfg80211_get_tx_power,
3260 .add_key = brcmf_cfg80211_add_key,
3261 .del_key = brcmf_cfg80211_del_key,
3262 .get_key = brcmf_cfg80211_get_key,
3263 .set_default_key = brcmf_cfg80211_config_default_key,
3264 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3265 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3266 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3267 .connect = brcmf_cfg80211_connect,
3268 .disconnect = brcmf_cfg80211_disconnect,
3269 .suspend = brcmf_cfg80211_suspend,
3270 .resume = brcmf_cfg80211_resume,
3271 .set_pmksa = brcmf_cfg80211_set_pmksa,
3272 .del_pmksa = brcmf_cfg80211_del_pmksa,
3273 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3274 #ifdef CONFIG_NL80211_TESTMODE
3275 .testmode_cmd = brcmf_cfg80211_testmode
3279 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3285 return NL80211_IFTYPE_STATION;
3287 return NL80211_IFTYPE_ADHOC;
3289 return NL80211_IFTYPE_UNSPECIFIED;
3295 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
3296 struct device *ndev)
3298 struct wireless_dev *wdev;
3301 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
3303 return ERR_PTR(-ENOMEM);
3306 wiphy_new(&wl_cfg80211_ops,
3307 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
3309 WL_ERR("Could not allocate wiphy device\n");
3313 set_wiphy_dev(wdev->wiphy, ndev);
3314 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3315 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3316 wdev->wiphy->interface_modes =
3317 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
3318 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3319 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
3320 * it as 11a by default.
3321 * This will be updated with
3324 * if phy has 11n capability
3326 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3327 wdev->wiphy->cipher_suites = __wl_cipher_suites;
3328 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3329 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
3333 err = wiphy_register(wdev->wiphy);
3335 WL_ERR("Could not register wiphy device (%d)\n", err);
3336 goto wiphy_register_out;
3341 wiphy_free(wdev->wiphy);
3346 return ERR_PTR(err);
3349 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
3351 struct wireless_dev *wdev = cfg_priv->wdev;
3354 WL_ERR("wdev is invalid\n");
3357 wiphy_unregister(wdev->wiphy);
3358 wiphy_free(wdev->wiphy);
3360 cfg_priv->wdev = NULL;
3363 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
3364 const struct brcmf_event_msg *e)
3366 u32 event = be32_to_cpu(e->event_type);
3367 u32 status = be32_to_cpu(e->status);
3369 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3370 WL_CONN("Processing set ssid\n");
3371 cfg_priv->link_up = true;
3378 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
3379 const struct brcmf_event_msg *e)
3381 u32 event = be32_to_cpu(e->event_type);
3382 u16 flags = be16_to_cpu(e->flags);
3384 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3385 WL_CONN("Processing link down\n");
3391 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
3392 const struct brcmf_event_msg *e)
3394 u32 event = be32_to_cpu(e->event_type);
3395 u32 status = be32_to_cpu(e->status);
3397 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3398 WL_CONN("Processing Link %s & no network found\n",
3399 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
3404 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3405 WL_CONN("Processing connecting & no network found\n");
3412 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3414 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3416 kfree(conn_info->req_ie);
3417 conn_info->req_ie = NULL;
3418 conn_info->req_ie_len = 0;
3419 kfree(conn_info->resp_ie);
3420 conn_info->resp_ie = NULL;
3421 conn_info->resp_ie_len = 0;
3424 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
3426 struct net_device *ndev = cfg_to_ndev(cfg_priv);
3427 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3428 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3433 brcmf_clear_assoc_ies(cfg_priv);
3435 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
3438 WL_ERR("could not get assoc info (%d)\n", err);
3442 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
3443 req_len = le32_to_cpu(assoc_info->req_len);
3444 resp_len = le32_to_cpu(assoc_info->resp_len);
3446 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
3447 cfg_priv->extra_buf,
3450 WL_ERR("could not get assoc req (%d)\n", err);
3453 conn_info->req_ie_len = req_len;
3455 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
3458 conn_info->req_ie_len = 0;
3459 conn_info->req_ie = NULL;
3462 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
3463 cfg_priv->extra_buf,
3466 WL_ERR("could not get assoc resp (%d)\n", err);
3469 conn_info->resp_ie_len = resp_len;
3470 conn_info->resp_ie =
3471 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
3474 conn_info->resp_ie_len = 0;
3475 conn_info->resp_ie = NULL;
3477 WL_CONN("req len (%d) resp len (%d)\n",
3478 conn_info->req_ie_len, conn_info->resp_ie_len);
3484 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
3485 struct net_device *ndev,
3486 const struct brcmf_event_msg *e)
3488 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3489 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
3490 struct brcmf_channel_info_le channel_le;
3491 struct ieee80211_channel *notify_channel;
3492 struct ieee80211_supported_band *band;
3497 WL_TRACE("Enter\n");
3499 brcmf_get_assoc_ies(cfg_priv);
3500 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
3501 brcmf_update_bss_info(cfg_priv);
3503 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
3504 sizeof(channel_le));
3506 target_channel = le32_to_cpu(channel_le.target_channel);
3507 WL_CONN("Roamed to channel %d\n", target_channel);
3509 if (target_channel <= CH_MAX_2G_CHANNEL)
3510 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3512 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3514 freq = ieee80211_channel_to_frequency(target_channel, band->band);
3515 notify_channel = ieee80211_get_channel(wiphy, freq);
3517 cfg80211_roamed(ndev, notify_channel,
3518 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
3519 conn_info->req_ie, conn_info->req_ie_len,
3520 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3521 WL_CONN("Report roaming result\n");
3523 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3529 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3530 struct net_device *ndev, const struct brcmf_event_msg *e,
3533 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3536 WL_TRACE("Enter\n");
3538 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3540 brcmf_get_assoc_ies(cfg_priv);
3541 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3543 brcmf_update_bss_info(cfg_priv);
3545 cfg80211_connect_result(ndev,
3546 (u8 *)brcmf_read_prof(cfg_priv,
3549 conn_info->req_ie_len,
3551 conn_info->resp_ie_len,
3552 completed ? WLAN_STATUS_SUCCESS :
3553 WLAN_STATUS_AUTH_TIMEOUT,
3556 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3557 WL_CONN("Report connect result - connection %s\n",
3558 completed ? "succeeded" : "failed");
3565 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3566 struct net_device *ndev,
3567 const struct brcmf_event_msg *e, void *data)
3571 if (brcmf_is_linkup(cfg_priv, e)) {
3572 WL_CONN("Linkup\n");
3573 if (brcmf_is_ibssmode(cfg_priv)) {
3574 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3576 wl_inform_ibss(cfg_priv, ndev, e->addr);
3577 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3578 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3579 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3581 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3582 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3583 WL_CONN("Linkdown\n");
3584 if (brcmf_is_ibssmode(cfg_priv)) {
3585 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3586 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3588 brcmf_link_down(cfg_priv);
3590 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3591 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3592 &cfg_priv->status)) {
3593 cfg80211_disconnected(ndev, 0, NULL, 0,
3595 brcmf_link_down(cfg_priv);
3598 brcmf_init_prof(cfg_priv->profile);
3599 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3600 if (brcmf_is_ibssmode(cfg_priv))
3601 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3603 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3610 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3611 struct net_device *ndev,
3612 const struct brcmf_event_msg *e, void *data)
3615 u32 event = be32_to_cpu(e->event_type);
3616 u32 status = be32_to_cpu(e->status);
3618 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3619 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3620 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3622 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3629 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3630 struct net_device *ndev,
3631 const struct brcmf_event_msg *e, void *data)
3633 u16 flags = be16_to_cpu(e->flags);
3634 enum nl80211_key_type key_type;
3636 if (flags & BRCMF_EVENT_MSG_GROUP)
3637 key_type = NL80211_KEYTYPE_GROUP;
3639 key_type = NL80211_KEYTYPE_PAIRWISE;
3641 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3648 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3649 struct net_device *ndev,
3650 const struct brcmf_event_msg *e, void *data)
3652 struct brcmf_channel_info_le channel_inform_le;
3653 struct brcmf_scan_results_le *bss_list_le;
3654 u32 len = WL_SCAN_BUF_MAX;
3656 bool scan_abort = false;
3659 WL_TRACE("Enter\n");
3661 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3663 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3666 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3667 WL_ERR("Scan complete while device not scanning\n");
3673 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3674 sizeof(channel_inform_le));
3676 WL_ERR("scan busy (%d)\n", err);
3680 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3682 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3683 cfg_priv->bss_list = cfg_priv->scan_results;
3684 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3686 memset(cfg_priv->scan_results, 0, len);
3687 bss_list_le->buflen = cpu_to_le32(len);
3688 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3689 cfg_priv->scan_results, len);
3691 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3696 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3697 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3698 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3700 err = brcmf_inform_bss(cfg_priv);
3705 if (cfg_priv->scan_request) {
3706 WL_SCAN("calling cfg80211_scan_done\n");
3707 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3708 brcmf_set_mpc(ndev, 1);
3709 cfg_priv->scan_request = NULL;
3717 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3719 conf->mode = (u32)-1;
3720 conf->frag_threshold = (u32)-1;
3721 conf->rts_threshold = (u32)-1;
3722 conf->retry_short = (u32)-1;
3723 conf->retry_long = (u32)-1;
3724 conf->tx_power = -1;
3727 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3729 memset(el, 0, sizeof(*el));
3730 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3731 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3732 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3733 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3734 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3737 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3739 kfree(cfg_priv->scan_results);
3740 cfg_priv->scan_results = NULL;
3741 kfree(cfg_priv->bss_info);
3742 cfg_priv->bss_info = NULL;
3743 kfree(cfg_priv->conf);
3744 cfg_priv->conf = NULL;
3745 kfree(cfg_priv->profile);
3746 cfg_priv->profile = NULL;
3747 kfree(cfg_priv->scan_req_int);
3748 cfg_priv->scan_req_int = NULL;
3749 kfree(cfg_priv->escan_ioctl_buf);
3750 cfg_priv->escan_ioctl_buf = NULL;
3751 kfree(cfg_priv->dcmd_buf);
3752 cfg_priv->dcmd_buf = NULL;
3753 kfree(cfg_priv->extra_buf);
3754 cfg_priv->extra_buf = NULL;
3755 kfree(cfg_priv->iscan);
3756 cfg_priv->iscan = NULL;
3757 kfree(cfg_priv->pmk_list);
3758 cfg_priv->pmk_list = NULL;
3761 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3763 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3764 if (!cfg_priv->scan_results)
3765 goto init_priv_mem_out;
3766 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3767 if (!cfg_priv->conf)
3768 goto init_priv_mem_out;
3769 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3770 if (!cfg_priv->profile)
3771 goto init_priv_mem_out;
3772 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3773 if (!cfg_priv->bss_info)
3774 goto init_priv_mem_out;
3775 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3777 if (!cfg_priv->scan_req_int)
3778 goto init_priv_mem_out;
3779 cfg_priv->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
3780 if (!cfg_priv->escan_ioctl_buf)
3781 goto init_priv_mem_out;
3782 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3783 if (!cfg_priv->dcmd_buf)
3784 goto init_priv_mem_out;
3785 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3786 if (!cfg_priv->extra_buf)
3787 goto init_priv_mem_out;
3788 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3789 if (!cfg_priv->iscan)
3790 goto init_priv_mem_out;
3791 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3792 if (!cfg_priv->pmk_list)
3793 goto init_priv_mem_out;
3798 brcmf_deinit_priv_mem(cfg_priv);
3804 * retrieve first queued event from head
3807 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3808 struct brcmf_cfg80211_priv *cfg_priv)
3810 struct brcmf_cfg80211_event_q *e = NULL;
3812 spin_lock_irq(&cfg_priv->evt_q_lock);
3813 if (!list_empty(&cfg_priv->evt_q_list)) {
3814 e = list_first_entry(&cfg_priv->evt_q_list,
3815 struct brcmf_cfg80211_event_q, evt_q_list);
3816 list_del(&e->evt_q_list);
3818 spin_unlock_irq(&cfg_priv->evt_q_lock);
3824 * push event to tail of the queue
3826 * remark: this function may not sleep as it is called in atomic context.
3830 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3831 const struct brcmf_event_msg *msg, void *data)
3833 struct brcmf_cfg80211_event_q *e;
3839 total_len = sizeof(struct brcmf_cfg80211_event_q);
3841 data_len = be32_to_cpu(msg->datalen);
3844 total_len += data_len;
3845 e = kzalloc(total_len, GFP_ATOMIC);
3850 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3852 memcpy(&e->edata, data, data_len);
3854 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3855 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3856 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3861 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3866 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3868 struct brcmf_cfg80211_priv *cfg_priv =
3869 container_of(work, struct brcmf_cfg80211_priv,
3871 struct brcmf_cfg80211_event_q *e;
3873 e = brcmf_deq_event(cfg_priv);
3875 WL_ERR("event queue empty...\n");
3880 WL_INFO("event type (%d)\n", e->etype);
3881 if (cfg_priv->el.handler[e->etype])
3882 cfg_priv->el.handler[e->etype](cfg_priv,
3883 cfg_to_ndev(cfg_priv),
3884 &e->emsg, e->edata);
3886 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3888 } while ((e = brcmf_deq_event(cfg_priv)));
3892 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3894 spin_lock_init(&cfg_priv->evt_q_lock);
3895 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3898 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3900 struct brcmf_cfg80211_event_q *e;
3902 spin_lock_irq(&cfg_priv->evt_q_lock);
3903 while (!list_empty(&cfg_priv->evt_q_list)) {
3904 e = list_first_entry(&cfg_priv->evt_q_list,
3905 struct brcmf_cfg80211_event_q, evt_q_list);
3906 list_del(&e->evt_q_list);
3909 spin_unlock_irq(&cfg_priv->evt_q_lock);
3912 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3916 cfg_priv->scan_request = NULL;
3917 cfg_priv->pwr_save = true;
3918 #ifdef CONFIG_BRCMISCAN
3919 cfg_priv->iscan_on = true; /* iscan on & off switch.
3920 we enable iscan per default */
3921 cfg_priv->escan_on = false; /* escan on & off switch.
3922 we disable escan per default */
3924 cfg_priv->iscan_on = false; /* iscan on & off switch.
3925 we disable iscan per default */
3926 cfg_priv->escan_on = true; /* escan on & off switch.
3927 we enable escan per default */
3929 cfg_priv->roam_on = true; /* roam on & off switch.
3930 we enable roam per default */
3932 cfg_priv->iscan_kickstart = false;
3933 cfg_priv->active_scan = true; /* we do active scan for
3934 specific scan per default */
3935 cfg_priv->dongle_up = false; /* dongle is not up yet */
3936 brcmf_init_eq(cfg_priv);
3937 err = brcmf_init_priv_mem(cfg_priv);
3940 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3941 brcmf_init_eloop_handler(&cfg_priv->el);
3942 mutex_init(&cfg_priv->usr_sync);
3943 err = brcmf_init_iscan(cfg_priv);
3946 brcmf_init_escan(cfg_priv);
3947 brcmf_init_conf(cfg_priv->conf);
3948 brcmf_init_prof(cfg_priv->profile);
3949 brcmf_link_down(cfg_priv);
3954 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3956 cancel_work_sync(&cfg_priv->event_work);
3957 cfg_priv->dongle_up = false; /* dongle down */
3958 brcmf_flush_eq(cfg_priv);
3959 brcmf_link_down(cfg_priv);
3960 brcmf_abort_scanning(cfg_priv);
3961 brcmf_deinit_priv_mem(cfg_priv);
3964 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3965 struct device *busdev,
3968 struct wireless_dev *wdev;
3969 struct brcmf_cfg80211_priv *cfg_priv;
3970 struct brcmf_cfg80211_iface *ci;
3971 struct brcmf_cfg80211_dev *cfg_dev;
3975 WL_ERR("ndev is invalid\n");
3978 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3982 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3988 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3989 cfg_priv = wdev_to_cfg(wdev);
3990 cfg_priv->wdev = wdev;
3991 cfg_priv->pub = data;
3992 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3993 ci->cfg_priv = cfg_priv;
3994 ndev->ieee80211_ptr = wdev;
3995 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3996 wdev->netdev = ndev;
3997 err = wl_init_priv(cfg_priv);
3999 WL_ERR("Failed to init iwm_priv (%d)\n", err);
4000 goto cfg80211_attach_out;
4002 brcmf_set_drvdata(cfg_dev, ci);
4006 cfg80211_attach_out:
4007 brcmf_free_wdev(cfg_priv);
4012 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
4014 struct brcmf_cfg80211_priv *cfg_priv;
4016 cfg_priv = brcmf_priv_get(cfg_dev);
4018 wl_deinit_priv(cfg_priv);
4019 brcmf_free_wdev(cfg_priv);
4020 brcmf_set_drvdata(cfg_dev, NULL);
4025 brcmf_cfg80211_event(struct net_device *ndev,
4026 const struct brcmf_event_msg *e, void *data)
4028 u32 event_type = be32_to_cpu(e->event_type);
4029 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
4031 if (!brcmf_enq_event(cfg_priv, event_type, e, data))
4032 schedule_work(&cfg_priv->event_work);
4035 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
4041 case NL80211_IFTYPE_MONITOR:
4042 case NL80211_IFTYPE_WDS:
4043 WL_ERR("type (%d) : currently we do not support this mode\n",
4047 case NL80211_IFTYPE_ADHOC:
4050 case NL80211_IFTYPE_STATION:
4055 WL_ERR("invalid type (%d)\n", iftype);
4058 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
4060 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
4067 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
4069 /* Room for "event_msgs" + '\0' + bitvec */
4070 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
4071 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
4074 WL_TRACE("Enter\n");
4076 /* Setup event_msgs */
4077 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
4078 iovbuf, sizeof(iovbuf));
4079 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
4081 WL_ERR("Get event_msgs error (%d)\n", err);
4082 goto dongle_eventmsg_out;
4084 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
4086 setbit(eventmask, BRCMF_E_SET_SSID);
4087 setbit(eventmask, BRCMF_E_ROAM);
4088 setbit(eventmask, BRCMF_E_PRUNE);
4089 setbit(eventmask, BRCMF_E_AUTH);
4090 setbit(eventmask, BRCMF_E_REASSOC);
4091 setbit(eventmask, BRCMF_E_REASSOC_IND);
4092 setbit(eventmask, BRCMF_E_DEAUTH_IND);
4093 setbit(eventmask, BRCMF_E_DISASSOC_IND);
4094 setbit(eventmask, BRCMF_E_DISASSOC);
4095 setbit(eventmask, BRCMF_E_JOIN);
4096 setbit(eventmask, BRCMF_E_ASSOC_IND);
4097 setbit(eventmask, BRCMF_E_PSK_SUP);
4098 setbit(eventmask, BRCMF_E_LINK);
4099 setbit(eventmask, BRCMF_E_NDIS_LINK);
4100 setbit(eventmask, BRCMF_E_MIC_ERROR);
4101 setbit(eventmask, BRCMF_E_PMKID_CACHE);
4102 setbit(eventmask, BRCMF_E_TXFAIL);
4103 setbit(eventmask, BRCMF_E_JOIN_START);
4104 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
4105 setbit(eventmask, BRCMF_E_ESCAN_RESULT);
4107 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
4108 iovbuf, sizeof(iovbuf));
4109 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
4111 WL_ERR("Set event_msgs error (%d)\n", err);
4112 goto dongle_eventmsg_out;
4115 dongle_eventmsg_out:
4121 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4125 __le32 roamtrigger[2];
4126 __le32 roam_delta[2];
4131 * Setup timeout if Beacons are lost and roam is
4132 * off to report link down
4135 bcn_to_le = cpu_to_le32(bcn_timeout);
4136 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
4137 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
4138 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
4139 iovbuf, sizeof(iovbuf));
4141 WL_ERR("bcn_timeout error (%d)\n", err);
4142 goto dongle_rom_out;
4147 * Enable/Disable built-in roaming to allow supplicant
4148 * to take care of roaming
4150 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
4151 roamvar_le = cpu_to_le32(roamvar);
4152 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
4153 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
4154 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
4156 WL_ERR("roam_off error (%d)\n", err);
4157 goto dongle_rom_out;
4160 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4161 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4162 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
4163 (void *)roamtrigger, sizeof(roamtrigger));
4165 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4166 goto dongle_rom_out;
4169 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4170 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4171 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
4172 (void *)roam_delta, sizeof(roam_delta));
4174 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
4175 goto dongle_rom_out;
4183 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4184 s32 scan_unassoc_time, s32 scan_passive_time)
4187 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
4188 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
4189 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
4191 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4192 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
4194 if (err == -EOPNOTSUPP)
4195 WL_INFO("Scan assoc time is not supported\n");
4197 WL_ERR("Scan assoc time error (%d)\n", err);
4198 goto dongle_scantime_out;
4200 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4201 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
4203 if (err == -EOPNOTSUPP)
4204 WL_INFO("Scan unassoc time is not supported\n");
4206 WL_ERR("Scan unassoc time error (%d)\n", err);
4207 goto dongle_scantime_out;
4210 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4211 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
4213 if (err == -EOPNOTSUPP)
4214 WL_INFO("Scan passive time is not supported\n");
4216 WL_ERR("Scan passive time error (%d)\n", err);
4217 goto dongle_scantime_out;
4220 dongle_scantime_out:
4224 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
4226 struct wiphy *wiphy;
4231 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
4232 &phy_list, sizeof(phy_list));
4234 WL_ERR("error (%d)\n", err);
4238 phy = ((char *)&phy_list)[1];
4239 WL_INFO("%c phy\n", phy);
4240 if (phy == 'n' || phy == 'a') {
4241 wiphy = cfg_to_wiphy(cfg_priv);
4242 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4248 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
4250 return wl_update_wiphybands(cfg_priv);
4253 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
4255 struct net_device *ndev;
4256 struct wireless_dev *wdev;
4260 if (cfg_priv->dongle_up)
4263 ndev = cfg_to_ndev(cfg_priv);
4264 wdev = ndev->ieee80211_ptr;
4266 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4267 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4269 err = brcmf_dongle_eventmsg(ndev);
4271 goto default_conf_out;
4273 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
4274 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
4276 goto default_conf_out;
4277 WL_INFO("power save set to %s\n",
4278 (power_mode ? "enabled" : "disabled"));
4280 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
4283 goto default_conf_out;
4284 err = brcmf_dongle_mode(ndev, wdev->iftype);
4285 if (err && err != -EINPROGRESS)
4286 goto default_conf_out;
4287 err = brcmf_dongle_probecap(cfg_priv);
4289 goto default_conf_out;
4291 /* -EINPROGRESS: Call commit handler */
4295 cfg_priv->dongle_up = true;
4301 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
4303 char buf[10+IFNAMSIZ];
4307 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
4308 cfg_priv->debugfsdir = debugfs_create_dir(buf,
4309 cfg_to_wiphy(cfg_priv)->debugfsdir);
4311 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
4312 (u16 *)&cfg_priv->profile->beacon_interval);
4318 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
4319 (u8 *)&cfg_priv->profile->dtim_period);
4329 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
4331 debugfs_remove_recursive(cfg_priv->debugfsdir);
4332 cfg_priv->debugfsdir = NULL;
4335 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
4339 set_bit(WL_STATUS_READY, &cfg_priv->status);
4341 brcmf_debugfs_add_netdev_params(cfg_priv);
4343 err = brcmf_config_dongle(cfg_priv);
4347 brcmf_invoke_iscan(cfg_priv);
4352 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
4355 * While going down, if associated with AP disassociate
4356 * from AP to save power
4358 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
4359 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
4360 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
4361 WL_INFO("Disassociating from AP");
4362 brcmf_link_down(cfg_priv);
4364 /* Make sure WPA_Supplicant receives all the event
4365 generated due to DISASSOC call to the fw to keep
4366 the state fw and WPA_Supplicant state consistent
4371 brcmf_abort_scanning(cfg_priv);
4372 clear_bit(WL_STATUS_READY, &cfg_priv->status);
4374 brcmf_debugfs_remove_netdev(cfg_priv);
4379 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
4381 struct brcmf_cfg80211_priv *cfg_priv;
4384 cfg_priv = brcmf_priv_get(cfg_dev);
4385 mutex_lock(&cfg_priv->usr_sync);
4386 err = __brcmf_cfg80211_up(cfg_priv);
4387 mutex_unlock(&cfg_priv->usr_sync);
4392 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
4394 struct brcmf_cfg80211_priv *cfg_priv;
4397 cfg_priv = brcmf_priv_get(cfg_dev);
4398 mutex_lock(&cfg_priv->usr_sync);
4399 err = __brcmf_cfg80211_down(cfg_priv);
4400 mutex_unlock(&cfg_priv->usr_sync);
4405 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
4408 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
4411 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
4412 WL_ERR("ei crosses buffer boundary\n");
4415 ie->buf[ie->offset] = t;
4416 ie->buf[ie->offset + 1] = l;
4417 memcpy(&ie->buf[ie->offset + 2], v, l);
4418 ie->offset += l + 2;