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 brcmf_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 brcmf_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_iscan(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
;
694 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
695 struct cfg80211_scan_request
*request
)
703 struct ieee80211_channel
*req_channel
;
705 struct brcmf_ssid_le ssid_le
;
707 memcpy(params_le
->bssid
, ether_bcast
, ETH_ALEN
);
708 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
709 params_le
->scan_type
= 0;
710 params_le
->channel_num
= 0;
711 params_le
->nprobes
= cpu_to_le32(-1);
712 params_le
->active_time
= cpu_to_le32(-1);
713 params_le
->passive_time
= cpu_to_le32(-1);
714 params_le
->home_time
= cpu_to_le32(-1);
715 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
717 /* if request is null exit so it will be all channel broadcast scan */
721 n_ssids
= request
->n_ssids
;
722 n_channels
= request
->n_channels
;
723 /* Copy channel array if applicable */
724 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels
);
725 if (n_channels
> 0) {
726 for (i
= 0; i
< n_channels
; i
++) {
728 req_channel
= request
->channels
[i
];
729 channel
= ieee80211_frequency_to_channel(
730 req_channel
->center_freq
);
731 if (req_channel
->band
== IEEE80211_BAND_2GHZ
)
732 chanspec
|= WL_CHANSPEC_BAND_2G
;
734 chanspec
|= WL_CHANSPEC_BAND_5G
;
736 if (req_channel
->flags
& IEEE80211_CHAN_NO_HT40
) {
737 chanspec
|= WL_CHANSPEC_BW_20
;
738 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
740 chanspec
|= WL_CHANSPEC_BW_40
;
741 if (req_channel
->flags
&
742 IEEE80211_CHAN_NO_HT40PLUS
)
743 chanspec
|= WL_CHANSPEC_CTL_SB_LOWER
;
745 chanspec
|= WL_CHANSPEC_CTL_SB_UPPER
;
748 chanspec
|= (channel
& WL_CHANSPEC_CHAN_MASK
);
749 WL_SCAN("Chan : %d, Channel spec: %x\n",
751 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
754 WL_SCAN("Scanning all channels\n");
756 /* Copy ssid array if applicable */
757 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids
);
759 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
760 n_channels
* sizeof(u16
);
761 offset
= roundup(offset
, sizeof(u32
));
762 ptr
= (char *)params_le
+ offset
;
763 for (i
= 0; i
< n_ssids
; i
++) {
764 memset(&ssid_le
, 0, sizeof(ssid_le
));
766 cpu_to_le32(request
->ssids
[i
].ssid_len
);
767 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
768 request
->ssids
[i
].ssid_len
);
769 if (!ssid_le
.SSID_len
)
770 WL_SCAN("%d: Broadcast scan\n", i
);
772 WL_SCAN("%d: scan for %s size =%d\n", i
,
773 ssid_le
.SSID
, ssid_le
.SSID_len
);
774 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
775 ptr
+= sizeof(ssid_le
);
778 WL_SCAN("Broadcast scan %p\n", request
->ssids
);
779 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
780 WL_SCAN("SSID %s len=%d\n", params_le
->ssid_le
.SSID
,
781 request
->ssids
->ssid_len
);
782 params_le
->ssid_le
.SSID_len
=
783 cpu_to_le32(request
->ssids
->ssid_len
);
784 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
785 request
->ssids
->ssid_len
);
788 /* Adding mask to channel numbers */
789 params_le
->channel_num
=
790 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
791 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
795 brcmf_notify_escan_complete(struct brcmf_cfg80211_priv
*cfg_priv
,
796 struct net_device
*ndev
,
797 bool aborted
, bool fw_abort
)
799 struct brcmf_scan_params_le params_le
;
800 struct cfg80211_scan_request
*scan_request
;
805 /* clear scan request, because the FW abort can cause a second call */
806 /* to this functon and might cause a double cfg80211_scan_done */
807 scan_request
= cfg_priv
->scan_request
;
808 cfg_priv
->scan_request
= NULL
;
810 if (timer_pending(&cfg_priv
->escan_timeout
))
811 del_timer_sync(&cfg_priv
->escan_timeout
);
814 /* Do a scan abort to stop the driver's scan engine */
815 WL_SCAN("ABORT scan in firmware\n");
816 memset(¶ms_le
, 0, sizeof(params_le
));
817 memcpy(params_le
.bssid
, ether_bcast
, ETH_ALEN
);
818 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
819 params_le
.scan_type
= 0;
820 params_le
.channel_num
= cpu_to_le32(1);
821 params_le
.nprobes
= cpu_to_le32(1);
822 params_le
.active_time
= cpu_to_le32(-1);
823 params_le
.passive_time
= cpu_to_le32(-1);
824 params_le
.home_time
= cpu_to_le32(-1);
825 /* Scan is aborted by setting channel_list[0] to -1 */
826 params_le
.channel_list
[0] = cpu_to_le16(-1);
827 /* E-Scan (or anyother type) can be aborted by SCAN */
828 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SCAN
, ¶ms_le
,
831 WL_ERR("Scan abort failed\n");
834 WL_SCAN("ESCAN Completed scan: %s\n",
835 aborted
? "Aborted" : "Done");
836 cfg80211_scan_done(scan_request
, aborted
);
837 brcmf_set_mpc(ndev
, 1);
839 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
)) {
840 WL_ERR("Scan complete while device not scanning\n");
848 brcmf_run_escan(struct brcmf_cfg80211_priv
*cfg_priv
, struct net_device
*ndev
,
849 struct cfg80211_scan_request
*request
, u16 action
)
851 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
852 offsetof(struct brcmf_escan_params_le
, params_le
);
853 struct brcmf_escan_params_le
*params
;
856 WL_SCAN("E-SCAN START\n");
858 if (request
!= NULL
) {
859 /* Allocate space for populating ssids in struct */
860 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
862 /* Allocate space for populating ssids in struct */
863 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
866 params
= kzalloc(params_size
, GFP_KERNEL
);
871 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
872 brcmf_escan_prep(¶ms
->params_le
, request
);
873 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
874 params
->action
= cpu_to_le16(action
);
875 params
->sync_id
= cpu_to_le16(0x1234);
877 err
= brcmf_dev_iovar_setbuf(ndev
, "escan", params
, params_size
,
878 cfg_priv
->escan_ioctl_buf
, BRCMF_DCMD_MEDLEN
);
881 WL_INFO("system busy : escan canceled\n");
883 WL_ERR("error (%d)\n", err
);
892 brcmf_do_escan(struct brcmf_cfg80211_priv
*cfg_priv
, struct wiphy
*wiphy
,
893 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
897 struct brcmf_scan_results
*results
;
900 cfg_priv
->escan_info
.ndev
= ndev
;
901 cfg_priv
->escan_info
.wiphy
= wiphy
;
902 cfg_priv
->escan_info
.escan_state
= WL_ESCAN_STATE_SCANNING
;
903 passive_scan
= cfg_priv
->active_scan
? 0 : cpu_to_le32(1);
904 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_PASSIVE_SCAN
,
905 &passive_scan
, sizeof(passive_scan
));
907 WL_ERR("error (%d)\n", err
);
910 brcmf_set_mpc(ndev
, 0);
911 results
= (struct brcmf_scan_results
*)cfg_priv
->escan_info
.escan_buf
;
912 results
->version
= 0;
914 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
916 err
= brcmf_run_escan(cfg_priv
, ndev
, request
, WL_ESCAN_ACTION_START
);
918 brcmf_set_mpc(ndev
, 1);
923 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
924 struct cfg80211_scan_request
*request
,
925 struct cfg80211_ssid
*this_ssid
)
927 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
928 struct cfg80211_ssid
*ssids
;
929 struct brcmf_cfg80211_scan_req
*sr
= cfg_priv
->scan_req_int
;
936 WL_SCAN("START ESCAN\n");
938 if (test_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
)) {
939 WL_ERR("Scanning already : status (%lu)\n", cfg_priv
->status
);
942 if (test_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
)) {
943 WL_ERR("Scanning being aborted : status (%lu)\n",
947 if (test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) {
948 WL_ERR("Connecting : status (%lu)\n",
953 /* Arm scan timeout timer */
954 mod_timer(&cfg_priv
->escan_timeout
, jiffies
+
955 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
960 ssids
= request
->ssids
;
964 /* we don't do escan in ibss */
968 cfg_priv
->scan_request
= request
;
969 set_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
971 err
= brcmf_do_escan(cfg_priv
, wiphy
, ndev
, request
);
977 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
978 ssids
->ssid
, ssids
->ssid_len
);
979 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
980 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
981 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
984 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
985 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
988 WL_SCAN("Broadcast scan\n");
990 passive_scan
= cfg_priv
->active_scan
? 0 : cpu_to_le32(1);
991 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_PASSIVE_SCAN
,
992 &passive_scan
, sizeof(passive_scan
));
994 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
997 brcmf_set_mpc(ndev
, 0);
998 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SCAN
, &sr
->ssid_le
,
999 sizeof(sr
->ssid_le
));
1002 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1005 WL_ERR("WLC_SCAN error (%d)\n", err
);
1007 brcmf_set_mpc(ndev
, 1);
1015 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
1016 if (timer_pending(&cfg_priv
->escan_timeout
))
1017 del_timer_sync(&cfg_priv
->escan_timeout
);
1018 cfg_priv
->scan_request
= NULL
;
1023 brcmf_cfg80211_scan(struct wiphy
*wiphy
,
1024 struct cfg80211_scan_request
*request
)
1026 struct net_device
*ndev
= request
->wdev
->netdev
;
1027 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1030 WL_TRACE("Enter\n");
1032 if (!check_sys_up(wiphy
))
1035 if (cfg_priv
->iscan_on
)
1036 err
= brcmf_cfg80211_iscan(wiphy
, ndev
, request
, NULL
);
1037 else if (cfg_priv
->escan_on
)
1038 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
1041 WL_ERR("scan error (%d)\n", err
);
1047 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1051 err
= brcmf_dev_intvar_set(ndev
, "rtsthresh", rts_threshold
);
1053 WL_ERR("Error (%d)\n", err
);
1058 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1062 err
= brcmf_dev_intvar_set(ndev
, "fragthresh", frag_threshold
);
1064 WL_ERR("Error (%d)\n", err
);
1069 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1072 u32 cmd
= (l
? BRCM_SET_LRL
: BRCM_SET_SRL
);
1074 err
= brcmf_exec_dcmd_u32(ndev
, cmd
, &retry
);
1076 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
1082 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1084 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1085 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
1088 WL_TRACE("Enter\n");
1089 if (!check_sys_up(wiphy
))
1092 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1093 (cfg_priv
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1094 cfg_priv
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1095 err
= brcmf_set_rts(ndev
, cfg_priv
->conf
->rts_threshold
);
1099 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1100 (cfg_priv
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1101 cfg_priv
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1102 err
= brcmf_set_frag(ndev
, cfg_priv
->conf
->frag_threshold
);
1106 if (changed
& WIPHY_PARAM_RETRY_LONG
1107 && (cfg_priv
->conf
->retry_long
!= wiphy
->retry_long
)) {
1108 cfg_priv
->conf
->retry_long
= wiphy
->retry_long
;
1109 err
= brcmf_set_retry(ndev
, cfg_priv
->conf
->retry_long
, true);
1113 if (changed
& WIPHY_PARAM_RETRY_SHORT
1114 && (cfg_priv
->conf
->retry_short
!= wiphy
->retry_short
)) {
1115 cfg_priv
->conf
->retry_short
= wiphy
->retry_short
;
1116 err
= brcmf_set_retry(ndev
, cfg_priv
->conf
->retry_short
, false);
1126 static void *brcmf_read_prof(struct brcmf_cfg80211_priv
*cfg_priv
, s32 item
)
1130 return &cfg_priv
->profile
->sec
;
1132 return &cfg_priv
->profile
->bssid
;
1134 return &cfg_priv
->profile
->ssid
;
1136 WL_ERR("invalid item (%d)\n", item
);
1141 brcmf_update_prof(struct brcmf_cfg80211_priv
*cfg_priv
,
1142 const struct brcmf_event_msg
*e
, void *data
, s32 item
)
1145 struct brcmf_ssid
*ssid
;
1149 ssid
= (struct brcmf_ssid
*) data
;
1150 memset(cfg_priv
->profile
->ssid
.SSID
, 0,
1151 sizeof(cfg_priv
->profile
->ssid
.SSID
));
1152 memcpy(cfg_priv
->profile
->ssid
.SSID
,
1153 ssid
->SSID
, ssid
->SSID_len
);
1154 cfg_priv
->profile
->ssid
.SSID_len
= ssid
->SSID_len
;
1158 memcpy(cfg_priv
->profile
->bssid
, data
, ETH_ALEN
);
1160 memset(cfg_priv
->profile
->bssid
, 0, ETH_ALEN
);
1163 memcpy(&cfg_priv
->profile
->sec
, data
,
1164 sizeof(cfg_priv
->profile
->sec
));
1166 case WL_PROF_BEACONINT
:
1167 cfg_priv
->profile
->beacon_interval
= *(u16
*)data
;
1169 case WL_PROF_DTIMPERIOD
:
1170 cfg_priv
->profile
->dtim_period
= *(u8
*)data
;
1173 WL_ERR("unsupported item (%d)\n", item
);
1181 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1183 memset(prof
, 0, sizeof(*prof
));
1186 static void brcmf_ch_to_chanspec(int ch
, struct brcmf_join_params
*join_params
,
1187 size_t *join_params_size
)
1192 if (ch
<= CH_MAX_2G_CHANNEL
)
1193 chanspec
|= WL_CHANSPEC_BAND_2G
;
1195 chanspec
|= WL_CHANSPEC_BAND_5G
;
1197 chanspec
|= WL_CHANSPEC_BW_20
;
1198 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
1200 *join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
+
1203 chanspec
|= (ch
& WL_CHANSPEC_CHAN_MASK
);
1204 join_params
->params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1205 join_params
->params_le
.chanspec_num
= cpu_to_le32(1);
1207 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
1208 "channel %d, chanspec %#X\n",
1209 chanspec
, ch
, chanspec
);
1213 static void brcmf_link_down(struct brcmf_cfg80211_priv
*cfg_priv
)
1215 struct net_device
*ndev
= NULL
;
1218 WL_TRACE("Enter\n");
1220 if (cfg_priv
->link_up
) {
1221 ndev
= cfg_to_ndev(cfg_priv
);
1222 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1223 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_DISASSOC
, NULL
, 0);
1225 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
1226 cfg_priv
->link_up
= false;
1232 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1233 struct cfg80211_ibss_params
*params
)
1235 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1236 struct brcmf_join_params join_params
;
1237 size_t join_params_size
= 0;
1241 struct brcmf_ssid ssid
;
1243 WL_TRACE("Enter\n");
1244 if (!check_sys_up(wiphy
))
1248 WL_CONN("SSID: %s\n", params
->ssid
);
1250 WL_CONN("SSID: NULL, Not supported\n");
1254 set_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1257 WL_CONN("BSSID: %pM\n", params
->bssid
);
1259 WL_CONN("No BSSID specified\n");
1261 if (params
->channel
)
1262 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
1264 WL_CONN("no channel specified\n");
1266 if (params
->channel_fixed
)
1267 WL_CONN("fixed channel required\n");
1269 WL_CONN("no fixed channel required\n");
1271 if (params
->ie
&& params
->ie_len
)
1272 WL_CONN("ie len: %d\n", params
->ie_len
);
1274 WL_CONN("no ie specified\n");
1276 if (params
->beacon_interval
)
1277 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
1279 WL_CONN("no beacon interval specified\n");
1281 if (params
->basic_rates
)
1282 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1284 WL_CONN("no basic rates specified\n");
1286 if (params
->privacy
)
1287 WL_CONN("privacy required\n");
1289 WL_CONN("no privacy required\n");
1291 /* Configure Privacy for starter */
1292 if (params
->privacy
)
1293 wsec
|= WEP_ENABLED
;
1295 err
= brcmf_dev_intvar_set(ndev
, "wsec", wsec
);
1297 WL_ERR("wsec failed (%d)\n", err
);
1301 /* Configure Beacon Interval for starter */
1302 if (params
->beacon_interval
)
1303 bcnprd
= params
->beacon_interval
;
1307 err
= brcmf_exec_dcmd_u32(ndev
, BRCM_SET_BCNPRD
, &bcnprd
);
1309 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1313 /* Configure required join parameter */
1314 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1317 ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1318 memcpy(ssid
.SSID
, params
->ssid
, ssid
.SSID_len
);
1319 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, ssid
.SSID_len
);
1320 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid
.SSID_len
);
1321 join_params_size
= sizeof(join_params
.ssid_le
);
1322 brcmf_update_prof(cfg_priv
, NULL
, &ssid
, WL_PROF_SSID
);
1325 if (params
->bssid
) {
1326 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1327 join_params_size
= sizeof(join_params
.ssid_le
) +
1328 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1330 memcpy(join_params
.params_le
.bssid
, ether_bcast
, ETH_ALEN
);
1333 brcmf_update_prof(cfg_priv
, NULL
,
1334 &join_params
.params_le
.bssid
, WL_PROF_BSSID
);
1337 if (params
->channel
) {
1341 ieee80211_frequency_to_channel(
1342 params
->channel
->center_freq
);
1343 if (params
->channel_fixed
) {
1344 /* adding chanspec */
1345 brcmf_ch_to_chanspec(cfg_priv
->channel
,
1346 &join_params
, &join_params_size
);
1349 /* set channel for starter */
1350 target_channel
= cfg_priv
->channel
;
1351 err
= brcmf_exec_dcmd_u32(ndev
, BRCM_SET_CHANNEL
,
1354 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1358 cfg_priv
->channel
= 0;
1360 cfg_priv
->ibss_starter
= false;
1363 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_SSID
,
1364 &join_params
, join_params_size
);
1366 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1372 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1378 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1380 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1383 WL_TRACE("Enter\n");
1384 if (!check_sys_up(wiphy
))
1387 brcmf_link_down(cfg_priv
);
1394 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1395 struct cfg80211_connect_params
*sme
)
1397 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1398 struct brcmf_cfg80211_security
*sec
;
1402 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1403 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1404 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1405 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1407 val
= WPA_AUTH_DISABLED
;
1408 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1409 err
= brcmf_dev_intvar_set(ndev
, "wpa_auth", val
);
1411 WL_ERR("set wpa_auth failed (%d)\n", err
);
1414 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1415 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1419 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1420 struct cfg80211_connect_params
*sme
)
1422 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1423 struct brcmf_cfg80211_security
*sec
;
1427 switch (sme
->auth_type
) {
1428 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1430 WL_CONN("open system\n");
1432 case NL80211_AUTHTYPE_SHARED_KEY
:
1434 WL_CONN("shared key\n");
1436 case NL80211_AUTHTYPE_AUTOMATIC
:
1438 WL_CONN("automatic\n");
1440 case NL80211_AUTHTYPE_NETWORK_EAP
:
1441 WL_CONN("network eap\n");
1444 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1448 err
= brcmf_dev_intvar_set(ndev
, "auth", val
);
1450 WL_ERR("set auth failed (%d)\n", err
);
1453 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1454 sec
->auth_type
= sme
->auth_type
;
1459 brcmf_set_set_cipher(struct net_device
*ndev
,
1460 struct cfg80211_connect_params
*sme
)
1462 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1463 struct brcmf_cfg80211_security
*sec
;
1468 if (sme
->crypto
.n_ciphers_pairwise
) {
1469 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1470 case WLAN_CIPHER_SUITE_WEP40
:
1471 case WLAN_CIPHER_SUITE_WEP104
:
1474 case WLAN_CIPHER_SUITE_TKIP
:
1475 pval
= TKIP_ENABLED
;
1477 case WLAN_CIPHER_SUITE_CCMP
:
1480 case WLAN_CIPHER_SUITE_AES_CMAC
:
1484 WL_ERR("invalid cipher pairwise (%d)\n",
1485 sme
->crypto
.ciphers_pairwise
[0]);
1489 if (sme
->crypto
.cipher_group
) {
1490 switch (sme
->crypto
.cipher_group
) {
1491 case WLAN_CIPHER_SUITE_WEP40
:
1492 case WLAN_CIPHER_SUITE_WEP104
:
1495 case WLAN_CIPHER_SUITE_TKIP
:
1496 gval
= TKIP_ENABLED
;
1498 case WLAN_CIPHER_SUITE_CCMP
:
1501 case WLAN_CIPHER_SUITE_AES_CMAC
:
1505 WL_ERR("invalid cipher group (%d)\n",
1506 sme
->crypto
.cipher_group
);
1511 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1512 err
= brcmf_dev_intvar_set(ndev
, "wsec", pval
| gval
);
1514 WL_ERR("error (%d)\n", err
);
1518 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1519 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1520 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1526 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1528 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1529 struct brcmf_cfg80211_security
*sec
;
1533 if (sme
->crypto
.n_akm_suites
) {
1534 err
= brcmf_dev_intvar_get(ndev
, "wpa_auth", &val
);
1536 WL_ERR("could not get wpa_auth (%d)\n", err
);
1539 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1540 switch (sme
->crypto
.akm_suites
[0]) {
1541 case WLAN_AKM_SUITE_8021X
:
1542 val
= WPA_AUTH_UNSPECIFIED
;
1544 case WLAN_AKM_SUITE_PSK
:
1548 WL_ERR("invalid cipher group (%d)\n",
1549 sme
->crypto
.cipher_group
);
1552 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1553 switch (sme
->crypto
.akm_suites
[0]) {
1554 case WLAN_AKM_SUITE_8021X
:
1555 val
= WPA2_AUTH_UNSPECIFIED
;
1557 case WLAN_AKM_SUITE_PSK
:
1558 val
= WPA2_AUTH_PSK
;
1561 WL_ERR("invalid cipher group (%d)\n",
1562 sme
->crypto
.cipher_group
);
1567 WL_CONN("setting wpa_auth to %d\n", val
);
1568 err
= brcmf_dev_intvar_set(ndev
, "wpa_auth", val
);
1570 WL_ERR("could not set wpa_auth (%d)\n", err
);
1574 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1575 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1581 brcmf_set_wep_sharedkey(struct net_device
*ndev
,
1582 struct cfg80211_connect_params
*sme
)
1584 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
1585 struct brcmf_cfg80211_security
*sec
;
1586 struct brcmf_wsec_key key
;
1590 WL_CONN("key len (%d)\n", sme
->key_len
);
1592 if (sme
->key_len
== 0)
1595 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
1596 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1597 sec
->wpa_versions
, sec
->cipher_pairwise
);
1599 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1602 if (sec
->cipher_pairwise
&
1603 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)) {
1604 memset(&key
, 0, sizeof(key
));
1605 key
.len
= (u32
) sme
->key_len
;
1606 key
.index
= (u32
) sme
->key_idx
;
1607 if (key
.len
> sizeof(key
.data
)) {
1608 WL_ERR("Too long key length (%u)\n", key
.len
);
1611 memcpy(key
.data
, sme
->key
, key
.len
);
1612 key
.flags
= BRCMF_PRIMARY_KEY
;
1613 switch (sec
->cipher_pairwise
) {
1614 case WLAN_CIPHER_SUITE_WEP40
:
1615 key
.algo
= CRYPTO_ALGO_WEP1
;
1617 case WLAN_CIPHER_SUITE_WEP104
:
1618 key
.algo
= CRYPTO_ALGO_WEP128
;
1621 WL_ERR("Invalid algorithm (%d)\n",
1622 sme
->crypto
.ciphers_pairwise
[0]);
1625 /* Set the new key/index */
1626 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1627 key
.len
, key
.index
, key
.algo
);
1628 WL_CONN("key \"%s\"\n", key
.data
);
1629 err
= send_key_to_dongle(ndev
, &key
);
1633 if (sec
->auth_type
== NL80211_AUTHTYPE_OPEN_SYSTEM
) {
1634 WL_CONN("set auth_type to shared key\n");
1635 val
= 1; /* shared key */
1636 err
= brcmf_dev_intvar_set(ndev
, "auth", val
);
1638 WL_ERR("set auth failed (%d)\n", err
);
1647 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1648 struct cfg80211_connect_params
*sme
)
1650 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1651 struct ieee80211_channel
*chan
= sme
->channel
;
1652 struct brcmf_join_params join_params
;
1653 size_t join_params_size
;
1654 struct brcmf_ssid ssid
;
1658 WL_TRACE("Enter\n");
1659 if (!check_sys_up(wiphy
))
1663 WL_ERR("Invalid ssid\n");
1667 set_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1671 ieee80211_frequency_to_channel(chan
->center_freq
);
1672 WL_CONN("channel (%d), center_req (%d)\n",
1673 cfg_priv
->channel
, chan
->center_freq
);
1675 cfg_priv
->channel
= 0;
1677 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1679 err
= brcmf_set_wpa_version(ndev
, sme
);
1681 WL_ERR("wl_set_wpa_version failed (%d)\n", err
);
1685 err
= brcmf_set_auth_type(ndev
, sme
);
1687 WL_ERR("wl_set_auth_type failed (%d)\n", err
);
1691 err
= brcmf_set_set_cipher(ndev
, sme
);
1693 WL_ERR("wl_set_set_cipher failed (%d)\n", err
);
1697 err
= brcmf_set_key_mgmt(ndev
, sme
);
1699 WL_ERR("wl_set_key_mgmt failed (%d)\n", err
);
1703 err
= brcmf_set_wep_sharedkey(ndev
, sme
);
1705 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err
);
1709 memset(&join_params
, 0, sizeof(join_params
));
1710 join_params_size
= sizeof(join_params
.ssid_le
);
1712 ssid
.SSID_len
= min_t(u32
, sizeof(ssid
.SSID
), (u32
)sme
->ssid_len
);
1713 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, ssid
.SSID_len
);
1714 memcpy(&ssid
.SSID
, sme
->ssid
, ssid
.SSID_len
);
1715 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid
.SSID_len
);
1716 brcmf_update_prof(cfg_priv
, NULL
, &ssid
, WL_PROF_SSID
);
1718 memcpy(join_params
.params_le
.bssid
, ether_bcast
, ETH_ALEN
);
1720 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1721 WL_CONN("ssid \"%s\", len (%d)\n",
1722 ssid
.SSID
, ssid
.SSID_len
);
1724 brcmf_ch_to_chanspec(cfg_priv
->channel
,
1725 &join_params
, &join_params_size
);
1726 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_SSID
,
1727 &join_params
, join_params_size
);
1729 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1733 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
1739 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1742 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1743 struct brcmf_scb_val_le scbval
;
1746 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1747 if (!check_sys_up(wiphy
))
1750 clear_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
1752 memcpy(&scbval
.ea
, brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
), ETH_ALEN
);
1753 scbval
.val
= cpu_to_le32(reason_code
);
1754 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_DISASSOC
, &scbval
,
1755 sizeof(struct brcmf_scb_val_le
));
1757 WL_ERR("error (%d)\n", err
);
1759 cfg_priv
->link_up
= false;
1766 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1767 enum nl80211_tx_power_setting type
, s32 mbm
)
1770 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1771 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
1775 s32 dbm
= MBM_TO_DBM(mbm
);
1777 WL_TRACE("Enter\n");
1778 if (!check_sys_up(wiphy
))
1782 case NL80211_TX_POWER_AUTOMATIC
:
1784 case NL80211_TX_POWER_LIMITED
:
1785 case NL80211_TX_POWER_FIXED
:
1787 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1793 /* Make sure radio is off or on as far as software is concerned */
1794 disable
= WL_RADIO_SW_DISABLE
<< 16;
1795 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_RADIO
, &disable
);
1797 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1802 txpwrmw
= (u16
) dbm
;
1803 err
= brcmf_dev_intvar_set(ndev
, "qtxpower",
1804 (s32
) (brcmf_mw_to_qdbm(txpwrmw
)));
1806 WL_ERR("qtxpower error (%d)\n", err
);
1807 cfg_priv
->conf
->tx_power
= dbm
;
1814 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1816 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
1817 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
1822 WL_TRACE("Enter\n");
1823 if (!check_sys_up(wiphy
))
1826 err
= brcmf_dev_intvar_get(ndev
, "qtxpower", &txpwrdbm
);
1828 WL_ERR("error (%d)\n", err
);
1832 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1833 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1841 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1842 u8 key_idx
, bool unicast
, bool multicast
)
1848 WL_TRACE("Enter\n");
1849 WL_CONN("key index (%d)\n", key_idx
);
1850 if (!check_sys_up(wiphy
))
1853 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_GET_WSEC
, &wsec
);
1855 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1859 if (wsec
& WEP_ENABLED
) {
1860 /* Just select a new current key */
1862 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_KEY_PRIMARY
,
1865 WL_ERR("error (%d)\n", err
);
1873 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1874 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1876 struct brcmf_wsec_key key
;
1877 struct brcmf_wsec_key_le key_le
;
1880 memset(&key
, 0, sizeof(key
));
1881 key
.index
= (u32
) key_idx
;
1882 /* Instead of bcast for ea address for default wep keys,
1883 driver needs it to be Null */
1884 if (!is_multicast_ether_addr(mac_addr
))
1885 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1886 key
.len
= (u32
) params
->key_len
;
1887 /* check for key index change */
1890 err
= send_key_to_dongle(ndev
, &key
);
1894 if (key
.len
> sizeof(key
.data
)) {
1895 WL_ERR("Invalid key length (%d)\n", key
.len
);
1899 WL_CONN("Setting the key index %d\n", key
.index
);
1900 memcpy(key
.data
, params
->key
, key
.len
);
1902 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1904 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1905 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1906 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1909 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1910 if (params
->seq
&& params
->seq_len
== 6) {
1913 ivptr
= (u8
*) params
->seq
;
1914 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1915 (ivptr
[3] << 8) | ivptr
[2];
1916 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1917 key
.iv_initialized
= true;
1920 switch (params
->cipher
) {
1921 case WLAN_CIPHER_SUITE_WEP40
:
1922 key
.algo
= CRYPTO_ALGO_WEP1
;
1923 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1925 case WLAN_CIPHER_SUITE_WEP104
:
1926 key
.algo
= CRYPTO_ALGO_WEP128
;
1927 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1929 case WLAN_CIPHER_SUITE_TKIP
:
1930 key
.algo
= CRYPTO_ALGO_TKIP
;
1931 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1933 case WLAN_CIPHER_SUITE_AES_CMAC
:
1934 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1935 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1937 case WLAN_CIPHER_SUITE_CCMP
:
1938 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1939 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1942 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1945 convert_key_from_CPU(&key
, &key_le
);
1947 brcmf_netdev_wait_pend8021x(ndev
);
1948 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_KEY
, &key_le
,
1951 WL_ERR("WLC_SET_KEY error (%d)\n", err
);
1959 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1960 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1961 struct key_params
*params
)
1963 struct brcmf_wsec_key key
;
1969 WL_TRACE("Enter\n");
1970 WL_CONN("key index (%d)\n", key_idx
);
1971 if (!check_sys_up(wiphy
))
1976 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1978 memset(&key
, 0, sizeof(key
));
1980 key
.len
= (u32
) params
->key_len
;
1981 key
.index
= (u32
) key_idx
;
1983 if (key
.len
> sizeof(key
.data
)) {
1984 WL_ERR("Too long key length (%u)\n", key
.len
);
1988 memcpy(key
.data
, params
->key
, key
.len
);
1990 key
.flags
= BRCMF_PRIMARY_KEY
;
1991 switch (params
->cipher
) {
1992 case WLAN_CIPHER_SUITE_WEP40
:
1993 key
.algo
= CRYPTO_ALGO_WEP1
;
1994 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1996 case WLAN_CIPHER_SUITE_WEP104
:
1997 key
.algo
= CRYPTO_ALGO_WEP128
;
1998 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2000 case WLAN_CIPHER_SUITE_TKIP
:
2001 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2002 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2003 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2004 key
.algo
= CRYPTO_ALGO_TKIP
;
2005 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2007 case WLAN_CIPHER_SUITE_AES_CMAC
:
2008 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2009 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2011 case WLAN_CIPHER_SUITE_CCMP
:
2012 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2013 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
2016 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
2021 err
= send_key_to_dongle(ndev
, &key
); /* Set the new key/index */
2026 err
= brcmf_dev_intvar_get(ndev
, "wsec", &wsec
);
2028 WL_ERR("get wsec error (%d)\n", err
);
2031 wsec
&= ~(WEP_ENABLED
);
2033 err
= brcmf_dev_intvar_set(ndev
, "wsec", wsec
);
2035 WL_ERR("set wsec error (%d)\n", err
);
2039 val
= 1; /* assume shared key. otherwise 0 */
2040 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_AUTH
, &val
);
2042 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
2049 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2050 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2052 struct brcmf_wsec_key key
;
2057 WL_TRACE("Enter\n");
2058 if (!check_sys_up(wiphy
))
2061 memset(&key
, 0, sizeof(key
));
2063 key
.index
= (u32
) key_idx
;
2064 key
.flags
= BRCMF_PRIMARY_KEY
;
2065 key
.algo
= CRYPTO_ALGO_OFF
;
2067 WL_CONN("key index (%d)\n", key_idx
);
2069 /* Set the new key/index */
2070 err
= send_key_to_dongle(ndev
, &key
);
2072 if (err
== -EINVAL
) {
2073 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
2074 /* we ignore this key index in this case */
2075 WL_ERR("invalid key index (%d)\n", key_idx
);
2077 /* Ignore this error, may happen during DISASSOC */
2083 err
= brcmf_dev_intvar_get(ndev
, "wsec", &wsec
);
2085 WL_ERR("get wsec error (%d)\n", err
);
2086 /* Ignore this error, may happen during DISASSOC */
2090 wsec
&= ~(WEP_ENABLED
);
2092 err
= brcmf_dev_intvar_set(ndev
, "wsec", wsec
);
2094 WL_ERR("set wsec error (%d)\n", err
);
2095 /* Ignore this error, may happen during DISASSOC */
2100 val
= 0; /* assume open key. otherwise 1 */
2101 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_AUTH
, &val
);
2103 WL_ERR("WLC_SET_AUTH error (%d)\n", err
);
2104 /* Ignore this error, may happen during DISASSOC */
2113 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2114 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2115 void (*callback
) (void *cookie
, struct key_params
* params
))
2117 struct key_params params
;
2118 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2119 struct brcmf_cfg80211_security
*sec
;
2123 WL_TRACE("Enter\n");
2124 WL_CONN("key index (%d)\n", key_idx
);
2125 if (!check_sys_up(wiphy
))
2128 memset(¶ms
, 0, sizeof(params
));
2130 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_GET_WSEC
, &wsec
);
2132 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
2133 /* Ignore this error, may happen during DISASSOC */
2139 sec
= brcmf_read_prof(cfg_priv
, WL_PROF_SEC
);
2140 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2141 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2142 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2143 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2144 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2145 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2149 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2150 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2153 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2154 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2157 WL_ERR("Invalid algo (0x%x)\n", wsec
);
2161 callback(cookie
, ¶ms
);
2169 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2170 struct net_device
*ndev
, u8 key_idx
)
2172 WL_INFO("Not supported\n");
2178 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2179 u8
*mac
, struct station_info
*sinfo
)
2181 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2182 struct brcmf_scb_val_le scb_val
;
2186 u8
*bssid
= brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
);
2188 WL_TRACE("Enter\n");
2189 if (!check_sys_up(wiphy
))
2192 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2193 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
2194 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
2195 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5],
2196 bssid
[0], bssid
[1], bssid
[2], bssid
[3],
2197 bssid
[4], bssid
[5]);
2202 /* Report the current tx rate */
2203 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_GET_RATE
, &rate
);
2205 WL_ERR("Could not get rate (%d)\n", err
);
2207 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2208 sinfo
->txrate
.legacy
= rate
* 5;
2209 WL_CONN("Rate %d Mbps\n", rate
/ 2);
2212 if (test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
)) {
2213 memset(&scb_val
, 0, sizeof(scb_val
));
2214 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_GET_RSSI
, &scb_val
,
2215 sizeof(struct brcmf_scb_val_le
));
2217 WL_ERR("Could not get rssi (%d)\n", err
);
2219 rssi
= le32_to_cpu(scb_val
.val
);
2220 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2221 sinfo
->signal
= rssi
;
2222 WL_CONN("RSSI %d dBm\n", rssi
);
2232 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2233 bool enabled
, s32 timeout
)
2237 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2239 WL_TRACE("Enter\n");
2242 * Powersave enable/disable request is coming from the
2243 * cfg80211 even before the interface is up. In that
2244 * scenario, driver will be storing the power save
2245 * preference in cfg_priv struct to apply this to
2246 * FW later while initializing the dongle
2248 cfg_priv
->pwr_save
= enabled
;
2249 if (!test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
2251 WL_INFO("Device is not ready,"
2252 "storing the value in cfg_priv struct\n");
2256 pm
= enabled
? PM_FAST
: PM_OFF
;
2257 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
2259 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_PM
, &pm
);
2262 WL_ERR("net_device is not ready yet\n");
2264 WL_ERR("error (%d)\n", err
);
2272 brcmf_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*ndev
,
2274 const struct cfg80211_bitrate_mask
*mask
)
2276 struct brcm_rateset_le rateset_le
;
2284 WL_TRACE("Enter\n");
2285 if (!check_sys_up(wiphy
))
2288 /* addr param is always NULL. ignore it */
2289 /* Get current rateset */
2290 err
= brcmf_exec_dcmd(ndev
, BRCM_GET_CURR_RATESET
, &rateset_le
,
2291 sizeof(rateset_le
));
2293 WL_ERR("could not get current rateset (%d)\n", err
);
2297 legacy
= ffs(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
& 0xFFFF);
2299 legacy
= ffs(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
&
2302 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2304 if (val
< le32_to_cpu(rateset_le
.count
))
2305 /* Select rate by rateset index */
2306 rate
= rateset_le
.rates
[val
] & 0x7f;
2308 /* Specified rate in bps */
2309 rate
= val
/ 500000;
2311 WL_CONN("rate %d mbps\n", rate
/ 2);
2315 * Set rate override,
2316 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2318 err_bg
= brcmf_dev_intvar_set(ndev
, "bg_rate", rate
);
2319 err_a
= brcmf_dev_intvar_set(ndev
, "a_rate", rate
);
2320 if (err_bg
&& err_a
) {
2321 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2322 err
= err_bg
| err_a
;
2330 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_priv
*cfg_priv
,
2331 struct brcmf_bss_info_le
*bi
)
2333 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
2334 struct ieee80211_channel
*notify_channel
;
2335 struct cfg80211_bss
*bss
;
2336 struct ieee80211_supported_band
*band
;
2340 u16 notify_capability
;
2341 u16 notify_interval
;
2343 size_t notify_ielen
;
2346 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2347 WL_ERR("Bss info is larger than buffer. Discarding\n");
2351 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2352 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2354 if (channel
<= CH_MAX_2G_CHANNEL
)
2355 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2357 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2359 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2360 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2362 notify_capability
= le16_to_cpu(bi
->capability
);
2363 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2364 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2365 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2366 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2368 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2369 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2370 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2371 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2372 WL_CONN("Capability: %X\n", notify_capability
);
2373 WL_CONN("Beacon interval: %d\n", notify_interval
);
2374 WL_CONN("Signal: %d\n", notify_signal
);
2376 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2377 0, notify_capability
, notify_interval
, notify_ie
,
2378 notify_ielen
, notify_signal
, GFP_KERNEL
);
2383 cfg80211_put_bss(bss
);
2388 static struct brcmf_bss_info_le
*
2389 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2392 return list
->bss_info_le
;
2393 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2394 le32_to_cpu(bss
->length
));
2397 static s32
brcmf_inform_bss(struct brcmf_cfg80211_priv
*cfg_priv
)
2399 struct brcmf_scan_results
*bss_list
;
2400 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2404 bss_list
= cfg_priv
->bss_list
;
2405 if (bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2406 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2410 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2411 for (i
= 0; i
< bss_list
->count
&& i
< WL_AP_MAX
; i
++) {
2412 bi
= next_bss_le(bss_list
, bi
);
2413 err
= brcmf_inform_single_bss(cfg_priv
, bi
);
2420 static s32
wl_inform_ibss(struct brcmf_cfg80211_priv
*cfg_priv
,
2421 struct net_device
*ndev
, const u8
*bssid
)
2423 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
2424 struct ieee80211_channel
*notify_channel
;
2425 struct brcmf_bss_info_le
*bi
= NULL
;
2426 struct ieee80211_supported_band
*band
;
2427 struct cfg80211_bss
*bss
;
2432 u16 notify_capability
;
2433 u16 notify_interval
;
2435 size_t notify_ielen
;
2438 WL_TRACE("Enter\n");
2440 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2446 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2448 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_GET_BSS_INFO
, buf
, WL_BSS_INFO_MAX
);
2450 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2454 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2456 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2457 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2459 if (channel
<= CH_MAX_2G_CHANNEL
)
2460 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2462 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2464 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2465 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2467 notify_capability
= le16_to_cpu(bi
->capability
);
2468 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2469 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2470 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2471 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2473 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2474 WL_CONN("capability: %X\n", notify_capability
);
2475 WL_CONN("beacon interval: %d\n", notify_interval
);
2476 WL_CONN("signal: %d\n", notify_signal
);
2478 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2479 0, notify_capability
, notify_interval
,
2480 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2487 cfg80211_put_bss(bss
);
2498 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv
*cfg_priv
)
2500 return cfg_priv
->conf
->mode
== WL_MODE_IBSS
;
2504 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2505 * triples, returning a pointer to the substring whose first element
2508 static struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
2510 struct brcmf_tlv
*elt
;
2513 elt
= (struct brcmf_tlv
*) buf
;
2516 /* find tagged parameter */
2517 while (totlen
>= 2) {
2520 /* validate remaining totlen */
2521 if ((elt
->id
== key
) && (totlen
>= (len
+ 2)))
2524 elt
= (struct brcmf_tlv
*) ((u8
*) elt
+ (len
+ 2));
2525 totlen
-= (len
+ 2);
2531 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_priv
*cfg_priv
)
2533 struct brcmf_bss_info_le
*bi
;
2534 struct brcmf_ssid
*ssid
;
2535 struct brcmf_tlv
*tim
;
2536 u16 beacon_interval
;
2542 WL_TRACE("Enter\n");
2543 if (brcmf_is_ibssmode(cfg_priv
))
2546 ssid
= (struct brcmf_ssid
*)brcmf_read_prof(cfg_priv
, WL_PROF_SSID
);
2548 *(__le32
*)cfg_priv
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2549 err
= brcmf_exec_dcmd(cfg_to_ndev(cfg_priv
), BRCMF_C_GET_BSS_INFO
,
2550 cfg_priv
->extra_buf
, WL_EXTRA_BUF_MAX
);
2552 WL_ERR("Could not get bss info %d\n", err
);
2553 goto update_bss_info_out
;
2556 bi
= (struct brcmf_bss_info_le
*)(cfg_priv
->extra_buf
+ 4);
2557 err
= brcmf_inform_single_bss(cfg_priv
, bi
);
2559 goto update_bss_info_out
;
2561 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2562 ie_len
= le32_to_cpu(bi
->ie_length
);
2563 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2565 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2567 dtim_period
= tim
->data
[1];
2570 * active scan was done so we could not get dtim
2571 * information out of probe response.
2572 * so we speficially query dtim information to dongle.
2575 err
= brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv
),
2576 "dtim_assoc", &var
);
2578 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2579 goto update_bss_info_out
;
2581 dtim_period
= (u8
)var
;
2584 brcmf_update_prof(cfg_priv
, NULL
, &beacon_interval
, WL_PROF_BEACONINT
);
2585 brcmf_update_prof(cfg_priv
, NULL
, &dtim_period
, WL_PROF_DTIMPERIOD
);
2587 update_bss_info_out
:
2592 static void brcmf_term_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
2594 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
2595 struct brcmf_ssid ssid
;
2597 if (cfg_priv
->iscan_on
) {
2598 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2600 if (iscan
->timer_on
) {
2601 del_timer_sync(&iscan
->timer
);
2602 iscan
->timer_on
= 0;
2605 cancel_work_sync(&iscan
->work
);
2607 /* Abort iscan running in FW */
2608 memset(&ssid
, 0, sizeof(ssid
));
2609 brcmf_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_ABORT
);
2613 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
2616 struct brcmf_cfg80211_priv
*cfg_priv
= iscan_to_cfg(iscan
);
2617 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
2619 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
)) {
2620 WL_ERR("Scan complete while device not scanning\n");
2623 if (cfg_priv
->scan_request
) {
2624 WL_SCAN("ISCAN Completed scan: %s\n",
2625 aborted
? "Aborted" : "Done");
2626 cfg80211_scan_done(cfg_priv
->scan_request
, aborted
);
2627 brcmf_set_mpc(ndev
, 1);
2628 cfg_priv
->scan_request
= NULL
;
2630 cfg_priv
->iscan_kickstart
= false;
2633 static s32
brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
)
2635 if (iscan
->state
!= WL_ISCAN_STATE_IDLE
) {
2636 WL_SCAN("wake up iscan\n");
2637 schedule_work(&iscan
->work
);
2645 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl
*iscan
, u32
*status
,
2646 struct brcmf_scan_results
**bss_list
)
2648 struct brcmf_iscan_results list
;
2649 struct brcmf_scan_results
*results
;
2650 struct brcmf_scan_results_le
*results_le
;
2651 struct brcmf_iscan_results
*list_buf
;
2654 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
2655 list_buf
= (struct brcmf_iscan_results
*)iscan
->scan_buf
;
2656 results
= &list_buf
->results
;
2657 results_le
= &list_buf
->results_le
;
2658 results
->buflen
= BRCMF_ISCAN_RESULTS_FIXED_SIZE
;
2659 results
->version
= 0;
2662 memset(&list
, 0, sizeof(list
));
2663 list
.results_le
.buflen
= cpu_to_le32(WL_ISCAN_BUF_MAX
);
2664 err
= brcmf_dev_iovar_getbuf(iscan
->ndev
, "iscanresults", &list
,
2665 BRCMF_ISCAN_RESULTS_FIXED_SIZE
,
2666 iscan
->scan_buf
, WL_ISCAN_BUF_MAX
);
2668 WL_ERR("error (%d)\n", err
);
2671 results
->buflen
= le32_to_cpu(results_le
->buflen
);
2672 results
->version
= le32_to_cpu(results_le
->version
);
2673 results
->count
= le32_to_cpu(results_le
->count
);
2674 WL_SCAN("results->count = %d\n", results_le
->count
);
2675 WL_SCAN("results->buflen = %d\n", results_le
->buflen
);
2676 *status
= le32_to_cpu(list_buf
->status_le
);
2677 WL_SCAN("status = %d\n", *status
);
2678 *bss_list
= results
;
2683 static s32
brcmf_iscan_done(struct brcmf_cfg80211_priv
*cfg_priv
)
2685 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
2688 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2689 brcmf_inform_bss(cfg_priv
);
2690 brcmf_notify_iscan_complete(iscan
, false);
2695 static s32
brcmf_iscan_pending(struct brcmf_cfg80211_priv
*cfg_priv
)
2697 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
2700 /* Reschedule the timer */
2701 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
2702 iscan
->timer_on
= 1;
2707 static s32
brcmf_iscan_inprogress(struct brcmf_cfg80211_priv
*cfg_priv
)
2709 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
2712 brcmf_inform_bss(cfg_priv
);
2713 brcmf_run_iscan(iscan
, NULL
, BRCMF_SCAN_ACTION_CONTINUE
);
2714 /* Reschedule the timer */
2715 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
2716 iscan
->timer_on
= 1;
2721 static s32
brcmf_iscan_aborted(struct brcmf_cfg80211_priv
*cfg_priv
)
2723 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_priv
->iscan
;
2726 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2727 brcmf_notify_iscan_complete(iscan
, true);
2732 static void brcmf_cfg80211_iscan_handler(struct work_struct
*work
)
2734 struct brcmf_cfg80211_iscan_ctrl
*iscan
=
2735 container_of(work
, struct brcmf_cfg80211_iscan_ctrl
,
2737 struct brcmf_cfg80211_priv
*cfg_priv
= iscan_to_cfg(iscan
);
2738 struct brcmf_cfg80211_iscan_eloop
*el
= &iscan
->el
;
2739 u32 status
= BRCMF_SCAN_RESULTS_PARTIAL
;
2741 if (iscan
->timer_on
) {
2742 del_timer_sync(&iscan
->timer
);
2743 iscan
->timer_on
= 0;
2746 if (brcmf_get_iscan_results(iscan
, &status
, &cfg_priv
->bss_list
)) {
2747 status
= BRCMF_SCAN_RESULTS_ABORTED
;
2748 WL_ERR("Abort iscan\n");
2751 el
->handler
[status
](cfg_priv
);
2754 static void brcmf_iscan_timer(unsigned long data
)
2756 struct brcmf_cfg80211_iscan_ctrl
*iscan
=
2757 (struct brcmf_cfg80211_iscan_ctrl
*)data
;
2760 iscan
->timer_on
= 0;
2761 WL_SCAN("timer expired\n");
2762 brcmf_wakeup_iscan(iscan
);
2766 static s32
brcmf_invoke_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
2768 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
2770 if (cfg_priv
->iscan_on
) {
2771 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2772 INIT_WORK(&iscan
->work
, brcmf_cfg80211_iscan_handler
);
2778 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop
*el
)
2780 memset(el
, 0, sizeof(*el
));
2781 el
->handler
[BRCMF_SCAN_RESULTS_SUCCESS
] = brcmf_iscan_done
;
2782 el
->handler
[BRCMF_SCAN_RESULTS_PARTIAL
] = brcmf_iscan_inprogress
;
2783 el
->handler
[BRCMF_SCAN_RESULTS_PENDING
] = brcmf_iscan_pending
;
2784 el
->handler
[BRCMF_SCAN_RESULTS_ABORTED
] = brcmf_iscan_aborted
;
2785 el
->handler
[BRCMF_SCAN_RESULTS_NO_MEM
] = brcmf_iscan_aborted
;
2788 static s32
brcmf_init_iscan(struct brcmf_cfg80211_priv
*cfg_priv
)
2790 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg_priv
);
2793 if (cfg_priv
->iscan_on
) {
2794 iscan
->ndev
= cfg_to_ndev(cfg_priv
);
2795 brcmf_init_iscan_eloop(&iscan
->el
);
2796 iscan
->timer_ms
= WL_ISCAN_TIMER_INTERVAL_MS
;
2797 init_timer(&iscan
->timer
);
2798 iscan
->timer
.data
= (unsigned long) iscan
;
2799 iscan
->timer
.function
= brcmf_iscan_timer
;
2800 err
= brcmf_invoke_iscan(cfg_priv
);
2802 iscan
->data
= cfg_priv
;
2808 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2810 struct brcmf_cfg80211_priv
*cfg_priv
=
2811 container_of(work
, struct brcmf_cfg80211_priv
,
2812 escan_timeout_work
);
2814 brcmf_notify_escan_complete(cfg_priv
,
2815 cfg_priv
->escan_info
.ndev
, true, true);
2818 static void brcmf_escan_timeout(unsigned long data
)
2820 struct brcmf_cfg80211_priv
*cfg_priv
=
2821 (struct brcmf_cfg80211_priv
*)data
;
2823 if (cfg_priv
->scan_request
) {
2824 WL_ERR("timer expired\n");
2825 if (cfg_priv
->escan_on
)
2826 schedule_work(&cfg_priv
->escan_timeout_work
);
2831 brcmf_compare_update_same_bss(struct brcmf_bss_info_le
*bss
,
2832 struct brcmf_bss_info_le
*bss_info_le
)
2834 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2835 (CHSPEC_BAND(le16_to_cpu(bss_info_le
->chanspec
)) ==
2836 CHSPEC_BAND(le16_to_cpu(bss
->chanspec
))) &&
2837 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2838 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2839 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2840 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2841 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2842 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2844 /* preserve max RSSI if the measurements are
2845 * both on-channel or both off-channel
2847 if (bss_info_rssi
> bss_rssi
)
2848 bss
->RSSI
= bss_info_le
->RSSI
;
2849 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2850 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2851 /* preserve the on-channel rssi measurement
2852 * if the new measurement is off channel
2854 bss
->RSSI
= bss_info_le
->RSSI
;
2855 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2863 brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_priv
*cfg_priv
,
2864 struct net_device
*ndev
,
2865 const struct brcmf_event_msg
*e
, void *data
)
2869 struct brcmf_escan_result_le
*escan_result_le
;
2870 struct brcmf_bss_info_le
*bss_info_le
;
2871 struct brcmf_bss_info_le
*bss
= NULL
;
2873 struct brcmf_scan_results
*list
;
2877 status
= be32_to_cpu(e
->status
);
2879 if (!ndev
|| !cfg_priv
->escan_on
||
2880 !test_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
)) {
2881 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
2882 ndev
, cfg_priv
->escan_on
,
2883 !test_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
));
2887 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2888 WL_SCAN("ESCAN Partial result\n");
2889 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2890 if (!escan_result_le
) {
2891 WL_ERR("Invalid escan result (NULL pointer)\n");
2894 if (!cfg_priv
->scan_request
) {
2895 WL_SCAN("result without cfg80211 request\n");
2899 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2900 WL_ERR("Invalid bss_count %d: ignoring\n",
2901 escan_result_le
->bss_count
);
2904 bss_info_le
= &escan_result_le
->bss_info_le
;
2906 bi_length
= le32_to_cpu(bss_info_le
->length
);
2907 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2908 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2909 WL_ERR("Invalid bss_info length %d: ignoring\n",
2914 if (!(cfg_to_wiphy(cfg_priv
)->interface_modes
&
2915 BIT(NL80211_IFTYPE_ADHOC
))) {
2916 if (le16_to_cpu(bss_info_le
->capability
) &
2917 WLAN_CAPABILITY_IBSS
) {
2918 WL_ERR("Ignoring IBSS result\n");
2923 list
= (struct brcmf_scan_results
*)
2924 cfg_priv
->escan_info
.escan_buf
;
2925 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2926 WL_ERR("Buffer is too small: ignoring\n");
2930 for (i
= 0; i
< list
->count
; i
++) {
2931 bss
= bss
? (struct brcmf_bss_info_le
*)
2932 ((unsigned char *)bss
+
2933 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2934 if (brcmf_compare_update_same_bss(bss
, bss_info_le
))
2937 memcpy(&(cfg_priv
->escan_info
.escan_buf
[list
->buflen
]),
2938 bss_info_le
, bi_length
);
2939 list
->version
= le32_to_cpu(bss_info_le
->version
);
2940 list
->buflen
+= bi_length
;
2943 cfg_priv
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2944 if (cfg_priv
->scan_request
) {
2945 cfg_priv
->bss_list
= (struct brcmf_scan_results
*)
2946 cfg_priv
->escan_info
.escan_buf
;
2947 brcmf_inform_bss(cfg_priv
);
2948 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2949 brcmf_notify_escan_complete(cfg_priv
, ndev
, aborted
,
2952 WL_ERR("Unexpected scan result 0x%x\n", status
);
2958 static void brcmf_init_escan(struct brcmf_cfg80211_priv
*cfg_priv
)
2961 if (cfg_priv
->escan_on
) {
2962 cfg_priv
->el
.handler
[BRCMF_E_ESCAN_RESULT
] =
2963 brcmf_cfg80211_escan_handler
;
2964 cfg_priv
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2965 /* Init scan_timeout timer */
2966 init_timer(&cfg_priv
->escan_timeout
);
2967 cfg_priv
->escan_timeout
.data
= (unsigned long) cfg_priv
;
2968 cfg_priv
->escan_timeout
.function
= brcmf_escan_timeout
;
2969 INIT_WORK(&cfg_priv
->escan_timeout_work
,
2970 brcmf_cfg80211_escan_timeout_worker
);
2974 static __always_inline
void brcmf_delay(u32 ms
)
2976 if (ms
< 1000 / HZ
) {
2984 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2986 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
2989 * Check for WL_STATUS_READY before any function call which
2990 * could result is bus access. Don't block the resume for
2991 * any driver error conditions
2993 WL_TRACE("Enter\n");
2995 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
))
2996 brcmf_invoke_iscan(wiphy_to_cfg(wiphy
));
3002 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
3003 struct cfg80211_wowlan
*wow
)
3005 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
3006 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
3008 WL_TRACE("Enter\n");
3011 * Check for WL_STATUS_READY before any function call which
3012 * could result is bus access. Don't block the suspend for
3013 * any driver error conditions
3017 * While going to suspend if associated with AP disassociate
3018 * from AP to save power while system is in suspended state
3020 if ((test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
) ||
3021 test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) &&
3022 test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
3023 WL_INFO("Disassociating from AP"
3024 " while entering suspend state\n");
3025 brcmf_link_down(cfg_priv
);
3028 * Make sure WPA_Supplicant receives all the event
3029 * generated due to DISASSOC call to the fw to keep
3030 * the state fw and WPA_Supplicant state consistent
3035 set_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
3036 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
))
3037 brcmf_term_iscan(cfg_priv
);
3039 if (cfg_priv
->scan_request
) {
3040 /* Indidate scan abort to cfg80211 layer */
3041 WL_INFO("Terminating scan in progress\n");
3042 cfg80211_scan_done(cfg_priv
->scan_request
, true);
3043 cfg_priv
->scan_request
= NULL
;
3045 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
3046 clear_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
3048 /* Turn off watchdog timer */
3049 if (test_bit(WL_STATUS_READY
, &cfg_priv
->status
))
3050 brcmf_set_mpc(ndev
, 1);
3058 brcmf_dev_bufvar_set(struct net_device
*ndev
, s8
*name
, s8
*buf
, s32 len
)
3060 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
3063 buflen
= brcmf_c_mkiovar(name
, buf
, len
, cfg_priv
->dcmd_buf
,
3067 return brcmf_exec_dcmd(ndev
, BRCMF_C_SET_VAR
, cfg_priv
->dcmd_buf
,
3072 brcmf_dev_bufvar_get(struct net_device
*ndev
, s8
*name
, s8
*buf
,
3075 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
3079 len
= brcmf_c_mkiovar(name
, NULL
, 0, cfg_priv
->dcmd_buf
,
3082 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_GET_VAR
, cfg_priv
->dcmd_buf
,
3085 WL_ERR("error (%d)\n", err
);
3088 memcpy(buf
, cfg_priv
->dcmd_buf
, buf_len
);
3094 brcmf_update_pmklist(struct net_device
*ndev
,
3095 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
3100 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
3102 WL_CONN("No of elements %d\n", pmkid_len
);
3103 for (i
= 0; i
< pmkid_len
; i
++) {
3104 WL_CONN("PMKID[%d]: %pM =\n", i
,
3105 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
3106 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
3107 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
3111 brcmf_dev_bufvar_set(ndev
, "pmkid_info", (char *)pmk_list
,
3118 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3119 struct cfg80211_pmksa
*pmksa
)
3121 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
3122 struct pmkid_list
*pmkids
= &cfg_priv
->pmk_list
->pmkids
;
3127 WL_TRACE("Enter\n");
3128 if (!check_sys_up(wiphy
))
3131 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
3132 for (i
= 0; i
< pmkid_len
; i
++)
3133 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
3135 if (i
< WL_NUM_PMKIDS_MAX
) {
3136 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
3137 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3138 if (i
== pmkid_len
) {
3140 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
3145 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3146 pmkids
->pmkid
[pmkid_len
].BSSID
);
3147 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
3148 WL_CONN("%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
3150 err
= brcmf_update_pmklist(ndev
, cfg_priv
->pmk_list
, err
);
3157 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3158 struct cfg80211_pmksa
*pmksa
)
3160 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
3161 struct pmkid_list pmkid
;
3165 WL_TRACE("Enter\n");
3166 if (!check_sys_up(wiphy
))
3169 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
3170 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3172 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3173 &pmkid
.pmkid
[0].BSSID
);
3174 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
3175 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
3177 pmkid_len
= le32_to_cpu(cfg_priv
->pmk_list
->pmkids
.npmkid
);
3178 for (i
= 0; i
< pmkid_len
; i
++)
3180 (pmksa
->bssid
, &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
3185 && (i
< pmkid_len
)) {
3186 memset(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
], 0,
3187 sizeof(struct pmkid
));
3188 for (; i
< (pmkid_len
- 1); i
++) {
3189 memcpy(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
3190 &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
3192 memcpy(&cfg_priv
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
3193 &cfg_priv
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
3196 cfg_priv
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
3200 err
= brcmf_update_pmklist(ndev
, cfg_priv
->pmk_list
, err
);
3208 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
3210 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
3213 WL_TRACE("Enter\n");
3214 if (!check_sys_up(wiphy
))
3217 memset(cfg_priv
->pmk_list
, 0, sizeof(*cfg_priv
->pmk_list
));
3218 err
= brcmf_update_pmklist(ndev
, cfg_priv
->pmk_list
, err
);
3225 #ifdef CONFIG_NL80211_TESTMODE
3226 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
3228 struct brcmf_cfg80211_priv
*cfg_priv
= wiphy_to_cfg(wiphy
);
3229 struct net_device
*ndev
= cfg_priv
->wdev
->netdev
;
3230 struct brcmf_dcmd
*dcmd
= data
;
3231 struct sk_buff
*reply
;
3234 ret
= brcmf_netlink_dcmd(ndev
, dcmd
);
3236 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3237 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3238 ret
= cfg80211_testmode_reply(reply
);
3244 static struct cfg80211_ops wl_cfg80211_ops
= {
3245 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
3246 .scan
= brcmf_cfg80211_scan
,
3247 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
3248 .join_ibss
= brcmf_cfg80211_join_ibss
,
3249 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
3250 .get_station
= brcmf_cfg80211_get_station
,
3251 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
3252 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
3253 .add_key
= brcmf_cfg80211_add_key
,
3254 .del_key
= brcmf_cfg80211_del_key
,
3255 .get_key
= brcmf_cfg80211_get_key
,
3256 .set_default_key
= brcmf_cfg80211_config_default_key
,
3257 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
3258 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
3259 .set_bitrate_mask
= brcmf_cfg80211_set_bitrate_mask
,
3260 .connect
= brcmf_cfg80211_connect
,
3261 .disconnect
= brcmf_cfg80211_disconnect
,
3262 .suspend
= brcmf_cfg80211_suspend
,
3263 .resume
= brcmf_cfg80211_resume
,
3264 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
3265 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
3266 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
3267 #ifdef CONFIG_NL80211_TESTMODE
3268 .testmode_cmd
= brcmf_cfg80211_testmode
3272 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
)
3278 return NL80211_IFTYPE_STATION
;
3280 return NL80211_IFTYPE_ADHOC
;
3282 return NL80211_IFTYPE_UNSPECIFIED
;
3288 static struct wireless_dev
*brcmf_alloc_wdev(s32 sizeof_iface
,
3289 struct device
*ndev
)
3291 struct wireless_dev
*wdev
;
3294 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
3296 return ERR_PTR(-ENOMEM
);
3299 wiphy_new(&wl_cfg80211_ops
,
3300 sizeof(struct brcmf_cfg80211_priv
) + sizeof_iface
);
3302 WL_ERR("Could not allocate wiphy device\n");
3306 set_wiphy_dev(wdev
->wiphy
, ndev
);
3307 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
3308 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
3309 wdev
->wiphy
->interface_modes
=
3310 BIT(NL80211_IFTYPE_STATION
) | BIT(NL80211_IFTYPE_ADHOC
);
3311 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
3312 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
3313 * it as 11a by default.
3314 * This will be updated with
3317 * if phy has 11n capability
3319 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3320 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
3321 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
3322 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
3326 err
= wiphy_register(wdev
->wiphy
);
3328 WL_ERR("Could not register wiphy device (%d)\n", err
);
3329 goto wiphy_register_out
;
3334 wiphy_free(wdev
->wiphy
);
3339 return ERR_PTR(err
);
3342 static void brcmf_free_wdev(struct brcmf_cfg80211_priv
*cfg_priv
)
3344 struct wireless_dev
*wdev
= cfg_priv
->wdev
;
3347 WL_ERR("wdev is invalid\n");
3350 wiphy_unregister(wdev
->wiphy
);
3351 wiphy_free(wdev
->wiphy
);
3353 cfg_priv
->wdev
= NULL
;
3356 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv
*cfg_priv
,
3357 const struct brcmf_event_msg
*e
)
3359 u32 event
= be32_to_cpu(e
->event_type
);
3360 u32 status
= be32_to_cpu(e
->status
);
3362 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
3363 WL_CONN("Processing set ssid\n");
3364 cfg_priv
->link_up
= true;
3371 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv
*cfg_priv
,
3372 const struct brcmf_event_msg
*e
)
3374 u32 event
= be32_to_cpu(e
->event_type
);
3375 u16 flags
= be16_to_cpu(e
->flags
);
3377 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
3378 WL_CONN("Processing link down\n");
3384 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv
*cfg_priv
,
3385 const struct brcmf_event_msg
*e
)
3387 u32 event
= be32_to_cpu(e
->event_type
);
3388 u32 status
= be32_to_cpu(e
->status
);
3390 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
3391 WL_CONN("Processing Link %s & no network found\n",
3392 be16_to_cpu(e
->flags
) & BRCMF_EVENT_MSG_LINK
?
3397 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
3398 WL_CONN("Processing connecting & no network found\n");
3405 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
)
3407 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
3409 kfree(conn_info
->req_ie
);
3410 conn_info
->req_ie
= NULL
;
3411 conn_info
->req_ie_len
= 0;
3412 kfree(conn_info
->resp_ie
);
3413 conn_info
->resp_ie
= NULL
;
3414 conn_info
->resp_ie_len
= 0;
3417 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_priv
*cfg_priv
)
3419 struct net_device
*ndev
= cfg_to_ndev(cfg_priv
);
3420 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
3421 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
3426 brcmf_clear_assoc_ies(cfg_priv
);
3428 err
= brcmf_dev_bufvar_get(ndev
, "assoc_info", cfg_priv
->extra_buf
,
3431 WL_ERR("could not get assoc info (%d)\n", err
);
3435 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg_priv
->extra_buf
;
3436 req_len
= le32_to_cpu(assoc_info
->req_len
);
3437 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
3439 err
= brcmf_dev_bufvar_get(ndev
, "assoc_req_ies",
3440 cfg_priv
->extra_buf
,
3443 WL_ERR("could not get assoc req (%d)\n", err
);
3446 conn_info
->req_ie_len
= req_len
;
3448 kmemdup(cfg_priv
->extra_buf
, conn_info
->req_ie_len
,
3451 conn_info
->req_ie_len
= 0;
3452 conn_info
->req_ie
= NULL
;
3455 err
= brcmf_dev_bufvar_get(ndev
, "assoc_resp_ies",
3456 cfg_priv
->extra_buf
,
3459 WL_ERR("could not get assoc resp (%d)\n", err
);
3462 conn_info
->resp_ie_len
= resp_len
;
3463 conn_info
->resp_ie
=
3464 kmemdup(cfg_priv
->extra_buf
, conn_info
->resp_ie_len
,
3467 conn_info
->resp_ie_len
= 0;
3468 conn_info
->resp_ie
= NULL
;
3470 WL_CONN("req len (%d) resp len (%d)\n",
3471 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
3477 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv
*cfg_priv
,
3478 struct net_device
*ndev
,
3479 const struct brcmf_event_msg
*e
)
3481 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
3482 struct wiphy
*wiphy
= cfg_to_wiphy(cfg_priv
);
3483 struct brcmf_channel_info_le channel_le
;
3484 struct ieee80211_channel
*notify_channel
;
3485 struct ieee80211_supported_band
*band
;
3490 WL_TRACE("Enter\n");
3492 brcmf_get_assoc_ies(cfg_priv
);
3493 brcmf_update_prof(cfg_priv
, NULL
, &e
->addr
, WL_PROF_BSSID
);
3494 brcmf_update_bss_info(cfg_priv
);
3496 brcmf_exec_dcmd(ndev
, BRCMF_C_GET_CHANNEL
, &channel_le
,
3497 sizeof(channel_le
));
3499 target_channel
= le32_to_cpu(channel_le
.target_channel
);
3500 WL_CONN("Roamed to channel %d\n", target_channel
);
3502 if (target_channel
<= CH_MAX_2G_CHANNEL
)
3503 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
3505 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
3507 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
3508 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
3510 cfg80211_roamed(ndev
, notify_channel
,
3511 (u8
*)brcmf_read_prof(cfg_priv
, WL_PROF_BSSID
),
3512 conn_info
->req_ie
, conn_info
->req_ie_len
,
3513 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
3514 WL_CONN("Report roaming result\n");
3516 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
3522 brcmf_bss_connect_done(struct brcmf_cfg80211_priv
*cfg_priv
,
3523 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
3526 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg_priv
);
3529 WL_TRACE("Enter\n");
3531 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) {
3533 brcmf_get_assoc_ies(cfg_priv
);
3534 brcmf_update_prof(cfg_priv
, NULL
, &e
->addr
,
3536 brcmf_update_bss_info(cfg_priv
);
3538 cfg80211_connect_result(ndev
,
3539 (u8
*)brcmf_read_prof(cfg_priv
,
3542 conn_info
->req_ie_len
,
3544 conn_info
->resp_ie_len
,
3545 completed
? WLAN_STATUS_SUCCESS
:
3546 WLAN_STATUS_AUTH_TIMEOUT
,
3549 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
3550 WL_CONN("Report connect result - connection %s\n",
3551 completed
? "succeeded" : "failed");
3558 brcmf_notify_connect_status(struct brcmf_cfg80211_priv
*cfg_priv
,
3559 struct net_device
*ndev
,
3560 const struct brcmf_event_msg
*e
, void *data
)
3564 if (brcmf_is_linkup(cfg_priv
, e
)) {
3565 WL_CONN("Linkup\n");
3566 if (brcmf_is_ibssmode(cfg_priv
)) {
3567 brcmf_update_prof(cfg_priv
, NULL
, (void *)e
->addr
,
3569 wl_inform_ibss(cfg_priv
, ndev
, e
->addr
);
3570 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
3571 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
3572 set_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
);
3574 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, true);
3575 } else if (brcmf_is_linkdown(cfg_priv
, e
)) {
3576 WL_CONN("Linkdown\n");
3577 if (brcmf_is_ibssmode(cfg_priv
)) {
3578 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
3579 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
3581 brcmf_link_down(cfg_priv
);
3583 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, false);
3584 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
3585 &cfg_priv
->status
)) {
3586 cfg80211_disconnected(ndev
, 0, NULL
, 0,
3588 brcmf_link_down(cfg_priv
);
3591 brcmf_init_prof(cfg_priv
->profile
);
3592 } else if (brcmf_is_nonetwork(cfg_priv
, e
)) {
3593 if (brcmf_is_ibssmode(cfg_priv
))
3594 clear_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
);
3596 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, false);
3603 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv
*cfg_priv
,
3604 struct net_device
*ndev
,
3605 const struct brcmf_event_msg
*e
, void *data
)
3608 u32 event
= be32_to_cpu(e
->event_type
);
3609 u32 status
= be32_to_cpu(e
->status
);
3611 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
3612 if (test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
))
3613 brcmf_bss_roaming_done(cfg_priv
, ndev
, e
);
3615 brcmf_bss_connect_done(cfg_priv
, ndev
, e
, true);
3622 brcmf_notify_mic_status(struct brcmf_cfg80211_priv
*cfg_priv
,
3623 struct net_device
*ndev
,
3624 const struct brcmf_event_msg
*e
, void *data
)
3626 u16 flags
= be16_to_cpu(e
->flags
);
3627 enum nl80211_key_type key_type
;
3629 if (flags
& BRCMF_EVENT_MSG_GROUP
)
3630 key_type
= NL80211_KEYTYPE_GROUP
;
3632 key_type
= NL80211_KEYTYPE_PAIRWISE
;
3634 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
3641 brcmf_notify_scan_status(struct brcmf_cfg80211_priv
*cfg_priv
,
3642 struct net_device
*ndev
,
3643 const struct brcmf_event_msg
*e
, void *data
)
3645 struct brcmf_channel_info_le channel_inform_le
;
3646 struct brcmf_scan_results_le
*bss_list_le
;
3647 u32 len
= WL_SCAN_BUF_MAX
;
3649 bool scan_abort
= false;
3652 WL_TRACE("Enter\n");
3654 if (cfg_priv
->iscan_on
&& cfg_priv
->iscan_kickstart
) {
3656 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv
));
3659 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
)) {
3660 WL_ERR("Scan complete while device not scanning\n");
3666 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_GET_CHANNEL
, &channel_inform_le
,
3667 sizeof(channel_inform_le
));
3669 WL_ERR("scan busy (%d)\n", err
);
3673 scan_channel
= le32_to_cpu(channel_inform_le
.scan_channel
);
3675 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel
);
3676 cfg_priv
->bss_list
= cfg_priv
->scan_results
;
3677 bss_list_le
= (struct brcmf_scan_results_le
*) cfg_priv
->bss_list
;
3679 memset(cfg_priv
->scan_results
, 0, len
);
3680 bss_list_le
->buflen
= cpu_to_le32(len
);
3681 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SCAN_RESULTS
,
3682 cfg_priv
->scan_results
, len
);
3684 WL_ERR("%s Scan_results error (%d)\n", ndev
->name
, err
);
3689 cfg_priv
->scan_results
->buflen
= le32_to_cpu(bss_list_le
->buflen
);
3690 cfg_priv
->scan_results
->version
= le32_to_cpu(bss_list_le
->version
);
3691 cfg_priv
->scan_results
->count
= le32_to_cpu(bss_list_le
->count
);
3693 err
= brcmf_inform_bss(cfg_priv
);
3698 if (cfg_priv
->scan_request
) {
3699 WL_SCAN("calling cfg80211_scan_done\n");
3700 cfg80211_scan_done(cfg_priv
->scan_request
, scan_abort
);
3701 brcmf_set_mpc(ndev
, 1);
3702 cfg_priv
->scan_request
= NULL
;
3710 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
3712 conf
->mode
= (u32
)-1;
3713 conf
->frag_threshold
= (u32
)-1;
3714 conf
->rts_threshold
= (u32
)-1;
3715 conf
->retry_short
= (u32
)-1;
3716 conf
->retry_long
= (u32
)-1;
3717 conf
->tx_power
= -1;
3720 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop
*el
)
3722 memset(el
, 0, sizeof(*el
));
3723 el
->handler
[BRCMF_E_SCAN_COMPLETE
] = brcmf_notify_scan_status
;
3724 el
->handler
[BRCMF_E_LINK
] = brcmf_notify_connect_status
;
3725 el
->handler
[BRCMF_E_ROAM
] = brcmf_notify_roaming_status
;
3726 el
->handler
[BRCMF_E_MIC_ERROR
] = brcmf_notify_mic_status
;
3727 el
->handler
[BRCMF_E_SET_SSID
] = brcmf_notify_connect_status
;
3730 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
)
3732 kfree(cfg_priv
->scan_results
);
3733 cfg_priv
->scan_results
= NULL
;
3734 kfree(cfg_priv
->bss_info
);
3735 cfg_priv
->bss_info
= NULL
;
3736 kfree(cfg_priv
->conf
);
3737 cfg_priv
->conf
= NULL
;
3738 kfree(cfg_priv
->profile
);
3739 cfg_priv
->profile
= NULL
;
3740 kfree(cfg_priv
->scan_req_int
);
3741 cfg_priv
->scan_req_int
= NULL
;
3742 kfree(cfg_priv
->escan_ioctl_buf
);
3743 cfg_priv
->escan_ioctl_buf
= NULL
;
3744 kfree(cfg_priv
->dcmd_buf
);
3745 cfg_priv
->dcmd_buf
= NULL
;
3746 kfree(cfg_priv
->extra_buf
);
3747 cfg_priv
->extra_buf
= NULL
;
3748 kfree(cfg_priv
->iscan
);
3749 cfg_priv
->iscan
= NULL
;
3750 kfree(cfg_priv
->pmk_list
);
3751 cfg_priv
->pmk_list
= NULL
;
3754 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_priv
*cfg_priv
)
3756 cfg_priv
->scan_results
= kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
3757 if (!cfg_priv
->scan_results
)
3758 goto init_priv_mem_out
;
3759 cfg_priv
->conf
= kzalloc(sizeof(*cfg_priv
->conf
), GFP_KERNEL
);
3760 if (!cfg_priv
->conf
)
3761 goto init_priv_mem_out
;
3762 cfg_priv
->profile
= kzalloc(sizeof(*cfg_priv
->profile
), GFP_KERNEL
);
3763 if (!cfg_priv
->profile
)
3764 goto init_priv_mem_out
;
3765 cfg_priv
->bss_info
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
3766 if (!cfg_priv
->bss_info
)
3767 goto init_priv_mem_out
;
3768 cfg_priv
->scan_req_int
= kzalloc(sizeof(*cfg_priv
->scan_req_int
),
3770 if (!cfg_priv
->scan_req_int
)
3771 goto init_priv_mem_out
;
3772 cfg_priv
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
3773 if (!cfg_priv
->escan_ioctl_buf
)
3774 goto init_priv_mem_out
;
3775 cfg_priv
->dcmd_buf
= kzalloc(WL_DCMD_LEN_MAX
, GFP_KERNEL
);
3776 if (!cfg_priv
->dcmd_buf
)
3777 goto init_priv_mem_out
;
3778 cfg_priv
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3779 if (!cfg_priv
->extra_buf
)
3780 goto init_priv_mem_out
;
3781 cfg_priv
->iscan
= kzalloc(sizeof(*cfg_priv
->iscan
), GFP_KERNEL
);
3782 if (!cfg_priv
->iscan
)
3783 goto init_priv_mem_out
;
3784 cfg_priv
->pmk_list
= kzalloc(sizeof(*cfg_priv
->pmk_list
), GFP_KERNEL
);
3785 if (!cfg_priv
->pmk_list
)
3786 goto init_priv_mem_out
;
3791 brcmf_deinit_priv_mem(cfg_priv
);
3797 * retrieve first queued event from head
3800 static struct brcmf_cfg80211_event_q
*brcmf_deq_event(
3801 struct brcmf_cfg80211_priv
*cfg_priv
)
3803 struct brcmf_cfg80211_event_q
*e
= NULL
;
3805 spin_lock_irq(&cfg_priv
->evt_q_lock
);
3806 if (!list_empty(&cfg_priv
->evt_q_list
)) {
3807 e
= list_first_entry(&cfg_priv
->evt_q_list
,
3808 struct brcmf_cfg80211_event_q
, evt_q_list
);
3809 list_del(&e
->evt_q_list
);
3811 spin_unlock_irq(&cfg_priv
->evt_q_lock
);
3817 * push event to tail of the queue
3819 * remark: this function may not sleep as it is called in atomic context.
3823 brcmf_enq_event(struct brcmf_cfg80211_priv
*cfg_priv
, u32 event
,
3824 const struct brcmf_event_msg
*msg
, void *data
)
3826 struct brcmf_cfg80211_event_q
*e
;
3832 total_len
= sizeof(struct brcmf_cfg80211_event_q
);
3834 data_len
= be32_to_cpu(msg
->datalen
);
3837 total_len
+= data_len
;
3838 e
= kzalloc(total_len
, GFP_ATOMIC
);
3843 memcpy(&e
->emsg
, msg
, sizeof(struct brcmf_event_msg
));
3845 memcpy(&e
->edata
, data
, data_len
);
3847 spin_lock_irqsave(&cfg_priv
->evt_q_lock
, flags
);
3848 list_add_tail(&e
->evt_q_list
, &cfg_priv
->evt_q_list
);
3849 spin_unlock_irqrestore(&cfg_priv
->evt_q_lock
, flags
);
3854 static void brcmf_put_event(struct brcmf_cfg80211_event_q
*e
)
3859 static void brcmf_cfg80211_event_handler(struct work_struct
*work
)
3861 struct brcmf_cfg80211_priv
*cfg_priv
=
3862 container_of(work
, struct brcmf_cfg80211_priv
,
3864 struct brcmf_cfg80211_event_q
*e
;
3866 e
= brcmf_deq_event(cfg_priv
);
3868 WL_ERR("event queue empty...\n");
3873 WL_INFO("event type (%d)\n", e
->etype
);
3874 if (cfg_priv
->el
.handler
[e
->etype
])
3875 cfg_priv
->el
.handler
[e
->etype
](cfg_priv
,
3876 cfg_to_ndev(cfg_priv
),
3877 &e
->emsg
, e
->edata
);
3879 WL_INFO("Unknown Event (%d): ignoring\n", e
->etype
);
3881 } while ((e
= brcmf_deq_event(cfg_priv
)));
3885 static void brcmf_init_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
3887 spin_lock_init(&cfg_priv
->evt_q_lock
);
3888 INIT_LIST_HEAD(&cfg_priv
->evt_q_list
);
3891 static void brcmf_flush_eq(struct brcmf_cfg80211_priv
*cfg_priv
)
3893 struct brcmf_cfg80211_event_q
*e
;
3895 spin_lock_irq(&cfg_priv
->evt_q_lock
);
3896 while (!list_empty(&cfg_priv
->evt_q_list
)) {
3897 e
= list_first_entry(&cfg_priv
->evt_q_list
,
3898 struct brcmf_cfg80211_event_q
, evt_q_list
);
3899 list_del(&e
->evt_q_list
);
3902 spin_unlock_irq(&cfg_priv
->evt_q_lock
);
3905 static s32
wl_init_priv(struct brcmf_cfg80211_priv
*cfg_priv
)
3909 cfg_priv
->scan_request
= NULL
;
3910 cfg_priv
->pwr_save
= true;
3911 #ifdef CONFIG_BRCMISCAN
3912 cfg_priv
->iscan_on
= true; /* iscan on & off switch.
3913 we enable iscan per default */
3914 cfg_priv
->escan_on
= false; /* escan on & off switch.
3915 we disable escan per default */
3917 cfg_priv
->iscan_on
= false; /* iscan on & off switch.
3918 we disable iscan per default */
3919 cfg_priv
->escan_on
= true; /* escan on & off switch.
3920 we enable escan per default */
3922 cfg_priv
->roam_on
= true; /* roam on & off switch.
3923 we enable roam per default */
3925 cfg_priv
->iscan_kickstart
= false;
3926 cfg_priv
->active_scan
= true; /* we do active scan for
3927 specific scan per default */
3928 cfg_priv
->dongle_up
= false; /* dongle is not up yet */
3929 brcmf_init_eq(cfg_priv
);
3930 err
= brcmf_init_priv_mem(cfg_priv
);
3933 INIT_WORK(&cfg_priv
->event_work
, brcmf_cfg80211_event_handler
);
3934 brcmf_init_eloop_handler(&cfg_priv
->el
);
3935 mutex_init(&cfg_priv
->usr_sync
);
3936 err
= brcmf_init_iscan(cfg_priv
);
3939 brcmf_init_escan(cfg_priv
);
3940 brcmf_init_conf(cfg_priv
->conf
);
3941 brcmf_init_prof(cfg_priv
->profile
);
3942 brcmf_link_down(cfg_priv
);
3947 static void wl_deinit_priv(struct brcmf_cfg80211_priv
*cfg_priv
)
3949 cancel_work_sync(&cfg_priv
->event_work
);
3950 cfg_priv
->dongle_up
= false; /* dongle down */
3951 brcmf_flush_eq(cfg_priv
);
3952 brcmf_link_down(cfg_priv
);
3953 brcmf_term_iscan(cfg_priv
);
3954 brcmf_deinit_priv_mem(cfg_priv
);
3957 struct brcmf_cfg80211_dev
*brcmf_cfg80211_attach(struct net_device
*ndev
,
3958 struct device
*busdev
,
3961 struct wireless_dev
*wdev
;
3962 struct brcmf_cfg80211_priv
*cfg_priv
;
3963 struct brcmf_cfg80211_iface
*ci
;
3964 struct brcmf_cfg80211_dev
*cfg_dev
;
3968 WL_ERR("ndev is invalid\n");
3971 cfg_dev
= kzalloc(sizeof(struct brcmf_cfg80211_dev
), GFP_KERNEL
);
3975 wdev
= brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface
), busdev
);
3981 wdev
->iftype
= brcmf_mode_to_nl80211_iftype(WL_MODE_BSS
);
3982 cfg_priv
= wdev_to_cfg(wdev
);
3983 cfg_priv
->wdev
= wdev
;
3984 cfg_priv
->pub
= data
;
3985 ci
= (struct brcmf_cfg80211_iface
*)&cfg_priv
->ci
;
3986 ci
->cfg_priv
= cfg_priv
;
3987 ndev
->ieee80211_ptr
= wdev
;
3988 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
3989 wdev
->netdev
= ndev
;
3990 err
= wl_init_priv(cfg_priv
);
3992 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
3993 goto cfg80211_attach_out
;
3995 brcmf_set_drvdata(cfg_dev
, ci
);
3999 cfg80211_attach_out
:
4000 brcmf_free_wdev(cfg_priv
);
4005 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev
*cfg_dev
)
4007 struct brcmf_cfg80211_priv
*cfg_priv
;
4009 cfg_priv
= brcmf_priv_get(cfg_dev
);
4011 wl_deinit_priv(cfg_priv
);
4012 brcmf_free_wdev(cfg_priv
);
4013 brcmf_set_drvdata(cfg_dev
, NULL
);
4018 brcmf_cfg80211_event(struct net_device
*ndev
,
4019 const struct brcmf_event_msg
*e
, void *data
)
4021 u32 event_type
= be32_to_cpu(e
->event_type
);
4022 struct brcmf_cfg80211_priv
*cfg_priv
= ndev_to_cfg(ndev
);
4024 if (!brcmf_enq_event(cfg_priv
, event_type
, e
, data
))
4025 schedule_work(&cfg_priv
->event_work
);
4028 static s32
brcmf_dongle_mode(struct net_device
*ndev
, s32 iftype
)
4034 case NL80211_IFTYPE_MONITOR
:
4035 case NL80211_IFTYPE_WDS
:
4036 WL_ERR("type (%d) : currently we do not support this mode\n",
4040 case NL80211_IFTYPE_ADHOC
:
4043 case NL80211_IFTYPE_STATION
:
4048 WL_ERR("invalid type (%d)\n", iftype
);
4051 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_INFRA
, &infra
);
4053 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
4060 static s32
brcmf_dongle_eventmsg(struct net_device
*ndev
)
4062 /* Room for "event_msgs" + '\0' + bitvec */
4063 s8 iovbuf
[BRCMF_EVENTING_MASK_LEN
+ 12];
4064 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
4067 WL_TRACE("Enter\n");
4069 /* Setup event_msgs */
4070 brcmf_c_mkiovar("event_msgs", eventmask
, BRCMF_EVENTING_MASK_LEN
,
4071 iovbuf
, sizeof(iovbuf
));
4072 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_GET_VAR
, iovbuf
, sizeof(iovbuf
));
4074 WL_ERR("Get event_msgs error (%d)\n", err
);
4075 goto dongle_eventmsg_out
;
4077 memcpy(eventmask
, iovbuf
, BRCMF_EVENTING_MASK_LEN
);
4079 setbit(eventmask
, BRCMF_E_SET_SSID
);
4080 setbit(eventmask
, BRCMF_E_ROAM
);
4081 setbit(eventmask
, BRCMF_E_PRUNE
);
4082 setbit(eventmask
, BRCMF_E_AUTH
);
4083 setbit(eventmask
, BRCMF_E_REASSOC
);
4084 setbit(eventmask
, BRCMF_E_REASSOC_IND
);
4085 setbit(eventmask
, BRCMF_E_DEAUTH_IND
);
4086 setbit(eventmask
, BRCMF_E_DISASSOC_IND
);
4087 setbit(eventmask
, BRCMF_E_DISASSOC
);
4088 setbit(eventmask
, BRCMF_E_JOIN
);
4089 setbit(eventmask
, BRCMF_E_ASSOC_IND
);
4090 setbit(eventmask
, BRCMF_E_PSK_SUP
);
4091 setbit(eventmask
, BRCMF_E_LINK
);
4092 setbit(eventmask
, BRCMF_E_NDIS_LINK
);
4093 setbit(eventmask
, BRCMF_E_MIC_ERROR
);
4094 setbit(eventmask
, BRCMF_E_PMKID_CACHE
);
4095 setbit(eventmask
, BRCMF_E_TXFAIL
);
4096 setbit(eventmask
, BRCMF_E_JOIN_START
);
4097 setbit(eventmask
, BRCMF_E_SCAN_COMPLETE
);
4098 setbit(eventmask
, BRCMF_E_ESCAN_RESULT
);
4100 brcmf_c_mkiovar("event_msgs", eventmask
, BRCMF_EVENTING_MASK_LEN
,
4101 iovbuf
, sizeof(iovbuf
));
4102 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_VAR
, iovbuf
, sizeof(iovbuf
));
4104 WL_ERR("Set event_msgs error (%d)\n", err
);
4105 goto dongle_eventmsg_out
;
4108 dongle_eventmsg_out
:
4114 brcmf_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
4118 __le32 roamtrigger
[2];
4119 __le32 roam_delta
[2];
4124 * Setup timeout if Beacons are lost and roam is
4125 * off to report link down
4128 bcn_to_le
= cpu_to_le32(bcn_timeout
);
4129 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le
,
4130 sizeof(bcn_to_le
), iovbuf
, sizeof(iovbuf
));
4131 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_VAR
,
4132 iovbuf
, sizeof(iovbuf
));
4134 WL_ERR("bcn_timeout error (%d)\n", err
);
4135 goto dongle_rom_out
;
4140 * Enable/Disable built-in roaming to allow supplicant
4141 * to take care of roaming
4143 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
4144 roamvar_le
= cpu_to_le32(roamvar
);
4145 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le
,
4146 sizeof(roamvar_le
), iovbuf
, sizeof(iovbuf
));
4147 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_VAR
, iovbuf
, sizeof(iovbuf
));
4149 WL_ERR("roam_off error (%d)\n", err
);
4150 goto dongle_rom_out
;
4153 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
4154 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4155 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_ROAM_TRIGGER
,
4156 (void *)roamtrigger
, sizeof(roamtrigger
));
4158 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
4159 goto dongle_rom_out
;
4162 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
4163 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4164 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_ROAM_DELTA
,
4165 (void *)roam_delta
, sizeof(roam_delta
));
4167 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
4168 goto dongle_rom_out
;
4176 brcmf_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
4177 s32 scan_unassoc_time
, s32 scan_passive_time
)
4180 __le32 scan_assoc_tm_le
= cpu_to_le32(scan_assoc_time
);
4181 __le32 scan_unassoc_tm_le
= cpu_to_le32(scan_unassoc_time
);
4182 __le32 scan_passive_tm_le
= cpu_to_le32(scan_passive_time
);
4184 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
4185 &scan_assoc_tm_le
, sizeof(scan_assoc_tm_le
));
4187 if (err
== -EOPNOTSUPP
)
4188 WL_INFO("Scan assoc time is not supported\n");
4190 WL_ERR("Scan assoc time error (%d)\n", err
);
4191 goto dongle_scantime_out
;
4193 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
4194 &scan_unassoc_tm_le
, sizeof(scan_unassoc_tm_le
));
4196 if (err
== -EOPNOTSUPP
)
4197 WL_INFO("Scan unassoc time is not supported\n");
4199 WL_ERR("Scan unassoc time error (%d)\n", err
);
4200 goto dongle_scantime_out
;
4203 err
= brcmf_exec_dcmd(ndev
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
4204 &scan_passive_tm_le
, sizeof(scan_passive_tm_le
));
4206 if (err
== -EOPNOTSUPP
)
4207 WL_INFO("Scan passive time is not supported\n");
4209 WL_ERR("Scan passive time error (%d)\n", err
);
4210 goto dongle_scantime_out
;
4213 dongle_scantime_out
:
4217 static s32
wl_update_wiphybands(struct brcmf_cfg80211_priv
*cfg_priv
)
4219 struct wiphy
*wiphy
;
4224 err
= brcmf_exec_dcmd(cfg_to_ndev(cfg_priv
), BRCM_GET_PHYLIST
,
4225 &phy_list
, sizeof(phy_list
));
4227 WL_ERR("error (%d)\n", err
);
4231 phy
= ((char *)&phy_list
)[1];
4232 WL_INFO("%c phy\n", phy
);
4233 if (phy
== 'n' || phy
== 'a') {
4234 wiphy
= cfg_to_wiphy(cfg_priv
);
4235 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4241 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_priv
*cfg_priv
)
4243 return wl_update_wiphybands(cfg_priv
);
4246 static s32
brcmf_config_dongle(struct brcmf_cfg80211_priv
*cfg_priv
)
4248 struct net_device
*ndev
;
4249 struct wireless_dev
*wdev
;
4253 if (cfg_priv
->dongle_up
)
4256 ndev
= cfg_to_ndev(cfg_priv
);
4257 wdev
= ndev
->ieee80211_ptr
;
4259 brcmf_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
4260 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4262 err
= brcmf_dongle_eventmsg(ndev
);
4264 goto default_conf_out
;
4266 power_mode
= cfg_priv
->pwr_save
? PM_FAST
: PM_OFF
;
4267 err
= brcmf_exec_dcmd_u32(ndev
, BRCMF_C_SET_PM
, &power_mode
);
4269 goto default_conf_out
;
4270 WL_INFO("power save set to %s\n",
4271 (power_mode
? "enabled" : "disabled"));
4273 err
= brcmf_dongle_roam(ndev
, (cfg_priv
->roam_on
? 0 : 1),
4276 goto default_conf_out
;
4277 err
= brcmf_dongle_mode(ndev
, wdev
->iftype
);
4278 if (err
&& err
!= -EINPROGRESS
)
4279 goto default_conf_out
;
4280 err
= brcmf_dongle_probecap(cfg_priv
);
4282 goto default_conf_out
;
4284 /* -EINPROGRESS: Call commit handler */
4288 cfg_priv
->dongle_up
= true;
4294 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv
*cfg_priv
)
4296 char buf
[10+IFNAMSIZ
];
4300 sprintf(buf
, "netdev:%s", cfg_to_ndev(cfg_priv
)->name
);
4301 cfg_priv
->debugfsdir
= debugfs_create_dir(buf
,
4302 cfg_to_wiphy(cfg_priv
)->debugfsdir
);
4304 fd
= debugfs_create_u16("beacon_int", S_IRUGO
, cfg_priv
->debugfsdir
,
4305 (u16
*)&cfg_priv
->profile
->beacon_interval
);
4311 fd
= debugfs_create_u8("dtim_period", S_IRUGO
, cfg_priv
->debugfsdir
,
4312 (u8
*)&cfg_priv
->profile
->dtim_period
);
4322 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv
*cfg_priv
)
4324 debugfs_remove_recursive(cfg_priv
->debugfsdir
);
4325 cfg_priv
->debugfsdir
= NULL
;
4328 static s32
__brcmf_cfg80211_up(struct brcmf_cfg80211_priv
*cfg_priv
)
4332 set_bit(WL_STATUS_READY
, &cfg_priv
->status
);
4334 brcmf_debugfs_add_netdev_params(cfg_priv
);
4336 err
= brcmf_config_dongle(cfg_priv
);
4340 brcmf_invoke_iscan(cfg_priv
);
4345 static s32
__brcmf_cfg80211_down(struct brcmf_cfg80211_priv
*cfg_priv
)
4348 * While going down, if associated with AP disassociate
4349 * from AP to save power
4351 if ((test_bit(WL_STATUS_CONNECTED
, &cfg_priv
->status
) ||
4352 test_bit(WL_STATUS_CONNECTING
, &cfg_priv
->status
)) &&
4353 test_bit(WL_STATUS_READY
, &cfg_priv
->status
)) {
4354 WL_INFO("Disassociating from AP");
4355 brcmf_link_down(cfg_priv
);
4357 /* Make sure WPA_Supplicant receives all the event
4358 generated due to DISASSOC call to the fw to keep
4359 the state fw and WPA_Supplicant state consistent
4364 set_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
4365 brcmf_term_iscan(cfg_priv
);
4366 if (cfg_priv
->scan_request
) {
4367 cfg80211_scan_done(cfg_priv
->scan_request
, true);
4368 /* May need to perform this to cover rmmod */
4369 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
4370 cfg_priv
->scan_request
= NULL
;
4372 clear_bit(WL_STATUS_READY
, &cfg_priv
->status
);
4373 clear_bit(WL_STATUS_SCANNING
, &cfg_priv
->status
);
4374 clear_bit(WL_STATUS_SCAN_ABORTING
, &cfg_priv
->status
);
4376 brcmf_debugfs_remove_netdev(cfg_priv
);
4381 s32
brcmf_cfg80211_up(struct brcmf_cfg80211_dev
*cfg_dev
)
4383 struct brcmf_cfg80211_priv
*cfg_priv
;
4386 cfg_priv
= brcmf_priv_get(cfg_dev
);
4387 mutex_lock(&cfg_priv
->usr_sync
);
4388 err
= __brcmf_cfg80211_up(cfg_priv
);
4389 mutex_unlock(&cfg_priv
->usr_sync
);
4394 s32
brcmf_cfg80211_down(struct brcmf_cfg80211_dev
*cfg_dev
)
4396 struct brcmf_cfg80211_priv
*cfg_priv
;
4399 cfg_priv
= brcmf_priv_get(cfg_dev
);
4400 mutex_lock(&cfg_priv
->usr_sync
);
4401 err
= __brcmf_cfg80211_down(cfg_priv
);
4402 mutex_unlock(&cfg_priv
->usr_sync
);
4407 static __used s32
brcmf_add_ie(struct brcmf_cfg80211_priv
*cfg_priv
,
4410 struct brcmf_cfg80211_ie
*ie
= &cfg_priv
->ie
;
4413 if (ie
->offset
+ l
+ 2 > WL_TLV_INFO_MAX
) {
4414 WL_ERR("ei crosses buffer boundary\n");
4417 ie
->buf
[ie
->offset
] = t
;
4418 ie
->buf
[ie
->offset
+ 1] = l
;
4419 memcpy(&ie
->buf
[ie
->offset
+ 2], v
, l
);
4420 ie
->offset
+= l
+ 2;