2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 #include <net/netlink.h>
33 #include <brcmu_utils.h>
35 #include <brcmu_wifi.h>
37 #include "wl_cfg80211.h"
39 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
40 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
42 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
44 static u32 brcmf_dbg_level = WL_DBG_ERR;
46 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
48 dev->driver_data = data;
51 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
56 data = dev->driver_data;
61 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
63 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
67 static bool check_sys_up(struct wiphy *wiphy)
69 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
70 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
71 WL_INFO("device is not ready : status (%d)\n",
72 (int)cfg_priv->status);
78 #define CHAN2G(_channel, _freq, _flags) { \
79 .band = IEEE80211_BAND_2GHZ, \
80 .center_freq = (_freq), \
81 .hw_value = (_channel), \
83 .max_antenna_gain = 0, \
87 #define CHAN5G(_channel, _flags) { \
88 .band = IEEE80211_BAND_5GHZ, \
89 .center_freq = 5000 + (5 * (_channel)), \
90 .hw_value = (_channel), \
92 .max_antenna_gain = 0, \
96 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
97 #define RATETAB_ENT(_rateid, _flags) \
99 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
100 .hw_value = (_rateid), \
104 static struct ieee80211_rate __wl_rates[] = {
105 RATETAB_ENT(BRCM_RATE_1M, 0),
106 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
107 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
108 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
109 RATETAB_ENT(BRCM_RATE_6M, 0),
110 RATETAB_ENT(BRCM_RATE_9M, 0),
111 RATETAB_ENT(BRCM_RATE_12M, 0),
112 RATETAB_ENT(BRCM_RATE_18M, 0),
113 RATETAB_ENT(BRCM_RATE_24M, 0),
114 RATETAB_ENT(BRCM_RATE_36M, 0),
115 RATETAB_ENT(BRCM_RATE_48M, 0),
116 RATETAB_ENT(BRCM_RATE_54M, 0),
119 #define wl_a_rates (__wl_rates + 4)
120 #define wl_a_rates_size 8
121 #define wl_g_rates (__wl_rates + 0)
122 #define wl_g_rates_size 12
124 static struct ieee80211_channel __wl_2ghz_channels[] = {
141 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
142 CHAN5G(34, 0), CHAN5G(36, 0),
143 CHAN5G(38, 0), CHAN5G(40, 0),
144 CHAN5G(42, 0), CHAN5G(44, 0),
145 CHAN5G(46, 0), CHAN5G(48, 0),
146 CHAN5G(52, 0), CHAN5G(56, 0),
147 CHAN5G(60, 0), CHAN5G(64, 0),
148 CHAN5G(100, 0), CHAN5G(104, 0),
149 CHAN5G(108, 0), CHAN5G(112, 0),
150 CHAN5G(116, 0), CHAN5G(120, 0),
151 CHAN5G(124, 0), CHAN5G(128, 0),
152 CHAN5G(132, 0), CHAN5G(136, 0),
153 CHAN5G(140, 0), CHAN5G(149, 0),
154 CHAN5G(153, 0), CHAN5G(157, 0),
155 CHAN5G(161, 0), CHAN5G(165, 0),
156 CHAN5G(184, 0), CHAN5G(188, 0),
157 CHAN5G(192, 0), CHAN5G(196, 0),
158 CHAN5G(200, 0), CHAN5G(204, 0),
159 CHAN5G(208, 0), CHAN5G(212, 0),
163 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
164 CHAN5G(32, 0), CHAN5G(34, 0),
165 CHAN5G(36, 0), CHAN5G(38, 0),
166 CHAN5G(40, 0), CHAN5G(42, 0),
167 CHAN5G(44, 0), CHAN5G(46, 0),
168 CHAN5G(48, 0), CHAN5G(50, 0),
169 CHAN5G(52, 0), CHAN5G(54, 0),
170 CHAN5G(56, 0), CHAN5G(58, 0),
171 CHAN5G(60, 0), CHAN5G(62, 0),
172 CHAN5G(64, 0), CHAN5G(66, 0),
173 CHAN5G(68, 0), CHAN5G(70, 0),
174 CHAN5G(72, 0), CHAN5G(74, 0),
175 CHAN5G(76, 0), CHAN5G(78, 0),
176 CHAN5G(80, 0), CHAN5G(82, 0),
177 CHAN5G(84, 0), CHAN5G(86, 0),
178 CHAN5G(88, 0), CHAN5G(90, 0),
179 CHAN5G(92, 0), CHAN5G(94, 0),
180 CHAN5G(96, 0), CHAN5G(98, 0),
181 CHAN5G(100, 0), CHAN5G(102, 0),
182 CHAN5G(104, 0), CHAN5G(106, 0),
183 CHAN5G(108, 0), CHAN5G(110, 0),
184 CHAN5G(112, 0), CHAN5G(114, 0),
185 CHAN5G(116, 0), CHAN5G(118, 0),
186 CHAN5G(120, 0), CHAN5G(122, 0),
187 CHAN5G(124, 0), CHAN5G(126, 0),
188 CHAN5G(128, 0), CHAN5G(130, 0),
189 CHAN5G(132, 0), CHAN5G(134, 0),
190 CHAN5G(136, 0), CHAN5G(138, 0),
191 CHAN5G(140, 0), CHAN5G(142, 0),
192 CHAN5G(144, 0), CHAN5G(145, 0),
193 CHAN5G(146, 0), CHAN5G(147, 0),
194 CHAN5G(148, 0), CHAN5G(149, 0),
195 CHAN5G(150, 0), CHAN5G(151, 0),
196 CHAN5G(152, 0), CHAN5G(153, 0),
197 CHAN5G(154, 0), CHAN5G(155, 0),
198 CHAN5G(156, 0), CHAN5G(157, 0),
199 CHAN5G(158, 0), CHAN5G(159, 0),
200 CHAN5G(160, 0), CHAN5G(161, 0),
201 CHAN5G(162, 0), CHAN5G(163, 0),
202 CHAN5G(164, 0), CHAN5G(165, 0),
203 CHAN5G(166, 0), CHAN5G(168, 0),
204 CHAN5G(170, 0), CHAN5G(172, 0),
205 CHAN5G(174, 0), CHAN5G(176, 0),
206 CHAN5G(178, 0), CHAN5G(180, 0),
207 CHAN5G(182, 0), CHAN5G(184, 0),
208 CHAN5G(186, 0), CHAN5G(188, 0),
209 CHAN5G(190, 0), CHAN5G(192, 0),
210 CHAN5G(194, 0), CHAN5G(196, 0),
211 CHAN5G(198, 0), CHAN5G(200, 0),
212 CHAN5G(202, 0), CHAN5G(204, 0),
213 CHAN5G(206, 0), CHAN5G(208, 0),
214 CHAN5G(210, 0), CHAN5G(212, 0),
215 CHAN5G(214, 0), CHAN5G(216, 0),
216 CHAN5G(218, 0), CHAN5G(220, 0),
217 CHAN5G(222, 0), CHAN5G(224, 0),
218 CHAN5G(226, 0), CHAN5G(228, 0),
221 static struct ieee80211_supported_band __wl_band_2ghz = {
222 .band = IEEE80211_BAND_2GHZ,
223 .channels = __wl_2ghz_channels,
224 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
225 .bitrates = wl_g_rates,
226 .n_bitrates = wl_g_rates_size,
229 static struct ieee80211_supported_band __wl_band_5ghz_a = {
230 .band = IEEE80211_BAND_5GHZ,
231 .channels = __wl_5ghz_a_channels,
232 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
233 .bitrates = wl_a_rates,
234 .n_bitrates = wl_a_rates_size,
237 static struct ieee80211_supported_band __wl_band_5ghz_n = {
238 .band = IEEE80211_BAND_5GHZ,
239 .channels = __wl_5ghz_n_channels,
240 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
241 .bitrates = wl_a_rates,
242 .n_bitrates = wl_a_rates_size,
245 static const u32 __wl_cipher_suites[] = {
246 WLAN_CIPHER_SUITE_WEP40,
247 WLAN_CIPHER_SUITE_WEP104,
248 WLAN_CIPHER_SUITE_TKIP,
249 WLAN_CIPHER_SUITE_CCMP,
250 WLAN_CIPHER_SUITE_AES_CMAC,
253 /* tag_ID/length/value_buffer tuple */
260 /* Quarter dBm units to mW
261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
262 * Table is offset so the last entry is largest mW value that fits in
266 #define QDBM_OFFSET 153 /* Offset for first entry */
267 #define QDBM_TABLE_LEN 40 /* Table size */
269 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
270 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
272 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
274 /* Largest mW value that will round down to the last table entry,
275 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
276 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
277 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
279 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
281 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
282 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
283 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
284 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
285 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
286 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
287 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
290 static u16 brcmf_qdbm_to_mw(u8 qdbm)
293 int idx = qdbm - QDBM_OFFSET;
295 if (idx >= QDBM_TABLE_LEN)
296 /* clamp to max u16 mW value */
299 /* scale the qdBm index up to the range of the table 0-40
300 * where an offset of 40 qdBm equals a factor of 10 mW.
307 /* return the mW value scaled down to the correct factor of 10,
308 * adding in factor/2 to get proper rounding.
310 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
313 static u8 brcmf_mw_to_qdbm(u16 mw)
320 /* handle boundary case */
324 offset = QDBM_OFFSET;
326 /* move mw into the range of the table */
327 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
332 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
333 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
334 nqdBm_to_mW_map[qdbm]) / 2;
335 if (mw_uint < boundary)
344 /* function for reading/writing a single u32 from/to the dongle */
346 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
349 __le32 par_le = cpu_to_le32(*par);
351 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
352 *par = le32_to_cpu(par_le);
357 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
358 struct brcmf_wsec_key_le *key_le)
360 key_le->index = cpu_to_le32(key->index);
361 key_le->len = cpu_to_le32(key->len);
362 key_le->algo = cpu_to_le32(key->algo);
363 key_le->flags = cpu_to_le32(key->flags);
364 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
365 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
366 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
367 memcpy(key_le->data, key->data, sizeof(key->data));
368 memcpy(key_le->ea, key->ea, sizeof(key->ea));
371 static int send_key_to_dongle(struct net_device *ndev,
372 struct brcmf_wsec_key *key)
375 struct brcmf_wsec_key_le key_le;
377 convert_key_from_CPU(key, &key_le);
378 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
380 WL_ERR("WLC_SET_KEY error (%d)\n", err);
385 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
386 enum nl80211_iftype type, u32 *flags,
387 struct vif_params *params)
389 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
390 struct wireless_dev *wdev;
395 if (!check_sys_up(wiphy))
399 case NL80211_IFTYPE_MONITOR:
400 case NL80211_IFTYPE_WDS:
401 WL_ERR("type (%d) : currently we do not support this type\n",
404 case NL80211_IFTYPE_ADHOC:
405 cfg_priv->conf->mode = WL_MODE_IBSS;
408 case NL80211_IFTYPE_STATION:
409 cfg_priv->conf->mode = WL_MODE_BSS;
417 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
419 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
422 wdev = ndev->ieee80211_ptr;
426 WL_INFO("IF Type = %s\n",
427 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
435 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
437 s8 buf[BRCMF_DCMD_SMLEN];
442 val_le = cpu_to_le32(val);
443 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
447 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
449 WL_ERR("error (%d)\n", err);
455 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
458 s8 buf[BRCMF_DCMD_SMLEN];
466 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
469 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
471 WL_ERR("error (%d)\n", err);
473 *retval = le32_to_cpu(var.val);
478 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
483 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
484 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
486 WL_ERR("fail to set mpc\n");
489 WL_INFO("MPC : %d\n", mpc);
493 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
494 struct brcmf_ssid *ssid)
496 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
497 params_le->bss_type = DOT11_BSSTYPE_ANY;
498 params_le->scan_type = 0;
499 params_le->channel_num = 0;
500 params_le->nprobes = cpu_to_le32(-1);
501 params_le->active_time = cpu_to_le32(-1);
502 params_le->passive_time = cpu_to_le32(-1);
503 params_le->home_time = cpu_to_le32(-1);
504 if (ssid && ssid->SSID_len)
505 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
509 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
510 s32 paramlen, void *bufptr, s32 buflen)
514 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
517 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
521 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
522 s32 paramlen, void *bufptr, s32 buflen)
526 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
529 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
533 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
534 struct brcmf_ssid *ssid, u16 action)
536 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
537 offsetof(struct brcmf_iscan_params_le, params_le);
538 struct brcmf_iscan_params_le *params;
541 if (ssid && ssid->SSID_len)
542 params_size += sizeof(struct brcmf_ssid);
543 params = kzalloc(params_size, GFP_KERNEL);
546 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
548 wl_iscan_prep(¶ms->params_le, ssid);
550 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
551 params->action = cpu_to_le16(action);
552 params->scan_duration = cpu_to_le16(0);
554 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
555 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
558 WL_INFO("system busy : iscan canceled\n");
560 WL_ERR("error (%d)\n", err);
567 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
569 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
570 struct net_device *ndev = cfg_to_ndev(cfg_priv);
571 struct brcmf_ssid ssid;
575 /* Broadcast scan by default */
576 memset(&ssid, 0, sizeof(ssid));
578 iscan->state = WL_ISCAN_STATE_SCANING;
580 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
581 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
582 &passive_scan, sizeof(passive_scan));
584 WL_ERR("error (%d)\n", err);
587 brcmf_set_mpc(ndev, 0);
588 cfg_priv->iscan_kickstart = true;
589 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
591 brcmf_set_mpc(ndev, 1);
592 cfg_priv->iscan_kickstart = false;
595 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
601 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
602 struct cfg80211_scan_request *request,
603 struct cfg80211_ssid *this_ssid)
605 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
606 struct cfg80211_ssid *ssids;
607 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
614 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
615 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
618 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
619 WL_ERR("Scanning being aborted : status (%lu)\n",
623 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
624 WL_ERR("Connecting : status (%lu)\n",
633 ssids = request->ssids;
634 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
638 /* we don't do iscan in ibss */
642 cfg_priv->scan_request = request;
643 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
645 err = brcmf_do_iscan(cfg_priv);
651 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
652 ssids->ssid, ssids->ssid_len);
653 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
654 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
655 sr->ssid_le.SSID_len = cpu_to_le32(0);
657 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
658 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
661 WL_SCAN("Broadcast scan\n");
664 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
665 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
666 &passive_scan, sizeof(passive_scan));
668 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
671 brcmf_set_mpc(ndev, 0);
672 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
673 sizeof(sr->ssid_le));
676 WL_INFO("system busy : scan for \"%s\" "
677 "canceled\n", sr->ssid_le.SSID);
679 WL_ERR("WLC_SCAN error (%d)\n", err);
681 brcmf_set_mpc(ndev, 1);
689 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
690 cfg_priv->scan_request = NULL;
695 brcmf_cfg80211_scan(struct wiphy *wiphy,
696 struct cfg80211_scan_request *request)
698 struct net_device *ndev = request->wdev->netdev;
703 if (!check_sys_up(wiphy))
706 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
708 WL_ERR("scan error (%d)\n", err);
714 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
718 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
720 WL_ERR("Error (%d)\n", err);
725 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
729 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
731 WL_ERR("Error (%d)\n", err);
736 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
739 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
741 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
743 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
749 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
751 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
752 struct net_device *ndev = cfg_to_ndev(cfg_priv);
756 if (!check_sys_up(wiphy))
759 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
760 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
761 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
762 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
766 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
767 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
768 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
769 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
773 if (changed & WIPHY_PARAM_RETRY_LONG
774 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
775 cfg_priv->conf->retry_long = wiphy->retry_long;
776 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
780 if (changed & WIPHY_PARAM_RETRY_SHORT
781 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
782 cfg_priv->conf->retry_short = wiphy->retry_short;
783 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
793 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
797 return &cfg_priv->profile->sec;
799 return &cfg_priv->profile->bssid;
801 return &cfg_priv->profile->ssid;
803 WL_ERR("invalid item (%d)\n", item);
808 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
809 const struct brcmf_event_msg *e, void *data, s32 item)
812 struct brcmf_ssid *ssid;
816 ssid = (struct brcmf_ssid *) data;
817 memset(cfg_priv->profile->ssid.SSID, 0,
818 sizeof(cfg_priv->profile->ssid.SSID));
819 memcpy(cfg_priv->profile->ssid.SSID,
820 ssid->SSID, ssid->SSID_len);
821 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
825 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
827 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
830 memcpy(&cfg_priv->profile->sec, data,
831 sizeof(cfg_priv->profile->sec));
833 case WL_PROF_BEACONINT:
834 cfg_priv->profile->beacon_interval = *(u16 *)data;
836 case WL_PROF_DTIMPERIOD:
837 cfg_priv->profile->dtim_period = *(u8 *)data;
840 WL_ERR("unsupported item (%d)\n", item);
848 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
850 memset(prof, 0, sizeof(*prof));
853 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
854 size_t *join_params_size)
859 if (ch <= CH_MAX_2G_CHANNEL)
860 chanspec |= WL_CHANSPEC_BAND_2G;
862 chanspec |= WL_CHANSPEC_BAND_5G;
864 chanspec |= WL_CHANSPEC_BW_20;
865 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
867 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
870 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
871 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
872 join_params->params_le.chanspec_num = cpu_to_le32(1);
874 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
875 "channel %d, chanspec %#X\n",
876 chanspec, ch, chanspec);
880 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
882 struct net_device *ndev = NULL;
887 if (cfg_priv->link_up) {
888 ndev = cfg_to_ndev(cfg_priv);
889 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
890 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
892 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
893 cfg_priv->link_up = false;
899 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
900 struct cfg80211_ibss_params *params)
902 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
903 struct brcmf_join_params join_params;
904 size_t join_params_size = 0;
908 struct brcmf_ssid ssid;
911 if (!check_sys_up(wiphy))
915 WL_CONN("SSID: %s\n", params->ssid);
917 WL_CONN("SSID: NULL, Not supported\n");
921 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
924 WL_CONN("BSSID: %pM\n", params->bssid);
926 WL_CONN("No BSSID specified\n");
929 WL_CONN("channel: %d\n", params->channel->center_freq);
931 WL_CONN("no channel specified\n");
933 if (params->channel_fixed)
934 WL_CONN("fixed channel required\n");
936 WL_CONN("no fixed channel required\n");
938 if (params->ie && params->ie_len)
939 WL_CONN("ie len: %d\n", params->ie_len);
941 WL_CONN("no ie specified\n");
943 if (params->beacon_interval)
944 WL_CONN("beacon interval: %d\n", params->beacon_interval);
946 WL_CONN("no beacon interval specified\n");
948 if (params->basic_rates)
949 WL_CONN("basic rates: %08X\n", params->basic_rates);
951 WL_CONN("no basic rates specified\n");
954 WL_CONN("privacy required\n");
956 WL_CONN("no privacy required\n");
958 /* Configure Privacy for starter */
962 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
964 WL_ERR("wsec failed (%d)\n", err);
968 /* Configure Beacon Interval for starter */
969 if (params->beacon_interval)
970 bcnprd = params->beacon_interval;
974 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
976 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
980 /* Configure required join parameter */
981 memset(&join_params, 0, sizeof(struct brcmf_join_params));
984 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
985 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
986 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
987 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
988 join_params_size = sizeof(join_params.ssid_le);
989 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
993 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
994 join_params_size = sizeof(join_params.ssid_le) +
995 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
997 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1000 brcmf_update_prof(cfg_priv, NULL,
1001 &join_params.params_le.bssid, WL_PROF_BSSID);
1004 if (params->channel) {
1008 ieee80211_frequency_to_channel(
1009 params->channel->center_freq);
1010 if (params->channel_fixed) {
1011 /* adding chanspec */
1012 brcmf_ch_to_chanspec(cfg_priv->channel,
1013 &join_params, &join_params_size);
1016 /* set channel for starter */
1017 target_channel = cfg_priv->channel;
1018 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1021 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1025 cfg_priv->channel = 0;
1027 cfg_priv->ibss_starter = false;
1030 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1031 &join_params, join_params_size);
1033 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1039 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1045 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1047 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1050 WL_TRACE("Enter\n");
1051 if (!check_sys_up(wiphy))
1054 brcmf_link_down(cfg_priv);
1061 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1062 struct cfg80211_connect_params *sme)
1064 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1065 struct brcmf_cfg80211_security *sec;
1069 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1070 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1071 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1072 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1074 val = WPA_AUTH_DISABLED;
1075 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1076 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1078 WL_ERR("set wpa_auth failed (%d)\n", err);
1081 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1082 sec->wpa_versions = sme->crypto.wpa_versions;
1086 static s32 brcmf_set_auth_type(struct net_device *ndev,
1087 struct cfg80211_connect_params *sme)
1089 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1090 struct brcmf_cfg80211_security *sec;
1094 switch (sme->auth_type) {
1095 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1097 WL_CONN("open system\n");
1099 case NL80211_AUTHTYPE_SHARED_KEY:
1101 WL_CONN("shared key\n");
1103 case NL80211_AUTHTYPE_AUTOMATIC:
1105 WL_CONN("automatic\n");
1107 case NL80211_AUTHTYPE_NETWORK_EAP:
1108 WL_CONN("network eap\n");
1111 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1115 err = brcmf_dev_intvar_set(ndev, "auth", val);
1117 WL_ERR("set auth failed (%d)\n", err);
1120 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1121 sec->auth_type = sme->auth_type;
1126 brcmf_set_set_cipher(struct net_device *ndev,
1127 struct cfg80211_connect_params *sme)
1129 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1130 struct brcmf_cfg80211_security *sec;
1135 if (sme->crypto.n_ciphers_pairwise) {
1136 switch (sme->crypto.ciphers_pairwise[0]) {
1137 case WLAN_CIPHER_SUITE_WEP40:
1138 case WLAN_CIPHER_SUITE_WEP104:
1141 case WLAN_CIPHER_SUITE_TKIP:
1142 pval = TKIP_ENABLED;
1144 case WLAN_CIPHER_SUITE_CCMP:
1147 case WLAN_CIPHER_SUITE_AES_CMAC:
1151 WL_ERR("invalid cipher pairwise (%d)\n",
1152 sme->crypto.ciphers_pairwise[0]);
1156 if (sme->crypto.cipher_group) {
1157 switch (sme->crypto.cipher_group) {
1158 case WLAN_CIPHER_SUITE_WEP40:
1159 case WLAN_CIPHER_SUITE_WEP104:
1162 case WLAN_CIPHER_SUITE_TKIP:
1163 gval = TKIP_ENABLED;
1165 case WLAN_CIPHER_SUITE_CCMP:
1168 case WLAN_CIPHER_SUITE_AES_CMAC:
1172 WL_ERR("invalid cipher group (%d)\n",
1173 sme->crypto.cipher_group);
1178 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1179 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1181 WL_ERR("error (%d)\n", err);
1185 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1186 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1187 sec->cipher_group = sme->crypto.cipher_group;
1193 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1195 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1196 struct brcmf_cfg80211_security *sec;
1200 if (sme->crypto.n_akm_suites) {
1201 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1203 WL_ERR("could not get wpa_auth (%d)\n", err);
1206 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1207 switch (sme->crypto.akm_suites[0]) {
1208 case WLAN_AKM_SUITE_8021X:
1209 val = WPA_AUTH_UNSPECIFIED;
1211 case WLAN_AKM_SUITE_PSK:
1215 WL_ERR("invalid cipher group (%d)\n",
1216 sme->crypto.cipher_group);
1219 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1220 switch (sme->crypto.akm_suites[0]) {
1221 case WLAN_AKM_SUITE_8021X:
1222 val = WPA2_AUTH_UNSPECIFIED;
1224 case WLAN_AKM_SUITE_PSK:
1225 val = WPA2_AUTH_PSK;
1228 WL_ERR("invalid cipher group (%d)\n",
1229 sme->crypto.cipher_group);
1234 WL_CONN("setting wpa_auth to %d\n", val);
1235 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1237 WL_ERR("could not set wpa_auth (%d)\n", err);
1241 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1242 sec->wpa_auth = sme->crypto.akm_suites[0];
1248 brcmf_set_wep_sharedkey(struct net_device *ndev,
1249 struct cfg80211_connect_params *sme)
1251 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1252 struct brcmf_cfg80211_security *sec;
1253 struct brcmf_wsec_key key;
1257 WL_CONN("key len (%d)\n", sme->key_len);
1259 if (sme->key_len == 0)
1262 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1263 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1264 sec->wpa_versions, sec->cipher_pairwise);
1266 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1269 if (sec->cipher_pairwise &
1270 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1271 memset(&key, 0, sizeof(key));
1272 key.len = (u32) sme->key_len;
1273 key.index = (u32) sme->key_idx;
1274 if (key.len > sizeof(key.data)) {
1275 WL_ERR("Too long key length (%u)\n", key.len);
1278 memcpy(key.data, sme->key, key.len);
1279 key.flags = BRCMF_PRIMARY_KEY;
1280 switch (sec->cipher_pairwise) {
1281 case WLAN_CIPHER_SUITE_WEP40:
1282 key.algo = CRYPTO_ALGO_WEP1;
1284 case WLAN_CIPHER_SUITE_WEP104:
1285 key.algo = CRYPTO_ALGO_WEP128;
1288 WL_ERR("Invalid algorithm (%d)\n",
1289 sme->crypto.ciphers_pairwise[0]);
1292 /* Set the new key/index */
1293 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1294 key.len, key.index, key.algo);
1295 WL_CONN("key \"%s\"\n", key.data);
1296 err = send_key_to_dongle(ndev, &key);
1300 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1301 WL_CONN("set auth_type to shared key\n");
1302 val = 1; /* shared key */
1303 err = brcmf_dev_intvar_set(ndev, "auth", val);
1305 WL_ERR("set auth failed (%d)\n", err);
1314 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1315 struct cfg80211_connect_params *sme)
1317 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1318 struct ieee80211_channel *chan = sme->channel;
1319 struct brcmf_join_params join_params;
1320 size_t join_params_size;
1321 struct brcmf_ssid ssid;
1325 WL_TRACE("Enter\n");
1326 if (!check_sys_up(wiphy))
1330 WL_ERR("Invalid ssid\n");
1334 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1338 ieee80211_frequency_to_channel(chan->center_freq);
1339 WL_CONN("channel (%d), center_req (%d)\n",
1340 cfg_priv->channel, chan->center_freq);
1342 cfg_priv->channel = 0;
1344 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1346 err = brcmf_set_wpa_version(ndev, sme);
1348 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1352 err = brcmf_set_auth_type(ndev, sme);
1354 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1358 err = brcmf_set_set_cipher(ndev, sme);
1360 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1364 err = brcmf_set_key_mgmt(ndev, sme);
1366 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1370 err = brcmf_set_wep_sharedkey(ndev, sme);
1372 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1376 memset(&join_params, 0, sizeof(join_params));
1377 join_params_size = sizeof(join_params.ssid_le);
1379 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1380 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1381 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1382 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1383 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1385 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1387 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1388 WL_CONN("ssid \"%s\", len (%d)\n",
1389 ssid.SSID, ssid.SSID_len);
1391 brcmf_ch_to_chanspec(cfg_priv->channel,
1392 &join_params, &join_params_size);
1393 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1394 &join_params, join_params_size);
1396 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1400 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1406 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1409 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1410 struct brcmf_scb_val_le scbval;
1413 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1414 if (!check_sys_up(wiphy))
1417 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1419 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1420 scbval.val = cpu_to_le32(reason_code);
1421 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1422 sizeof(struct brcmf_scb_val_le));
1424 WL_ERR("error (%d)\n", err);
1426 cfg_priv->link_up = false;
1433 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1434 enum nl80211_tx_power_setting type, s32 mbm)
1437 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1438 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1442 s32 dbm = MBM_TO_DBM(mbm);
1444 WL_TRACE("Enter\n");
1445 if (!check_sys_up(wiphy))
1449 case NL80211_TX_POWER_AUTOMATIC:
1451 case NL80211_TX_POWER_LIMITED:
1452 case NL80211_TX_POWER_FIXED:
1454 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1460 /* Make sure radio is off or on as far as software is concerned */
1461 disable = WL_RADIO_SW_DISABLE << 16;
1462 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1464 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1469 txpwrmw = (u16) dbm;
1470 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1471 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1473 WL_ERR("qtxpower error (%d)\n", err);
1474 cfg_priv->conf->tx_power = dbm;
1481 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1483 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1484 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1489 WL_TRACE("Enter\n");
1490 if (!check_sys_up(wiphy))
1493 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1495 WL_ERR("error (%d)\n", err);
1499 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1500 *dbm = (s32) brcmf_qdbm_to_mw(result);
1508 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1509 u8 key_idx, bool unicast, bool multicast)
1515 WL_TRACE("Enter\n");
1516 WL_CONN("key index (%d)\n", key_idx);
1517 if (!check_sys_up(wiphy))
1520 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1522 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1526 if (wsec & WEP_ENABLED) {
1527 /* Just select a new current key */
1529 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1532 WL_ERR("error (%d)\n", err);
1540 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1541 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1543 struct brcmf_wsec_key key;
1544 struct brcmf_wsec_key_le key_le;
1547 memset(&key, 0, sizeof(key));
1548 key.index = (u32) key_idx;
1549 /* Instead of bcast for ea address for default wep keys,
1550 driver needs it to be Null */
1551 if (!is_multicast_ether_addr(mac_addr))
1552 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1553 key.len = (u32) params->key_len;
1554 /* check for key index change */
1557 err = send_key_to_dongle(ndev, &key);
1561 if (key.len > sizeof(key.data)) {
1562 WL_ERR("Invalid key length (%d)\n", key.len);
1566 WL_CONN("Setting the key index %d\n", key.index);
1567 memcpy(key.data, params->key, key.len);
1569 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1571 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1572 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1573 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1576 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1577 if (params->seq && params->seq_len == 6) {
1580 ivptr = (u8 *) params->seq;
1581 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1582 (ivptr[3] << 8) | ivptr[2];
1583 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1584 key.iv_initialized = true;
1587 switch (params->cipher) {
1588 case WLAN_CIPHER_SUITE_WEP40:
1589 key.algo = CRYPTO_ALGO_WEP1;
1590 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1592 case WLAN_CIPHER_SUITE_WEP104:
1593 key.algo = CRYPTO_ALGO_WEP128;
1594 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1596 case WLAN_CIPHER_SUITE_TKIP:
1597 key.algo = CRYPTO_ALGO_TKIP;
1598 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1600 case WLAN_CIPHER_SUITE_AES_CMAC:
1601 key.algo = CRYPTO_ALGO_AES_CCM;
1602 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1604 case WLAN_CIPHER_SUITE_CCMP:
1605 key.algo = CRYPTO_ALGO_AES_CCM;
1606 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1609 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1612 convert_key_from_CPU(&key, &key_le);
1614 brcmf_netdev_wait_pend8021x(ndev);
1615 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1618 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1626 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1627 u8 key_idx, bool pairwise, const u8 *mac_addr,
1628 struct key_params *params)
1630 struct brcmf_wsec_key key;
1636 WL_TRACE("Enter\n");
1637 WL_CONN("key index (%d)\n", key_idx);
1638 if (!check_sys_up(wiphy))
1643 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1645 memset(&key, 0, sizeof(key));
1647 key.len = (u32) params->key_len;
1648 key.index = (u32) key_idx;
1650 if (key.len > sizeof(key.data)) {
1651 WL_ERR("Too long key length (%u)\n", key.len);
1655 memcpy(key.data, params->key, key.len);
1657 key.flags = BRCMF_PRIMARY_KEY;
1658 switch (params->cipher) {
1659 case WLAN_CIPHER_SUITE_WEP40:
1660 key.algo = CRYPTO_ALGO_WEP1;
1661 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1663 case WLAN_CIPHER_SUITE_WEP104:
1664 key.algo = CRYPTO_ALGO_WEP128;
1665 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1667 case WLAN_CIPHER_SUITE_TKIP:
1668 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1669 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1670 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1671 key.algo = CRYPTO_ALGO_TKIP;
1672 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1674 case WLAN_CIPHER_SUITE_AES_CMAC:
1675 key.algo = CRYPTO_ALGO_AES_CCM;
1676 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1678 case WLAN_CIPHER_SUITE_CCMP:
1679 key.algo = CRYPTO_ALGO_AES_CCM;
1680 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1683 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1688 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1693 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1695 WL_ERR("get wsec error (%d)\n", err);
1698 wsec &= ~(WEP_ENABLED);
1700 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1702 WL_ERR("set wsec error (%d)\n", err);
1706 val = 1; /* assume shared key. otherwise 0 */
1707 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1709 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1716 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1717 u8 key_idx, bool pairwise, const u8 *mac_addr)
1719 struct brcmf_wsec_key key;
1724 WL_TRACE("Enter\n");
1725 if (!check_sys_up(wiphy))
1728 memset(&key, 0, sizeof(key));
1730 key.index = (u32) key_idx;
1731 key.flags = BRCMF_PRIMARY_KEY;
1732 key.algo = CRYPTO_ALGO_OFF;
1734 WL_CONN("key index (%d)\n", key_idx);
1736 /* Set the new key/index */
1737 err = send_key_to_dongle(ndev, &key);
1739 if (err == -EINVAL) {
1740 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1741 /* we ignore this key index in this case */
1742 WL_ERR("invalid key index (%d)\n", key_idx);
1744 /* Ignore this error, may happen during DISASSOC */
1750 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1752 WL_ERR("get wsec error (%d)\n", err);
1753 /* Ignore this error, may happen during DISASSOC */
1757 wsec &= ~(WEP_ENABLED);
1759 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1761 WL_ERR("set wsec error (%d)\n", err);
1762 /* Ignore this error, may happen during DISASSOC */
1767 val = 0; /* assume open key. otherwise 1 */
1768 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1770 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1771 /* Ignore this error, may happen during DISASSOC */
1780 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1781 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1782 void (*callback) (void *cookie, struct key_params * params))
1784 struct key_params params;
1785 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1786 struct brcmf_cfg80211_security *sec;
1790 WL_TRACE("Enter\n");
1791 WL_CONN("key index (%d)\n", key_idx);
1792 if (!check_sys_up(wiphy))
1795 memset(¶ms, 0, sizeof(params));
1797 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1799 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1800 /* Ignore this error, may happen during DISASSOC */
1806 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1807 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1808 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1809 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1810 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1811 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1812 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1816 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1817 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1820 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1821 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1824 WL_ERR("Invalid algo (0x%x)\n", wsec);
1828 callback(cookie, ¶ms);
1836 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1837 struct net_device *ndev, u8 key_idx)
1839 WL_INFO("Not supported\n");
1845 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1846 u8 *mac, struct station_info *sinfo)
1848 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1849 struct brcmf_scb_val_le scb_val;
1853 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1855 WL_TRACE("Enter\n");
1856 if (!check_sys_up(wiphy))
1859 if (memcmp(mac, bssid, ETH_ALEN)) {
1860 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1861 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1862 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1863 bssid[0], bssid[1], bssid[2], bssid[3],
1864 bssid[4], bssid[5]);
1869 /* Report the current tx rate */
1870 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1872 WL_ERR("Could not get rate (%d)\n", err);
1874 sinfo->filled |= STATION_INFO_TX_BITRATE;
1875 sinfo->txrate.legacy = rate * 5;
1876 WL_CONN("Rate %d Mbps\n", rate / 2);
1879 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1880 memset(&scb_val, 0, sizeof(scb_val));
1881 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1882 sizeof(struct brcmf_scb_val_le));
1884 WL_ERR("Could not get rssi (%d)\n", err);
1886 rssi = le32_to_cpu(scb_val.val);
1887 sinfo->filled |= STATION_INFO_SIGNAL;
1888 sinfo->signal = rssi;
1889 WL_CONN("RSSI %d dBm\n", rssi);
1899 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1900 bool enabled, s32 timeout)
1904 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1906 WL_TRACE("Enter\n");
1909 * Powersave enable/disable request is coming from the
1910 * cfg80211 even before the interface is up. In that
1911 * scenario, driver will be storing the power save
1912 * preference in cfg_priv struct to apply this to
1913 * FW later while initializing the dongle
1915 cfg_priv->pwr_save = enabled;
1916 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1918 WL_INFO("Device is not ready,"
1919 "storing the value in cfg_priv struct\n");
1923 pm = enabled ? PM_FAST : PM_OFF;
1924 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1926 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1929 WL_ERR("net_device is not ready yet\n");
1931 WL_ERR("error (%d)\n", err);
1939 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1941 const struct cfg80211_bitrate_mask *mask)
1943 struct brcm_rateset_le rateset_le;
1951 WL_TRACE("Enter\n");
1952 if (!check_sys_up(wiphy))
1955 /* addr param is always NULL. ignore it */
1956 /* Get current rateset */
1957 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1958 sizeof(rateset_le));
1960 WL_ERR("could not get current rateset (%d)\n", err);
1964 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1966 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1969 val = wl_g_rates[legacy - 1].bitrate * 100000;
1971 if (val < le32_to_cpu(rateset_le.count))
1972 /* Select rate by rateset index */
1973 rate = rateset_le.rates[val] & 0x7f;
1975 /* Specified rate in bps */
1976 rate = val / 500000;
1978 WL_CONN("rate %d mbps\n", rate / 2);
1982 * Set rate override,
1983 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1985 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1986 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1987 if (err_bg && err_a) {
1988 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1989 err = err_bg | err_a;
1997 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1998 struct brcmf_bss_info_le *bi)
2000 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2001 struct ieee80211_channel *notify_channel;
2002 struct cfg80211_bss *bss;
2003 struct ieee80211_supported_band *band;
2007 u16 notify_capability;
2008 u16 notify_interval;
2010 size_t notify_ielen;
2013 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2014 WL_ERR("Bss info is larger than buffer. Discarding\n");
2018 channel = bi->ctl_ch ? bi->ctl_ch :
2019 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2021 if (channel <= CH_MAX_2G_CHANNEL)
2022 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2024 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2026 freq = ieee80211_channel_to_frequency(channel, band->band);
2027 notify_channel = ieee80211_get_channel(wiphy, freq);
2029 notify_capability = le16_to_cpu(bi->capability);
2030 notify_interval = le16_to_cpu(bi->beacon_period);
2031 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2032 notify_ielen = le32_to_cpu(bi->ie_length);
2033 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2035 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2036 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2037 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2038 WL_CONN("Channel: %d(%d)\n", channel, freq);
2039 WL_CONN("Capability: %X\n", notify_capability);
2040 WL_CONN("Beacon interval: %d\n", notify_interval);
2041 WL_CONN("Signal: %d\n", notify_signal);
2043 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2044 0, notify_capability, notify_interval, notify_ie,
2045 notify_ielen, notify_signal, GFP_KERNEL);
2050 cfg80211_put_bss(bss);
2055 static struct brcmf_bss_info_le *
2056 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2059 return list->bss_info_le;
2060 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2061 le32_to_cpu(bss->length));
2064 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2066 struct brcmf_scan_results *bss_list;
2067 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2071 bss_list = cfg_priv->bss_list;
2072 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2073 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2077 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2078 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2079 bi = next_bss_le(bss_list, bi);
2080 err = brcmf_inform_single_bss(cfg_priv, bi);
2087 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2088 struct net_device *ndev, const u8 *bssid)
2090 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2091 struct ieee80211_channel *notify_channel;
2092 struct brcmf_bss_info_le *bi = NULL;
2093 struct ieee80211_supported_band *band;
2094 struct cfg80211_bss *bss;
2099 u16 notify_capability;
2100 u16 notify_interval;
2102 size_t notify_ielen;
2105 WL_TRACE("Enter\n");
2107 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2113 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2115 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2117 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2121 bi = (struct brcmf_bss_info_le *)(buf + 4);
2123 channel = bi->ctl_ch ? bi->ctl_ch :
2124 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2126 if (channel <= CH_MAX_2G_CHANNEL)
2127 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2129 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2131 freq = ieee80211_channel_to_frequency(channel, band->band);
2132 notify_channel = ieee80211_get_channel(wiphy, freq);
2134 notify_capability = le16_to_cpu(bi->capability);
2135 notify_interval = le16_to_cpu(bi->beacon_period);
2136 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2137 notify_ielen = le32_to_cpu(bi->ie_length);
2138 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2140 WL_CONN("channel: %d(%d)\n", channel, freq);
2141 WL_CONN("capability: %X\n", notify_capability);
2142 WL_CONN("beacon interval: %d\n", notify_interval);
2143 WL_CONN("signal: %d\n", notify_signal);
2145 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2146 0, notify_capability, notify_interval,
2147 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2154 cfg80211_put_bss(bss);
2165 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2167 return cfg_priv->conf->mode == WL_MODE_IBSS;
2171 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2172 * triples, returning a pointer to the substring whose first element
2175 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2177 struct brcmf_tlv *elt;
2180 elt = (struct brcmf_tlv *) buf;
2183 /* find tagged parameter */
2184 while (totlen >= 2) {
2187 /* validate remaining totlen */
2188 if ((elt->id == key) && (totlen >= (len + 2)))
2191 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2192 totlen -= (len + 2);
2198 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2200 struct brcmf_bss_info_le *bi;
2201 struct brcmf_ssid *ssid;
2202 struct brcmf_tlv *tim;
2203 u16 beacon_interval;
2209 WL_TRACE("Enter\n");
2210 if (brcmf_is_ibssmode(cfg_priv))
2213 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2215 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2216 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2217 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2219 WL_ERR("Could not get bss info %d\n", err);
2220 goto update_bss_info_out;
2223 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2224 err = brcmf_inform_single_bss(cfg_priv, bi);
2226 goto update_bss_info_out;
2228 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2229 ie_len = le32_to_cpu(bi->ie_length);
2230 beacon_interval = le16_to_cpu(bi->beacon_period);
2232 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2234 dtim_period = tim->data[1];
2237 * active scan was done so we could not get dtim
2238 * information out of probe response.
2239 * so we speficially query dtim information to dongle.
2242 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2243 "dtim_assoc", &var);
2245 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2246 goto update_bss_info_out;
2248 dtim_period = (u8)var;
2251 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2252 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2254 update_bss_info_out:
2259 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2261 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2262 struct brcmf_ssid ssid;
2264 if (cfg_priv->iscan_on) {
2265 iscan->state = WL_ISCAN_STATE_IDLE;
2267 if (iscan->timer_on) {
2268 del_timer_sync(&iscan->timer);
2269 iscan->timer_on = 0;
2272 cancel_work_sync(&iscan->work);
2274 /* Abort iscan running in FW */
2275 memset(&ssid, 0, sizeof(ssid));
2276 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2280 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2283 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2284 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2286 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2287 WL_ERR("Scan complete while device not scanning\n");
2290 if (cfg_priv->scan_request) {
2291 WL_SCAN("ISCAN Completed scan: %s\n",
2292 aborted ? "Aborted" : "Done");
2293 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2294 brcmf_set_mpc(ndev, 1);
2295 cfg_priv->scan_request = NULL;
2297 cfg_priv->iscan_kickstart = false;
2300 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2302 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2303 WL_SCAN("wake up iscan\n");
2304 schedule_work(&iscan->work);
2312 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2313 struct brcmf_scan_results **bss_list)
2315 struct brcmf_iscan_results list;
2316 struct brcmf_scan_results *results;
2317 struct brcmf_scan_results_le *results_le;
2318 struct brcmf_iscan_results *list_buf;
2321 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2322 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2323 results = &list_buf->results;
2324 results_le = &list_buf->results_le;
2325 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2326 results->version = 0;
2329 memset(&list, 0, sizeof(list));
2330 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2331 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2332 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2333 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2335 WL_ERR("error (%d)\n", err);
2338 results->buflen = le32_to_cpu(results_le->buflen);
2339 results->version = le32_to_cpu(results_le->version);
2340 results->count = le32_to_cpu(results_le->count);
2341 WL_SCAN("results->count = %d\n", results_le->count);
2342 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2343 *status = le32_to_cpu(list_buf->status_le);
2344 WL_SCAN("status = %d\n", *status);
2345 *bss_list = results;
2350 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2352 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2355 iscan->state = WL_ISCAN_STATE_IDLE;
2356 brcmf_inform_bss(cfg_priv);
2357 brcmf_notify_iscan_complete(iscan, false);
2362 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2364 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2367 /* Reschedule the timer */
2368 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2369 iscan->timer_on = 1;
2374 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2376 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2379 brcmf_inform_bss(cfg_priv);
2380 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2381 /* Reschedule the timer */
2382 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2383 iscan->timer_on = 1;
2388 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2390 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2393 iscan->state = WL_ISCAN_STATE_IDLE;
2394 brcmf_notify_iscan_complete(iscan, true);
2399 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2401 struct brcmf_cfg80211_iscan_ctrl *iscan =
2402 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2404 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2405 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2406 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2408 if (iscan->timer_on) {
2409 del_timer_sync(&iscan->timer);
2410 iscan->timer_on = 0;
2413 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2414 status = BRCMF_SCAN_RESULTS_ABORTED;
2415 WL_ERR("Abort iscan\n");
2418 el->handler[status](cfg_priv);
2421 static void brcmf_iscan_timer(unsigned long data)
2423 struct brcmf_cfg80211_iscan_ctrl *iscan =
2424 (struct brcmf_cfg80211_iscan_ctrl *)data;
2427 iscan->timer_on = 0;
2428 WL_SCAN("timer expired\n");
2429 brcmf_wakeup_iscan(iscan);
2433 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2435 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2437 if (cfg_priv->iscan_on) {
2438 iscan->state = WL_ISCAN_STATE_IDLE;
2439 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2445 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2447 memset(el, 0, sizeof(*el));
2448 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2449 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2450 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2451 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2452 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2455 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2457 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2460 if (cfg_priv->iscan_on) {
2461 iscan->ndev = cfg_to_ndev(cfg_priv);
2462 brcmf_init_iscan_eloop(&iscan->el);
2463 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2464 init_timer(&iscan->timer);
2465 iscan->timer.data = (unsigned long) iscan;
2466 iscan->timer.function = brcmf_iscan_timer;
2467 err = brcmf_invoke_iscan(cfg_priv);
2469 iscan->data = cfg_priv;
2475 static __always_inline void brcmf_delay(u32 ms)
2477 if (ms < 1000 / HZ) {
2485 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2487 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2490 * Check for WL_STATUS_READY before any function call which
2491 * could result is bus access. Don't block the resume for
2492 * any driver error conditions
2494 WL_TRACE("Enter\n");
2496 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2497 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2503 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2504 struct cfg80211_wowlan *wow)
2506 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2507 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2509 WL_TRACE("Enter\n");
2512 * Check for WL_STATUS_READY before any function call which
2513 * could result is bus access. Don't block the suspend for
2514 * any driver error conditions
2518 * While going to suspend if associated with AP disassociate
2519 * from AP to save power while system is in suspended state
2521 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2522 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2523 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2524 WL_INFO("Disassociating from AP"
2525 " while entering suspend state\n");
2526 brcmf_link_down(cfg_priv);
2529 * Make sure WPA_Supplicant receives all the event
2530 * generated due to DISASSOC call to the fw to keep
2531 * the state fw and WPA_Supplicant state consistent
2536 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2537 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2538 brcmf_term_iscan(cfg_priv);
2540 if (cfg_priv->scan_request) {
2541 /* Indidate scan abort to cfg80211 layer */
2542 WL_INFO("Terminating scan in progress\n");
2543 cfg80211_scan_done(cfg_priv->scan_request, true);
2544 cfg_priv->scan_request = NULL;
2546 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2547 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2549 /* Turn off watchdog timer */
2550 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2551 WL_INFO("Enable MPC\n");
2552 brcmf_set_mpc(ndev, 1);
2561 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2563 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2566 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2570 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2575 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2578 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2582 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2585 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2588 WL_ERR("error (%d)\n", err);
2591 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2597 brcmf_update_pmklist(struct net_device *ndev,
2598 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2603 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2605 WL_CONN("No of elements %d\n", pmkid_len);
2606 for (i = 0; i < pmkid_len; i++) {
2607 WL_CONN("PMKID[%d]: %pM =\n", i,
2608 &pmk_list->pmkids.pmkid[i].BSSID);
2609 for (j = 0; j < WLAN_PMKID_LEN; j++)
2610 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2614 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2621 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2622 struct cfg80211_pmksa *pmksa)
2624 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2625 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2630 WL_TRACE("Enter\n");
2631 if (!check_sys_up(wiphy))
2634 pmkid_len = le32_to_cpu(pmkids->npmkid);
2635 for (i = 0; i < pmkid_len; i++)
2636 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2638 if (i < WL_NUM_PMKIDS_MAX) {
2639 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2640 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2641 if (i == pmkid_len) {
2643 pmkids->npmkid = cpu_to_le32(pmkid_len);
2648 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2649 pmkids->pmkid[pmkid_len].BSSID);
2650 for (i = 0; i < WLAN_PMKID_LEN; i++)
2651 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2653 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2660 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2661 struct cfg80211_pmksa *pmksa)
2663 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2664 struct pmkid_list pmkid;
2668 WL_TRACE("Enter\n");
2669 if (!check_sys_up(wiphy))
2672 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2673 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2675 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2676 &pmkid.pmkid[0].BSSID);
2677 for (i = 0; i < WLAN_PMKID_LEN; i++)
2678 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2680 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2681 for (i = 0; i < pmkid_len; i++)
2683 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2688 && (i < pmkid_len)) {
2689 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2690 sizeof(struct pmkid));
2691 for (; i < (pmkid_len - 1); i++) {
2692 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2693 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2695 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2696 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2699 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2703 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2711 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2713 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2716 WL_TRACE("Enter\n");
2717 if (!check_sys_up(wiphy))
2720 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2721 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2728 #ifdef CONFIG_NL80211_TESTMODE
2729 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
2731 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2732 struct net_device *ndev = cfg_priv->wdev->netdev;
2733 struct brcmf_dcmd *dcmd = data;
2734 struct sk_buff *reply;
2737 ret = brcmf_netlink_dcmd(ndev, dcmd);
2739 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
2740 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
2741 ret = cfg80211_testmode_reply(reply);
2747 static struct cfg80211_ops wl_cfg80211_ops = {
2748 .change_virtual_intf = brcmf_cfg80211_change_iface,
2749 .scan = brcmf_cfg80211_scan,
2750 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2751 .join_ibss = brcmf_cfg80211_join_ibss,
2752 .leave_ibss = brcmf_cfg80211_leave_ibss,
2753 .get_station = brcmf_cfg80211_get_station,
2754 .set_tx_power = brcmf_cfg80211_set_tx_power,
2755 .get_tx_power = brcmf_cfg80211_get_tx_power,
2756 .add_key = brcmf_cfg80211_add_key,
2757 .del_key = brcmf_cfg80211_del_key,
2758 .get_key = brcmf_cfg80211_get_key,
2759 .set_default_key = brcmf_cfg80211_config_default_key,
2760 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2761 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2762 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2763 .connect = brcmf_cfg80211_connect,
2764 .disconnect = brcmf_cfg80211_disconnect,
2765 .suspend = brcmf_cfg80211_suspend,
2766 .resume = brcmf_cfg80211_resume,
2767 .set_pmksa = brcmf_cfg80211_set_pmksa,
2768 .del_pmksa = brcmf_cfg80211_del_pmksa,
2769 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
2770 #ifdef CONFIG_NL80211_TESTMODE
2771 .testmode_cmd = brcmf_cfg80211_testmode
2775 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2781 return NL80211_IFTYPE_STATION;
2783 return NL80211_IFTYPE_ADHOC;
2785 return NL80211_IFTYPE_UNSPECIFIED;
2791 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2792 struct device *ndev)
2794 struct wireless_dev *wdev;
2797 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2799 return ERR_PTR(-ENOMEM);
2802 wiphy_new(&wl_cfg80211_ops,
2803 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2805 WL_ERR("Could not allocate wiphy device\n");
2809 set_wiphy_dev(wdev->wiphy, ndev);
2810 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2811 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2812 wdev->wiphy->interface_modes =
2813 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2814 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2815 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2816 * it as 11a by default.
2817 * This will be updated with
2820 * if phy has 11n capability
2822 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2823 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2824 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2825 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2829 err = wiphy_register(wdev->wiphy);
2831 WL_ERR("Could not register wiphy device (%d)\n", err);
2832 goto wiphy_register_out;
2837 wiphy_free(wdev->wiphy);
2842 return ERR_PTR(err);
2845 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2847 struct wireless_dev *wdev = cfg_priv->wdev;
2850 WL_ERR("wdev is invalid\n");
2853 wiphy_unregister(wdev->wiphy);
2854 wiphy_free(wdev->wiphy);
2856 cfg_priv->wdev = NULL;
2859 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2860 const struct brcmf_event_msg *e)
2862 u32 event = be32_to_cpu(e->event_type);
2863 u32 status = be32_to_cpu(e->status);
2865 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2866 WL_CONN("Processing set ssid\n");
2867 cfg_priv->link_up = true;
2874 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2875 const struct brcmf_event_msg *e)
2877 u32 event = be32_to_cpu(e->event_type);
2878 u16 flags = be16_to_cpu(e->flags);
2880 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2881 WL_CONN("Processing link down\n");
2887 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2888 const struct brcmf_event_msg *e)
2890 u32 event = be32_to_cpu(e->event_type);
2891 u32 status = be32_to_cpu(e->status);
2893 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2894 WL_CONN("Processing Link %s & no network found\n",
2895 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2900 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2901 WL_CONN("Processing connecting & no network found\n");
2908 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2910 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2912 kfree(conn_info->req_ie);
2913 conn_info->req_ie = NULL;
2914 conn_info->req_ie_len = 0;
2915 kfree(conn_info->resp_ie);
2916 conn_info->resp_ie = NULL;
2917 conn_info->resp_ie_len = 0;
2920 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2922 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2923 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2924 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2929 brcmf_clear_assoc_ies(cfg_priv);
2931 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2934 WL_ERR("could not get assoc info (%d)\n", err);
2938 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2939 req_len = le32_to_cpu(assoc_info->req_len);
2940 resp_len = le32_to_cpu(assoc_info->resp_len);
2942 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2943 cfg_priv->extra_buf,
2946 WL_ERR("could not get assoc req (%d)\n", err);
2949 conn_info->req_ie_len = req_len;
2951 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2954 conn_info->req_ie_len = 0;
2955 conn_info->req_ie = NULL;
2958 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2959 cfg_priv->extra_buf,
2962 WL_ERR("could not get assoc resp (%d)\n", err);
2965 conn_info->resp_ie_len = resp_len;
2966 conn_info->resp_ie =
2967 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2970 conn_info->resp_ie_len = 0;
2971 conn_info->resp_ie = NULL;
2973 WL_CONN("req len (%d) resp len (%d)\n",
2974 conn_info->req_ie_len, conn_info->resp_ie_len);
2980 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2981 struct net_device *ndev,
2982 const struct brcmf_event_msg *e)
2984 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2985 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2986 struct brcmf_channel_info_le channel_le;
2987 struct ieee80211_channel *notify_channel;
2988 struct ieee80211_supported_band *band;
2993 WL_TRACE("Enter\n");
2995 brcmf_get_assoc_ies(cfg_priv);
2996 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2997 brcmf_update_bss_info(cfg_priv);
2999 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
3000 sizeof(channel_le));
3002 target_channel = le32_to_cpu(channel_le.target_channel);
3003 WL_CONN("Roamed to channel %d\n", target_channel);
3005 if (target_channel <= CH_MAX_2G_CHANNEL)
3006 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3008 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3010 freq = ieee80211_channel_to_frequency(target_channel, band->band);
3011 notify_channel = ieee80211_get_channel(wiphy, freq);
3013 cfg80211_roamed(ndev, notify_channel,
3014 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
3015 conn_info->req_ie, conn_info->req_ie_len,
3016 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3017 WL_CONN("Report roaming result\n");
3019 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3025 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3026 struct net_device *ndev, const struct brcmf_event_msg *e,
3029 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3032 WL_TRACE("Enter\n");
3034 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3036 brcmf_get_assoc_ies(cfg_priv);
3037 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3039 brcmf_update_bss_info(cfg_priv);
3041 cfg80211_connect_result(ndev,
3042 (u8 *)brcmf_read_prof(cfg_priv,
3045 conn_info->req_ie_len,
3047 conn_info->resp_ie_len,
3048 completed ? WLAN_STATUS_SUCCESS :
3049 WLAN_STATUS_AUTH_TIMEOUT,
3052 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3053 WL_CONN("Report connect result - connection %s\n",
3054 completed ? "succeeded" : "failed");
3061 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3062 struct net_device *ndev,
3063 const struct brcmf_event_msg *e, void *data)
3067 if (brcmf_is_linkup(cfg_priv, e)) {
3068 WL_CONN("Linkup\n");
3069 if (brcmf_is_ibssmode(cfg_priv)) {
3070 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3072 wl_inform_ibss(cfg_priv, ndev, e->addr);
3073 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3074 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3075 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3077 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3078 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3079 WL_CONN("Linkdown\n");
3080 if (brcmf_is_ibssmode(cfg_priv)) {
3081 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3082 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3084 brcmf_link_down(cfg_priv);
3086 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3087 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3088 &cfg_priv->status)) {
3089 cfg80211_disconnected(ndev, 0, NULL, 0,
3091 brcmf_link_down(cfg_priv);
3094 brcmf_init_prof(cfg_priv->profile);
3095 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3096 if (brcmf_is_ibssmode(cfg_priv))
3097 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3099 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3106 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3107 struct net_device *ndev,
3108 const struct brcmf_event_msg *e, void *data)
3111 u32 event = be32_to_cpu(e->event_type);
3112 u32 status = be32_to_cpu(e->status);
3114 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3115 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3116 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3118 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3125 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3126 struct net_device *ndev,
3127 const struct brcmf_event_msg *e, void *data)
3129 u16 flags = be16_to_cpu(e->flags);
3130 enum nl80211_key_type key_type;
3132 if (flags & BRCMF_EVENT_MSG_GROUP)
3133 key_type = NL80211_KEYTYPE_GROUP;
3135 key_type = NL80211_KEYTYPE_PAIRWISE;
3137 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3144 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3145 struct net_device *ndev,
3146 const struct brcmf_event_msg *e, void *data)
3148 struct brcmf_channel_info_le channel_inform_le;
3149 struct brcmf_scan_results_le *bss_list_le;
3150 u32 len = WL_SCAN_BUF_MAX;
3152 bool scan_abort = false;
3155 WL_TRACE("Enter\n");
3157 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3159 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3162 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3163 WL_ERR("Scan complete while device not scanning\n");
3169 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3170 sizeof(channel_inform_le));
3172 WL_ERR("scan busy (%d)\n", err);
3176 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3178 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3179 cfg_priv->bss_list = cfg_priv->scan_results;
3180 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3182 memset(cfg_priv->scan_results, 0, len);
3183 bss_list_le->buflen = cpu_to_le32(len);
3184 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3185 cfg_priv->scan_results, len);
3187 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3192 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3193 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3194 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3196 err = brcmf_inform_bss(cfg_priv);
3203 if (cfg_priv->scan_request) {
3204 WL_SCAN("calling cfg80211_scan_done\n");
3205 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3206 brcmf_set_mpc(ndev, 1);
3207 cfg_priv->scan_request = NULL;
3215 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3217 conf->mode = (u32)-1;
3218 conf->frag_threshold = (u32)-1;
3219 conf->rts_threshold = (u32)-1;
3220 conf->retry_short = (u32)-1;
3221 conf->retry_long = (u32)-1;
3222 conf->tx_power = -1;
3225 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3227 memset(el, 0, sizeof(*el));
3228 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3229 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3230 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3231 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3232 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3235 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3237 kfree(cfg_priv->scan_results);
3238 cfg_priv->scan_results = NULL;
3239 kfree(cfg_priv->bss_info);
3240 cfg_priv->bss_info = NULL;
3241 kfree(cfg_priv->conf);
3242 cfg_priv->conf = NULL;
3243 kfree(cfg_priv->profile);
3244 cfg_priv->profile = NULL;
3245 kfree(cfg_priv->scan_req_int);
3246 cfg_priv->scan_req_int = NULL;
3247 kfree(cfg_priv->dcmd_buf);
3248 cfg_priv->dcmd_buf = NULL;
3249 kfree(cfg_priv->extra_buf);
3250 cfg_priv->extra_buf = NULL;
3251 kfree(cfg_priv->iscan);
3252 cfg_priv->iscan = NULL;
3253 kfree(cfg_priv->pmk_list);
3254 cfg_priv->pmk_list = NULL;
3257 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3259 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3260 if (!cfg_priv->scan_results)
3261 goto init_priv_mem_out;
3262 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3263 if (!cfg_priv->conf)
3264 goto init_priv_mem_out;
3265 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3266 if (!cfg_priv->profile)
3267 goto init_priv_mem_out;
3268 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3269 if (!cfg_priv->bss_info)
3270 goto init_priv_mem_out;
3271 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3273 if (!cfg_priv->scan_req_int)
3274 goto init_priv_mem_out;
3275 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3276 if (!cfg_priv->dcmd_buf)
3277 goto init_priv_mem_out;
3278 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3279 if (!cfg_priv->extra_buf)
3280 goto init_priv_mem_out;
3281 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3282 if (!cfg_priv->iscan)
3283 goto init_priv_mem_out;
3284 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3285 if (!cfg_priv->pmk_list)
3286 goto init_priv_mem_out;
3291 brcmf_deinit_priv_mem(cfg_priv);
3297 * retrieve first queued event from head
3300 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3301 struct brcmf_cfg80211_priv *cfg_priv)
3303 struct brcmf_cfg80211_event_q *e = NULL;
3305 spin_lock_irq(&cfg_priv->evt_q_lock);
3306 if (!list_empty(&cfg_priv->evt_q_list)) {
3307 e = list_first_entry(&cfg_priv->evt_q_list,
3308 struct brcmf_cfg80211_event_q, evt_q_list);
3309 list_del(&e->evt_q_list);
3311 spin_unlock_irq(&cfg_priv->evt_q_lock);
3317 * push event to tail of the queue
3319 * remark: this function may not sleep as it is called in atomic context.
3323 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3324 const struct brcmf_event_msg *msg)
3326 struct brcmf_cfg80211_event_q *e;
3330 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
3335 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3337 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3338 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3339 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3344 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3349 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3351 struct brcmf_cfg80211_priv *cfg_priv =
3352 container_of(work, struct brcmf_cfg80211_priv,
3354 struct brcmf_cfg80211_event_q *e;
3356 e = brcmf_deq_event(cfg_priv);
3358 WL_ERR("event queue empty...\n");
3363 WL_INFO("event type (%d)\n", e->etype);
3364 if (cfg_priv->el.handler[e->etype])
3365 cfg_priv->el.handler[e->etype](cfg_priv,
3366 cfg_to_ndev(cfg_priv),
3367 &e->emsg, e->edata);
3369 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3371 } while ((e = brcmf_deq_event(cfg_priv)));
3375 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3377 spin_lock_init(&cfg_priv->evt_q_lock);
3378 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3381 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3383 struct brcmf_cfg80211_event_q *e;
3385 spin_lock_irq(&cfg_priv->evt_q_lock);
3386 while (!list_empty(&cfg_priv->evt_q_list)) {
3387 e = list_first_entry(&cfg_priv->evt_q_list,
3388 struct brcmf_cfg80211_event_q, evt_q_list);
3389 list_del(&e->evt_q_list);
3392 spin_unlock_irq(&cfg_priv->evt_q_lock);
3395 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3399 cfg_priv->scan_request = NULL;
3400 cfg_priv->pwr_save = true;
3401 cfg_priv->iscan_on = true; /* iscan on & off switch.
3402 we enable iscan per default */
3403 cfg_priv->roam_on = true; /* roam on & off switch.
3404 we enable roam per default */
3406 cfg_priv->iscan_kickstart = false;
3407 cfg_priv->active_scan = true; /* we do active scan for
3408 specific scan per default */
3409 cfg_priv->dongle_up = false; /* dongle is not up yet */
3410 brcmf_init_eq(cfg_priv);
3411 err = brcmf_init_priv_mem(cfg_priv);
3414 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3415 brcmf_init_eloop_handler(&cfg_priv->el);
3416 mutex_init(&cfg_priv->usr_sync);
3417 err = brcmf_init_iscan(cfg_priv);
3420 brcmf_init_conf(cfg_priv->conf);
3421 brcmf_init_prof(cfg_priv->profile);
3422 brcmf_link_down(cfg_priv);
3427 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3429 cancel_work_sync(&cfg_priv->event_work);
3430 cfg_priv->dongle_up = false; /* dongle down */
3431 brcmf_flush_eq(cfg_priv);
3432 brcmf_link_down(cfg_priv);
3433 brcmf_term_iscan(cfg_priv);
3434 brcmf_deinit_priv_mem(cfg_priv);
3437 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3438 struct device *busdev,
3441 struct wireless_dev *wdev;
3442 struct brcmf_cfg80211_priv *cfg_priv;
3443 struct brcmf_cfg80211_iface *ci;
3444 struct brcmf_cfg80211_dev *cfg_dev;
3448 WL_ERR("ndev is invalid\n");
3451 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3455 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3461 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3462 cfg_priv = wdev_to_cfg(wdev);
3463 cfg_priv->wdev = wdev;
3464 cfg_priv->pub = data;
3465 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3466 ci->cfg_priv = cfg_priv;
3467 ndev->ieee80211_ptr = wdev;
3468 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3469 wdev->netdev = ndev;
3470 err = wl_init_priv(cfg_priv);
3472 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3473 goto cfg80211_attach_out;
3475 brcmf_set_drvdata(cfg_dev, ci);
3479 cfg80211_attach_out:
3480 brcmf_free_wdev(cfg_priv);
3485 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3487 struct brcmf_cfg80211_priv *cfg_priv;
3489 cfg_priv = brcmf_priv_get(cfg_dev);
3491 wl_deinit_priv(cfg_priv);
3492 brcmf_free_wdev(cfg_priv);
3493 brcmf_set_drvdata(cfg_dev, NULL);
3498 brcmf_cfg80211_event(struct net_device *ndev,
3499 const struct brcmf_event_msg *e, void *data)
3501 u32 event_type = be32_to_cpu(e->event_type);
3502 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3504 if (!brcmf_enq_event(cfg_priv, event_type, e))
3505 schedule_work(&cfg_priv->event_work);
3508 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3514 case NL80211_IFTYPE_MONITOR:
3515 case NL80211_IFTYPE_WDS:
3516 WL_ERR("type (%d) : currently we do not support this mode\n",
3520 case NL80211_IFTYPE_ADHOC:
3523 case NL80211_IFTYPE_STATION:
3528 WL_ERR("invalid type (%d)\n", iftype);
3531 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3533 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3540 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3542 /* Room for "event_msgs" + '\0' + bitvec */
3543 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3544 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3547 WL_TRACE("Enter\n");
3549 /* Setup event_msgs */
3550 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3551 iovbuf, sizeof(iovbuf));
3552 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3554 WL_ERR("Get event_msgs error (%d)\n", err);
3555 goto dongle_eventmsg_out;
3557 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3559 setbit(eventmask, BRCMF_E_SET_SSID);
3560 setbit(eventmask, BRCMF_E_ROAM);
3561 setbit(eventmask, BRCMF_E_PRUNE);
3562 setbit(eventmask, BRCMF_E_AUTH);
3563 setbit(eventmask, BRCMF_E_REASSOC);
3564 setbit(eventmask, BRCMF_E_REASSOC_IND);
3565 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3566 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3567 setbit(eventmask, BRCMF_E_DISASSOC);
3568 setbit(eventmask, BRCMF_E_JOIN);
3569 setbit(eventmask, BRCMF_E_ASSOC_IND);
3570 setbit(eventmask, BRCMF_E_PSK_SUP);
3571 setbit(eventmask, BRCMF_E_LINK);
3572 setbit(eventmask, BRCMF_E_NDIS_LINK);
3573 setbit(eventmask, BRCMF_E_MIC_ERROR);
3574 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3575 setbit(eventmask, BRCMF_E_TXFAIL);
3576 setbit(eventmask, BRCMF_E_JOIN_START);
3577 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3579 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3580 iovbuf, sizeof(iovbuf));
3581 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3583 WL_ERR("Set event_msgs error (%d)\n", err);
3584 goto dongle_eventmsg_out;
3587 dongle_eventmsg_out:
3593 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3597 __le32 roamtrigger[2];
3598 __le32 roam_delta[2];
3603 * Setup timeout if Beacons are lost and roam is
3604 * off to report link down
3607 bcn_to_le = cpu_to_le32(bcn_timeout);
3608 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3609 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3610 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3611 iovbuf, sizeof(iovbuf));
3613 WL_ERR("bcn_timeout error (%d)\n", err);
3614 goto dongle_rom_out;
3619 * Enable/Disable built-in roaming to allow supplicant
3620 * to take care of roaming
3622 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3623 roamvar_le = cpu_to_le32(roamvar);
3624 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3625 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3626 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3628 WL_ERR("roam_off error (%d)\n", err);
3629 goto dongle_rom_out;
3632 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3633 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3634 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3635 (void *)roamtrigger, sizeof(roamtrigger));
3637 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3638 goto dongle_rom_out;
3641 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3642 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3643 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3644 (void *)roam_delta, sizeof(roam_delta));
3646 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3647 goto dongle_rom_out;
3655 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3656 s32 scan_unassoc_time, s32 scan_passive_time)
3659 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3660 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3661 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3663 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3664 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3666 if (err == -EOPNOTSUPP)
3667 WL_INFO("Scan assoc time is not supported\n");
3669 WL_ERR("Scan assoc time error (%d)\n", err);
3670 goto dongle_scantime_out;
3672 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3673 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3675 if (err == -EOPNOTSUPP)
3676 WL_INFO("Scan unassoc time is not supported\n");
3678 WL_ERR("Scan unassoc time error (%d)\n", err);
3679 goto dongle_scantime_out;
3682 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3683 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3685 if (err == -EOPNOTSUPP)
3686 WL_INFO("Scan passive time is not supported\n");
3688 WL_ERR("Scan passive time error (%d)\n", err);
3689 goto dongle_scantime_out;
3692 dongle_scantime_out:
3696 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3698 struct wiphy *wiphy;
3703 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3704 &phy_list, sizeof(phy_list));
3706 WL_ERR("error (%d)\n", err);
3710 phy = ((char *)&phy_list)[1];
3711 WL_INFO("%c phy\n", phy);
3712 if (phy == 'n' || phy == 'a') {
3713 wiphy = cfg_to_wiphy(cfg_priv);
3714 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3720 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3722 return wl_update_wiphybands(cfg_priv);
3725 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3727 struct net_device *ndev;
3728 struct wireless_dev *wdev;
3732 if (cfg_priv->dongle_up)
3735 ndev = cfg_to_ndev(cfg_priv);
3736 wdev = ndev->ieee80211_ptr;
3738 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3739 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3741 err = brcmf_dongle_eventmsg(ndev);
3743 goto default_conf_out;
3745 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3746 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3748 goto default_conf_out;
3749 WL_INFO("power save set to %s\n",
3750 (power_mode ? "enabled" : "disabled"));
3752 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3755 goto default_conf_out;
3756 err = brcmf_dongle_mode(ndev, wdev->iftype);
3757 if (err && err != -EINPROGRESS)
3758 goto default_conf_out;
3759 err = brcmf_dongle_probecap(cfg_priv);
3761 goto default_conf_out;
3763 /* -EINPROGRESS: Call commit handler */
3767 cfg_priv->dongle_up = true;
3773 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3775 char buf[10+IFNAMSIZ];
3779 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3780 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3781 cfg_to_wiphy(cfg_priv)->debugfsdir);
3783 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3784 (u16 *)&cfg_priv->profile->beacon_interval);
3790 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3791 (u8 *)&cfg_priv->profile->dtim_period);
3801 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3803 debugfs_remove_recursive(cfg_priv->debugfsdir);
3804 cfg_priv->debugfsdir = NULL;
3807 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3811 set_bit(WL_STATUS_READY, &cfg_priv->status);
3813 brcmf_debugfs_add_netdev_params(cfg_priv);
3815 err = brcmf_config_dongle(cfg_priv);
3819 brcmf_invoke_iscan(cfg_priv);
3824 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3827 * While going down, if associated with AP disassociate
3828 * from AP to save power
3830 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3831 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3832 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3833 WL_INFO("Disassociating from AP");
3834 brcmf_link_down(cfg_priv);
3836 /* Make sure WPA_Supplicant receives all the event
3837 generated due to DISASSOC call to the fw to keep
3838 the state fw and WPA_Supplicant state consistent
3843 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3844 brcmf_term_iscan(cfg_priv);
3845 if (cfg_priv->scan_request) {
3846 cfg80211_scan_done(cfg_priv->scan_request, true);
3847 /* May need to perform this to cover rmmod */
3848 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3849 cfg_priv->scan_request = NULL;
3851 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3852 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3853 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3855 brcmf_debugfs_remove_netdev(cfg_priv);
3860 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3862 struct brcmf_cfg80211_priv *cfg_priv;
3865 cfg_priv = brcmf_priv_get(cfg_dev);
3866 mutex_lock(&cfg_priv->usr_sync);
3867 err = __brcmf_cfg80211_up(cfg_priv);
3868 mutex_unlock(&cfg_priv->usr_sync);
3873 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3875 struct brcmf_cfg80211_priv *cfg_priv;
3878 cfg_priv = brcmf_priv_get(cfg_dev);
3879 mutex_lock(&cfg_priv->usr_sync);
3880 err = __brcmf_cfg80211_down(cfg_priv);
3881 mutex_unlock(&cfg_priv->usr_sync);
3886 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3889 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3892 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3893 WL_ERR("ei crosses buffer boundary\n");
3896 ie->buf[ie->offset] = t;
3897 ie->buf[ie->offset + 1] = l;
3898 memcpy(&ie->buf[ie->offset + 2], v, l);
3899 ie->offset += l + 2;