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 : cpu_to_le32(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 : cpu_to_le32(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)
2472 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2474 WL_CONN("No of elements %d\n", pmkid_len);
2475 for (i = 0; i < pmkid_len; i++) {
2476 WL_CONN("PMKID[%d]: %pM =\n", i,
2477 &pmk_list->pmkids.pmkid[i].BSSID);
2478 for (j = 0; j < WLAN_PMKID_LEN; j++)
2479 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2483 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2490 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2491 struct cfg80211_pmksa *pmksa)
2493 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2494 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2499 WL_TRACE("Enter\n");
2500 if (!check_sys_up(wiphy))
2503 pmkid_len = le32_to_cpu(pmkids->npmkid);
2504 for (i = 0; i < pmkid_len; i++)
2505 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2507 if (i < WL_NUM_PMKIDS_MAX) {
2508 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2509 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2510 if (i == pmkid_len) {
2512 pmkids->npmkid = cpu_to_le32(pmkid_len);
2517 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2518 pmkids->pmkid[pmkid_len].BSSID);
2519 for (i = 0; i < WLAN_PMKID_LEN; i++)
2520 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2522 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2529 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2530 struct cfg80211_pmksa *pmksa)
2532 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2533 struct pmkid_list pmkid;
2537 WL_TRACE("Enter\n");
2538 if (!check_sys_up(wiphy))
2541 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2542 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2544 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2545 &pmkid.pmkid[0].BSSID);
2546 for (i = 0; i < WLAN_PMKID_LEN; i++)
2547 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2549 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2550 for (i = 0; i < pmkid_len; i++)
2552 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2557 && (i < pmkid_len)) {
2558 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2559 sizeof(struct pmkid));
2560 for (; i < (pmkid_len - 1); i++) {
2561 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2562 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2564 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2565 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2568 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2572 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2580 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2582 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2585 WL_TRACE("Enter\n");
2586 if (!check_sys_up(wiphy))
2589 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2590 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2597 static struct cfg80211_ops wl_cfg80211_ops = {
2598 .change_virtual_intf = brcmf_cfg80211_change_iface,
2599 .scan = brcmf_cfg80211_scan,
2600 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2601 .join_ibss = brcmf_cfg80211_join_ibss,
2602 .leave_ibss = brcmf_cfg80211_leave_ibss,
2603 .get_station = brcmf_cfg80211_get_station,
2604 .set_tx_power = brcmf_cfg80211_set_tx_power,
2605 .get_tx_power = brcmf_cfg80211_get_tx_power,
2606 .add_key = brcmf_cfg80211_add_key,
2607 .del_key = brcmf_cfg80211_del_key,
2608 .get_key = brcmf_cfg80211_get_key,
2609 .set_default_key = brcmf_cfg80211_config_default_key,
2610 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2611 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2612 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2613 .connect = brcmf_cfg80211_connect,
2614 .disconnect = brcmf_cfg80211_disconnect,
2615 .suspend = brcmf_cfg80211_suspend,
2616 .resume = brcmf_cfg80211_resume,
2617 .set_pmksa = brcmf_cfg80211_set_pmksa,
2618 .del_pmksa = brcmf_cfg80211_del_pmksa,
2619 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2622 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2628 return NL80211_IFTYPE_STATION;
2630 return NL80211_IFTYPE_ADHOC;
2632 return NL80211_IFTYPE_UNSPECIFIED;
2638 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2639 struct device *ndev)
2641 struct wireless_dev *wdev;
2644 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2646 return ERR_PTR(-ENOMEM);
2649 wiphy_new(&wl_cfg80211_ops,
2650 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2652 WL_ERR("Couldn not allocate wiphy device\n");
2656 set_wiphy_dev(wdev->wiphy, ndev);
2657 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2658 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2659 wdev->wiphy->interface_modes =
2660 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2661 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2662 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2663 * it as 11a by default.
2664 * This will be updated with
2667 * if phy has 11n capability
2669 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2670 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2671 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2672 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2676 err = wiphy_register(wdev->wiphy);
2678 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2679 goto wiphy_register_out;
2684 wiphy_free(wdev->wiphy);
2689 return ERR_PTR(err);
2692 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2694 struct wireless_dev *wdev = cfg_priv->wdev;
2697 WL_ERR("wdev is invalid\n");
2700 wiphy_unregister(wdev->wiphy);
2701 wiphy_free(wdev->wiphy);
2703 cfg_priv->wdev = NULL;
2706 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2707 const struct brcmf_event_msg *e)
2709 u32 event = be32_to_cpu(e->event_type);
2710 u32 status = be32_to_cpu(e->status);
2712 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2713 WL_CONN("Processing set ssid\n");
2714 cfg_priv->link_up = true;
2721 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2722 const struct brcmf_event_msg *e)
2724 u32 event = be32_to_cpu(e->event_type);
2725 u16 flags = be16_to_cpu(e->flags);
2727 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2728 WL_CONN("Processing link down\n");
2734 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2735 const struct brcmf_event_msg *e)
2737 u32 event = be32_to_cpu(e->event_type);
2738 u32 status = be32_to_cpu(e->status);
2740 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2741 WL_CONN("Processing Link %s & no network found\n",
2742 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2747 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2748 WL_CONN("Processing connecting & no network found\n");
2755 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2757 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2759 kfree(conn_info->req_ie);
2760 conn_info->req_ie = NULL;
2761 conn_info->req_ie_len = 0;
2762 kfree(conn_info->resp_ie);
2763 conn_info->resp_ie = NULL;
2764 conn_info->resp_ie_len = 0;
2767 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2769 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2770 struct brcmf_cfg80211_assoc_ielen *assoc_info;
2771 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2776 brcmf_clear_assoc_ies(cfg_priv);
2778 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2781 WL_ERR("could not get assoc info (%d)\n", err);
2784 assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2785 req_len = assoc_info->req_len;
2786 resp_len = assoc_info->resp_len;
2788 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2789 cfg_priv->extra_buf,
2792 WL_ERR("could not get assoc req (%d)\n", err);
2795 conn_info->req_ie_len = req_len;
2797 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2800 conn_info->req_ie_len = 0;
2801 conn_info->req_ie = NULL;
2804 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2805 cfg_priv->extra_buf,
2808 WL_ERR("could not get assoc resp (%d)\n", err);
2811 conn_info->resp_ie_len = resp_len;
2812 conn_info->resp_ie =
2813 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2816 conn_info->resp_ie_len = 0;
2817 conn_info->resp_ie = NULL;
2819 WL_CONN("req len (%d) resp len (%d)\n",
2820 conn_info->req_ie_len, conn_info->resp_ie_len);
2826 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2827 struct net_device *ndev,
2828 const struct brcmf_event_msg *e)
2830 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2831 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2832 struct brcmf_channel_info_le channel_le;
2833 struct ieee80211_channel *notify_channel;
2834 struct ieee80211_supported_band *band;
2839 WL_TRACE("Enter\n");
2841 brcmf_get_assoc_ies(cfg_priv);
2842 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2843 brcmf_update_bss_info(cfg_priv);
2845 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2846 sizeof(channel_le));
2848 target_channel = le32_to_cpu(channel_le.target_channel);
2849 WL_CONN("Roamed to channel %d\n", target_channel);
2851 if (target_channel <= CH_MAX_2G_CHANNEL)
2852 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2854 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2856 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2857 notify_channel = ieee80211_get_channel(wiphy, freq);
2859 cfg80211_roamed(ndev, notify_channel,
2860 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2861 conn_info->req_ie, conn_info->req_ie_len,
2862 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2863 WL_CONN("Report roaming result\n");
2865 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2871 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2872 struct net_device *ndev, const struct brcmf_event_msg *e,
2875 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2878 WL_TRACE("Enter\n");
2880 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2882 brcmf_get_assoc_ies(cfg_priv);
2883 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2885 brcmf_update_bss_info(cfg_priv);
2887 cfg80211_connect_result(ndev,
2888 (u8 *)brcmf_read_prof(cfg_priv,
2891 conn_info->req_ie_len,
2893 conn_info->resp_ie_len,
2894 completed ? WLAN_STATUS_SUCCESS :
2895 WLAN_STATUS_AUTH_TIMEOUT,
2898 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2899 WL_CONN("Report connect result - connection %s\n",
2900 completed ? "succeeded" : "failed");
2907 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2908 struct net_device *ndev,
2909 const struct brcmf_event_msg *e, void *data)
2913 if (brcmf_is_linkup(cfg_priv, e)) {
2914 WL_CONN("Linkup\n");
2915 if (brcmf_is_ibssmode(cfg_priv)) {
2916 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2918 wl_inform_ibss(cfg_priv, ndev, e->addr);
2919 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2920 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2921 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2923 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2924 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2925 WL_CONN("Linkdown\n");
2926 if (brcmf_is_ibssmode(cfg_priv)) {
2927 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2928 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2930 brcmf_link_down(cfg_priv);
2932 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2933 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2934 &cfg_priv->status)) {
2935 cfg80211_disconnected(ndev, 0, NULL, 0,
2937 brcmf_link_down(cfg_priv);
2940 brcmf_init_prof(cfg_priv->profile);
2941 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2942 if (brcmf_is_ibssmode(cfg_priv))
2943 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2945 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2952 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2953 struct net_device *ndev,
2954 const struct brcmf_event_msg *e, void *data)
2957 u32 event = be32_to_cpu(e->event_type);
2958 u32 status = be32_to_cpu(e->status);
2960 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2961 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2962 brcmf_bss_roaming_done(cfg_priv, ndev, e);
2964 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2971 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2972 struct net_device *ndev,
2973 const struct brcmf_event_msg *e, void *data)
2975 u16 flags = be16_to_cpu(e->flags);
2976 enum nl80211_key_type key_type;
2978 if (flags & BRCMF_EVENT_MSG_GROUP)
2979 key_type = NL80211_KEYTYPE_GROUP;
2981 key_type = NL80211_KEYTYPE_PAIRWISE;
2983 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2990 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2991 struct net_device *ndev,
2992 const struct brcmf_event_msg *e, void *data)
2994 struct brcmf_channel_info_le channel_inform_le;
2995 struct brcmf_scan_results_le *bss_list_le;
2996 u32 len = WL_SCAN_BUF_MAX;
2998 bool scan_abort = false;
3001 WL_TRACE("Enter\n");
3003 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3005 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3008 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3009 WL_ERR("Scan complete while device not scanning\n");
3015 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3016 sizeof(channel_inform_le));
3018 WL_ERR("scan busy (%d)\n", err);
3022 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3024 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3025 cfg_priv->bss_list = cfg_priv->scan_results;
3026 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3028 memset(cfg_priv->scan_results, 0, len);
3029 bss_list_le->buflen = cpu_to_le32(len);
3030 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3031 cfg_priv->scan_results, len);
3033 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3038 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3039 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3040 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3042 err = brcmf_inform_bss(cfg_priv);
3049 if (cfg_priv->scan_request) {
3050 WL_SCAN("calling cfg80211_scan_done\n");
3051 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3052 brcmf_set_mpc(ndev, 1);
3053 cfg_priv->scan_request = NULL;
3061 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3063 conf->mode = (u32)-1;
3064 conf->frag_threshold = (u32)-1;
3065 conf->rts_threshold = (u32)-1;
3066 conf->retry_short = (u32)-1;
3067 conf->retry_long = (u32)-1;
3068 conf->tx_power = -1;
3071 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3073 memset(el, 0, sizeof(*el));
3074 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3075 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3076 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3077 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3078 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3081 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3083 kfree(cfg_priv->scan_results);
3084 cfg_priv->scan_results = NULL;
3085 kfree(cfg_priv->bss_info);
3086 cfg_priv->bss_info = NULL;
3087 kfree(cfg_priv->conf);
3088 cfg_priv->conf = NULL;
3089 kfree(cfg_priv->profile);
3090 cfg_priv->profile = NULL;
3091 kfree(cfg_priv->scan_req_int);
3092 cfg_priv->scan_req_int = NULL;
3093 kfree(cfg_priv->dcmd_buf);
3094 cfg_priv->dcmd_buf = NULL;
3095 kfree(cfg_priv->extra_buf);
3096 cfg_priv->extra_buf = NULL;
3097 kfree(cfg_priv->iscan);
3098 cfg_priv->iscan = NULL;
3099 kfree(cfg_priv->pmk_list);
3100 cfg_priv->pmk_list = NULL;
3103 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3105 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3106 if (!cfg_priv->scan_results)
3107 goto init_priv_mem_out;
3108 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3109 if (!cfg_priv->conf)
3110 goto init_priv_mem_out;
3111 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3112 if (!cfg_priv->profile)
3113 goto init_priv_mem_out;
3114 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3115 if (!cfg_priv->bss_info)
3116 goto init_priv_mem_out;
3117 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3119 if (!cfg_priv->scan_req_int)
3120 goto init_priv_mem_out;
3121 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3122 if (!cfg_priv->dcmd_buf)
3123 goto init_priv_mem_out;
3124 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3125 if (!cfg_priv->extra_buf)
3126 goto init_priv_mem_out;
3127 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3128 if (!cfg_priv->iscan)
3129 goto init_priv_mem_out;
3130 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3131 if (!cfg_priv->pmk_list)
3132 goto init_priv_mem_out;
3137 brcmf_deinit_priv_mem(cfg_priv);
3143 * retrieve first queued event from head
3146 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3147 struct brcmf_cfg80211_priv *cfg_priv)
3149 struct brcmf_cfg80211_event_q *e = NULL;
3151 spin_lock_irq(&cfg_priv->evt_q_lock);
3152 if (!list_empty(&cfg_priv->evt_q_list)) {
3153 e = list_first_entry(&cfg_priv->evt_q_list,
3154 struct brcmf_cfg80211_event_q, evt_q_list);
3155 list_del(&e->evt_q_list);
3157 spin_unlock_irq(&cfg_priv->evt_q_lock);
3163 ** push event to tail of the queue
3167 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3168 const struct brcmf_event_msg *msg)
3170 struct brcmf_cfg80211_event_q *e;
3173 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3178 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3180 spin_lock_irq(&cfg_priv->evt_q_lock);
3181 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3182 spin_unlock_irq(&cfg_priv->evt_q_lock);
3187 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3192 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3194 struct brcmf_cfg80211_priv *cfg_priv =
3195 container_of(work, struct brcmf_cfg80211_priv,
3197 struct brcmf_cfg80211_event_q *e;
3199 e = brcmf_deq_event(cfg_priv);
3201 WL_ERR("event queue empty...\n");
3206 WL_INFO("event type (%d)\n", e->etype);
3207 if (cfg_priv->el.handler[e->etype])
3208 cfg_priv->el.handler[e->etype](cfg_priv,
3209 cfg_to_ndev(cfg_priv),
3210 &e->emsg, e->edata);
3212 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3214 } while ((e = brcmf_deq_event(cfg_priv)));
3218 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3220 spin_lock_init(&cfg_priv->evt_q_lock);
3221 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3224 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3226 struct brcmf_cfg80211_event_q *e;
3228 spin_lock_irq(&cfg_priv->evt_q_lock);
3229 while (!list_empty(&cfg_priv->evt_q_list)) {
3230 e = list_first_entry(&cfg_priv->evt_q_list,
3231 struct brcmf_cfg80211_event_q, evt_q_list);
3232 list_del(&e->evt_q_list);
3235 spin_unlock_irq(&cfg_priv->evt_q_lock);
3238 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3242 cfg_priv->scan_request = NULL;
3243 cfg_priv->pwr_save = true;
3244 cfg_priv->iscan_on = true; /* iscan on & off switch.
3245 we enable iscan per default */
3246 cfg_priv->roam_on = true; /* roam on & off switch.
3247 we enable roam per default */
3249 cfg_priv->iscan_kickstart = false;
3250 cfg_priv->active_scan = true; /* we do active scan for
3251 specific scan per default */
3252 cfg_priv->dongle_up = false; /* dongle is not up yet */
3253 brcmf_init_eq(cfg_priv);
3254 err = brcmf_init_priv_mem(cfg_priv);
3257 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3258 brcmf_init_eloop_handler(&cfg_priv->el);
3259 mutex_init(&cfg_priv->usr_sync);
3260 err = brcmf_init_iscan(cfg_priv);
3263 brcmf_init_conf(cfg_priv->conf);
3264 brcmf_init_prof(cfg_priv->profile);
3265 brcmf_link_down(cfg_priv);
3270 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3272 cancel_work_sync(&cfg_priv->event_work);
3273 cfg_priv->dongle_up = false; /* dongle down */
3274 brcmf_flush_eq(cfg_priv);
3275 brcmf_link_down(cfg_priv);
3276 brcmf_term_iscan(cfg_priv);
3277 brcmf_deinit_priv_mem(cfg_priv);
3280 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3281 struct device *busdev,
3284 struct wireless_dev *wdev;
3285 struct brcmf_cfg80211_priv *cfg_priv;
3286 struct brcmf_cfg80211_iface *ci;
3287 struct brcmf_cfg80211_dev *cfg_dev;
3291 WL_ERR("ndev is invalid\n");
3294 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3298 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3304 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3305 cfg_priv = wdev_to_cfg(wdev);
3306 cfg_priv->wdev = wdev;
3307 cfg_priv->pub = data;
3308 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3309 ci->cfg_priv = cfg_priv;
3310 ndev->ieee80211_ptr = wdev;
3311 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3312 wdev->netdev = ndev;
3313 err = wl_init_priv(cfg_priv);
3315 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3316 goto cfg80211_attach_out;
3318 brcmf_set_drvdata(cfg_dev, ci);
3322 cfg80211_attach_out:
3323 brcmf_free_wdev(cfg_priv);
3328 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3330 struct brcmf_cfg80211_priv *cfg_priv;
3332 cfg_priv = brcmf_priv_get(cfg_dev);
3334 wl_deinit_priv(cfg_priv);
3335 brcmf_free_wdev(cfg_priv);
3336 brcmf_set_drvdata(cfg_dev, NULL);
3341 brcmf_cfg80211_event(struct net_device *ndev,
3342 const struct brcmf_event_msg *e, void *data)
3344 u32 event_type = be32_to_cpu(e->event_type);
3345 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3347 if (!brcmf_enq_event(cfg_priv, event_type, e))
3348 schedule_work(&cfg_priv->event_work);
3351 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3357 case NL80211_IFTYPE_MONITOR:
3358 case NL80211_IFTYPE_WDS:
3359 WL_ERR("type (%d) : currently we do not support this mode\n",
3363 case NL80211_IFTYPE_ADHOC:
3366 case NL80211_IFTYPE_STATION:
3371 WL_ERR("invalid type (%d)\n", iftype);
3374 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3376 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3383 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3385 /* Room for "event_msgs" + '\0' + bitvec */
3386 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3387 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3390 WL_TRACE("Enter\n");
3392 /* Setup event_msgs */
3393 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3395 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3397 WL_ERR("Get event_msgs error (%d)\n", err);
3398 goto dongle_eventmsg_out;
3400 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3402 setbit(eventmask, BRCMF_E_SET_SSID);
3403 setbit(eventmask, BRCMF_E_ROAM);
3404 setbit(eventmask, BRCMF_E_PRUNE);
3405 setbit(eventmask, BRCMF_E_AUTH);
3406 setbit(eventmask, BRCMF_E_REASSOC);
3407 setbit(eventmask, BRCMF_E_REASSOC_IND);
3408 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3409 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3410 setbit(eventmask, BRCMF_E_DISASSOC);
3411 setbit(eventmask, BRCMF_E_JOIN);
3412 setbit(eventmask, BRCMF_E_ASSOC_IND);
3413 setbit(eventmask, BRCMF_E_PSK_SUP);
3414 setbit(eventmask, BRCMF_E_LINK);
3415 setbit(eventmask, BRCMF_E_NDIS_LINK);
3416 setbit(eventmask, BRCMF_E_MIC_ERROR);
3417 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3418 setbit(eventmask, BRCMF_E_TXFAIL);
3419 setbit(eventmask, BRCMF_E_JOIN_START);
3420 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3422 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3424 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3426 WL_ERR("Set event_msgs error (%d)\n", err);
3427 goto dongle_eventmsg_out;
3430 dongle_eventmsg_out:
3436 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3444 * Setup timeout if Beacons are lost and roam is
3445 * off to report link down
3448 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3449 sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3450 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3451 iovbuf, sizeof(iovbuf));
3453 WL_ERR("bcn_timeout error (%d)\n", err);
3454 goto dongle_rom_out;
3459 * Enable/Disable built-in roaming to allow supplicant
3460 * to take care of roaming
3462 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3463 brcmu_mkiovar("roam_off", (char *)&roamvar,
3464 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3465 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3467 WL_ERR("roam_off error (%d)\n", err);
3468 goto dongle_rom_out;
3471 roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3472 roamtrigger[1] = BRCM_BAND_ALL;
3473 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3474 (void *)roamtrigger, sizeof(roamtrigger));
3476 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3477 goto dongle_rom_out;
3480 roam_delta[0] = WL_ROAM_DELTA;
3481 roam_delta[1] = BRCM_BAND_ALL;
3482 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3483 (void *)roam_delta, sizeof(roam_delta));
3485 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3486 goto dongle_rom_out;
3494 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3495 s32 scan_unassoc_time, s32 scan_passive_time)
3499 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3500 &scan_assoc_time, sizeof(scan_assoc_time));
3502 if (err == -EOPNOTSUPP)
3503 WL_INFO("Scan assoc time is not supported\n");
3505 WL_ERR("Scan assoc time error (%d)\n", err);
3506 goto dongle_scantime_out;
3508 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3509 &scan_unassoc_time, sizeof(scan_unassoc_time));
3511 if (err == -EOPNOTSUPP)
3512 WL_INFO("Scan unassoc time is not supported\n");
3514 WL_ERR("Scan unassoc time error (%d)\n", err);
3515 goto dongle_scantime_out;
3518 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3519 &scan_passive_time, sizeof(scan_passive_time));
3521 if (err == -EOPNOTSUPP)
3522 WL_INFO("Scan passive time is not supported\n");
3524 WL_ERR("Scan passive time error (%d)\n", err);
3525 goto dongle_scantime_out;
3528 dongle_scantime_out:
3532 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3534 struct wiphy *wiphy;
3539 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3540 &phy_list, sizeof(phy_list));
3542 WL_ERR("error (%d)\n", err);
3546 phy = ((char *)&phy_list)[1];
3547 WL_INFO("%c phy\n", phy);
3548 if (phy == 'n' || phy == 'a') {
3549 wiphy = cfg_to_wiphy(cfg_priv);
3550 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3556 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3558 return wl_update_wiphybands(cfg_priv);
3561 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3563 struct net_device *ndev;
3564 struct wireless_dev *wdev;
3568 if (cfg_priv->dongle_up)
3571 ndev = cfg_to_ndev(cfg_priv);
3572 wdev = ndev->ieee80211_ptr;
3574 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3575 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3577 err = brcmf_dongle_eventmsg(ndev);
3579 goto default_conf_out;
3581 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3582 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3584 goto default_conf_out;
3585 WL_INFO("power save set to %s\n",
3586 (power_mode ? "enabled" : "disabled"));
3588 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3591 goto default_conf_out;
3592 err = brcmf_dongle_mode(ndev, wdev->iftype);
3593 if (err && err != -EINPROGRESS)
3594 goto default_conf_out;
3595 err = brcmf_dongle_probecap(cfg_priv);
3597 goto default_conf_out;
3599 /* -EINPROGRESS: Call commit handler */
3603 cfg_priv->dongle_up = true;
3609 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3611 char buf[10+IFNAMSIZ];
3615 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3616 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3617 cfg_to_wiphy(cfg_priv)->debugfsdir);
3619 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3620 (u16 *)&cfg_priv->profile->beacon_interval);
3626 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3627 (u8 *)&cfg_priv->profile->dtim_period);
3637 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3639 debugfs_remove_recursive(cfg_priv->debugfsdir);
3640 cfg_priv->debugfsdir = NULL;
3643 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3647 set_bit(WL_STATUS_READY, &cfg_priv->status);
3649 brcmf_debugfs_add_netdev_params(cfg_priv);
3651 err = brcmf_config_dongle(cfg_priv);
3655 brcmf_invoke_iscan(cfg_priv);
3660 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3663 * While going down, if associated with AP disassociate
3664 * from AP to save power
3666 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3667 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3668 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3669 WL_INFO("Disassociating from AP");
3670 brcmf_link_down(cfg_priv);
3672 /* Make sure WPA_Supplicant receives all the event
3673 generated due to DISASSOC call to the fw to keep
3674 the state fw and WPA_Supplicant state consistent
3679 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3680 brcmf_term_iscan(cfg_priv);
3681 if (cfg_priv->scan_request) {
3682 cfg80211_scan_done(cfg_priv->scan_request, true);
3683 /* May need to perform this to cover rmmod */
3684 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3685 cfg_priv->scan_request = NULL;
3687 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3688 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3689 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3691 brcmf_debugfs_remove_netdev(cfg_priv);
3696 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3698 struct brcmf_cfg80211_priv *cfg_priv;
3701 cfg_priv = brcmf_priv_get(cfg_dev);
3702 mutex_lock(&cfg_priv->usr_sync);
3703 err = __brcmf_cfg80211_up(cfg_priv);
3704 mutex_unlock(&cfg_priv->usr_sync);
3709 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3711 struct brcmf_cfg80211_priv *cfg_priv;
3714 cfg_priv = brcmf_priv_get(cfg_dev);
3715 mutex_lock(&cfg_priv->usr_sync);
3716 err = __brcmf_cfg80211_down(cfg_priv);
3717 mutex_unlock(&cfg_priv->usr_sync);
3722 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3725 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3728 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3729 WL_ERR("ei crosses buffer boundary\n");
3732 ie->buf[ie->offset] = t;
3733 ie->buf[ie->offset + 1] = l;
3734 memcpy(&ie->buf[ie->offset + 2], v, l);
3735 ie->offset += l + 2;