2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/if_arp.h>
21 #include <linux/sched.h>
22 #include <linux/kthread.h>
23 #include <linux/netdevice.h>
24 #include <linux/bitops.h>
25 #include <linux/etherdevice.h>
26 #include <linux/ieee80211.h>
27 #include <linux/uaccess.h>
28 #include <net/cfg80211.h>
30 #include <brcmu_utils.h>
32 #include <brcmu_wifi.h>
34 #include "wl_cfg80211.h"
36 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
37 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
39 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
41 static u32 brcmf_dbg_level = WL_DBG_ERR;
43 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
45 dev->driver_data = data;
48 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
53 data = dev->driver_data;
58 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
60 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
64 static bool check_sys_up(struct wiphy *wiphy)
66 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
67 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
68 WL_INFO("device is not ready : status (%d)\n",
69 (int)cfg_priv->status);
75 #define CHAN2G(_channel, _freq, _flags) { \
76 .band = IEEE80211_BAND_2GHZ, \
77 .center_freq = (_freq), \
78 .hw_value = (_channel), \
80 .max_antenna_gain = 0, \
84 #define CHAN5G(_channel, _flags) { \
85 .band = IEEE80211_BAND_5GHZ, \
86 .center_freq = 5000 + (5 * (_channel)), \
87 .hw_value = (_channel), \
89 .max_antenna_gain = 0, \
93 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
94 #define RATETAB_ENT(_rateid, _flags) \
96 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
97 .hw_value = (_rateid), \
101 static struct ieee80211_rate __wl_rates[] = {
102 RATETAB_ENT(BRCM_RATE_1M, 0),
103 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
104 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
105 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
106 RATETAB_ENT(BRCM_RATE_6M, 0),
107 RATETAB_ENT(BRCM_RATE_9M, 0),
108 RATETAB_ENT(BRCM_RATE_12M, 0),
109 RATETAB_ENT(BRCM_RATE_18M, 0),
110 RATETAB_ENT(BRCM_RATE_24M, 0),
111 RATETAB_ENT(BRCM_RATE_36M, 0),
112 RATETAB_ENT(BRCM_RATE_48M, 0),
113 RATETAB_ENT(BRCM_RATE_54M, 0),
116 #define wl_a_rates (__wl_rates + 4)
117 #define wl_a_rates_size 8
118 #define wl_g_rates (__wl_rates + 0)
119 #define wl_g_rates_size 12
121 static struct ieee80211_channel __wl_2ghz_channels[] = {
138 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
139 CHAN5G(34, 0), CHAN5G(36, 0),
140 CHAN5G(38, 0), CHAN5G(40, 0),
141 CHAN5G(42, 0), CHAN5G(44, 0),
142 CHAN5G(46, 0), CHAN5G(48, 0),
143 CHAN5G(52, 0), CHAN5G(56, 0),
144 CHAN5G(60, 0), CHAN5G(64, 0),
145 CHAN5G(100, 0), CHAN5G(104, 0),
146 CHAN5G(108, 0), CHAN5G(112, 0),
147 CHAN5G(116, 0), CHAN5G(120, 0),
148 CHAN5G(124, 0), CHAN5G(128, 0),
149 CHAN5G(132, 0), CHAN5G(136, 0),
150 CHAN5G(140, 0), CHAN5G(149, 0),
151 CHAN5G(153, 0), CHAN5G(157, 0),
152 CHAN5G(161, 0), CHAN5G(165, 0),
153 CHAN5G(184, 0), CHAN5G(188, 0),
154 CHAN5G(192, 0), CHAN5G(196, 0),
155 CHAN5G(200, 0), CHAN5G(204, 0),
156 CHAN5G(208, 0), CHAN5G(212, 0),
160 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
161 CHAN5G(32, 0), CHAN5G(34, 0),
162 CHAN5G(36, 0), CHAN5G(38, 0),
163 CHAN5G(40, 0), CHAN5G(42, 0),
164 CHAN5G(44, 0), CHAN5G(46, 0),
165 CHAN5G(48, 0), CHAN5G(50, 0),
166 CHAN5G(52, 0), CHAN5G(54, 0),
167 CHAN5G(56, 0), CHAN5G(58, 0),
168 CHAN5G(60, 0), CHAN5G(62, 0),
169 CHAN5G(64, 0), CHAN5G(66, 0),
170 CHAN5G(68, 0), CHAN5G(70, 0),
171 CHAN5G(72, 0), CHAN5G(74, 0),
172 CHAN5G(76, 0), CHAN5G(78, 0),
173 CHAN5G(80, 0), CHAN5G(82, 0),
174 CHAN5G(84, 0), CHAN5G(86, 0),
175 CHAN5G(88, 0), CHAN5G(90, 0),
176 CHAN5G(92, 0), CHAN5G(94, 0),
177 CHAN5G(96, 0), CHAN5G(98, 0),
178 CHAN5G(100, 0), CHAN5G(102, 0),
179 CHAN5G(104, 0), CHAN5G(106, 0),
180 CHAN5G(108, 0), CHAN5G(110, 0),
181 CHAN5G(112, 0), CHAN5G(114, 0),
182 CHAN5G(116, 0), CHAN5G(118, 0),
183 CHAN5G(120, 0), CHAN5G(122, 0),
184 CHAN5G(124, 0), CHAN5G(126, 0),
185 CHAN5G(128, 0), CHAN5G(130, 0),
186 CHAN5G(132, 0), CHAN5G(134, 0),
187 CHAN5G(136, 0), CHAN5G(138, 0),
188 CHAN5G(140, 0), CHAN5G(142, 0),
189 CHAN5G(144, 0), CHAN5G(145, 0),
190 CHAN5G(146, 0), CHAN5G(147, 0),
191 CHAN5G(148, 0), CHAN5G(149, 0),
192 CHAN5G(150, 0), CHAN5G(151, 0),
193 CHAN5G(152, 0), CHAN5G(153, 0),
194 CHAN5G(154, 0), CHAN5G(155, 0),
195 CHAN5G(156, 0), CHAN5G(157, 0),
196 CHAN5G(158, 0), CHAN5G(159, 0),
197 CHAN5G(160, 0), CHAN5G(161, 0),
198 CHAN5G(162, 0), CHAN5G(163, 0),
199 CHAN5G(164, 0), CHAN5G(165, 0),
200 CHAN5G(166, 0), CHAN5G(168, 0),
201 CHAN5G(170, 0), CHAN5G(172, 0),
202 CHAN5G(174, 0), CHAN5G(176, 0),
203 CHAN5G(178, 0), CHAN5G(180, 0),
204 CHAN5G(182, 0), CHAN5G(184, 0),
205 CHAN5G(186, 0), CHAN5G(188, 0),
206 CHAN5G(190, 0), CHAN5G(192, 0),
207 CHAN5G(194, 0), CHAN5G(196, 0),
208 CHAN5G(198, 0), CHAN5G(200, 0),
209 CHAN5G(202, 0), CHAN5G(204, 0),
210 CHAN5G(206, 0), CHAN5G(208, 0),
211 CHAN5G(210, 0), CHAN5G(212, 0),
212 CHAN5G(214, 0), CHAN5G(216, 0),
213 CHAN5G(218, 0), CHAN5G(220, 0),
214 CHAN5G(222, 0), CHAN5G(224, 0),
215 CHAN5G(226, 0), CHAN5G(228, 0),
218 static struct ieee80211_supported_band __wl_band_2ghz = {
219 .band = IEEE80211_BAND_2GHZ,
220 .channels = __wl_2ghz_channels,
221 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
222 .bitrates = wl_g_rates,
223 .n_bitrates = wl_g_rates_size,
226 static struct ieee80211_supported_band __wl_band_5ghz_a = {
227 .band = IEEE80211_BAND_5GHZ,
228 .channels = __wl_5ghz_a_channels,
229 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
230 .bitrates = wl_a_rates,
231 .n_bitrates = wl_a_rates_size,
234 static struct ieee80211_supported_band __wl_band_5ghz_n = {
235 .band = IEEE80211_BAND_5GHZ,
236 .channels = __wl_5ghz_n_channels,
237 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
238 .bitrates = wl_a_rates,
239 .n_bitrates = wl_a_rates_size,
242 static const u32 __wl_cipher_suites[] = {
243 WLAN_CIPHER_SUITE_WEP40,
244 WLAN_CIPHER_SUITE_WEP104,
245 WLAN_CIPHER_SUITE_TKIP,
246 WLAN_CIPHER_SUITE_CCMP,
247 WLAN_CIPHER_SUITE_AES_CMAC,
250 /* function for reading/writing a single u32 from/to the dongle */
252 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
255 __le32 par_le = cpu_to_le32(*par);
257 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
258 *par = le32_to_cpu(par_le);
263 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
264 struct brcmf_wsec_key_le *key_le)
266 key_le->index = cpu_to_le32(key->index);
267 key_le->len = cpu_to_le32(key->len);
268 key_le->algo = cpu_to_le32(key->algo);
269 key_le->flags = cpu_to_le32(key->flags);
270 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
271 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
272 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
273 memcpy(key_le->data, key->data, sizeof(key->data));
274 memcpy(key_le->ea, key->ea, sizeof(key->ea));
277 static int send_key_to_dongle(struct net_device *ndev,
278 struct brcmf_wsec_key *key)
281 struct brcmf_wsec_key_le key_le;
283 convert_key_from_CPU(key, &key_le);
284 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
286 WL_ERR("WLC_SET_KEY error (%d)\n", err);
291 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
292 enum nl80211_iftype type, u32 *flags,
293 struct vif_params *params)
295 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
296 struct wireless_dev *wdev;
301 if (!check_sys_up(wiphy))
305 case NL80211_IFTYPE_MONITOR:
306 case NL80211_IFTYPE_WDS:
307 WL_ERR("type (%d) : currently we do not support this type\n",
310 case NL80211_IFTYPE_ADHOC:
311 cfg_priv->conf->mode = WL_MODE_IBSS;
314 case NL80211_IFTYPE_STATION:
315 cfg_priv->conf->mode = WL_MODE_BSS;
323 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
325 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
328 wdev = ndev->ieee80211_ptr;
332 WL_INFO("IF Type = %s\n",
333 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
341 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
343 s8 buf[BRCMF_DCMD_SMLEN];
348 val_le = cpu_to_le32(val);
349 len = brcmu_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
353 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
355 WL_ERR("error (%d)\n", err);
361 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
364 s8 buf[BRCMF_DCMD_SMLEN];
372 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
375 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
377 WL_ERR("error (%d)\n", err);
379 *retval = le32_to_cpu(var.val);
384 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
387 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
389 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
390 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
392 WL_ERR("fail to set mpc\n");
395 WL_INFO("MPC : %d\n", mpc);
399 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
400 struct brcmf_ssid *ssid)
402 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
403 params_le->bss_type = DOT11_BSSTYPE_ANY;
404 params_le->scan_type = 0;
405 params_le->channel_num = 0;
406 params_le->nprobes = cpu_to_le32(-1);
407 params_le->active_time = cpu_to_le32(-1);
408 params_le->passive_time = cpu_to_le32(-1);
409 params_le->home_time = cpu_to_le32(-1);
410 if (ssid && ssid->SSID_len)
411 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
415 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
416 s32 paramlen, void *bufptr, s32 buflen)
420 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
423 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
427 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
428 s32 paramlen, void *bufptr, s32 buflen)
432 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
435 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
439 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
440 struct brcmf_ssid *ssid, u16 action)
442 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
443 offsetof(struct brcmf_iscan_params_le, params_le);
444 struct brcmf_iscan_params_le *params;
447 if (ssid && ssid->SSID_len)
448 params_size += sizeof(struct brcmf_ssid);
449 params = kzalloc(params_size, GFP_KERNEL);
452 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
454 wl_iscan_prep(¶ms->params_le, ssid);
456 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
457 params->action = cpu_to_le16(action);
458 params->scan_duration = cpu_to_le16(0);
460 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
461 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
464 WL_INFO("system busy : iscan canceled\n");
466 WL_ERR("error (%d)\n", err);
473 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
475 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
476 struct net_device *ndev = cfg_to_ndev(cfg_priv);
477 struct brcmf_ssid ssid;
481 /* Broadcast scan by default */
482 memset(&ssid, 0, sizeof(ssid));
484 iscan->state = WL_ISCAN_STATE_SCANING;
486 passive_scan = cfg_priv->active_scan ? 0 : 1;
487 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
488 &passive_scan, sizeof(passive_scan));
490 WL_ERR("error (%d)\n", err);
493 brcmf_set_mpc(ndev, 0);
494 cfg_priv->iscan_kickstart = true;
495 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
497 brcmf_set_mpc(ndev, 1);
498 cfg_priv->iscan_kickstart = false;
501 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
507 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
508 struct cfg80211_scan_request *request,
509 struct cfg80211_ssid *this_ssid)
511 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
512 struct cfg80211_ssid *ssids;
513 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
520 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
521 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
524 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
525 WL_ERR("Scanning being aborted : status (%lu)\n",
529 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
530 WL_ERR("Connecting : status (%lu)\n",
539 ssids = request->ssids;
540 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
544 /* we don't do iscan in ibss */
548 cfg_priv->scan_request = request;
549 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
551 err = brcmf_do_iscan(cfg_priv);
557 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
558 ssids->ssid, ssids->ssid_len);
559 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
560 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
561 sr->ssid_le.SSID_len = cpu_to_le32(0);
563 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
564 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
567 WL_SCAN("Broadcast scan\n");
570 passive_scan = cfg_priv->active_scan ? 0 : 1;
571 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
572 &passive_scan, sizeof(passive_scan));
574 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
577 brcmf_set_mpc(ndev, 0);
578 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
579 sizeof(sr->ssid_le));
582 WL_INFO("system busy : scan for \"%s\" "
583 "canceled\n", sr->ssid_le.SSID);
585 WL_ERR("WLC_SCAN error (%d)\n", err);
587 brcmf_set_mpc(ndev, 1);
595 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
596 cfg_priv->scan_request = NULL;
601 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
602 struct cfg80211_scan_request *request)
608 if (!check_sys_up(wiphy))
611 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
613 WL_ERR("scan error (%d)\n", err);
619 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
623 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
625 WL_ERR("Error (%d)\n", err);
630 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
634 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
636 WL_ERR("Error (%d)\n", err);
641 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
644 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
646 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
648 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
654 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
656 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
657 struct net_device *ndev = cfg_to_ndev(cfg_priv);
661 if (!check_sys_up(wiphy))
664 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
665 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
666 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
667 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
671 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
672 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
673 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
674 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
678 if (changed & WIPHY_PARAM_RETRY_LONG
679 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
680 cfg_priv->conf->retry_long = wiphy->retry_long;
681 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
685 if (changed & WIPHY_PARAM_RETRY_SHORT
686 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
687 cfg_priv->conf->retry_short = wiphy->retry_short;
688 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
698 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
702 return &cfg_priv->profile->sec;
704 return &cfg_priv->profile->bssid;
706 return &cfg_priv->profile->ssid;
708 WL_ERR("invalid item (%d)\n", item);
713 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
714 const struct brcmf_event_msg *e, void *data, s32 item)
717 struct brcmf_ssid *ssid;
721 ssid = (struct brcmf_ssid *) data;
722 memset(cfg_priv->profile->ssid.SSID, 0,
723 sizeof(cfg_priv->profile->ssid.SSID));
724 memcpy(cfg_priv->profile->ssid.SSID,
725 ssid->SSID, ssid->SSID_len);
726 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
730 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
732 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
735 memcpy(&cfg_priv->profile->sec, data,
736 sizeof(cfg_priv->profile->sec));
738 case WL_PROF_BEACONINT:
739 cfg_priv->profile->beacon_interval = *(u16 *)data;
741 case WL_PROF_DTIMPERIOD:
742 cfg_priv->profile->dtim_period = *(u8 *)data;
745 WL_ERR("unsupported item (%d)\n", item);
753 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
755 memset(prof, 0, sizeof(*prof));
758 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
759 size_t *join_params_size)
764 if (ch <= CH_MAX_2G_CHANNEL)
765 chanspec |= WL_CHANSPEC_BAND_2G;
767 chanspec |= WL_CHANSPEC_BAND_5G;
769 chanspec |= WL_CHANSPEC_BW_20;
770 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
772 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
775 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
776 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
777 join_params->params_le.chanspec_num = cpu_to_le32(1);
779 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
780 "channel %d, chanspec %#X\n",
781 chanspec, ch, chanspec);
785 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
787 struct net_device *ndev = NULL;
792 if (cfg_priv->link_up) {
793 ndev = cfg_to_ndev(cfg_priv);
794 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
795 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
797 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
798 cfg_priv->link_up = false;
804 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
805 struct cfg80211_ibss_params *params)
807 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
808 struct brcmf_join_params join_params;
809 size_t join_params_size = 0;
813 struct brcmf_ssid ssid;
816 if (!check_sys_up(wiphy))
820 WL_CONN("SSID: %s\n", params->ssid);
822 WL_CONN("SSID: NULL, Not supported\n");
826 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
829 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
830 params->bssid[0], params->bssid[1], params->bssid[2],
831 params->bssid[3], params->bssid[4], params->bssid[5]);
833 WL_CONN("No BSSID specified\n");
836 WL_CONN("channel: %d\n", params->channel->center_freq);
838 WL_CONN("no channel specified\n");
840 if (params->channel_fixed)
841 WL_CONN("fixed channel required\n");
843 WL_CONN("no fixed channel required\n");
845 if (params->ie && params->ie_len)
846 WL_CONN("ie len: %d\n", params->ie_len);
848 WL_CONN("no ie specified\n");
850 if (params->beacon_interval)
851 WL_CONN("beacon interval: %d\n", params->beacon_interval);
853 WL_CONN("no beacon interval specified\n");
855 if (params->basic_rates)
856 WL_CONN("basic rates: %08X\n", params->basic_rates);
858 WL_CONN("no basic rates specified\n");
861 WL_CONN("privacy required\n");
863 WL_CONN("no privacy required\n");
865 /* Configure Privacy for starter */
869 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
871 WL_ERR("wsec failed (%d)\n", err);
875 /* Configure Beacon Interval for starter */
876 if (params->beacon_interval)
877 bcnprd = params->beacon_interval;
881 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
883 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
887 /* Configure required join parameter */
888 memset(&join_params, 0, sizeof(struct brcmf_join_params));
891 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
892 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
893 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
894 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
895 join_params_size = sizeof(join_params.ssid_le);
896 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
900 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
901 join_params_size = sizeof(join_params.ssid_le) +
902 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
904 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
907 brcmf_update_prof(cfg_priv, NULL,
908 &join_params.params_le.bssid, WL_PROF_BSSID);
911 if (params->channel) {
915 ieee80211_frequency_to_channel(
916 params->channel->center_freq);
917 if (params->channel_fixed) {
918 /* adding chanspec */
919 brcmf_ch_to_chanspec(cfg_priv->channel,
920 &join_params, &join_params_size);
923 /* set channel for starter */
924 target_channel = cfg_priv->channel;
925 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
928 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
932 cfg_priv->channel = 0;
934 cfg_priv->ibss_starter = false;
937 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
938 &join_params, join_params_size);
940 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
946 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
952 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
954 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
958 if (!check_sys_up(wiphy))
961 brcmf_link_down(cfg_priv);
968 static s32 brcmf_set_wpa_version(struct net_device *ndev,
969 struct cfg80211_connect_params *sme)
971 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
972 struct brcmf_cfg80211_security *sec;
976 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
977 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
978 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
979 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
981 val = WPA_AUTH_DISABLED;
982 WL_CONN("setting wpa_auth to 0x%0x\n", val);
983 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
985 WL_ERR("set wpa_auth failed (%d)\n", err);
988 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
989 sec->wpa_versions = sme->crypto.wpa_versions;
993 static s32 brcmf_set_auth_type(struct net_device *ndev,
994 struct cfg80211_connect_params *sme)
996 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
997 struct brcmf_cfg80211_security *sec;
1001 switch (sme->auth_type) {
1002 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1004 WL_CONN("open system\n");
1006 case NL80211_AUTHTYPE_SHARED_KEY:
1008 WL_CONN("shared key\n");
1010 case NL80211_AUTHTYPE_AUTOMATIC:
1012 WL_CONN("automatic\n");
1014 case NL80211_AUTHTYPE_NETWORK_EAP:
1015 WL_CONN("network eap\n");
1018 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1022 err = brcmf_dev_intvar_set(ndev, "auth", val);
1024 WL_ERR("set auth failed (%d)\n", err);
1027 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1028 sec->auth_type = sme->auth_type;
1033 brcmf_set_set_cipher(struct net_device *ndev,
1034 struct cfg80211_connect_params *sme)
1036 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1037 struct brcmf_cfg80211_security *sec;
1042 if (sme->crypto.n_ciphers_pairwise) {
1043 switch (sme->crypto.ciphers_pairwise[0]) {
1044 case WLAN_CIPHER_SUITE_WEP40:
1045 case WLAN_CIPHER_SUITE_WEP104:
1048 case WLAN_CIPHER_SUITE_TKIP:
1049 pval = TKIP_ENABLED;
1051 case WLAN_CIPHER_SUITE_CCMP:
1054 case WLAN_CIPHER_SUITE_AES_CMAC:
1058 WL_ERR("invalid cipher pairwise (%d)\n",
1059 sme->crypto.ciphers_pairwise[0]);
1063 if (sme->crypto.cipher_group) {
1064 switch (sme->crypto.cipher_group) {
1065 case WLAN_CIPHER_SUITE_WEP40:
1066 case WLAN_CIPHER_SUITE_WEP104:
1069 case WLAN_CIPHER_SUITE_TKIP:
1070 gval = TKIP_ENABLED;
1072 case WLAN_CIPHER_SUITE_CCMP:
1075 case WLAN_CIPHER_SUITE_AES_CMAC:
1079 WL_ERR("invalid cipher group (%d)\n",
1080 sme->crypto.cipher_group);
1085 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1086 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1088 WL_ERR("error (%d)\n", err);
1092 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1093 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1094 sec->cipher_group = sme->crypto.cipher_group;
1100 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1102 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1103 struct brcmf_cfg80211_security *sec;
1107 if (sme->crypto.n_akm_suites) {
1108 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1110 WL_ERR("could not get wpa_auth (%d)\n", err);
1113 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1114 switch (sme->crypto.akm_suites[0]) {
1115 case WLAN_AKM_SUITE_8021X:
1116 val = WPA_AUTH_UNSPECIFIED;
1118 case WLAN_AKM_SUITE_PSK:
1122 WL_ERR("invalid cipher group (%d)\n",
1123 sme->crypto.cipher_group);
1126 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1127 switch (sme->crypto.akm_suites[0]) {
1128 case WLAN_AKM_SUITE_8021X:
1129 val = WPA2_AUTH_UNSPECIFIED;
1131 case WLAN_AKM_SUITE_PSK:
1132 val = WPA2_AUTH_PSK;
1135 WL_ERR("invalid cipher group (%d)\n",
1136 sme->crypto.cipher_group);
1141 WL_CONN("setting wpa_auth to %d\n", val);
1142 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1144 WL_ERR("could not set wpa_auth (%d)\n", err);
1148 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1149 sec->wpa_auth = sme->crypto.akm_suites[0];
1155 brcmf_set_set_sharedkey(struct net_device *ndev,
1156 struct cfg80211_connect_params *sme)
1158 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1159 struct brcmf_cfg80211_security *sec;
1160 struct brcmf_wsec_key key;
1164 WL_CONN("key len (%d)\n", sme->key_len);
1166 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1167 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1168 sec->wpa_versions, sec->cipher_pairwise);
1170 (sec->wpa_versions & (NL80211_WPA_VERSION_1 |
1171 NL80211_WPA_VERSION_2))
1172 && (sec->cipher_pairwise & (WLAN_CIPHER_SUITE_WEP40 |
1173 WLAN_CIPHER_SUITE_WEP104))) {
1174 memset(&key, 0, sizeof(key));
1175 key.len = (u32) sme->key_len;
1176 key.index = (u32) sme->key_idx;
1177 if (key.len > sizeof(key.data)) {
1178 WL_ERR("Too long key length (%u)\n", key.len);
1181 memcpy(key.data, sme->key, key.len);
1182 key.flags = BRCMF_PRIMARY_KEY;
1183 switch (sec->cipher_pairwise) {
1184 case WLAN_CIPHER_SUITE_WEP40:
1185 key.algo = CRYPTO_ALGO_WEP1;
1187 case WLAN_CIPHER_SUITE_WEP104:
1188 key.algo = CRYPTO_ALGO_WEP128;
1191 WL_ERR("Invalid algorithm (%d)\n",
1192 sme->crypto.ciphers_pairwise[0]);
1195 /* Set the new key/index */
1196 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1197 key.len, key.index, key.algo);
1198 WL_CONN("key \"%s\"\n", key.data);
1199 err = send_key_to_dongle(ndev, &key);
1203 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1204 WL_CONN("set auth_type to shared key\n");
1205 val = 1; /* shared key */
1206 err = brcmf_dev_intvar_set(ndev, "auth", val);
1208 WL_ERR("set auth failed (%d)\n", err);
1218 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1219 struct cfg80211_connect_params *sme)
1221 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1222 struct ieee80211_channel *chan = sme->channel;
1223 struct brcmf_join_params join_params;
1224 size_t join_params_size;
1225 struct brcmf_ssid ssid;
1229 WL_TRACE("Enter\n");
1230 if (!check_sys_up(wiphy))
1234 WL_ERR("Invalid ssid\n");
1238 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1242 ieee80211_frequency_to_channel(chan->center_freq);
1243 WL_CONN("channel (%d), center_req (%d)\n",
1244 cfg_priv->channel, chan->center_freq);
1246 cfg_priv->channel = 0;
1248 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1250 err = brcmf_set_wpa_version(ndev, sme);
1252 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1256 err = brcmf_set_auth_type(ndev, sme);
1258 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1262 err = brcmf_set_set_cipher(ndev, sme);
1264 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1268 err = brcmf_set_key_mgmt(ndev, sme);
1270 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1274 err = brcmf_set_set_sharedkey(ndev, sme);
1276 WL_ERR("wl_set_set_sharedkey failed (%d)\n", err);
1280 memset(&join_params, 0, sizeof(join_params));
1281 join_params_size = sizeof(join_params.ssid_le);
1283 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
1284 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1285 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1286 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1287 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1289 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1291 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1292 WL_CONN("ssid \"%s\", len (%d)\n",
1293 ssid.SSID, ssid.SSID_len);
1295 brcmf_ch_to_chanspec(cfg_priv->channel,
1296 &join_params, &join_params_size);
1297 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1298 &join_params, join_params_size);
1300 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1304 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1310 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1313 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1314 struct brcmf_scb_val_le scbval;
1317 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1318 if (!check_sys_up(wiphy))
1321 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1323 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1324 scbval.val = cpu_to_le32(reason_code);
1325 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1326 sizeof(struct brcmf_scb_val_le));
1328 WL_ERR("error (%d)\n", err);
1330 cfg_priv->link_up = false;
1337 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1338 enum nl80211_tx_power_setting type, s32 dbm)
1341 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1342 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1347 WL_TRACE("Enter\n");
1348 if (!check_sys_up(wiphy))
1352 case NL80211_TX_POWER_AUTOMATIC:
1354 case NL80211_TX_POWER_LIMITED:
1356 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1361 case NL80211_TX_POWER_FIXED:
1363 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1369 /* Make sure radio is off or on as far as software is concerned */
1370 disable = WL_RADIO_SW_DISABLE << 16;
1371 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1373 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1378 txpwrmw = (u16) dbm;
1379 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1380 (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1382 WL_ERR("qtxpower error (%d)\n", err);
1383 cfg_priv->conf->tx_power = dbm;
1390 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1392 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1393 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1398 WL_TRACE("Enter\n");
1399 if (!check_sys_up(wiphy))
1402 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1404 WL_ERR("error (%d)\n", err);
1408 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1409 *dbm = (s32) brcmu_qdbm_to_mw(result);
1417 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1418 u8 key_idx, bool unicast, bool multicast)
1424 WL_TRACE("Enter\n");
1425 WL_CONN("key index (%d)\n", key_idx);
1426 if (!check_sys_up(wiphy))
1429 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1431 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1435 if (wsec & WEP_ENABLED) {
1436 /* Just select a new current key */
1438 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1441 WL_ERR("error (%d)\n", err);
1449 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1450 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1452 struct brcmf_wsec_key key;
1453 struct brcmf_wsec_key_le key_le;
1456 memset(&key, 0, sizeof(key));
1457 key.index = (u32) key_idx;
1458 /* Instead of bcast for ea address for default wep keys,
1459 driver needs it to be Null */
1460 if (!is_multicast_ether_addr(mac_addr))
1461 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1462 key.len = (u32) params->key_len;
1463 /* check for key index change */
1466 err = send_key_to_dongle(ndev, &key);
1470 if (key.len > sizeof(key.data)) {
1471 WL_ERR("Invalid key length (%d)\n", key.len);
1475 WL_CONN("Setting the key index %d\n", key.index);
1476 memcpy(key.data, params->key, key.len);
1478 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1480 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1481 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1482 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1485 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1486 if (params->seq && params->seq_len == 6) {
1489 ivptr = (u8 *) params->seq;
1490 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1491 (ivptr[3] << 8) | ivptr[2];
1492 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1493 key.iv_initialized = true;
1496 switch (params->cipher) {
1497 case WLAN_CIPHER_SUITE_WEP40:
1498 key.algo = CRYPTO_ALGO_WEP1;
1499 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1501 case WLAN_CIPHER_SUITE_WEP104:
1502 key.algo = CRYPTO_ALGO_WEP128;
1503 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1505 case WLAN_CIPHER_SUITE_TKIP:
1506 key.algo = CRYPTO_ALGO_TKIP;
1507 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1509 case WLAN_CIPHER_SUITE_AES_CMAC:
1510 key.algo = CRYPTO_ALGO_AES_CCM;
1511 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1513 case WLAN_CIPHER_SUITE_CCMP:
1514 key.algo = CRYPTO_ALGO_AES_CCM;
1515 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1518 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1521 convert_key_from_CPU(&key, &key_le);
1523 brcmf_netdev_wait_pend8021x(ndev);
1524 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1527 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1535 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1536 u8 key_idx, bool pairwise, const u8 *mac_addr,
1537 struct key_params *params)
1539 struct brcmf_wsec_key key;
1545 WL_TRACE("Enter\n");
1546 WL_CONN("key index (%d)\n", key_idx);
1547 if (!check_sys_up(wiphy))
1552 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1554 memset(&key, 0, sizeof(key));
1556 key.len = (u32) params->key_len;
1557 key.index = (u32) key_idx;
1559 if (key.len > sizeof(key.data)) {
1560 WL_ERR("Too long key length (%u)\n", key.len);
1564 memcpy(key.data, params->key, key.len);
1566 key.flags = BRCMF_PRIMARY_KEY;
1567 switch (params->cipher) {
1568 case WLAN_CIPHER_SUITE_WEP40:
1569 key.algo = CRYPTO_ALGO_WEP1;
1570 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1572 case WLAN_CIPHER_SUITE_WEP104:
1573 key.algo = CRYPTO_ALGO_WEP128;
1574 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1576 case WLAN_CIPHER_SUITE_TKIP:
1577 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1578 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1579 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1580 key.algo = CRYPTO_ALGO_TKIP;
1581 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1583 case WLAN_CIPHER_SUITE_AES_CMAC:
1584 key.algo = CRYPTO_ALGO_AES_CCM;
1585 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1587 case WLAN_CIPHER_SUITE_CCMP:
1588 key.algo = CRYPTO_ALGO_AES_CCM;
1589 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1592 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1597 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1602 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1604 WL_ERR("get wsec error (%d)\n", err);
1607 wsec &= ~(WEP_ENABLED);
1609 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1611 WL_ERR("set wsec error (%d)\n", err);
1615 val = 1; /* assume shared key. otherwise 0 */
1616 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1618 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1625 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1626 u8 key_idx, bool pairwise, const u8 *mac_addr)
1628 struct brcmf_wsec_key key;
1633 WL_TRACE("Enter\n");
1634 if (!check_sys_up(wiphy))
1637 memset(&key, 0, sizeof(key));
1639 key.index = (u32) key_idx;
1640 key.flags = BRCMF_PRIMARY_KEY;
1641 key.algo = CRYPTO_ALGO_OFF;
1643 WL_CONN("key index (%d)\n", key_idx);
1645 /* Set the new key/index */
1646 err = send_key_to_dongle(ndev, &key);
1648 if (err == -EINVAL) {
1649 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1650 /* we ignore this key index in this case */
1651 WL_ERR("invalid key index (%d)\n", key_idx);
1653 /* Ignore this error, may happen during DISASSOC */
1659 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1661 WL_ERR("get wsec error (%d)\n", err);
1662 /* Ignore this error, may happen during DISASSOC */
1666 wsec &= ~(WEP_ENABLED);
1668 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1670 WL_ERR("set wsec error (%d)\n", err);
1671 /* Ignore this error, may happen during DISASSOC */
1676 val = 0; /* assume open key. otherwise 1 */
1677 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1679 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1680 /* Ignore this error, may happen during DISASSOC */
1689 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1690 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1691 void (*callback) (void *cookie, struct key_params * params))
1693 struct key_params params;
1694 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1695 struct brcmf_cfg80211_security *sec;
1699 WL_TRACE("Enter\n");
1700 WL_CONN("key index (%d)\n", key_idx);
1701 if (!check_sys_up(wiphy))
1704 memset(¶ms, 0, sizeof(params));
1706 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1708 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1709 /* Ignore this error, may happen during DISASSOC */
1715 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1716 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1717 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1718 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1719 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1720 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1721 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1725 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1726 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1729 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1730 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1733 WL_ERR("Invalid algo (0x%x)\n", wsec);
1737 callback(cookie, ¶ms);
1745 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1746 struct net_device *ndev, u8 key_idx)
1748 WL_INFO("Not supported\n");
1754 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1755 u8 *mac, struct station_info *sinfo)
1757 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1758 struct brcmf_scb_val_le scb_val;
1762 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1764 WL_TRACE("Enter\n");
1765 if (!check_sys_up(wiphy))
1768 if (memcmp(mac, bssid, ETH_ALEN)) {
1769 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1770 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1771 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1772 bssid[0], bssid[1], bssid[2], bssid[3],
1773 bssid[4], bssid[5]);
1778 /* Report the current tx rate */
1779 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1781 WL_ERR("Could not get rate (%d)\n", err);
1783 sinfo->filled |= STATION_INFO_TX_BITRATE;
1784 sinfo->txrate.legacy = rate * 5;
1785 WL_CONN("Rate %d Mbps\n", rate / 2);
1788 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1789 scb_val.val = cpu_to_le32(0);
1790 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1791 sizeof(struct brcmf_scb_val_le));
1793 WL_ERR("Could not get rssi (%d)\n", err);
1795 rssi = le32_to_cpu(scb_val.val);
1796 sinfo->filled |= STATION_INFO_SIGNAL;
1797 sinfo->signal = rssi;
1798 WL_CONN("RSSI %d dBm\n", rssi);
1807 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1808 bool enabled, s32 timeout)
1812 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1814 WL_TRACE("Enter\n");
1817 * Powersave enable/disable request is coming from the
1818 * cfg80211 even before the interface is up. In that
1819 * scenario, driver will be storing the power save
1820 * preference in cfg_priv struct to apply this to
1821 * FW later while initializing the dongle
1823 cfg_priv->pwr_save = enabled;
1824 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1826 WL_INFO("Device is not ready,"
1827 "storing the value in cfg_priv struct\n");
1831 pm = enabled ? PM_FAST : PM_OFF;
1832 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1834 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1837 WL_ERR("net_device is not ready yet\n");
1839 WL_ERR("error (%d)\n", err);
1847 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1849 const struct cfg80211_bitrate_mask *mask)
1851 struct brcm_rateset_le rateset_le;
1859 WL_TRACE("Enter\n");
1860 if (!check_sys_up(wiphy))
1863 /* addr param is always NULL. ignore it */
1864 /* Get current rateset */
1865 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1866 sizeof(rateset_le));
1868 WL_ERR("could not get current rateset (%d)\n", err);
1872 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1874 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1877 val = wl_g_rates[legacy - 1].bitrate * 100000;
1879 if (val < le32_to_cpu(rateset_le.count))
1880 /* Select rate by rateset index */
1881 rate = rateset_le.rates[val] & 0x7f;
1883 /* Specified rate in bps */
1884 rate = val / 500000;
1886 WL_CONN("rate %d mbps\n", rate / 2);
1890 * Set rate override,
1891 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1893 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1894 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1895 if (err_bg && err_a) {
1896 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1897 err = err_bg | err_a;
1905 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1906 struct brcmf_bss_info *bi)
1908 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1909 struct ieee80211_channel *notify_channel;
1910 struct cfg80211_bss *bss;
1911 struct ieee80211_supported_band *band;
1915 u64 notify_timestamp;
1916 u16 notify_capability;
1917 u16 notify_interval;
1919 size_t notify_ielen;
1922 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
1923 WL_ERR("Bss info is larger than buffer. Discarding\n");
1927 channel = bi->ctl_ch ? bi->ctl_ch :
1928 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
1930 if (channel <= CH_MAX_2G_CHANNEL)
1931 band = wiphy->bands[IEEE80211_BAND_2GHZ];
1933 band = wiphy->bands[IEEE80211_BAND_5GHZ];
1935 freq = ieee80211_channel_to_frequency(channel, band->band);
1936 notify_channel = ieee80211_get_channel(wiphy, freq);
1938 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
1939 notify_capability = le16_to_cpu(bi->capability);
1940 notify_interval = le16_to_cpu(bi->beacon_period);
1941 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
1942 notify_ielen = le32_to_cpu(bi->ie_length);
1943 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
1945 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
1946 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
1947 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
1948 WL_CONN("Channel: %d(%d)\n", channel, freq);
1949 WL_CONN("Capability: %X\n", notify_capability);
1950 WL_CONN("Beacon interval: %d\n", notify_interval);
1951 WL_CONN("Signal: %d\n", notify_signal);
1952 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
1954 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
1955 notify_timestamp, notify_capability, notify_interval, notify_ie,
1956 notify_ielen, notify_signal, GFP_KERNEL);
1959 WL_ERR("cfg80211_inform_bss_frame error\n");
1966 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
1968 struct brcmf_scan_results *bss_list;
1969 struct brcmf_bss_info *bi = NULL; /* must be initialized */
1973 bss_list = cfg_priv->bss_list;
1974 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
1975 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
1979 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
1980 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
1981 bi = next_bss(bss_list, bi);
1982 err = brcmf_inform_single_bss(cfg_priv, bi);
1989 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
1990 struct net_device *ndev, const u8 *bssid)
1992 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1993 struct ieee80211_channel *notify_channel;
1994 struct brcmf_bss_info *bi = NULL;
1995 struct ieee80211_supported_band *band;
2000 u64 notify_timestamp;
2001 u16 notify_capability;
2002 u16 notify_interval;
2004 size_t notify_ielen;
2007 WL_TRACE("Enter\n");
2009 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2015 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2017 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2019 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2023 bi = (struct brcmf_bss_info *)(buf + 4);
2025 channel = bi->ctl_ch ? bi->ctl_ch :
2026 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2028 if (channel <= CH_MAX_2G_CHANNEL)
2029 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2031 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2033 freq = ieee80211_channel_to_frequency(channel, band->band);
2034 notify_channel = ieee80211_get_channel(wiphy, freq);
2036 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2037 notify_capability = le16_to_cpu(bi->capability);
2038 notify_interval = le16_to_cpu(bi->beacon_period);
2039 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2040 notify_ielen = le32_to_cpu(bi->ie_length);
2041 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2043 WL_CONN("channel: %d(%d)\n", channel, freq);
2044 WL_CONN("capability: %X\n", notify_capability);
2045 WL_CONN("beacon interval: %d\n", notify_interval);
2046 WL_CONN("signal: %d\n", notify_signal);
2047 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2049 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2050 notify_timestamp, notify_capability, notify_interval,
2051 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2062 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2064 return cfg_priv->conf->mode == WL_MODE_IBSS;
2067 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2069 struct brcmf_bss_info *bi;
2070 struct brcmf_ssid *ssid;
2071 struct brcmu_tlv *tim;
2072 u16 beacon_interval;
2078 WL_TRACE("Enter\n");
2079 if (brcmf_is_ibssmode(cfg_priv))
2082 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2084 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2085 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2086 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2088 WL_ERR("Could not get bss info %d\n", err);
2089 goto update_bss_info_out;
2092 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2093 err = brcmf_inform_single_bss(cfg_priv, bi);
2095 goto update_bss_info_out;
2097 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2098 ie_len = le32_to_cpu(bi->ie_length);
2099 beacon_interval = le16_to_cpu(bi->beacon_period);
2101 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2103 dtim_period = tim->data[1];
2106 * active scan was done so we could not get dtim
2107 * information out of probe response.
2108 * so we speficially query dtim information to dongle.
2111 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2112 "dtim_assoc", &var);
2114 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2115 goto update_bss_info_out;
2117 dtim_period = (u8)var;
2120 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2121 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2123 update_bss_info_out:
2128 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2130 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2131 struct brcmf_ssid ssid;
2133 if (cfg_priv->iscan_on) {
2134 iscan->state = WL_ISCAN_STATE_IDLE;
2136 if (iscan->timer_on) {
2137 del_timer_sync(&iscan->timer);
2138 iscan->timer_on = 0;
2141 cancel_work_sync(&iscan->work);
2143 /* Abort iscan running in FW */
2144 memset(&ssid, 0, sizeof(ssid));
2145 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2149 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2152 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2153 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2155 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2156 WL_ERR("Scan complete while device not scanning\n");
2159 if (cfg_priv->scan_request) {
2160 WL_SCAN("ISCAN Completed scan: %s\n",
2161 aborted ? "Aborted" : "Done");
2162 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2163 brcmf_set_mpc(ndev, 1);
2164 cfg_priv->scan_request = NULL;
2166 cfg_priv->iscan_kickstart = false;
2169 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2171 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2172 WL_SCAN("wake up iscan\n");
2173 schedule_work(&iscan->work);
2181 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2182 struct brcmf_scan_results **bss_list)
2184 struct brcmf_iscan_results list;
2185 struct brcmf_scan_results *results;
2186 struct brcmf_scan_results_le *results_le;
2187 struct brcmf_iscan_results *list_buf;
2190 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2191 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2192 results = &list_buf->results;
2193 results_le = &list_buf->results_le;
2194 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2195 results->version = 0;
2198 memset(&list, 0, sizeof(list));
2199 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2200 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2201 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2202 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2204 WL_ERR("error (%d)\n", err);
2207 results->buflen = le32_to_cpu(results_le->buflen);
2208 results->version = le32_to_cpu(results_le->version);
2209 results->count = le32_to_cpu(results_le->count);
2210 WL_SCAN("results->count = %d\n", results_le->count);
2211 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2212 *status = le32_to_cpu(list_buf->status_le);
2213 WL_SCAN("status = %d\n", *status);
2214 *bss_list = results;
2219 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2221 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2224 iscan->state = WL_ISCAN_STATE_IDLE;
2225 brcmf_inform_bss(cfg_priv);
2226 brcmf_notify_iscan_complete(iscan, false);
2231 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2233 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2236 /* Reschedule the timer */
2237 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2238 iscan->timer_on = 1;
2243 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2245 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2248 brcmf_inform_bss(cfg_priv);
2249 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2250 /* Reschedule the timer */
2251 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2252 iscan->timer_on = 1;
2257 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2259 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2262 iscan->state = WL_ISCAN_STATE_IDLE;
2263 brcmf_notify_iscan_complete(iscan, true);
2268 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2270 struct brcmf_cfg80211_iscan_ctrl *iscan =
2271 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2273 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2274 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2275 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2277 if (iscan->timer_on) {
2278 del_timer_sync(&iscan->timer);
2279 iscan->timer_on = 0;
2282 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2283 status = BRCMF_SCAN_RESULTS_ABORTED;
2284 WL_ERR("Abort iscan\n");
2287 el->handler[status](cfg_priv);
2290 static void brcmf_iscan_timer(unsigned long data)
2292 struct brcmf_cfg80211_iscan_ctrl *iscan =
2293 (struct brcmf_cfg80211_iscan_ctrl *)data;
2296 iscan->timer_on = 0;
2297 WL_SCAN("timer expired\n");
2298 brcmf_wakeup_iscan(iscan);
2302 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2304 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2306 if (cfg_priv->iscan_on) {
2307 iscan->state = WL_ISCAN_STATE_IDLE;
2308 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2314 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2316 memset(el, 0, sizeof(*el));
2317 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2318 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2319 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2320 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2321 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2324 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2326 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2329 if (cfg_priv->iscan_on) {
2330 iscan->ndev = cfg_to_ndev(cfg_priv);
2331 brcmf_init_iscan_eloop(&iscan->el);
2332 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2333 init_timer(&iscan->timer);
2334 iscan->timer.data = (unsigned long) iscan;
2335 iscan->timer.function = brcmf_iscan_timer;
2336 err = brcmf_invoke_iscan(cfg_priv);
2338 iscan->data = cfg_priv;
2344 static void brcmf_delay(u32 ms)
2346 if (ms < 1000 / HZ) {
2354 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2356 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2359 * Check for WL_STATUS_READY before any function call which
2360 * could result is bus access. Don't block the resume for
2361 * any driver error conditions
2363 WL_TRACE("Enter\n");
2365 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2366 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2372 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2373 struct cfg80211_wowlan *wow)
2375 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2376 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2378 WL_TRACE("Enter\n");
2381 * Check for WL_STATUS_READY before any function call which
2382 * could result is bus access. Don't block the suspend for
2383 * any driver error conditions
2387 * While going to suspend if associated with AP disassociate
2388 * from AP to save power while system is in suspended state
2390 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2391 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2392 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2393 WL_INFO("Disassociating from AP"
2394 " while entering suspend state\n");
2395 brcmf_link_down(cfg_priv);
2398 * Make sure WPA_Supplicant receives all the event
2399 * generated due to DISASSOC call to the fw to keep
2400 * the state fw and WPA_Supplicant state consistent
2405 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2406 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2407 brcmf_term_iscan(cfg_priv);
2409 if (cfg_priv->scan_request) {
2410 /* Indidate scan abort to cfg80211 layer */
2411 WL_INFO("Terminating scan in progress\n");
2412 cfg80211_scan_done(cfg_priv->scan_request, true);
2413 cfg_priv->scan_request = NULL;
2415 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2416 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2418 /* Turn off watchdog timer */
2419 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2420 WL_INFO("Enable MPC\n");
2421 brcmf_set_mpc(ndev, 1);
2430 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2432 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2435 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2439 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2444 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2447 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2451 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2454 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2457 WL_ERR("error (%d)\n", err);
2460 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2466 brcmf_update_pmklist(struct net_device *ndev,
2467 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2471 WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2472 for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2473 WL_CONN("PMKID[%d]: %pM =\n", i,
2474 &pmk_list->pmkids.pmkid[i].BSSID);
2475 for (j = 0; j < WLAN_PMKID_LEN; j++)
2476 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2480 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2487 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2488 struct cfg80211_pmksa *pmksa)
2490 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2491 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2495 WL_TRACE("Enter\n");
2496 if (!check_sys_up(wiphy))
2499 for (i = 0; i < pmkids->npmkid; i++)
2500 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2502 if (i < WL_NUM_PMKIDS_MAX) {
2503 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2504 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2505 if (i == pmkids->npmkid)
2510 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2511 pmkids->pmkid[pmkids->npmkid].BSSID);
2512 for (i = 0; i < WLAN_PMKID_LEN; i++)
2513 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2515 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2522 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2523 struct cfg80211_pmksa *pmksa)
2525 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2526 struct pmkid_list pmkid;
2530 WL_TRACE("Enter\n");
2531 if (!check_sys_up(wiphy))
2534 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2535 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2537 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2538 &pmkid.pmkid[0].BSSID);
2539 for (i = 0; i < WLAN_PMKID_LEN; i++)
2540 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2542 for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2544 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2548 if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2549 && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2550 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2551 sizeof(struct pmkid));
2552 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2553 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2554 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2556 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2557 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2560 cfg_priv->pmk_list->pmkids.npmkid--;
2564 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2572 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2574 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2577 WL_TRACE("Enter\n");
2578 if (!check_sys_up(wiphy))
2581 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2582 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2589 static struct cfg80211_ops wl_cfg80211_ops = {
2590 .change_virtual_intf = brcmf_cfg80211_change_iface,
2591 .scan = brcmf_cfg80211_scan,
2592 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2593 .join_ibss = brcmf_cfg80211_join_ibss,
2594 .leave_ibss = brcmf_cfg80211_leave_ibss,
2595 .get_station = brcmf_cfg80211_get_station,
2596 .set_tx_power = brcmf_cfg80211_set_tx_power,
2597 .get_tx_power = brcmf_cfg80211_get_tx_power,
2598 .add_key = brcmf_cfg80211_add_key,
2599 .del_key = brcmf_cfg80211_del_key,
2600 .get_key = brcmf_cfg80211_get_key,
2601 .set_default_key = brcmf_cfg80211_config_default_key,
2602 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2603 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2604 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2605 .connect = brcmf_cfg80211_connect,
2606 .disconnect = brcmf_cfg80211_disconnect,
2607 .suspend = brcmf_cfg80211_suspend,
2608 .resume = brcmf_cfg80211_resume,
2609 .set_pmksa = brcmf_cfg80211_set_pmksa,
2610 .del_pmksa = brcmf_cfg80211_del_pmksa,
2611 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2614 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2620 return NL80211_IFTYPE_STATION;
2622 return NL80211_IFTYPE_ADHOC;
2624 return NL80211_IFTYPE_UNSPECIFIED;
2630 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2631 struct device *ndev)
2633 struct wireless_dev *wdev;
2636 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2638 return ERR_PTR(-ENOMEM);
2641 wiphy_new(&wl_cfg80211_ops,
2642 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2644 WL_ERR("Couldn not allocate wiphy device\n");
2648 set_wiphy_dev(wdev->wiphy, ndev);
2649 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2650 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2651 wdev->wiphy->interface_modes =
2652 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2653 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2654 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2655 * it as 11a by default.
2656 * This will be updated with
2659 * if phy has 11n capability
2661 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2662 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2663 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2664 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2668 err = wiphy_register(wdev->wiphy);
2670 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2671 goto wiphy_register_out;
2676 wiphy_free(wdev->wiphy);
2681 return ERR_PTR(err);
2684 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2686 struct wireless_dev *wdev = cfg_priv->wdev;
2689 WL_ERR("wdev is invalid\n");
2692 wiphy_unregister(wdev->wiphy);
2693 wiphy_free(wdev->wiphy);
2695 cfg_priv->wdev = NULL;
2698 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2699 const struct brcmf_event_msg *e)
2701 u32 event = be32_to_cpu(e->event_type);
2702 u32 status = be32_to_cpu(e->status);
2704 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2705 WL_CONN("Processing set ssid\n");
2706 cfg_priv->link_up = true;
2713 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2714 const struct brcmf_event_msg *e)
2716 u32 event = be32_to_cpu(e->event_type);
2717 u16 flags = be16_to_cpu(e->flags);
2719 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2720 WL_CONN("Processing link down\n");
2726 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2727 const struct brcmf_event_msg *e)
2729 u32 event = be32_to_cpu(e->event_type);
2730 u32 status = be32_to_cpu(e->status);
2732 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2733 WL_CONN("Processing Link %s & no network found\n",
2734 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2739 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2740 WL_CONN("Processing connecting & no network found\n");
2747 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2749 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2751 kfree(conn_info->req_ie);
2752 conn_info->req_ie = NULL;
2753 conn_info->req_ie_len = 0;
2754 kfree(conn_info->resp_ie);
2755 conn_info->resp_ie = NULL;
2756 conn_info->resp_ie_len = 0;
2759 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2761 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2762 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2763 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2768 brcmf_clear_assoc_ies(cfg_priv);
2770 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2773 WL_ERR("could not get assoc info (%d)\n", err);
2776 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2777 req_len = assoc_info->req_len;
2778 resp_len = assoc_info->resp_len;
2780 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2781 cfg_priv->extra_buf,
2784 WL_ERR("could not get assoc req (%d)\n", err);
2787 conn_info->req_ie_len = req_len;
2789 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2792 conn_info->req_ie_len = 0;
2793 conn_info->req_ie = NULL;
2796 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2797 cfg_priv->extra_buf,
2800 WL_ERR("could not get assoc resp (%d)\n", err);
2803 conn_info->resp_ie_len = resp_len;
2804 conn_info->resp_ie =
2805 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2808 conn_info->resp_ie_len = 0;
2809 conn_info->resp_ie = NULL;
2811 WL_CONN("req len (%d) resp len (%d)\n",
2812 conn_info->req_ie_len, conn_info->resp_ie_len);
2818 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2819 struct net_device *ndev,
2820 const struct brcmf_event_msg *e)
2822 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2823 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2824 struct brcmf_channel_info_le channel_le;
2825 struct ieee80211_channel *notify_channel;
2826 struct ieee80211_supported_band *band;
2831 WL_TRACE("Enter\n");
2833 brcmf_get_assoc_ies(cfg_priv);
2834 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2835 brcmf_update_bss_info(cfg_priv);
2837 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2838 sizeof(channel_le));
2840 target_channel = le32_to_cpu(channel_le.target_channel);
2841 WL_CONN("Roamed to channel %d\n", target_channel);
2843 if (target_channel <= CH_MAX_2G_CHANNEL)
2844 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2846 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2848 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2849 notify_channel = ieee80211_get_channel(wiphy, freq);
2851 cfg80211_roamed(ndev, notify_channel,
2852 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2853 conn_info->req_ie, conn_info->req_ie_len,
2854 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2855 WL_CONN("Report roaming result\n");
2857 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2863 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2864 struct net_device *ndev, const struct brcmf_event_msg *e,
2867 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2870 WL_TRACE("Enter\n");
2872 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2874 brcmf_get_assoc_ies(cfg_priv);
2875 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2877 brcmf_update_bss_info(cfg_priv);
2879 cfg80211_connect_result(ndev,
2880 (u8 *)brcmf_read_prof(cfg_priv,
2883 conn_info->req_ie_len,
2885 conn_info->resp_ie_len,
2886 completed ? WLAN_STATUS_SUCCESS :
2887 WLAN_STATUS_AUTH_TIMEOUT,
2890 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2891 WL_CONN("Report connect result - connection %s\n",
2892 completed ? "succeeded" : "failed");
2899 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2900 struct net_device *ndev,
2901 const struct brcmf_event_msg *e, void *data)
2905 if (brcmf_is_linkup(cfg_priv, e)) {
2906 WL_CONN("Linkup\n");
2907 if (brcmf_is_ibssmode(cfg_priv)) {
2908 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2910 wl_inform_ibss(cfg_priv, ndev, e->addr);
2911 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2912 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2913 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2915 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2916 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2917 WL_CONN("Linkdown\n");
2918 if (brcmf_is_ibssmode(cfg_priv)) {
2919 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2920 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2922 brcmf_link_down(cfg_priv);
2924 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2925 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2926 &cfg_priv->status)) {
2927 cfg80211_disconnected(ndev, 0, NULL, 0,
2929 brcmf_link_down(cfg_priv);
2932 brcmf_init_prof(cfg_priv->profile);
2933 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2934 if (brcmf_is_ibssmode(cfg_priv))
2935 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2937 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2944 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2945 struct net_device *ndev,
2946 const struct brcmf_event_msg *e, void *data)
2949 u32 event = be32_to_cpu(e->event_type);
2950 u32 status = be32_to_cpu(e->status);
2952 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2953 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2954 brcmf_bss_roaming_done(cfg_priv, ndev, e);
2956 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2963 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2964 struct net_device *ndev,
2965 const struct brcmf_event_msg *e, void *data)
2967 u16 flags = be16_to_cpu(e->flags);
2968 enum nl80211_key_type key_type;
2970 if (flags & BRCMF_EVENT_MSG_GROUP)
2971 key_type = NL80211_KEYTYPE_GROUP;
2973 key_type = NL80211_KEYTYPE_PAIRWISE;
2975 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2982 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2983 struct net_device *ndev,
2984 const struct brcmf_event_msg *e, void *data)
2986 struct brcmf_channel_info_le channel_inform_le;
2987 struct brcmf_scan_results_le *bss_list_le;
2988 u32 len = WL_SCAN_BUF_MAX;
2990 bool scan_abort = false;
2993 WL_TRACE("Enter\n");
2995 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
2997 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3000 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3001 WL_ERR("Scan complete while device not scanning\n");
3007 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3008 sizeof(channel_inform_le));
3010 WL_ERR("scan busy (%d)\n", err);
3014 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3016 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3017 cfg_priv->bss_list = cfg_priv->scan_results;
3018 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3020 memset(cfg_priv->scan_results, 0, len);
3021 bss_list_le->buflen = cpu_to_le32(len);
3022 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3023 cfg_priv->scan_results, len);
3025 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3030 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3031 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3032 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3034 err = brcmf_inform_bss(cfg_priv);
3041 if (cfg_priv->scan_request) {
3042 WL_SCAN("calling cfg80211_scan_done\n");
3043 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3044 brcmf_set_mpc(ndev, 1);
3045 cfg_priv->scan_request = NULL;
3053 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3055 conf->mode = (u32)-1;
3056 conf->frag_threshold = (u32)-1;
3057 conf->rts_threshold = (u32)-1;
3058 conf->retry_short = (u32)-1;
3059 conf->retry_long = (u32)-1;
3060 conf->tx_power = -1;
3063 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3065 memset(el, 0, sizeof(*el));
3066 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3067 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3068 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3069 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3070 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3073 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3075 kfree(cfg_priv->scan_results);
3076 cfg_priv->scan_results = NULL;
3077 kfree(cfg_priv->bss_info);
3078 cfg_priv->bss_info = NULL;
3079 kfree(cfg_priv->conf);
3080 cfg_priv->conf = NULL;
3081 kfree(cfg_priv->profile);
3082 cfg_priv->profile = NULL;
3083 kfree(cfg_priv->scan_req_int);
3084 cfg_priv->scan_req_int = NULL;
3085 kfree(cfg_priv->dcmd_buf);
3086 cfg_priv->dcmd_buf = NULL;
3087 kfree(cfg_priv->extra_buf);
3088 cfg_priv->extra_buf = NULL;
3089 kfree(cfg_priv->iscan);
3090 cfg_priv->iscan = NULL;
3091 kfree(cfg_priv->pmk_list);
3092 cfg_priv->pmk_list = NULL;
3095 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3097 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3098 if (!cfg_priv->scan_results)
3099 goto init_priv_mem_out;
3100 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3101 if (!cfg_priv->conf)
3102 goto init_priv_mem_out;
3103 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3104 if (!cfg_priv->profile)
3105 goto init_priv_mem_out;
3106 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3107 if (!cfg_priv->bss_info)
3108 goto init_priv_mem_out;
3109 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3111 if (!cfg_priv->scan_req_int)
3112 goto init_priv_mem_out;
3113 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3114 if (!cfg_priv->dcmd_buf)
3115 goto init_priv_mem_out;
3116 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3117 if (!cfg_priv->extra_buf)
3118 goto init_priv_mem_out;
3119 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3120 if (!cfg_priv->iscan)
3121 goto init_priv_mem_out;
3122 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3123 if (!cfg_priv->pmk_list)
3124 goto init_priv_mem_out;
3129 brcmf_deinit_priv_mem(cfg_priv);
3135 * retrieve first queued event from head
3138 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3139 struct brcmf_cfg80211_priv *cfg_priv)
3141 struct brcmf_cfg80211_event_q *e = NULL;
3143 spin_lock_irq(&cfg_priv->evt_q_lock);
3144 if (!list_empty(&cfg_priv->evt_q_list)) {
3145 e = list_first_entry(&cfg_priv->evt_q_list,
3146 struct brcmf_cfg80211_event_q, evt_q_list);
3147 list_del(&e->evt_q_list);
3149 spin_unlock_irq(&cfg_priv->evt_q_lock);
3155 ** push event to tail of the queue
3159 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3160 const struct brcmf_event_msg *msg)
3162 struct brcmf_cfg80211_event_q *e;
3165 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3170 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3172 spin_lock_irq(&cfg_priv->evt_q_lock);
3173 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3174 spin_unlock_irq(&cfg_priv->evt_q_lock);
3179 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3184 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3186 struct brcmf_cfg80211_priv *cfg_priv =
3187 container_of(work, struct brcmf_cfg80211_priv,
3189 struct brcmf_cfg80211_event_q *e;
3191 e = brcmf_deq_event(cfg_priv);
3193 WL_ERR("event queue empty...\n");
3198 WL_INFO("event type (%d)\n", e->etype);
3199 if (cfg_priv->el.handler[e->etype])
3200 cfg_priv->el.handler[e->etype](cfg_priv,
3201 cfg_to_ndev(cfg_priv),
3202 &e->emsg, e->edata);
3204 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3206 } while ((e = brcmf_deq_event(cfg_priv)));
3210 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3212 spin_lock_init(&cfg_priv->evt_q_lock);
3213 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3216 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3218 struct brcmf_cfg80211_event_q *e;
3220 spin_lock_irq(&cfg_priv->evt_q_lock);
3221 while (!list_empty(&cfg_priv->evt_q_list)) {
3222 e = list_first_entry(&cfg_priv->evt_q_list,
3223 struct brcmf_cfg80211_event_q, evt_q_list);
3224 list_del(&e->evt_q_list);
3227 spin_unlock_irq(&cfg_priv->evt_q_lock);
3230 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3234 cfg_priv->scan_request = NULL;
3235 cfg_priv->pwr_save = true;
3236 cfg_priv->iscan_on = true; /* iscan on & off switch.
3237 we enable iscan per default */
3238 cfg_priv->roam_on = true; /* roam on & off switch.
3239 we enable roam per default */
3241 cfg_priv->iscan_kickstart = false;
3242 cfg_priv->active_scan = true; /* we do active scan for
3243 specific scan per default */
3244 cfg_priv->dongle_up = false; /* dongle is not up yet */
3245 brcmf_init_eq(cfg_priv);
3246 err = brcmf_init_priv_mem(cfg_priv);
3249 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3250 brcmf_init_eloop_handler(&cfg_priv->el);
3251 mutex_init(&cfg_priv->usr_sync);
3252 err = brcmf_init_iscan(cfg_priv);
3255 brcmf_init_conf(cfg_priv->conf);
3256 brcmf_init_prof(cfg_priv->profile);
3257 brcmf_link_down(cfg_priv);
3262 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3264 cancel_work_sync(&cfg_priv->event_work);
3265 cfg_priv->dongle_up = false; /* dongle down */
3266 brcmf_flush_eq(cfg_priv);
3267 brcmf_link_down(cfg_priv);
3268 brcmf_term_iscan(cfg_priv);
3269 brcmf_deinit_priv_mem(cfg_priv);
3272 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3273 struct device *busdev,
3276 struct wireless_dev *wdev;
3277 struct brcmf_cfg80211_priv *cfg_priv;
3278 struct brcmf_cfg80211_iface *ci;
3279 struct brcmf_cfg80211_dev *cfg_dev;
3283 WL_ERR("ndev is invalid\n");
3286 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3290 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3296 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3297 cfg_priv = wdev_to_cfg(wdev);
3298 cfg_priv->wdev = wdev;
3299 cfg_priv->pub = data;
3300 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3301 ci->cfg_priv = cfg_priv;
3302 ndev->ieee80211_ptr = wdev;
3303 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3304 wdev->netdev = ndev;
3305 err = wl_init_priv(cfg_priv);
3307 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3308 goto cfg80211_attach_out;
3310 brcmf_set_drvdata(cfg_dev, ci);
3314 cfg80211_attach_out:
3315 brcmf_free_wdev(cfg_priv);
3320 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3322 struct brcmf_cfg80211_priv *cfg_priv;
3324 cfg_priv = brcmf_priv_get(cfg_dev);
3326 wl_deinit_priv(cfg_priv);
3327 brcmf_free_wdev(cfg_priv);
3328 brcmf_set_drvdata(cfg_dev, NULL);
3333 brcmf_cfg80211_event(struct net_device *ndev,
3334 const struct brcmf_event_msg *e, void *data)
3336 u32 event_type = be32_to_cpu(e->event_type);
3337 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3339 if (!brcmf_enq_event(cfg_priv, event_type, e))
3340 schedule_work(&cfg_priv->event_work);
3343 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3349 case NL80211_IFTYPE_MONITOR:
3350 case NL80211_IFTYPE_WDS:
3351 WL_ERR("type (%d) : currently we do not support this mode\n",
3355 case NL80211_IFTYPE_ADHOC:
3358 case NL80211_IFTYPE_STATION:
3363 WL_ERR("invalid type (%d)\n", iftype);
3366 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3368 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3375 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3377 /* Room for "event_msgs" + '\0' + bitvec */
3378 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3379 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3382 WL_TRACE("Enter\n");
3384 /* Setup event_msgs */
3385 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3387 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3389 WL_ERR("Get event_msgs error (%d)\n", err);
3390 goto dongle_eventmsg_out;
3392 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3394 setbit(eventmask, BRCMF_E_SET_SSID);
3395 setbit(eventmask, BRCMF_E_ROAM);
3396 setbit(eventmask, BRCMF_E_PRUNE);
3397 setbit(eventmask, BRCMF_E_AUTH);
3398 setbit(eventmask, BRCMF_E_REASSOC);
3399 setbit(eventmask, BRCMF_E_REASSOC_IND);
3400 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3401 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3402 setbit(eventmask, BRCMF_E_DISASSOC);
3403 setbit(eventmask, BRCMF_E_JOIN);
3404 setbit(eventmask, BRCMF_E_ASSOC_IND);
3405 setbit(eventmask, BRCMF_E_PSK_SUP);
3406 setbit(eventmask, BRCMF_E_LINK);
3407 setbit(eventmask, BRCMF_E_NDIS_LINK);
3408 setbit(eventmask, BRCMF_E_MIC_ERROR);
3409 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3410 setbit(eventmask, BRCMF_E_TXFAIL);
3411 setbit(eventmask, BRCMF_E_JOIN_START);
3412 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3414 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3416 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3418 WL_ERR("Set event_msgs error (%d)\n", err);
3419 goto dongle_eventmsg_out;
3422 dongle_eventmsg_out:
3428 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3436 * Setup timeout if Beacons are lost and roam is
3437 * off to report link down
3440 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3441 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3442 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3443 iovbuf, sizeof(iovbuf));
3445 WL_ERR("bcn_timeout error (%d)\n", err);
3446 goto dongle_rom_out;
3451 * Enable/Disable built-in roaming to allow supplicant
3452 * to take care of roaming
3454 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3455 brcmu_mkiovar("roam_off", (char *)&roamvar,
3456 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3457 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3459 WL_ERR("roam_off error (%d)\n", err);
3460 goto dongle_rom_out;
3463 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3464 roamtrigger[1] = BRCM_BAND_ALL;
3465 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3466 (void *)roamtrigger, sizeof(roamtrigger));
3468 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3469 goto dongle_rom_out;
3472 roam_delta[0] = WL_ROAM_DELTA;
3473 roam_delta[1] = BRCM_BAND_ALL;
3474 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3475 (void *)roam_delta, sizeof(roam_delta));
3477 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3478 goto dongle_rom_out;
3486 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3487 s32 scan_unassoc_time, s32 scan_passive_time)
3491 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3492 &scan_assoc_time, sizeof(scan_assoc_time));
3494 if (err == -EOPNOTSUPP)
3495 WL_INFO("Scan assoc time is not supported\n");
3497 WL_ERR("Scan assoc time error (%d)\n", err);
3498 goto dongle_scantime_out;
3500 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3501 &scan_unassoc_time, sizeof(scan_unassoc_time));
3503 if (err == -EOPNOTSUPP)
3504 WL_INFO("Scan unassoc time is not supported\n");
3506 WL_ERR("Scan unassoc time error (%d)\n", err);
3507 goto dongle_scantime_out;
3510 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3511 &scan_passive_time, sizeof(scan_passive_time));
3513 if (err == -EOPNOTSUPP)
3514 WL_INFO("Scan passive time is not supported\n");
3516 WL_ERR("Scan passive time error (%d)\n", err);
3517 goto dongle_scantime_out;
3520 dongle_scantime_out:
3524 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3526 struct wiphy *wiphy;
3531 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3532 &phy_list, sizeof(phy_list));
3534 WL_ERR("error (%d)\n", err);
3538 phy = ((char *)&phy_list)[1];
3539 WL_INFO("%c phy\n", phy);
3540 if (phy == 'n' || phy == 'a') {
3541 wiphy = cfg_to_wiphy(cfg_priv);
3542 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3548 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3550 return wl_update_wiphybands(cfg_priv);
3553 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3555 struct net_device *ndev;
3556 struct wireless_dev *wdev;
3560 if (cfg_priv->dongle_up)
3563 ndev = cfg_to_ndev(cfg_priv);
3564 wdev = ndev->ieee80211_ptr;
3566 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3567 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3569 err = brcmf_dongle_eventmsg(ndev);
3571 goto default_conf_out;
3573 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3574 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3576 goto default_conf_out;
3577 WL_INFO("power save set to %s\n",
3578 (power_mode ? "enabled" : "disabled"));
3580 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3583 goto default_conf_out;
3584 err = brcmf_dongle_mode(ndev, wdev->iftype);
3585 if (err && err != -EINPROGRESS)
3586 goto default_conf_out;
3587 err = brcmf_dongle_probecap(cfg_priv);
3589 goto default_conf_out;
3591 /* -EINPROGRESS: Call commit handler */
3595 cfg_priv->dongle_up = true;
3601 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3603 char buf[10+IFNAMSIZ];
3607 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3608 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3609 cfg_to_wiphy(cfg_priv)->debugfsdir);
3611 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3612 (u16 *)&cfg_priv->profile->beacon_interval);
3618 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3619 (u8 *)&cfg_priv->profile->dtim_period);
3629 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3631 debugfs_remove_recursive(cfg_priv->debugfsdir);
3632 cfg_priv->debugfsdir = NULL;
3635 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3639 set_bit(WL_STATUS_READY, &cfg_priv->status);
3641 brcmf_debugfs_add_netdev_params(cfg_priv);
3643 err = brcmf_config_dongle(cfg_priv);
3647 brcmf_invoke_iscan(cfg_priv);
3652 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3655 * While going down, if associated with AP disassociate
3656 * from AP to save power
3658 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3659 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3660 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3661 WL_INFO("Disassociating from AP");
3662 brcmf_link_down(cfg_priv);
3664 /* Make sure WPA_Supplicant receives all the event
3665 generated due to DISASSOC call to the fw to keep
3666 the state fw and WPA_Supplicant state consistent
3671 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3672 brcmf_term_iscan(cfg_priv);
3673 if (cfg_priv->scan_request) {
3674 cfg80211_scan_done(cfg_priv->scan_request, true);
3675 /* May need to perform this to cover rmmod */
3676 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3677 cfg_priv->scan_request = NULL;
3679 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3680 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3681 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3683 brcmf_debugfs_remove_netdev(cfg_priv);
3688 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3690 struct brcmf_cfg80211_priv *cfg_priv;
3693 cfg_priv = brcmf_priv_get(cfg_dev);
3694 mutex_lock(&cfg_priv->usr_sync);
3695 err = __brcmf_cfg80211_up(cfg_priv);
3696 mutex_unlock(&cfg_priv->usr_sync);
3701 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3703 struct brcmf_cfg80211_priv *cfg_priv;
3706 cfg_priv = brcmf_priv_get(cfg_dev);
3707 mutex_lock(&cfg_priv->usr_sync);
3708 err = __brcmf_cfg80211_down(cfg_priv);
3709 mutex_unlock(&cfg_priv->usr_sync);
3714 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3717 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3720 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3721 WL_ERR("ei crosses buffer boundary\n");
3724 ie->buf[ie->offset] = t;
3725 ie->buf[ie->offset + 1] = l;
3726 memcpy(&ie->buf[ie->offset + 2], v, l);
3727 ie->offset += l + 2;