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"
40 #define BRCMF_SCAN_IE_LEN_MAX 2048
41 #define BRCMF_PNO_VERSION 2
42 #define BRCMF_PNO_TIME 30
43 #define BRCMF_PNO_REPEAT 4
44 #define BRCMF_PNO_FREQ_EXPO_MAX 3
45 #define BRCMF_PNO_MAX_PFN_COUNT 16
46 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
47 #define BRCMF_PNO_HIDDEN_BIT 2
48 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
49 #define BRCMF_PNO_SCAN_COMPLETE 1
50 #define BRCMF_PNO_SCAN_INCOMPLETE 0
52 #define TLV_LEN_OFF 1 /* length offset */
53 #define TLV_HDR_LEN 2 /* header length */
54 #define TLV_BODY_OFF 2 /* body offset */
55 #define TLV_OUI_LEN 3 /* oui id length */
56 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
57 #define WPA_OUI_TYPE 1
58 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
59 #define WME_OUI_TYPE 2
61 #define VS_IE_FIXED_HDR_LEN 6
62 #define WPA_IE_VERSION_LEN 2
63 #define WPA_IE_MIN_OUI_LEN 4
64 #define WPA_IE_SUITE_COUNT_LEN 2
66 #define WPA_CIPHER_NONE 0 /* None */
67 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
72 #define RSN_AKM_NONE 0 /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74 #define RSN_AKM_PSK 2 /* Pre-shared Key */
75 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
81 #define VNDR_IE_COUNT_OFFSET 4
82 #define VNDR_IE_PKTFLAG_OFFSET 8
83 #define VNDR_IE_VSIE_OFFSET 12
84 #define VNDR_IE_HDR_SIZE 12
85 #define VNDR_IE_BEACON_FLAG 0x1
86 #define VNDR_IE_PRBRSP_FLAG 0x2
87 #define MAX_VNDR_IE_NUMBER 5
89 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
90 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
92 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
93 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
95 static const u8 ether_bcast
[ETH_ALEN
] = {255, 255, 255, 255, 255, 255};
97 static u32 brcmf_dbg_level
= WL_DBG_ERR
;
99 static bool check_sys_up(struct wiphy
*wiphy
)
101 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
102 if (!test_bit(WL_STATUS_READY
, &cfg
->status
)) {
103 WL_INFO("device is not ready : status (%d)\n",
110 #define CHAN2G(_channel, _freq, _flags) { \
111 .band = IEEE80211_BAND_2GHZ, \
112 .center_freq = (_freq), \
113 .hw_value = (_channel), \
115 .max_antenna_gain = 0, \
119 #define CHAN5G(_channel, _flags) { \
120 .band = IEEE80211_BAND_5GHZ, \
121 .center_freq = 5000 + (5 * (_channel)), \
122 .hw_value = (_channel), \
124 .max_antenna_gain = 0, \
128 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
129 #define RATETAB_ENT(_rateid, _flags) \
131 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
132 .hw_value = (_rateid), \
136 static struct ieee80211_rate __wl_rates
[] = {
137 RATETAB_ENT(BRCM_RATE_1M
, 0),
138 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
139 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
140 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
141 RATETAB_ENT(BRCM_RATE_6M
, 0),
142 RATETAB_ENT(BRCM_RATE_9M
, 0),
143 RATETAB_ENT(BRCM_RATE_12M
, 0),
144 RATETAB_ENT(BRCM_RATE_18M
, 0),
145 RATETAB_ENT(BRCM_RATE_24M
, 0),
146 RATETAB_ENT(BRCM_RATE_36M
, 0),
147 RATETAB_ENT(BRCM_RATE_48M
, 0),
148 RATETAB_ENT(BRCM_RATE_54M
, 0),
151 #define wl_a_rates (__wl_rates + 4)
152 #define wl_a_rates_size 8
153 #define wl_g_rates (__wl_rates + 0)
154 #define wl_g_rates_size 12
156 static struct ieee80211_channel __wl_2ghz_channels
[] = {
173 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
174 CHAN5G(34, 0), CHAN5G(36, 0),
175 CHAN5G(38, 0), CHAN5G(40, 0),
176 CHAN5G(42, 0), CHAN5G(44, 0),
177 CHAN5G(46, 0), CHAN5G(48, 0),
178 CHAN5G(52, 0), CHAN5G(56, 0),
179 CHAN5G(60, 0), CHAN5G(64, 0),
180 CHAN5G(100, 0), CHAN5G(104, 0),
181 CHAN5G(108, 0), CHAN5G(112, 0),
182 CHAN5G(116, 0), CHAN5G(120, 0),
183 CHAN5G(124, 0), CHAN5G(128, 0),
184 CHAN5G(132, 0), CHAN5G(136, 0),
185 CHAN5G(140, 0), CHAN5G(149, 0),
186 CHAN5G(153, 0), CHAN5G(157, 0),
187 CHAN5G(161, 0), CHAN5G(165, 0),
188 CHAN5G(184, 0), CHAN5G(188, 0),
189 CHAN5G(192, 0), CHAN5G(196, 0),
190 CHAN5G(200, 0), CHAN5G(204, 0),
191 CHAN5G(208, 0), CHAN5G(212, 0),
195 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
196 CHAN5G(32, 0), CHAN5G(34, 0),
197 CHAN5G(36, 0), CHAN5G(38, 0),
198 CHAN5G(40, 0), CHAN5G(42, 0),
199 CHAN5G(44, 0), CHAN5G(46, 0),
200 CHAN5G(48, 0), CHAN5G(50, 0),
201 CHAN5G(52, 0), CHAN5G(54, 0),
202 CHAN5G(56, 0), CHAN5G(58, 0),
203 CHAN5G(60, 0), CHAN5G(62, 0),
204 CHAN5G(64, 0), CHAN5G(66, 0),
205 CHAN5G(68, 0), CHAN5G(70, 0),
206 CHAN5G(72, 0), CHAN5G(74, 0),
207 CHAN5G(76, 0), CHAN5G(78, 0),
208 CHAN5G(80, 0), CHAN5G(82, 0),
209 CHAN5G(84, 0), CHAN5G(86, 0),
210 CHAN5G(88, 0), CHAN5G(90, 0),
211 CHAN5G(92, 0), CHAN5G(94, 0),
212 CHAN5G(96, 0), CHAN5G(98, 0),
213 CHAN5G(100, 0), CHAN5G(102, 0),
214 CHAN5G(104, 0), CHAN5G(106, 0),
215 CHAN5G(108, 0), CHAN5G(110, 0),
216 CHAN5G(112, 0), CHAN5G(114, 0),
217 CHAN5G(116, 0), CHAN5G(118, 0),
218 CHAN5G(120, 0), CHAN5G(122, 0),
219 CHAN5G(124, 0), CHAN5G(126, 0),
220 CHAN5G(128, 0), CHAN5G(130, 0),
221 CHAN5G(132, 0), CHAN5G(134, 0),
222 CHAN5G(136, 0), CHAN5G(138, 0),
223 CHAN5G(140, 0), CHAN5G(142, 0),
224 CHAN5G(144, 0), CHAN5G(145, 0),
225 CHAN5G(146, 0), CHAN5G(147, 0),
226 CHAN5G(148, 0), CHAN5G(149, 0),
227 CHAN5G(150, 0), CHAN5G(151, 0),
228 CHAN5G(152, 0), CHAN5G(153, 0),
229 CHAN5G(154, 0), CHAN5G(155, 0),
230 CHAN5G(156, 0), CHAN5G(157, 0),
231 CHAN5G(158, 0), CHAN5G(159, 0),
232 CHAN5G(160, 0), CHAN5G(161, 0),
233 CHAN5G(162, 0), CHAN5G(163, 0),
234 CHAN5G(164, 0), CHAN5G(165, 0),
235 CHAN5G(166, 0), CHAN5G(168, 0),
236 CHAN5G(170, 0), CHAN5G(172, 0),
237 CHAN5G(174, 0), CHAN5G(176, 0),
238 CHAN5G(178, 0), CHAN5G(180, 0),
239 CHAN5G(182, 0), CHAN5G(184, 0),
240 CHAN5G(186, 0), CHAN5G(188, 0),
241 CHAN5G(190, 0), CHAN5G(192, 0),
242 CHAN5G(194, 0), CHAN5G(196, 0),
243 CHAN5G(198, 0), CHAN5G(200, 0),
244 CHAN5G(202, 0), CHAN5G(204, 0),
245 CHAN5G(206, 0), CHAN5G(208, 0),
246 CHAN5G(210, 0), CHAN5G(212, 0),
247 CHAN5G(214, 0), CHAN5G(216, 0),
248 CHAN5G(218, 0), CHAN5G(220, 0),
249 CHAN5G(222, 0), CHAN5G(224, 0),
250 CHAN5G(226, 0), CHAN5G(228, 0),
253 static struct ieee80211_supported_band __wl_band_2ghz
= {
254 .band
= IEEE80211_BAND_2GHZ
,
255 .channels
= __wl_2ghz_channels
,
256 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
257 .bitrates
= wl_g_rates
,
258 .n_bitrates
= wl_g_rates_size
,
261 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
262 .band
= IEEE80211_BAND_5GHZ
,
263 .channels
= __wl_5ghz_a_channels
,
264 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
265 .bitrates
= wl_a_rates
,
266 .n_bitrates
= wl_a_rates_size
,
269 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
270 .band
= IEEE80211_BAND_5GHZ
,
271 .channels
= __wl_5ghz_n_channels
,
272 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
273 .bitrates
= wl_a_rates
,
274 .n_bitrates
= wl_a_rates_size
,
277 static const u32 __wl_cipher_suites
[] = {
278 WLAN_CIPHER_SUITE_WEP40
,
279 WLAN_CIPHER_SUITE_WEP104
,
280 WLAN_CIPHER_SUITE_TKIP
,
281 WLAN_CIPHER_SUITE_CCMP
,
282 WLAN_CIPHER_SUITE_AES_CMAC
,
285 /* tag_ID/length/value_buffer tuple */
292 /* Vendor specific ie. id = 221, oui and type defines exact ie */
293 struct brcmf_vs_tlv
{
300 struct parsed_vndr_ie_info
{
302 u32 ie_len
; /* total length including id & length field */
303 struct brcmf_vs_tlv vndrie
;
306 struct parsed_vndr_ies
{
308 struct parsed_vndr_ie_info ie_info
[MAX_VNDR_IE_NUMBER
];
311 /* Quarter dBm units to mW
312 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
313 * Table is offset so the last entry is largest mW value that fits in
317 #define QDBM_OFFSET 153 /* Offset for first entry */
318 #define QDBM_TABLE_LEN 40 /* Table size */
320 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
321 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
323 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
325 /* Largest mW value that will round down to the last table entry,
326 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
327 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
328 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
330 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
332 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
333 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
334 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
335 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
336 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
337 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
338 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
341 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
344 int idx
= qdbm
- QDBM_OFFSET
;
346 if (idx
>= QDBM_TABLE_LEN
)
347 /* clamp to max u16 mW value */
350 /* scale the qdBm index up to the range of the table 0-40
351 * where an offset of 40 qdBm equals a factor of 10 mW.
358 /* return the mW value scaled down to the correct factor of 10,
359 * adding in factor/2 to get proper rounding.
361 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
364 static u8
brcmf_mw_to_qdbm(u16 mw
)
371 /* handle boundary case */
375 offset
= QDBM_OFFSET
;
377 /* move mw into the range of the table */
378 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
383 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
384 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
385 nqdBm_to_mW_map
[qdbm
]) / 2;
386 if (mw_uint
< boundary
)
395 static u16
channel_to_chanspec(struct ieee80211_channel
*ch
)
399 chanspec
= ieee80211_frequency_to_channel(ch
->center_freq
);
400 chanspec
&= WL_CHANSPEC_CHAN_MASK
;
402 if (ch
->band
== IEEE80211_BAND_2GHZ
)
403 chanspec
|= WL_CHANSPEC_BAND_2G
;
405 chanspec
|= WL_CHANSPEC_BAND_5G
;
407 if (ch
->flags
& IEEE80211_CHAN_NO_HT40
) {
408 chanspec
|= WL_CHANSPEC_BW_20
;
409 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
411 chanspec
|= WL_CHANSPEC_BW_40
;
412 if (ch
->flags
& IEEE80211_CHAN_NO_HT40PLUS
)
413 chanspec
|= WL_CHANSPEC_CTL_SB_LOWER
;
415 chanspec
|= WL_CHANSPEC_CTL_SB_UPPER
;
420 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
421 struct brcmf_wsec_key_le
*key_le
)
423 key_le
->index
= cpu_to_le32(key
->index
);
424 key_le
->len
= cpu_to_le32(key
->len
);
425 key_le
->algo
= cpu_to_le32(key
->algo
);
426 key_le
->flags
= cpu_to_le32(key
->flags
);
427 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
428 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
429 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
430 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
431 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
435 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
438 struct brcmf_wsec_key_le key_le
;
440 convert_key_from_CPU(key
, &key_le
);
442 brcmf_netdev_wait_pend8021x(ndev
);
444 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
448 WL_ERR("wsec_key error (%d)\n", err
);
453 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
454 enum nl80211_iftype type
, u32
*flags
,
455 struct vif_params
*params
)
457 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
462 WL_TRACE("Enter, ndev=%p, type=%d\n", ndev
, type
);
465 case NL80211_IFTYPE_MONITOR
:
466 case NL80211_IFTYPE_WDS
:
467 WL_ERR("type (%d) : currently we do not support this type\n",
470 case NL80211_IFTYPE_ADHOC
:
471 cfg
->conf
->mode
= WL_MODE_IBSS
;
474 case NL80211_IFTYPE_STATION
:
475 cfg
->conf
->mode
= WL_MODE_BSS
;
478 case NL80211_IFTYPE_AP
:
479 cfg
->conf
->mode
= WL_MODE_AP
;
488 set_bit(WL_STATUS_AP_CREATING
, &cfg
->status
);
490 cfg
->ap_info
= kzalloc(sizeof(*cfg
->ap_info
),
496 WL_INFO("IF Type = AP\n");
498 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
499 BRCMF_C_SET_INFRA
, infra
);
501 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
505 WL_INFO("IF Type = %s\n",
506 (cfg
->conf
->mode
== WL_MODE_IBSS
) ?
509 ndev
->ieee80211_ptr
->iftype
= type
;
517 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
520 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
522 if (test_bit(WL_STATUS_READY
, &cfg
->status
)) {
523 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", mpc
);
525 WL_ERR("fail to set mpc\n");
528 WL_INFO("MPC : %d\n", mpc
);
532 static void brcmf_iscan_prep(struct brcmf_scan_params_le
*params_le
,
533 struct brcmf_ssid
*ssid
)
535 memcpy(params_le
->bssid
, ether_bcast
, ETH_ALEN
);
536 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
537 params_le
->scan_type
= 0;
538 params_le
->channel_num
= 0;
539 params_le
->nprobes
= cpu_to_le32(-1);
540 params_le
->active_time
= cpu_to_le32(-1);
541 params_le
->passive_time
= cpu_to_le32(-1);
542 params_le
->home_time
= cpu_to_le32(-1);
543 if (ssid
&& ssid
->SSID_len
) {
544 params_le
->ssid_le
.SSID_len
= cpu_to_le32(ssid
->SSID_len
);
545 memcpy(¶ms_le
->ssid_le
.SSID
, ssid
->SSID
, ssid
->SSID_len
);
550 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
551 struct brcmf_ssid
*ssid
, u16 action
)
553 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
554 offsetof(struct brcmf_iscan_params_le
, params_le
);
555 struct brcmf_iscan_params_le
*params
;
558 if (ssid
&& ssid
->SSID_len
)
559 params_size
+= sizeof(struct brcmf_ssid
);
560 params
= kzalloc(params_size
, GFP_KERNEL
);
563 BUG_ON(params_size
>= BRCMF_DCMD_SMLEN
);
565 brcmf_iscan_prep(¶ms
->params_le
, ssid
);
567 params
->version
= cpu_to_le32(BRCMF_ISCAN_REQ_VERSION
);
568 params
->action
= cpu_to_le16(action
);
569 params
->scan_duration
= cpu_to_le16(0);
571 err
= brcmf_fil_iovar_data_set(netdev_priv(iscan
->ndev
), "iscan",
572 params
, params_size
);
575 WL_INFO("system busy : iscan canceled\n");
577 WL_ERR("error (%d)\n", err
);
584 static s32
brcmf_do_iscan(struct brcmf_cfg80211_info
*cfg
)
586 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg
);
587 struct net_device
*ndev
= cfg_to_ndev(cfg
);
588 struct brcmf_ssid ssid
;
592 /* Broadcast scan by default */
593 memset(&ssid
, 0, sizeof(ssid
));
595 iscan
->state
= WL_ISCAN_STATE_SCANING
;
597 passive_scan
= cfg
->active_scan
? 0 : 1;
598 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
599 BRCMF_C_SET_PASSIVE_SCAN
, passive_scan
);
601 WL_ERR("error (%d)\n", err
);
604 brcmf_set_mpc(ndev
, 0);
605 cfg
->iscan_kickstart
= true;
606 err
= brcmf_run_iscan(iscan
, &ssid
, BRCMF_SCAN_ACTION_START
);
608 brcmf_set_mpc(ndev
, 1);
609 cfg
->iscan_kickstart
= false;
612 mod_timer(&iscan
->timer
, jiffies
+ iscan
->timer_ms
* HZ
/ 1000);
618 brcmf_cfg80211_iscan(struct wiphy
*wiphy
, struct net_device
*ndev
,
619 struct cfg80211_scan_request
*request
,
620 struct cfg80211_ssid
*this_ssid
)
622 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
623 struct cfg80211_ssid
*ssids
;
624 struct brcmf_cfg80211_scan_req
*sr
= cfg
->scan_req_int
;
631 if (test_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
632 WL_ERR("Scanning already : status (%lu)\n", cfg
->status
);
635 if (test_bit(WL_STATUS_SCAN_ABORTING
, &cfg
->status
)) {
636 WL_ERR("Scanning being aborted : status (%lu)\n",
640 if (test_bit(WL_STATUS_CONNECTING
, &cfg
->status
)) {
641 WL_ERR("Connecting : status (%lu)\n",
650 ssids
= request
->ssids
;
651 if (cfg
->iscan_on
&& (!ssids
|| !ssids
->ssid_len
))
655 /* we don't do iscan in ibss */
659 cfg
->scan_request
= request
;
660 set_bit(WL_STATUS_SCANNING
, &cfg
->status
);
662 err
= brcmf_do_iscan(cfg
);
668 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
669 ssids
->ssid
, ssids
->ssid_len
);
670 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
671 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
672 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
674 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
675 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
678 WL_SCAN("Broadcast scan\n");
681 passive_scan
= cfg
->active_scan
? 0 : 1;
682 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
683 BRCMF_C_SET_PASSIVE_SCAN
,
686 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
689 brcmf_set_mpc(ndev
, 0);
690 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
691 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
694 WL_INFO("system busy : scan for \"%s\" "
695 "canceled\n", sr
->ssid_le
.SSID
);
697 WL_ERR("WLC_SCAN error (%d)\n", err
);
699 brcmf_set_mpc(ndev
, 1);
707 clear_bit(WL_STATUS_SCANNING
, &cfg
->status
);
708 cfg
->scan_request
= NULL
;
712 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
713 struct cfg80211_scan_request
*request
)
721 struct brcmf_ssid_le ssid_le
;
723 memcpy(params_le
->bssid
, ether_bcast
, ETH_ALEN
);
724 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
725 params_le
->scan_type
= 0;
726 params_le
->channel_num
= 0;
727 params_le
->nprobes
= cpu_to_le32(-1);
728 params_le
->active_time
= cpu_to_le32(-1);
729 params_le
->passive_time
= cpu_to_le32(-1);
730 params_le
->home_time
= cpu_to_le32(-1);
731 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
733 /* if request is null exit so it will be all channel broadcast scan */
737 n_ssids
= request
->n_ssids
;
738 n_channels
= request
->n_channels
;
739 /* Copy channel array if applicable */
740 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels
);
741 if (n_channels
> 0) {
742 for (i
= 0; i
< n_channels
; i
++) {
743 chanspec
= channel_to_chanspec(request
->channels
[i
]);
744 WL_SCAN("Chan : %d, Channel spec: %x\n",
745 request
->channels
[i
]->hw_value
, chanspec
);
746 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
749 WL_SCAN("Scanning all channels\n");
751 /* Copy ssid array if applicable */
752 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids
);
754 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
755 n_channels
* sizeof(u16
);
756 offset
= roundup(offset
, sizeof(u32
));
757 ptr
= (char *)params_le
+ offset
;
758 for (i
= 0; i
< n_ssids
; i
++) {
759 memset(&ssid_le
, 0, sizeof(ssid_le
));
761 cpu_to_le32(request
->ssids
[i
].ssid_len
);
762 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
763 request
->ssids
[i
].ssid_len
);
764 if (!ssid_le
.SSID_len
)
765 WL_SCAN("%d: Broadcast scan\n", i
);
767 WL_SCAN("%d: scan for %s size =%d\n", i
,
768 ssid_le
.SSID
, ssid_le
.SSID_len
);
769 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
770 ptr
+= sizeof(ssid_le
);
773 WL_SCAN("Broadcast scan %p\n", request
->ssids
);
774 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
775 WL_SCAN("SSID %s len=%d\n", params_le
->ssid_le
.SSID
,
776 request
->ssids
->ssid_len
);
777 params_le
->ssid_le
.SSID_len
=
778 cpu_to_le32(request
->ssids
->ssid_len
);
779 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
780 request
->ssids
->ssid_len
);
783 /* Adding mask to channel numbers */
784 params_le
->channel_num
=
785 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
786 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
790 brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
791 struct net_device
*ndev
,
792 bool aborted
, bool fw_abort
)
794 struct brcmf_scan_params_le params_le
;
795 struct cfg80211_scan_request
*scan_request
;
800 /* clear scan request, because the FW abort can cause a second call */
801 /* to this functon and might cause a double cfg80211_scan_done */
802 scan_request
= cfg
->scan_request
;
803 cfg
->scan_request
= NULL
;
805 if (timer_pending(&cfg
->escan_timeout
))
806 del_timer_sync(&cfg
->escan_timeout
);
809 /* Do a scan abort to stop the driver's scan engine */
810 WL_SCAN("ABORT scan in firmware\n");
811 memset(¶ms_le
, 0, sizeof(params_le
));
812 memcpy(params_le
.bssid
, ether_bcast
, ETH_ALEN
);
813 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
814 params_le
.scan_type
= 0;
815 params_le
.channel_num
= cpu_to_le32(1);
816 params_le
.nprobes
= cpu_to_le32(1);
817 params_le
.active_time
= cpu_to_le32(-1);
818 params_le
.passive_time
= cpu_to_le32(-1);
819 params_le
.home_time
= cpu_to_le32(-1);
820 /* Scan is aborted by setting channel_list[0] to -1 */
821 params_le
.channel_list
[0] = cpu_to_le16(-1);
822 /* E-Scan (or anyother type) can be aborted by SCAN */
823 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
824 ¶ms_le
, sizeof(params_le
));
826 WL_ERR("Scan abort failed\n");
829 * e-scan can be initiated by scheduled scan
830 * which takes precedence.
832 if (cfg
->sched_escan
) {
833 WL_SCAN("scheduled scan completed\n");
834 cfg
->sched_escan
= false;
836 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
837 brcmf_set_mpc(ndev
, 1);
838 } else if (scan_request
) {
839 WL_SCAN("ESCAN Completed scan: %s\n",
840 aborted
? "Aborted" : "Done");
841 cfg80211_scan_done(scan_request
, aborted
);
842 brcmf_set_mpc(ndev
, 1);
844 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
845 WL_ERR("Scan complete while device not scanning\n");
853 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct net_device
*ndev
,
854 struct cfg80211_scan_request
*request
, u16 action
)
856 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
857 offsetof(struct brcmf_escan_params_le
, params_le
);
858 struct brcmf_escan_params_le
*params
;
861 WL_SCAN("E-SCAN START\n");
863 if (request
!= NULL
) {
864 /* Allocate space for populating ssids in struct */
865 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
867 /* Allocate space for populating ssids in struct */
868 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
871 params
= kzalloc(params_size
, GFP_KERNEL
);
876 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
877 brcmf_escan_prep(¶ms
->params_le
, request
);
878 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
879 params
->action
= cpu_to_le16(action
);
880 params
->sync_id
= cpu_to_le16(0x1234);
882 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "escan",
883 params
, params_size
);
886 WL_INFO("system busy : escan canceled\n");
888 WL_ERR("error (%d)\n", err
);
897 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
898 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
902 struct brcmf_scan_results
*results
;
905 cfg
->escan_info
.ndev
= ndev
;
906 cfg
->escan_info
.wiphy
= wiphy
;
907 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_SCANNING
;
908 passive_scan
= cfg
->active_scan
? 0 : 1;
909 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PASSIVE_SCAN
,
912 WL_ERR("error (%d)\n", err
);
915 brcmf_set_mpc(ndev
, 0);
916 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
917 results
->version
= 0;
919 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
921 err
= brcmf_run_escan(cfg
, ndev
, request
, WL_ESCAN_ACTION_START
);
923 brcmf_set_mpc(ndev
, 1);
928 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
929 struct cfg80211_scan_request
*request
,
930 struct cfg80211_ssid
*this_ssid
)
932 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
933 struct cfg80211_ssid
*ssids
;
934 struct brcmf_cfg80211_scan_req
*sr
= cfg
->scan_req_int
;
941 WL_SCAN("START ESCAN\n");
943 if (test_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
944 WL_ERR("Scanning already : status (%lu)\n", cfg
->status
);
947 if (test_bit(WL_STATUS_SCAN_ABORTING
, &cfg
->status
)) {
948 WL_ERR("Scanning being aborted : status (%lu)\n",
952 if (test_bit(WL_STATUS_CONNECTING
, &cfg
->status
)) {
953 WL_ERR("Connecting : status (%lu)\n",
958 /* Arm scan timeout timer */
959 mod_timer(&cfg
->escan_timeout
, jiffies
+
960 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
965 ssids
= request
->ssids
;
969 /* we don't do escan in ibss */
973 cfg
->scan_request
= request
;
974 set_bit(WL_STATUS_SCANNING
, &cfg
->status
);
976 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
982 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
983 ssids
->ssid
, ssids
->ssid_len
);
984 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
985 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
986 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
989 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
990 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
993 WL_SCAN("Broadcast scan\n");
995 passive_scan
= cfg
->active_scan
? 0 : 1;
996 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
997 BRCMF_C_SET_PASSIVE_SCAN
,
1000 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
1003 brcmf_set_mpc(ndev
, 0);
1004 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
1005 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
1008 WL_INFO("BUSY: scan for \"%s\" canceled\n",
1011 WL_ERR("WLC_SCAN error (%d)\n", err
);
1013 brcmf_set_mpc(ndev
, 1);
1021 clear_bit(WL_STATUS_SCANNING
, &cfg
->status
);
1022 if (timer_pending(&cfg
->escan_timeout
))
1023 del_timer_sync(&cfg
->escan_timeout
);
1024 cfg
->scan_request
= NULL
;
1029 brcmf_cfg80211_scan(struct wiphy
*wiphy
,
1030 struct cfg80211_scan_request
*request
)
1032 struct net_device
*ndev
= request
->wdev
->netdev
;
1033 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1036 WL_TRACE("Enter\n");
1038 if (!check_sys_up(wiphy
))
1042 err
= brcmf_cfg80211_iscan(wiphy
, ndev
, request
, NULL
);
1043 else if (cfg
->escan_on
)
1044 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
1047 WL_ERR("scan error (%d)\n", err
);
1053 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1057 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1060 WL_ERR("Error (%d)\n", err
);
1065 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1069 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1072 WL_ERR("Error (%d)\n", err
);
1077 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1080 u32 cmd
= (l
? BRCM_SET_LRL
: BRCM_SET_SRL
);
1082 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1084 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
1090 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1092 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1093 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1096 WL_TRACE("Enter\n");
1097 if (!check_sys_up(wiphy
))
1100 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1101 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1102 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1103 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1107 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1108 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1109 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1110 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1114 if (changed
& WIPHY_PARAM_RETRY_LONG
1115 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1116 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1117 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1121 if (changed
& WIPHY_PARAM_RETRY_SHORT
1122 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1123 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1124 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1134 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1136 memset(prof
, 0, sizeof(*prof
));
1139 static void brcmf_ch_to_chanspec(int ch
, struct brcmf_join_params
*join_params
,
1140 size_t *join_params_size
)
1145 if (ch
<= CH_MAX_2G_CHANNEL
)
1146 chanspec
|= WL_CHANSPEC_BAND_2G
;
1148 chanspec
|= WL_CHANSPEC_BAND_5G
;
1150 chanspec
|= WL_CHANSPEC_BW_20
;
1151 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
1153 *join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
+
1156 chanspec
|= (ch
& WL_CHANSPEC_CHAN_MASK
);
1157 join_params
->params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1158 join_params
->params_le
.chanspec_num
= cpu_to_le32(1);
1160 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
1161 "channel %d, chanspec %#X\n",
1162 chanspec
, ch
, chanspec
);
1166 static void brcmf_link_down(struct brcmf_cfg80211_info
*cfg
)
1168 struct net_device
*ndev
= NULL
;
1171 WL_TRACE("Enter\n");
1174 ndev
= cfg_to_ndev(cfg
);
1175 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
1176 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
),
1177 BRCMF_C_DISASSOC
, NULL
, 0);
1179 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
1180 cfg
->link_up
= false;
1186 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1187 struct cfg80211_ibss_params
*params
)
1189 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1190 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1191 struct brcmf_join_params join_params
;
1192 size_t join_params_size
= 0;
1197 WL_TRACE("Enter\n");
1198 if (!check_sys_up(wiphy
))
1202 WL_CONN("SSID: %s\n", params
->ssid
);
1204 WL_CONN("SSID: NULL, Not supported\n");
1208 set_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
1211 WL_CONN("BSSID: %pM\n", params
->bssid
);
1213 WL_CONN("No BSSID specified\n");
1215 if (params
->channel
)
1216 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
1218 WL_CONN("no channel specified\n");
1220 if (params
->channel_fixed
)
1221 WL_CONN("fixed channel required\n");
1223 WL_CONN("no fixed channel required\n");
1225 if (params
->ie
&& params
->ie_len
)
1226 WL_CONN("ie len: %d\n", params
->ie_len
);
1228 WL_CONN("no ie specified\n");
1230 if (params
->beacon_interval
)
1231 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
1233 WL_CONN("no beacon interval specified\n");
1235 if (params
->basic_rates
)
1236 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1238 WL_CONN("no basic rates specified\n");
1240 if (params
->privacy
)
1241 WL_CONN("privacy required\n");
1243 WL_CONN("no privacy required\n");
1245 /* Configure Privacy for starter */
1246 if (params
->privacy
)
1247 wsec
|= WEP_ENABLED
;
1249 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wsec", wsec
);
1251 WL_ERR("wsec failed (%d)\n", err
);
1255 /* Configure Beacon Interval for starter */
1256 if (params
->beacon_interval
)
1257 bcnprd
= params
->beacon_interval
;
1261 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCM_SET_BCNPRD
, bcnprd
);
1263 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1267 /* Configure required join parameter */
1268 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1271 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1272 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1273 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1274 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1275 join_params_size
= sizeof(join_params
.ssid_le
);
1278 if (params
->bssid
) {
1279 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1280 join_params_size
= sizeof(join_params
.ssid_le
) +
1281 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1282 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1284 memcpy(join_params
.params_le
.bssid
, ether_bcast
, ETH_ALEN
);
1285 memset(profile
->bssid
, 0, ETH_ALEN
);
1289 if (params
->channel
) {
1293 ieee80211_frequency_to_channel(
1294 params
->channel
->center_freq
);
1295 if (params
->channel_fixed
) {
1296 /* adding chanspec */
1297 brcmf_ch_to_chanspec(cfg
->channel
,
1298 &join_params
, &join_params_size
);
1301 /* set channel for starter */
1302 target_channel
= cfg
->channel
;
1303 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCM_SET_CHANNEL
,
1306 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1312 cfg
->ibss_starter
= false;
1315 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SET_SSID
,
1316 &join_params
, join_params_size
);
1318 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1324 clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
1330 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1332 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1335 WL_TRACE("Enter\n");
1336 if (!check_sys_up(wiphy
))
1339 brcmf_link_down(cfg
);
1346 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1347 struct cfg80211_connect_params
*sme
)
1349 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1350 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1351 struct brcmf_cfg80211_security
*sec
;
1355 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1356 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1357 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1358 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1360 val
= WPA_AUTH_DISABLED
;
1361 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1362 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1364 WL_ERR("set wpa_auth failed (%d)\n", err
);
1367 sec
= &profile
->sec
;
1368 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1372 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1373 struct cfg80211_connect_params
*sme
)
1375 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1376 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1377 struct brcmf_cfg80211_security
*sec
;
1381 switch (sme
->auth_type
) {
1382 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1384 WL_CONN("open system\n");
1386 case NL80211_AUTHTYPE_SHARED_KEY
:
1388 WL_CONN("shared key\n");
1390 case NL80211_AUTHTYPE_AUTOMATIC
:
1392 WL_CONN("automatic\n");
1394 case NL80211_AUTHTYPE_NETWORK_EAP
:
1395 WL_CONN("network eap\n");
1398 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1402 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "auth", val
);
1404 WL_ERR("set auth failed (%d)\n", err
);
1407 sec
= &profile
->sec
;
1408 sec
->auth_type
= sme
->auth_type
;
1413 brcmf_set_set_cipher(struct net_device
*ndev
,
1414 struct cfg80211_connect_params
*sme
)
1416 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1417 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1418 struct brcmf_cfg80211_security
*sec
;
1423 if (sme
->crypto
.n_ciphers_pairwise
) {
1424 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1425 case WLAN_CIPHER_SUITE_WEP40
:
1426 case WLAN_CIPHER_SUITE_WEP104
:
1429 case WLAN_CIPHER_SUITE_TKIP
:
1430 pval
= TKIP_ENABLED
;
1432 case WLAN_CIPHER_SUITE_CCMP
:
1435 case WLAN_CIPHER_SUITE_AES_CMAC
:
1439 WL_ERR("invalid cipher pairwise (%d)\n",
1440 sme
->crypto
.ciphers_pairwise
[0]);
1444 if (sme
->crypto
.cipher_group
) {
1445 switch (sme
->crypto
.cipher_group
) {
1446 case WLAN_CIPHER_SUITE_WEP40
:
1447 case WLAN_CIPHER_SUITE_WEP104
:
1450 case WLAN_CIPHER_SUITE_TKIP
:
1451 gval
= TKIP_ENABLED
;
1453 case WLAN_CIPHER_SUITE_CCMP
:
1456 case WLAN_CIPHER_SUITE_AES_CMAC
:
1460 WL_ERR("invalid cipher group (%d)\n",
1461 sme
->crypto
.cipher_group
);
1466 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1467 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1469 WL_ERR("error (%d)\n", err
);
1473 sec
= &profile
->sec
;
1474 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1475 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1481 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1483 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1484 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1485 struct brcmf_cfg80211_security
*sec
;
1489 if (sme
->crypto
.n_akm_suites
) {
1490 err
= brcmf_fil_iovar_int_get(netdev_priv(ndev
),
1493 WL_ERR("could not get wpa_auth (%d)\n", err
);
1496 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1497 switch (sme
->crypto
.akm_suites
[0]) {
1498 case WLAN_AKM_SUITE_8021X
:
1499 val
= WPA_AUTH_UNSPECIFIED
;
1501 case WLAN_AKM_SUITE_PSK
:
1505 WL_ERR("invalid cipher group (%d)\n",
1506 sme
->crypto
.cipher_group
);
1509 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1510 switch (sme
->crypto
.akm_suites
[0]) {
1511 case WLAN_AKM_SUITE_8021X
:
1512 val
= WPA2_AUTH_UNSPECIFIED
;
1514 case WLAN_AKM_SUITE_PSK
:
1515 val
= WPA2_AUTH_PSK
;
1518 WL_ERR("invalid cipher group (%d)\n",
1519 sme
->crypto
.cipher_group
);
1524 WL_CONN("setting wpa_auth to %d\n", val
);
1525 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
),
1528 WL_ERR("could not set wpa_auth (%d)\n", err
);
1532 sec
= &profile
->sec
;
1533 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1539 brcmf_set_sharedkey(struct net_device
*ndev
,
1540 struct cfg80211_connect_params
*sme
)
1542 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
1543 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1544 struct brcmf_cfg80211_security
*sec
;
1545 struct brcmf_wsec_key key
;
1549 WL_CONN("key len (%d)\n", sme
->key_len
);
1551 if (sme
->key_len
== 0)
1554 sec
= &profile
->sec
;
1555 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1556 sec
->wpa_versions
, sec
->cipher_pairwise
);
1558 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1561 if (!(sec
->cipher_pairwise
&
1562 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1565 memset(&key
, 0, sizeof(key
));
1566 key
.len
= (u32
) sme
->key_len
;
1567 key
.index
= (u32
) sme
->key_idx
;
1568 if (key
.len
> sizeof(key
.data
)) {
1569 WL_ERR("Too long key length (%u)\n", key
.len
);
1572 memcpy(key
.data
, sme
->key
, key
.len
);
1573 key
.flags
= BRCMF_PRIMARY_KEY
;
1574 switch (sec
->cipher_pairwise
) {
1575 case WLAN_CIPHER_SUITE_WEP40
:
1576 key
.algo
= CRYPTO_ALGO_WEP1
;
1578 case WLAN_CIPHER_SUITE_WEP104
:
1579 key
.algo
= CRYPTO_ALGO_WEP128
;
1582 WL_ERR("Invalid algorithm (%d)\n",
1583 sme
->crypto
.ciphers_pairwise
[0]);
1586 /* Set the new key/index */
1587 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1588 key
.len
, key
.index
, key
.algo
);
1589 WL_CONN("key \"%s\"\n", key
.data
);
1590 err
= send_key_to_dongle(ndev
, &key
);
1594 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1595 WL_CONN("set auth_type to shared key\n");
1596 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1597 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1599 WL_ERR("set auth failed (%d)\n", err
);
1605 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1606 struct cfg80211_connect_params
*sme
)
1608 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1609 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1610 struct ieee80211_channel
*chan
= sme
->channel
;
1611 struct brcmf_join_params join_params
;
1612 size_t join_params_size
;
1613 struct brcmf_ssid ssid
;
1617 WL_TRACE("Enter\n");
1618 if (!check_sys_up(wiphy
))
1622 WL_ERR("Invalid ssid\n");
1626 set_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
1630 ieee80211_frequency_to_channel(chan
->center_freq
);
1631 WL_CONN("channel (%d), center_req (%d)\n",
1632 cfg
->channel
, chan
->center_freq
);
1636 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1638 err
= brcmf_set_wpa_version(ndev
, sme
);
1640 WL_ERR("wl_set_wpa_version failed (%d)\n", err
);
1644 err
= brcmf_set_auth_type(ndev
, sme
);
1646 WL_ERR("wl_set_auth_type failed (%d)\n", err
);
1650 err
= brcmf_set_set_cipher(ndev
, sme
);
1652 WL_ERR("wl_set_set_cipher failed (%d)\n", err
);
1656 err
= brcmf_set_key_mgmt(ndev
, sme
);
1658 WL_ERR("wl_set_key_mgmt failed (%d)\n", err
);
1662 err
= brcmf_set_sharedkey(ndev
, sme
);
1664 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err
);
1668 memset(&join_params
, 0, sizeof(join_params
));
1669 join_params_size
= sizeof(join_params
.ssid_le
);
1671 profile
->ssid
.SSID_len
= min_t(u32
,
1672 sizeof(ssid
.SSID
), (u32
)sme
->ssid_len
);
1673 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1674 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1675 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1677 memcpy(join_params
.params_le
.bssid
, ether_bcast
, ETH_ALEN
);
1679 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1680 WL_CONN("ssid \"%s\", len (%d)\n",
1681 ssid
.SSID
, ssid
.SSID_len
);
1683 brcmf_ch_to_chanspec(cfg
->channel
,
1684 &join_params
, &join_params_size
);
1685 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SET_SSID
,
1686 &join_params
, join_params_size
);
1688 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1692 clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
1698 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1701 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1702 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
1703 struct brcmf_scb_val_le scbval
;
1706 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1707 if (!check_sys_up(wiphy
))
1710 clear_bit(WL_STATUS_CONNECTED
, &cfg
->status
);
1712 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1713 scbval
.val
= cpu_to_le32(reason_code
);
1714 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_DISASSOC
,
1715 &scbval
, sizeof(scbval
));
1717 WL_ERR("error (%d)\n", err
);
1719 cfg
->link_up
= false;
1726 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1727 enum nl80211_tx_power_setting type
, s32 mbm
)
1730 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1731 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1735 s32 dbm
= MBM_TO_DBM(mbm
);
1737 WL_TRACE("Enter\n");
1738 if (!check_sys_up(wiphy
))
1742 case NL80211_TX_POWER_AUTOMATIC
:
1744 case NL80211_TX_POWER_LIMITED
:
1745 case NL80211_TX_POWER_FIXED
:
1747 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1753 /* Make sure radio is off or on as far as software is concerned */
1754 disable
= WL_RADIO_SW_DISABLE
<< 16;
1755 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1757 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1762 txpwrmw
= (u16
) dbm
;
1763 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1764 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1766 WL_ERR("qtxpower error (%d)\n", err
);
1767 cfg
->conf
->tx_power
= dbm
;
1774 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1776 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1777 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1782 WL_TRACE("Enter\n");
1783 if (!check_sys_up(wiphy
))
1786 err
= brcmf_fil_iovar_int_get(netdev_priv(ndev
), "qtxpower", &txpwrdbm
);
1788 WL_ERR("error (%d)\n", err
);
1792 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1793 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1801 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1802 u8 key_idx
, bool unicast
, bool multicast
)
1808 WL_TRACE("Enter\n");
1809 WL_CONN("key index (%d)\n", key_idx
);
1810 if (!check_sys_up(wiphy
))
1813 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
), "wsec", &wsec
);
1815 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1819 if (wsec
& WEP_ENABLED
) {
1820 /* Just select a new current key */
1822 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
1823 BRCMF_C_SET_KEY_PRIMARY
, index
);
1825 WL_ERR("error (%d)\n", err
);
1833 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1834 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1836 struct brcmf_wsec_key key
;
1839 memset(&key
, 0, sizeof(key
));
1840 key
.index
= (u32
) key_idx
;
1841 /* Instead of bcast for ea address for default wep keys,
1842 driver needs it to be Null */
1843 if (!is_multicast_ether_addr(mac_addr
))
1844 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1845 key
.len
= (u32
) params
->key_len
;
1846 /* check for key index change */
1849 err
= send_key_to_dongle(ndev
, &key
);
1851 WL_ERR("key delete error (%d)\n", err
);
1853 if (key
.len
> sizeof(key
.data
)) {
1854 WL_ERR("Invalid key length (%d)\n", key
.len
);
1858 WL_CONN("Setting the key index %d\n", key
.index
);
1859 memcpy(key
.data
, params
->key
, key
.len
);
1861 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1863 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1864 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1865 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1868 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1869 if (params
->seq
&& params
->seq_len
== 6) {
1872 ivptr
= (u8
*) params
->seq
;
1873 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1874 (ivptr
[3] << 8) | ivptr
[2];
1875 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1876 key
.iv_initialized
= true;
1879 switch (params
->cipher
) {
1880 case WLAN_CIPHER_SUITE_WEP40
:
1881 key
.algo
= CRYPTO_ALGO_WEP1
;
1882 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1884 case WLAN_CIPHER_SUITE_WEP104
:
1885 key
.algo
= CRYPTO_ALGO_WEP128
;
1886 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1888 case WLAN_CIPHER_SUITE_TKIP
:
1889 key
.algo
= CRYPTO_ALGO_TKIP
;
1890 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1892 case WLAN_CIPHER_SUITE_AES_CMAC
:
1893 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1894 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1896 case WLAN_CIPHER_SUITE_CCMP
:
1897 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1898 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1901 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1904 err
= send_key_to_dongle(ndev
, &key
);
1906 WL_ERR("wsec_key error (%d)\n", err
);
1912 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1913 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1914 struct key_params
*params
)
1916 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1917 struct brcmf_wsec_key key
;
1923 WL_TRACE("Enter\n");
1924 WL_CONN("key index (%d)\n", key_idx
);
1925 if (!check_sys_up(wiphy
))
1930 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1932 memset(&key
, 0, sizeof(key
));
1934 key
.len
= (u32
) params
->key_len
;
1935 key
.index
= (u32
) key_idx
;
1937 if (key
.len
> sizeof(key
.data
)) {
1938 WL_ERR("Too long key length (%u)\n", key
.len
);
1942 memcpy(key
.data
, params
->key
, key
.len
);
1944 key
.flags
= BRCMF_PRIMARY_KEY
;
1945 switch (params
->cipher
) {
1946 case WLAN_CIPHER_SUITE_WEP40
:
1947 key
.algo
= CRYPTO_ALGO_WEP1
;
1949 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1951 case WLAN_CIPHER_SUITE_WEP104
:
1952 key
.algo
= CRYPTO_ALGO_WEP128
;
1954 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1956 case WLAN_CIPHER_SUITE_TKIP
:
1957 if (cfg
->conf
->mode
!= WL_MODE_AP
) {
1958 WL_CONN("Swapping key\n");
1959 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1960 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1961 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1963 key
.algo
= CRYPTO_ALGO_TKIP
;
1965 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1967 case WLAN_CIPHER_SUITE_AES_CMAC
:
1968 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1970 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1972 case WLAN_CIPHER_SUITE_CCMP
:
1973 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1975 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1978 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1983 err
= send_key_to_dongle(ndev
, &key
);
1987 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
), "wsec", &wsec
);
1989 WL_ERR("get wsec error (%d)\n", err
);
1993 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", wsec
);
1995 WL_ERR("set wsec error (%d)\n", err
);
2005 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2006 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2008 struct brcmf_wsec_key key
;
2011 WL_TRACE("Enter\n");
2012 if (!check_sys_up(wiphy
))
2015 memset(&key
, 0, sizeof(key
));
2017 key
.index
= (u32
) key_idx
;
2018 key
.flags
= BRCMF_PRIMARY_KEY
;
2019 key
.algo
= CRYPTO_ALGO_OFF
;
2021 WL_CONN("key index (%d)\n", key_idx
);
2023 /* Set the new key/index */
2024 err
= send_key_to_dongle(ndev
, &key
);
2026 if (err
== -EINVAL
) {
2027 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
2028 /* we ignore this key index in this case */
2029 WL_ERR("invalid key index (%d)\n", key_idx
);
2031 /* Ignore this error, may happen during DISASSOC */
2040 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2041 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2042 void (*callback
) (void *cookie
, struct key_params
* params
))
2044 struct key_params params
;
2045 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2046 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
2047 struct brcmf_cfg80211_security
*sec
;
2051 WL_TRACE("Enter\n");
2052 WL_CONN("key index (%d)\n", key_idx
);
2053 if (!check_sys_up(wiphy
))
2056 memset(¶ms
, 0, sizeof(params
));
2058 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
), "wsec", &wsec
);
2060 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
2061 /* Ignore this error, may happen during DISASSOC */
2065 switch (wsec
& ~SES_OW_ENABLED
) {
2067 sec
= &profile
->sec
;
2068 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2069 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2070 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
2071 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2072 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2073 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
2077 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2078 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
2081 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2082 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
2085 WL_ERR("Invalid algo (0x%x)\n", wsec
);
2089 callback(cookie
, ¶ms
);
2097 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2098 struct net_device
*ndev
, u8 key_idx
)
2100 WL_INFO("Not supported\n");
2106 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2107 u8
*mac
, struct station_info
*sinfo
)
2109 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2110 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
2111 struct brcmf_scb_val_le scb_val
;
2115 u8
*bssid
= profile
->bssid
;
2116 struct brcmf_sta_info_le sta_info_le
;
2118 WL_TRACE("Enter, MAC %pM\n", mac
);
2119 if (!check_sys_up(wiphy
))
2122 if (cfg
->conf
->mode
== WL_MODE_AP
) {
2123 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2124 err
= brcmf_fil_iovar_data_get(netdev_priv(ndev
), "sta_info",
2126 sizeof(sta_info_le
));
2128 WL_ERR("GET STA INFO failed, %d\n", err
);
2131 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2132 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2133 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2134 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2135 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2137 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
2138 sinfo
->inactive_time
, sinfo
->connected_time
);
2139 } else if (cfg
->conf
->mode
== WL_MODE_BSS
) {
2140 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2141 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2146 /* Report the current tx rate */
2147 err
= brcmf_fil_cmd_int_get(netdev_priv(ndev
), BRCMF_C_GET_RATE
, &rate
);
2149 WL_ERR("Could not get rate (%d)\n", err
);
2152 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2153 sinfo
->txrate
.legacy
= rate
* 5;
2154 WL_CONN("Rate %d Mbps\n", rate
/ 2);
2157 if (test_bit(WL_STATUS_CONNECTED
, &cfg
->status
)) {
2158 memset(&scb_val
, 0, sizeof(scb_val
));
2159 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
),
2160 BRCMF_C_GET_RSSI
, &scb_val
,
2163 WL_ERR("Could not get rssi (%d)\n", err
);
2166 rssi
= le32_to_cpu(scb_val
.val
);
2167 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2168 sinfo
->signal
= rssi
;
2169 WL_CONN("RSSI %d dBm\n", rssi
);
2180 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2181 bool enabled
, s32 timeout
)
2185 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2187 WL_TRACE("Enter\n");
2190 * Powersave enable/disable request is coming from the
2191 * cfg80211 even before the interface is up. In that
2192 * scenario, driver will be storing the power save
2193 * preference in cfg struct to apply this to
2194 * FW later while initializing the dongle
2196 cfg
->pwr_save
= enabled
;
2197 if (!test_bit(WL_STATUS_READY
, &cfg
->status
)) {
2199 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2203 pm
= enabled
? PM_FAST
: PM_OFF
;
2204 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
2206 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PM
, pm
);
2209 WL_ERR("net_device is not ready yet\n");
2211 WL_ERR("error (%d)\n", err
);
2219 brcmf_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*ndev
,
2221 const struct cfg80211_bitrate_mask
*mask
)
2223 struct brcm_rateset_le rateset_le
;
2231 WL_TRACE("Enter\n");
2232 if (!check_sys_up(wiphy
))
2235 /* addr param is always NULL. ignore it */
2236 /* Get current rateset */
2237 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCM_GET_CURR_RATESET
,
2238 &rateset_le
, sizeof(rateset_le
));
2240 WL_ERR("could not get current rateset (%d)\n", err
);
2244 legacy
= ffs(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
& 0xFFFF);
2246 legacy
= ffs(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
&
2249 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2251 if (val
< le32_to_cpu(rateset_le
.count
))
2252 /* Select rate by rateset index */
2253 rate
= rateset_le
.rates
[val
] & 0x7f;
2255 /* Specified rate in bps */
2256 rate
= val
/ 500000;
2258 WL_CONN("rate %d mbps\n", rate
/ 2);
2262 * Set rate override,
2263 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2265 err_bg
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "bg_rate", rate
);
2266 err_a
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "a_rate", rate
);
2267 if (err_bg
&& err_a
) {
2268 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2269 err
= err_bg
| err_a
;
2277 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2278 struct brcmf_bss_info_le
*bi
)
2280 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2281 struct ieee80211_channel
*notify_channel
;
2282 struct cfg80211_bss
*bss
;
2283 struct ieee80211_supported_band
*band
;
2287 u16 notify_capability
;
2288 u16 notify_interval
;
2290 size_t notify_ielen
;
2293 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2294 WL_ERR("Bss info is larger than buffer. Discarding\n");
2298 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2299 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2301 if (channel
<= CH_MAX_2G_CHANNEL
)
2302 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2304 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2306 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2307 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2309 notify_capability
= le16_to_cpu(bi
->capability
);
2310 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2311 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2312 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2313 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2315 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2316 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2317 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2318 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2319 WL_CONN("Capability: %X\n", notify_capability
);
2320 WL_CONN("Beacon interval: %d\n", notify_interval
);
2321 WL_CONN("Signal: %d\n", notify_signal
);
2323 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2324 0, notify_capability
, notify_interval
, notify_ie
,
2325 notify_ielen
, notify_signal
, GFP_KERNEL
);
2330 cfg80211_put_bss(bss
);
2335 static struct brcmf_bss_info_le
*
2336 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2339 return list
->bss_info_le
;
2340 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2341 le32_to_cpu(bss
->length
));
2344 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2346 struct brcmf_scan_results
*bss_list
;
2347 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2351 bss_list
= cfg
->bss_list
;
2352 if (bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2353 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2357 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2358 for (i
= 0; i
< bss_list
->count
&& i
< WL_AP_MAX
; i
++) {
2359 bi
= next_bss_le(bss_list
, bi
);
2360 err
= brcmf_inform_single_bss(cfg
, bi
);
2367 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2368 struct net_device
*ndev
, const u8
*bssid
)
2370 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2371 struct ieee80211_channel
*notify_channel
;
2372 struct brcmf_bss_info_le
*bi
= NULL
;
2373 struct ieee80211_supported_band
*band
;
2374 struct cfg80211_bss
*bss
;
2379 u16 notify_capability
;
2380 u16 notify_interval
;
2382 size_t notify_ielen
;
2385 WL_TRACE("Enter\n");
2387 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2393 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2395 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2396 buf
, WL_BSS_INFO_MAX
);
2398 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2402 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2404 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2405 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2407 if (channel
<= CH_MAX_2G_CHANNEL
)
2408 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2410 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2412 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2413 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2415 notify_capability
= le16_to_cpu(bi
->capability
);
2416 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2417 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2418 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2419 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2421 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2422 WL_CONN("capability: %X\n", notify_capability
);
2423 WL_CONN("beacon interval: %d\n", notify_interval
);
2424 WL_CONN("signal: %d\n", notify_signal
);
2426 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2427 0, notify_capability
, notify_interval
,
2428 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2435 cfg80211_put_bss(bss
);
2446 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info
*cfg
)
2448 return cfg
->conf
->mode
== WL_MODE_IBSS
;
2452 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2453 * triples, returning a pointer to the substring whose first element
2456 static struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
2458 struct brcmf_tlv
*elt
;
2461 elt
= (struct brcmf_tlv
*) buf
;
2464 /* find tagged parameter */
2465 while (totlen
>= TLV_HDR_LEN
) {
2468 /* validate remaining totlen */
2469 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
2472 elt
= (struct brcmf_tlv
*) ((u8
*) elt
+ (len
+ TLV_HDR_LEN
));
2473 totlen
-= (len
+ TLV_HDR_LEN
);
2479 /* Is any of the tlvs the expected entry? If
2480 * not update the tlvs buffer pointer/length.
2483 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
2484 u8
*oui
, u32 oui_len
, u8 type
)
2486 /* If the contents match the OUI and the type */
2487 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
2488 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
2489 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
2495 /* point to the next ie */
2496 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
2497 /* calculate the length of the rest of the buffer */
2498 *tlvs_len
-= (int)(ie
- *tlvs
);
2499 /* update the pointer to the start of the buffer */
2505 static struct brcmf_vs_tlv
*
2506 brcmf_find_wpaie(u8
*parse
, u32 len
)
2508 struct brcmf_tlv
*ie
;
2510 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
2511 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
2512 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
2513 return (struct brcmf_vs_tlv
*)ie
;
2518 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
)
2520 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
2521 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
2522 struct brcmf_bss_info_le
*bi
;
2523 struct brcmf_ssid
*ssid
;
2524 struct brcmf_tlv
*tim
;
2525 u16 beacon_interval
;
2531 WL_TRACE("Enter\n");
2532 if (brcmf_is_ibssmode(cfg
))
2535 ssid
= &profile
->ssid
;
2537 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2538 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2539 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2541 WL_ERR("Could not get bss info %d\n", err
);
2542 goto update_bss_info_out
;
2545 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2546 err
= brcmf_inform_single_bss(cfg
, bi
);
2548 goto update_bss_info_out
;
2550 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2551 ie_len
= le32_to_cpu(bi
->ie_length
);
2552 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2554 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2556 dtim_period
= tim
->data
[1];
2559 * active scan was done so we could not get dtim
2560 * information out of probe response.
2561 * so we speficially query dtim information to dongle.
2564 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2566 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2567 goto update_bss_info_out
;
2569 dtim_period
= (u8
)var
;
2572 profile
->beacon_interval
= beacon_interval
;
2573 profile
->dtim_period
= dtim_period
;
2575 update_bss_info_out
:
2580 static void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2582 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg
);
2583 struct escan_info
*escan
= &cfg
->escan_info
;
2584 struct brcmf_ssid ssid
;
2586 set_bit(WL_STATUS_SCAN_ABORTING
, &cfg
->status
);
2587 if (cfg
->iscan_on
) {
2588 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2590 if (iscan
->timer_on
) {
2591 del_timer_sync(&iscan
->timer
);
2592 iscan
->timer_on
= 0;
2595 cancel_work_sync(&iscan
->work
);
2597 /* Abort iscan running in FW */
2598 memset(&ssid
, 0, sizeof(ssid
));
2599 brcmf_run_iscan(iscan
, &ssid
, WL_SCAN_ACTION_ABORT
);
2601 if (cfg
->scan_request
) {
2602 /* Indidate scan abort to cfg80211 layer */
2603 WL_INFO("Terminating scan in progress\n");
2604 cfg80211_scan_done(cfg
->scan_request
, true);
2605 cfg
->scan_request
= NULL
;
2608 if (cfg
->escan_on
&& cfg
->scan_request
) {
2609 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2610 brcmf_notify_escan_complete(cfg
, escan
->ndev
, true, true);
2612 clear_bit(WL_STATUS_SCANNING
, &cfg
->status
);
2613 clear_bit(WL_STATUS_SCAN_ABORTING
, &cfg
->status
);
2616 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl
*iscan
,
2619 struct brcmf_cfg80211_info
*cfg
= iscan_to_cfg(iscan
);
2620 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2622 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
2623 WL_ERR("Scan complete while device not scanning\n");
2626 if (cfg
->scan_request
) {
2627 WL_SCAN("ISCAN Completed scan: %s\n",
2628 aborted
? "Aborted" : "Done");
2629 cfg80211_scan_done(cfg
->scan_request
, aborted
);
2630 brcmf_set_mpc(ndev
, 1);
2631 cfg
->scan_request
= NULL
;
2633 cfg
->iscan_kickstart
= false;
2636 static s32
brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl
*iscan
)
2638 if (iscan
->state
!= WL_ISCAN_STATE_IDLE
) {
2639 WL_SCAN("wake up iscan\n");
2640 schedule_work(&iscan
->work
);
2648 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl
*iscan
, u32
*status
,
2649 struct brcmf_scan_results
**bss_list
)
2651 struct brcmf_scan_results
*results
;
2652 struct brcmf_scan_results_le
*results_le
;
2653 struct brcmf_iscan_results
*list_buf
;
2656 memset(iscan
->scan_buf
, 0, WL_ISCAN_BUF_MAX
);
2657 list_buf
= (struct brcmf_iscan_results
*)iscan
->scan_buf
;
2658 results
= &list_buf
->results
;
2659 results_le
= &list_buf
->results_le
;
2660 results_le
->buflen
= cpu_to_le32(sizeof(iscan
->scan_buf
));
2661 results_le
->version
= 0;
2662 results_le
->count
= 0;
2664 err
= brcmf_fil_iovar_data_get(netdev_priv(iscan
->ndev
), "iscanresults",
2666 sizeof(iscan
->scan_buf
));
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_info
*cfg
)
2685 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg
->iscan
;
2688 iscan
->state
= WL_ISCAN_STATE_IDLE
;
2689 brcmf_inform_bss(cfg
);
2690 brcmf_notify_iscan_complete(iscan
, false);
2695 static s32
brcmf_iscan_pending(struct brcmf_cfg80211_info
*cfg
)
2697 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg
->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_info
*cfg
)
2709 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg
->iscan
;
2712 brcmf_inform_bss(cfg
);
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_info
*cfg
)
2723 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg
->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_info
*cfg
= 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
->bss_list
)) {
2747 status
= BRCMF_SCAN_RESULTS_ABORTED
;
2748 WL_ERR("Abort iscan\n");
2751 el
->handler
[status
](cfg
);
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_info
*cfg
)
2768 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg
);
2770 if (cfg
->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_info
*cfg
)
2790 struct brcmf_cfg80211_iscan_ctrl
*iscan
= cfg_to_iscan(cfg
);
2793 if (cfg
->iscan_on
) {
2794 iscan
->ndev
= cfg_to_ndev(cfg
);
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
);
2808 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2810 struct brcmf_cfg80211_info
*cfg
=
2811 container_of(work
, struct brcmf_cfg80211_info
,
2812 escan_timeout_work
);
2814 brcmf_notify_escan_complete(cfg
,
2815 cfg
->escan_info
.ndev
, true, true);
2818 static void brcmf_escan_timeout(unsigned long data
)
2820 struct brcmf_cfg80211_info
*cfg
=
2821 (struct brcmf_cfg80211_info
*)data
;
2823 if (cfg
->scan_request
) {
2824 WL_ERR("timer expired\n");
2826 schedule_work(&cfg
->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_info
*cfg
,
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
->escan_on
||
2880 !test_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
2881 WL_ERR("scan not ready ndev %p wl->escan_on %d drv_status %x\n",
2882 ndev
, cfg
->escan_on
,
2883 !test_bit(WL_STATUS_SCANNING
, &cfg
->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
->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
)->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
->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
->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
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2944 if (cfg
->scan_request
) {
2945 cfg
->bss_list
= (struct brcmf_scan_results
*)
2946 cfg
->escan_info
.escan_buf
;
2947 brcmf_inform_bss(cfg
);
2948 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2949 brcmf_notify_escan_complete(cfg
, ndev
, aborted
,
2952 WL_ERR("Unexpected scan result 0x%x\n", status
);
2958 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2961 if (cfg
->escan_on
) {
2962 cfg
->el
.handler
[BRCMF_E_ESCAN_RESULT
] =
2963 brcmf_cfg80211_escan_handler
;
2964 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2965 /* Init scan_timeout timer */
2966 init_timer(&cfg
->escan_timeout
);
2967 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2968 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2969 INIT_WORK(&cfg
->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_info
*cfg
= 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
->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_info
*cfg
= wiphy_to_cfg(wiphy
);
3006 struct net_device
*ndev
= cfg_to_ndev(cfg
);
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
->status
) ||
3021 test_bit(WL_STATUS_CONNECTING
, &cfg
->status
)) &&
3022 test_bit(WL_STATUS_READY
, &cfg
->status
)) {
3023 WL_INFO("Disassociating from AP"
3024 " while entering suspend state\n");
3025 brcmf_link_down(cfg
);
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 if (test_bit(WL_STATUS_READY
, &cfg
->status
))
3036 brcmf_abort_scanning(cfg
);
3038 clear_bit(WL_STATUS_SCANNING
, &cfg
->status
);
3040 /* Turn off watchdog timer */
3041 if (test_bit(WL_STATUS_READY
, &cfg
->status
))
3042 brcmf_set_mpc(ndev
, 1);
3050 brcmf_update_pmklist(struct net_device
*ndev
,
3051 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
3056 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
3058 WL_CONN("No of elements %d\n", pmkid_len
);
3059 for (i
= 0; i
< pmkid_len
; i
++) {
3060 WL_CONN("PMKID[%d]: %pM =\n", i
,
3061 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
3062 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
3063 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
3067 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
3068 (char *)pmk_list
, sizeof(*pmk_list
));
3074 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3075 struct cfg80211_pmksa
*pmksa
)
3077 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3078 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
3083 WL_TRACE("Enter\n");
3084 if (!check_sys_up(wiphy
))
3087 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
3088 for (i
= 0; i
< pmkid_len
; i
++)
3089 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
3091 if (i
< WL_NUM_PMKIDS_MAX
) {
3092 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
3093 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3094 if (i
== pmkid_len
) {
3096 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
3101 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3102 pmkids
->pmkid
[pmkid_len
].BSSID
);
3103 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
3104 WL_CONN("%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
3106 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
3113 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3114 struct cfg80211_pmksa
*pmksa
)
3116 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3117 struct pmkid_list pmkid
;
3121 WL_TRACE("Enter\n");
3122 if (!check_sys_up(wiphy
))
3125 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
3126 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3128 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3129 &pmkid
.pmkid
[0].BSSID
);
3130 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
3131 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
3133 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
3134 for (i
= 0; i
< pmkid_len
; i
++)
3136 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
3141 && (i
< pmkid_len
)) {
3142 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
3143 sizeof(struct pmkid
));
3144 for (; i
< (pmkid_len
- 1); i
++) {
3145 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
3146 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
3148 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
3149 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
3152 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
3156 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
3164 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
3166 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3169 WL_TRACE("Enter\n");
3170 if (!check_sys_up(wiphy
))
3173 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
3174 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
3182 * PFN result doesn't have all the info which are
3183 * required by the supplicant
3184 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3185 * via wl_inform_single_bss in the required format. Escan does require the
3186 * scan request in the form of cfg80211_scan_request. For timebeing, create
3187 * cfg80211_scan_request one out of the received PNO event.
3190 brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info
*cfg
,
3191 struct net_device
*ndev
,
3192 const struct brcmf_event_msg
*e
, void *data
)
3194 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
3195 struct cfg80211_scan_request
*request
= NULL
;
3196 struct cfg80211_ssid
*ssid
= NULL
;
3197 struct ieee80211_channel
*channel
= NULL
;
3198 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3200 int channel_req
= 0;
3202 struct brcmf_pno_scanresults_le
*pfn_result
;
3208 if (e
->event_type
== cpu_to_be32(BRCMF_E_PFN_NET_LOST
)) {
3209 WL_SCAN("PFN NET LOST event. Do Nothing\n");
3213 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
3214 result_count
= le32_to_cpu(pfn_result
->count
);
3215 status
= le32_to_cpu(pfn_result
->status
);
3218 * PFN event is limited to fit 512 bytes so we may get
3219 * multiple NET_FOUND events. For now place a warning here.
3221 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
3222 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count
);
3223 if (result_count
> 0) {
3226 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
3227 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
3228 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
3229 if (!request
|| !ssid
|| !channel
) {
3234 request
->wiphy
= wiphy
;
3235 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3236 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
3238 for (i
= 0; i
< result_count
; i
++) {
3239 netinfo
= &netinfo_start
[i
];
3241 WL_ERR("Invalid netinfo ptr. index: %d\n", i
);
3246 WL_SCAN("SSID:%s Channel:%d\n",
3247 netinfo
->SSID
, netinfo
->channel
);
3248 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3249 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
3252 channel_req
= netinfo
->channel
;
3253 if (channel_req
<= CH_MAX_2G_CHANNEL
)
3254 band
= NL80211_BAND_2GHZ
;
3256 band
= NL80211_BAND_5GHZ
;
3257 channel
[i
].center_freq
=
3258 ieee80211_channel_to_frequency(channel_req
,
3260 channel
[i
].band
= band
;
3261 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
3262 request
->channels
[i
] = &channel
[i
];
3263 request
->n_channels
++;
3266 /* assign parsed ssid array */
3267 if (request
->n_ssids
)
3268 request
->ssids
= &ssid
[0];
3270 if (test_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
3271 /* Abort any on-going scan */
3272 brcmf_abort_scanning(cfg
);
3275 set_bit(WL_STATUS_SCANNING
, &cfg
->status
);
3276 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
3278 clear_bit(WL_STATUS_SCANNING
, &cfg
->status
);
3281 cfg
->sched_escan
= true;
3282 cfg
->scan_request
= request
;
3284 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
3297 cfg80211_sched_scan_stopped(wiphy
);
3301 #ifndef CONFIG_BRCMISCAN
3302 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3307 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3310 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3314 WL_ERR("failed code %d\n", ret
);
3319 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3321 struct brcmf_pno_param_le pfn_param
;
3323 memset(&pfn_param
, 0, sizeof(pfn_param
));
3324 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3326 /* set extra pno params */
3327 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3328 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3329 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3331 /* set up pno scan fr */
3332 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3334 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3335 &pfn_param
, sizeof(pfn_param
));
3339 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3340 struct net_device
*ndev
,
3341 struct cfg80211_sched_scan_request
*request
)
3343 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3344 struct brcmf_pno_net_param_le pfn
;
3348 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
3349 request
->n_match_sets
, request
->n_ssids
);
3350 if (test_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
3351 WL_ERR("Scanning already : status (%lu)\n", cfg
->status
);
3355 if (!request
|| !request
->n_ssids
|| !request
->n_match_sets
) {
3356 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
3361 if (request
->n_ssids
> 0) {
3362 for (i
= 0; i
< request
->n_ssids
; i
++) {
3363 /* Active scan req for ssids */
3364 WL_SCAN(">>> Active scan req for ssid (%s)\n",
3365 request
->ssids
[i
].ssid
);
3368 * match_set ssids is a supert set of n_ssid list,
3369 * so we need not add these set seperately.
3374 if (request
->n_match_sets
> 0) {
3375 /* clean up everything */
3376 ret
= brcmf_dev_pno_clean(ndev
);
3378 WL_ERR("failed error=%d\n", ret
);
3383 ret
= brcmf_dev_pno_config(ndev
);
3385 WL_ERR("PNO setup failed!! ret=%d\n", ret
);
3389 /* configure each match set */
3390 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3391 struct cfg80211_ssid
*ssid
;
3394 ssid
= &request
->match_sets
[i
].ssid
;
3395 ssid_len
= ssid
->ssid_len
;
3398 WL_ERR("skip broadcast ssid\n");
3401 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3402 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3403 pfn
.wsec
= cpu_to_le32(0);
3404 pfn
.infra
= cpu_to_le32(1);
3405 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3406 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3407 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3408 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
),
3411 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
3412 ret
== 0 ? "set" : "failed",
3415 /* Enable the PNO */
3416 if (brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 1) < 0) {
3417 WL_ERR("PNO enable failed!! ret=%d\n", ret
);
3427 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3428 struct net_device
*ndev
)
3430 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3433 brcmf_dev_pno_clean(ndev
);
3434 if (cfg
->sched_escan
)
3435 brcmf_notify_escan_complete(cfg
, ndev
, true, true);
3438 #endif /* CONFIG_BRCMISCAN */
3440 #ifdef CONFIG_NL80211_TESTMODE
3441 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
3443 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3444 struct net_device
*ndev
= cfg
->wdev
->netdev
;
3445 struct brcmf_dcmd
*dcmd
= data
;
3446 struct sk_buff
*reply
;
3449 WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3450 dcmd
->buf
, dcmd
->len
);
3453 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3454 dcmd
->buf
, dcmd
->len
);
3456 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3457 dcmd
->buf
, dcmd
->len
);
3459 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3460 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3461 ret
= cfg80211_testmode_reply(reply
);
3467 static s32
brcmf_configure_opensecurity(struct net_device
*ndev
, s32 bssidx
)
3469 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3473 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3475 WL_ERR("auth error %d\n", err
);
3479 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3481 WL_ERR("wsec error %d\n", err
);
3484 /* set upper-layer auth */
3485 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3487 WL_ERR("wpa_auth error %d\n", err
);
3494 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3497 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3499 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3503 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3504 bool is_rsn_ie
, s32 bssidx
)
3506 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3507 u32 auth
= 0; /* d11 open authentication */
3519 u32 wme_bss_disable
;
3521 WL_TRACE("Enter\n");
3525 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3526 data
= (u8
*)wpa_ie
;
3529 offset
+= VS_IE_FIXED_HDR_LEN
;
3530 offset
+= WPA_IE_VERSION_LEN
;
3532 /* check for multicast cipher suite */
3533 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3535 WL_ERR("no multicast cipher suite\n");
3539 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3541 WL_ERR("ivalid OUI\n");
3544 offset
+= TLV_OUI_LEN
;
3546 /* pick up multicast cipher */
3547 switch (data
[offset
]) {
3548 case WPA_CIPHER_NONE
:
3551 case WPA_CIPHER_WEP_40
:
3552 case WPA_CIPHER_WEP_104
:
3555 case WPA_CIPHER_TKIP
:
3556 gval
= TKIP_ENABLED
;
3558 case WPA_CIPHER_AES_CCM
:
3563 WL_ERR("Invalid multi cast cipher info\n");
3568 /* walk thru unicast cipher list and pick up what we recognize */
3569 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3570 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3571 /* Check for unicast suite(s) */
3572 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3574 WL_ERR("no unicast cipher suite\n");
3577 for (i
= 0; i
< count
; i
++) {
3578 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3580 WL_ERR("ivalid OUI\n");
3583 offset
+= TLV_OUI_LEN
;
3584 switch (data
[offset
]) {
3585 case WPA_CIPHER_NONE
:
3587 case WPA_CIPHER_WEP_40
:
3588 case WPA_CIPHER_WEP_104
:
3589 pval
|= WEP_ENABLED
;
3591 case WPA_CIPHER_TKIP
:
3592 pval
|= TKIP_ENABLED
;
3594 case WPA_CIPHER_AES_CCM
:
3595 pval
|= AES_ENABLED
;
3598 WL_ERR("Ivalid unicast security info\n");
3602 /* walk thru auth management suite list and pick up what we recognize */
3603 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3604 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3605 /* Check for auth key management suite(s) */
3606 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3608 WL_ERR("no auth key mgmt suite\n");
3611 for (i
= 0; i
< count
; i
++) {
3612 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3614 WL_ERR("ivalid OUI\n");
3617 offset
+= TLV_OUI_LEN
;
3618 switch (data
[offset
]) {
3620 WL_TRACE("RSN_AKM_NONE\n");
3621 wpa_auth
|= WPA_AUTH_NONE
;
3623 case RSN_AKM_UNSPECIFIED
:
3624 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3625 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3626 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3629 WL_TRACE("RSN_AKM_PSK\n");
3630 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3631 (wpa_auth
|= WPA_AUTH_PSK
);
3634 WL_ERR("Ivalid key mgmt info\n");
3640 wme_bss_disable
= 1;
3641 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3642 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3643 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3644 wme_bss_disable
= 0;
3646 /* set wme_bss_disable to sync RSN Capabilities */
3647 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3650 WL_ERR("wme_bss_disable error %d\n", err
);
3654 /* FOR WPS , set SES_OW_ENABLED */
3655 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3658 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3660 WL_ERR("auth error %d\n", err
);
3664 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3666 WL_ERR("wsec error %d\n", err
);
3669 /* set upper-layer auth */
3670 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3672 WL_ERR("wpa_auth error %d\n", err
);
3681 brcmf_parse_vndr_ies(u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3682 struct parsed_vndr_ies
*vndr_ies
)
3685 struct brcmf_vs_tlv
*vndrie
;
3686 struct brcmf_tlv
*ie
;
3687 struct parsed_vndr_ie_info
*parsed_info
;
3690 remaining_len
= (s32
)vndr_ie_len
;
3691 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3693 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3695 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3697 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3698 /* len should be bigger than OUI length + one */
3699 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3700 WL_ERR("invalid vndr ie. length is too small %d\n",
3704 /* if wpa or wme ie, do not add ie */
3705 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3706 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3707 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3708 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3712 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3714 /* save vndr ie information */
3715 parsed_info
->ie_ptr
= (char *)vndrie
;
3716 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3717 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3721 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3722 parsed_info
->vndrie
.oui
[0],
3723 parsed_info
->vndrie
.oui
[1],
3724 parsed_info
->vndrie
.oui
[2],
3725 parsed_info
->vndrie
.oui_type
);
3727 if (vndr_ies
->count
>= MAX_VNDR_IE_NUMBER
)
3730 remaining_len
-= ie
->len
;
3731 if (remaining_len
<= 2)
3734 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
);
3740 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3746 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3747 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3749 iecount_le
= cpu_to_le32(1);
3750 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3752 pktflag_le
= cpu_to_le32(pktflag
);
3753 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3755 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3757 return ie_len
+ VNDR_IE_HDR_SIZE
;
3761 brcmf_set_management_ie(struct brcmf_cfg80211_info
*cfg
,
3762 struct net_device
*ndev
, s32 pktflag
,
3763 u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3768 u8
*mgmt_ie_buf
= NULL
;
3769 int mgmt_ie_buf_len
;
3771 u32 del_add_ie_buf_len
= 0;
3772 u32 total_ie_buf_len
= 0;
3773 u32 parsed_ie_buf_len
= 0;
3774 struct parsed_vndr_ies old_vndr_ies
;
3775 struct parsed_vndr_ies new_vndr_ies
;
3776 struct parsed_vndr_ie_info
*vndrie_info
;
3778 s32 bssidx
= brcmf_ndev_bssidx(ndev
);
3780 int remained_buf_len
;
3782 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", bssidx
, pktflag
);
3783 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3786 curr_ie_buf
= iovar_ie_buf
;
3787 if (test_bit(WL_STATUS_AP_CREATING
, &cfg
->status
) ||
3788 test_bit(WL_STATUS_AP_CREATED
, &cfg
->status
)) {
3790 case VNDR_IE_PRBRSP_FLAG
:
3791 mgmt_ie_buf
= cfg
->ap_info
->probe_res_ie
;
3792 mgmt_ie_len
= &cfg
->ap_info
->probe_res_ie_len
;
3793 mgmt_ie_buf_len
= sizeof(cfg
->ap_info
->probe_res_ie
);
3795 case VNDR_IE_BEACON_FLAG
:
3796 mgmt_ie_buf
= cfg
->ap_info
->beacon_ie
;
3797 mgmt_ie_len
= &cfg
->ap_info
->beacon_ie_len
;
3798 mgmt_ie_buf_len
= sizeof(cfg
->ap_info
->beacon_ie
);
3802 WL_ERR("not suitable type\n");
3807 WL_ERR("not suitable type\n");
3811 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3813 WL_ERR("extra IE size too big\n");
3817 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3818 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3820 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3821 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3822 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3823 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3824 vndrie_info
->ie_len
);
3825 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3829 if (mgmt_ie_buf
!= NULL
) {
3830 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3831 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3832 parsed_ie_buf_len
) == 0)) {
3833 WL_TRACE("Previous mgmt IE is equals to current IE");
3837 /* parse old vndr_ie */
3838 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3840 /* make a command to delete old ie */
3841 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3842 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3844 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3845 vndrie_info
->vndrie
.id
,
3846 vndrie_info
->vndrie
.len
,
3847 vndrie_info
->vndrie
.oui
[0],
3848 vndrie_info
->vndrie
.oui
[1],
3849 vndrie_info
->vndrie
.oui
[2]);
3851 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3852 vndrie_info
->ie_ptr
,
3853 vndrie_info
->ie_len
,
3855 curr_ie_buf
+= del_add_ie_buf_len
;
3856 total_ie_buf_len
+= del_add_ie_buf_len
;
3861 /* Add if there is any extra IE */
3862 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3865 remained_buf_len
= mgmt_ie_buf_len
;
3867 /* make a command to add new ie */
3868 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3869 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3871 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3872 vndrie_info
->vndrie
.id
,
3873 vndrie_info
->vndrie
.len
,
3874 vndrie_info
->vndrie
.oui
[0],
3875 vndrie_info
->vndrie
.oui
[1],
3876 vndrie_info
->vndrie
.oui
[2]);
3878 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3879 vndrie_info
->ie_ptr
,
3880 vndrie_info
->ie_len
,
3882 /* verify remained buf size before copy data */
3883 remained_buf_len
-= vndrie_info
->ie_len
;
3884 if (remained_buf_len
< 0) {
3885 WL_ERR("no space in mgmt_ie_buf: len left %d",
3890 /* save the parsed IE in wl struct */
3891 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3892 vndrie_info
->ie_len
);
3893 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3895 curr_ie_buf
+= del_add_ie_buf_len
;
3896 total_ie_buf_len
+= del_add_ie_buf_len
;
3899 if (total_ie_buf_len
) {
3900 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "vndr_ie",
3904 WL_ERR("vndr ie set error : %d\n", err
);
3908 kfree(iovar_ie_buf
);
3913 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3914 struct cfg80211_ap_settings
*settings
)
3917 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3918 struct brcmf_tlv
*ssid_ie
;
3919 struct brcmf_ssid_le ssid_le
;
3921 struct brcmf_tlv
*rsn_ie
;
3922 struct brcmf_vs_tlv
*wpa_ie
;
3923 struct brcmf_join_params join_params
;
3924 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3927 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3928 settings
->channel_type
, settings
->beacon_interval
,
3929 settings
->dtim_period
);
3930 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
3931 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3932 settings
->inactivity_timeout
);
3934 if (!test_bit(WL_STATUS_AP_CREATING
, &cfg
->status
)) {
3935 WL_ERR("Not in AP creation mode\n");
3939 memset(&ssid_le
, 0, sizeof(ssid_le
));
3940 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3941 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3942 ssid_ie
= brcmf_parse_tlvs(
3943 (u8
*)&settings
->beacon
.head
[ie_offset
],
3944 settings
->beacon
.head_len
- ie_offset
,
3949 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3950 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3951 WL_TRACE("SSID is (%s) in Head\n", ssid_le
.SSID
);
3953 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3954 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3957 brcmf_set_mpc(ndev
, 0);
3958 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3960 WL_ERR("BRCMF_C_DOWN error %d\n", err
);
3963 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3965 WL_ERR("SET INFRA error %d\n", err
);
3968 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3970 WL_ERR("setting AP mode failed %d\n", err
);
3974 /* find the RSN_IE */
3975 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3976 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3978 /* find the WPA_IE */
3979 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3980 settings
->beacon
.tail_len
);
3982 kfree(cfg
->ap_info
->rsn_ie
);
3983 cfg
->ap_info
->rsn_ie
= NULL
;
3984 kfree(cfg
->ap_info
->wpa_ie
);
3985 cfg
->ap_info
->wpa_ie
= NULL
;
3987 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3988 WL_TRACE("WPA(2) IE is found\n");
3989 if (wpa_ie
!= NULL
) {
3991 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false,
3995 cfg
->ap_info
->wpa_ie
= kmemdup(wpa_ie
,
4001 err
= brcmf_configure_wpaie(ndev
,
4002 (struct brcmf_vs_tlv
*)rsn_ie
, true, bssidx
);
4005 cfg
->ap_info
->rsn_ie
= kmemdup(rsn_ie
,
4010 cfg
->ap_info
->security_mode
= true;
4012 WL_TRACE("No WPA(2) IEs found\n");
4013 brcmf_configure_opensecurity(ndev
, bssidx
);
4014 cfg
->ap_info
->security_mode
= false;
4016 /* Set Beacon IEs to FW */
4017 err
= brcmf_set_management_ie(cfg
, ndev
,
4018 VNDR_IE_BEACON_FLAG
,
4019 (u8
*)settings
->beacon
.tail
,
4020 settings
->beacon
.tail_len
);
4022 WL_ERR("Set Beacon IE Failed\n");
4024 WL_TRACE("Applied Vndr IEs for Beacon\n");
4026 /* Set Probe Response IEs to FW */
4027 err
= brcmf_set_management_ie(cfg
, ndev
,
4028 VNDR_IE_PRBRSP_FLAG
,
4029 (u8
*)settings
->beacon
.proberesp_ies
,
4030 settings
->beacon
.proberesp_ies_len
);
4032 WL_ERR("Set Probe Resp IE Failed\n");
4034 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
4036 if (settings
->beacon_interval
) {
4037 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
4038 settings
->beacon_interval
);
4040 WL_ERR("Beacon Interval Set Error, %d\n", err
);
4044 if (settings
->dtim_period
) {
4045 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
4046 settings
->dtim_period
);
4048 WL_ERR("DTIM Interval Set Error, %d\n", err
);
4052 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
4054 WL_ERR("BRCMF_C_UP error (%d)\n", err
);
4058 memset(&join_params
, 0, sizeof(join_params
));
4059 /* join parameters starts with ssid */
4060 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
4062 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
4063 &join_params
, sizeof(join_params
));
4065 WL_ERR("SET SSID error (%d)\n", err
);
4068 clear_bit(WL_STATUS_AP_CREATING
, &cfg
->status
);
4069 set_bit(WL_STATUS_AP_CREATED
, &cfg
->status
);
4073 brcmf_set_mpc(ndev
, 1);
4077 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
4079 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4082 WL_TRACE("Enter\n");
4084 if (cfg
->conf
->mode
== WL_MODE_AP
) {
4085 /* Due to most likely deauths outstanding we sleep */
4086 /* first to make sure they get processed by fw. */
4088 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
4091 WL_ERR("setting AP mode failed %d\n", err
);
4094 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_UP
, 0);
4096 WL_ERR("BRCMF_C_UP error %d\n", err
);
4099 brcmf_set_mpc(ndev
, 1);
4100 clear_bit(WL_STATUS_AP_CREATING
, &cfg
->status
);
4101 clear_bit(WL_STATUS_AP_CREATED
, &cfg
->status
);
4108 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
4111 struct brcmf_scb_val_le scbval
;
4117 WL_TRACE("Enter %pM\n", mac
);
4119 if (!check_sys_up(wiphy
))
4122 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
4123 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
4124 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
),
4125 BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
4126 &scbval
, sizeof(scbval
));
4128 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
4134 static struct cfg80211_ops wl_cfg80211_ops
= {
4135 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4136 .scan
= brcmf_cfg80211_scan
,
4137 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4138 .join_ibss
= brcmf_cfg80211_join_ibss
,
4139 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4140 .get_station
= brcmf_cfg80211_get_station
,
4141 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4142 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4143 .add_key
= brcmf_cfg80211_add_key
,
4144 .del_key
= brcmf_cfg80211_del_key
,
4145 .get_key
= brcmf_cfg80211_get_key
,
4146 .set_default_key
= brcmf_cfg80211_config_default_key
,
4147 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4148 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4149 .set_bitrate_mask
= brcmf_cfg80211_set_bitrate_mask
,
4150 .connect
= brcmf_cfg80211_connect
,
4151 .disconnect
= brcmf_cfg80211_disconnect
,
4152 .suspend
= brcmf_cfg80211_suspend
,
4153 .resume
= brcmf_cfg80211_resume
,
4154 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4155 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4156 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4157 .start_ap
= brcmf_cfg80211_start_ap
,
4158 .stop_ap
= brcmf_cfg80211_stop_ap
,
4159 .del_station
= brcmf_cfg80211_del_station
,
4160 #ifndef CONFIG_BRCMISCAN
4161 /* scheduled scan need e-scan, which is mutual exclusive with i-scan */
4162 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4163 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4165 #ifdef CONFIG_NL80211_TESTMODE
4166 .testmode_cmd
= brcmf_cfg80211_testmode
4170 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
)
4176 return NL80211_IFTYPE_STATION
;
4178 return NL80211_IFTYPE_ADHOC
;
4180 return NL80211_IFTYPE_UNSPECIFIED
;
4186 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4188 #ifndef CONFIG_BRCMFISCAN
4189 /* scheduled scan settings */
4190 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4191 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4192 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4193 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4197 static struct wireless_dev
*brcmf_alloc_wdev(struct device
*ndev
)
4199 struct wireless_dev
*wdev
;
4202 wdev
= kzalloc(sizeof(*wdev
), GFP_KERNEL
);
4204 return ERR_PTR(-ENOMEM
);
4206 wdev
->wiphy
= wiphy_new(&wl_cfg80211_ops
,
4207 sizeof(struct brcmf_cfg80211_info
));
4209 WL_ERR("Could not allocate wiphy device\n");
4213 set_wiphy_dev(wdev
->wiphy
, ndev
);
4214 wdev
->wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4215 wdev
->wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4216 wdev
->wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4217 BIT(NL80211_IFTYPE_ADHOC
) |
4218 BIT(NL80211_IFTYPE_AP
);
4219 wdev
->wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4220 wdev
->wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
4221 * it as 11a by default.
4222 * This will be updated with
4225 * if phy has 11n capability
4227 wdev
->wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4228 wdev
->wiphy
->cipher_suites
= __wl_cipher_suites
;
4229 wdev
->wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4230 wdev
->wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
4234 brcmf_wiphy_pno_params(wdev
->wiphy
);
4235 err
= wiphy_register(wdev
->wiphy
);
4237 WL_ERR("Could not register wiphy device (%d)\n", err
);
4238 goto wiphy_register_out
;
4243 wiphy_free(wdev
->wiphy
);
4248 return ERR_PTR(err
);
4251 static void brcmf_free_wdev(struct brcmf_cfg80211_info
*cfg
)
4253 struct wireless_dev
*wdev
= cfg
->wdev
;
4256 WL_ERR("wdev is invalid\n");
4259 wiphy_unregister(wdev
->wiphy
);
4260 wiphy_free(wdev
->wiphy
);
4265 static bool brcmf_is_linkup(struct brcmf_cfg80211_info
*cfg
,
4266 const struct brcmf_event_msg
*e
)
4268 u32 event
= be32_to_cpu(e
->event_type
);
4269 u32 status
= be32_to_cpu(e
->status
);
4271 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4272 WL_CONN("Processing set ssid\n");
4273 cfg
->link_up
= true;
4280 static bool brcmf_is_linkdown(struct brcmf_cfg80211_info
*cfg
,
4281 const struct brcmf_event_msg
*e
)
4283 u32 event
= be32_to_cpu(e
->event_type
);
4284 u16 flags
= be16_to_cpu(e
->flags
);
4286 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
4287 WL_CONN("Processing link down\n");
4293 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4294 const struct brcmf_event_msg
*e
)
4296 u32 event
= be32_to_cpu(e
->event_type
);
4297 u32 status
= be32_to_cpu(e
->status
);
4299 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4300 WL_CONN("Processing Link %s & no network found\n",
4301 be16_to_cpu(e
->flags
) & BRCMF_EVENT_MSG_LINK
?
4306 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4307 WL_CONN("Processing connecting & no network found\n");
4314 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4316 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4318 kfree(conn_info
->req_ie
);
4319 conn_info
->req_ie
= NULL
;
4320 conn_info
->req_ie_len
= 0;
4321 kfree(conn_info
->resp_ie
);
4322 conn_info
->resp_ie
= NULL
;
4323 conn_info
->resp_ie_len
= 0;
4326 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4328 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4329 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4330 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4335 brcmf_clear_assoc_ies(cfg
);
4337 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4338 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4340 WL_ERR("could not get assoc info (%d)\n", err
);
4344 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4345 req_len
= le32_to_cpu(assoc_info
->req_len
);
4346 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4348 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4352 WL_ERR("could not get assoc req (%d)\n", err
);
4355 conn_info
->req_ie_len
= req_len
;
4357 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4360 conn_info
->req_ie_len
= 0;
4361 conn_info
->req_ie
= NULL
;
4364 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4368 WL_ERR("could not get assoc resp (%d)\n", err
);
4371 conn_info
->resp_ie_len
= resp_len
;
4372 conn_info
->resp_ie
=
4373 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4376 conn_info
->resp_ie_len
= 0;
4377 conn_info
->resp_ie
= NULL
;
4379 WL_CONN("req len (%d) resp len (%d)\n",
4380 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4386 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4387 struct net_device
*ndev
,
4388 const struct brcmf_event_msg
*e
)
4390 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
4391 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4392 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4393 struct ieee80211_channel
*notify_channel
= NULL
;
4394 struct ieee80211_supported_band
*band
;
4395 struct brcmf_bss_info_le
*bi
;
4401 WL_TRACE("Enter\n");
4403 brcmf_get_assoc_ies(cfg
);
4404 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4405 brcmf_update_bss_info(cfg
);
4407 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4413 /* data sent to dongle has to be little endian */
4414 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4415 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
4416 buf
, WL_BSS_INFO_MAX
);
4421 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4422 target_channel
= bi
->ctl_ch
? bi
->ctl_ch
:
4423 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
4425 if (target_channel
<= CH_MAX_2G_CHANNEL
)
4426 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4428 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4430 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
4431 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4435 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4436 conn_info
->req_ie
, conn_info
->req_ie_len
,
4437 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4438 WL_CONN("Report roaming result\n");
4440 set_bit(WL_STATUS_CONNECTED
, &cfg
->status
);
4446 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4447 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4450 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
4451 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4454 WL_TRACE("Enter\n");
4456 if (test_and_clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
)) {
4458 brcmf_get_assoc_ies(cfg
);
4459 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4460 brcmf_update_bss_info(cfg
);
4462 cfg80211_connect_result(ndev
,
4463 (u8
*)profile
->bssid
,
4465 conn_info
->req_ie_len
,
4467 conn_info
->resp_ie_len
,
4468 completed
? WLAN_STATUS_SUCCESS
:
4469 WLAN_STATUS_AUTH_TIMEOUT
,
4472 set_bit(WL_STATUS_CONNECTED
, &cfg
->status
);
4473 WL_CONN("Report connect result - connection %s\n",
4474 completed
? "succeeded" : "failed");
4481 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4482 struct net_device
*ndev
,
4483 const struct brcmf_event_msg
*e
, void *data
)
4486 u32 event
= be32_to_cpu(e
->event_type
);
4487 u32 reason
= be32_to_cpu(e
->reason
);
4488 u32 len
= be32_to_cpu(e
->datalen
);
4489 static int generation
;
4491 struct station_info sinfo
;
4493 WL_CONN("event %d, reason %d\n", event
, reason
);
4494 memset(&sinfo
, 0, sizeof(sinfo
));
4497 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4498 reason
== BRCMF_E_STATUS_SUCCESS
) {
4499 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4501 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4504 sinfo
.assoc_req_ies
= data
;
4505 sinfo
.assoc_req_ies_len
= len
;
4507 sinfo
.generation
= generation
;
4508 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_ATOMIC
);
4509 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4510 (event
== BRCMF_E_DEAUTH_IND
) ||
4511 (event
== BRCMF_E_DEAUTH
)) {
4513 sinfo
.generation
= generation
;
4514 cfg80211_del_sta(ndev
, e
->addr
, GFP_ATOMIC
);
4520 brcmf_notify_connect_status(struct brcmf_cfg80211_info
*cfg
,
4521 struct net_device
*ndev
,
4522 const struct brcmf_event_msg
*e
, void *data
)
4524 struct brcmf_cfg80211_profile
*profile
= cfg
->profile
;
4527 if (cfg
->conf
->mode
== WL_MODE_AP
) {
4528 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4529 } else if (brcmf_is_linkup(cfg
, e
)) {
4530 WL_CONN("Linkup\n");
4531 if (brcmf_is_ibssmode(cfg
)) {
4532 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4533 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4534 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4535 clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
4536 set_bit(WL_STATUS_CONNECTED
, &cfg
->status
);
4538 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4539 } else if (brcmf_is_linkdown(cfg
, e
)) {
4540 WL_CONN("Linkdown\n");
4541 if (brcmf_is_ibssmode(cfg
)) {
4542 clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
4543 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
4545 brcmf_link_down(cfg
);
4547 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4548 if (test_and_clear_bit(WL_STATUS_CONNECTED
,
4550 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4552 brcmf_link_down(cfg
);
4555 brcmf_init_prof(cfg
->profile
);
4556 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4557 if (brcmf_is_ibssmode(cfg
))
4558 clear_bit(WL_STATUS_CONNECTING
, &cfg
->status
);
4560 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4567 brcmf_notify_roaming_status(struct brcmf_cfg80211_info
*cfg
,
4568 struct net_device
*ndev
,
4569 const struct brcmf_event_msg
*e
, void *data
)
4572 u32 event
= be32_to_cpu(e
->event_type
);
4573 u32 status
= be32_to_cpu(e
->status
);
4575 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4576 if (test_bit(WL_STATUS_CONNECTED
, &cfg
->status
))
4577 brcmf_bss_roaming_done(cfg
, ndev
, e
);
4579 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4586 brcmf_notify_mic_status(struct brcmf_cfg80211_info
*cfg
,
4587 struct net_device
*ndev
,
4588 const struct brcmf_event_msg
*e
, void *data
)
4590 u16 flags
= be16_to_cpu(e
->flags
);
4591 enum nl80211_key_type key_type
;
4593 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4594 key_type
= NL80211_KEYTYPE_GROUP
;
4596 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4598 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
4605 brcmf_notify_scan_status(struct brcmf_cfg80211_info
*cfg
,
4606 struct net_device
*ndev
,
4607 const struct brcmf_event_msg
*e
, void *data
)
4609 struct brcmf_channel_info_le channel_inform_le
;
4610 struct brcmf_scan_results_le
*bss_list_le
;
4611 u32 len
= WL_SCAN_BUF_MAX
;
4613 bool scan_abort
= false;
4616 WL_TRACE("Enter\n");
4618 if (cfg
->iscan_on
&& cfg
->iscan_kickstart
) {
4620 return brcmf_wakeup_iscan(cfg_to_iscan(cfg
));
4623 if (!test_and_clear_bit(WL_STATUS_SCANNING
, &cfg
->status
)) {
4624 WL_ERR("Scan complete while device not scanning\n");
4630 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_CHANNEL
,
4632 sizeof(channel_inform_le
));
4634 WL_ERR("scan busy (%d)\n", err
);
4638 scan_channel
= le32_to_cpu(channel_inform_le
.scan_channel
);
4640 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel
);
4641 cfg
->bss_list
= cfg
->scan_results
;
4642 bss_list_le
= (struct brcmf_scan_results_le
*) cfg
->bss_list
;
4644 memset(cfg
->scan_results
, 0, len
);
4645 bss_list_le
->buflen
= cpu_to_le32(len
);
4646 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_SCAN_RESULTS
,
4647 cfg
->scan_results
, len
);
4649 WL_ERR("%s Scan_results error (%d)\n", ndev
->name
, err
);
4654 cfg
->scan_results
->buflen
= le32_to_cpu(bss_list_le
->buflen
);
4655 cfg
->scan_results
->version
= le32_to_cpu(bss_list_le
->version
);
4656 cfg
->scan_results
->count
= le32_to_cpu(bss_list_le
->count
);
4658 err
= brcmf_inform_bss(cfg
);
4663 if (cfg
->scan_request
) {
4664 WL_SCAN("calling cfg80211_scan_done\n");
4665 cfg80211_scan_done(cfg
->scan_request
, scan_abort
);
4666 brcmf_set_mpc(ndev
, 1);
4667 cfg
->scan_request
= NULL
;
4675 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4677 conf
->mode
= (u32
)-1;
4678 conf
->frag_threshold
= (u32
)-1;
4679 conf
->rts_threshold
= (u32
)-1;
4680 conf
->retry_short
= (u32
)-1;
4681 conf
->retry_long
= (u32
)-1;
4682 conf
->tx_power
= -1;
4685 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop
*el
)
4687 memset(el
, 0, sizeof(*el
));
4688 el
->handler
[BRCMF_E_SCAN_COMPLETE
] = brcmf_notify_scan_status
;
4689 el
->handler
[BRCMF_E_LINK
] = brcmf_notify_connect_status
;
4690 el
->handler
[BRCMF_E_DEAUTH_IND
] = brcmf_notify_connect_status
;
4691 el
->handler
[BRCMF_E_DEAUTH
] = brcmf_notify_connect_status
;
4692 el
->handler
[BRCMF_E_DISASSOC_IND
] = brcmf_notify_connect_status
;
4693 el
->handler
[BRCMF_E_ASSOC_IND
] = brcmf_notify_connect_status
;
4694 el
->handler
[BRCMF_E_REASSOC_IND
] = brcmf_notify_connect_status
;
4695 el
->handler
[BRCMF_E_ROAM
] = brcmf_notify_roaming_status
;
4696 el
->handler
[BRCMF_E_MIC_ERROR
] = brcmf_notify_mic_status
;
4697 el
->handler
[BRCMF_E_SET_SSID
] = brcmf_notify_connect_status
;
4698 el
->handler
[BRCMF_E_PFN_NET_FOUND
] = brcmf_notify_sched_scan_results
;
4701 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4703 kfree(cfg
->scan_results
);
4704 cfg
->scan_results
= NULL
;
4705 kfree(cfg
->bss_info
);
4706 cfg
->bss_info
= NULL
;
4709 kfree(cfg
->profile
);
4710 cfg
->profile
= NULL
;
4711 kfree(cfg
->scan_req_int
);
4712 cfg
->scan_req_int
= NULL
;
4713 kfree(cfg
->escan_ioctl_buf
);
4714 cfg
->escan_ioctl_buf
= NULL
;
4715 kfree(cfg
->dcmd_buf
);
4716 cfg
->dcmd_buf
= NULL
;
4717 kfree(cfg
->extra_buf
);
4718 cfg
->extra_buf
= NULL
;
4721 kfree(cfg
->pmk_list
);
4722 cfg
->pmk_list
= NULL
;
4724 kfree(cfg
->ap_info
->wpa_ie
);
4725 kfree(cfg
->ap_info
->rsn_ie
);
4726 kfree(cfg
->ap_info
);
4727 cfg
->ap_info
= NULL
;
4731 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4733 cfg
->scan_results
= kzalloc(WL_SCAN_BUF_MAX
, GFP_KERNEL
);
4734 if (!cfg
->scan_results
)
4735 goto init_priv_mem_out
;
4736 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4738 goto init_priv_mem_out
;
4739 cfg
->profile
= kzalloc(sizeof(*cfg
->profile
), GFP_KERNEL
);
4741 goto init_priv_mem_out
;
4742 cfg
->bss_info
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4744 goto init_priv_mem_out
;
4745 cfg
->scan_req_int
= kzalloc(sizeof(*cfg
->scan_req_int
),
4747 if (!cfg
->scan_req_int
)
4748 goto init_priv_mem_out
;
4749 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4750 if (!cfg
->escan_ioctl_buf
)
4751 goto init_priv_mem_out
;
4752 cfg
->dcmd_buf
= kzalloc(WL_DCMD_LEN_MAX
, GFP_KERNEL
);
4754 goto init_priv_mem_out
;
4755 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4756 if (!cfg
->extra_buf
)
4757 goto init_priv_mem_out
;
4758 cfg
->iscan
= kzalloc(sizeof(*cfg
->iscan
), GFP_KERNEL
);
4760 goto init_priv_mem_out
;
4761 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4763 goto init_priv_mem_out
;
4768 brcmf_deinit_priv_mem(cfg
);
4774 * retrieve first queued event from head
4777 static struct brcmf_cfg80211_event_q
*brcmf_deq_event(
4778 struct brcmf_cfg80211_info
*cfg
)
4780 struct brcmf_cfg80211_event_q
*e
= NULL
;
4782 spin_lock_irq(&cfg
->evt_q_lock
);
4783 if (!list_empty(&cfg
->evt_q_list
)) {
4784 e
= list_first_entry(&cfg
->evt_q_list
,
4785 struct brcmf_cfg80211_event_q
, evt_q_list
);
4786 list_del(&e
->evt_q_list
);
4788 spin_unlock_irq(&cfg
->evt_q_lock
);
4794 * push event to tail of the queue
4796 * remark: this function may not sleep as it is called in atomic context.
4800 brcmf_enq_event(struct brcmf_cfg80211_info
*cfg
, u32 event
,
4801 const struct brcmf_event_msg
*msg
, void *data
)
4803 struct brcmf_cfg80211_event_q
*e
;
4809 total_len
= sizeof(struct brcmf_cfg80211_event_q
);
4811 data_len
= be32_to_cpu(msg
->datalen
);
4814 total_len
+= data_len
;
4815 e
= kzalloc(total_len
, GFP_ATOMIC
);
4820 memcpy(&e
->emsg
, msg
, sizeof(struct brcmf_event_msg
));
4822 memcpy(&e
->edata
, data
, data_len
);
4824 spin_lock_irqsave(&cfg
->evt_q_lock
, flags
);
4825 list_add_tail(&e
->evt_q_list
, &cfg
->evt_q_list
);
4826 spin_unlock_irqrestore(&cfg
->evt_q_lock
, flags
);
4831 static void brcmf_put_event(struct brcmf_cfg80211_event_q
*e
)
4836 static void brcmf_cfg80211_event_handler(struct work_struct
*work
)
4838 struct brcmf_cfg80211_info
*cfg
=
4839 container_of(work
, struct brcmf_cfg80211_info
,
4841 struct brcmf_cfg80211_event_q
*e
;
4843 e
= brcmf_deq_event(cfg
);
4845 WL_ERR("event queue empty...\n");
4850 WL_INFO("event type (%d)\n", e
->etype
);
4851 if (cfg
->el
.handler
[e
->etype
])
4852 cfg
->el
.handler
[e
->etype
](cfg
,
4854 &e
->emsg
, e
->edata
);
4856 WL_INFO("Unknown Event (%d): ignoring\n", e
->etype
);
4858 } while ((e
= brcmf_deq_event(cfg
)));
4862 static void brcmf_init_eq(struct brcmf_cfg80211_info
*cfg
)
4864 spin_lock_init(&cfg
->evt_q_lock
);
4865 INIT_LIST_HEAD(&cfg
->evt_q_list
);
4868 static void brcmf_flush_eq(struct brcmf_cfg80211_info
*cfg
)
4870 struct brcmf_cfg80211_event_q
*e
;
4872 spin_lock_irq(&cfg
->evt_q_lock
);
4873 while (!list_empty(&cfg
->evt_q_list
)) {
4874 e
= list_first_entry(&cfg
->evt_q_list
,
4875 struct brcmf_cfg80211_event_q
, evt_q_list
);
4876 list_del(&e
->evt_q_list
);
4879 spin_unlock_irq(&cfg
->evt_q_lock
);
4882 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4886 cfg
->scan_request
= NULL
;
4887 cfg
->pwr_save
= true;
4888 #ifdef CONFIG_BRCMISCAN
4889 cfg
->iscan_on
= true; /* iscan on & off switch.
4890 we enable iscan per default */
4891 cfg
->escan_on
= false; /* escan on & off switch.
4892 we disable escan per default */
4894 cfg
->iscan_on
= false; /* iscan on & off switch.
4895 we disable iscan per default */
4896 cfg
->escan_on
= true; /* escan on & off switch.
4897 we enable escan per default */
4899 cfg
->roam_on
= true; /* roam on & off switch.
4900 we enable roam per default */
4902 cfg
->iscan_kickstart
= false;
4903 cfg
->active_scan
= true; /* we do active scan for
4904 specific scan per default */
4905 cfg
->dongle_up
= false; /* dongle is not up yet */
4907 err
= brcmf_init_priv_mem(cfg
);
4910 INIT_WORK(&cfg
->event_work
, brcmf_cfg80211_event_handler
);
4911 brcmf_init_eloop_handler(&cfg
->el
);
4912 mutex_init(&cfg
->usr_sync
);
4913 err
= brcmf_init_iscan(cfg
);
4916 brcmf_init_escan(cfg
);
4917 brcmf_init_conf(cfg
->conf
);
4918 brcmf_init_prof(cfg
->profile
);
4919 brcmf_link_down(cfg
);
4924 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4926 cancel_work_sync(&cfg
->event_work
);
4927 cfg
->dongle_up
= false; /* dongle down */
4928 brcmf_flush_eq(cfg
);
4929 brcmf_link_down(cfg
);
4930 brcmf_abort_scanning(cfg
);
4931 brcmf_deinit_priv_mem(cfg
);
4934 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
)
4936 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4937 struct device
*busdev
= drvr
->dev
;
4938 struct wireless_dev
*wdev
;
4939 struct brcmf_cfg80211_info
*cfg
;
4943 WL_ERR("ndev is invalid\n");
4947 wdev
= brcmf_alloc_wdev(busdev
);
4952 wdev
->iftype
= brcmf_mode_to_nl80211_iftype(WL_MODE_BSS
);
4953 cfg
= wdev_to_cfg(wdev
);
4956 ndev
->ieee80211_ptr
= wdev
;
4957 SET_NETDEV_DEV(ndev
, wiphy_dev(wdev
->wiphy
));
4958 wdev
->netdev
= ndev
;
4959 err
= wl_init_priv(cfg
);
4961 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
4962 goto cfg80211_attach_out
;
4967 cfg80211_attach_out
:
4968 brcmf_free_wdev(cfg
);
4972 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4974 wl_deinit_priv(cfg
);
4975 brcmf_free_wdev(cfg
);
4979 brcmf_cfg80211_event(struct net_device
*ndev
,
4980 const struct brcmf_event_msg
*e
, void *data
)
4982 u32 event_type
= be32_to_cpu(e
->event_type
);
4983 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
4985 if (!brcmf_enq_event(cfg
, event_type
, e
, data
))
4986 schedule_work(&cfg
->event_work
);
4989 static s32
brcmf_dongle_eventmsg(struct net_device
*ndev
)
4991 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
4994 WL_TRACE("Enter\n");
4996 /* Setup event_msgs */
4997 err
= brcmf_fil_iovar_data_get(netdev_priv(ndev
), "event_msgs",
4998 eventmask
, BRCMF_EVENTING_MASK_LEN
);
5000 WL_ERR("Get event_msgs error (%d)\n", err
);
5001 goto dongle_eventmsg_out
;
5004 setbit(eventmask
, BRCMF_E_SET_SSID
);
5005 setbit(eventmask
, BRCMF_E_ROAM
);
5006 setbit(eventmask
, BRCMF_E_PRUNE
);
5007 setbit(eventmask
, BRCMF_E_AUTH
);
5008 setbit(eventmask
, BRCMF_E_REASSOC
);
5009 setbit(eventmask
, BRCMF_E_REASSOC_IND
);
5010 setbit(eventmask
, BRCMF_E_DEAUTH_IND
);
5011 setbit(eventmask
, BRCMF_E_DISASSOC_IND
);
5012 setbit(eventmask
, BRCMF_E_DISASSOC
);
5013 setbit(eventmask
, BRCMF_E_JOIN
);
5014 setbit(eventmask
, BRCMF_E_ASSOC_IND
);
5015 setbit(eventmask
, BRCMF_E_PSK_SUP
);
5016 setbit(eventmask
, BRCMF_E_LINK
);
5017 setbit(eventmask
, BRCMF_E_NDIS_LINK
);
5018 setbit(eventmask
, BRCMF_E_MIC_ERROR
);
5019 setbit(eventmask
, BRCMF_E_PMKID_CACHE
);
5020 setbit(eventmask
, BRCMF_E_TXFAIL
);
5021 setbit(eventmask
, BRCMF_E_JOIN_START
);
5022 setbit(eventmask
, BRCMF_E_SCAN_COMPLETE
);
5023 setbit(eventmask
, BRCMF_E_ESCAN_RESULT
);
5024 setbit(eventmask
, BRCMF_E_PFN_NET_FOUND
);
5026 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "event_msgs",
5027 eventmask
, BRCMF_EVENTING_MASK_LEN
);
5029 WL_ERR("Set event_msgs error (%d)\n", err
);
5030 goto dongle_eventmsg_out
;
5033 dongle_eventmsg_out
:
5039 brcmf_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
5041 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5043 __le32 roamtrigger
[2];
5044 __le32 roam_delta
[2];
5047 * Setup timeout if Beacons are lost and roam is
5048 * off to report link down
5051 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5053 WL_ERR("bcn_timeout error (%d)\n", err
);
5054 goto dongle_rom_out
;
5059 * Enable/Disable built-in roaming to allow supplicant
5060 * to take care of roaming
5062 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
5063 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
5065 WL_ERR("roam_off error (%d)\n", err
);
5066 goto dongle_rom_out
;
5069 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5070 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5071 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5072 (void *)roamtrigger
, sizeof(roamtrigger
));
5074 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5075 goto dongle_rom_out
;
5078 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5079 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5080 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5081 (void *)roam_delta
, sizeof(roam_delta
));
5083 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5084 goto dongle_rom_out
;
5092 brcmf_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
5093 s32 scan_unassoc_time
, s32 scan_passive_time
)
5095 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5098 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5101 if (err
== -EOPNOTSUPP
)
5102 WL_INFO("Scan assoc time is not supported\n");
5104 WL_ERR("Scan assoc time error (%d)\n", err
);
5105 goto dongle_scantime_out
;
5107 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5110 if (err
== -EOPNOTSUPP
)
5111 WL_INFO("Scan unassoc time is not supported\n");
5113 WL_ERR("Scan unassoc time error (%d)\n", err
);
5114 goto dongle_scantime_out
;
5117 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5120 if (err
== -EOPNOTSUPP
)
5121 WL_INFO("Scan passive time is not supported\n");
5123 WL_ERR("Scan passive time error (%d)\n", err
);
5124 goto dongle_scantime_out
;
5127 dongle_scantime_out
:
5131 static s32
wl_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
5133 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5134 struct wiphy
*wiphy
;
5139 err
= brcmf_fil_cmd_data_get(ifp
, BRCM_GET_PHYLIST
,
5140 &phy_list
, sizeof(phy_list
));
5142 WL_ERR("error (%d)\n", err
);
5146 phy
= ((char *)&phy_list
)[0];
5147 WL_INFO("%c phy\n", phy
);
5148 if (phy
== 'n' || phy
== 'a') {
5149 wiphy
= cfg_to_wiphy(cfg
);
5150 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
5156 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5158 return wl_update_wiphybands(cfg
);
5161 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5163 struct net_device
*ndev
;
5164 struct wireless_dev
*wdev
;
5171 ndev
= cfg_to_ndev(cfg
);
5172 wdev
= ndev
->ieee80211_ptr
;
5174 brcmf_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
5175 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5177 err
= brcmf_dongle_eventmsg(ndev
);
5179 goto default_conf_out
;
5181 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5182 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PM
,
5185 goto default_conf_out
;
5186 WL_INFO("power save set to %s\n",
5187 (power_mode
? "enabled" : "disabled"));
5189 err
= brcmf_dongle_roam(ndev
, (cfg
->roam_on
? 0 : 1),
5192 goto default_conf_out
;
5193 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5195 if (err
&& err
!= -EINPROGRESS
)
5196 goto default_conf_out
;
5197 err
= brcmf_dongle_probecap(cfg
);
5199 goto default_conf_out
;
5201 /* -EINPROGRESS: Call commit handler */
5205 cfg
->dongle_up
= true;
5211 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_info
*cfg
)
5213 char buf
[10+IFNAMSIZ
];
5217 sprintf(buf
, "netdev:%s", cfg_to_ndev(cfg
)->name
);
5218 cfg
->debugfsdir
= debugfs_create_dir(buf
,
5219 cfg_to_wiphy(cfg
)->debugfsdir
);
5221 fd
= debugfs_create_u16("beacon_int", S_IRUGO
, cfg
->debugfsdir
,
5222 (u16
*)&cfg
->profile
->beacon_interval
);
5228 fd
= debugfs_create_u8("dtim_period", S_IRUGO
, cfg
->debugfsdir
,
5229 (u8
*)&cfg
->profile
->dtim_period
);
5239 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_info
*cfg
)
5241 debugfs_remove_recursive(cfg
->debugfsdir
);
5242 cfg
->debugfsdir
= NULL
;
5245 static s32
__brcmf_cfg80211_up(struct brcmf_cfg80211_info
*cfg
)
5249 set_bit(WL_STATUS_READY
, &cfg
->status
);
5251 brcmf_debugfs_add_netdev_params(cfg
);
5253 err
= brcmf_config_dongle(cfg
);
5257 brcmf_invoke_iscan(cfg
);
5262 static s32
__brcmf_cfg80211_down(struct brcmf_cfg80211_info
*cfg
)
5265 * While going down, if associated with AP disassociate
5266 * from AP to save power
5268 if ((test_bit(WL_STATUS_CONNECTED
, &cfg
->status
) ||
5269 test_bit(WL_STATUS_CONNECTING
, &cfg
->status
)) &&
5270 test_bit(WL_STATUS_READY
, &cfg
->status
)) {
5271 WL_INFO("Disassociating from AP");
5272 brcmf_link_down(cfg
);
5274 /* Make sure WPA_Supplicant receives all the event
5275 generated due to DISASSOC call to the fw to keep
5276 the state fw and WPA_Supplicant state consistent
5281 brcmf_abort_scanning(cfg
);
5282 clear_bit(WL_STATUS_READY
, &cfg
->status
);
5284 brcmf_debugfs_remove_netdev(cfg
);
5289 s32
brcmf_cfg80211_up(struct brcmf_cfg80211_info
*cfg
)
5293 mutex_lock(&cfg
->usr_sync
);
5294 err
= __brcmf_cfg80211_up(cfg
);
5295 mutex_unlock(&cfg
->usr_sync
);
5300 s32
brcmf_cfg80211_down(struct brcmf_cfg80211_info
*cfg
)
5304 mutex_lock(&cfg
->usr_sync
);
5305 err
= __brcmf_cfg80211_down(cfg
);
5306 mutex_unlock(&cfg
->usr_sync
);