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 /* Quarter dBm units to mW
251 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
252 * Table is offset so the last entry is largest mW value that fits in
256 #define QDBM_OFFSET 153 /* Offset for first entry */
257 #define QDBM_TABLE_LEN 40 /* Table size */
259 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
260 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
262 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
264 /* Largest mW value that will round down to the last table entry,
265 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
266 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
267 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
269 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
271 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
272 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
273 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
274 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
275 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
276 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
277 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
280 static u16 brcmf_qdbm_to_mw(u8 qdbm)
283 int idx = qdbm - QDBM_OFFSET;
285 if (idx >= QDBM_TABLE_LEN)
286 /* clamp to max u16 mW value */
289 /* scale the qdBm index up to the range of the table 0-40
290 * where an offset of 40 qdBm equals a factor of 10 mW.
297 /* return the mW value scaled down to the correct factor of 10,
298 * adding in factor/2 to get proper rounding.
300 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
303 static u8 brcmf_mw_to_qdbm(u16 mw)
310 /* handle boundary case */
314 offset = QDBM_OFFSET;
316 /* move mw into the range of the table */
317 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
322 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
323 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
324 nqdBm_to_mW_map[qdbm]) / 2;
325 if (mw_uint < boundary)
334 /* function for reading/writing a single u32 from/to the dongle */
336 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
339 __le32 par_le = cpu_to_le32(*par);
341 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
342 *par = le32_to_cpu(par_le);
347 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
348 struct brcmf_wsec_key_le *key_le)
350 key_le->index = cpu_to_le32(key->index);
351 key_le->len = cpu_to_le32(key->len);
352 key_le->algo = cpu_to_le32(key->algo);
353 key_le->flags = cpu_to_le32(key->flags);
354 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
355 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
356 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
357 memcpy(key_le->data, key->data, sizeof(key->data));
358 memcpy(key_le->ea, key->ea, sizeof(key->ea));
361 static int send_key_to_dongle(struct net_device *ndev,
362 struct brcmf_wsec_key *key)
365 struct brcmf_wsec_key_le key_le;
367 convert_key_from_CPU(key, &key_le);
368 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
370 WL_ERR("WLC_SET_KEY error (%d)\n", err);
375 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
376 enum nl80211_iftype type, u32 *flags,
377 struct vif_params *params)
379 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
380 struct wireless_dev *wdev;
385 if (!check_sys_up(wiphy))
389 case NL80211_IFTYPE_MONITOR:
390 case NL80211_IFTYPE_WDS:
391 WL_ERR("type (%d) : currently we do not support this type\n",
394 case NL80211_IFTYPE_ADHOC:
395 cfg_priv->conf->mode = WL_MODE_IBSS;
398 case NL80211_IFTYPE_STATION:
399 cfg_priv->conf->mode = WL_MODE_BSS;
407 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
409 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
412 wdev = ndev->ieee80211_ptr;
416 WL_INFO("IF Type = %s\n",
417 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
425 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
427 s8 buf[BRCMF_DCMD_SMLEN];
432 val_le = cpu_to_le32(val);
433 len = brcmu_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
437 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
439 WL_ERR("error (%d)\n", err);
445 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
448 s8 buf[BRCMF_DCMD_SMLEN];
456 brcmu_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
459 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
461 WL_ERR("error (%d)\n", err);
463 *retval = le32_to_cpu(var.val);
468 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
471 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
473 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
474 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
476 WL_ERR("fail to set mpc\n");
479 WL_INFO("MPC : %d\n", mpc);
483 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
484 struct brcmf_ssid *ssid)
486 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
487 params_le->bss_type = DOT11_BSSTYPE_ANY;
488 params_le->scan_type = 0;
489 params_le->channel_num = 0;
490 params_le->nprobes = cpu_to_le32(-1);
491 params_le->active_time = cpu_to_le32(-1);
492 params_le->passive_time = cpu_to_le32(-1);
493 params_le->home_time = cpu_to_le32(-1);
494 if (ssid && ssid->SSID_len)
495 memcpy(¶ms_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
499 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
500 s32 paramlen, void *bufptr, s32 buflen)
504 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
507 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
511 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
512 s32 paramlen, void *bufptr, s32 buflen)
516 iolen = brcmu_mkiovar(iovar, param, paramlen, bufptr, buflen);
519 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
523 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
524 struct brcmf_ssid *ssid, u16 action)
526 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
527 offsetof(struct brcmf_iscan_params_le, params_le);
528 struct brcmf_iscan_params_le *params;
531 if (ssid && ssid->SSID_len)
532 params_size += sizeof(struct brcmf_ssid);
533 params = kzalloc(params_size, GFP_KERNEL);
536 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
538 wl_iscan_prep(¶ms->params_le, ssid);
540 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
541 params->action = cpu_to_le16(action);
542 params->scan_duration = cpu_to_le16(0);
544 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
545 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
548 WL_INFO("system busy : iscan canceled\n");
550 WL_ERR("error (%d)\n", err);
557 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
559 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
560 struct net_device *ndev = cfg_to_ndev(cfg_priv);
561 struct brcmf_ssid ssid;
565 /* Broadcast scan by default */
566 memset(&ssid, 0, sizeof(ssid));
568 iscan->state = WL_ISCAN_STATE_SCANING;
570 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
571 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
572 &passive_scan, sizeof(passive_scan));
574 WL_ERR("error (%d)\n", err);
577 brcmf_set_mpc(ndev, 0);
578 cfg_priv->iscan_kickstart = true;
579 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
581 brcmf_set_mpc(ndev, 1);
582 cfg_priv->iscan_kickstart = false;
585 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
591 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
592 struct cfg80211_scan_request *request,
593 struct cfg80211_ssid *this_ssid)
595 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
596 struct cfg80211_ssid *ssids;
597 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
604 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
605 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
608 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
609 WL_ERR("Scanning being aborted : status (%lu)\n",
613 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
614 WL_ERR("Connecting : status (%lu)\n",
623 ssids = request->ssids;
624 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
628 /* we don't do iscan in ibss */
632 cfg_priv->scan_request = request;
633 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
635 err = brcmf_do_iscan(cfg_priv);
641 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
642 ssids->ssid, ssids->ssid_len);
643 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
644 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
645 sr->ssid_le.SSID_len = cpu_to_le32(0);
647 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
648 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
651 WL_SCAN("Broadcast scan\n");
654 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
655 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
656 &passive_scan, sizeof(passive_scan));
658 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
661 brcmf_set_mpc(ndev, 0);
662 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
663 sizeof(sr->ssid_le));
666 WL_INFO("system busy : scan for \"%s\" "
667 "canceled\n", sr->ssid_le.SSID);
669 WL_ERR("WLC_SCAN error (%d)\n", err);
671 brcmf_set_mpc(ndev, 1);
679 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
680 cfg_priv->scan_request = NULL;
685 brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
686 struct cfg80211_scan_request *request)
692 if (!check_sys_up(wiphy))
695 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
697 WL_ERR("scan error (%d)\n", err);
703 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
707 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
709 WL_ERR("Error (%d)\n", err);
714 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
718 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
720 WL_ERR("Error (%d)\n", err);
725 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
728 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
730 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
732 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
738 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
740 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
741 struct net_device *ndev = cfg_to_ndev(cfg_priv);
745 if (!check_sys_up(wiphy))
748 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
749 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
750 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
751 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
755 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
756 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
757 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
758 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
762 if (changed & WIPHY_PARAM_RETRY_LONG
763 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
764 cfg_priv->conf->retry_long = wiphy->retry_long;
765 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
769 if (changed & WIPHY_PARAM_RETRY_SHORT
770 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
771 cfg_priv->conf->retry_short = wiphy->retry_short;
772 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
782 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
786 return &cfg_priv->profile->sec;
788 return &cfg_priv->profile->bssid;
790 return &cfg_priv->profile->ssid;
792 WL_ERR("invalid item (%d)\n", item);
797 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
798 const struct brcmf_event_msg *e, void *data, s32 item)
801 struct brcmf_ssid *ssid;
805 ssid = (struct brcmf_ssid *) data;
806 memset(cfg_priv->profile->ssid.SSID, 0,
807 sizeof(cfg_priv->profile->ssid.SSID));
808 memcpy(cfg_priv->profile->ssid.SSID,
809 ssid->SSID, ssid->SSID_len);
810 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
814 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
816 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
819 memcpy(&cfg_priv->profile->sec, data,
820 sizeof(cfg_priv->profile->sec));
822 case WL_PROF_BEACONINT:
823 cfg_priv->profile->beacon_interval = *(u16 *)data;
825 case WL_PROF_DTIMPERIOD:
826 cfg_priv->profile->dtim_period = *(u8 *)data;
829 WL_ERR("unsupported item (%d)\n", item);
837 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
839 memset(prof, 0, sizeof(*prof));
842 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
843 size_t *join_params_size)
848 if (ch <= CH_MAX_2G_CHANNEL)
849 chanspec |= WL_CHANSPEC_BAND_2G;
851 chanspec |= WL_CHANSPEC_BAND_5G;
853 chanspec |= WL_CHANSPEC_BW_20;
854 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
856 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
859 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
860 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
861 join_params->params_le.chanspec_num = cpu_to_le32(1);
863 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
864 "channel %d, chanspec %#X\n",
865 chanspec, ch, chanspec);
869 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
871 struct net_device *ndev = NULL;
876 if (cfg_priv->link_up) {
877 ndev = cfg_to_ndev(cfg_priv);
878 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
879 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
881 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
882 cfg_priv->link_up = false;
888 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
889 struct cfg80211_ibss_params *params)
891 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
892 struct brcmf_join_params join_params;
893 size_t join_params_size = 0;
897 struct brcmf_ssid ssid;
900 if (!check_sys_up(wiphy))
904 WL_CONN("SSID: %s\n", params->ssid);
906 WL_CONN("SSID: NULL, Not supported\n");
910 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
913 WL_CONN("BSSID: %02X %02X %02X %02X %02X %02X\n",
914 params->bssid[0], params->bssid[1], params->bssid[2],
915 params->bssid[3], params->bssid[4], params->bssid[5]);
917 WL_CONN("No BSSID specified\n");
920 WL_CONN("channel: %d\n", params->channel->center_freq);
922 WL_CONN("no channel specified\n");
924 if (params->channel_fixed)
925 WL_CONN("fixed channel required\n");
927 WL_CONN("no fixed channel required\n");
929 if (params->ie && params->ie_len)
930 WL_CONN("ie len: %d\n", params->ie_len);
932 WL_CONN("no ie specified\n");
934 if (params->beacon_interval)
935 WL_CONN("beacon interval: %d\n", params->beacon_interval);
937 WL_CONN("no beacon interval specified\n");
939 if (params->basic_rates)
940 WL_CONN("basic rates: %08X\n", params->basic_rates);
942 WL_CONN("no basic rates specified\n");
945 WL_CONN("privacy required\n");
947 WL_CONN("no privacy required\n");
949 /* Configure Privacy for starter */
953 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
955 WL_ERR("wsec failed (%d)\n", err);
959 /* Configure Beacon Interval for starter */
960 if (params->beacon_interval)
961 bcnprd = params->beacon_interval;
965 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
967 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
971 /* Configure required join parameter */
972 memset(&join_params, 0, sizeof(struct brcmf_join_params));
975 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
976 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
977 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
978 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
979 join_params_size = sizeof(join_params.ssid_le);
980 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
984 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
985 join_params_size = sizeof(join_params.ssid_le) +
986 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
988 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
991 brcmf_update_prof(cfg_priv, NULL,
992 &join_params.params_le.bssid, WL_PROF_BSSID);
995 if (params->channel) {
999 ieee80211_frequency_to_channel(
1000 params->channel->center_freq);
1001 if (params->channel_fixed) {
1002 /* adding chanspec */
1003 brcmf_ch_to_chanspec(cfg_priv->channel,
1004 &join_params, &join_params_size);
1007 /* set channel for starter */
1008 target_channel = cfg_priv->channel;
1009 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1012 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1016 cfg_priv->channel = 0;
1018 cfg_priv->ibss_starter = false;
1021 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1022 &join_params, join_params_size);
1024 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1030 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1036 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1038 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1041 WL_TRACE("Enter\n");
1042 if (!check_sys_up(wiphy))
1045 brcmf_link_down(cfg_priv);
1052 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1053 struct cfg80211_connect_params *sme)
1055 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1056 struct brcmf_cfg80211_security *sec;
1060 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1061 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1062 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1063 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1065 val = WPA_AUTH_DISABLED;
1066 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1067 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1069 WL_ERR("set wpa_auth failed (%d)\n", err);
1072 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1073 sec->wpa_versions = sme->crypto.wpa_versions;
1077 static s32 brcmf_set_auth_type(struct net_device *ndev,
1078 struct cfg80211_connect_params *sme)
1080 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1081 struct brcmf_cfg80211_security *sec;
1085 switch (sme->auth_type) {
1086 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1088 WL_CONN("open system\n");
1090 case NL80211_AUTHTYPE_SHARED_KEY:
1092 WL_CONN("shared key\n");
1094 case NL80211_AUTHTYPE_AUTOMATIC:
1096 WL_CONN("automatic\n");
1098 case NL80211_AUTHTYPE_NETWORK_EAP:
1099 WL_CONN("network eap\n");
1102 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1106 err = brcmf_dev_intvar_set(ndev, "auth", val);
1108 WL_ERR("set auth failed (%d)\n", err);
1111 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1112 sec->auth_type = sme->auth_type;
1117 brcmf_set_set_cipher(struct net_device *ndev,
1118 struct cfg80211_connect_params *sme)
1120 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1121 struct brcmf_cfg80211_security *sec;
1126 if (sme->crypto.n_ciphers_pairwise) {
1127 switch (sme->crypto.ciphers_pairwise[0]) {
1128 case WLAN_CIPHER_SUITE_WEP40:
1129 case WLAN_CIPHER_SUITE_WEP104:
1132 case WLAN_CIPHER_SUITE_TKIP:
1133 pval = TKIP_ENABLED;
1135 case WLAN_CIPHER_SUITE_CCMP:
1138 case WLAN_CIPHER_SUITE_AES_CMAC:
1142 WL_ERR("invalid cipher pairwise (%d)\n",
1143 sme->crypto.ciphers_pairwise[0]);
1147 if (sme->crypto.cipher_group) {
1148 switch (sme->crypto.cipher_group) {
1149 case WLAN_CIPHER_SUITE_WEP40:
1150 case WLAN_CIPHER_SUITE_WEP104:
1153 case WLAN_CIPHER_SUITE_TKIP:
1154 gval = TKIP_ENABLED;
1156 case WLAN_CIPHER_SUITE_CCMP:
1159 case WLAN_CIPHER_SUITE_AES_CMAC:
1163 WL_ERR("invalid cipher group (%d)\n",
1164 sme->crypto.cipher_group);
1169 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1170 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1172 WL_ERR("error (%d)\n", err);
1176 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1177 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1178 sec->cipher_group = sme->crypto.cipher_group;
1184 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1186 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1187 struct brcmf_cfg80211_security *sec;
1191 if (sme->crypto.n_akm_suites) {
1192 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1194 WL_ERR("could not get wpa_auth (%d)\n", err);
1197 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1198 switch (sme->crypto.akm_suites[0]) {
1199 case WLAN_AKM_SUITE_8021X:
1200 val = WPA_AUTH_UNSPECIFIED;
1202 case WLAN_AKM_SUITE_PSK:
1206 WL_ERR("invalid cipher group (%d)\n",
1207 sme->crypto.cipher_group);
1210 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1211 switch (sme->crypto.akm_suites[0]) {
1212 case WLAN_AKM_SUITE_8021X:
1213 val = WPA2_AUTH_UNSPECIFIED;
1215 case WLAN_AKM_SUITE_PSK:
1216 val = WPA2_AUTH_PSK;
1219 WL_ERR("invalid cipher group (%d)\n",
1220 sme->crypto.cipher_group);
1225 WL_CONN("setting wpa_auth to %d\n", val);
1226 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1228 WL_ERR("could not set wpa_auth (%d)\n", err);
1232 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1233 sec->wpa_auth = sme->crypto.akm_suites[0];
1239 brcmf_set_wep_sharedkey(struct net_device *ndev,
1240 struct cfg80211_connect_params *sme)
1242 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1243 struct brcmf_cfg80211_security *sec;
1244 struct brcmf_wsec_key key;
1248 WL_CONN("key len (%d)\n", sme->key_len);
1250 if (sme->key_len == 0)
1253 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1254 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1255 sec->wpa_versions, sec->cipher_pairwise);
1257 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1260 if (sec->cipher_pairwise &
1261 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1262 memset(&key, 0, sizeof(key));
1263 key.len = (u32) sme->key_len;
1264 key.index = (u32) sme->key_idx;
1265 if (key.len > sizeof(key.data)) {
1266 WL_ERR("Too long key length (%u)\n", key.len);
1269 memcpy(key.data, sme->key, key.len);
1270 key.flags = BRCMF_PRIMARY_KEY;
1271 switch (sec->cipher_pairwise) {
1272 case WLAN_CIPHER_SUITE_WEP40:
1273 key.algo = CRYPTO_ALGO_WEP1;
1275 case WLAN_CIPHER_SUITE_WEP104:
1276 key.algo = CRYPTO_ALGO_WEP128;
1279 WL_ERR("Invalid algorithm (%d)\n",
1280 sme->crypto.ciphers_pairwise[0]);
1283 /* Set the new key/index */
1284 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1285 key.len, key.index, key.algo);
1286 WL_CONN("key \"%s\"\n", key.data);
1287 err = send_key_to_dongle(ndev, &key);
1291 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1292 WL_CONN("set auth_type to shared key\n");
1293 val = 1; /* shared key */
1294 err = brcmf_dev_intvar_set(ndev, "auth", val);
1296 WL_ERR("set auth failed (%d)\n", err);
1305 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1306 struct cfg80211_connect_params *sme)
1308 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1309 struct ieee80211_channel *chan = sme->channel;
1310 struct brcmf_join_params join_params;
1311 size_t join_params_size;
1312 struct brcmf_ssid ssid;
1316 WL_TRACE("Enter\n");
1317 if (!check_sys_up(wiphy))
1321 WL_ERR("Invalid ssid\n");
1325 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1329 ieee80211_frequency_to_channel(chan->center_freq);
1330 WL_CONN("channel (%d), center_req (%d)\n",
1331 cfg_priv->channel, chan->center_freq);
1333 cfg_priv->channel = 0;
1335 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1337 err = brcmf_set_wpa_version(ndev, sme);
1339 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1343 err = brcmf_set_auth_type(ndev, sme);
1345 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1349 err = brcmf_set_set_cipher(ndev, sme);
1351 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1355 err = brcmf_set_key_mgmt(ndev, sme);
1357 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1361 err = brcmf_set_wep_sharedkey(ndev, sme);
1363 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1367 memset(&join_params, 0, sizeof(join_params));
1368 join_params_size = sizeof(join_params.ssid_le);
1370 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), sme->ssid_len);
1371 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1372 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1373 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1374 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1376 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1378 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1379 WL_CONN("ssid \"%s\", len (%d)\n",
1380 ssid.SSID, ssid.SSID_len);
1382 brcmf_ch_to_chanspec(cfg_priv->channel,
1383 &join_params, &join_params_size);
1384 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1385 &join_params, join_params_size);
1387 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1391 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1397 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1400 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1401 struct brcmf_scb_val_le scbval;
1404 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1405 if (!check_sys_up(wiphy))
1408 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1410 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1411 scbval.val = cpu_to_le32(reason_code);
1412 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1413 sizeof(struct brcmf_scb_val_le));
1415 WL_ERR("error (%d)\n", err);
1417 cfg_priv->link_up = false;
1424 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1425 enum nl80211_tx_power_setting type, s32 dbm)
1428 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1429 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1434 WL_TRACE("Enter\n");
1435 if (!check_sys_up(wiphy))
1439 case NL80211_TX_POWER_AUTOMATIC:
1441 case NL80211_TX_POWER_LIMITED:
1443 WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1448 case NL80211_TX_POWER_FIXED:
1450 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1456 /* Make sure radio is off or on as far as software is concerned */
1457 disable = WL_RADIO_SW_DISABLE << 16;
1458 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1460 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1465 txpwrmw = (u16) dbm;
1466 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1467 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1469 WL_ERR("qtxpower error (%d)\n", err);
1470 cfg_priv->conf->tx_power = dbm;
1477 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1479 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1480 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1485 WL_TRACE("Enter\n");
1486 if (!check_sys_up(wiphy))
1489 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1491 WL_ERR("error (%d)\n", err);
1495 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1496 *dbm = (s32) brcmf_qdbm_to_mw(result);
1504 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1505 u8 key_idx, bool unicast, bool multicast)
1511 WL_TRACE("Enter\n");
1512 WL_CONN("key index (%d)\n", key_idx);
1513 if (!check_sys_up(wiphy))
1516 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1518 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1522 if (wsec & WEP_ENABLED) {
1523 /* Just select a new current key */
1525 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1528 WL_ERR("error (%d)\n", err);
1536 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1537 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1539 struct brcmf_wsec_key key;
1540 struct brcmf_wsec_key_le key_le;
1543 memset(&key, 0, sizeof(key));
1544 key.index = (u32) key_idx;
1545 /* Instead of bcast for ea address for default wep keys,
1546 driver needs it to be Null */
1547 if (!is_multicast_ether_addr(mac_addr))
1548 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1549 key.len = (u32) params->key_len;
1550 /* check for key index change */
1553 err = send_key_to_dongle(ndev, &key);
1557 if (key.len > sizeof(key.data)) {
1558 WL_ERR("Invalid key length (%d)\n", key.len);
1562 WL_CONN("Setting the key index %d\n", key.index);
1563 memcpy(key.data, params->key, key.len);
1565 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1567 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1568 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1569 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1572 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1573 if (params->seq && params->seq_len == 6) {
1576 ivptr = (u8 *) params->seq;
1577 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1578 (ivptr[3] << 8) | ivptr[2];
1579 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1580 key.iv_initialized = true;
1583 switch (params->cipher) {
1584 case WLAN_CIPHER_SUITE_WEP40:
1585 key.algo = CRYPTO_ALGO_WEP1;
1586 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1588 case WLAN_CIPHER_SUITE_WEP104:
1589 key.algo = CRYPTO_ALGO_WEP128;
1590 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1592 case WLAN_CIPHER_SUITE_TKIP:
1593 key.algo = CRYPTO_ALGO_TKIP;
1594 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1596 case WLAN_CIPHER_SUITE_AES_CMAC:
1597 key.algo = CRYPTO_ALGO_AES_CCM;
1598 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1600 case WLAN_CIPHER_SUITE_CCMP:
1601 key.algo = CRYPTO_ALGO_AES_CCM;
1602 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1605 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1608 convert_key_from_CPU(&key, &key_le);
1610 brcmf_netdev_wait_pend8021x(ndev);
1611 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1614 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1622 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1623 u8 key_idx, bool pairwise, const u8 *mac_addr,
1624 struct key_params *params)
1626 struct brcmf_wsec_key key;
1632 WL_TRACE("Enter\n");
1633 WL_CONN("key index (%d)\n", key_idx);
1634 if (!check_sys_up(wiphy))
1639 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1641 memset(&key, 0, sizeof(key));
1643 key.len = (u32) params->key_len;
1644 key.index = (u32) key_idx;
1646 if (key.len > sizeof(key.data)) {
1647 WL_ERR("Too long key length (%u)\n", key.len);
1651 memcpy(key.data, params->key, key.len);
1653 key.flags = BRCMF_PRIMARY_KEY;
1654 switch (params->cipher) {
1655 case WLAN_CIPHER_SUITE_WEP40:
1656 key.algo = CRYPTO_ALGO_WEP1;
1657 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1659 case WLAN_CIPHER_SUITE_WEP104:
1660 key.algo = CRYPTO_ALGO_WEP128;
1661 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1663 case WLAN_CIPHER_SUITE_TKIP:
1664 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1665 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1666 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1667 key.algo = CRYPTO_ALGO_TKIP;
1668 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1670 case WLAN_CIPHER_SUITE_AES_CMAC:
1671 key.algo = CRYPTO_ALGO_AES_CCM;
1672 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1674 case WLAN_CIPHER_SUITE_CCMP:
1675 key.algo = CRYPTO_ALGO_AES_CCM;
1676 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1679 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1684 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1689 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1691 WL_ERR("get wsec error (%d)\n", err);
1694 wsec &= ~(WEP_ENABLED);
1696 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1698 WL_ERR("set wsec error (%d)\n", err);
1702 val = 1; /* assume shared key. otherwise 0 */
1703 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1705 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1712 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1713 u8 key_idx, bool pairwise, const u8 *mac_addr)
1715 struct brcmf_wsec_key key;
1720 WL_TRACE("Enter\n");
1721 if (!check_sys_up(wiphy))
1724 memset(&key, 0, sizeof(key));
1726 key.index = (u32) key_idx;
1727 key.flags = BRCMF_PRIMARY_KEY;
1728 key.algo = CRYPTO_ALGO_OFF;
1730 WL_CONN("key index (%d)\n", key_idx);
1732 /* Set the new key/index */
1733 err = send_key_to_dongle(ndev, &key);
1735 if (err == -EINVAL) {
1736 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1737 /* we ignore this key index in this case */
1738 WL_ERR("invalid key index (%d)\n", key_idx);
1740 /* Ignore this error, may happen during DISASSOC */
1746 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1748 WL_ERR("get wsec error (%d)\n", err);
1749 /* Ignore this error, may happen during DISASSOC */
1753 wsec &= ~(WEP_ENABLED);
1755 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1757 WL_ERR("set wsec error (%d)\n", err);
1758 /* Ignore this error, may happen during DISASSOC */
1763 val = 0; /* assume open key. otherwise 1 */
1764 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1766 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1767 /* Ignore this error, may happen during DISASSOC */
1776 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1777 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1778 void (*callback) (void *cookie, struct key_params * params))
1780 struct key_params params;
1781 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1782 struct brcmf_cfg80211_security *sec;
1786 WL_TRACE("Enter\n");
1787 WL_CONN("key index (%d)\n", key_idx);
1788 if (!check_sys_up(wiphy))
1791 memset(¶ms, 0, sizeof(params));
1793 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1795 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1796 /* Ignore this error, may happen during DISASSOC */
1802 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1803 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1804 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1805 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1806 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1807 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1808 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1812 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1813 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1816 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1817 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1820 WL_ERR("Invalid algo (0x%x)\n", wsec);
1824 callback(cookie, ¶ms);
1832 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1833 struct net_device *ndev, u8 key_idx)
1835 WL_INFO("Not supported\n");
1841 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1842 u8 *mac, struct station_info *sinfo)
1844 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1845 struct brcmf_scb_val_le scb_val;
1849 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1851 WL_TRACE("Enter\n");
1852 if (!check_sys_up(wiphy))
1855 if (memcmp(mac, bssid, ETH_ALEN)) {
1856 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1857 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1858 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1859 bssid[0], bssid[1], bssid[2], bssid[3],
1860 bssid[4], bssid[5]);
1865 /* Report the current tx rate */
1866 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1868 WL_ERR("Could not get rate (%d)\n", err);
1870 sinfo->filled |= STATION_INFO_TX_BITRATE;
1871 sinfo->txrate.legacy = rate * 5;
1872 WL_CONN("Rate %d Mbps\n", rate / 2);
1875 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1876 scb_val.val = cpu_to_le32(0);
1877 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1878 sizeof(struct brcmf_scb_val_le));
1880 WL_ERR("Could not get rssi (%d)\n", err);
1882 rssi = le32_to_cpu(scb_val.val);
1883 sinfo->filled |= STATION_INFO_SIGNAL;
1884 sinfo->signal = rssi;
1885 WL_CONN("RSSI %d dBm\n", rssi);
1894 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1895 bool enabled, s32 timeout)
1899 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1901 WL_TRACE("Enter\n");
1904 * Powersave enable/disable request is coming from the
1905 * cfg80211 even before the interface is up. In that
1906 * scenario, driver will be storing the power save
1907 * preference in cfg_priv struct to apply this to
1908 * FW later while initializing the dongle
1910 cfg_priv->pwr_save = enabled;
1911 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1913 WL_INFO("Device is not ready,"
1914 "storing the value in cfg_priv struct\n");
1918 pm = enabled ? PM_FAST : PM_OFF;
1919 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1921 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1924 WL_ERR("net_device is not ready yet\n");
1926 WL_ERR("error (%d)\n", err);
1934 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1936 const struct cfg80211_bitrate_mask *mask)
1938 struct brcm_rateset_le rateset_le;
1946 WL_TRACE("Enter\n");
1947 if (!check_sys_up(wiphy))
1950 /* addr param is always NULL. ignore it */
1951 /* Get current rateset */
1952 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1953 sizeof(rateset_le));
1955 WL_ERR("could not get current rateset (%d)\n", err);
1959 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1961 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1964 val = wl_g_rates[legacy - 1].bitrate * 100000;
1966 if (val < le32_to_cpu(rateset_le.count))
1967 /* Select rate by rateset index */
1968 rate = rateset_le.rates[val] & 0x7f;
1970 /* Specified rate in bps */
1971 rate = val / 500000;
1973 WL_CONN("rate %d mbps\n", rate / 2);
1977 * Set rate override,
1978 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1980 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1981 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1982 if (err_bg && err_a) {
1983 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1984 err = err_bg | err_a;
1992 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1993 struct brcmf_bss_info *bi)
1995 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1996 struct ieee80211_channel *notify_channel;
1997 struct cfg80211_bss *bss;
1998 struct ieee80211_supported_band *band;
2002 u64 notify_timestamp;
2003 u16 notify_capability;
2004 u16 notify_interval;
2006 size_t notify_ielen;
2009 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2010 WL_ERR("Bss info is larger than buffer. Discarding\n");
2014 channel = bi->ctl_ch ? bi->ctl_ch :
2015 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2017 if (channel <= CH_MAX_2G_CHANNEL)
2018 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2020 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2022 freq = ieee80211_channel_to_frequency(channel, band->band);
2023 notify_channel = ieee80211_get_channel(wiphy, freq);
2025 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2026 notify_capability = le16_to_cpu(bi->capability);
2027 notify_interval = le16_to_cpu(bi->beacon_period);
2028 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2029 notify_ielen = le32_to_cpu(bi->ie_length);
2030 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2032 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2033 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2034 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2035 WL_CONN("Channel: %d(%d)\n", channel, freq);
2036 WL_CONN("Capability: %X\n", notify_capability);
2037 WL_CONN("Beacon interval: %d\n", notify_interval);
2038 WL_CONN("Signal: %d\n", notify_signal);
2039 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2041 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2042 notify_timestamp, notify_capability, notify_interval, notify_ie,
2043 notify_ielen, notify_signal, GFP_KERNEL);
2046 WL_ERR("cfg80211_inform_bss_frame error\n");
2053 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2055 struct brcmf_scan_results *bss_list;
2056 struct brcmf_bss_info *bi = NULL; /* must be initialized */
2060 bss_list = cfg_priv->bss_list;
2061 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2062 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2066 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2067 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2068 bi = next_bss(bss_list, bi);
2069 err = brcmf_inform_single_bss(cfg_priv, bi);
2076 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2077 struct net_device *ndev, const u8 *bssid)
2079 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2080 struct ieee80211_channel *notify_channel;
2081 struct brcmf_bss_info *bi = NULL;
2082 struct ieee80211_supported_band *band;
2087 u64 notify_timestamp;
2088 u16 notify_capability;
2089 u16 notify_interval;
2091 size_t notify_ielen;
2094 WL_TRACE("Enter\n");
2096 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2102 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2104 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2106 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2110 bi = (struct brcmf_bss_info *)(buf + 4);
2112 channel = bi->ctl_ch ? bi->ctl_ch :
2113 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2115 if (channel <= CH_MAX_2G_CHANNEL)
2116 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2118 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2120 freq = ieee80211_channel_to_frequency(channel, band->band);
2121 notify_channel = ieee80211_get_channel(wiphy, freq);
2123 notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2124 notify_capability = le16_to_cpu(bi->capability);
2125 notify_interval = le16_to_cpu(bi->beacon_period);
2126 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2127 notify_ielen = le32_to_cpu(bi->ie_length);
2128 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2130 WL_CONN("channel: %d(%d)\n", channel, freq);
2131 WL_CONN("capability: %X\n", notify_capability);
2132 WL_CONN("beacon interval: %d\n", notify_interval);
2133 WL_CONN("signal: %d\n", notify_signal);
2134 WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2136 cfg80211_inform_bss(wiphy, notify_channel, bssid,
2137 notify_timestamp, notify_capability, notify_interval,
2138 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2149 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2151 return cfg_priv->conf->mode == WL_MODE_IBSS;
2154 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2156 struct brcmf_bss_info *bi;
2157 struct brcmf_ssid *ssid;
2158 struct brcmu_tlv *tim;
2159 u16 beacon_interval;
2165 WL_TRACE("Enter\n");
2166 if (brcmf_is_ibssmode(cfg_priv))
2169 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2171 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2172 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2173 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2175 WL_ERR("Could not get bss info %d\n", err);
2176 goto update_bss_info_out;
2179 bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2180 err = brcmf_inform_single_bss(cfg_priv, bi);
2182 goto update_bss_info_out;
2184 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2185 ie_len = le32_to_cpu(bi->ie_length);
2186 beacon_interval = le16_to_cpu(bi->beacon_period);
2188 tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2190 dtim_period = tim->data[1];
2193 * active scan was done so we could not get dtim
2194 * information out of probe response.
2195 * so we speficially query dtim information to dongle.
2198 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2199 "dtim_assoc", &var);
2201 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2202 goto update_bss_info_out;
2204 dtim_period = (u8)var;
2207 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2208 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2210 update_bss_info_out:
2215 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2217 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2218 struct brcmf_ssid ssid;
2220 if (cfg_priv->iscan_on) {
2221 iscan->state = WL_ISCAN_STATE_IDLE;
2223 if (iscan->timer_on) {
2224 del_timer_sync(&iscan->timer);
2225 iscan->timer_on = 0;
2228 cancel_work_sync(&iscan->work);
2230 /* Abort iscan running in FW */
2231 memset(&ssid, 0, sizeof(ssid));
2232 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2236 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2239 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2240 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2242 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2243 WL_ERR("Scan complete while device not scanning\n");
2246 if (cfg_priv->scan_request) {
2247 WL_SCAN("ISCAN Completed scan: %s\n",
2248 aborted ? "Aborted" : "Done");
2249 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2250 brcmf_set_mpc(ndev, 1);
2251 cfg_priv->scan_request = NULL;
2253 cfg_priv->iscan_kickstart = false;
2256 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2258 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2259 WL_SCAN("wake up iscan\n");
2260 schedule_work(&iscan->work);
2268 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2269 struct brcmf_scan_results **bss_list)
2271 struct brcmf_iscan_results list;
2272 struct brcmf_scan_results *results;
2273 struct brcmf_scan_results_le *results_le;
2274 struct brcmf_iscan_results *list_buf;
2277 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2278 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2279 results = &list_buf->results;
2280 results_le = &list_buf->results_le;
2281 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2282 results->version = 0;
2285 memset(&list, 0, sizeof(list));
2286 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2287 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2288 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2289 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2291 WL_ERR("error (%d)\n", err);
2294 results->buflen = le32_to_cpu(results_le->buflen);
2295 results->version = le32_to_cpu(results_le->version);
2296 results->count = le32_to_cpu(results_le->count);
2297 WL_SCAN("results->count = %d\n", results_le->count);
2298 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2299 *status = le32_to_cpu(list_buf->status_le);
2300 WL_SCAN("status = %d\n", *status);
2301 *bss_list = results;
2306 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2308 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2311 iscan->state = WL_ISCAN_STATE_IDLE;
2312 brcmf_inform_bss(cfg_priv);
2313 brcmf_notify_iscan_complete(iscan, false);
2318 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2320 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2323 /* Reschedule the timer */
2324 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2325 iscan->timer_on = 1;
2330 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2332 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2335 brcmf_inform_bss(cfg_priv);
2336 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2337 /* Reschedule the timer */
2338 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2339 iscan->timer_on = 1;
2344 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2346 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2349 iscan->state = WL_ISCAN_STATE_IDLE;
2350 brcmf_notify_iscan_complete(iscan, true);
2355 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2357 struct brcmf_cfg80211_iscan_ctrl *iscan =
2358 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2360 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2361 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2362 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2364 if (iscan->timer_on) {
2365 del_timer_sync(&iscan->timer);
2366 iscan->timer_on = 0;
2369 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2370 status = BRCMF_SCAN_RESULTS_ABORTED;
2371 WL_ERR("Abort iscan\n");
2374 el->handler[status](cfg_priv);
2377 static void brcmf_iscan_timer(unsigned long data)
2379 struct brcmf_cfg80211_iscan_ctrl *iscan =
2380 (struct brcmf_cfg80211_iscan_ctrl *)data;
2383 iscan->timer_on = 0;
2384 WL_SCAN("timer expired\n");
2385 brcmf_wakeup_iscan(iscan);
2389 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2391 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2393 if (cfg_priv->iscan_on) {
2394 iscan->state = WL_ISCAN_STATE_IDLE;
2395 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2401 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2403 memset(el, 0, sizeof(*el));
2404 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2405 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2406 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2407 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2408 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2411 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2413 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2416 if (cfg_priv->iscan_on) {
2417 iscan->ndev = cfg_to_ndev(cfg_priv);
2418 brcmf_init_iscan_eloop(&iscan->el);
2419 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2420 init_timer(&iscan->timer);
2421 iscan->timer.data = (unsigned long) iscan;
2422 iscan->timer.function = brcmf_iscan_timer;
2423 err = brcmf_invoke_iscan(cfg_priv);
2425 iscan->data = cfg_priv;
2431 static void brcmf_delay(u32 ms)
2433 if (ms < 1000 / HZ) {
2441 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2443 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2446 * Check for WL_STATUS_READY before any function call which
2447 * could result is bus access. Don't block the resume for
2448 * any driver error conditions
2450 WL_TRACE("Enter\n");
2452 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2453 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2459 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2460 struct cfg80211_wowlan *wow)
2462 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2463 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2465 WL_TRACE("Enter\n");
2468 * Check for WL_STATUS_READY before any function call which
2469 * could result is bus access. Don't block the suspend for
2470 * any driver error conditions
2474 * While going to suspend if associated with AP disassociate
2475 * from AP to save power while system is in suspended state
2477 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2478 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2479 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2480 WL_INFO("Disassociating from AP"
2481 " while entering suspend state\n");
2482 brcmf_link_down(cfg_priv);
2485 * Make sure WPA_Supplicant receives all the event
2486 * generated due to DISASSOC call to the fw to keep
2487 * the state fw and WPA_Supplicant state consistent
2492 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2493 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2494 brcmf_term_iscan(cfg_priv);
2496 if (cfg_priv->scan_request) {
2497 /* Indidate scan abort to cfg80211 layer */
2498 WL_INFO("Terminating scan in progress\n");
2499 cfg80211_scan_done(cfg_priv->scan_request, true);
2500 cfg_priv->scan_request = NULL;
2502 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2503 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2505 /* Turn off watchdog timer */
2506 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2507 WL_INFO("Enable MPC\n");
2508 brcmf_set_mpc(ndev, 1);
2517 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2519 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2522 buflen = brcmu_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2526 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2531 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2534 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2538 len = brcmu_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2541 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2544 WL_ERR("error (%d)\n", err);
2547 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2553 brcmf_update_pmklist(struct net_device *ndev,
2554 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2559 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2561 WL_CONN("No of elements %d\n", pmkid_len);
2562 for (i = 0; i < pmkid_len; i++) {
2563 WL_CONN("PMKID[%d]: %pM =\n", i,
2564 &pmk_list->pmkids.pmkid[i].BSSID);
2565 for (j = 0; j < WLAN_PMKID_LEN; j++)
2566 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2570 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2577 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2578 struct cfg80211_pmksa *pmksa)
2580 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2581 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2586 WL_TRACE("Enter\n");
2587 if (!check_sys_up(wiphy))
2590 pmkid_len = le32_to_cpu(pmkids->npmkid);
2591 for (i = 0; i < pmkid_len; i++)
2592 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2594 if (i < WL_NUM_PMKIDS_MAX) {
2595 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2596 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2597 if (i == pmkid_len) {
2599 pmkids->npmkid = cpu_to_le32(pmkid_len);
2604 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2605 pmkids->pmkid[pmkid_len].BSSID);
2606 for (i = 0; i < WLAN_PMKID_LEN; i++)
2607 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2609 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2616 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2617 struct cfg80211_pmksa *pmksa)
2619 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2620 struct pmkid_list pmkid;
2624 WL_TRACE("Enter\n");
2625 if (!check_sys_up(wiphy))
2628 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2629 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2631 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2632 &pmkid.pmkid[0].BSSID);
2633 for (i = 0; i < WLAN_PMKID_LEN; i++)
2634 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2636 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2637 for (i = 0; i < pmkid_len; i++)
2639 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2644 && (i < pmkid_len)) {
2645 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2646 sizeof(struct pmkid));
2647 for (; i < (pmkid_len - 1); i++) {
2648 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2649 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2651 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2652 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2655 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2659 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2667 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2669 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2672 WL_TRACE("Enter\n");
2673 if (!check_sys_up(wiphy))
2676 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2677 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2684 static struct cfg80211_ops wl_cfg80211_ops = {
2685 .change_virtual_intf = brcmf_cfg80211_change_iface,
2686 .scan = brcmf_cfg80211_scan,
2687 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2688 .join_ibss = brcmf_cfg80211_join_ibss,
2689 .leave_ibss = brcmf_cfg80211_leave_ibss,
2690 .get_station = brcmf_cfg80211_get_station,
2691 .set_tx_power = brcmf_cfg80211_set_tx_power,
2692 .get_tx_power = brcmf_cfg80211_get_tx_power,
2693 .add_key = brcmf_cfg80211_add_key,
2694 .del_key = brcmf_cfg80211_del_key,
2695 .get_key = brcmf_cfg80211_get_key,
2696 .set_default_key = brcmf_cfg80211_config_default_key,
2697 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2698 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2699 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2700 .connect = brcmf_cfg80211_connect,
2701 .disconnect = brcmf_cfg80211_disconnect,
2702 .suspend = brcmf_cfg80211_suspend,
2703 .resume = brcmf_cfg80211_resume,
2704 .set_pmksa = brcmf_cfg80211_set_pmksa,
2705 .del_pmksa = brcmf_cfg80211_del_pmksa,
2706 .flush_pmksa = brcmf_cfg80211_flush_pmksa
2709 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2715 return NL80211_IFTYPE_STATION;
2717 return NL80211_IFTYPE_ADHOC;
2719 return NL80211_IFTYPE_UNSPECIFIED;
2725 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2726 struct device *ndev)
2728 struct wireless_dev *wdev;
2731 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2733 return ERR_PTR(-ENOMEM);
2736 wiphy_new(&wl_cfg80211_ops,
2737 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2739 WL_ERR("Couldn not allocate wiphy device\n");
2743 set_wiphy_dev(wdev->wiphy, ndev);
2744 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2745 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2746 wdev->wiphy->interface_modes =
2747 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2748 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2749 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2750 * it as 11a by default.
2751 * This will be updated with
2754 * if phy has 11n capability
2756 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2757 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2758 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2759 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2763 err = wiphy_register(wdev->wiphy);
2765 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2766 goto wiphy_register_out;
2771 wiphy_free(wdev->wiphy);
2776 return ERR_PTR(err);
2779 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2781 struct wireless_dev *wdev = cfg_priv->wdev;
2784 WL_ERR("wdev is invalid\n");
2787 wiphy_unregister(wdev->wiphy);
2788 wiphy_free(wdev->wiphy);
2790 cfg_priv->wdev = NULL;
2793 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2794 const struct brcmf_event_msg *e)
2796 u32 event = be32_to_cpu(e->event_type);
2797 u32 status = be32_to_cpu(e->status);
2799 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2800 WL_CONN("Processing set ssid\n");
2801 cfg_priv->link_up = true;
2808 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2809 const struct brcmf_event_msg *e)
2811 u32 event = be32_to_cpu(e->event_type);
2812 u16 flags = be16_to_cpu(e->flags);
2814 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2815 WL_CONN("Processing link down\n");
2821 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2822 const struct brcmf_event_msg *e)
2824 u32 event = be32_to_cpu(e->event_type);
2825 u32 status = be32_to_cpu(e->status);
2827 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2828 WL_CONN("Processing Link %s & no network found\n",
2829 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2834 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2835 WL_CONN("Processing connecting & no network found\n");
2842 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2844 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2846 kfree(conn_info->req_ie);
2847 conn_info->req_ie = NULL;
2848 conn_info->req_ie_len = 0;
2849 kfree(conn_info->resp_ie);
2850 conn_info->resp_ie = NULL;
2851 conn_info->resp_ie_len = 0;
2854 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2856 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2857 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2858 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2863 brcmf_clear_assoc_ies(cfg_priv);
2865 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2868 WL_ERR("could not get assoc info (%d)\n", err);
2872 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2873 req_len = le32_to_cpu(assoc_info->req_len);
2874 resp_len = le32_to_cpu(assoc_info->resp_len);
2876 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2877 cfg_priv->extra_buf,
2880 WL_ERR("could not get assoc req (%d)\n", err);
2883 conn_info->req_ie_len = req_len;
2885 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2888 conn_info->req_ie_len = 0;
2889 conn_info->req_ie = NULL;
2892 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2893 cfg_priv->extra_buf,
2896 WL_ERR("could not get assoc resp (%d)\n", err);
2899 conn_info->resp_ie_len = resp_len;
2900 conn_info->resp_ie =
2901 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2904 conn_info->resp_ie_len = 0;
2905 conn_info->resp_ie = NULL;
2907 WL_CONN("req len (%d) resp len (%d)\n",
2908 conn_info->req_ie_len, conn_info->resp_ie_len);
2914 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2915 struct net_device *ndev,
2916 const struct brcmf_event_msg *e)
2918 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2919 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2920 struct brcmf_channel_info_le channel_le;
2921 struct ieee80211_channel *notify_channel;
2922 struct ieee80211_supported_band *band;
2927 WL_TRACE("Enter\n");
2929 brcmf_get_assoc_ies(cfg_priv);
2930 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2931 brcmf_update_bss_info(cfg_priv);
2933 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2934 sizeof(channel_le));
2936 target_channel = le32_to_cpu(channel_le.target_channel);
2937 WL_CONN("Roamed to channel %d\n", target_channel);
2939 if (target_channel <= CH_MAX_2G_CHANNEL)
2940 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2942 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2944 freq = ieee80211_channel_to_frequency(target_channel, band->band);
2945 notify_channel = ieee80211_get_channel(wiphy, freq);
2947 cfg80211_roamed(ndev, notify_channel,
2948 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2949 conn_info->req_ie, conn_info->req_ie_len,
2950 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2951 WL_CONN("Report roaming result\n");
2953 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2959 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2960 struct net_device *ndev, const struct brcmf_event_msg *e,
2963 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2966 WL_TRACE("Enter\n");
2968 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2970 brcmf_get_assoc_ies(cfg_priv);
2971 brcmf_update_prof(cfg_priv, NULL, &e->addr,
2973 brcmf_update_bss_info(cfg_priv);
2975 cfg80211_connect_result(ndev,
2976 (u8 *)brcmf_read_prof(cfg_priv,
2979 conn_info->req_ie_len,
2981 conn_info->resp_ie_len,
2982 completed ? WLAN_STATUS_SUCCESS :
2983 WLAN_STATUS_AUTH_TIMEOUT,
2986 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2987 WL_CONN("Report connect result - connection %s\n",
2988 completed ? "succeeded" : "failed");
2995 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2996 struct net_device *ndev,
2997 const struct brcmf_event_msg *e, void *data)
3001 if (brcmf_is_linkup(cfg_priv, e)) {
3002 WL_CONN("Linkup\n");
3003 if (brcmf_is_ibssmode(cfg_priv)) {
3004 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3006 wl_inform_ibss(cfg_priv, ndev, e->addr);
3007 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3008 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3009 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3011 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3012 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3013 WL_CONN("Linkdown\n");
3014 if (brcmf_is_ibssmode(cfg_priv)) {
3015 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3016 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3018 brcmf_link_down(cfg_priv);
3020 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3021 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3022 &cfg_priv->status)) {
3023 cfg80211_disconnected(ndev, 0, NULL, 0,
3025 brcmf_link_down(cfg_priv);
3028 brcmf_init_prof(cfg_priv->profile);
3029 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3030 if (brcmf_is_ibssmode(cfg_priv))
3031 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3033 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3040 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3041 struct net_device *ndev,
3042 const struct brcmf_event_msg *e, void *data)
3045 u32 event = be32_to_cpu(e->event_type);
3046 u32 status = be32_to_cpu(e->status);
3048 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3049 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3050 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3052 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3059 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3060 struct net_device *ndev,
3061 const struct brcmf_event_msg *e, void *data)
3063 u16 flags = be16_to_cpu(e->flags);
3064 enum nl80211_key_type key_type;
3066 if (flags & BRCMF_EVENT_MSG_GROUP)
3067 key_type = NL80211_KEYTYPE_GROUP;
3069 key_type = NL80211_KEYTYPE_PAIRWISE;
3071 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3078 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3079 struct net_device *ndev,
3080 const struct brcmf_event_msg *e, void *data)
3082 struct brcmf_channel_info_le channel_inform_le;
3083 struct brcmf_scan_results_le *bss_list_le;
3084 u32 len = WL_SCAN_BUF_MAX;
3086 bool scan_abort = false;
3089 WL_TRACE("Enter\n");
3091 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3093 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3096 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3097 WL_ERR("Scan complete while device not scanning\n");
3103 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3104 sizeof(channel_inform_le));
3106 WL_ERR("scan busy (%d)\n", err);
3110 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3112 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3113 cfg_priv->bss_list = cfg_priv->scan_results;
3114 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3116 memset(cfg_priv->scan_results, 0, len);
3117 bss_list_le->buflen = cpu_to_le32(len);
3118 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3119 cfg_priv->scan_results, len);
3121 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3126 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3127 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3128 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3130 err = brcmf_inform_bss(cfg_priv);
3137 if (cfg_priv->scan_request) {
3138 WL_SCAN("calling cfg80211_scan_done\n");
3139 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3140 brcmf_set_mpc(ndev, 1);
3141 cfg_priv->scan_request = NULL;
3149 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3151 conf->mode = (u32)-1;
3152 conf->frag_threshold = (u32)-1;
3153 conf->rts_threshold = (u32)-1;
3154 conf->retry_short = (u32)-1;
3155 conf->retry_long = (u32)-1;
3156 conf->tx_power = -1;
3159 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3161 memset(el, 0, sizeof(*el));
3162 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3163 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3164 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3165 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3166 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3169 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3171 kfree(cfg_priv->scan_results);
3172 cfg_priv->scan_results = NULL;
3173 kfree(cfg_priv->bss_info);
3174 cfg_priv->bss_info = NULL;
3175 kfree(cfg_priv->conf);
3176 cfg_priv->conf = NULL;
3177 kfree(cfg_priv->profile);
3178 cfg_priv->profile = NULL;
3179 kfree(cfg_priv->scan_req_int);
3180 cfg_priv->scan_req_int = NULL;
3181 kfree(cfg_priv->dcmd_buf);
3182 cfg_priv->dcmd_buf = NULL;
3183 kfree(cfg_priv->extra_buf);
3184 cfg_priv->extra_buf = NULL;
3185 kfree(cfg_priv->iscan);
3186 cfg_priv->iscan = NULL;
3187 kfree(cfg_priv->pmk_list);
3188 cfg_priv->pmk_list = NULL;
3191 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3193 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3194 if (!cfg_priv->scan_results)
3195 goto init_priv_mem_out;
3196 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3197 if (!cfg_priv->conf)
3198 goto init_priv_mem_out;
3199 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3200 if (!cfg_priv->profile)
3201 goto init_priv_mem_out;
3202 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3203 if (!cfg_priv->bss_info)
3204 goto init_priv_mem_out;
3205 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3207 if (!cfg_priv->scan_req_int)
3208 goto init_priv_mem_out;
3209 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3210 if (!cfg_priv->dcmd_buf)
3211 goto init_priv_mem_out;
3212 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3213 if (!cfg_priv->extra_buf)
3214 goto init_priv_mem_out;
3215 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3216 if (!cfg_priv->iscan)
3217 goto init_priv_mem_out;
3218 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3219 if (!cfg_priv->pmk_list)
3220 goto init_priv_mem_out;
3225 brcmf_deinit_priv_mem(cfg_priv);
3231 * retrieve first queued event from head
3234 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3235 struct brcmf_cfg80211_priv *cfg_priv)
3237 struct brcmf_cfg80211_event_q *e = NULL;
3239 spin_lock_irq(&cfg_priv->evt_q_lock);
3240 if (!list_empty(&cfg_priv->evt_q_list)) {
3241 e = list_first_entry(&cfg_priv->evt_q_list,
3242 struct brcmf_cfg80211_event_q, evt_q_list);
3243 list_del(&e->evt_q_list);
3245 spin_unlock_irq(&cfg_priv->evt_q_lock);
3251 ** push event to tail of the queue
3255 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3256 const struct brcmf_event_msg *msg)
3258 struct brcmf_cfg80211_event_q *e;
3261 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3266 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3268 spin_lock_irq(&cfg_priv->evt_q_lock);
3269 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3270 spin_unlock_irq(&cfg_priv->evt_q_lock);
3275 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3280 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3282 struct brcmf_cfg80211_priv *cfg_priv =
3283 container_of(work, struct brcmf_cfg80211_priv,
3285 struct brcmf_cfg80211_event_q *e;
3287 e = brcmf_deq_event(cfg_priv);
3289 WL_ERR("event queue empty...\n");
3294 WL_INFO("event type (%d)\n", e->etype);
3295 if (cfg_priv->el.handler[e->etype])
3296 cfg_priv->el.handler[e->etype](cfg_priv,
3297 cfg_to_ndev(cfg_priv),
3298 &e->emsg, e->edata);
3300 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3302 } while ((e = brcmf_deq_event(cfg_priv)));
3306 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3308 spin_lock_init(&cfg_priv->evt_q_lock);
3309 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3312 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3314 struct brcmf_cfg80211_event_q *e;
3316 spin_lock_irq(&cfg_priv->evt_q_lock);
3317 while (!list_empty(&cfg_priv->evt_q_list)) {
3318 e = list_first_entry(&cfg_priv->evt_q_list,
3319 struct brcmf_cfg80211_event_q, evt_q_list);
3320 list_del(&e->evt_q_list);
3323 spin_unlock_irq(&cfg_priv->evt_q_lock);
3326 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3330 cfg_priv->scan_request = NULL;
3331 cfg_priv->pwr_save = true;
3332 cfg_priv->iscan_on = true; /* iscan on & off switch.
3333 we enable iscan per default */
3334 cfg_priv->roam_on = true; /* roam on & off switch.
3335 we enable roam per default */
3337 cfg_priv->iscan_kickstart = false;
3338 cfg_priv->active_scan = true; /* we do active scan for
3339 specific scan per default */
3340 cfg_priv->dongle_up = false; /* dongle is not up yet */
3341 brcmf_init_eq(cfg_priv);
3342 err = brcmf_init_priv_mem(cfg_priv);
3345 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3346 brcmf_init_eloop_handler(&cfg_priv->el);
3347 mutex_init(&cfg_priv->usr_sync);
3348 err = brcmf_init_iscan(cfg_priv);
3351 brcmf_init_conf(cfg_priv->conf);
3352 brcmf_init_prof(cfg_priv->profile);
3353 brcmf_link_down(cfg_priv);
3358 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3360 cancel_work_sync(&cfg_priv->event_work);
3361 cfg_priv->dongle_up = false; /* dongle down */
3362 brcmf_flush_eq(cfg_priv);
3363 brcmf_link_down(cfg_priv);
3364 brcmf_term_iscan(cfg_priv);
3365 brcmf_deinit_priv_mem(cfg_priv);
3368 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3369 struct device *busdev,
3372 struct wireless_dev *wdev;
3373 struct brcmf_cfg80211_priv *cfg_priv;
3374 struct brcmf_cfg80211_iface *ci;
3375 struct brcmf_cfg80211_dev *cfg_dev;
3379 WL_ERR("ndev is invalid\n");
3382 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3386 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3392 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3393 cfg_priv = wdev_to_cfg(wdev);
3394 cfg_priv->wdev = wdev;
3395 cfg_priv->pub = data;
3396 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3397 ci->cfg_priv = cfg_priv;
3398 ndev->ieee80211_ptr = wdev;
3399 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3400 wdev->netdev = ndev;
3401 err = wl_init_priv(cfg_priv);
3403 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3404 goto cfg80211_attach_out;
3406 brcmf_set_drvdata(cfg_dev, ci);
3410 cfg80211_attach_out:
3411 brcmf_free_wdev(cfg_priv);
3416 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3418 struct brcmf_cfg80211_priv *cfg_priv;
3420 cfg_priv = brcmf_priv_get(cfg_dev);
3422 wl_deinit_priv(cfg_priv);
3423 brcmf_free_wdev(cfg_priv);
3424 brcmf_set_drvdata(cfg_dev, NULL);
3429 brcmf_cfg80211_event(struct net_device *ndev,
3430 const struct brcmf_event_msg *e, void *data)
3432 u32 event_type = be32_to_cpu(e->event_type);
3433 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3435 if (!brcmf_enq_event(cfg_priv, event_type, e))
3436 schedule_work(&cfg_priv->event_work);
3439 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3445 case NL80211_IFTYPE_MONITOR:
3446 case NL80211_IFTYPE_WDS:
3447 WL_ERR("type (%d) : currently we do not support this mode\n",
3451 case NL80211_IFTYPE_ADHOC:
3454 case NL80211_IFTYPE_STATION:
3459 WL_ERR("invalid type (%d)\n", iftype);
3462 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3464 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3471 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3473 /* Room for "event_msgs" + '\0' + bitvec */
3474 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3475 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3478 WL_TRACE("Enter\n");
3480 /* Setup event_msgs */
3481 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3483 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3485 WL_ERR("Get event_msgs error (%d)\n", err);
3486 goto dongle_eventmsg_out;
3488 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3490 setbit(eventmask, BRCMF_E_SET_SSID);
3491 setbit(eventmask, BRCMF_E_ROAM);
3492 setbit(eventmask, BRCMF_E_PRUNE);
3493 setbit(eventmask, BRCMF_E_AUTH);
3494 setbit(eventmask, BRCMF_E_REASSOC);
3495 setbit(eventmask, BRCMF_E_REASSOC_IND);
3496 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3497 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3498 setbit(eventmask, BRCMF_E_DISASSOC);
3499 setbit(eventmask, BRCMF_E_JOIN);
3500 setbit(eventmask, BRCMF_E_ASSOC_IND);
3501 setbit(eventmask, BRCMF_E_PSK_SUP);
3502 setbit(eventmask, BRCMF_E_LINK);
3503 setbit(eventmask, BRCMF_E_NDIS_LINK);
3504 setbit(eventmask, BRCMF_E_MIC_ERROR);
3505 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3506 setbit(eventmask, BRCMF_E_TXFAIL);
3507 setbit(eventmask, BRCMF_E_JOIN_START);
3508 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3510 brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3512 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3514 WL_ERR("Set event_msgs error (%d)\n", err);
3515 goto dongle_eventmsg_out;
3518 dongle_eventmsg_out:
3524 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3528 __le32 roamtrigger[2];
3529 __le32 roam_delta[2];
3534 * Setup timeout if Beacons are lost and roam is
3535 * off to report link down
3538 bcn_to_le = cpu_to_le32(bcn_timeout);
3539 brcmu_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3540 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3541 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3542 iovbuf, sizeof(iovbuf));
3544 WL_ERR("bcn_timeout error (%d)\n", err);
3545 goto dongle_rom_out;
3550 * Enable/Disable built-in roaming to allow supplicant
3551 * to take care of roaming
3553 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3554 roamvar_le = cpu_to_le32(roamvar);
3555 brcmu_mkiovar("roam_off", (char *)&roamvar_le,
3556 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3557 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3559 WL_ERR("roam_off error (%d)\n", err);
3560 goto dongle_rom_out;
3563 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3564 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3565 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3566 (void *)roamtrigger, sizeof(roamtrigger));
3568 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3569 goto dongle_rom_out;
3572 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3573 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3574 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3575 (void *)roam_delta, sizeof(roam_delta));
3577 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3578 goto dongle_rom_out;
3586 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3587 s32 scan_unassoc_time, s32 scan_passive_time)
3590 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3591 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3592 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3594 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3595 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3597 if (err == -EOPNOTSUPP)
3598 WL_INFO("Scan assoc time is not supported\n");
3600 WL_ERR("Scan assoc time error (%d)\n", err);
3601 goto dongle_scantime_out;
3603 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3604 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3606 if (err == -EOPNOTSUPP)
3607 WL_INFO("Scan unassoc time is not supported\n");
3609 WL_ERR("Scan unassoc time error (%d)\n", err);
3610 goto dongle_scantime_out;
3613 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3614 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3616 if (err == -EOPNOTSUPP)
3617 WL_INFO("Scan passive time is not supported\n");
3619 WL_ERR("Scan passive time error (%d)\n", err);
3620 goto dongle_scantime_out;
3623 dongle_scantime_out:
3627 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3629 struct wiphy *wiphy;
3634 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3635 &phy_list, sizeof(phy_list));
3637 WL_ERR("error (%d)\n", err);
3641 phy = ((char *)&phy_list)[1];
3642 WL_INFO("%c phy\n", phy);
3643 if (phy == 'n' || phy == 'a') {
3644 wiphy = cfg_to_wiphy(cfg_priv);
3645 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3651 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3653 return wl_update_wiphybands(cfg_priv);
3656 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3658 struct net_device *ndev;
3659 struct wireless_dev *wdev;
3663 if (cfg_priv->dongle_up)
3666 ndev = cfg_to_ndev(cfg_priv);
3667 wdev = ndev->ieee80211_ptr;
3669 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3670 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3672 err = brcmf_dongle_eventmsg(ndev);
3674 goto default_conf_out;
3676 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3677 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3679 goto default_conf_out;
3680 WL_INFO("power save set to %s\n",
3681 (power_mode ? "enabled" : "disabled"));
3683 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3686 goto default_conf_out;
3687 err = brcmf_dongle_mode(ndev, wdev->iftype);
3688 if (err && err != -EINPROGRESS)
3689 goto default_conf_out;
3690 err = brcmf_dongle_probecap(cfg_priv);
3692 goto default_conf_out;
3694 /* -EINPROGRESS: Call commit handler */
3698 cfg_priv->dongle_up = true;
3704 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3706 char buf[10+IFNAMSIZ];
3710 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3711 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3712 cfg_to_wiphy(cfg_priv)->debugfsdir);
3714 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3715 (u16 *)&cfg_priv->profile->beacon_interval);
3721 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3722 (u8 *)&cfg_priv->profile->dtim_period);
3732 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3734 debugfs_remove_recursive(cfg_priv->debugfsdir);
3735 cfg_priv->debugfsdir = NULL;
3738 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3742 set_bit(WL_STATUS_READY, &cfg_priv->status);
3744 brcmf_debugfs_add_netdev_params(cfg_priv);
3746 err = brcmf_config_dongle(cfg_priv);
3750 brcmf_invoke_iscan(cfg_priv);
3755 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3758 * While going down, if associated with AP disassociate
3759 * from AP to save power
3761 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3762 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3763 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3764 WL_INFO("Disassociating from AP");
3765 brcmf_link_down(cfg_priv);
3767 /* Make sure WPA_Supplicant receives all the event
3768 generated due to DISASSOC call to the fw to keep
3769 the state fw and WPA_Supplicant state consistent
3774 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3775 brcmf_term_iscan(cfg_priv);
3776 if (cfg_priv->scan_request) {
3777 cfg80211_scan_done(cfg_priv->scan_request, true);
3778 /* May need to perform this to cover rmmod */
3779 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3780 cfg_priv->scan_request = NULL;
3782 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3783 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3784 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3786 brcmf_debugfs_remove_netdev(cfg_priv);
3791 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3793 struct brcmf_cfg80211_priv *cfg_priv;
3796 cfg_priv = brcmf_priv_get(cfg_dev);
3797 mutex_lock(&cfg_priv->usr_sync);
3798 err = __brcmf_cfg80211_up(cfg_priv);
3799 mutex_unlock(&cfg_priv->usr_sync);
3804 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3806 struct brcmf_cfg80211_priv *cfg_priv;
3809 cfg_priv = brcmf_priv_get(cfg_dev);
3810 mutex_lock(&cfg_priv->usr_sync);
3811 err = __brcmf_cfg80211_down(cfg_priv);
3812 mutex_unlock(&cfg_priv->usr_sync);
3817 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3820 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3823 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3824 WL_ERR("ei crosses buffer boundary\n");
3827 ie->buf[ie->offset] = t;
3828 ie->buf[ie->offset + 1] = l;
3829 memcpy(&ie->buf[ie->offset + 2], v, l);
3830 ie->offset += l + 2;