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 /* tag_ID/length/value_buffer tuple */
257 /* Quarter dBm units to mW
258 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
259 * Table is offset so the last entry is largest mW value that fits in
263 #define QDBM_OFFSET 153 /* Offset for first entry */
264 #define QDBM_TABLE_LEN 40 /* Table size */
266 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
267 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
269 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
271 /* Largest mW value that will round down to the last table entry,
272 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
273 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
274 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
276 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
278 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
279 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
280 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
281 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
282 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
283 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
284 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
287 static u16 brcmf_qdbm_to_mw(u8 qdbm)
290 int idx = qdbm - QDBM_OFFSET;
292 if (idx >= QDBM_TABLE_LEN)
293 /* clamp to max u16 mW value */
296 /* scale the qdBm index up to the range of the table 0-40
297 * where an offset of 40 qdBm equals a factor of 10 mW.
304 /* return the mW value scaled down to the correct factor of 10,
305 * adding in factor/2 to get proper rounding.
307 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
310 static u8 brcmf_mw_to_qdbm(u16 mw)
317 /* handle boundary case */
321 offset = QDBM_OFFSET;
323 /* move mw into the range of the table */
324 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
329 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
330 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
331 nqdBm_to_mW_map[qdbm]) / 2;
332 if (mw_uint < boundary)
341 /* function for reading/writing a single u32 from/to the dongle */
343 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
346 __le32 par_le = cpu_to_le32(*par);
348 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
349 *par = le32_to_cpu(par_le);
354 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
355 struct brcmf_wsec_key_le *key_le)
357 key_le->index = cpu_to_le32(key->index);
358 key_le->len = cpu_to_le32(key->len);
359 key_le->algo = cpu_to_le32(key->algo);
360 key_le->flags = cpu_to_le32(key->flags);
361 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
362 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
363 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
364 memcpy(key_le->data, key->data, sizeof(key->data));
365 memcpy(key_le->ea, key->ea, sizeof(key->ea));
368 static int send_key_to_dongle(struct net_device *ndev,
369 struct brcmf_wsec_key *key)
372 struct brcmf_wsec_key_le key_le;
374 convert_key_from_CPU(key, &key_le);
375 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
377 WL_ERR("WLC_SET_KEY error (%d)\n", err);
382 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
383 enum nl80211_iftype type, u32 *flags,
384 struct vif_params *params)
386 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
387 struct wireless_dev *wdev;
392 if (!check_sys_up(wiphy))
396 case NL80211_IFTYPE_MONITOR:
397 case NL80211_IFTYPE_WDS:
398 WL_ERR("type (%d) : currently we do not support this type\n",
401 case NL80211_IFTYPE_ADHOC:
402 cfg_priv->conf->mode = WL_MODE_IBSS;
405 case NL80211_IFTYPE_STATION:
406 cfg_priv->conf->mode = WL_MODE_BSS;
414 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
416 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
419 wdev = ndev->ieee80211_ptr;
423 WL_INFO("IF Type = %s\n",
424 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
432 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
434 s8 buf[BRCMF_DCMD_SMLEN];
439 val_le = cpu_to_le32(val);
440 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
444 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
446 WL_ERR("error (%d)\n", err);
452 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
455 s8 buf[BRCMF_DCMD_SMLEN];
463 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
466 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
468 WL_ERR("error (%d)\n", err);
470 *retval = le32_to_cpu(var.val);
475 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
478 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
480 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
481 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
483 WL_ERR("fail to set mpc\n");
486 WL_INFO("MPC : %d\n", mpc);
490 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
491 struct brcmf_ssid *ssid)
493 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
494 params_le->bss_type = DOT11_BSSTYPE_ANY;
495 params_le->scan_type = 0;
496 params_le->channel_num = 0;
497 params_le->nprobes = cpu_to_le32(-1);
498 params_le->active_time = cpu_to_le32(-1);
499 params_le->passive_time = cpu_to_le32(-1);
500 params_le->home_time = cpu_to_le32(-1);
501 if (ssid && ssid->SSID_len)
502 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
506 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
507 s32 paramlen, void *bufptr, s32 buflen)
511 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
514 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
518 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
519 s32 paramlen, void *bufptr, s32 buflen)
523 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
526 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
530 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
531 struct brcmf_ssid *ssid, u16 action)
533 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
534 offsetof(struct brcmf_iscan_params_le, params_le);
535 struct brcmf_iscan_params_le *params;
538 if (ssid && ssid->SSID_len)
539 params_size += sizeof(struct brcmf_ssid);
540 params = kzalloc(params_size, GFP_KERNEL);
543 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
545 wl_iscan_prep(¶ms->params_le, ssid);
547 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
548 params->action = cpu_to_le16(action);
549 params->scan_duration = cpu_to_le16(0);
551 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
552 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
555 WL_INFO("system busy : iscan canceled\n");
557 WL_ERR("error (%d)\n", err);
564 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
566 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
567 struct net_device *ndev = cfg_to_ndev(cfg_priv);
568 struct brcmf_ssid ssid;
572 /* Broadcast scan by default */
573 memset(&ssid, 0, sizeof(ssid));
575 iscan->state = WL_ISCAN_STATE_SCANING;
577 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
578 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
579 &passive_scan, sizeof(passive_scan));
581 WL_ERR("error (%d)\n", err);
584 brcmf_set_mpc(ndev, 0);
585 cfg_priv->iscan_kickstart = true;
586 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
588 brcmf_set_mpc(ndev, 1);
589 cfg_priv->iscan_kickstart = false;
592 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
598 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
599 struct cfg80211_scan_request *request,
600 struct cfg80211_ssid *this_ssid)
602 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
603 struct cfg80211_ssid *ssids;
604 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
611 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
612 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
615 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
616 WL_ERR("Scanning being aborted : status (%lu)\n",
620 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
621 WL_ERR("Connecting : status (%lu)\n",
630 ssids = request->ssids;
631 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
635 /* we don't do iscan in ibss */
639 cfg_priv->scan_request = request;
640 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
642 err = brcmf_do_iscan(cfg_priv);
648 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
649 ssids->ssid, ssids->ssid_len);
650 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
651 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
652 sr->ssid_le.SSID_len = cpu_to_le32(0);
654 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
655 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
658 WL_SCAN("Broadcast scan\n");
661 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
662 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
663 &passive_scan, sizeof(passive_scan));
665 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
668 brcmf_set_mpc(ndev, 0);
669 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
670 sizeof(sr->ssid_le));
673 WL_INFO("system busy : scan for \"%s\" "
674 "canceled\n", sr->ssid_le.SSID);
676 WL_ERR("WLC_SCAN error (%d)\n", err);
678 brcmf_set_mpc(ndev, 1);
686 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
687 cfg_priv->scan_request = NULL;
692 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
693 struct cfg80211_scan_request *request)
699 if (!check_sys_up(wiphy))
702 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
704 WL_ERR("scan error (%d)\n", err);
710 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
714 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
716 WL_ERR("Error (%d)\n", err);
721 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
725 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
727 WL_ERR("Error (%d)\n", err);
732 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
735 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
737 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
739 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
745 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
747 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
748 struct net_device *ndev = cfg_to_ndev(cfg_priv);
752 if (!check_sys_up(wiphy))
755 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
756 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
757 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
758 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
762 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
763 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
764 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
765 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
769 if (changed & WIPHY_PARAM_RETRY_LONG
770 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
771 cfg_priv->conf->retry_long = wiphy->retry_long;
772 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
776 if (changed & WIPHY_PARAM_RETRY_SHORT
777 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
778 cfg_priv->conf->retry_short = wiphy->retry_short;
779 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
789 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
793 return &cfg_priv->profile->sec;
795 return &cfg_priv->profile->bssid;
797 return &cfg_priv->profile->ssid;
799 WL_ERR("invalid item (%d)\n", item);
804 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
805 const struct brcmf_event_msg *e, void *data, s32 item)
808 struct brcmf_ssid *ssid;
812 ssid = (struct brcmf_ssid *) data;
813 memset(cfg_priv->profile->ssid.SSID, 0,
814 sizeof(cfg_priv->profile->ssid.SSID));
815 memcpy(cfg_priv->profile->ssid.SSID,
816 ssid->SSID, ssid->SSID_len);
817 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
821 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
823 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
826 memcpy(&cfg_priv->profile->sec, data,
827 sizeof(cfg_priv->profile->sec));
829 case WL_PROF_BEACONINT:
830 cfg_priv->profile->beacon_interval = *(u16 *)data;
832 case WL_PROF_DTIMPERIOD:
833 cfg_priv->profile->dtim_period = *(u8 *)data;
836 WL_ERR("unsupported item (%d)\n", item);
844 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
846 memset(prof, 0, sizeof(*prof));
849 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
850 size_t *join_params_size)
855 if (ch <= CH_MAX_2G_CHANNEL)
856 chanspec |= WL_CHANSPEC_BAND_2G;
858 chanspec |= WL_CHANSPEC_BAND_5G;
860 chanspec |= WL_CHANSPEC_BW_20;
861 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
863 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
866 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
867 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
868 join_params->params_le.chanspec_num = cpu_to_le32(1);
870 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
871 "channel %d, chanspec %#X\n",
872 chanspec, ch, chanspec);
876 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
878 struct net_device *ndev = NULL;
883 if (cfg_priv->link_up) {
884 ndev = cfg_to_ndev(cfg_priv);
885 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
886 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
888 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
889 cfg_priv->link_up = false;
895 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
896 struct cfg80211_ibss_params *params)
898 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
899 struct brcmf_join_params join_params;
900 size_t join_params_size = 0;
904 struct brcmf_ssid ssid;
907 if (!check_sys_up(wiphy))
911 WL_CONN("SSID: %s\n", params->ssid);
913 WL_CONN("SSID: NULL, Not supported\n");
917 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
920 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
921 params->bssid[0], params->bssid[1], params->bssid[2],
922 params->bssid[3], params->bssid[4], params->bssid[5]);
924 WL_CONN("No BSSID specified\n");
927 WL_CONN("channel: %d\n", params->channel->center_freq);
929 WL_CONN("no channel specified\n");
931 if (params->channel_fixed)
932 WL_CONN("fixed channel required\n");
934 WL_CONN("no fixed channel required\n");
936 if (params->ie && params->ie_len)
937 WL_CONN("ie len: %d\n", params->ie_len);
939 WL_CONN("no ie specified\n");
941 if (params->beacon_interval)
942 WL_CONN("beacon interval: %d\n", params->beacon_interval);
944 WL_CONN("no beacon interval specified\n");
946 if (params->basic_rates)
947 WL_CONN("basic rates: %08X\n", params->basic_rates);
949 WL_CONN("no basic rates specified\n");
952 WL_CONN("privacy required\n");
954 WL_CONN("no privacy required\n");
956 /* Configure Privacy for starter */
960 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
962 WL_ERR("wsec failed (%d)\n", err);
966 /* Configure Beacon Interval for starter */
967 if (params->beacon_interval)
968 bcnprd = params->beacon_interval;
972 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
974 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
978 /* Configure required join parameter */
979 memset(&join_params, 0, sizeof(struct brcmf_join_params));
982 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
983 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
984 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
985 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
986 join_params_size = sizeof(join_params.ssid_le);
987 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
991 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
992 join_params_size = sizeof(join_params.ssid_le) +
993 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
995 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
998 brcmf_update_prof(cfg_priv, NULL,
999 &join_params.params_le.bssid, WL_PROF_BSSID);
1002 if (params->channel) {
1006 ieee80211_frequency_to_channel(
1007 params->channel->center_freq);
1008 if (params->channel_fixed) {
1009 /* adding chanspec */
1010 brcmf_ch_to_chanspec(cfg_priv->channel,
1011 &join_params, &join_params_size);
1014 /* set channel for starter */
1015 target_channel = cfg_priv->channel;
1016 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1019 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1023 cfg_priv->channel = 0;
1025 cfg_priv->ibss_starter = false;
1028 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1029 &join_params, join_params_size);
1031 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1037 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1043 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1045 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1048 WL_TRACE("Enter\n");
1049 if (!check_sys_up(wiphy))
1052 brcmf_link_down(cfg_priv);
1059 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1060 struct cfg80211_connect_params *sme)
1062 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1063 struct brcmf_cfg80211_security *sec;
1067 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1068 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1069 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1070 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1072 val = WPA_AUTH_DISABLED;
1073 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1074 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1076 WL_ERR("set wpa_auth failed (%d)\n", err);
1079 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1080 sec->wpa_versions = sme->crypto.wpa_versions;
1084 static s32 brcmf_set_auth_type(struct net_device *ndev,
1085 struct cfg80211_connect_params *sme)
1087 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1088 struct brcmf_cfg80211_security *sec;
1092 switch (sme->auth_type) {
1093 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1095 WL_CONN("open system\n");
1097 case NL80211_AUTHTYPE_SHARED_KEY:
1099 WL_CONN("shared key\n");
1101 case NL80211_AUTHTYPE_AUTOMATIC:
1103 WL_CONN("automatic\n");
1105 case NL80211_AUTHTYPE_NETWORK_EAP:
1106 WL_CONN("network eap\n");
1109 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1113 err = brcmf_dev_intvar_set(ndev, "auth", val);
1115 WL_ERR("set auth failed (%d)\n", err);
1118 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1119 sec->auth_type = sme->auth_type;
1124 brcmf_set_set_cipher(struct net_device *ndev,
1125 struct cfg80211_connect_params *sme)
1127 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1128 struct brcmf_cfg80211_security *sec;
1133 if (sme->crypto.n_ciphers_pairwise) {
1134 switch (sme->crypto.ciphers_pairwise[0]) {
1135 case WLAN_CIPHER_SUITE_WEP40:
1136 case WLAN_CIPHER_SUITE_WEP104:
1139 case WLAN_CIPHER_SUITE_TKIP:
1140 pval = TKIP_ENABLED;
1142 case WLAN_CIPHER_SUITE_CCMP:
1145 case WLAN_CIPHER_SUITE_AES_CMAC:
1149 WL_ERR("invalid cipher pairwise (%d)\n",
1150 sme->crypto.ciphers_pairwise[0]);
1154 if (sme->crypto.cipher_group) {
1155 switch (sme->crypto.cipher_group) {
1156 case WLAN_CIPHER_SUITE_WEP40:
1157 case WLAN_CIPHER_SUITE_WEP104:
1160 case WLAN_CIPHER_SUITE_TKIP:
1161 gval = TKIP_ENABLED;
1163 case WLAN_CIPHER_SUITE_CCMP:
1166 case WLAN_CIPHER_SUITE_AES_CMAC:
1170 WL_ERR("invalid cipher group (%d)\n",
1171 sme->crypto.cipher_group);
1176 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1177 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1179 WL_ERR("error (%d)\n", err);
1183 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1184 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1185 sec->cipher_group = sme->crypto.cipher_group;
1191 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1193 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1194 struct brcmf_cfg80211_security *sec;
1198 if (sme->crypto.n_akm_suites) {
1199 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1201 WL_ERR("could not get wpa_auth (%d)\n", err);
1204 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1205 switch (sme->crypto.akm_suites[0]) {
1206 case WLAN_AKM_SUITE_8021X:
1207 val = WPA_AUTH_UNSPECIFIED;
1209 case WLAN_AKM_SUITE_PSK:
1213 WL_ERR("invalid cipher group (%d)\n",
1214 sme->crypto.cipher_group);
1217 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1218 switch (sme->crypto.akm_suites[0]) {
1219 case WLAN_AKM_SUITE_8021X:
1220 val = WPA2_AUTH_UNSPECIFIED;
1222 case WLAN_AKM_SUITE_PSK:
1223 val = WPA2_AUTH_PSK;
1226 WL_ERR("invalid cipher group (%d)\n",
1227 sme->crypto.cipher_group);
1232 WL_CONN("setting wpa_auth to %d\n", val);
1233 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1235 WL_ERR("could not set wpa_auth (%d)\n", err);
1239 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1240 sec->wpa_auth = sme->crypto.akm_suites[0];
1246 brcmf_set_wep_sharedkey(struct net_device *ndev,
1247 struct cfg80211_connect_params *sme)
1249 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1250 struct brcmf_cfg80211_security *sec;
1251 struct brcmf_wsec_key key;
1255 WL_CONN("key len (%d)\n", sme->key_len);
1257 if (sme->key_len == 0)
1260 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1261 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1262 sec->wpa_versions, sec->cipher_pairwise);
1264 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1267 if (sec->cipher_pairwise &
1268 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1269 memset(&key, 0, sizeof(key));
1270 key.len = (u32) sme->key_len;
1271 key.index = (u32) sme->key_idx;
1272 if (key.len > sizeof(key.data)) {
1273 WL_ERR("Too long key length (%u)\n", key.len);
1276 memcpy(key.data, sme->key, key.len);
1277 key.flags = BRCMF_PRIMARY_KEY;
1278 switch (sec->cipher_pairwise) {
1279 case WLAN_CIPHER_SUITE_WEP40:
1280 key.algo = CRYPTO_ALGO_WEP1;
1282 case WLAN_CIPHER_SUITE_WEP104:
1283 key.algo = CRYPTO_ALGO_WEP128;
1286 WL_ERR("Invalid algorithm (%d)\n",
1287 sme->crypto.ciphers_pairwise[0]);
1290 /* Set the new key/index */
1291 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1292 key.len, key.index, key.algo);
1293 WL_CONN("key \"%s\"\n", key.data);
1294 err = send_key_to_dongle(ndev, &key);
1298 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1299 WL_CONN("set auth_type to shared key\n");
1300 val = 1; /* shared key */
1301 err = brcmf_dev_intvar_set(ndev, "auth", val);
1303 WL_ERR("set auth failed (%d)\n", err);
1312 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1313 struct cfg80211_connect_params *sme)
1315 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1316 struct ieee80211_channel *chan = sme->channel;
1317 struct brcmf_join_params join_params;
1318 size_t join_params_size;
1319 struct brcmf_ssid ssid;
1323 WL_TRACE("Enter\n");
1324 if (!check_sys_up(wiphy))
1328 WL_ERR("Invalid ssid\n");
1332 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1336 ieee80211_frequency_to_channel(chan->center_freq);
1337 WL_CONN("channel (%d), center_req (%d)\n",
1338 cfg_priv->channel, chan->center_freq);
1340 cfg_priv->channel = 0;
1342 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1344 err = brcmf_set_wpa_version(ndev, sme);
1346 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1350 err = brcmf_set_auth_type(ndev, sme);
1352 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1356 err = brcmf_set_set_cipher(ndev, sme);
1358 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1362 err = brcmf_set_key_mgmt(ndev, sme);
1364 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1368 err = brcmf_set_wep_sharedkey(ndev, sme);
1370 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1374 memset(&join_params, 0, sizeof(join_params));
1375 join_params_size = sizeof(join_params.ssid_le);
1377 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
1378 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1379 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1380 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1381 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1383 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1385 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1386 WL_CONN("ssid \"%s\", len (%d)\n",
1387 ssid.SSID, ssid.SSID_len);
1389 brcmf_ch_to_chanspec(cfg_priv->channel,
1390 &join_params, &join_params_size);
1391 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1392 &join_params, join_params_size);
1394 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1398 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1404 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1407 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1408 struct brcmf_scb_val_le scbval;
1411 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1412 if (!check_sys_up(wiphy))
1415 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1417 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1418 scbval.val = cpu_to_le32(reason_code);
1419 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1420 sizeof(struct brcmf_scb_val_le));
1422 WL_ERR("error (%d)\n", err);
1424 cfg_priv->link_up = false;
1431 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1432 enum nl80211_tx_power_setting type, s32 dbm)
1435 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1436 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1441 WL_TRACE("Enter\n");
1442 if (!check_sys_up(wiphy))
1446 case NL80211_TX_POWER_AUTOMATIC:
1448 case NL80211_TX_POWER_LIMITED:
1450 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1455 case NL80211_TX_POWER_FIXED:
1457 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1463 /* Make sure radio is off or on as far as software is concerned */
1464 disable = WL_RADIO_SW_DISABLE << 16;
1465 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1467 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1472 txpwrmw = (u16) dbm;
1473 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1474 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1476 WL_ERR("qtxpower error (%d)\n", err);
1477 cfg_priv->conf->tx_power = dbm;
1484 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1486 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1487 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1492 WL_TRACE("Enter\n");
1493 if (!check_sys_up(wiphy))
1496 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1498 WL_ERR("error (%d)\n", err);
1502 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1503 *dbm = (s32) brcmf_qdbm_to_mw(result);
1511 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1512 u8 key_idx, bool unicast, bool multicast)
1518 WL_TRACE("Enter\n");
1519 WL_CONN("key index (%d)\n", key_idx);
1520 if (!check_sys_up(wiphy))
1523 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1525 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1529 if (wsec & WEP_ENABLED) {
1530 /* Just select a new current key */
1532 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1535 WL_ERR("error (%d)\n", err);
1543 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1544 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1546 struct brcmf_wsec_key key;
1547 struct brcmf_wsec_key_le key_le;
1550 memset(&key, 0, sizeof(key));
1551 key.index = (u32) key_idx;
1552 /* Instead of bcast for ea address for default wep keys,
1553 driver needs it to be Null */
1554 if (!is_multicast_ether_addr(mac_addr))
1555 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1556 key.len = (u32) params->key_len;
1557 /* check for key index change */
1560 err = send_key_to_dongle(ndev, &key);
1564 if (key.len > sizeof(key.data)) {
1565 WL_ERR("Invalid key length (%d)\n", key.len);
1569 WL_CONN("Setting the key index %d\n", key.index);
1570 memcpy(key.data, params->key, key.len);
1572 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1574 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1575 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1576 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1579 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1580 if (params->seq && params->seq_len == 6) {
1583 ivptr = (u8 *) params->seq;
1584 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1585 (ivptr[3] << 8) | ivptr[2];
1586 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1587 key.iv_initialized = true;
1590 switch (params->cipher) {
1591 case WLAN_CIPHER_SUITE_WEP40:
1592 key.algo = CRYPTO_ALGO_WEP1;
1593 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1595 case WLAN_CIPHER_SUITE_WEP104:
1596 key.algo = CRYPTO_ALGO_WEP128;
1597 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1599 case WLAN_CIPHER_SUITE_TKIP:
1600 key.algo = CRYPTO_ALGO_TKIP;
1601 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1603 case WLAN_CIPHER_SUITE_AES_CMAC:
1604 key.algo = CRYPTO_ALGO_AES_CCM;
1605 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1607 case WLAN_CIPHER_SUITE_CCMP:
1608 key.algo = CRYPTO_ALGO_AES_CCM;
1609 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1612 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1615 convert_key_from_CPU(&key, &key_le);
1617 brcmf_netdev_wait_pend8021x(ndev);
1618 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1621 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1629 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1630 u8 key_idx, bool pairwise, const u8 *mac_addr,
1631 struct key_params *params)
1633 struct brcmf_wsec_key key;
1639 WL_TRACE("Enter\n");
1640 WL_CONN("key index (%d)\n", key_idx);
1641 if (!check_sys_up(wiphy))
1646 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1648 memset(&key, 0, sizeof(key));
1650 key.len = (u32) params->key_len;
1651 key.index = (u32) key_idx;
1653 if (key.len > sizeof(key.data)) {
1654 WL_ERR("Too long key length (%u)\n", key.len);
1658 memcpy(key.data, params->key, key.len);
1660 key.flags = BRCMF_PRIMARY_KEY;
1661 switch (params->cipher) {
1662 case WLAN_CIPHER_SUITE_WEP40:
1663 key.algo = CRYPTO_ALGO_WEP1;
1664 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1666 case WLAN_CIPHER_SUITE_WEP104:
1667 key.algo = CRYPTO_ALGO_WEP128;
1668 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1670 case WLAN_CIPHER_SUITE_TKIP:
1671 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1672 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1673 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1674 key.algo = CRYPTO_ALGO_TKIP;
1675 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1677 case WLAN_CIPHER_SUITE_AES_CMAC:
1678 key.algo = CRYPTO_ALGO_AES_CCM;
1679 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1681 case WLAN_CIPHER_SUITE_CCMP:
1682 key.algo = CRYPTO_ALGO_AES_CCM;
1683 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1686 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1691 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1696 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1698 WL_ERR("get wsec error (%d)\n", err);
1701 wsec &= ~(WEP_ENABLED);
1703 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1705 WL_ERR("set wsec error (%d)\n", err);
1709 val = 1; /* assume shared key. otherwise 0 */
1710 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1712 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1719 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1720 u8 key_idx, bool pairwise, const u8 *mac_addr)
1722 struct brcmf_wsec_key key;
1727 WL_TRACE("Enter\n");
1728 if (!check_sys_up(wiphy))
1731 memset(&key, 0, sizeof(key));
1733 key.index = (u32) key_idx;
1734 key.flags = BRCMF_PRIMARY_KEY;
1735 key.algo = CRYPTO_ALGO_OFF;
1737 WL_CONN("key index (%d)\n", key_idx);
1739 /* Set the new key/index */
1740 err = send_key_to_dongle(ndev, &key);
1742 if (err == -EINVAL) {
1743 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1744 /* we ignore this key index in this case */
1745 WL_ERR("invalid key index (%d)\n", key_idx);
1747 /* Ignore this error, may happen during DISASSOC */
1753 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1755 WL_ERR("get wsec error (%d)\n", err);
1756 /* Ignore this error, may happen during DISASSOC */
1760 wsec &= ~(WEP_ENABLED);
1762 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1764 WL_ERR("set wsec error (%d)\n", err);
1765 /* Ignore this error, may happen during DISASSOC */
1770 val = 0; /* assume open key. otherwise 1 */
1771 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1773 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1774 /* Ignore this error, may happen during DISASSOC */
1783 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1784 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1785 void (*callback) (void *cookie, struct key_params * params))
1787 struct key_params params;
1788 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1789 struct brcmf_cfg80211_security *sec;
1793 WL_TRACE("Enter\n");
1794 WL_CONN("key index (%d)\n", key_idx);
1795 if (!check_sys_up(wiphy))
1798 memset(¶ms, 0, sizeof(params));
1800 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1802 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1803 /* Ignore this error, may happen during DISASSOC */
1809 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1810 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1811 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1812 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1813 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1814 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1815 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1819 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1820 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1823 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1824 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1827 WL_ERR("Invalid algo (0x%x)\n", wsec);
1831 callback(cookie, ¶ms);
1839 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1840 struct net_device *ndev, u8 key_idx)
1842 WL_INFO("Not supported\n");
1848 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1849 u8 *mac, struct station_info *sinfo)
1851 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1852 struct brcmf_scb_val_le scb_val;
1856 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1858 WL_TRACE("Enter\n");
1859 if (!check_sys_up(wiphy))
1862 if (memcmp(mac, bssid, ETH_ALEN)) {
1863 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1864 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1865 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1866 bssid[0], bssid[1], bssid[2], bssid[3],
1867 bssid[4], bssid[5]);
1872 /* Report the current tx rate */
1873 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1875 WL_ERR("Could not get rate (%d)\n", err);
1877 sinfo->filled |= STATION_INFO_TX_BITRATE;
1878 sinfo->txrate.legacy = rate * 5;
1879 WL_CONN("Rate %d Mbps\n", rate / 2);
1882 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1883 scb_val.val = cpu_to_le32(0);
1884 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1885 sizeof(struct brcmf_scb_val_le));
1887 WL_ERR("Could not get rssi (%d)\n", err);
1889 rssi = le32_to_cpu(scb_val.val);
1890 sinfo->filled |= STATION_INFO_SIGNAL;
1891 sinfo->signal = rssi;
1892 WL_CONN("RSSI %d dBm\n", rssi);
1901 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1902 bool enabled, s32 timeout)
1906 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1908 WL_TRACE("Enter\n");
1911 * Powersave enable/disable request is coming from the
1912 * cfg80211 even before the interface is up. In that
1913 * scenario, driver will be storing the power save
1914 * preference in cfg_priv struct to apply this to
1915 * FW later while initializing the dongle
1917 cfg_priv->pwr_save = enabled;
1918 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1920 WL_INFO("Device is not ready,"
1921 "storing the value in cfg_priv struct\n");
1925 pm = enabled ? PM_FAST : PM_OFF;
1926 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1928 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1931 WL_ERR("net_device is not ready yet\n");
1933 WL_ERR("error (%d)\n", err);
1941 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1943 const struct cfg80211_bitrate_mask *mask)
1945 struct brcm_rateset_le rateset_le;
1953 WL_TRACE("Enter\n");
1954 if (!check_sys_up(wiphy))
1957 /* addr param is always NULL. ignore it */
1958 /* Get current rateset */
1959 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1960 sizeof(rateset_le));
1962 WL_ERR("could not get current rateset (%d)\n", err);
1966 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1968 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1971 val = wl_g_rates[legacy - 1].bitrate * 100000;
1973 if (val < le32_to_cpu(rateset_le.count))
1974 /* Select rate by rateset index */
1975 rate = rateset_le.rates[val] & 0x7f;
1977 /* Specified rate in bps */
1978 rate = val / 500000;
1980 WL_CONN("rate %d mbps\n", rate / 2);
1984 * Set rate override,
1985 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1987 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1988 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1989 if (err_bg && err_a) {
1990 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1991 err = err_bg | err_a;
1999 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
2000 struct brcmf_bss_info *bi)
2002 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2003 struct ieee80211_channel *notify_channel;
2004 struct cfg80211_bss *bss;
2005 struct ieee80211_supported_band *band;
2009 u64 notify_timestamp;
2010 u16 notify_capability;
2011 u16 notify_interval;
2013 size_t notify_ielen;
2016 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2017 WL_ERR("Bss info is larger than buffer. Discarding\n");
2021 channel = bi->ctl_ch ? bi->ctl_ch :
2022 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2024 if (channel <= CH_MAX_2G_CHANNEL)
2025 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2027 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2029 freq = ieee80211_channel_to_frequency(channel, band->band);
2030 notify_channel = ieee80211_get_channel(wiphy, freq);
2032 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2033 notify_capability = le16_to_cpu(bi->capability);
2034 notify_interval = le16_to_cpu(bi->beacon_period);
2035 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2036 notify_ielen = le32_to_cpu(bi->ie_length);
2037 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2039 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2040 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2041 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2042 WL_CONN("Channel: %d(%d)\n", channel, freq);
2043 WL_CONN("Capability: %X\n", notify_capability);
2044 WL_CONN("Beacon interval: %d\n", notify_interval);
2045 WL_CONN("Signal: %d\n", notify_signal);
2046 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2048 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2049 notify_timestamp, notify_capability, notify_interval, notify_ie,
2050 notify_ielen, notify_signal, GFP_KERNEL);
2053 WL_ERR("cfg80211_inform_bss_frame error\n");
2060 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2062 struct brcmf_scan_results *bss_list;
2063 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2067 bss_list = cfg_priv->bss_list;
2068 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2069 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2073 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2074 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2075 bi = next_bss(bss_list, bi);
2076 err = brcmf_inform_single_bss(cfg_priv, bi);
2083 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2084 struct net_device *ndev, const u8 *bssid)
2086 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2087 struct ieee80211_channel *notify_channel;
2088 struct brcmf_bss_info *bi = NULL;
2089 struct ieee80211_supported_band *band;
2094 u64 notify_timestamp;
2095 u16 notify_capability;
2096 u16 notify_interval;
2098 size_t notify_ielen;
2101 WL_TRACE("Enter\n");
2103 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2109 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2111 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2113 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2117 bi = (struct brcmf_bss_info *)(buf + 4);
2119 channel = bi->ctl_ch ? bi->ctl_ch :
2120 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2122 if (channel <= CH_MAX_2G_CHANNEL)
2123 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2125 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2127 freq = ieee80211_channel_to_frequency(channel, band->band);
2128 notify_channel = ieee80211_get_channel(wiphy, freq);
2130 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2131 notify_capability = le16_to_cpu(bi->capability);
2132 notify_interval = le16_to_cpu(bi->beacon_period);
2133 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2134 notify_ielen = le32_to_cpu(bi->ie_length);
2135 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2137 WL_CONN("channel: %d(%d)\n", channel, freq);
2138 WL_CONN("capability: %X\n", notify_capability);
2139 WL_CONN("beacon interval: %d\n", notify_interval);
2140 WL_CONN("signal: %d\n", notify_signal);
2141 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2143 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2144 notify_timestamp, notify_capability, notify_interval,
2145 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2156 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2158 return cfg_priv->conf->mode == WL_MODE_IBSS;
2162 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2163 * triples, returning a pointer to the substring whose first element
2166 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2168 struct brcmf_tlv *elt;
2171 elt = (struct brcmf_tlv *) buf;
2174 /* find tagged parameter */
2175 while (totlen >= 2) {
2178 /* validate remaining totlen */
2179 if ((elt->id == key) && (totlen >= (len + 2)))
2182 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2183 totlen -= (len + 2);
2189 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2191 struct brcmf_bss_info *bi;
2192 struct brcmf_ssid *ssid;
2193 struct brcmf_tlv *tim;
2194 u16 beacon_interval;
2200 WL_TRACE("Enter\n");
2201 if (brcmf_is_ibssmode(cfg_priv))
2204 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2206 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2207 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2208 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2210 WL_ERR("Could not get bss info %d\n", err);
2211 goto update_bss_info_out;
2214 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2215 err = brcmf_inform_single_bss(cfg_priv, bi);
2217 goto update_bss_info_out;
2219 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2220 ie_len = le32_to_cpu(bi->ie_length);
2221 beacon_interval = le16_to_cpu(bi->beacon_period);
2223 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2225 dtim_period = tim->data[1];
2228 * active scan was done so we could not get dtim
2229 * information out of probe response.
2230 * so we speficially query dtim information to dongle.
2233 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2234 "dtim_assoc", &var);
2236 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2237 goto update_bss_info_out;
2239 dtim_period = (u8)var;
2242 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2243 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2245 update_bss_info_out:
2250 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2252 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2253 struct brcmf_ssid ssid;
2255 if (cfg_priv->iscan_on) {
2256 iscan->state = WL_ISCAN_STATE_IDLE;
2258 if (iscan->timer_on) {
2259 del_timer_sync(&iscan->timer);
2260 iscan->timer_on = 0;
2263 cancel_work_sync(&iscan->work);
2265 /* Abort iscan running in FW */
2266 memset(&ssid, 0, sizeof(ssid));
2267 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2271 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2274 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2275 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2277 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2278 WL_ERR("Scan complete while device not scanning\n");
2281 if (cfg_priv->scan_request) {
2282 WL_SCAN("ISCAN Completed scan: %s\n",
2283 aborted ? "Aborted" : "Done");
2284 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2285 brcmf_set_mpc(ndev, 1);
2286 cfg_priv->scan_request = NULL;
2288 cfg_priv->iscan_kickstart = false;
2291 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2293 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2294 WL_SCAN("wake up iscan\n");
2295 schedule_work(&iscan->work);
2303 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2304 struct brcmf_scan_results **bss_list)
2306 struct brcmf_iscan_results list;
2307 struct brcmf_scan_results *results;
2308 struct brcmf_scan_results_le *results_le;
2309 struct brcmf_iscan_results *list_buf;
2312 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2313 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2314 results = &list_buf->results;
2315 results_le = &list_buf->results_le;
2316 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2317 results->version = 0;
2320 memset(&list, 0, sizeof(list));
2321 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2322 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2323 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2324 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2326 WL_ERR("error (%d)\n", err);
2329 results->buflen = le32_to_cpu(results_le->buflen);
2330 results->version = le32_to_cpu(results_le->version);
2331 results->count = le32_to_cpu(results_le->count);
2332 WL_SCAN("results->count = %d\n", results_le->count);
2333 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2334 *status = le32_to_cpu(list_buf->status_le);
2335 WL_SCAN("status = %d\n", *status);
2336 *bss_list = results;
2341 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2343 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2346 iscan->state = WL_ISCAN_STATE_IDLE;
2347 brcmf_inform_bss(cfg_priv);
2348 brcmf_notify_iscan_complete(iscan, false);
2353 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2355 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2358 /* Reschedule the timer */
2359 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2360 iscan->timer_on = 1;
2365 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2367 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2370 brcmf_inform_bss(cfg_priv);
2371 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2372 /* Reschedule the timer */
2373 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2374 iscan->timer_on = 1;
2379 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2381 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2384 iscan->state = WL_ISCAN_STATE_IDLE;
2385 brcmf_notify_iscan_complete(iscan, true);
2390 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2392 struct brcmf_cfg80211_iscan_ctrl *iscan =
2393 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2395 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2396 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2397 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2399 if (iscan->timer_on) {
2400 del_timer_sync(&iscan->timer);
2401 iscan->timer_on = 0;
2404 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2405 status = BRCMF_SCAN_RESULTS_ABORTED;
2406 WL_ERR("Abort iscan\n");
2409 el->handler[status](cfg_priv);
2412 static void brcmf_iscan_timer(unsigned long data)
2414 struct brcmf_cfg80211_iscan_ctrl *iscan =
2415 (struct brcmf_cfg80211_iscan_ctrl *)data;
2418 iscan->timer_on = 0;
2419 WL_SCAN("timer expired\n");
2420 brcmf_wakeup_iscan(iscan);
2424 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2426 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2428 if (cfg_priv->iscan_on) {
2429 iscan->state = WL_ISCAN_STATE_IDLE;
2430 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2436 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2438 memset(el, 0, sizeof(*el));
2439 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2440 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2441 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2442 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2443 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2446 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2448 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2451 if (cfg_priv->iscan_on) {
2452 iscan->ndev = cfg_to_ndev(cfg_priv);
2453 brcmf_init_iscan_eloop(&iscan->el);
2454 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2455 init_timer(&iscan->timer);
2456 iscan->timer.data = (unsigned long) iscan;
2457 iscan->timer.function = brcmf_iscan_timer;
2458 err = brcmf_invoke_iscan(cfg_priv);
2460 iscan->data = cfg_priv;
2466 static void brcmf_delay(u32 ms)
2468 if (ms < 1000 / HZ) {
2476 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2478 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2481 * Check for WL_STATUS_READY before any function call which
2482 * could result is bus access. Don't block the resume for
2483 * any driver error conditions
2485 WL_TRACE("Enter\n");
2487 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2488 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2494 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2495 struct cfg80211_wowlan *wow)
2497 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2498 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2500 WL_TRACE("Enter\n");
2503 * Check for WL_STATUS_READY before any function call which
2504 * could result is bus access. Don't block the suspend for
2505 * any driver error conditions
2509 * While going to suspend if associated with AP disassociate
2510 * from AP to save power while system is in suspended state
2512 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2513 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2514 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2515 WL_INFO("Disassociating from AP"
2516 " while entering suspend state\n");
2517 brcmf_link_down(cfg_priv);
2520 * Make sure WPA_Supplicant receives all the event
2521 * generated due to DISASSOC call to the fw to keep
2522 * the state fw and WPA_Supplicant state consistent
2527 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2528 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2529 brcmf_term_iscan(cfg_priv);
2531 if (cfg_priv->scan_request) {
2532 /* Indidate scan abort to cfg80211 layer */
2533 WL_INFO("Terminating scan in progress\n");
2534 cfg80211_scan_done(cfg_priv->scan_request, true);
2535 cfg_priv->scan_request = NULL;
2537 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2538 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2540 /* Turn off watchdog timer */
2541 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2542 WL_INFO("Enable MPC\n");
2543 brcmf_set_mpc(ndev, 1);
2552 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2554 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2557 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2561 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2566 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2569 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2573 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2576 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2579 WL_ERR("error (%d)\n", err);
2582 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2588 brcmf_update_pmklist(struct net_device *ndev,
2589 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2594 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2596 WL_CONN("No of elements %d\n", pmkid_len);
2597 for (i = 0; i < pmkid_len; i++) {
2598 WL_CONN("PMKID[%d]: %pM =\n", i,
2599 &pmk_list->pmkids.pmkid[i].BSSID);
2600 for (j = 0; j < WLAN_PMKID_LEN; j++)
2601 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2605 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2612 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2613 struct cfg80211_pmksa *pmksa)
2615 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2616 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2621 WL_TRACE("Enter\n");
2622 if (!check_sys_up(wiphy))
2625 pmkid_len = le32_to_cpu(pmkids->npmkid);
2626 for (i = 0; i < pmkid_len; i++)
2627 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2629 if (i < WL_NUM_PMKIDS_MAX) {
2630 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2631 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2632 if (i == pmkid_len) {
2634 pmkids->npmkid = cpu_to_le32(pmkid_len);
2639 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2640 pmkids->pmkid[pmkid_len].BSSID);
2641 for (i = 0; i < WLAN_PMKID_LEN; i++)
2642 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2644 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2651 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2652 struct cfg80211_pmksa *pmksa)
2654 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2655 struct pmkid_list pmkid;
2659 WL_TRACE("Enter\n");
2660 if (!check_sys_up(wiphy))
2663 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2664 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2666 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2667 &pmkid.pmkid[0].BSSID);
2668 for (i = 0; i < WLAN_PMKID_LEN; i++)
2669 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2671 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2672 for (i = 0; i < pmkid_len; i++)
2674 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2679 && (i < pmkid_len)) {
2680 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2681 sizeof(struct pmkid));
2682 for (; i < (pmkid_len - 1); i++) {
2683 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2684 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2686 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2687 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2690 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2694 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2702 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2704 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2707 WL_TRACE("Enter\n");
2708 if (!check_sys_up(wiphy))
2711 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2712 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2719 static struct cfg80211_ops wl_cfg80211_ops = {
2720 .change_virtual_intf = brcmf_cfg80211_change_iface,
2721 .scan = brcmf_cfg80211_scan,
2722 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2723 .join_ibss = brcmf_cfg80211_join_ibss,
2724 .leave_ibss = brcmf_cfg80211_leave_ibss,
2725 .get_station = brcmf_cfg80211_get_station,
2726 .set_tx_power = brcmf_cfg80211_set_tx_power,
2727 .get_tx_power = brcmf_cfg80211_get_tx_power,
2728 .add_key = brcmf_cfg80211_add_key,
2729 .del_key = brcmf_cfg80211_del_key,
2730 .get_key = brcmf_cfg80211_get_key,
2731 .set_default_key = brcmf_cfg80211_config_default_key,
2732 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2733 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2734 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2735 .connect = brcmf_cfg80211_connect,
2736 .disconnect = brcmf_cfg80211_disconnect,
2737 .suspend = brcmf_cfg80211_suspend,
2738 .resume = brcmf_cfg80211_resume,
2739 .set_pmksa = brcmf_cfg80211_set_pmksa,
2740 .del_pmksa = brcmf_cfg80211_del_pmksa,
2741 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2744 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2750 return NL80211_IFTYPE_STATION;
2752 return NL80211_IFTYPE_ADHOC;
2754 return NL80211_IFTYPE_UNSPECIFIED;
2760 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2761 struct device *ndev)
2763 struct wireless_dev *wdev;
2766 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2768 return ERR_PTR(-ENOMEM);
2771 wiphy_new(&wl_cfg80211_ops,
2772 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2774 WL_ERR("Couldn not allocate wiphy device\n");
2778 set_wiphy_dev(wdev->wiphy, ndev);
2779 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2780 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2781 wdev->wiphy->interface_modes =
2782 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2783 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2784 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2785 * it as 11a by default.
2786 * This will be updated with
2789 * if phy has 11n capability
2791 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2792 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2793 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2794 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2798 err = wiphy_register(wdev->wiphy);
2800 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2801 goto wiphy_register_out;
2806 wiphy_free(wdev->wiphy);
2811 return ERR_PTR(err);
2814 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2816 struct wireless_dev *wdev = cfg_priv->wdev;
2819 WL_ERR("wdev is invalid\n");
2822 wiphy_unregister(wdev->wiphy);
2823 wiphy_free(wdev->wiphy);
2825 cfg_priv->wdev = NULL;
2828 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2829 const struct brcmf_event_msg *e)
2831 u32 event = be32_to_cpu(e->event_type);
2832 u32 status = be32_to_cpu(e->status);
2834 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2835 WL_CONN("Processing set ssid\n");
2836 cfg_priv->link_up = true;
2843 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2844 const struct brcmf_event_msg *e)
2846 u32 event = be32_to_cpu(e->event_type);
2847 u16 flags = be16_to_cpu(e->flags);
2849 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2850 WL_CONN("Processing link down\n");
2856 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2857 const struct brcmf_event_msg *e)
2859 u32 event = be32_to_cpu(e->event_type);
2860 u32 status = be32_to_cpu(e->status);
2862 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2863 WL_CONN("Processing Link %s & no network found\n",
2864 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2869 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2870 WL_CONN("Processing connecting & no network found\n");
2877 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2879 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2881 kfree(conn_info->req_ie);
2882 conn_info->req_ie = NULL;
2883 conn_info->req_ie_len = 0;
2884 kfree(conn_info->resp_ie);
2885 conn_info->resp_ie = NULL;
2886 conn_info->resp_ie_len = 0;
2889 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2891 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2892 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2893 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2898 brcmf_clear_assoc_ies(cfg_priv);
2900 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2903 WL_ERR("could not get assoc info (%d)\n", err);
2907 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2908 req_len = le32_to_cpu(assoc_info->req_len);
2909 resp_len = le32_to_cpu(assoc_info->resp_len);
2911 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2912 cfg_priv->extra_buf,
2915 WL_ERR("could not get assoc req (%d)\n", err);
2918 conn_info->req_ie_len = req_len;
2920 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2923 conn_info->req_ie_len = 0;
2924 conn_info->req_ie = NULL;
2927 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2928 cfg_priv->extra_buf,
2931 WL_ERR("could not get assoc resp (%d)\n", err);
2934 conn_info->resp_ie_len = resp_len;
2935 conn_info->resp_ie =
2936 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2939 conn_info->resp_ie_len = 0;
2940 conn_info->resp_ie = NULL;
2942 WL_CONN("req len (%d) resp len (%d)\n",
2943 conn_info->req_ie_len, conn_info->resp_ie_len);
2949 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2950 struct net_device *ndev,
2951 const struct brcmf_event_msg *e)
2953 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2954 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2955 struct brcmf_channel_info_le channel_le;
2956 struct ieee80211_channel *notify_channel;
2957 struct ieee80211_supported_band *band;
2962 WL_TRACE("Enter\n");
2964 brcmf_get_assoc_ies(cfg_priv);
2965 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2966 brcmf_update_bss_info(cfg_priv);
2968 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2969 sizeof(channel_le));
2971 target_channel = le32_to_cpu(channel_le.target_channel);
2972 WL_CONN("Roamed to channel %d\n", target_channel);
2974 if (target_channel <= CH_MAX_2G_CHANNEL)
2975 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2977 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2979 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2980 notify_channel = ieee80211_get_channel(wiphy, freq);
2982 cfg80211_roamed(ndev, notify_channel,
2983 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2984 conn_info->req_ie, conn_info->req_ie_len,
2985 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2986 WL_CONN("Report roaming result\n");
2988 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2994 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2995 struct net_device *ndev, const struct brcmf_event_msg *e,
2998 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3001 WL_TRACE("Enter\n");
3003 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3005 brcmf_get_assoc_ies(cfg_priv);
3006 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3008 brcmf_update_bss_info(cfg_priv);
3010 cfg80211_connect_result(ndev,
3011 (u8 *)brcmf_read_prof(cfg_priv,
3014 conn_info->req_ie_len,
3016 conn_info->resp_ie_len,
3017 completed ? WLAN_STATUS_SUCCESS :
3018 WLAN_STATUS_AUTH_TIMEOUT,
3021 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3022 WL_CONN("Report connect result - connection %s\n",
3023 completed ? "succeeded" : "failed");
3030 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3031 struct net_device *ndev,
3032 const struct brcmf_event_msg *e, void *data)
3036 if (brcmf_is_linkup(cfg_priv, e)) {
3037 WL_CONN("Linkup\n");
3038 if (brcmf_is_ibssmode(cfg_priv)) {
3039 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3041 wl_inform_ibss(cfg_priv, ndev, e->addr);
3042 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3043 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3044 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3046 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3047 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3048 WL_CONN("Linkdown\n");
3049 if (brcmf_is_ibssmode(cfg_priv)) {
3050 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3051 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3053 brcmf_link_down(cfg_priv);
3055 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3056 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3057 &cfg_priv->status)) {
3058 cfg80211_disconnected(ndev, 0, NULL, 0,
3060 brcmf_link_down(cfg_priv);
3063 brcmf_init_prof(cfg_priv->profile);
3064 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3065 if (brcmf_is_ibssmode(cfg_priv))
3066 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3068 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3075 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3076 struct net_device *ndev,
3077 const struct brcmf_event_msg *e, void *data)
3080 u32 event = be32_to_cpu(e->event_type);
3081 u32 status = be32_to_cpu(e->status);
3083 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3084 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3085 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3087 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3094 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3095 struct net_device *ndev,
3096 const struct brcmf_event_msg *e, void *data)
3098 u16 flags = be16_to_cpu(e->flags);
3099 enum nl80211_key_type key_type;
3101 if (flags & BRCMF_EVENT_MSG_GROUP)
3102 key_type = NL80211_KEYTYPE_GROUP;
3104 key_type = NL80211_KEYTYPE_PAIRWISE;
3106 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3113 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3114 struct net_device *ndev,
3115 const struct brcmf_event_msg *e, void *data)
3117 struct brcmf_channel_info_le channel_inform_le;
3118 struct brcmf_scan_results_le *bss_list_le;
3119 u32 len = WL_SCAN_BUF_MAX;
3121 bool scan_abort = false;
3124 WL_TRACE("Enter\n");
3126 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3128 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3131 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3132 WL_ERR("Scan complete while device not scanning\n");
3138 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3139 sizeof(channel_inform_le));
3141 WL_ERR("scan busy (%d)\n", err);
3145 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3147 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3148 cfg_priv->bss_list = cfg_priv->scan_results;
3149 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3151 memset(cfg_priv->scan_results, 0, len);
3152 bss_list_le->buflen = cpu_to_le32(len);
3153 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3154 cfg_priv->scan_results, len);
3156 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3161 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3162 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3163 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3165 err = brcmf_inform_bss(cfg_priv);
3172 if (cfg_priv->scan_request) {
3173 WL_SCAN("calling cfg80211_scan_done\n");
3174 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3175 brcmf_set_mpc(ndev, 1);
3176 cfg_priv->scan_request = NULL;
3184 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3186 conf->mode = (u32)-1;
3187 conf->frag_threshold = (u32)-1;
3188 conf->rts_threshold = (u32)-1;
3189 conf->retry_short = (u32)-1;
3190 conf->retry_long = (u32)-1;
3191 conf->tx_power = -1;
3194 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3196 memset(el, 0, sizeof(*el));
3197 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3198 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3199 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3200 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3201 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3204 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3206 kfree(cfg_priv->scan_results);
3207 cfg_priv->scan_results = NULL;
3208 kfree(cfg_priv->bss_info);
3209 cfg_priv->bss_info = NULL;
3210 kfree(cfg_priv->conf);
3211 cfg_priv->conf = NULL;
3212 kfree(cfg_priv->profile);
3213 cfg_priv->profile = NULL;
3214 kfree(cfg_priv->scan_req_int);
3215 cfg_priv->scan_req_int = NULL;
3216 kfree(cfg_priv->dcmd_buf);
3217 cfg_priv->dcmd_buf = NULL;
3218 kfree(cfg_priv->extra_buf);
3219 cfg_priv->extra_buf = NULL;
3220 kfree(cfg_priv->iscan);
3221 cfg_priv->iscan = NULL;
3222 kfree(cfg_priv->pmk_list);
3223 cfg_priv->pmk_list = NULL;
3226 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3228 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3229 if (!cfg_priv->scan_results)
3230 goto init_priv_mem_out;
3231 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3232 if (!cfg_priv->conf)
3233 goto init_priv_mem_out;
3234 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3235 if (!cfg_priv->profile)
3236 goto init_priv_mem_out;
3237 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3238 if (!cfg_priv->bss_info)
3239 goto init_priv_mem_out;
3240 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3242 if (!cfg_priv->scan_req_int)
3243 goto init_priv_mem_out;
3244 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3245 if (!cfg_priv->dcmd_buf)
3246 goto init_priv_mem_out;
3247 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3248 if (!cfg_priv->extra_buf)
3249 goto init_priv_mem_out;
3250 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3251 if (!cfg_priv->iscan)
3252 goto init_priv_mem_out;
3253 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3254 if (!cfg_priv->pmk_list)
3255 goto init_priv_mem_out;
3260 brcmf_deinit_priv_mem(cfg_priv);
3266 * retrieve first queued event from head
3269 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3270 struct brcmf_cfg80211_priv *cfg_priv)
3272 struct brcmf_cfg80211_event_q *e = NULL;
3274 spin_lock_irq(&cfg_priv->evt_q_lock);
3275 if (!list_empty(&cfg_priv->evt_q_list)) {
3276 e = list_first_entry(&cfg_priv->evt_q_list,
3277 struct brcmf_cfg80211_event_q, evt_q_list);
3278 list_del(&e->evt_q_list);
3280 spin_unlock_irq(&cfg_priv->evt_q_lock);
3286 ** push event to tail of the queue
3290 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3291 const struct brcmf_event_msg *msg)
3293 struct brcmf_cfg80211_event_q *e;
3296 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3301 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3303 spin_lock_irq(&cfg_priv->evt_q_lock);
3304 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3305 spin_unlock_irq(&cfg_priv->evt_q_lock);
3310 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3315 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3317 struct brcmf_cfg80211_priv *cfg_priv =
3318 container_of(work, struct brcmf_cfg80211_priv,
3320 struct brcmf_cfg80211_event_q *e;
3322 e = brcmf_deq_event(cfg_priv);
3324 WL_ERR("event queue empty...\n");
3329 WL_INFO("event type (%d)\n", e->etype);
3330 if (cfg_priv->el.handler[e->etype])
3331 cfg_priv->el.handler[e->etype](cfg_priv,
3332 cfg_to_ndev(cfg_priv),
3333 &e->emsg, e->edata);
3335 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3337 } while ((e = brcmf_deq_event(cfg_priv)));
3341 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3343 spin_lock_init(&cfg_priv->evt_q_lock);
3344 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3347 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3349 struct brcmf_cfg80211_event_q *e;
3351 spin_lock_irq(&cfg_priv->evt_q_lock);
3352 while (!list_empty(&cfg_priv->evt_q_list)) {
3353 e = list_first_entry(&cfg_priv->evt_q_list,
3354 struct brcmf_cfg80211_event_q, evt_q_list);
3355 list_del(&e->evt_q_list);
3358 spin_unlock_irq(&cfg_priv->evt_q_lock);
3361 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3365 cfg_priv->scan_request = NULL;
3366 cfg_priv->pwr_save = true;
3367 cfg_priv->iscan_on = true; /* iscan on & off switch.
3368 we enable iscan per default */
3369 cfg_priv->roam_on = true; /* roam on & off switch.
3370 we enable roam per default */
3372 cfg_priv->iscan_kickstart = false;
3373 cfg_priv->active_scan = true; /* we do active scan for
3374 specific scan per default */
3375 cfg_priv->dongle_up = false; /* dongle is not up yet */
3376 brcmf_init_eq(cfg_priv);
3377 err = brcmf_init_priv_mem(cfg_priv);
3380 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3381 brcmf_init_eloop_handler(&cfg_priv->el);
3382 mutex_init(&cfg_priv->usr_sync);
3383 err = brcmf_init_iscan(cfg_priv);
3386 brcmf_init_conf(cfg_priv->conf);
3387 brcmf_init_prof(cfg_priv->profile);
3388 brcmf_link_down(cfg_priv);
3393 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3395 cancel_work_sync(&cfg_priv->event_work);
3396 cfg_priv->dongle_up = false; /* dongle down */
3397 brcmf_flush_eq(cfg_priv);
3398 brcmf_link_down(cfg_priv);
3399 brcmf_term_iscan(cfg_priv);
3400 brcmf_deinit_priv_mem(cfg_priv);
3403 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3404 struct device *busdev,
3407 struct wireless_dev *wdev;
3408 struct brcmf_cfg80211_priv *cfg_priv;
3409 struct brcmf_cfg80211_iface *ci;
3410 struct brcmf_cfg80211_dev *cfg_dev;
3414 WL_ERR("ndev is invalid\n");
3417 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3421 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3427 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3428 cfg_priv = wdev_to_cfg(wdev);
3429 cfg_priv->wdev = wdev;
3430 cfg_priv->pub = data;
3431 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3432 ci->cfg_priv = cfg_priv;
3433 ndev->ieee80211_ptr = wdev;
3434 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3435 wdev->netdev = ndev;
3436 err = wl_init_priv(cfg_priv);
3438 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3439 goto cfg80211_attach_out;
3441 brcmf_set_drvdata(cfg_dev, ci);
3445 cfg80211_attach_out:
3446 brcmf_free_wdev(cfg_priv);
3451 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3453 struct brcmf_cfg80211_priv *cfg_priv;
3455 cfg_priv = brcmf_priv_get(cfg_dev);
3457 wl_deinit_priv(cfg_priv);
3458 brcmf_free_wdev(cfg_priv);
3459 brcmf_set_drvdata(cfg_dev, NULL);
3464 brcmf_cfg80211_event(struct net_device *ndev,
3465 const struct brcmf_event_msg *e, void *data)
3467 u32 event_type = be32_to_cpu(e->event_type);
3468 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3470 if (!brcmf_enq_event(cfg_priv, event_type, e))
3471 schedule_work(&cfg_priv->event_work);
3474 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3480 case NL80211_IFTYPE_MONITOR:
3481 case NL80211_IFTYPE_WDS:
3482 WL_ERR("type (%d) : currently we do not support this mode\n",
3486 case NL80211_IFTYPE_ADHOC:
3489 case NL80211_IFTYPE_STATION:
3494 WL_ERR("invalid type (%d)\n", iftype);
3497 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3499 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3506 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3508 /* Room for "event_msgs" + '\0' + bitvec */
3509 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3510 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3513 WL_TRACE("Enter\n");
3515 /* Setup event_msgs */
3516 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3517 iovbuf, sizeof(iovbuf));
3518 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3520 WL_ERR("Get event_msgs error (%d)\n", err);
3521 goto dongle_eventmsg_out;
3523 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3525 setbit(eventmask, BRCMF_E_SET_SSID);
3526 setbit(eventmask, BRCMF_E_ROAM);
3527 setbit(eventmask, BRCMF_E_PRUNE);
3528 setbit(eventmask, BRCMF_E_AUTH);
3529 setbit(eventmask, BRCMF_E_REASSOC);
3530 setbit(eventmask, BRCMF_E_REASSOC_IND);
3531 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3532 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3533 setbit(eventmask, BRCMF_E_DISASSOC);
3534 setbit(eventmask, BRCMF_E_JOIN);
3535 setbit(eventmask, BRCMF_E_ASSOC_IND);
3536 setbit(eventmask, BRCMF_E_PSK_SUP);
3537 setbit(eventmask, BRCMF_E_LINK);
3538 setbit(eventmask, BRCMF_E_NDIS_LINK);
3539 setbit(eventmask, BRCMF_E_MIC_ERROR);
3540 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3541 setbit(eventmask, BRCMF_E_TXFAIL);
3542 setbit(eventmask, BRCMF_E_JOIN_START);
3543 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3545 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3546 iovbuf, sizeof(iovbuf));
3547 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3549 WL_ERR("Set event_msgs error (%d)\n", err);
3550 goto dongle_eventmsg_out;
3553 dongle_eventmsg_out:
3559 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3563 __le32 roamtrigger[2];
3564 __le32 roam_delta[2];
3569 * Setup timeout if Beacons are lost and roam is
3570 * off to report link down
3573 bcn_to_le = cpu_to_le32(bcn_timeout);
3574 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3575 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3576 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3577 iovbuf, sizeof(iovbuf));
3579 WL_ERR("bcn_timeout error (%d)\n", err);
3580 goto dongle_rom_out;
3585 * Enable/Disable built-in roaming to allow supplicant
3586 * to take care of roaming
3588 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3589 roamvar_le = cpu_to_le32(roamvar);
3590 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3591 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3592 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3594 WL_ERR("roam_off error (%d)\n", err);
3595 goto dongle_rom_out;
3598 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3599 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3600 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3601 (void *)roamtrigger, sizeof(roamtrigger));
3603 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3604 goto dongle_rom_out;
3607 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3608 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3609 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3610 (void *)roam_delta, sizeof(roam_delta));
3612 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3613 goto dongle_rom_out;
3621 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3622 s32 scan_unassoc_time, s32 scan_passive_time)
3625 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3626 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3627 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3629 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3630 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3632 if (err == -EOPNOTSUPP)
3633 WL_INFO("Scan assoc time is not supported\n");
3635 WL_ERR("Scan assoc time error (%d)\n", err);
3636 goto dongle_scantime_out;
3638 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3639 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3641 if (err == -EOPNOTSUPP)
3642 WL_INFO("Scan unassoc time is not supported\n");
3644 WL_ERR("Scan unassoc time error (%d)\n", err);
3645 goto dongle_scantime_out;
3648 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3649 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3651 if (err == -EOPNOTSUPP)
3652 WL_INFO("Scan passive time is not supported\n");
3654 WL_ERR("Scan passive time error (%d)\n", err);
3655 goto dongle_scantime_out;
3658 dongle_scantime_out:
3662 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3664 struct wiphy *wiphy;
3669 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3670 &phy_list, sizeof(phy_list));
3672 WL_ERR("error (%d)\n", err);
3676 phy = ((char *)&phy_list)[1];
3677 WL_INFO("%c phy\n", phy);
3678 if (phy == 'n' || phy == 'a') {
3679 wiphy = cfg_to_wiphy(cfg_priv);
3680 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3686 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3688 return wl_update_wiphybands(cfg_priv);
3691 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3693 struct net_device *ndev;
3694 struct wireless_dev *wdev;
3698 if (cfg_priv->dongle_up)
3701 ndev = cfg_to_ndev(cfg_priv);
3702 wdev = ndev->ieee80211_ptr;
3704 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3705 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3707 err = brcmf_dongle_eventmsg(ndev);
3709 goto default_conf_out;
3711 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3712 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3714 goto default_conf_out;
3715 WL_INFO("power save set to %s\n",
3716 (power_mode ? "enabled" : "disabled"));
3718 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3721 goto default_conf_out;
3722 err = brcmf_dongle_mode(ndev, wdev->iftype);
3723 if (err && err != -EINPROGRESS)
3724 goto default_conf_out;
3725 err = brcmf_dongle_probecap(cfg_priv);
3727 goto default_conf_out;
3729 /* -EINPROGRESS: Call commit handler */
3733 cfg_priv->dongle_up = true;
3739 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3741 char buf[10+IFNAMSIZ];
3745 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3746 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3747 cfg_to_wiphy(cfg_priv)->debugfsdir);
3749 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3750 (u16 *)&cfg_priv->profile->beacon_interval);
3756 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3757 (u8 *)&cfg_priv->profile->dtim_period);
3767 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3769 debugfs_remove_recursive(cfg_priv->debugfsdir);
3770 cfg_priv->debugfsdir = NULL;
3773 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3777 set_bit(WL_STATUS_READY, &cfg_priv->status);
3779 brcmf_debugfs_add_netdev_params(cfg_priv);
3781 err = brcmf_config_dongle(cfg_priv);
3785 brcmf_invoke_iscan(cfg_priv);
3790 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3793 * While going down, if associated with AP disassociate
3794 * from AP to save power
3796 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3797 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3798 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3799 WL_INFO("Disassociating from AP");
3800 brcmf_link_down(cfg_priv);
3802 /* Make sure WPA_Supplicant receives all the event
3803 generated due to DISASSOC call to the fw to keep
3804 the state fw and WPA_Supplicant state consistent
3809 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3810 brcmf_term_iscan(cfg_priv);
3811 if (cfg_priv->scan_request) {
3812 cfg80211_scan_done(cfg_priv->scan_request, true);
3813 /* May need to perform this to cover rmmod */
3814 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3815 cfg_priv->scan_request = NULL;
3817 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3818 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3819 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3821 brcmf_debugfs_remove_netdev(cfg_priv);
3826 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3828 struct brcmf_cfg80211_priv *cfg_priv;
3831 cfg_priv = brcmf_priv_get(cfg_dev);
3832 mutex_lock(&cfg_priv->usr_sync);
3833 err = __brcmf_cfg80211_up(cfg_priv);
3834 mutex_unlock(&cfg_priv->usr_sync);
3839 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3841 struct brcmf_cfg80211_priv *cfg_priv;
3844 cfg_priv = brcmf_priv_get(cfg_dev);
3845 mutex_lock(&cfg_priv->usr_sync);
3846 err = __brcmf_cfg80211_down(cfg_priv);
3847 mutex_unlock(&cfg_priv->usr_sync);
3852 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3855 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3858 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3859 WL_ERR("ei crosses buffer boundary\n");
3862 ie->buf[ie->offset] = t;
3863 ie->buf[ie->offset + 1] = l;
3864 memcpy(&ie->buf[ie->offset + 2], v, l);
3865 ie->offset += l + 2;