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 BRCMF_IFACE_MAX_CNT 2
54 #define TLV_LEN_OFF 1 /* length offset */
55 #define TLV_HDR_LEN 2 /* header length */
56 #define TLV_BODY_OFF 2 /* body offset */
57 #define TLV_OUI_LEN 3 /* oui id length */
58 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
59 #define WPA_OUI_TYPE 1
60 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
61 #define WME_OUI_TYPE 2
63 #define VS_IE_FIXED_HDR_LEN 6
64 #define WPA_IE_VERSION_LEN 2
65 #define WPA_IE_MIN_OUI_LEN 4
66 #define WPA_IE_SUITE_COUNT_LEN 2
68 #define WPA_CIPHER_NONE 0 /* None */
69 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
70 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
71 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
72 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
74 #define RSN_AKM_NONE 0 /* None (IBSS) */
75 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
76 #define RSN_AKM_PSK 2 /* Pre-shared Key */
77 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
78 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
80 #define VNDR_IE_CMD_LEN 4 /* length of the set command
81 * string :"add", "del" (+ NUL)
83 #define VNDR_IE_COUNT_OFFSET 4
84 #define VNDR_IE_PKTFLAG_OFFSET 8
85 #define VNDR_IE_VSIE_OFFSET 12
86 #define VNDR_IE_HDR_SIZE 12
87 #define VNDR_IE_BEACON_FLAG 0x1
88 #define VNDR_IE_PRBRSP_FLAG 0x2
89 #define MAX_VNDR_IE_NUMBER 5
91 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
92 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
97 static u32 brcmf_dbg_level
= WL_DBG_ERR
;
99 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
101 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
102 WL_INFO("device is not ready : status (%lu)\n",
109 #define CHAN2G(_channel, _freq, _flags) { \
110 .band = IEEE80211_BAND_2GHZ, \
111 .center_freq = (_freq), \
112 .hw_value = (_channel), \
114 .max_antenna_gain = 0, \
118 #define CHAN5G(_channel, _flags) { \
119 .band = IEEE80211_BAND_5GHZ, \
120 .center_freq = 5000 + (5 * (_channel)), \
121 .hw_value = (_channel), \
123 .max_antenna_gain = 0, \
127 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
128 #define RATETAB_ENT(_rateid, _flags) \
130 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
131 .hw_value = (_rateid), \
135 static struct ieee80211_rate __wl_rates
[] = {
136 RATETAB_ENT(BRCM_RATE_1M
, 0),
137 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
138 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
139 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
140 RATETAB_ENT(BRCM_RATE_6M
, 0),
141 RATETAB_ENT(BRCM_RATE_9M
, 0),
142 RATETAB_ENT(BRCM_RATE_12M
, 0),
143 RATETAB_ENT(BRCM_RATE_18M
, 0),
144 RATETAB_ENT(BRCM_RATE_24M
, 0),
145 RATETAB_ENT(BRCM_RATE_36M
, 0),
146 RATETAB_ENT(BRCM_RATE_48M
, 0),
147 RATETAB_ENT(BRCM_RATE_54M
, 0),
150 #define wl_a_rates (__wl_rates + 4)
151 #define wl_a_rates_size 8
152 #define wl_g_rates (__wl_rates + 0)
153 #define wl_g_rates_size 12
155 static struct ieee80211_channel __wl_2ghz_channels
[] = {
172 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
173 CHAN5G(34, 0), CHAN5G(36, 0),
174 CHAN5G(38, 0), CHAN5G(40, 0),
175 CHAN5G(42, 0), CHAN5G(44, 0),
176 CHAN5G(46, 0), CHAN5G(48, 0),
177 CHAN5G(52, 0), CHAN5G(56, 0),
178 CHAN5G(60, 0), CHAN5G(64, 0),
179 CHAN5G(100, 0), CHAN5G(104, 0),
180 CHAN5G(108, 0), CHAN5G(112, 0),
181 CHAN5G(116, 0), CHAN5G(120, 0),
182 CHAN5G(124, 0), CHAN5G(128, 0),
183 CHAN5G(132, 0), CHAN5G(136, 0),
184 CHAN5G(140, 0), CHAN5G(149, 0),
185 CHAN5G(153, 0), CHAN5G(157, 0),
186 CHAN5G(161, 0), CHAN5G(165, 0),
187 CHAN5G(184, 0), CHAN5G(188, 0),
188 CHAN5G(192, 0), CHAN5G(196, 0),
189 CHAN5G(200, 0), CHAN5G(204, 0),
190 CHAN5G(208, 0), CHAN5G(212, 0),
194 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
195 CHAN5G(32, 0), CHAN5G(34, 0),
196 CHAN5G(36, 0), CHAN5G(38, 0),
197 CHAN5G(40, 0), CHAN5G(42, 0),
198 CHAN5G(44, 0), CHAN5G(46, 0),
199 CHAN5G(48, 0), CHAN5G(50, 0),
200 CHAN5G(52, 0), CHAN5G(54, 0),
201 CHAN5G(56, 0), CHAN5G(58, 0),
202 CHAN5G(60, 0), CHAN5G(62, 0),
203 CHAN5G(64, 0), CHAN5G(66, 0),
204 CHAN5G(68, 0), CHAN5G(70, 0),
205 CHAN5G(72, 0), CHAN5G(74, 0),
206 CHAN5G(76, 0), CHAN5G(78, 0),
207 CHAN5G(80, 0), CHAN5G(82, 0),
208 CHAN5G(84, 0), CHAN5G(86, 0),
209 CHAN5G(88, 0), CHAN5G(90, 0),
210 CHAN5G(92, 0), CHAN5G(94, 0),
211 CHAN5G(96, 0), CHAN5G(98, 0),
212 CHAN5G(100, 0), CHAN5G(102, 0),
213 CHAN5G(104, 0), CHAN5G(106, 0),
214 CHAN5G(108, 0), CHAN5G(110, 0),
215 CHAN5G(112, 0), CHAN5G(114, 0),
216 CHAN5G(116, 0), CHAN5G(118, 0),
217 CHAN5G(120, 0), CHAN5G(122, 0),
218 CHAN5G(124, 0), CHAN5G(126, 0),
219 CHAN5G(128, 0), CHAN5G(130, 0),
220 CHAN5G(132, 0), CHAN5G(134, 0),
221 CHAN5G(136, 0), CHAN5G(138, 0),
222 CHAN5G(140, 0), CHAN5G(142, 0),
223 CHAN5G(144, 0), CHAN5G(145, 0),
224 CHAN5G(146, 0), CHAN5G(147, 0),
225 CHAN5G(148, 0), CHAN5G(149, 0),
226 CHAN5G(150, 0), CHAN5G(151, 0),
227 CHAN5G(152, 0), CHAN5G(153, 0),
228 CHAN5G(154, 0), CHAN5G(155, 0),
229 CHAN5G(156, 0), CHAN5G(157, 0),
230 CHAN5G(158, 0), CHAN5G(159, 0),
231 CHAN5G(160, 0), CHAN5G(161, 0),
232 CHAN5G(162, 0), CHAN5G(163, 0),
233 CHAN5G(164, 0), CHAN5G(165, 0),
234 CHAN5G(166, 0), CHAN5G(168, 0),
235 CHAN5G(170, 0), CHAN5G(172, 0),
236 CHAN5G(174, 0), CHAN5G(176, 0),
237 CHAN5G(178, 0), CHAN5G(180, 0),
238 CHAN5G(182, 0), CHAN5G(184, 0),
239 CHAN5G(186, 0), CHAN5G(188, 0),
240 CHAN5G(190, 0), CHAN5G(192, 0),
241 CHAN5G(194, 0), CHAN5G(196, 0),
242 CHAN5G(198, 0), CHAN5G(200, 0),
243 CHAN5G(202, 0), CHAN5G(204, 0),
244 CHAN5G(206, 0), CHAN5G(208, 0),
245 CHAN5G(210, 0), CHAN5G(212, 0),
246 CHAN5G(214, 0), CHAN5G(216, 0),
247 CHAN5G(218, 0), CHAN5G(220, 0),
248 CHAN5G(222, 0), CHAN5G(224, 0),
249 CHAN5G(226, 0), CHAN5G(228, 0),
252 static struct ieee80211_supported_band __wl_band_2ghz
= {
253 .band
= IEEE80211_BAND_2GHZ
,
254 .channels
= __wl_2ghz_channels
,
255 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
256 .bitrates
= wl_g_rates
,
257 .n_bitrates
= wl_g_rates_size
,
260 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
261 .band
= IEEE80211_BAND_5GHZ
,
262 .channels
= __wl_5ghz_a_channels
,
263 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
264 .bitrates
= wl_a_rates
,
265 .n_bitrates
= wl_a_rates_size
,
268 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
269 .band
= IEEE80211_BAND_5GHZ
,
270 .channels
= __wl_5ghz_n_channels
,
271 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
272 .bitrates
= wl_a_rates
,
273 .n_bitrates
= wl_a_rates_size
,
276 static const u32 __wl_cipher_suites
[] = {
277 WLAN_CIPHER_SUITE_WEP40
,
278 WLAN_CIPHER_SUITE_WEP104
,
279 WLAN_CIPHER_SUITE_TKIP
,
280 WLAN_CIPHER_SUITE_CCMP
,
281 WLAN_CIPHER_SUITE_AES_CMAC
,
284 /* tag_ID/length/value_buffer tuple */
291 /* Vendor specific ie. id = 221, oui and type defines exact ie */
292 struct brcmf_vs_tlv
{
299 struct parsed_vndr_ie_info
{
301 u32 ie_len
; /* total length including id & length field */
302 struct brcmf_vs_tlv vndrie
;
305 struct parsed_vndr_ies
{
307 struct parsed_vndr_ie_info ie_info
[MAX_VNDR_IE_NUMBER
];
310 /* Quarter dBm units to mW
311 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
312 * Table is offset so the last entry is largest mW value that fits in
316 #define QDBM_OFFSET 153 /* Offset for first entry */
317 #define QDBM_TABLE_LEN 40 /* Table size */
319 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
320 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
322 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
324 /* Largest mW value that will round down to the last table entry,
325 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
326 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
327 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
329 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
331 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
332 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
333 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
334 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
335 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
336 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
337 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
340 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
343 int idx
= qdbm
- QDBM_OFFSET
;
345 if (idx
>= QDBM_TABLE_LEN
)
346 /* clamp to max u16 mW value */
349 /* scale the qdBm index up to the range of the table 0-40
350 * where an offset of 40 qdBm equals a factor of 10 mW.
357 /* return the mW value scaled down to the correct factor of 10,
358 * adding in factor/2 to get proper rounding.
360 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
363 static u8
brcmf_mw_to_qdbm(u16 mw
)
370 /* handle boundary case */
374 offset
= QDBM_OFFSET
;
376 /* move mw into the range of the table */
377 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
382 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
383 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
384 nqdBm_to_mW_map
[qdbm
]) / 2;
385 if (mw_uint
< boundary
)
394 static u16
channel_to_chanspec(struct ieee80211_channel
*ch
)
398 chanspec
= ieee80211_frequency_to_channel(ch
->center_freq
);
399 chanspec
&= WL_CHANSPEC_CHAN_MASK
;
401 if (ch
->band
== IEEE80211_BAND_2GHZ
)
402 chanspec
|= WL_CHANSPEC_BAND_2G
;
404 chanspec
|= WL_CHANSPEC_BAND_5G
;
406 if (ch
->flags
& IEEE80211_CHAN_NO_HT40
) {
407 chanspec
|= WL_CHANSPEC_BW_20
;
408 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
410 chanspec
|= WL_CHANSPEC_BW_40
;
411 if (ch
->flags
& IEEE80211_CHAN_NO_HT40PLUS
)
412 chanspec
|= WL_CHANSPEC_CTL_SB_LOWER
;
414 chanspec
|= WL_CHANSPEC_CTL_SB_UPPER
;
419 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
420 struct brcmf_wsec_key_le
*key_le
)
422 key_le
->index
= cpu_to_le32(key
->index
);
423 key_le
->len
= cpu_to_le32(key
->len
);
424 key_le
->algo
= cpu_to_le32(key
->algo
);
425 key_le
->flags
= cpu_to_le32(key
->flags
);
426 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
427 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
428 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
429 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
430 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
434 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
437 struct brcmf_wsec_key_le key_le
;
439 convert_key_from_CPU(key
, &key_le
);
441 brcmf_netdev_wait_pend8021x(ndev
);
443 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
447 WL_ERR("wsec_key error (%d)\n", err
);
452 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
453 enum nl80211_iftype type
, u32
*flags
,
454 struct vif_params
*params
)
456 struct brcmf_if
*ifp
= netdev_priv(ndev
);
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(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
489 WL_INFO("IF Type = AP\n");
491 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
492 BRCMF_C_SET_INFRA
, infra
);
494 WL_ERR("WLC_SET_INFRA error (%d)\n", err
);
498 WL_INFO("IF Type = %s\n",
499 (cfg
->conf
->mode
== WL_MODE_IBSS
) ?
502 ndev
->ieee80211_ptr
->iftype
= type
;
510 static void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
512 struct brcmf_if
*ifp
= netdev_priv(ndev
);
515 if (check_vif_up(ifp
->vif
)) {
516 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
518 WL_ERR("fail to set mpc\n");
521 WL_INFO("MPC : %d\n", mpc
);
525 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
526 struct cfg80211_scan_request
*request
)
534 struct brcmf_ssid_le ssid_le
;
536 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
537 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
538 params_le
->scan_type
= 0;
539 params_le
->channel_num
= 0;
540 params_le
->nprobes
= cpu_to_le32(-1);
541 params_le
->active_time
= cpu_to_le32(-1);
542 params_le
->passive_time
= cpu_to_le32(-1);
543 params_le
->home_time
= cpu_to_le32(-1);
544 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
546 /* if request is null exit so it will be all channel broadcast scan */
550 n_ssids
= request
->n_ssids
;
551 n_channels
= request
->n_channels
;
552 /* Copy channel array if applicable */
553 WL_SCAN("### List of channelspecs to scan ### %d\n", n_channels
);
554 if (n_channels
> 0) {
555 for (i
= 0; i
< n_channels
; i
++) {
556 chanspec
= channel_to_chanspec(request
->channels
[i
]);
557 WL_SCAN("Chan : %d, Channel spec: %x\n",
558 request
->channels
[i
]->hw_value
, chanspec
);
559 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
562 WL_SCAN("Scanning all channels\n");
564 /* Copy ssid array if applicable */
565 WL_SCAN("### List of SSIDs to scan ### %d\n", n_ssids
);
567 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
568 n_channels
* sizeof(u16
);
569 offset
= roundup(offset
, sizeof(u32
));
570 ptr
= (char *)params_le
+ offset
;
571 for (i
= 0; i
< n_ssids
; i
++) {
572 memset(&ssid_le
, 0, sizeof(ssid_le
));
574 cpu_to_le32(request
->ssids
[i
].ssid_len
);
575 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
576 request
->ssids
[i
].ssid_len
);
577 if (!ssid_le
.SSID_len
)
578 WL_SCAN("%d: Broadcast scan\n", i
);
580 WL_SCAN("%d: scan for %s size =%d\n", i
,
581 ssid_le
.SSID
, ssid_le
.SSID_len
);
582 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
583 ptr
+= sizeof(ssid_le
);
586 WL_SCAN("Broadcast scan %p\n", request
->ssids
);
587 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
588 WL_SCAN("SSID %s len=%d\n", params_le
->ssid_le
.SSID
,
589 request
->ssids
->ssid_len
);
590 params_le
->ssid_le
.SSID_len
=
591 cpu_to_le32(request
->ssids
->ssid_len
);
592 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
593 request
->ssids
->ssid_len
);
596 /* Adding mask to channel numbers */
597 params_le
->channel_num
=
598 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
599 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
603 brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
604 struct net_device
*ndev
,
605 bool aborted
, bool fw_abort
)
607 struct brcmf_scan_params_le params_le
;
608 struct cfg80211_scan_request
*scan_request
;
613 /* clear scan request, because the FW abort can cause a second call */
614 /* to this functon and might cause a double cfg80211_scan_done */
615 scan_request
= cfg
->scan_request
;
616 cfg
->scan_request
= NULL
;
618 if (timer_pending(&cfg
->escan_timeout
))
619 del_timer_sync(&cfg
->escan_timeout
);
622 /* Do a scan abort to stop the driver's scan engine */
623 WL_SCAN("ABORT scan in firmware\n");
624 memset(¶ms_le
, 0, sizeof(params_le
));
625 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
626 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
627 params_le
.scan_type
= 0;
628 params_le
.channel_num
= cpu_to_le32(1);
629 params_le
.nprobes
= cpu_to_le32(1);
630 params_le
.active_time
= cpu_to_le32(-1);
631 params_le
.passive_time
= cpu_to_le32(-1);
632 params_le
.home_time
= cpu_to_le32(-1);
633 /* Scan is aborted by setting channel_list[0] to -1 */
634 params_le
.channel_list
[0] = cpu_to_le16(-1);
635 /* E-Scan (or anyother type) can be aborted by SCAN */
636 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
637 ¶ms_le
, sizeof(params_le
));
639 WL_ERR("Scan abort failed\n");
642 * e-scan can be initiated by scheduled scan
643 * which takes precedence.
645 if (cfg
->sched_escan
) {
646 WL_SCAN("scheduled scan completed\n");
647 cfg
->sched_escan
= false;
649 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
650 brcmf_set_mpc(ndev
, 1);
651 } else if (scan_request
) {
652 WL_SCAN("ESCAN Completed scan: %s\n",
653 aborted
? "Aborted" : "Done");
654 cfg80211_scan_done(scan_request
, aborted
);
655 brcmf_set_mpc(ndev
, 1);
657 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
658 WL_ERR("Scan complete while device not scanning\n");
666 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct net_device
*ndev
,
667 struct cfg80211_scan_request
*request
, u16 action
)
669 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
670 offsetof(struct brcmf_escan_params_le
, params_le
);
671 struct brcmf_escan_params_le
*params
;
674 WL_SCAN("E-SCAN START\n");
676 if (request
!= NULL
) {
677 /* Allocate space for populating ssids in struct */
678 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
680 /* Allocate space for populating ssids in struct */
681 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
684 params
= kzalloc(params_size
, GFP_KERNEL
);
689 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
690 brcmf_escan_prep(¶ms
->params_le
, request
);
691 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
692 params
->action
= cpu_to_le16(action
);
693 params
->sync_id
= cpu_to_le16(0x1234);
695 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "escan",
696 params
, params_size
);
699 WL_INFO("system busy : escan canceled\n");
701 WL_ERR("error (%d)\n", err
);
710 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
711 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
715 struct brcmf_scan_results
*results
;
718 cfg
->escan_info
.ndev
= ndev
;
719 cfg
->escan_info
.wiphy
= wiphy
;
720 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_SCANNING
;
721 passive_scan
= cfg
->active_scan
? 0 : 1;
722 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PASSIVE_SCAN
,
725 WL_ERR("error (%d)\n", err
);
728 brcmf_set_mpc(ndev
, 0);
729 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
730 results
->version
= 0;
732 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
734 err
= brcmf_run_escan(cfg
, ndev
, request
, WL_ESCAN_ACTION_START
);
736 brcmf_set_mpc(ndev
, 1);
741 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
742 struct cfg80211_scan_request
*request
,
743 struct cfg80211_ssid
*this_ssid
)
745 struct brcmf_if
*ifp
= netdev_priv(ndev
);
746 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
747 struct cfg80211_ssid
*ssids
;
748 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
755 WL_SCAN("START ESCAN\n");
757 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
758 WL_ERR("Scanning already: status (%lu)\n", cfg
->scan_status
);
761 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
762 WL_ERR("Scanning being aborted: status (%lu)\n",
766 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
767 WL_ERR("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
771 /* Arm scan timeout timer */
772 mod_timer(&cfg
->escan_timeout
, jiffies
+
773 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
778 ssids
= request
->ssids
;
782 /* we don't do escan in ibss */
786 cfg
->scan_request
= request
;
787 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
789 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
793 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
794 ssids
->ssid
, ssids
->ssid_len
);
795 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
796 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
797 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
800 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
801 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
804 WL_SCAN("Broadcast scan\n");
806 passive_scan
= cfg
->active_scan
? 0 : 1;
807 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
810 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
813 brcmf_set_mpc(ndev
, 0);
814 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
815 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
818 WL_INFO("BUSY: scan for \"%s\" canceled\n",
821 WL_ERR("WLC_SCAN error (%d)\n", err
);
823 brcmf_set_mpc(ndev
, 1);
831 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
832 if (timer_pending(&cfg
->escan_timeout
))
833 del_timer_sync(&cfg
->escan_timeout
);
834 cfg
->scan_request
= NULL
;
839 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
841 struct net_device
*ndev
= request
->wdev
->netdev
;
846 if (!check_vif_up(container_of(request
->wdev
,
847 struct brcmf_cfg80211_vif
, wdev
)))
850 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
853 WL_ERR("scan error (%d)\n", err
);
859 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
863 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
866 WL_ERR("Error (%d)\n", err
);
871 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
875 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
878 WL_ERR("Error (%d)\n", err
);
883 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
886 u32 cmd
= (l
? BRCM_SET_LRL
: BRCM_SET_SRL
);
888 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
890 WL_ERR("cmd (%d) , error (%d)\n", cmd
, err
);
896 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
898 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
899 struct net_device
*ndev
= cfg_to_ndev(cfg
);
900 struct brcmf_if
*ifp
= netdev_priv(ndev
);
904 if (!check_vif_up(ifp
->vif
))
907 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
908 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
909 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
910 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
914 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
915 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
916 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
917 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
921 if (changed
& WIPHY_PARAM_RETRY_LONG
922 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
923 cfg
->conf
->retry_long
= wiphy
->retry_long
;
924 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
928 if (changed
& WIPHY_PARAM_RETRY_SHORT
929 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
930 cfg
->conf
->retry_short
= wiphy
->retry_short
;
931 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
941 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
943 memset(prof
, 0, sizeof(*prof
));
946 static void brcmf_ch_to_chanspec(int ch
, struct brcmf_join_params
*join_params
,
947 size_t *join_params_size
)
952 if (ch
<= CH_MAX_2G_CHANNEL
)
953 chanspec
|= WL_CHANSPEC_BAND_2G
;
955 chanspec
|= WL_CHANSPEC_BAND_5G
;
957 chanspec
|= WL_CHANSPEC_BW_20
;
958 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
960 *join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
+
963 chanspec
|= (ch
& WL_CHANSPEC_CHAN_MASK
);
964 join_params
->params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
965 join_params
->params_le
.chanspec_num
= cpu_to_le32(1);
967 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
968 "channel %d, chanspec %#X\n",
969 chanspec
, ch
, chanspec
);
973 static void brcmf_link_down(struct brcmf_cfg80211_info
*cfg
)
975 struct net_device
*ndev
= NULL
;
981 ndev
= cfg_to_ndev(cfg
);
982 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
983 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
),
984 BRCMF_C_DISASSOC
, NULL
, 0);
986 WL_ERR("WLC_DISASSOC failed (%d)\n", err
);
987 cfg
->link_up
= false;
993 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
994 struct cfg80211_ibss_params
*params
)
996 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
997 struct brcmf_if
*ifp
= netdev_priv(ndev
);
998 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
999 struct brcmf_join_params join_params
;
1000 size_t join_params_size
= 0;
1005 WL_TRACE("Enter\n");
1006 if (!check_vif_up(ifp
->vif
))
1010 WL_CONN("SSID: %s\n", params
->ssid
);
1012 WL_CONN("SSID: NULL, Not supported\n");
1016 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1019 WL_CONN("BSSID: %pM\n", params
->bssid
);
1021 WL_CONN("No BSSID specified\n");
1023 if (params
->channel
)
1024 WL_CONN("channel: %d\n", params
->channel
->center_freq
);
1026 WL_CONN("no channel specified\n");
1028 if (params
->channel_fixed
)
1029 WL_CONN("fixed channel required\n");
1031 WL_CONN("no fixed channel required\n");
1033 if (params
->ie
&& params
->ie_len
)
1034 WL_CONN("ie len: %d\n", params
->ie_len
);
1036 WL_CONN("no ie specified\n");
1038 if (params
->beacon_interval
)
1039 WL_CONN("beacon interval: %d\n", params
->beacon_interval
);
1041 WL_CONN("no beacon interval specified\n");
1043 if (params
->basic_rates
)
1044 WL_CONN("basic rates: %08X\n", params
->basic_rates
);
1046 WL_CONN("no basic rates specified\n");
1048 if (params
->privacy
)
1049 WL_CONN("privacy required\n");
1051 WL_CONN("no privacy required\n");
1053 /* Configure Privacy for starter */
1054 if (params
->privacy
)
1055 wsec
|= WEP_ENABLED
;
1057 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1059 WL_ERR("wsec failed (%d)\n", err
);
1063 /* Configure Beacon Interval for starter */
1064 if (params
->beacon_interval
)
1065 bcnprd
= params
->beacon_interval
;
1069 err
= brcmf_fil_cmd_int_set(ifp
, BRCM_SET_BCNPRD
, bcnprd
);
1071 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err
);
1075 /* Configure required join parameter */
1076 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1079 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1080 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1081 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1082 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1083 join_params_size
= sizeof(join_params
.ssid_le
);
1086 if (params
->bssid
) {
1087 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1088 join_params_size
= sizeof(join_params
.ssid_le
) +
1089 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1090 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1092 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1093 memset(profile
->bssid
, 0, ETH_ALEN
);
1097 if (params
->channel
) {
1101 ieee80211_frequency_to_channel(
1102 params
->channel
->center_freq
);
1103 if (params
->channel_fixed
) {
1104 /* adding chanspec */
1105 brcmf_ch_to_chanspec(cfg
->channel
,
1106 &join_params
, &join_params_size
);
1109 /* set channel for starter */
1110 target_channel
= cfg
->channel
;
1111 err
= brcmf_fil_cmd_int_set(ifp
, BRCM_SET_CHANNEL
,
1114 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err
);
1120 cfg
->ibss_starter
= false;
1123 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1124 &join_params
, join_params_size
);
1126 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1132 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1138 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1140 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1141 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1144 WL_TRACE("Enter\n");
1145 if (!check_vif_up(ifp
->vif
))
1148 brcmf_link_down(cfg
);
1155 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1156 struct cfg80211_connect_params
*sme
)
1158 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1159 struct brcmf_cfg80211_security
*sec
;
1163 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1164 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1165 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1166 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1168 val
= WPA_AUTH_DISABLED
;
1169 WL_CONN("setting wpa_auth to 0x%0x\n", val
);
1170 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1172 WL_ERR("set wpa_auth failed (%d)\n", err
);
1175 sec
= &profile
->sec
;
1176 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1180 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1181 struct cfg80211_connect_params
*sme
)
1183 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1184 struct brcmf_cfg80211_security
*sec
;
1188 switch (sme
->auth_type
) {
1189 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1191 WL_CONN("open system\n");
1193 case NL80211_AUTHTYPE_SHARED_KEY
:
1195 WL_CONN("shared key\n");
1197 case NL80211_AUTHTYPE_AUTOMATIC
:
1199 WL_CONN("automatic\n");
1201 case NL80211_AUTHTYPE_NETWORK_EAP
:
1202 WL_CONN("network eap\n");
1205 WL_ERR("invalid auth type (%d)\n", sme
->auth_type
);
1209 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "auth", val
);
1211 WL_ERR("set auth failed (%d)\n", err
);
1214 sec
= &profile
->sec
;
1215 sec
->auth_type
= sme
->auth_type
;
1220 brcmf_set_set_cipher(struct net_device
*ndev
,
1221 struct cfg80211_connect_params
*sme
)
1223 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1224 struct brcmf_cfg80211_security
*sec
;
1229 if (sme
->crypto
.n_ciphers_pairwise
) {
1230 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1231 case WLAN_CIPHER_SUITE_WEP40
:
1232 case WLAN_CIPHER_SUITE_WEP104
:
1235 case WLAN_CIPHER_SUITE_TKIP
:
1236 pval
= TKIP_ENABLED
;
1238 case WLAN_CIPHER_SUITE_CCMP
:
1241 case WLAN_CIPHER_SUITE_AES_CMAC
:
1245 WL_ERR("invalid cipher pairwise (%d)\n",
1246 sme
->crypto
.ciphers_pairwise
[0]);
1250 if (sme
->crypto
.cipher_group
) {
1251 switch (sme
->crypto
.cipher_group
) {
1252 case WLAN_CIPHER_SUITE_WEP40
:
1253 case WLAN_CIPHER_SUITE_WEP104
:
1256 case WLAN_CIPHER_SUITE_TKIP
:
1257 gval
= TKIP_ENABLED
;
1259 case WLAN_CIPHER_SUITE_CCMP
:
1262 case WLAN_CIPHER_SUITE_AES_CMAC
:
1266 WL_ERR("invalid cipher group (%d)\n",
1267 sme
->crypto
.cipher_group
);
1272 WL_CONN("pval (%d) gval (%d)\n", pval
, gval
);
1273 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1275 WL_ERR("error (%d)\n", err
);
1279 sec
= &profile
->sec
;
1280 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1281 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1287 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1289 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1290 struct brcmf_cfg80211_security
*sec
;
1294 if (sme
->crypto
.n_akm_suites
) {
1295 err
= brcmf_fil_iovar_int_get(netdev_priv(ndev
),
1298 WL_ERR("could not get wpa_auth (%d)\n", err
);
1301 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1302 switch (sme
->crypto
.akm_suites
[0]) {
1303 case WLAN_AKM_SUITE_8021X
:
1304 val
= WPA_AUTH_UNSPECIFIED
;
1306 case WLAN_AKM_SUITE_PSK
:
1310 WL_ERR("invalid cipher group (%d)\n",
1311 sme
->crypto
.cipher_group
);
1314 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1315 switch (sme
->crypto
.akm_suites
[0]) {
1316 case WLAN_AKM_SUITE_8021X
:
1317 val
= WPA2_AUTH_UNSPECIFIED
;
1319 case WLAN_AKM_SUITE_PSK
:
1320 val
= WPA2_AUTH_PSK
;
1323 WL_ERR("invalid cipher group (%d)\n",
1324 sme
->crypto
.cipher_group
);
1329 WL_CONN("setting wpa_auth to %d\n", val
);
1330 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
),
1333 WL_ERR("could not set wpa_auth (%d)\n", err
);
1337 sec
= &profile
->sec
;
1338 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1344 brcmf_set_sharedkey(struct net_device
*ndev
,
1345 struct cfg80211_connect_params
*sme
)
1347 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1348 struct brcmf_cfg80211_security
*sec
;
1349 struct brcmf_wsec_key key
;
1353 WL_CONN("key len (%d)\n", sme
->key_len
);
1355 if (sme
->key_len
== 0)
1358 sec
= &profile
->sec
;
1359 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1360 sec
->wpa_versions
, sec
->cipher_pairwise
);
1362 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1365 if (!(sec
->cipher_pairwise
&
1366 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1369 memset(&key
, 0, sizeof(key
));
1370 key
.len
= (u32
) sme
->key_len
;
1371 key
.index
= (u32
) sme
->key_idx
;
1372 if (key
.len
> sizeof(key
.data
)) {
1373 WL_ERR("Too long key length (%u)\n", key
.len
);
1376 memcpy(key
.data
, sme
->key
, key
.len
);
1377 key
.flags
= BRCMF_PRIMARY_KEY
;
1378 switch (sec
->cipher_pairwise
) {
1379 case WLAN_CIPHER_SUITE_WEP40
:
1380 key
.algo
= CRYPTO_ALGO_WEP1
;
1382 case WLAN_CIPHER_SUITE_WEP104
:
1383 key
.algo
= CRYPTO_ALGO_WEP128
;
1386 WL_ERR("Invalid algorithm (%d)\n",
1387 sme
->crypto
.ciphers_pairwise
[0]);
1390 /* Set the new key/index */
1391 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1392 key
.len
, key
.index
, key
.algo
);
1393 WL_CONN("key \"%s\"\n", key
.data
);
1394 err
= send_key_to_dongle(ndev
, &key
);
1398 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1399 WL_CONN("set auth_type to shared key\n");
1400 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1401 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1403 WL_ERR("set auth failed (%d)\n", err
);
1409 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1410 struct cfg80211_connect_params
*sme
)
1412 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1413 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1414 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1415 struct ieee80211_channel
*chan
= sme
->channel
;
1416 struct brcmf_join_params join_params
;
1417 size_t join_params_size
;
1418 struct brcmf_ssid ssid
;
1422 WL_TRACE("Enter\n");
1423 if (!check_vif_up(ifp
->vif
))
1427 WL_ERR("Invalid ssid\n");
1431 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1435 ieee80211_frequency_to_channel(chan
->center_freq
);
1436 WL_CONN("channel (%d), center_req (%d)\n",
1437 cfg
->channel
, chan
->center_freq
);
1441 WL_INFO("ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1443 err
= brcmf_set_wpa_version(ndev
, sme
);
1445 WL_ERR("wl_set_wpa_version failed (%d)\n", err
);
1449 err
= brcmf_set_auth_type(ndev
, sme
);
1451 WL_ERR("wl_set_auth_type failed (%d)\n", err
);
1455 err
= brcmf_set_set_cipher(ndev
, sme
);
1457 WL_ERR("wl_set_set_cipher failed (%d)\n", err
);
1461 err
= brcmf_set_key_mgmt(ndev
, sme
);
1463 WL_ERR("wl_set_key_mgmt failed (%d)\n", err
);
1467 err
= brcmf_set_sharedkey(ndev
, sme
);
1469 WL_ERR("brcmf_set_sharedkey failed (%d)\n", err
);
1473 memset(&join_params
, 0, sizeof(join_params
));
1474 join_params_size
= sizeof(join_params
.ssid_le
);
1476 profile
->ssid
.SSID_len
= min_t(u32
,
1477 sizeof(ssid
.SSID
), (u32
)sme
->ssid_len
);
1478 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1479 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1480 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1482 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1484 if (ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
)
1485 WL_CONN("ssid \"%s\", len (%d)\n",
1486 ssid
.SSID
, ssid
.SSID_len
);
1488 brcmf_ch_to_chanspec(cfg
->channel
,
1489 &join_params
, &join_params_size
);
1490 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1491 &join_params
, join_params_size
);
1493 WL_ERR("WLC_SET_SSID failed (%d)\n", err
);
1497 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1503 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1506 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1507 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1508 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1509 struct brcmf_scb_val_le scbval
;
1512 WL_TRACE("Enter. Reason code = %d\n", reason_code
);
1513 if (!check_vif_up(ifp
->vif
))
1516 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1518 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1519 scbval
.val
= cpu_to_le32(reason_code
);
1520 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1521 &scbval
, sizeof(scbval
));
1523 WL_ERR("error (%d)\n", err
);
1525 cfg
->link_up
= false;
1532 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
,
1533 enum nl80211_tx_power_setting type
, s32 mbm
)
1536 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1537 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1538 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1542 s32 dbm
= MBM_TO_DBM(mbm
);
1544 WL_TRACE("Enter\n");
1545 if (!check_vif_up(ifp
->vif
))
1549 case NL80211_TX_POWER_AUTOMATIC
:
1551 case NL80211_TX_POWER_LIMITED
:
1552 case NL80211_TX_POWER_FIXED
:
1554 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1560 /* Make sure radio is off or on as far as software is concerned */
1561 disable
= WL_RADIO_SW_DISABLE
<< 16;
1562 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1564 WL_ERR("WLC_SET_RADIO error (%d)\n", err
);
1569 txpwrmw
= (u16
) dbm
;
1570 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1571 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1573 WL_ERR("qtxpower error (%d)\n", err
);
1574 cfg
->conf
->tx_power
= dbm
;
1581 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, s32
*dbm
)
1583 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1584 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1589 WL_TRACE("Enter\n");
1590 if (!check_vif_up(ifp
->vif
))
1593 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1595 WL_ERR("error (%d)\n", err
);
1599 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1600 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1608 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1609 u8 key_idx
, bool unicast
, bool multicast
)
1611 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1616 WL_TRACE("Enter\n");
1617 WL_CONN("key index (%d)\n", key_idx
);
1618 if (!check_vif_up(ifp
->vif
))
1621 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1623 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1627 if (wsec
& WEP_ENABLED
) {
1628 /* Just select a new current key */
1630 err
= brcmf_fil_cmd_int_set(ifp
,
1631 BRCMF_C_SET_KEY_PRIMARY
, index
);
1633 WL_ERR("error (%d)\n", err
);
1641 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1642 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1644 struct brcmf_wsec_key key
;
1647 memset(&key
, 0, sizeof(key
));
1648 key
.index
= (u32
) key_idx
;
1649 /* Instead of bcast for ea address for default wep keys,
1650 driver needs it to be Null */
1651 if (!is_multicast_ether_addr(mac_addr
))
1652 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1653 key
.len
= (u32
) params
->key_len
;
1654 /* check for key index change */
1657 err
= send_key_to_dongle(ndev
, &key
);
1659 WL_ERR("key delete error (%d)\n", err
);
1661 if (key
.len
> sizeof(key
.data
)) {
1662 WL_ERR("Invalid key length (%d)\n", key
.len
);
1666 WL_CONN("Setting the key index %d\n", key
.index
);
1667 memcpy(key
.data
, params
->key
, key
.len
);
1669 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1671 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1672 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1673 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1676 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1677 if (params
->seq
&& params
->seq_len
== 6) {
1680 ivptr
= (u8
*) params
->seq
;
1681 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1682 (ivptr
[3] << 8) | ivptr
[2];
1683 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1684 key
.iv_initialized
= true;
1687 switch (params
->cipher
) {
1688 case WLAN_CIPHER_SUITE_WEP40
:
1689 key
.algo
= CRYPTO_ALGO_WEP1
;
1690 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1692 case WLAN_CIPHER_SUITE_WEP104
:
1693 key
.algo
= CRYPTO_ALGO_WEP128
;
1694 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1696 case WLAN_CIPHER_SUITE_TKIP
:
1697 key
.algo
= CRYPTO_ALGO_TKIP
;
1698 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1700 case WLAN_CIPHER_SUITE_AES_CMAC
:
1701 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1702 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1704 case WLAN_CIPHER_SUITE_CCMP
:
1705 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1706 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1709 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1712 err
= send_key_to_dongle(ndev
, &key
);
1714 WL_ERR("wsec_key error (%d)\n", err
);
1720 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1721 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1722 struct key_params
*params
)
1724 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1725 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1726 struct brcmf_wsec_key key
;
1732 WL_TRACE("Enter\n");
1733 WL_CONN("key index (%d)\n", key_idx
);
1734 if (!check_vif_up(ifp
->vif
))
1739 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1741 memset(&key
, 0, sizeof(key
));
1743 key
.len
= (u32
) params
->key_len
;
1744 key
.index
= (u32
) key_idx
;
1746 if (key
.len
> sizeof(key
.data
)) {
1747 WL_ERR("Too long key length (%u)\n", key
.len
);
1751 memcpy(key
.data
, params
->key
, key
.len
);
1753 key
.flags
= BRCMF_PRIMARY_KEY
;
1754 switch (params
->cipher
) {
1755 case WLAN_CIPHER_SUITE_WEP40
:
1756 key
.algo
= CRYPTO_ALGO_WEP1
;
1758 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1760 case WLAN_CIPHER_SUITE_WEP104
:
1761 key
.algo
= CRYPTO_ALGO_WEP128
;
1763 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1765 case WLAN_CIPHER_SUITE_TKIP
:
1766 if (cfg
->conf
->mode
!= WL_MODE_AP
) {
1767 WL_CONN("Swapping key\n");
1768 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1769 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1770 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1772 key
.algo
= CRYPTO_ALGO_TKIP
;
1774 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1776 case WLAN_CIPHER_SUITE_AES_CMAC
:
1777 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1779 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1781 case WLAN_CIPHER_SUITE_CCMP
:
1782 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1784 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1787 WL_ERR("Invalid cipher (0x%x)\n", params
->cipher
);
1792 err
= send_key_to_dongle(ndev
, &key
);
1796 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1798 WL_ERR("get wsec error (%d)\n", err
);
1802 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
1804 WL_ERR("set wsec error (%d)\n", err
);
1814 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1815 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
1817 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1818 struct brcmf_wsec_key key
;
1821 WL_TRACE("Enter\n");
1822 if (!check_vif_up(ifp
->vif
))
1825 memset(&key
, 0, sizeof(key
));
1827 key
.index
= (u32
) key_idx
;
1828 key
.flags
= BRCMF_PRIMARY_KEY
;
1829 key
.algo
= CRYPTO_ALGO_OFF
;
1831 WL_CONN("key index (%d)\n", key_idx
);
1833 /* Set the new key/index */
1834 err
= send_key_to_dongle(ndev
, &key
);
1836 if (err
== -EINVAL
) {
1837 if (key
.index
>= DOT11_MAX_DEFAULT_KEYS
)
1838 /* we ignore this key index in this case */
1839 WL_ERR("invalid key index (%d)\n", key_idx
);
1841 /* Ignore this error, may happen during DISASSOC */
1850 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1851 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
1852 void (*callback
) (void *cookie
, struct key_params
* params
))
1854 struct key_params params
;
1855 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1856 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1857 struct brcmf_cfg80211_security
*sec
;
1861 WL_TRACE("Enter\n");
1862 WL_CONN("key index (%d)\n", key_idx
);
1863 if (!check_vif_up(ifp
->vif
))
1866 memset(¶ms
, 0, sizeof(params
));
1868 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1870 WL_ERR("WLC_GET_WSEC error (%d)\n", err
);
1871 /* Ignore this error, may happen during DISASSOC */
1875 switch (wsec
& ~SES_OW_ENABLED
) {
1877 sec
= &profile
->sec
;
1878 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
1879 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
1880 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1881 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
1882 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
1883 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1887 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
1888 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1891 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
1892 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1895 WL_ERR("Invalid algo (0x%x)\n", wsec
);
1899 callback(cookie
, ¶ms
);
1907 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
1908 struct net_device
*ndev
, u8 key_idx
)
1910 WL_INFO("Not supported\n");
1916 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
1917 u8
*mac
, struct station_info
*sinfo
)
1919 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1920 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1921 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1922 struct brcmf_scb_val_le scb_val
;
1926 u8
*bssid
= profile
->bssid
;
1927 struct brcmf_sta_info_le sta_info_le
;
1929 WL_TRACE("Enter, MAC %pM\n", mac
);
1930 if (!check_vif_up(ifp
->vif
))
1933 if (cfg
->conf
->mode
== WL_MODE_AP
) {
1934 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
1935 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
1937 sizeof(sta_info_le
));
1939 WL_ERR("GET STA INFO failed, %d\n", err
);
1942 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
1943 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
1944 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
1945 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
1946 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
1948 WL_TRACE("STA idle time : %d ms, connected time :%d sec\n",
1949 sinfo
->inactive_time
, sinfo
->connected_time
);
1950 } else if (cfg
->conf
->mode
== WL_MODE_BSS
) {
1951 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
1952 WL_ERR("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1957 /* Report the current tx rate */
1958 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
1960 WL_ERR("Could not get rate (%d)\n", err
);
1963 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
1964 sinfo
->txrate
.legacy
= rate
* 5;
1965 WL_CONN("Rate %d Mbps\n", rate
/ 2);
1968 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
1969 &ifp
->vif
->sme_state
)) {
1970 memset(&scb_val
, 0, sizeof(scb_val
));
1971 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
1972 &scb_val
, sizeof(scb_val
));
1974 WL_ERR("Could not get rssi (%d)\n", err
);
1977 rssi
= le32_to_cpu(scb_val
.val
);
1978 sinfo
->filled
|= STATION_INFO_SIGNAL
;
1979 sinfo
->signal
= rssi
;
1980 WL_CONN("RSSI %d dBm\n", rssi
);
1991 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
1992 bool enabled
, s32 timeout
)
1996 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1997 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1999 WL_TRACE("Enter\n");
2002 * Powersave enable/disable request is coming from the
2003 * cfg80211 even before the interface is up. In that
2004 * scenario, driver will be storing the power save
2005 * preference in cfg struct to apply this to
2006 * FW later while initializing the dongle
2008 cfg
->pwr_save
= enabled
;
2009 if (!check_vif_up(ifp
->vif
)) {
2011 WL_INFO("Device is not ready, storing the value in cfg_info struct\n");
2015 pm
= enabled
? PM_FAST
: PM_OFF
;
2016 WL_INFO("power save %s\n", (pm
? "enabled" : "disabled"));
2018 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2021 WL_ERR("net_device is not ready yet\n");
2023 WL_ERR("error (%d)\n", err
);
2031 brcmf_cfg80211_set_bitrate_mask(struct wiphy
*wiphy
, struct net_device
*ndev
,
2033 const struct cfg80211_bitrate_mask
*mask
)
2035 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2036 struct brcm_rateset_le rateset_le
;
2044 WL_TRACE("Enter\n");
2045 if (!check_vif_up(ifp
->vif
))
2048 /* addr param is always NULL. ignore it */
2049 /* Get current rateset */
2050 err
= brcmf_fil_cmd_data_get(ifp
, BRCM_GET_CURR_RATESET
,
2051 &rateset_le
, sizeof(rateset_le
));
2053 WL_ERR("could not get current rateset (%d)\n", err
);
2057 legacy
= ffs(mask
->control
[IEEE80211_BAND_2GHZ
].legacy
& 0xFFFF);
2059 legacy
= ffs(mask
->control
[IEEE80211_BAND_5GHZ
].legacy
&
2062 val
= wl_g_rates
[legacy
- 1].bitrate
* 100000;
2064 if (val
< le32_to_cpu(rateset_le
.count
))
2065 /* Select rate by rateset index */
2066 rate
= rateset_le
.rates
[val
] & 0x7f;
2068 /* Specified rate in bps */
2069 rate
= val
/ 500000;
2071 WL_CONN("rate %d mbps\n", rate
/ 2);
2075 * Set rate override,
2076 * Since the is a/b/g-blind, both a/bg_rate are enforced.
2078 err_bg
= brcmf_fil_iovar_int_set(ifp
, "bg_rate", rate
);
2079 err_a
= brcmf_fil_iovar_int_set(ifp
, "a_rate", rate
);
2080 if (err_bg
&& err_a
) {
2081 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg
, err_a
);
2082 err
= err_bg
| err_a
;
2090 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2091 struct brcmf_bss_info_le
*bi
)
2093 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2094 struct ieee80211_channel
*notify_channel
;
2095 struct cfg80211_bss
*bss
;
2096 struct ieee80211_supported_band
*band
;
2100 u16 notify_capability
;
2101 u16 notify_interval
;
2103 size_t notify_ielen
;
2106 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2107 WL_ERR("Bss info is larger than buffer. Discarding\n");
2111 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2112 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2114 if (channel
<= CH_MAX_2G_CHANNEL
)
2115 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2117 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2119 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2120 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2122 notify_capability
= le16_to_cpu(bi
->capability
);
2123 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2124 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2125 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2126 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2128 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2129 bi
->BSSID
[0], bi
->BSSID
[1], bi
->BSSID
[2],
2130 bi
->BSSID
[3], bi
->BSSID
[4], bi
->BSSID
[5]);
2131 WL_CONN("Channel: %d(%d)\n", channel
, freq
);
2132 WL_CONN("Capability: %X\n", notify_capability
);
2133 WL_CONN("Beacon interval: %d\n", notify_interval
);
2134 WL_CONN("Signal: %d\n", notify_signal
);
2136 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2137 0, notify_capability
, notify_interval
, notify_ie
,
2138 notify_ielen
, notify_signal
, GFP_KERNEL
);
2143 cfg80211_put_bss(bss
);
2148 static struct brcmf_bss_info_le
*
2149 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2152 return list
->bss_info_le
;
2153 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2154 le32_to_cpu(bss
->length
));
2157 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2159 struct brcmf_scan_results
*bss_list
;
2160 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2164 bss_list
= cfg
->bss_list
;
2165 if (bss_list
->count
!= 0 &&
2166 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2167 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2171 WL_SCAN("scanned AP count (%d)\n", bss_list
->count
);
2172 for (i
= 0; i
< bss_list
->count
; i
++) {
2173 bi
= next_bss_le(bss_list
, bi
);
2174 err
= brcmf_inform_single_bss(cfg
, bi
);
2181 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2182 struct net_device
*ndev
, const u8
*bssid
)
2184 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2185 struct ieee80211_channel
*notify_channel
;
2186 struct brcmf_bss_info_le
*bi
= NULL
;
2187 struct ieee80211_supported_band
*band
;
2188 struct cfg80211_bss
*bss
;
2193 u16 notify_capability
;
2194 u16 notify_interval
;
2196 size_t notify_ielen
;
2199 WL_TRACE("Enter\n");
2201 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2207 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2209 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2210 buf
, WL_BSS_INFO_MAX
);
2212 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err
);
2216 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2218 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2219 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2221 if (channel
<= CH_MAX_2G_CHANNEL
)
2222 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2224 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2226 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2227 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2229 notify_capability
= le16_to_cpu(bi
->capability
);
2230 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2231 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2232 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2233 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2235 WL_CONN("channel: %d(%d)\n", channel
, freq
);
2236 WL_CONN("capability: %X\n", notify_capability
);
2237 WL_CONN("beacon interval: %d\n", notify_interval
);
2238 WL_CONN("signal: %d\n", notify_signal
);
2240 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2241 0, notify_capability
, notify_interval
,
2242 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2249 cfg80211_put_bss(bss
);
2260 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_info
*cfg
)
2262 return cfg
->conf
->mode
== WL_MODE_IBSS
;
2266 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2267 * triples, returning a pointer to the substring whose first element
2270 static struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
2272 struct brcmf_tlv
*elt
;
2275 elt
= (struct brcmf_tlv
*) buf
;
2278 /* find tagged parameter */
2279 while (totlen
>= TLV_HDR_LEN
) {
2282 /* validate remaining totlen */
2283 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
2286 elt
= (struct brcmf_tlv
*) ((u8
*) elt
+ (len
+ TLV_HDR_LEN
));
2287 totlen
-= (len
+ TLV_HDR_LEN
);
2293 /* Is any of the tlvs the expected entry? If
2294 * not update the tlvs buffer pointer/length.
2297 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
2298 u8
*oui
, u32 oui_len
, u8 type
)
2300 /* If the contents match the OUI and the type */
2301 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
2302 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
2303 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
2309 /* point to the next ie */
2310 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
2311 /* calculate the length of the rest of the buffer */
2312 *tlvs_len
-= (int)(ie
- *tlvs
);
2313 /* update the pointer to the start of the buffer */
2319 static struct brcmf_vs_tlv
*
2320 brcmf_find_wpaie(u8
*parse
, u32 len
)
2322 struct brcmf_tlv
*ie
;
2324 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
2325 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
2326 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
2327 return (struct brcmf_vs_tlv
*)ie
;
2332 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
)
2334 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2335 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
2336 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2337 struct brcmf_bss_info_le
*bi
;
2338 struct brcmf_ssid
*ssid
;
2339 struct brcmf_tlv
*tim
;
2340 u16 beacon_interval
;
2346 WL_TRACE("Enter\n");
2347 if (brcmf_is_ibssmode(cfg
))
2350 ssid
= &profile
->ssid
;
2352 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2353 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2354 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2356 WL_ERR("Could not get bss info %d\n", err
);
2357 goto update_bss_info_out
;
2360 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2361 err
= brcmf_inform_single_bss(cfg
, bi
);
2363 goto update_bss_info_out
;
2365 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2366 ie_len
= le32_to_cpu(bi
->ie_length
);
2367 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2369 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2371 dtim_period
= tim
->data
[1];
2374 * active scan was done so we could not get dtim
2375 * information out of probe response.
2376 * so we speficially query dtim information to dongle.
2379 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2381 WL_ERR("wl dtim_assoc failed (%d)\n", err
);
2382 goto update_bss_info_out
;
2384 dtim_period
= (u8
)var
;
2387 update_bss_info_out
:
2392 static void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2394 struct escan_info
*escan
= &cfg
->escan_info
;
2396 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2397 if (cfg
->scan_request
) {
2398 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2399 brcmf_notify_escan_complete(cfg
, escan
->ndev
, true, true);
2401 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2402 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2405 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2407 struct brcmf_cfg80211_info
*cfg
=
2408 container_of(work
, struct brcmf_cfg80211_info
,
2409 escan_timeout_work
);
2411 brcmf_notify_escan_complete(cfg
,
2412 cfg
->escan_info
.ndev
, true, true);
2415 static void brcmf_escan_timeout(unsigned long data
)
2417 struct brcmf_cfg80211_info
*cfg
=
2418 (struct brcmf_cfg80211_info
*)data
;
2420 if (cfg
->scan_request
) {
2421 WL_ERR("timer expired\n");
2422 schedule_work(&cfg
->escan_timeout_work
);
2427 brcmf_compare_update_same_bss(struct brcmf_bss_info_le
*bss
,
2428 struct brcmf_bss_info_le
*bss_info_le
)
2430 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2431 (CHSPEC_BAND(le16_to_cpu(bss_info_le
->chanspec
)) ==
2432 CHSPEC_BAND(le16_to_cpu(bss
->chanspec
))) &&
2433 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2434 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2435 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2436 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2437 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2438 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2440 /* preserve max RSSI if the measurements are
2441 * both on-channel or both off-channel
2443 if (bss_info_rssi
> bss_rssi
)
2444 bss
->RSSI
= bss_info_le
->RSSI
;
2445 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2446 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2447 /* preserve the on-channel rssi measurement
2448 * if the new measurement is off channel
2450 bss
->RSSI
= bss_info_le
->RSSI
;
2451 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2459 brcmf_cfg80211_escan_handler(struct brcmf_cfg80211_info
*cfg
,
2460 struct net_device
*ndev
,
2461 const struct brcmf_event_msg
*e
, void *data
)
2465 struct brcmf_escan_result_le
*escan_result_le
;
2466 struct brcmf_bss_info_le
*bss_info_le
;
2467 struct brcmf_bss_info_le
*bss
= NULL
;
2469 struct brcmf_scan_results
*list
;
2473 status
= be32_to_cpu(e
->status
);
2475 if (!ndev
|| !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2476 WL_ERR("scan not ready ndev %p drv_status %x\n", ndev
,
2477 !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
));
2481 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2482 WL_SCAN("ESCAN Partial result\n");
2483 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2484 if (!escan_result_le
) {
2485 WL_ERR("Invalid escan result (NULL pointer)\n");
2488 if (!cfg
->scan_request
) {
2489 WL_SCAN("result without cfg80211 request\n");
2493 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2494 WL_ERR("Invalid bss_count %d: ignoring\n",
2495 escan_result_le
->bss_count
);
2498 bss_info_le
= &escan_result_le
->bss_info_le
;
2500 bi_length
= le32_to_cpu(bss_info_le
->length
);
2501 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2502 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2503 WL_ERR("Invalid bss_info length %d: ignoring\n",
2508 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2509 BIT(NL80211_IFTYPE_ADHOC
))) {
2510 if (le16_to_cpu(bss_info_le
->capability
) &
2511 WLAN_CAPABILITY_IBSS
) {
2512 WL_ERR("Ignoring IBSS result\n");
2517 list
= (struct brcmf_scan_results
*)
2518 cfg
->escan_info
.escan_buf
;
2519 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2520 WL_ERR("Buffer is too small: ignoring\n");
2524 for (i
= 0; i
< list
->count
; i
++) {
2525 bss
= bss
? (struct brcmf_bss_info_le
*)
2526 ((unsigned char *)bss
+
2527 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2528 if (brcmf_compare_update_same_bss(bss
, bss_info_le
))
2531 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2532 bss_info_le
, bi_length
);
2533 list
->version
= le32_to_cpu(bss_info_le
->version
);
2534 list
->buflen
+= bi_length
;
2537 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2538 if (cfg
->scan_request
) {
2539 cfg
->bss_list
= (struct brcmf_scan_results
*)
2540 cfg
->escan_info
.escan_buf
;
2541 brcmf_inform_bss(cfg
);
2542 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2543 brcmf_notify_escan_complete(cfg
, ndev
, aborted
,
2546 WL_ERR("Unexpected scan result 0x%x\n", status
);
2552 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2555 cfg
->el
.handler
[BRCMF_E_ESCAN_RESULT
] =
2556 brcmf_cfg80211_escan_handler
;
2557 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2558 /* Init scan_timeout timer */
2559 init_timer(&cfg
->escan_timeout
);
2560 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2561 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2562 INIT_WORK(&cfg
->escan_timeout_work
,
2563 brcmf_cfg80211_escan_timeout_worker
);
2566 static __always_inline
void brcmf_delay(u32 ms
)
2568 if (ms
< 1000 / HZ
) {
2576 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2578 WL_TRACE("Enter\n");
2583 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2584 struct cfg80211_wowlan
*wow
)
2586 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2587 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2588 struct brcmf_cfg80211_vif
*vif
;
2590 WL_TRACE("Enter\n");
2593 * if the primary net_device is not READY there is nothing
2594 * we can do but pray resume goes smoothly.
2596 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2597 if (!check_vif_up(vif
))
2600 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2601 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2604 * While going to suspend if associated with AP disassociate
2605 * from AP to save power while system is in suspended state
2607 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
) ||
2608 test_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
)) {
2609 WL_INFO("Disassociating from AP before suspend\n");
2610 brcmf_link_down(cfg
);
2612 /* Make sure WPA_Supplicant receives all the event
2613 * generated due to DISASSOC call to the fw to keep
2614 * the state fw and WPA_Supplicant state consistent
2620 /* end any scanning */
2621 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2622 brcmf_abort_scanning(cfg
);
2624 /* Turn off watchdog timer */
2625 brcmf_set_mpc(ndev
, 1);
2629 /* clear any scanning activity */
2630 cfg
->scan_status
= 0;
2635 brcmf_update_pmklist(struct net_device
*ndev
,
2636 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2641 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2643 WL_CONN("No of elements %d\n", pmkid_len
);
2644 for (i
= 0; i
< pmkid_len
; i
++) {
2645 WL_CONN("PMKID[%d]: %pM =\n", i
,
2646 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2647 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2648 WL_CONN("%02x\n", pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2652 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2653 (char *)pmk_list
, sizeof(*pmk_list
));
2659 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2660 struct cfg80211_pmksa
*pmksa
)
2662 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2663 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2664 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2669 WL_TRACE("Enter\n");
2670 if (!check_vif_up(ifp
->vif
))
2673 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2674 for (i
= 0; i
< pmkid_len
; i
++)
2675 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2677 if (i
< WL_NUM_PMKIDS_MAX
) {
2678 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2679 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2680 if (i
== pmkid_len
) {
2682 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2687 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2688 pmkids
->pmkid
[pmkid_len
].BSSID
);
2689 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2690 WL_CONN("%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2692 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2699 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2700 struct cfg80211_pmksa
*pmksa
)
2702 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2703 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2704 struct pmkid_list pmkid
;
2708 WL_TRACE("Enter\n");
2709 if (!check_vif_up(ifp
->vif
))
2712 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2713 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2715 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2716 &pmkid
.pmkid
[0].BSSID
);
2717 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2718 WL_CONN("%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2720 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2721 for (i
= 0; i
< pmkid_len
; i
++)
2723 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2728 && (i
< pmkid_len
)) {
2729 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2730 sizeof(struct pmkid
));
2731 for (; i
< (pmkid_len
- 1); i
++) {
2732 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2733 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2735 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2736 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2739 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2743 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2751 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2753 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2754 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2757 WL_TRACE("Enter\n");
2758 if (!check_vif_up(ifp
->vif
))
2761 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2762 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2770 * PFN result doesn't have all the info which are
2771 * required by the supplicant
2772 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2773 * via wl_inform_single_bss in the required format. Escan does require the
2774 * scan request in the form of cfg80211_scan_request. For timebeing, create
2775 * cfg80211_scan_request one out of the received PNO event.
2778 brcmf_notify_sched_scan_results(struct brcmf_cfg80211_info
*cfg
,
2779 struct net_device
*ndev
,
2780 const struct brcmf_event_msg
*e
, void *data
)
2782 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2783 struct cfg80211_scan_request
*request
= NULL
;
2784 struct cfg80211_ssid
*ssid
= NULL
;
2785 struct ieee80211_channel
*channel
= NULL
;
2786 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2788 int channel_req
= 0;
2790 struct brcmf_pno_scanresults_le
*pfn_result
;
2796 if (e
->event_type
== cpu_to_be32(BRCMF_E_PFN_NET_LOST
)) {
2797 WL_SCAN("PFN NET LOST event. Do Nothing\n");
2801 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2802 result_count
= le32_to_cpu(pfn_result
->count
);
2803 status
= le32_to_cpu(pfn_result
->status
);
2806 * PFN event is limited to fit 512 bytes so we may get
2807 * multiple NET_FOUND events. For now place a warning here.
2809 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2810 WL_SCAN("PFN NET FOUND event. count: %d\n", result_count
);
2811 if (result_count
> 0) {
2814 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2815 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2816 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2817 if (!request
|| !ssid
|| !channel
) {
2822 request
->wiphy
= wiphy
;
2823 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2824 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2826 for (i
= 0; i
< result_count
; i
++) {
2827 netinfo
= &netinfo_start
[i
];
2829 WL_ERR("Invalid netinfo ptr. index: %d\n", i
);
2834 WL_SCAN("SSID:%s Channel:%d\n",
2835 netinfo
->SSID
, netinfo
->channel
);
2836 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2837 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2840 channel_req
= netinfo
->channel
;
2841 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2842 band
= NL80211_BAND_2GHZ
;
2844 band
= NL80211_BAND_5GHZ
;
2845 channel
[i
].center_freq
=
2846 ieee80211_channel_to_frequency(channel_req
,
2848 channel
[i
].band
= band
;
2849 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2850 request
->channels
[i
] = &channel
[i
];
2851 request
->n_channels
++;
2854 /* assign parsed ssid array */
2855 if (request
->n_ssids
)
2856 request
->ssids
= &ssid
[0];
2858 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2859 /* Abort any on-going scan */
2860 brcmf_abort_scanning(cfg
);
2863 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2864 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
2866 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2869 cfg
->sched_escan
= true;
2870 cfg
->scan_request
= request
;
2872 WL_ERR("FALSE PNO Event. (pfn_count == 0)\n");
2885 cfg80211_sched_scan_stopped(wiphy
);
2889 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
2894 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
2897 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
2901 WL_ERR("failed code %d\n", ret
);
2906 static int brcmf_dev_pno_config(struct net_device
*ndev
)
2908 struct brcmf_pno_param_le pfn_param
;
2910 memset(&pfn_param
, 0, sizeof(pfn_param
));
2911 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
2913 /* set extra pno params */
2914 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
2915 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
2916 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
2918 /* set up pno scan fr */
2919 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
2921 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
2922 &pfn_param
, sizeof(pfn_param
));
2926 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
2927 struct net_device
*ndev
,
2928 struct cfg80211_sched_scan_request
*request
)
2930 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2931 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
2932 struct brcmf_pno_net_param_le pfn
;
2936 WL_SCAN("Enter n_match_sets:%d n_ssids:%d\n",
2937 request
->n_match_sets
, request
->n_ssids
);
2938 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2939 WL_ERR("Scanning already: status (%lu)\n", cfg
->scan_status
);
2943 if (!request
|| !request
->n_ssids
|| !request
->n_match_sets
) {
2944 WL_ERR("Invalid sched scan req!! n_ssids:%d\n",
2945 request
? request
->n_ssids
: 0);
2949 if (request
->n_ssids
> 0) {
2950 for (i
= 0; i
< request
->n_ssids
; i
++) {
2951 /* Active scan req for ssids */
2952 WL_SCAN(">>> Active scan req for ssid (%s)\n",
2953 request
->ssids
[i
].ssid
);
2956 * match_set ssids is a supert set of n_ssid list,
2957 * so we need not add these set seperately.
2962 if (request
->n_match_sets
> 0) {
2963 /* clean up everything */
2964 ret
= brcmf_dev_pno_clean(ndev
);
2966 WL_ERR("failed error=%d\n", ret
);
2971 ret
= brcmf_dev_pno_config(ndev
);
2973 WL_ERR("PNO setup failed!! ret=%d\n", ret
);
2977 /* configure each match set */
2978 for (i
= 0; i
< request
->n_match_sets
; i
++) {
2979 struct cfg80211_ssid
*ssid
;
2982 ssid
= &request
->match_sets
[i
].ssid
;
2983 ssid_len
= ssid
->ssid_len
;
2986 WL_ERR("skip broadcast ssid\n");
2989 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
2990 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
2991 pfn
.wsec
= cpu_to_le32(0);
2992 pfn
.infra
= cpu_to_le32(1);
2993 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
2994 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
2995 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
2996 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
2998 WL_SCAN(">>> PNO filter %s for ssid (%s)\n",
2999 ret
== 0 ? "set" : "failed",
3002 /* Enable the PNO */
3003 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3004 WL_ERR("PNO enable failed!! ret=%d\n", ret
);
3014 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3015 struct net_device
*ndev
)
3017 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3020 brcmf_dev_pno_clean(ndev
);
3021 if (cfg
->sched_escan
)
3022 brcmf_notify_escan_complete(cfg
, ndev
, true, true);
3026 #ifdef CONFIG_NL80211_TESTMODE
3027 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
3029 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3030 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3031 struct brcmf_dcmd
*dcmd
= data
;
3032 struct sk_buff
*reply
;
3035 WL_TRACE("cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3036 dcmd
->buf
, dcmd
->len
);
3039 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3040 dcmd
->buf
, dcmd
->len
);
3042 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3043 dcmd
->buf
, dcmd
->len
);
3045 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3046 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3047 ret
= cfg80211_testmode_reply(reply
);
3053 static s32
brcmf_configure_opensecurity(struct net_device
*ndev
, s32 bssidx
)
3055 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3059 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3061 WL_ERR("auth error %d\n", err
);
3065 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3067 WL_ERR("wsec error %d\n", err
);
3070 /* set upper-layer auth */
3071 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3073 WL_ERR("wpa_auth error %d\n", err
);
3080 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3083 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3085 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3089 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3092 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3093 u32 auth
= 0; /* d11 open authentication */
3105 u32 wme_bss_disable
;
3107 WL_TRACE("Enter\n");
3111 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3112 data
= (u8
*)wpa_ie
;
3115 offset
+= VS_IE_FIXED_HDR_LEN
;
3116 offset
+= WPA_IE_VERSION_LEN
;
3118 /* check for multicast cipher suite */
3119 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3121 WL_ERR("no multicast cipher suite\n");
3125 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3127 WL_ERR("ivalid OUI\n");
3130 offset
+= TLV_OUI_LEN
;
3132 /* pick up multicast cipher */
3133 switch (data
[offset
]) {
3134 case WPA_CIPHER_NONE
:
3137 case WPA_CIPHER_WEP_40
:
3138 case WPA_CIPHER_WEP_104
:
3141 case WPA_CIPHER_TKIP
:
3142 gval
= TKIP_ENABLED
;
3144 case WPA_CIPHER_AES_CCM
:
3149 WL_ERR("Invalid multi cast cipher info\n");
3154 /* walk thru unicast cipher list and pick up what we recognize */
3155 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3156 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3157 /* Check for unicast suite(s) */
3158 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3160 WL_ERR("no unicast cipher suite\n");
3163 for (i
= 0; i
< count
; i
++) {
3164 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3166 WL_ERR("ivalid OUI\n");
3169 offset
+= TLV_OUI_LEN
;
3170 switch (data
[offset
]) {
3171 case WPA_CIPHER_NONE
:
3173 case WPA_CIPHER_WEP_40
:
3174 case WPA_CIPHER_WEP_104
:
3175 pval
|= WEP_ENABLED
;
3177 case WPA_CIPHER_TKIP
:
3178 pval
|= TKIP_ENABLED
;
3180 case WPA_CIPHER_AES_CCM
:
3181 pval
|= AES_ENABLED
;
3184 WL_ERR("Ivalid unicast security info\n");
3188 /* walk thru auth management suite list and pick up what we recognize */
3189 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3190 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3191 /* Check for auth key management suite(s) */
3192 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3194 WL_ERR("no auth key mgmt suite\n");
3197 for (i
= 0; i
< count
; i
++) {
3198 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3200 WL_ERR("ivalid OUI\n");
3203 offset
+= TLV_OUI_LEN
;
3204 switch (data
[offset
]) {
3206 WL_TRACE("RSN_AKM_NONE\n");
3207 wpa_auth
|= WPA_AUTH_NONE
;
3209 case RSN_AKM_UNSPECIFIED
:
3210 WL_TRACE("RSN_AKM_UNSPECIFIED\n");
3211 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3212 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3215 WL_TRACE("RSN_AKM_PSK\n");
3216 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3217 (wpa_auth
|= WPA_AUTH_PSK
);
3220 WL_ERR("Ivalid key mgmt info\n");
3226 wme_bss_disable
= 1;
3227 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3228 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3229 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3230 wme_bss_disable
= 0;
3232 /* set wme_bss_disable to sync RSN Capabilities */
3233 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3236 WL_ERR("wme_bss_disable error %d\n", err
);
3240 /* FOR WPS , set SES_OW_ENABLED */
3241 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3244 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3246 WL_ERR("auth error %d\n", err
);
3250 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3252 WL_ERR("wsec error %d\n", err
);
3255 /* set upper-layer auth */
3256 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3258 WL_ERR("wpa_auth error %d\n", err
);
3267 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3268 struct parsed_vndr_ies
*vndr_ies
)
3271 struct brcmf_vs_tlv
*vndrie
;
3272 struct brcmf_tlv
*ie
;
3273 struct parsed_vndr_ie_info
*parsed_info
;
3276 remaining_len
= (s32
)vndr_ie_len
;
3277 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3279 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3281 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3283 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3284 /* len should be bigger than OUI length + one */
3285 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3286 WL_ERR("invalid vndr ie. length is too small %d\n",
3290 /* if wpa or wme ie, do not add ie */
3291 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3292 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3293 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3294 WL_TRACE("Found WPA/WME oui. Do not add it\n");
3298 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3300 /* save vndr ie information */
3301 parsed_info
->ie_ptr
= (char *)vndrie
;
3302 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3303 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3307 WL_TRACE("** OUI %02x %02x %02x, type 0x%02x\n",
3308 parsed_info
->vndrie
.oui
[0],
3309 parsed_info
->vndrie
.oui
[1],
3310 parsed_info
->vndrie
.oui
[2],
3311 parsed_info
->vndrie
.oui_type
);
3313 if (vndr_ies
->count
>= MAX_VNDR_IE_NUMBER
)
3316 remaining_len
-= ie
->len
;
3317 if (remaining_len
<= 2)
3320 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
);
3326 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3332 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3333 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3335 iecount_le
= cpu_to_le32(1);
3336 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3338 pktflag_le
= cpu_to_le32(pktflag
);
3339 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3341 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3343 return ie_len
+ VNDR_IE_HDR_SIZE
;
3347 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3348 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3350 struct brcmf_if
*ifp
;
3351 struct vif_saved_ie
*saved_ie
;
3355 u8
*mgmt_ie_buf
= NULL
;
3356 int mgmt_ie_buf_len
;
3358 u32 del_add_ie_buf_len
= 0;
3359 u32 total_ie_buf_len
= 0;
3360 u32 parsed_ie_buf_len
= 0;
3361 struct parsed_vndr_ies old_vndr_ies
;
3362 struct parsed_vndr_ies new_vndr_ies
;
3363 struct parsed_vndr_ie_info
*vndrie_info
;
3366 int remained_buf_len
;
3371 saved_ie
= &vif
->saved_ie
;
3373 WL_TRACE("bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3374 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3377 curr_ie_buf
= iovar_ie_buf
;
3378 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3380 case VNDR_IE_PRBRSP_FLAG
:
3381 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3382 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3383 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3385 case VNDR_IE_BEACON_FLAG
:
3386 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3387 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3388 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3392 WL_ERR("not suitable type\n");
3397 WL_ERR("not suitable type\n");
3401 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3403 WL_ERR("extra IE size too big\n");
3407 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3408 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3410 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3411 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3412 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3413 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3414 vndrie_info
->ie_len
);
3415 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3419 if (mgmt_ie_buf
!= NULL
) {
3420 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3421 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3422 parsed_ie_buf_len
) == 0)) {
3423 WL_TRACE("Previous mgmt IE is equals to current IE");
3427 /* parse old vndr_ie */
3428 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3430 /* make a command to delete old ie */
3431 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3432 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3434 WL_TRACE("DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3435 vndrie_info
->vndrie
.id
,
3436 vndrie_info
->vndrie
.len
,
3437 vndrie_info
->vndrie
.oui
[0],
3438 vndrie_info
->vndrie
.oui
[1],
3439 vndrie_info
->vndrie
.oui
[2]);
3441 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3442 vndrie_info
->ie_ptr
,
3443 vndrie_info
->ie_len
,
3445 curr_ie_buf
+= del_add_ie_buf_len
;
3446 total_ie_buf_len
+= del_add_ie_buf_len
;
3451 /* Add if there is any extra IE */
3452 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3455 remained_buf_len
= mgmt_ie_buf_len
;
3457 /* make a command to add new ie */
3458 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3459 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3461 WL_TRACE("ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3462 vndrie_info
->vndrie
.id
,
3463 vndrie_info
->vndrie
.len
,
3464 vndrie_info
->vndrie
.oui
[0],
3465 vndrie_info
->vndrie
.oui
[1],
3466 vndrie_info
->vndrie
.oui
[2]);
3468 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3469 vndrie_info
->ie_ptr
,
3470 vndrie_info
->ie_len
,
3472 /* verify remained buf size before copy data */
3473 remained_buf_len
-= vndrie_info
->ie_len
;
3474 if (remained_buf_len
< 0) {
3475 WL_ERR("no space in mgmt_ie_buf: len left %d",
3480 /* save the parsed IE in wl struct */
3481 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3482 vndrie_info
->ie_len
);
3483 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3485 curr_ie_buf
+= del_add_ie_buf_len
;
3486 total_ie_buf_len
+= del_add_ie_buf_len
;
3489 if (total_ie_buf_len
) {
3490 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3493 WL_ERR("vndr ie set error : %d\n", err
);
3497 kfree(iovar_ie_buf
);
3502 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3503 struct cfg80211_ap_settings
*settings
)
3506 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3507 struct brcmf_tlv
*ssid_ie
;
3508 struct brcmf_ssid_le ssid_le
;
3510 struct brcmf_tlv
*rsn_ie
;
3511 struct brcmf_vs_tlv
*wpa_ie
;
3512 struct brcmf_join_params join_params
;
3515 WL_TRACE("channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3516 settings
->channel_type
, settings
->beacon_interval
,
3517 settings
->dtim_period
);
3518 WL_TRACE("ssid=%s(%d), auth_type=%d, inactivity_timeout=%d\n",
3519 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3520 settings
->inactivity_timeout
);
3522 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
)) {
3523 WL_ERR("Not in AP creation mode\n");
3527 memset(&ssid_le
, 0, sizeof(ssid_le
));
3528 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3529 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3530 ssid_ie
= brcmf_parse_tlvs(
3531 (u8
*)&settings
->beacon
.head
[ie_offset
],
3532 settings
->beacon
.head_len
- ie_offset
,
3537 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3538 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3539 WL_TRACE("SSID is (%s) in Head\n", ssid_le
.SSID
);
3541 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3542 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3545 brcmf_set_mpc(ndev
, 0);
3546 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3548 WL_ERR("BRCMF_C_DOWN error %d\n", err
);
3551 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3553 WL_ERR("SET INFRA error %d\n", err
);
3556 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3558 WL_ERR("setting AP mode failed %d\n", err
);
3562 /* find the RSN_IE */
3563 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3564 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3566 /* find the WPA_IE */
3567 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3568 settings
->beacon
.tail_len
);
3570 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3571 WL_TRACE("WPA(2) IE is found\n");
3572 if (wpa_ie
!= NULL
) {
3574 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3579 err
= brcmf_configure_wpaie(ndev
,
3580 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3585 WL_TRACE("No WPA(2) IEs found\n");
3586 brcmf_configure_opensecurity(ndev
, bssidx
);
3588 /* Set Beacon IEs to FW */
3589 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3590 VNDR_IE_BEACON_FLAG
,
3591 settings
->beacon
.tail
,
3592 settings
->beacon
.tail_len
);
3594 WL_ERR("Set Beacon IE Failed\n");
3596 WL_TRACE("Applied Vndr IEs for Beacon\n");
3598 /* Set Probe Response IEs to FW */
3599 err
= brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev
),
3600 VNDR_IE_PRBRSP_FLAG
,
3601 settings
->beacon
.proberesp_ies
,
3602 settings
->beacon
.proberesp_ies_len
);
3604 WL_ERR("Set Probe Resp IE Failed\n");
3606 WL_TRACE("Applied Vndr IEs for Probe Resp\n");
3608 if (settings
->beacon_interval
) {
3609 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3610 settings
->beacon_interval
);
3612 WL_ERR("Beacon Interval Set Error, %d\n", err
);
3616 if (settings
->dtim_period
) {
3617 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3618 settings
->dtim_period
);
3620 WL_ERR("DTIM Interval Set Error, %d\n", err
);
3624 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3626 WL_ERR("BRCMF_C_UP error (%d)\n", err
);
3630 memset(&join_params
, 0, sizeof(join_params
));
3631 /* join parameters starts with ssid */
3632 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3634 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3635 &join_params
, sizeof(join_params
));
3637 WL_ERR("SET SSID error (%d)\n", err
);
3640 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3641 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3645 brcmf_set_mpc(ndev
, 1);
3649 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3651 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3652 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3655 WL_TRACE("Enter\n");
3657 if (cfg
->conf
->mode
== WL_MODE_AP
) {
3658 /* Due to most likely deauths outstanding we sleep */
3659 /* first to make sure they get processed by fw. */
3661 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
),
3664 WL_ERR("setting AP mode failed %d\n", err
);
3667 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_UP
, 0);
3669 WL_ERR("BRCMF_C_UP error %d\n", err
);
3672 brcmf_set_mpc(ndev
, 1);
3673 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3674 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3681 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3684 struct brcmf_scb_val_le scbval
;
3685 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3691 WL_TRACE("Enter %pM\n", mac
);
3693 if (!check_vif_up(ifp
->vif
))
3696 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3697 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3698 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3699 &scbval
, sizeof(scbval
));
3701 WL_ERR("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3707 static struct cfg80211_ops wl_cfg80211_ops
= {
3708 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
3709 .scan
= brcmf_cfg80211_scan
,
3710 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
3711 .join_ibss
= brcmf_cfg80211_join_ibss
,
3712 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
3713 .get_station
= brcmf_cfg80211_get_station
,
3714 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
3715 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
3716 .add_key
= brcmf_cfg80211_add_key
,
3717 .del_key
= brcmf_cfg80211_del_key
,
3718 .get_key
= brcmf_cfg80211_get_key
,
3719 .set_default_key
= brcmf_cfg80211_config_default_key
,
3720 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
3721 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
3722 .set_bitrate_mask
= brcmf_cfg80211_set_bitrate_mask
,
3723 .connect
= brcmf_cfg80211_connect
,
3724 .disconnect
= brcmf_cfg80211_disconnect
,
3725 .suspend
= brcmf_cfg80211_suspend
,
3726 .resume
= brcmf_cfg80211_resume
,
3727 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
3728 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
3729 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
3730 .start_ap
= brcmf_cfg80211_start_ap
,
3731 .stop_ap
= brcmf_cfg80211_stop_ap
,
3732 .del_station
= brcmf_cfg80211_del_station
,
3733 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
3734 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
3735 #ifdef CONFIG_NL80211_TESTMODE
3736 .testmode_cmd
= brcmf_cfg80211_testmode
3740 static s32
brcmf_mode_to_nl80211_iftype(s32 mode
)
3746 return NL80211_IFTYPE_STATION
;
3748 return NL80211_IFTYPE_ADHOC
;
3750 return NL80211_IFTYPE_UNSPECIFIED
;
3756 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
3758 /* scheduled scan settings */
3759 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
3760 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
3761 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
3762 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
3765 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
3767 struct wiphy
*wiphy
;
3770 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
3772 WL_ERR("Could not allocate wiphy device\n");
3773 return ERR_PTR(-ENOMEM
);
3775 set_wiphy_dev(wiphy
, phydev
);
3776 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
3777 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
3778 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
3779 BIT(NL80211_IFTYPE_ADHOC
) |
3780 BIT(NL80211_IFTYPE_AP
);
3781 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
3782 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
3783 * it as 11a by default.
3784 * This will be updated with
3787 * if phy has 11n capability
3789 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
3790 wiphy
->cipher_suites
= __wl_cipher_suites
;
3791 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
3792 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
; /* enable power
3796 brcmf_wiphy_pno_params(wiphy
);
3797 err
= wiphy_register(wiphy
);
3799 WL_ERR("Could not register wiphy device (%d)\n", err
);
3801 return ERR_PTR(err
);
3807 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
3808 struct net_device
*netdev
,
3809 s32 mode
, bool pm_block
)
3811 struct brcmf_cfg80211_vif
*vif
;
3813 if (cfg
->vif_cnt
== BRCMF_IFACE_MAX_CNT
)
3814 return ERR_PTR(-ENOSPC
);
3816 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
3818 return ERR_PTR(-ENOMEM
);
3820 vif
->wdev
.wiphy
= cfg
->wiphy
;
3821 vif
->wdev
.netdev
= netdev
;
3822 vif
->wdev
.iftype
= brcmf_mode_to_nl80211_iftype(mode
);
3825 vif
->ifp
= netdev_priv(netdev
);
3826 netdev
->ieee80211_ptr
= &vif
->wdev
;
3827 SET_NETDEV_DEV(netdev
, wiphy_dev(cfg
->wiphy
));
3831 vif
->pm_block
= pm_block
;
3834 brcmf_init_prof(&vif
->profile
);
3836 list_add_tail(&vif
->list
, &cfg
->vif_list
);
3841 static void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
3843 struct brcmf_cfg80211_info
*cfg
;
3844 struct wiphy
*wiphy
;
3846 wiphy
= vif
->wdev
.wiphy
;
3847 cfg
= wiphy_priv(wiphy
);
3848 list_del(&vif
->list
);
3852 if (!cfg
->vif_cnt
) {
3853 wiphy_unregister(wiphy
);
3858 static bool brcmf_is_linkup(struct brcmf_cfg80211_info
*cfg
,
3859 const struct brcmf_event_msg
*e
)
3861 u32 event
= be32_to_cpu(e
->event_type
);
3862 u32 status
= be32_to_cpu(e
->status
);
3864 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
3865 WL_CONN("Processing set ssid\n");
3866 cfg
->link_up
= true;
3873 static bool brcmf_is_linkdown(struct brcmf_cfg80211_info
*cfg
,
3874 const struct brcmf_event_msg
*e
)
3876 u32 event
= be32_to_cpu(e
->event_type
);
3877 u16 flags
= be16_to_cpu(e
->flags
);
3879 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
3880 WL_CONN("Processing link down\n");
3886 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
3887 const struct brcmf_event_msg
*e
)
3889 u32 event
= be32_to_cpu(e
->event_type
);
3890 u32 status
= be32_to_cpu(e
->status
);
3892 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
3893 WL_CONN("Processing Link %s & no network found\n",
3894 be16_to_cpu(e
->flags
) & BRCMF_EVENT_MSG_LINK
?
3899 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
3900 WL_CONN("Processing connecting & no network found\n");
3907 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3909 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3911 kfree(conn_info
->req_ie
);
3912 conn_info
->req_ie
= NULL
;
3913 conn_info
->req_ie_len
= 0;
3914 kfree(conn_info
->resp_ie
);
3915 conn_info
->resp_ie
= NULL
;
3916 conn_info
->resp_ie_len
= 0;
3919 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
3921 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
3922 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
3923 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3928 brcmf_clear_assoc_ies(cfg
);
3930 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
3931 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
3933 WL_ERR("could not get assoc info (%d)\n", err
);
3937 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
3938 req_len
= le32_to_cpu(assoc_info
->req_len
);
3939 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
3941 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
3945 WL_ERR("could not get assoc req (%d)\n", err
);
3948 conn_info
->req_ie_len
= req_len
;
3950 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
3953 conn_info
->req_ie_len
= 0;
3954 conn_info
->req_ie
= NULL
;
3957 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
3961 WL_ERR("could not get assoc resp (%d)\n", err
);
3964 conn_info
->resp_ie_len
= resp_len
;
3965 conn_info
->resp_ie
=
3966 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
3969 conn_info
->resp_ie_len
= 0;
3970 conn_info
->resp_ie
= NULL
;
3972 WL_CONN("req len (%d) resp len (%d)\n",
3973 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
3979 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
3980 struct net_device
*ndev
,
3981 const struct brcmf_event_msg
*e
)
3983 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3984 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
3985 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
3986 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3987 struct ieee80211_channel
*notify_channel
= NULL
;
3988 struct ieee80211_supported_band
*band
;
3989 struct brcmf_bss_info_le
*bi
;
3995 WL_TRACE("Enter\n");
3997 brcmf_get_assoc_ies(cfg
);
3998 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
3999 brcmf_update_bss_info(cfg
);
4001 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4007 /* data sent to dongle has to be little endian */
4008 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4009 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4010 buf
, WL_BSS_INFO_MAX
);
4015 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4016 target_channel
= bi
->ctl_ch
? bi
->ctl_ch
:
4017 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
4019 if (target_channel
<= CH_MAX_2G_CHANNEL
)
4020 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4022 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4024 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
4025 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4029 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4030 conn_info
->req_ie
, conn_info
->req_ie_len
,
4031 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4032 WL_CONN("Report roaming result\n");
4034 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4040 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4041 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4044 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4045 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4046 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4049 WL_TRACE("Enter\n");
4051 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4052 &ifp
->vif
->sme_state
)) {
4054 brcmf_get_assoc_ies(cfg
);
4055 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4056 brcmf_update_bss_info(cfg
);
4058 cfg80211_connect_result(ndev
,
4059 (u8
*)profile
->bssid
,
4061 conn_info
->req_ie_len
,
4063 conn_info
->resp_ie_len
,
4064 completed
? WLAN_STATUS_SUCCESS
:
4065 WLAN_STATUS_AUTH_TIMEOUT
,
4068 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4069 &ifp
->vif
->sme_state
);
4070 WL_CONN("Report connect result - connection %s\n",
4071 completed
? "succeeded" : "failed");
4078 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4079 struct net_device
*ndev
,
4080 const struct brcmf_event_msg
*e
, void *data
)
4083 u32 event
= be32_to_cpu(e
->event_type
);
4084 u32 reason
= be32_to_cpu(e
->reason
);
4085 u32 len
= be32_to_cpu(e
->datalen
);
4086 static int generation
;
4088 struct station_info sinfo
;
4090 WL_CONN("event %d, reason %d\n", event
, reason
);
4091 memset(&sinfo
, 0, sizeof(sinfo
));
4094 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4095 reason
== BRCMF_E_STATUS_SUCCESS
) {
4096 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4098 WL_ERR("No IEs present in ASSOC/REASSOC_IND");
4101 sinfo
.assoc_req_ies
= data
;
4102 sinfo
.assoc_req_ies_len
= len
;
4104 sinfo
.generation
= generation
;
4105 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_ATOMIC
);
4106 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4107 (event
== BRCMF_E_DEAUTH_IND
) ||
4108 (event
== BRCMF_E_DEAUTH
)) {
4110 sinfo
.generation
= generation
;
4111 cfg80211_del_sta(ndev
, e
->addr
, GFP_ATOMIC
);
4117 brcmf_notify_connect_status(struct brcmf_cfg80211_info
*cfg
,
4118 struct net_device
*ndev
,
4119 const struct brcmf_event_msg
*e
, void *data
)
4121 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4122 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4125 if (cfg
->conf
->mode
== WL_MODE_AP
) {
4126 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4127 } else if (brcmf_is_linkup(cfg
, e
)) {
4128 WL_CONN("Linkup\n");
4129 if (brcmf_is_ibssmode(cfg
)) {
4130 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4131 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4132 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4133 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4134 &ifp
->vif
->sme_state
);
4135 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4136 &ifp
->vif
->sme_state
);
4138 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4139 } else if (brcmf_is_linkdown(cfg
, e
)) {
4140 WL_CONN("Linkdown\n");
4141 if (brcmf_is_ibssmode(cfg
)) {
4142 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4143 &ifp
->vif
->sme_state
);
4144 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4145 &ifp
->vif
->sme_state
))
4146 brcmf_link_down(cfg
);
4148 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4149 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4150 &ifp
->vif
->sme_state
)) {
4151 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4153 brcmf_link_down(cfg
);
4156 brcmf_init_prof(ndev_to_prof(ndev
));
4157 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4158 if (brcmf_is_ibssmode(cfg
))
4159 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4160 &ifp
->vif
->sme_state
);
4162 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4169 brcmf_notify_roaming_status(struct brcmf_cfg80211_info
*cfg
,
4170 struct net_device
*ndev
,
4171 const struct brcmf_event_msg
*e
, void *data
)
4173 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4175 u32 event
= be32_to_cpu(e
->event_type
);
4176 u32 status
= be32_to_cpu(e
->status
);
4178 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4179 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4180 brcmf_bss_roaming_done(cfg
, ndev
, e
);
4182 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4189 brcmf_notify_mic_status(struct brcmf_cfg80211_info
*cfg
,
4190 struct net_device
*ndev
,
4191 const struct brcmf_event_msg
*e
, void *data
)
4193 u16 flags
= be16_to_cpu(e
->flags
);
4194 enum nl80211_key_type key_type
;
4196 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4197 key_type
= NL80211_KEYTYPE_GROUP
;
4199 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4201 cfg80211_michael_mic_failure(ndev
, (u8
*)&e
->addr
, key_type
, -1,
4207 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4209 conf
->mode
= (u32
)-1;
4210 conf
->frag_threshold
= (u32
)-1;
4211 conf
->rts_threshold
= (u32
)-1;
4212 conf
->retry_short
= (u32
)-1;
4213 conf
->retry_long
= (u32
)-1;
4214 conf
->tx_power
= -1;
4217 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop
*el
)
4219 memset(el
, 0, sizeof(*el
));
4220 el
->handler
[BRCMF_E_LINK
] = brcmf_notify_connect_status
;
4221 el
->handler
[BRCMF_E_DEAUTH_IND
] = brcmf_notify_connect_status
;
4222 el
->handler
[BRCMF_E_DEAUTH
] = brcmf_notify_connect_status
;
4223 el
->handler
[BRCMF_E_DISASSOC_IND
] = brcmf_notify_connect_status
;
4224 el
->handler
[BRCMF_E_ASSOC_IND
] = brcmf_notify_connect_status
;
4225 el
->handler
[BRCMF_E_REASSOC_IND
] = brcmf_notify_connect_status
;
4226 el
->handler
[BRCMF_E_ROAM
] = brcmf_notify_roaming_status
;
4227 el
->handler
[BRCMF_E_MIC_ERROR
] = brcmf_notify_mic_status
;
4228 el
->handler
[BRCMF_E_SET_SSID
] = brcmf_notify_connect_status
;
4229 el
->handler
[BRCMF_E_PFN_NET_FOUND
] = brcmf_notify_sched_scan_results
;
4232 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4236 kfree(cfg
->escan_ioctl_buf
);
4237 cfg
->escan_ioctl_buf
= NULL
;
4238 kfree(cfg
->extra_buf
);
4239 cfg
->extra_buf
= NULL
;
4240 kfree(cfg
->pmk_list
);
4241 cfg
->pmk_list
= NULL
;
4244 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4246 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4248 goto init_priv_mem_out
;
4249 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4250 if (!cfg
->escan_ioctl_buf
)
4251 goto init_priv_mem_out
;
4252 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4253 if (!cfg
->extra_buf
)
4254 goto init_priv_mem_out
;
4255 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4257 goto init_priv_mem_out
;
4262 brcmf_deinit_priv_mem(cfg
);
4268 * retrieve first queued event from head
4271 static struct brcmf_cfg80211_event_q
*brcmf_deq_event(
4272 struct brcmf_cfg80211_info
*cfg
)
4274 struct brcmf_cfg80211_event_q
*e
= NULL
;
4276 spin_lock_irq(&cfg
->evt_q_lock
);
4277 if (!list_empty(&cfg
->evt_q_list
)) {
4278 e
= list_first_entry(&cfg
->evt_q_list
,
4279 struct brcmf_cfg80211_event_q
, evt_q_list
);
4280 list_del(&e
->evt_q_list
);
4282 spin_unlock_irq(&cfg
->evt_q_lock
);
4288 * push event to tail of the queue
4290 * remark: this function may not sleep as it is called in atomic context.
4294 brcmf_enq_event(struct brcmf_cfg80211_info
*cfg
, u32 event
,
4295 const struct brcmf_event_msg
*msg
, void *data
)
4297 struct brcmf_cfg80211_event_q
*e
;
4303 total_len
= sizeof(struct brcmf_cfg80211_event_q
);
4305 data_len
= be32_to_cpu(msg
->datalen
);
4308 total_len
+= data_len
;
4309 e
= kzalloc(total_len
, GFP_ATOMIC
);
4314 memcpy(&e
->emsg
, msg
, sizeof(struct brcmf_event_msg
));
4316 memcpy(&e
->edata
, data
, data_len
);
4318 spin_lock_irqsave(&cfg
->evt_q_lock
, flags
);
4319 list_add_tail(&e
->evt_q_list
, &cfg
->evt_q_list
);
4320 spin_unlock_irqrestore(&cfg
->evt_q_lock
, flags
);
4325 static void brcmf_put_event(struct brcmf_cfg80211_event_q
*e
)
4330 static void brcmf_cfg80211_event_handler(struct work_struct
*work
)
4332 struct brcmf_cfg80211_info
*cfg
=
4333 container_of(work
, struct brcmf_cfg80211_info
,
4335 struct brcmf_cfg80211_event_q
*e
;
4337 e
= brcmf_deq_event(cfg
);
4339 WL_ERR("event queue empty...\n");
4344 WL_INFO("event type (%d)\n", e
->etype
);
4345 if (cfg
->el
.handler
[e
->etype
])
4346 cfg
->el
.handler
[e
->etype
](cfg
,
4348 &e
->emsg
, e
->edata
);
4350 WL_INFO("Unknown Event (%d): ignoring\n", e
->etype
);
4352 } while ((e
= brcmf_deq_event(cfg
)));
4356 static void brcmf_init_eq(struct brcmf_cfg80211_info
*cfg
)
4358 spin_lock_init(&cfg
->evt_q_lock
);
4359 INIT_LIST_HEAD(&cfg
->evt_q_list
);
4362 static void brcmf_flush_eq(struct brcmf_cfg80211_info
*cfg
)
4364 struct brcmf_cfg80211_event_q
*e
;
4366 spin_lock_irq(&cfg
->evt_q_lock
);
4367 while (!list_empty(&cfg
->evt_q_list
)) {
4368 e
= list_first_entry(&cfg
->evt_q_list
,
4369 struct brcmf_cfg80211_event_q
, evt_q_list
);
4370 list_del(&e
->evt_q_list
);
4373 spin_unlock_irq(&cfg
->evt_q_lock
);
4376 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4380 cfg
->scan_request
= NULL
;
4381 cfg
->pwr_save
= true;
4382 cfg
->roam_on
= true; /* roam on & off switch.
4383 we enable roam per default */
4384 cfg
->active_scan
= true; /* we do active scan for
4385 specific scan per default */
4386 cfg
->dongle_up
= false; /* dongle is not up yet */
4388 err
= brcmf_init_priv_mem(cfg
);
4391 INIT_WORK(&cfg
->event_work
, brcmf_cfg80211_event_handler
);
4392 brcmf_init_eloop_handler(&cfg
->el
);
4393 mutex_init(&cfg
->usr_sync
);
4394 brcmf_init_escan(cfg
);
4395 brcmf_init_conf(cfg
->conf
);
4396 brcmf_link_down(cfg
);
4401 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4403 cancel_work_sync(&cfg
->event_work
);
4404 cfg
->dongle_up
= false; /* dongle down */
4405 brcmf_flush_eq(cfg
);
4406 brcmf_link_down(cfg
);
4407 brcmf_abort_scanning(cfg
);
4408 brcmf_deinit_priv_mem(cfg
);
4411 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
)
4413 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4414 struct device
*busdev
= drvr
->dev
;
4415 struct brcmf_cfg80211_info
*cfg
;
4416 struct wiphy
*wiphy
;
4417 struct brcmf_cfg80211_vif
*vif
;
4418 struct brcmf_if
*ifp
;
4422 WL_ERR("ndev is invalid\n");
4426 ifp
= netdev_priv(ndev
);
4427 wiphy
= brcmf_setup_wiphy(busdev
);
4431 cfg
= wiphy_priv(wiphy
);
4434 INIT_LIST_HEAD(&cfg
->vif_list
);
4436 vif
= brcmf_alloc_vif(cfg
, ndev
, WL_MODE_BSS
, false);
4442 err
= wl_init_priv(cfg
);
4444 WL_ERR("Failed to init iwm_priv (%d)\n", err
);
4445 goto cfg80211_attach_out
;
4451 cfg80211_attach_out
:
4452 brcmf_free_vif(vif
);
4456 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4458 struct brcmf_cfg80211_vif
*vif
;
4459 struct brcmf_cfg80211_vif
*tmp
;
4461 wl_deinit_priv(cfg
);
4462 list_for_each_entry_safe(vif
, tmp
, &cfg
->vif_list
, list
) {
4463 brcmf_free_vif(vif
);
4468 brcmf_cfg80211_event(struct net_device
*ndev
,
4469 const struct brcmf_event_msg
*e
, void *data
)
4471 u32 event_type
= be32_to_cpu(e
->event_type
);
4472 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
4474 if (!brcmf_enq_event(cfg
, event_type
, e
, data
))
4475 schedule_work(&cfg
->event_work
);
4478 static s32
brcmf_dongle_eventmsg(struct net_device
*ndev
)
4480 s8 eventmask
[BRCMF_EVENTING_MASK_LEN
];
4483 WL_TRACE("Enter\n");
4485 /* Setup event_msgs */
4486 err
= brcmf_fil_iovar_data_get(netdev_priv(ndev
), "event_msgs",
4487 eventmask
, BRCMF_EVENTING_MASK_LEN
);
4489 WL_ERR("Get event_msgs error (%d)\n", err
);
4490 goto dongle_eventmsg_out
;
4493 setbit(eventmask
, BRCMF_E_SET_SSID
);
4494 setbit(eventmask
, BRCMF_E_ROAM
);
4495 setbit(eventmask
, BRCMF_E_PRUNE
);
4496 setbit(eventmask
, BRCMF_E_AUTH
);
4497 setbit(eventmask
, BRCMF_E_REASSOC
);
4498 setbit(eventmask
, BRCMF_E_REASSOC_IND
);
4499 setbit(eventmask
, BRCMF_E_DEAUTH_IND
);
4500 setbit(eventmask
, BRCMF_E_DISASSOC_IND
);
4501 setbit(eventmask
, BRCMF_E_DISASSOC
);
4502 setbit(eventmask
, BRCMF_E_JOIN
);
4503 setbit(eventmask
, BRCMF_E_ASSOC_IND
);
4504 setbit(eventmask
, BRCMF_E_PSK_SUP
);
4505 setbit(eventmask
, BRCMF_E_LINK
);
4506 setbit(eventmask
, BRCMF_E_NDIS_LINK
);
4507 setbit(eventmask
, BRCMF_E_MIC_ERROR
);
4508 setbit(eventmask
, BRCMF_E_PMKID_CACHE
);
4509 setbit(eventmask
, BRCMF_E_TXFAIL
);
4510 setbit(eventmask
, BRCMF_E_JOIN_START
);
4511 setbit(eventmask
, BRCMF_E_ESCAN_RESULT
);
4512 setbit(eventmask
, BRCMF_E_PFN_NET_FOUND
);
4514 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "event_msgs",
4515 eventmask
, BRCMF_EVENTING_MASK_LEN
);
4517 WL_ERR("Set event_msgs error (%d)\n", err
);
4518 goto dongle_eventmsg_out
;
4521 dongle_eventmsg_out
:
4527 brcmf_dongle_roam(struct net_device
*ndev
, u32 roamvar
, u32 bcn_timeout
)
4529 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4531 __le32 roamtrigger
[2];
4532 __le32 roam_delta
[2];
4535 * Setup timeout if Beacons are lost and roam is
4536 * off to report link down
4539 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
4541 WL_ERR("bcn_timeout error (%d)\n", err
);
4542 goto dongle_rom_out
;
4547 * Enable/Disable built-in roaming to allow supplicant
4548 * to take care of roaming
4550 WL_INFO("Internal Roaming = %s\n", roamvar
? "Off" : "On");
4551 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
4553 WL_ERR("roam_off error (%d)\n", err
);
4554 goto dongle_rom_out
;
4557 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
4558 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4559 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
4560 (void *)roamtrigger
, sizeof(roamtrigger
));
4562 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
4563 goto dongle_rom_out
;
4566 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
4567 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4568 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
4569 (void *)roam_delta
, sizeof(roam_delta
));
4571 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err
);
4572 goto dongle_rom_out
;
4580 brcmf_dongle_scantime(struct net_device
*ndev
, s32 scan_assoc_time
,
4581 s32 scan_unassoc_time
, s32 scan_passive_time
)
4583 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4586 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
4589 if (err
== -EOPNOTSUPP
)
4590 WL_INFO("Scan assoc time is not supported\n");
4592 WL_ERR("Scan assoc time error (%d)\n", err
);
4593 goto dongle_scantime_out
;
4595 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
4598 if (err
== -EOPNOTSUPP
)
4599 WL_INFO("Scan unassoc time is not supported\n");
4601 WL_ERR("Scan unassoc time error (%d)\n", err
);
4602 goto dongle_scantime_out
;
4605 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
4608 if (err
== -EOPNOTSUPP
)
4609 WL_INFO("Scan passive time is not supported\n");
4611 WL_ERR("Scan passive time error (%d)\n", err
);
4612 goto dongle_scantime_out
;
4615 dongle_scantime_out
:
4619 static s32
wl_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
4621 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4622 struct wiphy
*wiphy
;
4627 err
= brcmf_fil_cmd_data_get(ifp
, BRCM_GET_PHYLIST
,
4628 &phy_list
, sizeof(phy_list
));
4630 WL_ERR("error (%d)\n", err
);
4634 phy
= ((char *)&phy_list
)[0];
4635 WL_INFO("%c phy\n", phy
);
4636 if (phy
== 'n' || phy
== 'a') {
4637 wiphy
= cfg_to_wiphy(cfg
);
4638 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4644 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
4646 return wl_update_wiphybands(cfg
);
4649 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
4651 struct net_device
*ndev
;
4652 struct wireless_dev
*wdev
;
4659 ndev
= cfg_to_ndev(cfg
);
4660 wdev
= ndev
->ieee80211_ptr
;
4662 brcmf_dongle_scantime(ndev
, WL_SCAN_CHANNEL_TIME
,
4663 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
4665 err
= brcmf_dongle_eventmsg(ndev
);
4667 goto default_conf_out
;
4669 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
4670 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PM
,
4673 goto default_conf_out
;
4674 WL_INFO("power save set to %s\n",
4675 (power_mode
? "enabled" : "disabled"));
4677 err
= brcmf_dongle_roam(ndev
, (cfg
->roam_on
? 0 : 1),
4680 goto default_conf_out
;
4681 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
4683 if (err
&& err
!= -EINPROGRESS
)
4684 goto default_conf_out
;
4685 err
= brcmf_dongle_probecap(cfg
);
4687 goto default_conf_out
;
4689 /* -EINPROGRESS: Call commit handler */
4693 cfg
->dongle_up
= true;
4699 static s32
__brcmf_cfg80211_up(struct brcmf_cfg80211_info
*cfg
)
4701 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4703 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4705 return brcmf_config_dongle(cfg
);
4708 static s32
__brcmf_cfg80211_down(struct brcmf_cfg80211_info
*cfg
)
4710 struct net_device
*ndev
= cfg_to_ndev(cfg
);
4711 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4714 * While going down, if associated with AP disassociate
4715 * from AP to save power
4717 if ((test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
) ||
4718 test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) &&
4719 check_vif_up(ifp
->vif
)) {
4720 WL_INFO("Disassociating from AP");
4721 brcmf_link_down(cfg
);
4723 /* Make sure WPA_Supplicant receives all the event
4724 generated due to DISASSOC call to the fw to keep
4725 the state fw and WPA_Supplicant state consistent
4730 brcmf_abort_scanning(cfg
);
4731 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
4736 s32
brcmf_cfg80211_up(struct brcmf_cfg80211_info
*cfg
)
4740 mutex_lock(&cfg
->usr_sync
);
4741 err
= __brcmf_cfg80211_up(cfg
);
4742 mutex_unlock(&cfg
->usr_sync
);
4747 s32
brcmf_cfg80211_down(struct brcmf_cfg80211_info
*cfg
)
4751 mutex_lock(&cfg
->usr_sync
);
4752 err
= __brcmf_cfg80211_down(cfg
);
4753 mutex_unlock(&cfg
->usr_sync
);