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_le *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);
2785 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2786 req_len = le32_to_cpu(assoc_info->req_len);
2787 resp_len = le32_to_cpu(assoc_info->resp_len);
2789 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2790 cfg_priv->extra_buf,
2793 WL_ERR("could not get assoc req (%d)\n", err);
2796 conn_info->req_ie_len = req_len;
2798 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2801 conn_info->req_ie_len = 0;
2802 conn_info->req_ie = NULL;
2805 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2806 cfg_priv->extra_buf,
2809 WL_ERR("could not get assoc resp (%d)\n", err);
2812 conn_info->resp_ie_len = resp_len;
2813 conn_info->resp_ie =
2814 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2817 conn_info->resp_ie_len = 0;
2818 conn_info->resp_ie = NULL;
2820 WL_CONN("req len (%d) resp len (%d)\n",
2821 conn_info->req_ie_len, conn_info->resp_ie_len);
2827 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2828 struct net_device *ndev,
2829 const struct brcmf_event_msg *e)
2831 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2832 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2833 struct brcmf_channel_info_le channel_le;
2834 struct ieee80211_channel *notify_channel;
2835 struct ieee80211_supported_band *band;
2840 WL_TRACE("Enter\n");
2842 brcmf_get_assoc_ies(cfg_priv);
2843 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2844 brcmf_update_bss_info(cfg_priv);
2846 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2847 sizeof(channel_le));
2849 target_channel = le32_to_cpu(channel_le.target_channel);
2850 WL_CONN("Roamed to channel %d\n", target_channel);
2852 if (target_channel <= CH_MAX_2G_CHANNEL)
2853 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2855 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2857 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2858 notify_channel = ieee80211_get_channel(wiphy, freq);
2860 cfg80211_roamed(ndev, notify_channel,
2861 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2862 conn_info->req_ie, conn_info->req_ie_len,
2863 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2864 WL_CONN("Report roaming result\n");
2866 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2872 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2873 struct net_device *ndev, const struct brcmf_event_msg *e,
2876 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2879 WL_TRACE("Enter\n");
2881 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2883 brcmf_get_assoc_ies(cfg_priv);
2884 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2886 brcmf_update_bss_info(cfg_priv);
2888 cfg80211_connect_result(ndev,
2889 (u8 *)brcmf_read_prof(cfg_priv,
2892 conn_info->req_ie_len,
2894 conn_info->resp_ie_len,
2895 completed ? WLAN_STATUS_SUCCESS :
2896 WLAN_STATUS_AUTH_TIMEOUT,
2899 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2900 WL_CONN("Report connect result - connection %s\n",
2901 completed ? "succeeded" : "failed");
2908 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2909 struct net_device *ndev,
2910 const struct brcmf_event_msg *e, void *data)
2914 if (brcmf_is_linkup(cfg_priv, e)) {
2915 WL_CONN("Linkup\n");
2916 if (brcmf_is_ibssmode(cfg_priv)) {
2917 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2919 wl_inform_ibss(cfg_priv, ndev, e->addr);
2920 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2921 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2922 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2924 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2925 } else if (brcmf_is_linkdown(cfg_priv, e)) {
2926 WL_CONN("Linkdown\n");
2927 if (brcmf_is_ibssmode(cfg_priv)) {
2928 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2929 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2931 brcmf_link_down(cfg_priv);
2933 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2934 if (test_and_clear_bit(WL_STATUS_CONNECTED,
2935 &cfg_priv->status)) {
2936 cfg80211_disconnected(ndev, 0, NULL, 0,
2938 brcmf_link_down(cfg_priv);
2941 brcmf_init_prof(cfg_priv->profile);
2942 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2943 if (brcmf_is_ibssmode(cfg_priv))
2944 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2946 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2953 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2954 struct net_device *ndev,
2955 const struct brcmf_event_msg *e, void *data)
2958 u32 event = be32_to_cpu(e->event_type);
2959 u32 status = be32_to_cpu(e->status);
2961 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2962 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2963 brcmf_bss_roaming_done(cfg_priv, ndev, e);
2965 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2972 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2973 struct net_device *ndev,
2974 const struct brcmf_event_msg *e, void *data)
2976 u16 flags = be16_to_cpu(e->flags);
2977 enum nl80211_key_type key_type;
2979 if (flags & BRCMF_EVENT_MSG_GROUP)
2980 key_type = NL80211_KEYTYPE_GROUP;
2982 key_type = NL80211_KEYTYPE_PAIRWISE;
2984 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2991 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2992 struct net_device *ndev,
2993 const struct brcmf_event_msg *e, void *data)
2995 struct brcmf_channel_info_le channel_inform_le;
2996 struct brcmf_scan_results_le *bss_list_le;
2997 u32 len = WL_SCAN_BUF_MAX;
2999 bool scan_abort = false;
3002 WL_TRACE("Enter\n");
3004 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3006 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3009 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3010 WL_ERR("Scan complete while device not scanning\n");
3016 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3017 sizeof(channel_inform_le));
3019 WL_ERR("scan busy (%d)\n", err);
3023 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3025 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3026 cfg_priv->bss_list = cfg_priv->scan_results;
3027 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3029 memset(cfg_priv->scan_results, 0, len);
3030 bss_list_le->buflen = cpu_to_le32(len);
3031 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3032 cfg_priv->scan_results, len);
3034 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3039 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3040 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3041 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3043 err = brcmf_inform_bss(cfg_priv);
3050 if (cfg_priv->scan_request) {
3051 WL_SCAN("calling cfg80211_scan_done\n");
3052 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3053 brcmf_set_mpc(ndev, 1);
3054 cfg_priv->scan_request = NULL;
3062 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3064 conf->mode = (u32)-1;
3065 conf->frag_threshold = (u32)-1;
3066 conf->rts_threshold = (u32)-1;
3067 conf->retry_short = (u32)-1;
3068 conf->retry_long = (u32)-1;
3069 conf->tx_power = -1;
3072 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3074 memset(el, 0, sizeof(*el));
3075 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3076 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3077 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3078 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3079 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3082 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3084 kfree(cfg_priv->scan_results);
3085 cfg_priv->scan_results = NULL;
3086 kfree(cfg_priv->bss_info);
3087 cfg_priv->bss_info = NULL;
3088 kfree(cfg_priv->conf);
3089 cfg_priv->conf = NULL;
3090 kfree(cfg_priv->profile);
3091 cfg_priv->profile = NULL;
3092 kfree(cfg_priv->scan_req_int);
3093 cfg_priv->scan_req_int = NULL;
3094 kfree(cfg_priv->dcmd_buf);
3095 cfg_priv->dcmd_buf = NULL;
3096 kfree(cfg_priv->extra_buf);
3097 cfg_priv->extra_buf = NULL;
3098 kfree(cfg_priv->iscan);
3099 cfg_priv->iscan = NULL;
3100 kfree(cfg_priv->pmk_list);
3101 cfg_priv->pmk_list = NULL;
3104 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3106 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3107 if (!cfg_priv->scan_results)
3108 goto init_priv_mem_out;
3109 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3110 if (!cfg_priv->conf)
3111 goto init_priv_mem_out;
3112 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3113 if (!cfg_priv->profile)
3114 goto init_priv_mem_out;
3115 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3116 if (!cfg_priv->bss_info)
3117 goto init_priv_mem_out;
3118 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3120 if (!cfg_priv->scan_req_int)
3121 goto init_priv_mem_out;
3122 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3123 if (!cfg_priv->dcmd_buf)
3124 goto init_priv_mem_out;
3125 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3126 if (!cfg_priv->extra_buf)
3127 goto init_priv_mem_out;
3128 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3129 if (!cfg_priv->iscan)
3130 goto init_priv_mem_out;
3131 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3132 if (!cfg_priv->pmk_list)
3133 goto init_priv_mem_out;
3138 brcmf_deinit_priv_mem(cfg_priv);
3144 * retrieve first queued event from head
3147 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3148 struct brcmf_cfg80211_priv *cfg_priv)
3150 struct brcmf_cfg80211_event_q *e = NULL;
3152 spin_lock_irq(&cfg_priv->evt_q_lock);
3153 if (!list_empty(&cfg_priv->evt_q_list)) {
3154 e = list_first_entry(&cfg_priv->evt_q_list,
3155 struct brcmf_cfg80211_event_q, evt_q_list);
3156 list_del(&e->evt_q_list);
3158 spin_unlock_irq(&cfg_priv->evt_q_lock);
3164 ** push event to tail of the queue
3168 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3169 const struct brcmf_event_msg *msg)
3171 struct brcmf_cfg80211_event_q *e;
3174 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3179 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3181 spin_lock_irq(&cfg_priv->evt_q_lock);
3182 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3183 spin_unlock_irq(&cfg_priv->evt_q_lock);
3188 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3193 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3195 struct brcmf_cfg80211_priv *cfg_priv =
3196 container_of(work, struct brcmf_cfg80211_priv,
3198 struct brcmf_cfg80211_event_q *e;
3200 e = brcmf_deq_event(cfg_priv);
3202 WL_ERR("event queue empty...\n");
3207 WL_INFO("event type (%d)\n", e->etype);
3208 if (cfg_priv->el.handler[e->etype])
3209 cfg_priv->el.handler[e->etype](cfg_priv,
3210 cfg_to_ndev(cfg_priv),
3211 &e->emsg, e->edata);
3213 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3215 } while ((e = brcmf_deq_event(cfg_priv)));
3219 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3221 spin_lock_init(&cfg_priv->evt_q_lock);
3222 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3225 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3227 struct brcmf_cfg80211_event_q *e;
3229 spin_lock_irq(&cfg_priv->evt_q_lock);
3230 while (!list_empty(&cfg_priv->evt_q_list)) {
3231 e = list_first_entry(&cfg_priv->evt_q_list,
3232 struct brcmf_cfg80211_event_q, evt_q_list);
3233 list_del(&e->evt_q_list);
3236 spin_unlock_irq(&cfg_priv->evt_q_lock);
3239 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3243 cfg_priv->scan_request = NULL;
3244 cfg_priv->pwr_save = true;
3245 cfg_priv->iscan_on = true; /* iscan on & off switch.
3246 we enable iscan per default */
3247 cfg_priv->roam_on = true; /* roam on & off switch.
3248 we enable roam per default */
3250 cfg_priv->iscan_kickstart = false;
3251 cfg_priv->active_scan = true; /* we do active scan for
3252 specific scan per default */
3253 cfg_priv->dongle_up = false; /* dongle is not up yet */
3254 brcmf_init_eq(cfg_priv);
3255 err = brcmf_init_priv_mem(cfg_priv);
3258 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3259 brcmf_init_eloop_handler(&cfg_priv->el);
3260 mutex_init(&cfg_priv->usr_sync);
3261 err = brcmf_init_iscan(cfg_priv);
3264 brcmf_init_conf(cfg_priv->conf);
3265 brcmf_init_prof(cfg_priv->profile);
3266 brcmf_link_down(cfg_priv);
3271 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3273 cancel_work_sync(&cfg_priv->event_work);
3274 cfg_priv->dongle_up = false; /* dongle down */
3275 brcmf_flush_eq(cfg_priv);
3276 brcmf_link_down(cfg_priv);
3277 brcmf_term_iscan(cfg_priv);
3278 brcmf_deinit_priv_mem(cfg_priv);
3281 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3282 struct device *busdev,
3285 struct wireless_dev *wdev;
3286 struct brcmf_cfg80211_priv *cfg_priv;
3287 struct brcmf_cfg80211_iface *ci;
3288 struct brcmf_cfg80211_dev *cfg_dev;
3292 WL_ERR("ndev is invalid\n");
3295 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3299 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3305 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3306 cfg_priv = wdev_to_cfg(wdev);
3307 cfg_priv->wdev = wdev;
3308 cfg_priv->pub = data;
3309 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3310 ci->cfg_priv = cfg_priv;
3311 ndev->ieee80211_ptr = wdev;
3312 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3313 wdev->netdev = ndev;
3314 err = wl_init_priv(cfg_priv);
3316 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3317 goto cfg80211_attach_out;
3319 brcmf_set_drvdata(cfg_dev, ci);
3323 cfg80211_attach_out:
3324 brcmf_free_wdev(cfg_priv);
3329 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3331 struct brcmf_cfg80211_priv *cfg_priv;
3333 cfg_priv = brcmf_priv_get(cfg_dev);
3335 wl_deinit_priv(cfg_priv);
3336 brcmf_free_wdev(cfg_priv);
3337 brcmf_set_drvdata(cfg_dev, NULL);
3342 brcmf_cfg80211_event(struct net_device *ndev,
3343 const struct brcmf_event_msg *e, void *data)
3345 u32 event_type = be32_to_cpu(e->event_type);
3346 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3348 if (!brcmf_enq_event(cfg_priv, event_type, e))
3349 schedule_work(&cfg_priv->event_work);
3352 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3358 case NL80211_IFTYPE_MONITOR:
3359 case NL80211_IFTYPE_WDS:
3360 WL_ERR("type (%d) : currently we do not support this mode\n",
3364 case NL80211_IFTYPE_ADHOC:
3367 case NL80211_IFTYPE_STATION:
3372 WL_ERR("invalid type (%d)\n", iftype);
3375 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3377 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3384 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3386 /* Room for "event_msgs" + '\0' + bitvec */
3387 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3388 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3391 WL_TRACE("Enter\n");
3393 /* Setup event_msgs */
3394 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3396 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3398 WL_ERR("Get event_msgs error (%d)\n", err);
3399 goto dongle_eventmsg_out;
3401 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3403 setbit(eventmask, BRCMF_E_SET_SSID);
3404 setbit(eventmask, BRCMF_E_ROAM);
3405 setbit(eventmask, BRCMF_E_PRUNE);
3406 setbit(eventmask, BRCMF_E_AUTH);
3407 setbit(eventmask, BRCMF_E_REASSOC);
3408 setbit(eventmask, BRCMF_E_REASSOC_IND);
3409 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3410 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3411 setbit(eventmask, BRCMF_E_DISASSOC);
3412 setbit(eventmask, BRCMF_E_JOIN);
3413 setbit(eventmask, BRCMF_E_ASSOC_IND);
3414 setbit(eventmask, BRCMF_E_PSK_SUP);
3415 setbit(eventmask, BRCMF_E_LINK);
3416 setbit(eventmask, BRCMF_E_NDIS_LINK);
3417 setbit(eventmask, BRCMF_E_MIC_ERROR);
3418 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3419 setbit(eventmask, BRCMF_E_TXFAIL);
3420 setbit(eventmask, BRCMF_E_JOIN_START);
3421 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3423 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3425 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3427 WL_ERR("Set event_msgs error (%d)\n", err);
3428 goto dongle_eventmsg_out;
3431 dongle_eventmsg_out:
3437 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3441 __le32 roamtrigger[2];
3442 __le32 roam_delta[2];
3447 * Setup timeout if Beacons are lost and roam is
3448 * off to report link down
3451 bcn_to_le = cpu_to_le32(bcn_timeout);
3452 brcmu_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3453 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3454 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3455 iovbuf, sizeof(iovbuf));
3457 WL_ERR("bcn_timeout error (%d)\n", err);
3458 goto dongle_rom_out;
3463 * Enable/Disable built-in roaming to allow supplicant
3464 * to take care of roaming
3466 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3467 roamvar_le = cpu_to_le32(roamvar);
3468 brcmu_mkiovar("roam_off", (char *)&roamvar_le,
3469 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3470 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3472 WL_ERR("roam_off error (%d)\n", err);
3473 goto dongle_rom_out;
3476 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3477 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3478 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3479 (void *)roamtrigger, sizeof(roamtrigger));
3481 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3482 goto dongle_rom_out;
3485 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3486 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3487 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3488 (void *)roam_delta, sizeof(roam_delta));
3490 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3491 goto dongle_rom_out;
3499 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3500 s32 scan_unassoc_time, s32 scan_passive_time)
3503 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3504 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3505 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3507 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3508 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3510 if (err == -EOPNOTSUPP)
3511 WL_INFO("Scan assoc time is not supported\n");
3513 WL_ERR("Scan assoc time error (%d)\n", err);
3514 goto dongle_scantime_out;
3516 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3517 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3519 if (err == -EOPNOTSUPP)
3520 WL_INFO("Scan unassoc time is not supported\n");
3522 WL_ERR("Scan unassoc time error (%d)\n", err);
3523 goto dongle_scantime_out;
3526 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3527 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3529 if (err == -EOPNOTSUPP)
3530 WL_INFO("Scan passive time is not supported\n");
3532 WL_ERR("Scan passive time error (%d)\n", err);
3533 goto dongle_scantime_out;
3536 dongle_scantime_out:
3540 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3542 struct wiphy *wiphy;
3547 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3548 &phy_list, sizeof(phy_list));
3550 WL_ERR("error (%d)\n", err);
3554 phy = ((char *)&phy_list)[1];
3555 WL_INFO("%c phy\n", phy);
3556 if (phy == 'n' || phy == 'a') {
3557 wiphy = cfg_to_wiphy(cfg_priv);
3558 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3564 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3566 return wl_update_wiphybands(cfg_priv);
3569 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3571 struct net_device *ndev;
3572 struct wireless_dev *wdev;
3576 if (cfg_priv->dongle_up)
3579 ndev = cfg_to_ndev(cfg_priv);
3580 wdev = ndev->ieee80211_ptr;
3582 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3583 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3585 err = brcmf_dongle_eventmsg(ndev);
3587 goto default_conf_out;
3589 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3590 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3592 goto default_conf_out;
3593 WL_INFO("power save set to %s\n",
3594 (power_mode ? "enabled" : "disabled"));
3596 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3599 goto default_conf_out;
3600 err = brcmf_dongle_mode(ndev, wdev->iftype);
3601 if (err && err != -EINPROGRESS)
3602 goto default_conf_out;
3603 err = brcmf_dongle_probecap(cfg_priv);
3605 goto default_conf_out;
3607 /* -EINPROGRESS: Call commit handler */
3611 cfg_priv->dongle_up = true;
3617 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3619 char buf[10+IFNAMSIZ];
3623 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3624 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3625 cfg_to_wiphy(cfg_priv)->debugfsdir);
3627 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3628 (u16 *)&cfg_priv->profile->beacon_interval);
3634 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3635 (u8 *)&cfg_priv->profile->dtim_period);
3645 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3647 debugfs_remove_recursive(cfg_priv->debugfsdir);
3648 cfg_priv->debugfsdir = NULL;
3651 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3655 set_bit(WL_STATUS_READY, &cfg_priv->status);
3657 brcmf_debugfs_add_netdev_params(cfg_priv);
3659 err = brcmf_config_dongle(cfg_priv);
3663 brcmf_invoke_iscan(cfg_priv);
3668 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3671 * While going down, if associated with AP disassociate
3672 * from AP to save power
3674 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3675 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3676 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3677 WL_INFO("Disassociating from AP");
3678 brcmf_link_down(cfg_priv);
3680 /* Make sure WPA_Supplicant receives all the event
3681 generated due to DISASSOC call to the fw to keep
3682 the state fw and WPA_Supplicant state consistent
3687 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3688 brcmf_term_iscan(cfg_priv);
3689 if (cfg_priv->scan_request) {
3690 cfg80211_scan_done(cfg_priv->scan_request, true);
3691 /* May need to perform this to cover rmmod */
3692 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3693 cfg_priv->scan_request = NULL;
3695 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3696 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3697 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3699 brcmf_debugfs_remove_netdev(cfg_priv);
3704 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3706 struct brcmf_cfg80211_priv *cfg_priv;
3709 cfg_priv = brcmf_priv_get(cfg_dev);
3710 mutex_lock(&cfg_priv->usr_sync);
3711 err = __brcmf_cfg80211_up(cfg_priv);
3712 mutex_unlock(&cfg_priv->usr_sync);
3717 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3719 struct brcmf_cfg80211_priv *cfg_priv;
3722 cfg_priv = brcmf_priv_get(cfg_dev);
3723 mutex_lock(&cfg_priv->usr_sync);
3724 err = __brcmf_cfg80211_down(cfg_priv);
3725 mutex_unlock(&cfg_priv->usr_sync);
3730 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3733 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3736 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3737 WL_ERR("ei crosses buffer boundary\n");
3740 ie->buf[ie->offset] = t;
3741 ie->buf[ie->offset + 1] = l;
3742 memcpy(&ie->buf[ie->offset + 2], v, l);
3743 ie->offset += l + 2;