2 * Copyright (c) 2010 Broadcom Corporation
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <net/cfg80211.h>
22 #include <net/netlink.h>
24 #include <brcmu_utils.h>
26 #include <brcmu_wifi.h>
29 #include "fwil_types.h"
31 #include "wl_cfg80211.h"
34 #define BRCMF_SCAN_IE_LEN_MAX 2048
35 #define BRCMF_PNO_VERSION 2
36 #define BRCMF_PNO_TIME 30
37 #define BRCMF_PNO_REPEAT 4
38 #define BRCMF_PNO_FREQ_EXPO_MAX 3
39 #define BRCMF_PNO_MAX_PFN_COUNT 16
40 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
41 #define BRCMF_PNO_HIDDEN_BIT 2
42 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
43 #define BRCMF_PNO_SCAN_COMPLETE 1
44 #define BRCMF_PNO_SCAN_INCOMPLETE 0
46 #define BRCMF_IFACE_MAX_CNT 3
48 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
49 #define WPA_OUI_TYPE 1
50 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
51 #define WME_OUI_TYPE 2
52 #define WPS_OUI_TYPE 4
54 #define VS_IE_FIXED_HDR_LEN 6
55 #define WPA_IE_VERSION_LEN 2
56 #define WPA_IE_MIN_OUI_LEN 4
57 #define WPA_IE_SUITE_COUNT_LEN 2
59 #define WPA_CIPHER_NONE 0 /* None */
60 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
61 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
62 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
63 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
65 #define RSN_AKM_NONE 0 /* None (IBSS) */
66 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
67 #define RSN_AKM_PSK 2 /* Pre-shared Key */
68 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
69 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
71 #define VNDR_IE_CMD_LEN 4 /* length of the set command
72 * string :"add", "del" (+ NUL)
74 #define VNDR_IE_COUNT_OFFSET 4
75 #define VNDR_IE_PKTFLAG_OFFSET 8
76 #define VNDR_IE_VSIE_OFFSET 12
77 #define VNDR_IE_HDR_SIZE 12
78 #define VNDR_IE_PARSE_LIMIT 5
80 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
81 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
83 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
84 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
85 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
87 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
88 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
90 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
92 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
93 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
100 #define CHAN2G(_channel, _freq, _flags) { \
101 .band = IEEE80211_BAND_2GHZ, \
102 .center_freq = (_freq), \
103 .hw_value = (_channel), \
105 .max_antenna_gain = 0, \
109 #define CHAN5G(_channel, _flags) { \
110 .band = IEEE80211_BAND_5GHZ, \
111 .center_freq = 5000 + (5 * (_channel)), \
112 .hw_value = (_channel), \
114 .max_antenna_gain = 0, \
118 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
119 #define RATETAB_ENT(_rateid, _flags) \
121 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
122 .hw_value = (_rateid), \
126 static struct ieee80211_rate __wl_rates
[] = {
127 RATETAB_ENT(BRCM_RATE_1M
, 0),
128 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
129 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
130 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
131 RATETAB_ENT(BRCM_RATE_6M
, 0),
132 RATETAB_ENT(BRCM_RATE_9M
, 0),
133 RATETAB_ENT(BRCM_RATE_12M
, 0),
134 RATETAB_ENT(BRCM_RATE_18M
, 0),
135 RATETAB_ENT(BRCM_RATE_24M
, 0),
136 RATETAB_ENT(BRCM_RATE_36M
, 0),
137 RATETAB_ENT(BRCM_RATE_48M
, 0),
138 RATETAB_ENT(BRCM_RATE_54M
, 0),
141 #define wl_a_rates (__wl_rates + 4)
142 #define wl_a_rates_size 8
143 #define wl_g_rates (__wl_rates + 0)
144 #define wl_g_rates_size 12
146 static struct ieee80211_channel __wl_2ghz_channels
[] = {
163 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
164 CHAN5G(34, 0), CHAN5G(36, 0),
165 CHAN5G(38, 0), CHAN5G(40, 0),
166 CHAN5G(42, 0), CHAN5G(44, 0),
167 CHAN5G(46, 0), CHAN5G(48, 0),
168 CHAN5G(52, 0), CHAN5G(56, 0),
169 CHAN5G(60, 0), CHAN5G(64, 0),
170 CHAN5G(100, 0), CHAN5G(104, 0),
171 CHAN5G(108, 0), CHAN5G(112, 0),
172 CHAN5G(116, 0), CHAN5G(120, 0),
173 CHAN5G(124, 0), CHAN5G(128, 0),
174 CHAN5G(132, 0), CHAN5G(136, 0),
175 CHAN5G(140, 0), CHAN5G(149, 0),
176 CHAN5G(153, 0), CHAN5G(157, 0),
177 CHAN5G(161, 0), CHAN5G(165, 0),
178 CHAN5G(184, 0), CHAN5G(188, 0),
179 CHAN5G(192, 0), CHAN5G(196, 0),
180 CHAN5G(200, 0), CHAN5G(204, 0),
181 CHAN5G(208, 0), CHAN5G(212, 0),
185 static struct ieee80211_channel __wl_5ghz_n_channels
[] = {
186 CHAN5G(32, 0), CHAN5G(34, 0),
187 CHAN5G(36, 0), CHAN5G(38, 0),
188 CHAN5G(40, 0), CHAN5G(42, 0),
189 CHAN5G(44, 0), CHAN5G(46, 0),
190 CHAN5G(48, 0), CHAN5G(50, 0),
191 CHAN5G(52, 0), CHAN5G(54, 0),
192 CHAN5G(56, 0), CHAN5G(58, 0),
193 CHAN5G(60, 0), CHAN5G(62, 0),
194 CHAN5G(64, 0), CHAN5G(66, 0),
195 CHAN5G(68, 0), CHAN5G(70, 0),
196 CHAN5G(72, 0), CHAN5G(74, 0),
197 CHAN5G(76, 0), CHAN5G(78, 0),
198 CHAN5G(80, 0), CHAN5G(82, 0),
199 CHAN5G(84, 0), CHAN5G(86, 0),
200 CHAN5G(88, 0), CHAN5G(90, 0),
201 CHAN5G(92, 0), CHAN5G(94, 0),
202 CHAN5G(96, 0), CHAN5G(98, 0),
203 CHAN5G(100, 0), CHAN5G(102, 0),
204 CHAN5G(104, 0), CHAN5G(106, 0),
205 CHAN5G(108, 0), CHAN5G(110, 0),
206 CHAN5G(112, 0), CHAN5G(114, 0),
207 CHAN5G(116, 0), CHAN5G(118, 0),
208 CHAN5G(120, 0), CHAN5G(122, 0),
209 CHAN5G(124, 0), CHAN5G(126, 0),
210 CHAN5G(128, 0), CHAN5G(130, 0),
211 CHAN5G(132, 0), CHAN5G(134, 0),
212 CHAN5G(136, 0), CHAN5G(138, 0),
213 CHAN5G(140, 0), CHAN5G(142, 0),
214 CHAN5G(144, 0), CHAN5G(145, 0),
215 CHAN5G(146, 0), CHAN5G(147, 0),
216 CHAN5G(148, 0), CHAN5G(149, 0),
217 CHAN5G(150, 0), CHAN5G(151, 0),
218 CHAN5G(152, 0), CHAN5G(153, 0),
219 CHAN5G(154, 0), CHAN5G(155, 0),
220 CHAN5G(156, 0), CHAN5G(157, 0),
221 CHAN5G(158, 0), CHAN5G(159, 0),
222 CHAN5G(160, 0), CHAN5G(161, 0),
223 CHAN5G(162, 0), CHAN5G(163, 0),
224 CHAN5G(164, 0), CHAN5G(165, 0),
225 CHAN5G(166, 0), CHAN5G(168, 0),
226 CHAN5G(170, 0), CHAN5G(172, 0),
227 CHAN5G(174, 0), CHAN5G(176, 0),
228 CHAN5G(178, 0), CHAN5G(180, 0),
229 CHAN5G(182, 0), CHAN5G(184, 0),
230 CHAN5G(186, 0), CHAN5G(188, 0),
231 CHAN5G(190, 0), CHAN5G(192, 0),
232 CHAN5G(194, 0), CHAN5G(196, 0),
233 CHAN5G(198, 0), CHAN5G(200, 0),
234 CHAN5G(202, 0), CHAN5G(204, 0),
235 CHAN5G(206, 0), CHAN5G(208, 0),
236 CHAN5G(210, 0), CHAN5G(212, 0),
237 CHAN5G(214, 0), CHAN5G(216, 0),
238 CHAN5G(218, 0), CHAN5G(220, 0),
239 CHAN5G(222, 0), CHAN5G(224, 0),
240 CHAN5G(226, 0), CHAN5G(228, 0),
243 static struct ieee80211_supported_band __wl_band_2ghz
= {
244 .band
= IEEE80211_BAND_2GHZ
,
245 .channels
= __wl_2ghz_channels
,
246 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
247 .bitrates
= wl_g_rates
,
248 .n_bitrates
= wl_g_rates_size
,
251 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
252 .band
= IEEE80211_BAND_5GHZ
,
253 .channels
= __wl_5ghz_a_channels
,
254 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
255 .bitrates
= wl_a_rates
,
256 .n_bitrates
= wl_a_rates_size
,
259 static struct ieee80211_supported_band __wl_band_5ghz_n
= {
260 .band
= IEEE80211_BAND_5GHZ
,
261 .channels
= __wl_5ghz_n_channels
,
262 .n_channels
= ARRAY_SIZE(__wl_5ghz_n_channels
),
263 .bitrates
= wl_a_rates
,
264 .n_bitrates
= wl_a_rates_size
,
267 static const u32 __wl_cipher_suites
[] = {
268 WLAN_CIPHER_SUITE_WEP40
,
269 WLAN_CIPHER_SUITE_WEP104
,
270 WLAN_CIPHER_SUITE_TKIP
,
271 WLAN_CIPHER_SUITE_CCMP
,
272 WLAN_CIPHER_SUITE_AES_CMAC
,
275 /* Vendor specific ie. id = 221, oui and type defines exact ie */
276 struct brcmf_vs_tlv
{
283 struct parsed_vndr_ie_info
{
285 u32 ie_len
; /* total length including id & length field */
286 struct brcmf_vs_tlv vndrie
;
289 struct parsed_vndr_ies
{
291 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
294 /* Quarter dBm units to mW
295 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
296 * Table is offset so the last entry is largest mW value that fits in
300 #define QDBM_OFFSET 153 /* Offset for first entry */
301 #define QDBM_TABLE_LEN 40 /* Table size */
303 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
304 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
306 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
308 /* Largest mW value that will round down to the last table entry,
309 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
310 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
311 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
313 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
315 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
316 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
317 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
318 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
319 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
320 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
321 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
324 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
327 int idx
= qdbm
- QDBM_OFFSET
;
329 if (idx
>= QDBM_TABLE_LEN
)
330 /* clamp to max u16 mW value */
333 /* scale the qdBm index up to the range of the table 0-40
334 * where an offset of 40 qdBm equals a factor of 10 mW.
341 /* return the mW value scaled down to the correct factor of 10,
342 * adding in factor/2 to get proper rounding.
344 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
347 static u8
brcmf_mw_to_qdbm(u16 mw
)
354 /* handle boundary case */
358 offset
= QDBM_OFFSET
;
360 /* move mw into the range of the table */
361 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
366 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
367 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
368 nqdBm_to_mW_map
[qdbm
]) / 2;
369 if (mw_uint
< boundary
)
378 u16
channel_to_chanspec(struct ieee80211_channel
*ch
)
382 chanspec
= ieee80211_frequency_to_channel(ch
->center_freq
);
383 chanspec
&= WL_CHANSPEC_CHAN_MASK
;
385 if (ch
->band
== IEEE80211_BAND_2GHZ
)
386 chanspec
|= WL_CHANSPEC_BAND_2G
;
388 chanspec
|= WL_CHANSPEC_BAND_5G
;
390 chanspec
|= WL_CHANSPEC_BW_20
;
391 chanspec
|= WL_CHANSPEC_CTL_SB_NONE
;
396 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
397 * triples, returning a pointer to the substring whose first element
400 struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
402 struct brcmf_tlv
*elt
;
405 elt
= (struct brcmf_tlv
*)buf
;
408 /* find tagged parameter */
409 while (totlen
>= TLV_HDR_LEN
) {
412 /* validate remaining totlen */
413 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
416 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
417 totlen
-= (len
+ TLV_HDR_LEN
);
423 /* Is any of the tlvs the expected entry? If
424 * not update the tlvs buffer pointer/length.
427 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
428 u8
*oui
, u32 oui_len
, u8 type
)
430 /* If the contents match the OUI and the type */
431 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
432 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
433 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
439 /* point to the next ie */
440 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
441 /* calculate the length of the rest of the buffer */
442 *tlvs_len
-= (int)(ie
- *tlvs
);
443 /* update the pointer to the start of the buffer */
449 static struct brcmf_vs_tlv
*
450 brcmf_find_wpaie(u8
*parse
, u32 len
)
452 struct brcmf_tlv
*ie
;
454 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
455 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
456 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
457 return (struct brcmf_vs_tlv
*)ie
;
462 static struct brcmf_vs_tlv
*
463 brcmf_find_wpsie(u8
*parse
, u32 len
)
465 struct brcmf_tlv
*ie
;
467 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
468 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
469 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
470 return (struct brcmf_vs_tlv
*)ie
;
476 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
477 struct brcmf_wsec_key_le
*key_le
)
479 key_le
->index
= cpu_to_le32(key
->index
);
480 key_le
->len
= cpu_to_le32(key
->len
);
481 key_le
->algo
= cpu_to_le32(key
->algo
);
482 key_le
->flags
= cpu_to_le32(key
->flags
);
483 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
484 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
485 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
486 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
487 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
491 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
494 struct brcmf_wsec_key_le key_le
;
496 convert_key_from_CPU(key
, &key_le
);
498 brcmf_netdev_wait_pend8021x(ndev
);
500 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
504 brcmf_err("wsec_key error (%d)\n", err
);
508 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
510 enum nl80211_iftype type
,
512 struct vif_params
*params
)
514 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
516 case NL80211_IFTYPE_ADHOC
:
517 case NL80211_IFTYPE_STATION
:
518 case NL80211_IFTYPE_AP
:
519 case NL80211_IFTYPE_AP_VLAN
:
520 case NL80211_IFTYPE_WDS
:
521 case NL80211_IFTYPE_MONITOR
:
522 case NL80211_IFTYPE_MESH_POINT
:
523 return ERR_PTR(-EOPNOTSUPP
);
524 case NL80211_IFTYPE_P2P_CLIENT
:
525 case NL80211_IFTYPE_P2P_GO
:
526 return brcmf_p2p_add_vif(wiphy
, name
, type
, flags
, params
);
527 case NL80211_IFTYPE_UNSPECIFIED
:
528 case NL80211_IFTYPE_P2P_DEVICE
:
530 return ERR_PTR(-EINVAL
);
534 void brcmf_set_mpc(struct net_device
*ndev
, int mpc
)
536 struct brcmf_if
*ifp
= netdev_priv(ndev
);
539 if (check_vif_up(ifp
->vif
)) {
540 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
542 brcmf_err("fail to set mpc\n");
545 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
550 brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
551 struct net_device
*ndev
,
552 bool aborted
, bool fw_abort
)
554 struct brcmf_scan_params_le params_le
;
555 struct cfg80211_scan_request
*scan_request
;
558 brcmf_dbg(SCAN
, "Enter\n");
560 /* clear scan request, because the FW abort can cause a second call */
561 /* to this functon and might cause a double cfg80211_scan_done */
562 scan_request
= cfg
->scan_request
;
563 cfg
->scan_request
= NULL
;
565 if (timer_pending(&cfg
->escan_timeout
))
566 del_timer_sync(&cfg
->escan_timeout
);
569 /* Do a scan abort to stop the driver's scan engine */
570 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
571 memset(¶ms_le
, 0, sizeof(params_le
));
572 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
573 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
574 params_le
.scan_type
= 0;
575 params_le
.channel_num
= cpu_to_le32(1);
576 params_le
.nprobes
= cpu_to_le32(1);
577 params_le
.active_time
= cpu_to_le32(-1);
578 params_le
.passive_time
= cpu_to_le32(-1);
579 params_le
.home_time
= cpu_to_le32(-1);
580 /* Scan is aborted by setting channel_list[0] to -1 */
581 params_le
.channel_list
[0] = cpu_to_le16(-1);
582 /* E-Scan (or anyother type) can be aborted by SCAN */
583 err
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), BRCMF_C_SCAN
,
584 ¶ms_le
, sizeof(params_le
));
586 brcmf_err("Scan abort failed\n");
589 * e-scan can be initiated by scheduled scan
590 * which takes precedence.
592 if (cfg
->sched_escan
) {
593 brcmf_dbg(SCAN
, "scheduled scan completed\n");
594 cfg
->sched_escan
= false;
596 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
597 brcmf_set_mpc(ndev
, 1);
598 } else if (scan_request
) {
599 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
600 aborted
? "Aborted" : "Done");
601 cfg80211_scan_done(scan_request
, aborted
);
602 brcmf_set_mpc(ndev
, 1);
604 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
605 brcmf_err("Scan complete while device not scanning\n");
613 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
615 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
616 struct net_device
*ndev
= wdev
->netdev
;
618 /* vif event pending in firmware */
619 if (brcmf_cfg80211_vif_event_armed(cfg
))
623 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
624 cfg
->escan_info
.ndev
== ndev
)
625 brcmf_notify_escan_complete(cfg
, ndev
, true,
628 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
631 switch (wdev
->iftype
) {
632 case NL80211_IFTYPE_ADHOC
:
633 case NL80211_IFTYPE_STATION
:
634 case NL80211_IFTYPE_AP
:
635 case NL80211_IFTYPE_AP_VLAN
:
636 case NL80211_IFTYPE_WDS
:
637 case NL80211_IFTYPE_MONITOR
:
638 case NL80211_IFTYPE_MESH_POINT
:
640 case NL80211_IFTYPE_P2P_CLIENT
:
641 case NL80211_IFTYPE_P2P_GO
:
642 return brcmf_p2p_del_vif(wiphy
, wdev
);
643 case NL80211_IFTYPE_UNSPECIFIED
:
644 case NL80211_IFTYPE_P2P_DEVICE
:
652 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
653 enum nl80211_iftype type
, u32
*flags
,
654 struct vif_params
*params
)
656 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
657 struct brcmf_if
*ifp
= netdev_priv(ndev
);
658 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
663 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
666 case NL80211_IFTYPE_MONITOR
:
667 case NL80211_IFTYPE_WDS
:
668 brcmf_err("type (%d) : currently we do not support this type\n",
671 case NL80211_IFTYPE_ADHOC
:
672 vif
->mode
= WL_MODE_IBSS
;
675 case NL80211_IFTYPE_STATION
:
676 vif
->mode
= WL_MODE_BSS
;
679 case NL80211_IFTYPE_AP
:
680 case NL80211_IFTYPE_P2P_GO
:
681 vif
->mode
= WL_MODE_AP
;
690 if (type
== NL80211_IFTYPE_P2P_GO
) {
691 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
692 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
695 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
696 brcmf_dbg(INFO
, "IF Type = AP\n");
699 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
701 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
705 brcmf_dbg(INFO
, "IF Type = %s\n", (vif
->mode
== WL_MODE_IBSS
) ?
708 ndev
->ieee80211_ptr
->iftype
= type
;
711 brcmf_dbg(TRACE
, "Exit\n");
716 static void brcmf_escan_prep(struct brcmf_scan_params_le
*params_le
,
717 struct cfg80211_scan_request
*request
)
725 struct brcmf_ssid_le ssid_le
;
727 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
728 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
729 params_le
->scan_type
= 0;
730 params_le
->channel_num
= 0;
731 params_le
->nprobes
= cpu_to_le32(-1);
732 params_le
->active_time
= cpu_to_le32(-1);
733 params_le
->passive_time
= cpu_to_le32(-1);
734 params_le
->home_time
= cpu_to_le32(-1);
735 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
737 /* if request is null exit so it will be all channel broadcast scan */
741 n_ssids
= request
->n_ssids
;
742 n_channels
= request
->n_channels
;
743 /* Copy channel array if applicable */
744 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
746 if (n_channels
> 0) {
747 for (i
= 0; i
< n_channels
; i
++) {
748 chanspec
= channel_to_chanspec(request
->channels
[i
]);
749 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
750 request
->channels
[i
]->hw_value
, chanspec
);
751 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
754 brcmf_dbg(SCAN
, "Scanning all channels\n");
756 /* Copy ssid array if applicable */
757 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
759 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
760 n_channels
* sizeof(u16
);
761 offset
= roundup(offset
, sizeof(u32
));
762 ptr
= (char *)params_le
+ offset
;
763 for (i
= 0; i
< n_ssids
; i
++) {
764 memset(&ssid_le
, 0, sizeof(ssid_le
));
766 cpu_to_le32(request
->ssids
[i
].ssid_len
);
767 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
768 request
->ssids
[i
].ssid_len
);
769 if (!ssid_le
.SSID_len
)
770 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
772 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
773 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
774 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
775 ptr
+= sizeof(ssid_le
);
778 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
779 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
780 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
781 params_le
->ssid_le
.SSID
,
782 request
->ssids
->ssid_len
);
783 params_le
->ssid_le
.SSID_len
=
784 cpu_to_le32(request
->ssids
->ssid_len
);
785 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
786 request
->ssids
->ssid_len
);
789 /* Adding mask to channel numbers */
790 params_le
->channel_num
=
791 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
792 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
796 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct net_device
*ndev
,
797 struct cfg80211_scan_request
*request
, u16 action
)
799 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
800 offsetof(struct brcmf_escan_params_le
, params_le
);
801 struct brcmf_escan_params_le
*params
;
804 brcmf_dbg(SCAN
, "E-SCAN START\n");
806 if (request
!= NULL
) {
807 /* Allocate space for populating ssids in struct */
808 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
810 /* Allocate space for populating ssids in struct */
811 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
814 params
= kzalloc(params_size
, GFP_KERNEL
);
819 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
820 brcmf_escan_prep(¶ms
->params_le
, request
);
821 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
822 params
->action
= cpu_to_le16(action
);
823 params
->sync_id
= cpu_to_le16(0x1234);
825 err
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "escan",
826 params
, params_size
);
829 brcmf_dbg(INFO
, "system busy : escan canceled\n");
831 brcmf_err("error (%d)\n", err
);
840 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
841 struct net_device
*ndev
, struct cfg80211_scan_request
*request
)
845 struct brcmf_scan_results
*results
;
846 struct escan_info
*escan
= &cfg
->escan_info
;
848 brcmf_dbg(SCAN
, "Enter\n");
850 escan
->wiphy
= wiphy
;
851 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
852 passive_scan
= cfg
->active_scan
? 0 : 1;
853 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), BRCMF_C_SET_PASSIVE_SCAN
,
856 brcmf_err("error (%d)\n", err
);
859 brcmf_set_mpc(ndev
, 0);
860 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
861 results
->version
= 0;
863 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
865 err
= escan
->run(cfg
, ndev
, request
, WL_ESCAN_ACTION_START
);
867 brcmf_set_mpc(ndev
, 1);
872 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct net_device
*ndev
,
873 struct cfg80211_scan_request
*request
,
874 struct cfg80211_ssid
*this_ssid
)
876 struct brcmf_if
*ifp
= netdev_priv(ndev
);
877 struct brcmf_cfg80211_info
*cfg
= ndev_to_cfg(ndev
);
878 struct cfg80211_ssid
*ssids
;
879 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
886 brcmf_dbg(SCAN
, "START ESCAN\n");
888 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
889 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
892 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
893 brcmf_err("Scanning being aborted: status (%lu)\n",
897 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
898 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
902 /* If scan req comes for p2p0, send it over primary I/F */
903 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
) {
904 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
908 /* Arm scan timeout timer */
909 mod_timer(&cfg
->escan_timeout
, jiffies
+
910 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
915 ssids
= request
->ssids
;
919 /* we don't do escan in ibss */
923 cfg
->scan_request
= request
;
924 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
926 cfg
->escan_info
.run
= brcmf_run_escan
;
927 err
= brcmf_p2p_scan_prep(wiphy
, request
, ifp
->vif
);
931 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
935 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
936 ssids
->ssid
, ssids
->ssid_len
);
937 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
938 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
939 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
942 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
943 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
946 brcmf_dbg(SCAN
, "Broadcast scan\n");
948 passive_scan
= cfg
->active_scan
? 0 : 1;
949 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
952 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
955 brcmf_set_mpc(ndev
, 0);
956 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
957 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
960 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
963 brcmf_err("WLC_SCAN error (%d)\n", err
);
965 brcmf_set_mpc(ndev
, 1);
973 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
974 if (timer_pending(&cfg
->escan_timeout
))
975 del_timer_sync(&cfg
->escan_timeout
);
976 cfg
->scan_request
= NULL
;
981 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
983 struct net_device
*ndev
= request
->wdev
->netdev
;
986 brcmf_dbg(TRACE
, "Enter\n");
988 if (!check_vif_up(container_of(request
->wdev
,
989 struct brcmf_cfg80211_vif
, wdev
)))
992 err
= brcmf_cfg80211_escan(wiphy
, ndev
, request
, NULL
);
995 brcmf_err("scan error (%d)\n", err
);
997 brcmf_dbg(TRACE
, "Exit\n");
1001 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1005 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1008 brcmf_err("Error (%d)\n", err
);
1013 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1017 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1020 brcmf_err("Error (%d)\n", err
);
1025 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1028 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1030 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1032 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1038 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1040 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1041 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1042 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1045 brcmf_dbg(TRACE
, "Enter\n");
1046 if (!check_vif_up(ifp
->vif
))
1049 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1050 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1051 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1052 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1056 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1057 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1058 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1059 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1063 if (changed
& WIPHY_PARAM_RETRY_LONG
1064 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1065 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1066 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1070 if (changed
& WIPHY_PARAM_RETRY_SHORT
1071 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1072 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1073 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1079 brcmf_dbg(TRACE
, "Exit\n");
1083 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1085 memset(prof
, 0, sizeof(*prof
));
1088 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
1092 brcmf_dbg(TRACE
, "Enter\n");
1094 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1095 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1096 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1097 BRCMF_C_DISASSOC
, NULL
, 0);
1099 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1100 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
1102 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1103 brcmf_dbg(TRACE
, "Exit\n");
1107 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1108 struct cfg80211_ibss_params
*params
)
1110 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1111 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1112 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1113 struct brcmf_join_params join_params
;
1114 size_t join_params_size
= 0;
1120 brcmf_dbg(TRACE
, "Enter\n");
1121 if (!check_vif_up(ifp
->vif
))
1125 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1127 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1131 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1134 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1136 brcmf_dbg(CONN
, "No BSSID specified\n");
1138 if (params
->chandef
.chan
)
1139 brcmf_dbg(CONN
, "channel: %d\n",
1140 params
->chandef
.chan
->center_freq
);
1142 brcmf_dbg(CONN
, "no channel specified\n");
1144 if (params
->channel_fixed
)
1145 brcmf_dbg(CONN
, "fixed channel required\n");
1147 brcmf_dbg(CONN
, "no fixed channel required\n");
1149 if (params
->ie
&& params
->ie_len
)
1150 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1152 brcmf_dbg(CONN
, "no ie specified\n");
1154 if (params
->beacon_interval
)
1155 brcmf_dbg(CONN
, "beacon interval: %d\n",
1156 params
->beacon_interval
);
1158 brcmf_dbg(CONN
, "no beacon interval specified\n");
1160 if (params
->basic_rates
)
1161 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1163 brcmf_dbg(CONN
, "no basic rates specified\n");
1165 if (params
->privacy
)
1166 brcmf_dbg(CONN
, "privacy required\n");
1168 brcmf_dbg(CONN
, "no privacy required\n");
1170 /* Configure Privacy for starter */
1171 if (params
->privacy
)
1172 wsec
|= WEP_ENABLED
;
1174 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1176 brcmf_err("wsec failed (%d)\n", err
);
1180 /* Configure Beacon Interval for starter */
1181 if (params
->beacon_interval
)
1182 bcnprd
= params
->beacon_interval
;
1186 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1188 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1192 /* Configure required join parameter */
1193 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1196 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1197 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1198 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1199 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1200 join_params_size
= sizeof(join_params
.ssid_le
);
1203 if (params
->bssid
) {
1204 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1205 join_params_size
= sizeof(join_params
.ssid_le
) +
1206 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1207 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1209 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1210 memset(profile
->bssid
, 0, ETH_ALEN
);
1214 if (params
->chandef
.chan
) {
1218 ieee80211_frequency_to_channel(
1219 params
->chandef
.chan
->center_freq
);
1220 if (params
->channel_fixed
) {
1221 /* adding chanspec */
1222 chanspec
= channel_to_chanspec(params
->chandef
.chan
);
1223 join_params
.params_le
.chanspec_list
[0] =
1224 cpu_to_le16(chanspec
);
1225 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1226 join_params_size
+= sizeof(join_params
.params_le
);
1229 /* set channel for starter */
1230 target_channel
= cfg
->channel
;
1231 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1234 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1240 cfg
->ibss_starter
= false;
1243 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1244 &join_params
, join_params_size
);
1246 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1252 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1253 brcmf_dbg(TRACE
, "Exit\n");
1258 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1260 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1263 brcmf_dbg(TRACE
, "Enter\n");
1264 if (!check_vif_up(ifp
->vif
))
1267 brcmf_link_down(ifp
->vif
);
1269 brcmf_dbg(TRACE
, "Exit\n");
1274 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1275 struct cfg80211_connect_params
*sme
)
1277 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1278 struct brcmf_cfg80211_security
*sec
;
1282 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1283 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1284 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1285 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1287 val
= WPA_AUTH_DISABLED
;
1288 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1289 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1291 brcmf_err("set wpa_auth failed (%d)\n", err
);
1294 sec
= &profile
->sec
;
1295 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1299 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1300 struct cfg80211_connect_params
*sme
)
1302 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1303 struct brcmf_cfg80211_security
*sec
;
1307 switch (sme
->auth_type
) {
1308 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1310 brcmf_dbg(CONN
, "open system\n");
1312 case NL80211_AUTHTYPE_SHARED_KEY
:
1314 brcmf_dbg(CONN
, "shared key\n");
1316 case NL80211_AUTHTYPE_AUTOMATIC
:
1318 brcmf_dbg(CONN
, "automatic\n");
1320 case NL80211_AUTHTYPE_NETWORK_EAP
:
1321 brcmf_dbg(CONN
, "network eap\n");
1324 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1328 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1330 brcmf_err("set auth failed (%d)\n", err
);
1333 sec
= &profile
->sec
;
1334 sec
->auth_type
= sme
->auth_type
;
1339 brcmf_set_set_cipher(struct net_device
*ndev
,
1340 struct cfg80211_connect_params
*sme
)
1342 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1343 struct brcmf_cfg80211_security
*sec
;
1348 if (sme
->crypto
.n_ciphers_pairwise
) {
1349 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1350 case WLAN_CIPHER_SUITE_WEP40
:
1351 case WLAN_CIPHER_SUITE_WEP104
:
1354 case WLAN_CIPHER_SUITE_TKIP
:
1355 pval
= TKIP_ENABLED
;
1357 case WLAN_CIPHER_SUITE_CCMP
:
1360 case WLAN_CIPHER_SUITE_AES_CMAC
:
1364 brcmf_err("invalid cipher pairwise (%d)\n",
1365 sme
->crypto
.ciphers_pairwise
[0]);
1369 if (sme
->crypto
.cipher_group
) {
1370 switch (sme
->crypto
.cipher_group
) {
1371 case WLAN_CIPHER_SUITE_WEP40
:
1372 case WLAN_CIPHER_SUITE_WEP104
:
1375 case WLAN_CIPHER_SUITE_TKIP
:
1376 gval
= TKIP_ENABLED
;
1378 case WLAN_CIPHER_SUITE_CCMP
:
1381 case WLAN_CIPHER_SUITE_AES_CMAC
:
1385 brcmf_err("invalid cipher group (%d)\n",
1386 sme
->crypto
.cipher_group
);
1391 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1392 /* In case of privacy, but no security and WPS then simulate */
1393 /* setting AES. WPS-2.0 allows no security */
1394 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1397 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1399 brcmf_err("error (%d)\n", err
);
1403 sec
= &profile
->sec
;
1404 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1405 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1411 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1413 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1414 struct brcmf_cfg80211_security
*sec
;
1418 if (sme
->crypto
.n_akm_suites
) {
1419 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
),
1422 brcmf_err("could not get wpa_auth (%d)\n", err
);
1425 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1426 switch (sme
->crypto
.akm_suites
[0]) {
1427 case WLAN_AKM_SUITE_8021X
:
1428 val
= WPA_AUTH_UNSPECIFIED
;
1430 case WLAN_AKM_SUITE_PSK
:
1434 brcmf_err("invalid cipher group (%d)\n",
1435 sme
->crypto
.cipher_group
);
1438 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1439 switch (sme
->crypto
.akm_suites
[0]) {
1440 case WLAN_AKM_SUITE_8021X
:
1441 val
= WPA2_AUTH_UNSPECIFIED
;
1443 case WLAN_AKM_SUITE_PSK
:
1444 val
= WPA2_AUTH_PSK
;
1447 brcmf_err("invalid cipher group (%d)\n",
1448 sme
->crypto
.cipher_group
);
1453 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1454 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
),
1457 brcmf_err("could not set wpa_auth (%d)\n", err
);
1461 sec
= &profile
->sec
;
1462 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1468 brcmf_set_sharedkey(struct net_device
*ndev
,
1469 struct cfg80211_connect_params
*sme
)
1471 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1472 struct brcmf_cfg80211_security
*sec
;
1473 struct brcmf_wsec_key key
;
1477 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1479 if (sme
->key_len
== 0)
1482 sec
= &profile
->sec
;
1483 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1484 sec
->wpa_versions
, sec
->cipher_pairwise
);
1486 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1489 if (!(sec
->cipher_pairwise
&
1490 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1493 memset(&key
, 0, sizeof(key
));
1494 key
.len
= (u32
) sme
->key_len
;
1495 key
.index
= (u32
) sme
->key_idx
;
1496 if (key
.len
> sizeof(key
.data
)) {
1497 brcmf_err("Too long key length (%u)\n", key
.len
);
1500 memcpy(key
.data
, sme
->key
, key
.len
);
1501 key
.flags
= BRCMF_PRIMARY_KEY
;
1502 switch (sec
->cipher_pairwise
) {
1503 case WLAN_CIPHER_SUITE_WEP40
:
1504 key
.algo
= CRYPTO_ALGO_WEP1
;
1506 case WLAN_CIPHER_SUITE_WEP104
:
1507 key
.algo
= CRYPTO_ALGO_WEP128
;
1510 brcmf_err("Invalid algorithm (%d)\n",
1511 sme
->crypto
.ciphers_pairwise
[0]);
1514 /* Set the new key/index */
1515 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1516 key
.len
, key
.index
, key
.algo
);
1517 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1518 err
= send_key_to_dongle(ndev
, &key
);
1522 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1523 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1524 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1525 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1527 brcmf_err("set auth failed (%d)\n", err
);
1533 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1534 enum nl80211_auth_type type
)
1537 if (type
== NL80211_AUTHTYPE_AUTOMATIC
) {
1538 /* shift to ignore chip revision */
1539 ci
= brcmf_get_chip_info(ifp
) >> 4;
1542 brcmf_dbg(CONN
, "43236 WAR: use OPEN instead of AUTO\n");
1543 return NL80211_AUTHTYPE_OPEN_SYSTEM
;
1552 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1553 struct cfg80211_connect_params
*sme
)
1555 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1556 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1557 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1558 struct ieee80211_channel
*chan
= sme
->channel
;
1559 struct brcmf_join_params join_params
;
1560 size_t join_params_size
;
1561 struct brcmf_tlv
*rsn_ie
;
1562 struct brcmf_vs_tlv
*wpa_ie
;
1565 struct brcmf_ext_join_params_le
*ext_join_params
;
1570 brcmf_dbg(TRACE
, "Enter\n");
1571 if (!check_vif_up(ifp
->vif
))
1575 brcmf_err("Invalid ssid\n");
1579 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1580 /* A normal (non P2P) connection request setup. */
1583 /* find the WPA_IE */
1584 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1587 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1589 /* find the RSN_IE */
1590 rsn_ie
= brcmf_parse_tlvs((u8
*)sme
->ie
, sme
->ie_len
,
1594 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1597 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1600 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1601 sme
->ie
, sme
->ie_len
);
1603 brcmf_err("Set Assoc REQ IE Failed\n");
1605 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1607 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1611 ieee80211_frequency_to_channel(chan
->center_freq
);
1612 chanspec
= channel_to_chanspec(chan
);
1613 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1614 cfg
->channel
, chan
->center_freq
, chanspec
);
1620 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1622 err
= brcmf_set_wpa_version(ndev
, sme
);
1624 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1628 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1629 err
= brcmf_set_auth_type(ndev
, sme
);
1631 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1635 err
= brcmf_set_set_cipher(ndev
, sme
);
1637 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1641 err
= brcmf_set_key_mgmt(ndev
, sme
);
1643 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1647 err
= brcmf_set_sharedkey(ndev
, sme
);
1649 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1653 profile
->ssid
.SSID_len
= min_t(u32
, (u32
)sizeof(profile
->ssid
.SSID
),
1654 (u32
)sme
->ssid_len
);
1655 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1656 if (profile
->ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1657 profile
->ssid
.SSID
[profile
->ssid
.SSID_len
] = 0;
1658 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n", profile
->ssid
.SSID
,
1659 profile
->ssid
.SSID_len
);
1662 /* Join with specific BSSID and cached SSID
1663 * If SSID is zero join based on BSSID only
1665 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1666 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1668 join_params_size
+= sizeof(u16
);
1669 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1670 if (ext_join_params
== NULL
) {
1674 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1675 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
,
1676 profile
->ssid
.SSID_len
);
1677 /*increase dwell time to receive probe response or detect Beacon
1678 * from target AP at a noisy air only during connect command
1680 ext_join_params
->scan_le
.active_time
=
1681 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1682 ext_join_params
->scan_le
.passive_time
=
1683 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
1684 /* Set up join scan parameters */
1685 ext_join_params
->scan_le
.scan_type
= -1;
1686 /* to sync with presence period of VSDB GO.
1687 * Send probe request more frequently. Probe request will be stopped
1688 * when it gets probe response from target AP/GO.
1690 ext_join_params
->scan_le
.nprobes
=
1691 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
1692 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
1693 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1696 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1698 memset(&ext_join_params
->assoc_le
.bssid
, 0xFF, ETH_ALEN
);
1701 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1703 ext_join_params
->assoc_le
.chanspec_list
[0] =
1704 cpu_to_le16(chanspec
);
1707 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
1709 kfree(ext_join_params
);
1711 /* This is it. join command worked, we are done */
1714 /* join command failed, fallback to set ssid */
1715 memset(&join_params
, 0, sizeof(join_params
));
1716 join_params_size
= sizeof(join_params
.ssid_le
);
1718 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1719 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1722 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1724 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1727 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1728 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1729 join_params_size
+= sizeof(join_params
.params_le
);
1731 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1732 &join_params
, join_params_size
);
1734 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
1738 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1739 brcmf_dbg(TRACE
, "Exit\n");
1744 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1747 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1748 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1749 struct brcmf_scb_val_le scbval
;
1752 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1753 if (!check_vif_up(ifp
->vif
))
1756 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1758 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1759 scbval
.val
= cpu_to_le32(reason_code
);
1760 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1761 &scbval
, sizeof(scbval
));
1763 brcmf_err("error (%d)\n", err
);
1765 brcmf_dbg(TRACE
, "Exit\n");
1770 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1771 enum nl80211_tx_power_setting type
, s32 mbm
)
1774 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1775 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1776 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1780 s32 dbm
= MBM_TO_DBM(mbm
);
1782 brcmf_dbg(TRACE
, "Enter\n");
1783 if (!check_vif_up(ifp
->vif
))
1787 case NL80211_TX_POWER_AUTOMATIC
:
1789 case NL80211_TX_POWER_LIMITED
:
1790 case NL80211_TX_POWER_FIXED
:
1792 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1798 /* Make sure radio is off or on as far as software is concerned */
1799 disable
= WL_RADIO_SW_DISABLE
<< 16;
1800 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1802 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1807 txpwrmw
= (u16
) dbm
;
1808 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1809 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1811 brcmf_err("qtxpower error (%d)\n", err
);
1812 cfg
->conf
->tx_power
= dbm
;
1815 brcmf_dbg(TRACE
, "Exit\n");
1819 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1820 struct wireless_dev
*wdev
,
1823 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1824 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1829 brcmf_dbg(TRACE
, "Enter\n");
1830 if (!check_vif_up(ifp
->vif
))
1833 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1835 brcmf_err("error (%d)\n", err
);
1839 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1840 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1843 brcmf_dbg(TRACE
, "Exit\n");
1848 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1849 u8 key_idx
, bool unicast
, bool multicast
)
1851 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1856 brcmf_dbg(TRACE
, "Enter\n");
1857 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1858 if (!check_vif_up(ifp
->vif
))
1861 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1863 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1867 if (wsec
& WEP_ENABLED
) {
1868 /* Just select a new current key */
1870 err
= brcmf_fil_cmd_int_set(ifp
,
1871 BRCMF_C_SET_KEY_PRIMARY
, index
);
1873 brcmf_err("error (%d)\n", err
);
1876 brcmf_dbg(TRACE
, "Exit\n");
1881 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1882 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1884 struct brcmf_wsec_key key
;
1887 memset(&key
, 0, sizeof(key
));
1888 key
.index
= (u32
) key_idx
;
1889 /* Instead of bcast for ea address for default wep keys,
1890 driver needs it to be Null */
1891 if (!is_multicast_ether_addr(mac_addr
))
1892 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1893 key
.len
= (u32
) params
->key_len
;
1894 /* check for key index change */
1897 err
= send_key_to_dongle(ndev
, &key
);
1899 brcmf_err("key delete error (%d)\n", err
);
1901 if (key
.len
> sizeof(key
.data
)) {
1902 brcmf_err("Invalid key length (%d)\n", key
.len
);
1906 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1907 memcpy(key
.data
, params
->key
, key
.len
);
1909 if (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
) {
1911 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1912 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1913 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1916 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1917 if (params
->seq
&& params
->seq_len
== 6) {
1920 ivptr
= (u8
*) params
->seq
;
1921 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1922 (ivptr
[3] << 8) | ivptr
[2];
1923 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1924 key
.iv_initialized
= true;
1927 switch (params
->cipher
) {
1928 case WLAN_CIPHER_SUITE_WEP40
:
1929 key
.algo
= CRYPTO_ALGO_WEP1
;
1930 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1932 case WLAN_CIPHER_SUITE_WEP104
:
1933 key
.algo
= CRYPTO_ALGO_WEP128
;
1934 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1936 case WLAN_CIPHER_SUITE_TKIP
:
1937 key
.algo
= CRYPTO_ALGO_TKIP
;
1938 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1940 case WLAN_CIPHER_SUITE_AES_CMAC
:
1941 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1942 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1944 case WLAN_CIPHER_SUITE_CCMP
:
1945 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1946 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1949 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1952 err
= send_key_to_dongle(ndev
, &key
);
1954 brcmf_err("wsec_key error (%d)\n", err
);
1960 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1961 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1962 struct key_params
*params
)
1964 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1965 struct brcmf_wsec_key key
;
1971 brcmf_dbg(TRACE
, "Enter\n");
1972 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1973 if (!check_vif_up(ifp
->vif
))
1977 brcmf_dbg(TRACE
, "Exit");
1978 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1980 memset(&key
, 0, sizeof(key
));
1982 key
.len
= (u32
) params
->key_len
;
1983 key
.index
= (u32
) key_idx
;
1985 if (key
.len
> sizeof(key
.data
)) {
1986 brcmf_err("Too long key length (%u)\n", key
.len
);
1990 memcpy(key
.data
, params
->key
, key
.len
);
1992 key
.flags
= BRCMF_PRIMARY_KEY
;
1993 switch (params
->cipher
) {
1994 case WLAN_CIPHER_SUITE_WEP40
:
1995 key
.algo
= CRYPTO_ALGO_WEP1
;
1997 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1999 case WLAN_CIPHER_SUITE_WEP104
:
2000 key
.algo
= CRYPTO_ALGO_WEP128
;
2002 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2004 case WLAN_CIPHER_SUITE_TKIP
:
2005 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
2006 brcmf_dbg(CONN
, "Swapping key\n");
2007 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2008 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2009 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2011 key
.algo
= CRYPTO_ALGO_TKIP
;
2013 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2015 case WLAN_CIPHER_SUITE_AES_CMAC
:
2016 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2018 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2020 case WLAN_CIPHER_SUITE_CCMP
:
2021 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2023 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2026 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2031 err
= send_key_to_dongle(ndev
, &key
);
2035 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2037 brcmf_err("get wsec error (%d)\n", err
);
2041 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2043 brcmf_err("set wsec error (%d)\n", err
);
2048 brcmf_dbg(TRACE
, "Exit\n");
2053 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2054 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2056 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2057 struct brcmf_wsec_key key
;
2060 brcmf_dbg(TRACE
, "Enter\n");
2061 if (!check_vif_up(ifp
->vif
))
2064 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
2065 /* we ignore this key index in this case */
2066 brcmf_err("invalid key index (%d)\n", key_idx
);
2070 memset(&key
, 0, sizeof(key
));
2072 key
.index
= (u32
) key_idx
;
2073 key
.flags
= BRCMF_PRIMARY_KEY
;
2074 key
.algo
= CRYPTO_ALGO_OFF
;
2076 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2078 /* Set the new key/index */
2079 err
= send_key_to_dongle(ndev
, &key
);
2081 brcmf_dbg(TRACE
, "Exit\n");
2086 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2087 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2088 void (*callback
) (void *cookie
, struct key_params
* params
))
2090 struct key_params params
;
2091 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2092 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2093 struct brcmf_cfg80211_security
*sec
;
2097 brcmf_dbg(TRACE
, "Enter\n");
2098 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2099 if (!check_vif_up(ifp
->vif
))
2102 memset(¶ms
, 0, sizeof(params
));
2104 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2106 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2107 /* Ignore this error, may happen during DISASSOC */
2111 switch (wsec
& ~SES_OW_ENABLED
) {
2113 sec
= &profile
->sec
;
2114 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2115 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2116 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2117 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2118 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2119 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2123 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2124 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2127 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2128 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2131 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2135 callback(cookie
, ¶ms
);
2138 brcmf_dbg(TRACE
, "Exit\n");
2143 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2144 struct net_device
*ndev
, u8 key_idx
)
2146 brcmf_dbg(INFO
, "Not supported\n");
2152 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2153 u8
*mac
, struct station_info
*sinfo
)
2155 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2156 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2157 struct brcmf_scb_val_le scb_val
;
2161 u8
*bssid
= profile
->bssid
;
2162 struct brcmf_sta_info_le sta_info_le
;
2164 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2165 if (!check_vif_up(ifp
->vif
))
2168 if (ifp
->vif
->mode
== WL_MODE_AP
) {
2169 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2170 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2172 sizeof(sta_info_le
));
2174 brcmf_err("GET STA INFO failed, %d\n", err
);
2177 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2178 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2179 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2180 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2181 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2183 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
2184 sinfo
->inactive_time
, sinfo
->connected_time
);
2185 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
2186 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2187 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2192 /* Report the current tx rate */
2193 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2195 brcmf_err("Could not get rate (%d)\n", err
);
2198 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2199 sinfo
->txrate
.legacy
= rate
* 5;
2200 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
2203 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2204 &ifp
->vif
->sme_state
)) {
2205 memset(&scb_val
, 0, sizeof(scb_val
));
2206 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2207 &scb_val
, sizeof(scb_val
));
2209 brcmf_err("Could not get rssi (%d)\n", err
);
2212 rssi
= le32_to_cpu(scb_val
.val
);
2213 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2214 sinfo
->signal
= rssi
;
2215 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2221 brcmf_dbg(TRACE
, "Exit\n");
2226 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2227 bool enabled
, s32 timeout
)
2231 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2232 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2234 brcmf_dbg(TRACE
, "Enter\n");
2237 * Powersave enable/disable request is coming from the
2238 * cfg80211 even before the interface is up. In that
2239 * scenario, driver will be storing the power save
2240 * preference in cfg struct to apply this to
2241 * FW later while initializing the dongle
2243 cfg
->pwr_save
= enabled
;
2244 if (!check_vif_up(ifp
->vif
)) {
2246 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2250 pm
= enabled
? PM_FAST
: PM_OFF
;
2251 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2253 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2256 brcmf_err("net_device is not ready yet\n");
2258 brcmf_err("error (%d)\n", err
);
2261 brcmf_dbg(TRACE
, "Exit\n");
2265 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2266 struct brcmf_bss_info_le
*bi
)
2268 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2269 struct ieee80211_channel
*notify_channel
;
2270 struct cfg80211_bss
*bss
;
2271 struct ieee80211_supported_band
*band
;
2275 u16 notify_capability
;
2276 u16 notify_interval
;
2278 size_t notify_ielen
;
2281 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2282 brcmf_err("Bss info is larger than buffer. Discarding\n");
2286 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2287 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2289 if (channel
<= CH_MAX_2G_CHANNEL
)
2290 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2292 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2294 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2295 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2297 notify_capability
= le16_to_cpu(bi
->capability
);
2298 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2299 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2300 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2301 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2303 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2304 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2305 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2306 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2307 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2309 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2310 0, notify_capability
, notify_interval
, notify_ie
,
2311 notify_ielen
, notify_signal
, GFP_KERNEL
);
2316 cfg80211_put_bss(bss
);
2321 static struct brcmf_bss_info_le
*
2322 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2325 return list
->bss_info_le
;
2326 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2327 le32_to_cpu(bss
->length
));
2330 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2332 struct brcmf_scan_results
*bss_list
;
2333 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2337 bss_list
= cfg
->bss_list
;
2338 if (bss_list
->count
!= 0 &&
2339 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2340 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2344 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2345 for (i
= 0; i
< bss_list
->count
; i
++) {
2346 bi
= next_bss_le(bss_list
, bi
);
2347 err
= brcmf_inform_single_bss(cfg
, bi
);
2354 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2355 struct net_device
*ndev
, const u8
*bssid
)
2357 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2358 struct ieee80211_channel
*notify_channel
;
2359 struct brcmf_bss_info_le
*bi
= NULL
;
2360 struct ieee80211_supported_band
*band
;
2361 struct cfg80211_bss
*bss
;
2366 u16 notify_capability
;
2367 u16 notify_interval
;
2369 size_t notify_ielen
;
2372 brcmf_dbg(TRACE
, "Enter\n");
2374 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2380 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2382 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2383 buf
, WL_BSS_INFO_MAX
);
2385 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2389 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2391 channel
= bi
->ctl_ch
? bi
->ctl_ch
:
2392 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
2394 if (channel
<= CH_MAX_2G_CHANNEL
)
2395 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2397 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2399 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2400 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2402 notify_capability
= le16_to_cpu(bi
->capability
);
2403 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2404 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2405 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2406 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2408 brcmf_dbg(CONN
, "channel: %d(%d)\n", channel
, freq
);
2409 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2410 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2411 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2413 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2414 0, notify_capability
, notify_interval
,
2415 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2422 cfg80211_put_bss(bss
);
2428 brcmf_dbg(TRACE
, "Exit\n");
2433 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2435 return vif
->mode
== WL_MODE_IBSS
;
2438 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2439 struct brcmf_if
*ifp
)
2441 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ifp
->ndev
);
2442 struct brcmf_bss_info_le
*bi
;
2443 struct brcmf_ssid
*ssid
;
2444 struct brcmf_tlv
*tim
;
2445 u16 beacon_interval
;
2451 brcmf_dbg(TRACE
, "Enter\n");
2452 if (brcmf_is_ibssmode(ifp
->vif
))
2455 ssid
= &profile
->ssid
;
2457 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2458 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2459 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2461 brcmf_err("Could not get bss info %d\n", err
);
2462 goto update_bss_info_out
;
2465 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2466 err
= brcmf_inform_single_bss(cfg
, bi
);
2468 goto update_bss_info_out
;
2470 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2471 ie_len
= le32_to_cpu(bi
->ie_length
);
2472 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2474 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2476 dtim_period
= tim
->data
[1];
2479 * active scan was done so we could not get dtim
2480 * information out of probe response.
2481 * so we speficially query dtim information to dongle.
2484 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2486 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2487 goto update_bss_info_out
;
2489 dtim_period
= (u8
)var
;
2492 update_bss_info_out
:
2493 brcmf_dbg(TRACE
, "Exit");
2497 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2499 struct escan_info
*escan
= &cfg
->escan_info
;
2501 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2502 if (cfg
->scan_request
) {
2503 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2504 brcmf_notify_escan_complete(cfg
, escan
->ndev
, true, true);
2506 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2507 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2510 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2512 struct brcmf_cfg80211_info
*cfg
=
2513 container_of(work
, struct brcmf_cfg80211_info
,
2514 escan_timeout_work
);
2516 brcmf_notify_escan_complete(cfg
,
2517 cfg
->escan_info
.ndev
, true, true);
2520 static void brcmf_escan_timeout(unsigned long data
)
2522 struct brcmf_cfg80211_info
*cfg
=
2523 (struct brcmf_cfg80211_info
*)data
;
2525 if (cfg
->scan_request
) {
2526 brcmf_err("timer expired\n");
2527 schedule_work(&cfg
->escan_timeout_work
);
2532 brcmf_compare_update_same_bss(struct brcmf_bss_info_le
*bss
,
2533 struct brcmf_bss_info_le
*bss_info_le
)
2535 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2536 (CHSPEC_BAND(le16_to_cpu(bss_info_le
->chanspec
)) ==
2537 CHSPEC_BAND(le16_to_cpu(bss
->chanspec
))) &&
2538 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2539 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2540 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2541 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2542 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2543 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2545 /* preserve max RSSI if the measurements are
2546 * both on-channel or both off-channel
2548 if (bss_info_rssi
> bss_rssi
)
2549 bss
->RSSI
= bss_info_le
->RSSI
;
2550 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2551 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2552 /* preserve the on-channel rssi measurement
2553 * if the new measurement is off channel
2555 bss
->RSSI
= bss_info_le
->RSSI
;
2556 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2564 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2565 const struct brcmf_event_msg
*e
, void *data
)
2567 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2568 struct net_device
*ndev
= ifp
->ndev
;
2571 struct brcmf_escan_result_le
*escan_result_le
;
2572 struct brcmf_bss_info_le
*bss_info_le
;
2573 struct brcmf_bss_info_le
*bss
= NULL
;
2575 struct brcmf_scan_results
*list
;
2581 if (!ndev
|| !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2582 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev
,
2583 !test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
));
2587 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2588 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2589 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2590 if (!escan_result_le
) {
2591 brcmf_err("Invalid escan result (NULL pointer)\n");
2594 if (!cfg
->scan_request
) {
2595 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2599 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2600 brcmf_err("Invalid bss_count %d: ignoring\n",
2601 escan_result_le
->bss_count
);
2604 bss_info_le
= &escan_result_le
->bss_info_le
;
2606 bi_length
= le32_to_cpu(bss_info_le
->length
);
2607 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2608 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2609 brcmf_err("Invalid bss_info length %d: ignoring\n",
2614 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2615 BIT(NL80211_IFTYPE_ADHOC
))) {
2616 if (le16_to_cpu(bss_info_le
->capability
) &
2617 WLAN_CAPABILITY_IBSS
) {
2618 brcmf_err("Ignoring IBSS result\n");
2623 list
= (struct brcmf_scan_results
*)
2624 cfg
->escan_info
.escan_buf
;
2625 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2626 brcmf_err("Buffer is too small: ignoring\n");
2630 for (i
= 0; i
< list
->count
; i
++) {
2631 bss
= bss
? (struct brcmf_bss_info_le
*)
2632 ((unsigned char *)bss
+
2633 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2634 if (brcmf_compare_update_same_bss(bss
, bss_info_le
))
2637 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2638 bss_info_le
, bi_length
);
2639 list
->version
= le32_to_cpu(bss_info_le
->version
);
2640 list
->buflen
+= bi_length
;
2643 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2644 if (cfg
->scan_request
) {
2645 cfg
->bss_list
= (struct brcmf_scan_results
*)
2646 cfg
->escan_info
.escan_buf
;
2647 brcmf_inform_bss(cfg
);
2648 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2649 brcmf_notify_escan_complete(cfg
, ndev
, aborted
,
2652 brcmf_err("Unexpected scan result 0x%x\n", status
);
2658 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2660 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2661 brcmf_cfg80211_escan_handler
);
2662 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2663 /* Init scan_timeout timer */
2664 init_timer(&cfg
->escan_timeout
);
2665 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2666 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2667 INIT_WORK(&cfg
->escan_timeout_work
,
2668 brcmf_cfg80211_escan_timeout_worker
);
2671 static __always_inline
void brcmf_delay(u32 ms
)
2673 if (ms
< 1000 / HZ
) {
2681 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2683 brcmf_dbg(TRACE
, "Enter\n");
2688 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2689 struct cfg80211_wowlan
*wow
)
2691 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2692 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2693 struct brcmf_cfg80211_vif
*vif
;
2695 brcmf_dbg(TRACE
, "Enter\n");
2698 * if the primary net_device is not READY there is nothing
2699 * we can do but pray resume goes smoothly.
2701 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2702 if (!check_vif_up(vif
))
2705 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2706 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2709 * While going to suspend if associated with AP disassociate
2710 * from AP to save power while system is in suspended state
2712 brcmf_link_down(vif
);
2714 /* Make sure WPA_Supplicant receives all the event
2715 * generated due to DISASSOC call to the fw to keep
2716 * the state fw and WPA_Supplicant state consistent
2721 /* end any scanning */
2722 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2723 brcmf_abort_scanning(cfg
);
2725 /* Turn off watchdog timer */
2726 brcmf_set_mpc(ndev
, 1);
2729 brcmf_dbg(TRACE
, "Exit\n");
2730 /* clear any scanning activity */
2731 cfg
->scan_status
= 0;
2736 brcmf_update_pmklist(struct net_device
*ndev
,
2737 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2742 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2744 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2745 for (i
= 0; i
< pmkid_len
; i
++) {
2746 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2747 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2748 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2749 brcmf_dbg(CONN
, "%02x\n",
2750 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2754 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2755 (char *)pmk_list
, sizeof(*pmk_list
));
2761 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2762 struct cfg80211_pmksa
*pmksa
)
2764 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2765 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2766 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2771 brcmf_dbg(TRACE
, "Enter\n");
2772 if (!check_vif_up(ifp
->vif
))
2775 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2776 for (i
= 0; i
< pmkid_len
; i
++)
2777 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2779 if (i
< WL_NUM_PMKIDS_MAX
) {
2780 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2781 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2782 if (i
== pmkid_len
) {
2784 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2789 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2790 pmkids
->pmkid
[pmkid_len
].BSSID
);
2791 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2792 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2794 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2796 brcmf_dbg(TRACE
, "Exit\n");
2801 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2802 struct cfg80211_pmksa
*pmksa
)
2804 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2805 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2806 struct pmkid_list pmkid
;
2810 brcmf_dbg(TRACE
, "Enter\n");
2811 if (!check_vif_up(ifp
->vif
))
2814 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2815 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2817 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2818 &pmkid
.pmkid
[0].BSSID
);
2819 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2820 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2822 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2823 for (i
= 0; i
< pmkid_len
; i
++)
2825 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2830 && (i
< pmkid_len
)) {
2831 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2832 sizeof(struct pmkid
));
2833 for (; i
< (pmkid_len
- 1); i
++) {
2834 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2835 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2837 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2838 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2841 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2845 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2847 brcmf_dbg(TRACE
, "Exit\n");
2853 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2855 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2856 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2859 brcmf_dbg(TRACE
, "Enter\n");
2860 if (!check_vif_up(ifp
->vif
))
2863 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2864 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2866 brcmf_dbg(TRACE
, "Exit\n");
2872 * PFN result doesn't have all the info which are
2873 * required by the supplicant
2874 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2875 * via wl_inform_single_bss in the required format. Escan does require the
2876 * scan request in the form of cfg80211_scan_request. For timebeing, create
2877 * cfg80211_scan_request one out of the received PNO event.
2880 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2881 const struct brcmf_event_msg
*e
, void *data
)
2883 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2884 struct net_device
*ndev
= ifp
->ndev
;
2885 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2886 struct cfg80211_scan_request
*request
= NULL
;
2887 struct cfg80211_ssid
*ssid
= NULL
;
2888 struct ieee80211_channel
*channel
= NULL
;
2889 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2891 int channel_req
= 0;
2893 struct brcmf_pno_scanresults_le
*pfn_result
;
2897 brcmf_dbg(SCAN
, "Enter\n");
2899 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2900 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2904 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2905 result_count
= le32_to_cpu(pfn_result
->count
);
2906 status
= le32_to_cpu(pfn_result
->status
);
2909 * PFN event is limited to fit 512 bytes so we may get
2910 * multiple NET_FOUND events. For now place a warning here.
2912 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2913 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2914 if (result_count
> 0) {
2917 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2918 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2919 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2920 if (!request
|| !ssid
|| !channel
) {
2925 request
->wiphy
= wiphy
;
2926 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2927 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2929 for (i
= 0; i
< result_count
; i
++) {
2930 netinfo
= &netinfo_start
[i
];
2932 brcmf_err("Invalid netinfo ptr. index: %d\n",
2938 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2939 netinfo
->SSID
, netinfo
->channel
);
2940 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2941 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2944 channel_req
= netinfo
->channel
;
2945 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2946 band
= NL80211_BAND_2GHZ
;
2948 band
= NL80211_BAND_5GHZ
;
2949 channel
[i
].center_freq
=
2950 ieee80211_channel_to_frequency(channel_req
,
2952 channel
[i
].band
= band
;
2953 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2954 request
->channels
[i
] = &channel
[i
];
2955 request
->n_channels
++;
2958 /* assign parsed ssid array */
2959 if (request
->n_ssids
)
2960 request
->ssids
= &ssid
[0];
2962 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2963 /* Abort any on-going scan */
2964 brcmf_abort_scanning(cfg
);
2967 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2968 err
= brcmf_do_escan(cfg
, wiphy
, ndev
, request
);
2970 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2973 cfg
->sched_escan
= true;
2974 cfg
->scan_request
= request
;
2976 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2989 cfg80211_sched_scan_stopped(wiphy
);
2993 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
2998 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3001 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3005 brcmf_err("failed code %d\n", ret
);
3010 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3012 struct brcmf_pno_param_le pfn_param
;
3014 memset(&pfn_param
, 0, sizeof(pfn_param
));
3015 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3017 /* set extra pno params */
3018 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3019 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3020 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3022 /* set up pno scan fr */
3023 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3025 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3026 &pfn_param
, sizeof(pfn_param
));
3030 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3031 struct net_device
*ndev
,
3032 struct cfg80211_sched_scan_request
*request
)
3034 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3035 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3036 struct brcmf_pno_net_param_le pfn
;
3040 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3041 request
->n_match_sets
, request
->n_ssids
);
3042 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3043 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3047 if (!request
|| !request
->n_ssids
|| !request
->n_match_sets
) {
3048 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3049 request
? request
->n_ssids
: 0);
3053 if (request
->n_ssids
> 0) {
3054 for (i
= 0; i
< request
->n_ssids
; i
++) {
3055 /* Active scan req for ssids */
3056 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3057 request
->ssids
[i
].ssid
);
3060 * match_set ssids is a supert set of n_ssid list,
3061 * so we need not add these set seperately.
3066 if (request
->n_match_sets
> 0) {
3067 /* clean up everything */
3068 ret
= brcmf_dev_pno_clean(ndev
);
3070 brcmf_err("failed error=%d\n", ret
);
3075 ret
= brcmf_dev_pno_config(ndev
);
3077 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
3081 /* configure each match set */
3082 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3083 struct cfg80211_ssid
*ssid
;
3086 ssid
= &request
->match_sets
[i
].ssid
;
3087 ssid_len
= ssid
->ssid_len
;
3090 brcmf_err("skip broadcast ssid\n");
3093 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3094 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3095 pfn
.wsec
= cpu_to_le32(0);
3096 pfn
.infra
= cpu_to_le32(1);
3097 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3098 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3099 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3100 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3102 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3103 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3105 /* Enable the PNO */
3106 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3107 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3117 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3118 struct net_device
*ndev
)
3120 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3122 brcmf_dbg(SCAN
, "enter\n");
3123 brcmf_dev_pno_clean(ndev
);
3124 if (cfg
->sched_escan
)
3125 brcmf_notify_escan_complete(cfg
, ndev
, true, true);
3129 #ifdef CONFIG_NL80211_TESTMODE
3130 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
, void *data
, int len
)
3132 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3133 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3134 struct brcmf_dcmd
*dcmd
= data
;
3135 struct sk_buff
*reply
;
3138 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3139 dcmd
->buf
, dcmd
->len
);
3142 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3143 dcmd
->buf
, dcmd
->len
);
3145 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3146 dcmd
->buf
, dcmd
->len
);
3148 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3149 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3150 ret
= cfg80211_testmode_reply(reply
);
3156 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3161 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3163 brcmf_err("auth error %d\n", err
);
3167 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3169 brcmf_err("wsec error %d\n", err
);
3172 /* set upper-layer auth */
3173 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3175 brcmf_err("wpa_auth error %d\n", err
);
3182 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3185 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3187 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3191 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3194 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3195 u32 auth
= 0; /* d11 open authentication */
3207 u32 wme_bss_disable
;
3209 brcmf_dbg(TRACE
, "Enter\n");
3213 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3214 data
= (u8
*)wpa_ie
;
3215 offset
= TLV_HDR_LEN
;
3217 offset
+= VS_IE_FIXED_HDR_LEN
;
3219 offset
+= WPA_IE_VERSION_LEN
;
3221 /* check for multicast cipher suite */
3222 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3224 brcmf_err("no multicast cipher suite\n");
3228 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3230 brcmf_err("ivalid OUI\n");
3233 offset
+= TLV_OUI_LEN
;
3235 /* pick up multicast cipher */
3236 switch (data
[offset
]) {
3237 case WPA_CIPHER_NONE
:
3240 case WPA_CIPHER_WEP_40
:
3241 case WPA_CIPHER_WEP_104
:
3244 case WPA_CIPHER_TKIP
:
3245 gval
= TKIP_ENABLED
;
3247 case WPA_CIPHER_AES_CCM
:
3252 brcmf_err("Invalid multi cast cipher info\n");
3257 /* walk thru unicast cipher list and pick up what we recognize */
3258 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3259 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3260 /* Check for unicast suite(s) */
3261 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3263 brcmf_err("no unicast cipher suite\n");
3266 for (i
= 0; i
< count
; i
++) {
3267 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3269 brcmf_err("ivalid OUI\n");
3272 offset
+= TLV_OUI_LEN
;
3273 switch (data
[offset
]) {
3274 case WPA_CIPHER_NONE
:
3276 case WPA_CIPHER_WEP_40
:
3277 case WPA_CIPHER_WEP_104
:
3278 pval
|= WEP_ENABLED
;
3280 case WPA_CIPHER_TKIP
:
3281 pval
|= TKIP_ENABLED
;
3283 case WPA_CIPHER_AES_CCM
:
3284 pval
|= AES_ENABLED
;
3287 brcmf_err("Ivalid unicast security info\n");
3291 /* walk thru auth management suite list and pick up what we recognize */
3292 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3293 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3294 /* Check for auth key management suite(s) */
3295 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3297 brcmf_err("no auth key mgmt suite\n");
3300 for (i
= 0; i
< count
; i
++) {
3301 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3303 brcmf_err("ivalid OUI\n");
3306 offset
+= TLV_OUI_LEN
;
3307 switch (data
[offset
]) {
3309 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3310 wpa_auth
|= WPA_AUTH_NONE
;
3312 case RSN_AKM_UNSPECIFIED
:
3313 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3314 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3315 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3318 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3319 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3320 (wpa_auth
|= WPA_AUTH_PSK
);
3323 brcmf_err("Ivalid key mgmt info\n");
3329 wme_bss_disable
= 1;
3330 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3331 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3332 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3333 wme_bss_disable
= 0;
3335 /* set wme_bss_disable to sync RSN Capabilities */
3336 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3339 brcmf_err("wme_bss_disable error %d\n", err
);
3343 /* FOR WPS , set SES_OW_ENABLED */
3344 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3347 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3349 brcmf_err("auth error %d\n", err
);
3353 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3355 brcmf_err("wsec error %d\n", err
);
3358 /* set upper-layer auth */
3359 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3361 brcmf_err("wpa_auth error %d\n", err
);
3370 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3371 struct parsed_vndr_ies
*vndr_ies
)
3374 struct brcmf_vs_tlv
*vndrie
;
3375 struct brcmf_tlv
*ie
;
3376 struct parsed_vndr_ie_info
*parsed_info
;
3379 remaining_len
= (s32
)vndr_ie_len
;
3380 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3382 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3384 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3386 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3387 /* len should be bigger than OUI length + one */
3388 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3389 brcmf_err("invalid vndr ie. length is too small %d\n",
3393 /* if wpa or wme ie, do not add ie */
3394 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3395 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3396 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3397 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3401 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3403 /* save vndr ie information */
3404 parsed_info
->ie_ptr
= (char *)vndrie
;
3405 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3406 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3410 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3411 parsed_info
->vndrie
.oui
[0],
3412 parsed_info
->vndrie
.oui
[1],
3413 parsed_info
->vndrie
.oui
[2],
3414 parsed_info
->vndrie
.oui_type
);
3416 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3419 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3420 if (remaining_len
<= TLV_HDR_LEN
)
3423 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3430 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3436 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3437 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3439 iecount_le
= cpu_to_le32(1);
3440 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3442 pktflag_le
= cpu_to_le32(pktflag
);
3443 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3445 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3447 return ie_len
+ VNDR_IE_HDR_SIZE
;
3450 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3451 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3453 struct brcmf_if
*ifp
;
3454 struct vif_saved_ie
*saved_ie
;
3458 u8
*mgmt_ie_buf
= NULL
;
3459 int mgmt_ie_buf_len
;
3461 u32 del_add_ie_buf_len
= 0;
3462 u32 total_ie_buf_len
= 0;
3463 u32 parsed_ie_buf_len
= 0;
3464 struct parsed_vndr_ies old_vndr_ies
;
3465 struct parsed_vndr_ies new_vndr_ies
;
3466 struct parsed_vndr_ie_info
*vndrie_info
;
3469 int remained_buf_len
;
3474 saved_ie
= &vif
->saved_ie
;
3476 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3477 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3480 curr_ie_buf
= iovar_ie_buf
;
3482 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3483 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3484 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3485 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3487 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3488 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3489 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3490 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3492 case BRCMF_VNDR_IE_BEACON_FLAG
:
3493 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3494 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3495 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3497 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
3498 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
3499 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
3500 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
3504 brcmf_err("not suitable type\n");
3508 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3510 brcmf_err("extra IE size too big\n");
3514 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3515 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3517 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3518 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3519 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3520 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3521 vndrie_info
->ie_len
);
3522 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3526 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3527 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3528 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3529 parsed_ie_buf_len
) == 0)) {
3530 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3534 /* parse old vndr_ie */
3535 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3537 /* make a command to delete old ie */
3538 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3539 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3541 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3542 vndrie_info
->vndrie
.id
,
3543 vndrie_info
->vndrie
.len
,
3544 vndrie_info
->vndrie
.oui
[0],
3545 vndrie_info
->vndrie
.oui
[1],
3546 vndrie_info
->vndrie
.oui
[2]);
3548 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3549 vndrie_info
->ie_ptr
,
3550 vndrie_info
->ie_len
,
3552 curr_ie_buf
+= del_add_ie_buf_len
;
3553 total_ie_buf_len
+= del_add_ie_buf_len
;
3558 /* Add if there is any extra IE */
3559 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3562 remained_buf_len
= mgmt_ie_buf_len
;
3564 /* make a command to add new ie */
3565 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3566 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3568 /* verify remained buf size before copy data */
3569 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3570 VNDR_IE_VSIE_OFFSET
)) {
3571 brcmf_err("no space in mgmt_ie_buf: len left %d",
3575 remained_buf_len
-= (vndrie_info
->ie_len
+
3576 VNDR_IE_VSIE_OFFSET
);
3578 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3579 vndrie_info
->vndrie
.id
,
3580 vndrie_info
->vndrie
.len
,
3581 vndrie_info
->vndrie
.oui
[0],
3582 vndrie_info
->vndrie
.oui
[1],
3583 vndrie_info
->vndrie
.oui
[2]);
3585 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3586 vndrie_info
->ie_ptr
,
3587 vndrie_info
->ie_len
,
3590 /* save the parsed IE in wl struct */
3591 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3592 vndrie_info
->ie_len
);
3593 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3595 curr_ie_buf
+= del_add_ie_buf_len
;
3596 total_ie_buf_len
+= del_add_ie_buf_len
;
3599 if (total_ie_buf_len
) {
3600 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3603 brcmf_err("vndr ie set error : %d\n", err
);
3607 kfree(iovar_ie_buf
);
3611 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
3614 BRCMF_VNDR_IE_PRBREQ_FLAG
,
3615 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3616 BRCMF_VNDR_IE_BEACON_FLAG
3620 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
3621 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
3623 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
3628 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
3629 struct cfg80211_beacon_data
*beacon
)
3633 /* Set Beacon IEs to FW */
3634 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
3635 beacon
->tail
, beacon
->tail_len
);
3637 brcmf_err("Set Beacon IE Failed\n");
3640 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3642 /* Set Probe Response IEs to FW */
3643 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
3644 beacon
->proberesp_ies
,
3645 beacon
->proberesp_ies_len
);
3647 brcmf_err("Set Probe Resp IE Failed\n");
3649 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3655 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3656 struct cfg80211_ap_settings
*settings
)
3658 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3660 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3661 struct brcmf_tlv
*ssid_ie
;
3662 struct brcmf_ssid_le ssid_le
;
3664 struct brcmf_tlv
*rsn_ie
;
3665 struct brcmf_vs_tlv
*wpa_ie
;
3666 struct brcmf_join_params join_params
;
3667 enum nl80211_iftype dev_role
;
3668 struct brcmf_fil_bss_enable_le bss_enable
;
3670 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3671 cfg80211_get_chandef_type(&settings
->chandef
),
3672 settings
->beacon_interval
,
3673 settings
->dtim_period
);
3674 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3675 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3676 settings
->inactivity_timeout
);
3678 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
3679 brcmf_dbg(TRACE
, "Role = AP\n");
3680 dev_role
= NL80211_IFTYPE_AP
;
3681 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING
,
3682 &ifp
->vif
->sme_state
)) {
3683 brcmf_err("Not in AP creation mode\n");
3687 brcmf_dbg(TRACE
, "Role = P2P GO\n");
3688 dev_role
= NL80211_IFTYPE_P2P_GO
;
3689 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
) {
3690 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3695 memset(&ssid_le
, 0, sizeof(ssid_le
));
3696 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3697 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3698 ssid_ie
= brcmf_parse_tlvs(
3699 (u8
*)&settings
->beacon
.head
[ie_offset
],
3700 settings
->beacon
.head_len
- ie_offset
,
3705 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3706 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3707 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3709 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3710 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3713 brcmf_set_mpc(ndev
, 0);
3715 /* find the RSN_IE */
3716 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3717 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3719 /* find the WPA_IE */
3720 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3721 settings
->beacon
.tail_len
);
3723 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3724 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3725 if (wpa_ie
!= NULL
) {
3727 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3732 err
= brcmf_configure_wpaie(ndev
,
3733 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3738 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3739 brcmf_configure_opensecurity(ifp
);
3742 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
3744 if (settings
->beacon_interval
) {
3745 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3746 settings
->beacon_interval
);
3748 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3752 if (settings
->dtim_period
) {
3753 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3754 settings
->dtim_period
);
3756 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3761 if (dev_role
== NL80211_IFTYPE_AP
) {
3762 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3764 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3767 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3770 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3772 brcmf_err("SET INFRA error %d\n", err
);
3775 if (dev_role
== NL80211_IFTYPE_AP
) {
3776 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3778 brcmf_err("setting AP mode failed %d\n", err
);
3781 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3783 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3787 memset(&join_params
, 0, sizeof(join_params
));
3788 /* join parameters starts with ssid */
3789 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3791 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3792 &join_params
, sizeof(join_params
));
3794 brcmf_err("SET SSID error (%d)\n", err
);
3797 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
3799 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
3802 brcmf_err("setting ssid failed %d\n", err
);
3805 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3806 bss_enable
.enable
= cpu_to_le32(1);
3807 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3808 sizeof(bss_enable
));
3810 brcmf_err("bss_enable config failed %d\n", err
);
3814 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
3816 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3817 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3821 brcmf_set_mpc(ndev
, 1);
3825 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3827 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3830 brcmf_dbg(TRACE
, "Enter\n");
3832 if (ifp
->vif
->mode
== WL_MODE_AP
) {
3833 /* Due to most likely deauths outstanding we sleep */
3834 /* first to make sure they get processed by fw. */
3836 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3838 brcmf_err("setting AP mode failed %d\n", err
);
3841 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3843 brcmf_err("BRCMF_C_UP error %d\n", err
);
3846 brcmf_set_mpc(ndev
, 1);
3847 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3848 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3855 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3856 struct cfg80211_beacon_data
*info
)
3858 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3859 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3862 brcmf_dbg(TRACE
, "Enter\n");
3864 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
3865 brcmf_dbg(TRACE
, "Role = AP\n");
3866 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATED
,
3867 &ifp
->vif
->sme_state
)) {
3868 brcmf_err("AP was not yet created\n");
3872 brcmf_dbg(TRACE
, "Role = P2P GO\n");
3873 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
) {
3874 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3879 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
3885 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3888 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3889 struct brcmf_scb_val_le scbval
;
3890 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3896 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3898 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
3899 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3900 if (!check_vif_up(ifp
->vif
))
3903 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3904 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3905 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3906 &scbval
, sizeof(scbval
));
3908 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3910 * Wait for the deauth event to come, supplicant will do the
3911 * delete iface immediately and we will have problem in sending
3912 * deauth frame if we delete the bss in firmware
3915 brcmf_dbg(TRACE
, "Exit\n");
3921 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
3922 struct wireless_dev
*wdev
,
3923 u16 frame_type
, bool reg
)
3925 struct brcmf_if
*ifp
= netdev_priv(wdev
->netdev
);
3926 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
3929 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
3931 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
3933 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
3935 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
3940 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
3941 struct ieee80211_channel
*chan
, bool offchan
,
3942 unsigned int wait
, const u8
*buf
, size_t len
,
3943 bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
3945 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3946 const struct ieee80211_mgmt
*mgmt
;
3947 struct brcmf_if
*ifp
;
3948 struct brcmf_cfg80211_vif
*vif
;
3952 struct brcmf_fil_action_frame_le
*action_frame
;
3953 struct brcmf_fil_af_params_le
*af_params
;
3957 brcmf_dbg(TRACE
, "Enter\n");
3961 mgmt
= (const struct ieee80211_mgmt
*)buf
;
3963 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
3964 brcmf_err("Driver only allows MGMT packet type\n");
3968 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
3969 /* Right now the only reason to get a probe response */
3970 /* is for p2p listen response or for p2p GO from */
3971 /* wpa_supplicant. Unfortunately the probe is send */
3972 /* on primary ndev, while dongle wants it on the p2p */
3973 /* vif. Since this is only reason for a probe */
3974 /* response to be sent, the vif is taken from cfg. */
3975 /* If ever desired to send proberesp for non p2p */
3976 /* response then data should be checked for */
3977 /* "DIRECT-". Note in future supplicant will take */
3978 /* dedicated p2p wdev to do this and then this 'hack'*/
3979 /* is not needed anymore. */
3980 ie_offset
= DOT11_MGMT_HDR_LEN
+
3981 DOT11_BCN_PRB_FIXED_LEN
;
3982 ie_len
= len
- ie_offset
;
3983 ifp
= netdev_priv(wdev
->netdev
);
3985 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
3986 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
3987 err
= brcmf_vif_set_mgmt_ie(vif
,
3988 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3991 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
3993 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
3994 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
3995 if (af_params
== NULL
) {
3996 brcmf_err("unable to allocate frame\n");
4000 action_frame
= &af_params
->action_frame
;
4001 /* Add the packet Id */
4002 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4004 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4005 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4006 /* Add the length exepted for 802.11 header */
4007 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4008 /* Add the channel */
4009 chan_nr
= ieee80211_frequency_to_channel(chan
->center_freq
);
4010 af_params
->channel
= cpu_to_le32(chan_nr
);
4012 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4013 le16_to_cpu(action_frame
->len
));
4015 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4016 *cookie
, le16_to_cpu(action_frame
->len
),
4019 ack
= brcmf_p2p_send_action_frame(cfg
, wdev
->netdev
,
4022 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4026 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4027 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4036 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4037 struct wireless_dev
*wdev
,
4040 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4041 struct brcmf_cfg80211_vif
*vif
;
4044 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4046 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4048 brcmf_err("No p2p device available for probe response\n");
4052 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4057 static s32
brcmf_notify_rx_mgmt_p2p_probereq(struct brcmf_if
*ifp
,
4058 const struct brcmf_event_msg
*e
,
4061 struct wireless_dev
*wdev
;
4062 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
4063 struct brcmf_rx_mgmt_data
*rxframe
= (struct brcmf_rx_mgmt_data
*)data
;
4064 u16 chanspec
= be16_to_cpu(rxframe
->chanspec
);
4071 "Enter: event %d reason %d\n", e
->event_code
, e
->reason
);
4073 /* Firmware sends us two proberesponses for each idx one. At the */
4074 /* moment anything but bsscfgidx 0 is passed up to supplicant */
4075 if (e
->bsscfgidx
== 0)
4078 /* Check if wpa_supplicant has registered for this frame */
4079 brcmf_dbg(INFO
, "vif->mgmt_rx_reg %04x\n", vif
->mgmt_rx_reg
);
4080 mgmt_type
= (IEEE80211_STYPE_PROBE_REQ
& IEEE80211_FCTL_STYPE
) >> 4;
4081 if ((vif
->mgmt_rx_reg
& BIT(mgmt_type
)) == 0)
4084 mgmt_frame
= (u8
*)(rxframe
+ 1);
4085 mgmt_frame_len
= e
->datalen
- sizeof(*rxframe
);
4086 freq
= ieee80211_channel_to_frequency(CHSPEC_CHANNEL(chanspec
),
4087 CHSPEC_IS2G(chanspec
) ?
4088 IEEE80211_BAND_2GHZ
:
4089 IEEE80211_BAND_5GHZ
);
4090 wdev
= ifp
->ndev
->ieee80211_ptr
;
4091 cfg80211_rx_mgmt(wdev
, freq
, 0, mgmt_frame
, mgmt_frame_len
, GFP_ATOMIC
);
4094 "mgmt_frame_len (%d) , e->datalen (%d), chanspec (%04x), freq (%d)\n",
4095 mgmt_frame_len
, e
->datalen
, chanspec
, freq
);
4101 static struct cfg80211_ops wl_cfg80211_ops
= {
4102 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4103 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4104 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4105 .scan
= brcmf_cfg80211_scan
,
4106 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4107 .join_ibss
= brcmf_cfg80211_join_ibss
,
4108 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4109 .get_station
= brcmf_cfg80211_get_station
,
4110 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4111 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4112 .add_key
= brcmf_cfg80211_add_key
,
4113 .del_key
= brcmf_cfg80211_del_key
,
4114 .get_key
= brcmf_cfg80211_get_key
,
4115 .set_default_key
= brcmf_cfg80211_config_default_key
,
4116 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4117 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4118 .connect
= brcmf_cfg80211_connect
,
4119 .disconnect
= brcmf_cfg80211_disconnect
,
4120 .suspend
= brcmf_cfg80211_suspend
,
4121 .resume
= brcmf_cfg80211_resume
,
4122 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4123 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4124 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4125 .start_ap
= brcmf_cfg80211_start_ap
,
4126 .stop_ap
= brcmf_cfg80211_stop_ap
,
4127 .change_beacon
= brcmf_cfg80211_change_beacon
,
4128 .del_station
= brcmf_cfg80211_del_station
,
4129 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4130 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4131 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4132 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4133 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4134 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4135 #ifdef CONFIG_NL80211_TESTMODE
4136 .testmode_cmd
= brcmf_cfg80211_testmode
4140 static s32
brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type
)
4143 case NL80211_IFTYPE_AP_VLAN
:
4144 case NL80211_IFTYPE_WDS
:
4145 case NL80211_IFTYPE_MONITOR
:
4146 case NL80211_IFTYPE_MESH_POINT
:
4148 case NL80211_IFTYPE_ADHOC
:
4149 return WL_MODE_IBSS
;
4150 case NL80211_IFTYPE_STATION
:
4151 case NL80211_IFTYPE_P2P_CLIENT
:
4153 case NL80211_IFTYPE_AP
:
4154 case NL80211_IFTYPE_P2P_GO
:
4156 case NL80211_IFTYPE_P2P_DEVICE
:
4158 case NL80211_IFTYPE_UNSPECIFIED
:
4166 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4168 /* scheduled scan settings */
4169 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4170 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4171 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4172 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4175 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
4178 .types
= BIT(NL80211_IFTYPE_STATION
) |
4179 BIT(NL80211_IFTYPE_ADHOC
) |
4180 BIT(NL80211_IFTYPE_AP
)
4184 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4185 BIT(NL80211_IFTYPE_P2P_GO
)
4188 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
4190 .max_interfaces
= BRCMF_IFACE_MAX_CNT
- 1,
4191 .num_different_channels
= 1, /* no multi-channel for now */
4192 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
4193 .limits
= brcmf_iface_limits
4197 static const struct ieee80211_txrx_stypes
4198 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
4199 [NL80211_IFTYPE_STATION
] = {
4201 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4202 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4204 [NL80211_IFTYPE_P2P_CLIENT
] = {
4206 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4207 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4209 [NL80211_IFTYPE_P2P_GO
] = {
4211 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
4212 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
4213 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
4214 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
4215 BIT(IEEE80211_STYPE_AUTH
>> 4) |
4216 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
4217 BIT(IEEE80211_STYPE_ACTION
>> 4)
4221 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
4223 struct wiphy
*wiphy
;
4226 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
4228 brcmf_err("Could not allocate wiphy device\n");
4229 return ERR_PTR(-ENOMEM
);
4231 set_wiphy_dev(wiphy
, phydev
);
4232 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4233 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4234 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4235 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4236 BIT(NL80211_IFTYPE_ADHOC
) |
4237 BIT(NL80211_IFTYPE_AP
) |
4238 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4239 BIT(NL80211_IFTYPE_P2P_GO
);
4240 wiphy
->iface_combinations
= brcmf_iface_combos
;
4241 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
4242 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4243 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_a
; /* Set
4244 * it as 11a by default.
4245 * This will be updated with
4248 * if phy has 11n capability
4250 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4251 wiphy
->cipher_suites
= __wl_cipher_suites
;
4252 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4253 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
4254 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
4255 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
4256 wiphy
->max_remain_on_channel_duration
= 5000;
4257 brcmf_wiphy_pno_params(wiphy
);
4258 err
= wiphy_register(wiphy
);
4260 brcmf_err("Could not register wiphy device (%d)\n", err
);
4262 return ERR_PTR(err
);
4267 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4268 enum nl80211_iftype type
,
4271 struct brcmf_cfg80211_vif
*vif
;
4273 if (cfg
->vif_cnt
== BRCMF_IFACE_MAX_CNT
)
4274 return ERR_PTR(-ENOSPC
);
4276 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
4278 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
4280 return ERR_PTR(-ENOMEM
);
4282 vif
->wdev
.wiphy
= cfg
->wiphy
;
4283 vif
->wdev
.iftype
= type
;
4285 vif
->mode
= brcmf_nl80211_iftype_to_mode(type
);
4286 vif
->pm_block
= pm_block
;
4289 brcmf_init_prof(&vif
->profile
);
4291 list_add_tail(&vif
->list
, &cfg
->vif_list
);
4296 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
4298 struct brcmf_cfg80211_info
*cfg
;
4299 struct wiphy
*wiphy
;
4301 wiphy
= vif
->wdev
.wiphy
;
4302 cfg
= wiphy_priv(wiphy
);
4303 list_del(&vif
->list
);
4307 if (!cfg
->vif_cnt
) {
4308 wiphy_unregister(wiphy
);
4313 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4315 u32 event
= e
->event_code
;
4316 u32 status
= e
->status
;
4318 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4319 brcmf_dbg(CONN
, "Processing set ssid\n");
4326 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4328 u32 event
= e
->event_code
;
4329 u16 flags
= e
->flags
;
4331 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
4332 brcmf_dbg(CONN
, "Processing link down\n");
4338 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4339 const struct brcmf_event_msg
*e
)
4341 u32 event
= e
->event_code
;
4342 u32 status
= e
->status
;
4344 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4345 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
4346 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
4350 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4351 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
4358 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4360 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4362 kfree(conn_info
->req_ie
);
4363 conn_info
->req_ie
= NULL
;
4364 conn_info
->req_ie_len
= 0;
4365 kfree(conn_info
->resp_ie
);
4366 conn_info
->resp_ie
= NULL
;
4367 conn_info
->resp_ie_len
= 0;
4370 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
4371 struct brcmf_if
*ifp
)
4373 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4374 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4379 brcmf_clear_assoc_ies(cfg
);
4381 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4382 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4384 brcmf_err("could not get assoc info (%d)\n", err
);
4388 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4389 req_len
= le32_to_cpu(assoc_info
->req_len
);
4390 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4392 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4396 brcmf_err("could not get assoc req (%d)\n", err
);
4399 conn_info
->req_ie_len
= req_len
;
4401 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4404 conn_info
->req_ie_len
= 0;
4405 conn_info
->req_ie
= NULL
;
4408 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4412 brcmf_err("could not get assoc resp (%d)\n", err
);
4415 conn_info
->resp_ie_len
= resp_len
;
4416 conn_info
->resp_ie
=
4417 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4420 conn_info
->resp_ie_len
= 0;
4421 conn_info
->resp_ie
= NULL
;
4423 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
4424 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4430 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4431 struct net_device
*ndev
,
4432 const struct brcmf_event_msg
*e
)
4434 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4435 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4436 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4437 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4438 struct ieee80211_channel
*notify_channel
= NULL
;
4439 struct ieee80211_supported_band
*band
;
4440 struct brcmf_bss_info_le
*bi
;
4446 brcmf_dbg(TRACE
, "Enter\n");
4448 brcmf_get_assoc_ies(cfg
, ifp
);
4449 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4450 brcmf_update_bss_info(cfg
, ifp
);
4452 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4458 /* data sent to dongle has to be little endian */
4459 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4460 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4461 buf
, WL_BSS_INFO_MAX
);
4466 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4467 target_channel
= bi
->ctl_ch
? bi
->ctl_ch
:
4468 CHSPEC_CHANNEL(le16_to_cpu(bi
->chanspec
));
4470 if (target_channel
<= CH_MAX_2G_CHANNEL
)
4471 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4473 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4475 freq
= ieee80211_channel_to_frequency(target_channel
, band
->band
);
4476 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4480 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4481 conn_info
->req_ie
, conn_info
->req_ie_len
,
4482 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4483 brcmf_dbg(CONN
, "Report roaming result\n");
4485 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4486 brcmf_dbg(TRACE
, "Exit\n");
4491 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4492 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4495 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4496 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4497 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4500 brcmf_dbg(TRACE
, "Enter\n");
4502 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4503 &ifp
->vif
->sme_state
)) {
4505 brcmf_get_assoc_ies(cfg
, ifp
);
4506 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4507 brcmf_update_bss_info(cfg
, ifp
);
4508 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4509 &ifp
->vif
->sme_state
);
4511 cfg80211_connect_result(ndev
,
4512 (u8
*)profile
->bssid
,
4514 conn_info
->req_ie_len
,
4516 conn_info
->resp_ie_len
,
4517 completed
? WLAN_STATUS_SUCCESS
:
4518 WLAN_STATUS_AUTH_TIMEOUT
,
4520 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4521 completed
? "succeeded" : "failed");
4523 brcmf_dbg(TRACE
, "Exit\n");
4528 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4529 struct net_device
*ndev
,
4530 const struct brcmf_event_msg
*e
, void *data
)
4532 static int generation
;
4533 u32 event
= e
->event_code
;
4534 u32 reason
= e
->reason
;
4535 struct station_info sinfo
;
4537 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4538 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
4539 ndev
!= cfg_to_ndev(cfg
)) {
4540 brcmf_dbg(CONN
, "AP mode link down\n");
4541 complete(&cfg
->vif_disabled
);
4545 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4546 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4547 memset(&sinfo
, 0, sizeof(sinfo
));
4548 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4550 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4553 sinfo
.assoc_req_ies
= data
;
4554 sinfo
.assoc_req_ies_len
= e
->datalen
;
4556 sinfo
.generation
= generation
;
4557 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4558 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4559 (event
== BRCMF_E_DEAUTH_IND
) ||
4560 (event
== BRCMF_E_DEAUTH
)) {
4561 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4567 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4568 const struct brcmf_event_msg
*e
, void *data
)
4570 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4571 struct net_device
*ndev
= ifp
->ndev
;
4572 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4575 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4576 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4577 } else if (brcmf_is_linkup(e
)) {
4578 brcmf_dbg(CONN
, "Linkup\n");
4579 if (brcmf_is_ibssmode(ifp
->vif
)) {
4580 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4581 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4582 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4583 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4584 &ifp
->vif
->sme_state
);
4585 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4586 &ifp
->vif
->sme_state
);
4588 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4589 } else if (brcmf_is_linkdown(e
)) {
4590 brcmf_dbg(CONN
, "Linkdown\n");
4591 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4592 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4593 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4594 &ifp
->vif
->sme_state
))
4595 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4598 brcmf_link_down(ifp
->vif
);
4599 brcmf_init_prof(ndev_to_prof(ndev
));
4600 if (ndev
!= cfg_to_ndev(cfg
))
4601 complete(&cfg
->vif_disabled
);
4602 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4603 if (brcmf_is_ibssmode(ifp
->vif
))
4604 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4605 &ifp
->vif
->sme_state
);
4607 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4614 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4615 const struct brcmf_event_msg
*e
, void *data
)
4617 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4619 u32 event
= e
->event_code
;
4620 u32 status
= e
->status
;
4622 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4623 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4624 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4626 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4633 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4634 const struct brcmf_event_msg
*e
, void *data
)
4636 u16 flags
= e
->flags
;
4637 enum nl80211_key_type key_type
;
4639 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4640 key_type
= NL80211_KEYTYPE_GROUP
;
4642 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4644 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4650 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4651 const struct brcmf_event_msg
*e
, void *data
)
4653 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4654 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4655 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4656 struct brcmf_cfg80211_vif
*vif
;
4658 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4659 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4662 mutex_lock(&event
->vif_event_lock
);
4663 event
->action
= ifevent
->action
;
4666 switch (ifevent
->action
) {
4667 case BRCMF_E_IF_ADD
:
4668 /* waiting process may have timed out */
4669 if (!cfg
->vif_event
.vif
)
4674 vif
->wdev
.netdev
= ifp
->ndev
;
4675 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4676 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4677 mutex_unlock(&event
->vif_event_lock
);
4678 wake_up(&event
->vif_wq
);
4680 /* waiting process need to set the netdev name */
4681 wait_for_completion(&event
->vif_complete
);
4682 return brcmf_net_attach(ifp
);
4684 case BRCMF_E_IF_DEL
:
4686 mutex_unlock(&event
->vif_event_lock
);
4687 /* event may not be upon user request */
4688 if (brcmf_cfg80211_vif_event_armed(cfg
))
4689 wake_up(&event
->vif_wq
);
4692 case BRCMF_E_IF_CHANGE
:
4693 mutex_unlock(&event
->vif_event_lock
);
4694 wake_up(&event
->vif_wq
);
4698 mutex_unlock(&event
->vif_event_lock
);
4704 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4706 conf
->frag_threshold
= (u32
)-1;
4707 conf
->rts_threshold
= (u32
)-1;
4708 conf
->retry_short
= (u32
)-1;
4709 conf
->retry_long
= (u32
)-1;
4710 conf
->tx_power
= -1;
4713 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4715 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4716 brcmf_notify_connect_status
);
4717 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4718 brcmf_notify_connect_status
);
4719 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4720 brcmf_notify_connect_status
);
4721 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4722 brcmf_notify_connect_status
);
4723 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4724 brcmf_notify_connect_status
);
4725 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4726 brcmf_notify_connect_status
);
4727 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4728 brcmf_notify_roaming_status
);
4729 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4730 brcmf_notify_mic_status
);
4731 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4732 brcmf_notify_connect_status
);
4733 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4734 brcmf_notify_sched_scan_results
);
4735 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4736 brcmf_notify_vif_event
);
4737 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
4738 brcmf_notify_rx_mgmt_p2p_probereq
);
4739 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
4740 brcmf_p2p_notify_listen_complete
);
4741 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
4742 brcmf_p2p_notify_action_frame_rx
);
4743 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
4744 brcmf_p2p_notify_action_tx_complete
);
4747 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4751 kfree(cfg
->escan_ioctl_buf
);
4752 cfg
->escan_ioctl_buf
= NULL
;
4753 kfree(cfg
->extra_buf
);
4754 cfg
->extra_buf
= NULL
;
4755 kfree(cfg
->pmk_list
);
4756 cfg
->pmk_list
= NULL
;
4759 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4761 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4763 goto init_priv_mem_out
;
4764 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4765 if (!cfg
->escan_ioctl_buf
)
4766 goto init_priv_mem_out
;
4767 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4768 if (!cfg
->extra_buf
)
4769 goto init_priv_mem_out
;
4770 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4772 goto init_priv_mem_out
;
4777 brcmf_deinit_priv_mem(cfg
);
4782 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4786 cfg
->scan_request
= NULL
;
4787 cfg
->pwr_save
= true;
4788 cfg
->roam_on
= true; /* roam on & off switch.
4789 we enable roam per default */
4790 cfg
->active_scan
= true; /* we do active scan for
4791 specific scan per default */
4792 cfg
->dongle_up
= false; /* dongle is not up yet */
4793 err
= brcmf_init_priv_mem(cfg
);
4796 brcmf_register_event_handlers(cfg
);
4797 mutex_init(&cfg
->usr_sync
);
4798 brcmf_init_escan(cfg
);
4799 brcmf_init_conf(cfg
->conf
);
4800 init_completion(&cfg
->vif_disabled
);
4804 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4806 cfg
->dongle_up
= false; /* dongle down */
4807 brcmf_abort_scanning(cfg
);
4808 brcmf_deinit_priv_mem(cfg
);
4811 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4813 init_waitqueue_head(&event
->vif_wq
);
4814 init_completion(&event
->vif_complete
);
4815 mutex_init(&event
->vif_event_lock
);
4818 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4819 struct device
*busdev
)
4821 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4822 struct brcmf_cfg80211_info
*cfg
;
4823 struct wiphy
*wiphy
;
4824 struct brcmf_cfg80211_vif
*vif
;
4825 struct brcmf_if
*ifp
;
4829 brcmf_err("ndev is invalid\n");
4833 ifp
= netdev_priv(ndev
);
4834 wiphy
= brcmf_setup_wiphy(busdev
);
4838 cfg
= wiphy_priv(wiphy
);
4841 init_vif_event(&cfg
->vif_event
);
4842 INIT_LIST_HEAD(&cfg
->vif_list
);
4844 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4851 vif
->wdev
.netdev
= ndev
;
4852 ndev
->ieee80211_ptr
= &vif
->wdev
;
4853 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4855 err
= wl_init_priv(cfg
);
4857 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4858 goto cfg80211_attach_out
;
4860 brcmf_p2p_attach(cfg
, vif
);
4865 cfg80211_attach_out
:
4866 brcmf_free_vif(vif
);
4871 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4873 struct brcmf_cfg80211_vif
*vif
;
4874 struct brcmf_cfg80211_vif
*tmp
;
4876 wl_deinit_priv(cfg
);
4877 list_for_each_entry_safe(vif
, tmp
, &cfg
->vif_list
, list
) {
4878 brcmf_free_vif(vif
);
4883 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
4886 __le32 roamtrigger
[2];
4887 __le32 roam_delta
[2];
4890 * Setup timeout if Beacons are lost and roam is
4891 * off to report link down
4894 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
4896 brcmf_err("bcn_timeout error (%d)\n", err
);
4897 goto dongle_rom_out
;
4902 * Enable/Disable built-in roaming to allow supplicant
4903 * to take care of roaming
4905 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
4906 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
4908 brcmf_err("roam_off error (%d)\n", err
);
4909 goto dongle_rom_out
;
4912 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
4913 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4914 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
4915 (void *)roamtrigger
, sizeof(roamtrigger
));
4917 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
4918 goto dongle_rom_out
;
4921 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
4922 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
4923 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
4924 (void *)roam_delta
, sizeof(roam_delta
));
4926 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
4927 goto dongle_rom_out
;
4935 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
4936 s32 scan_unassoc_time
, s32 scan_passive_time
)
4940 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
4943 if (err
== -EOPNOTSUPP
)
4944 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
4946 brcmf_err("Scan assoc time error (%d)\n", err
);
4947 goto dongle_scantime_out
;
4949 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
4952 if (err
== -EOPNOTSUPP
)
4953 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
4955 brcmf_err("Scan unassoc time error (%d)\n", err
);
4956 goto dongle_scantime_out
;
4959 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
4962 if (err
== -EOPNOTSUPP
)
4963 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
4965 brcmf_err("Scan passive time error (%d)\n", err
);
4966 goto dongle_scantime_out
;
4969 dongle_scantime_out
:
4973 static s32
wl_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
4975 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
4976 struct wiphy
*wiphy
;
4981 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
4982 &phy_list
, sizeof(phy_list
));
4984 brcmf_err("error (%d)\n", err
);
4988 phy
= ((char *)&phy_list
)[0];
4989 brcmf_dbg(INFO
, "%c phy\n", phy
);
4990 if (phy
== 'n' || phy
== 'a') {
4991 wiphy
= cfg_to_wiphy(cfg
);
4992 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = &__wl_band_5ghz_n
;
4998 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5000 return wl_update_wiphybands(cfg
);
5003 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5005 struct net_device
*ndev
;
5006 struct wireless_dev
*wdev
;
5007 struct brcmf_if
*ifp
;
5014 ndev
= cfg_to_ndev(cfg
);
5015 wdev
= ndev
->ieee80211_ptr
;
5016 ifp
= netdev_priv(ndev
);
5018 /* make sure RF is ready for work */
5019 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
5021 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
5022 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5024 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5025 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
5027 goto default_conf_out
;
5028 brcmf_dbg(INFO
, "power save set to %s\n",
5029 (power_mode
? "enabled" : "disabled"));
5031 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
5033 goto default_conf_out
;
5034 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5037 goto default_conf_out
;
5038 err
= brcmf_dongle_probecap(cfg
);
5040 goto default_conf_out
;
5042 cfg
->dongle_up
= true;
5049 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
5051 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5053 return brcmf_config_dongle(ifp
->drvr
->config
);
5056 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
5058 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5061 * While going down, if associated with AP disassociate
5062 * from AP to save power
5064 if (check_vif_up(ifp
->vif
)) {
5065 brcmf_link_down(ifp
->vif
);
5067 /* Make sure WPA_Supplicant receives all the event
5068 generated due to DISASSOC call to the fw to keep
5069 the state fw and WPA_Supplicant state consistent
5074 brcmf_abort_scanning(cfg
);
5075 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5080 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
5082 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5083 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5086 mutex_lock(&cfg
->usr_sync
);
5087 err
= __brcmf_cfg80211_up(ifp
);
5088 mutex_unlock(&cfg
->usr_sync
);
5093 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
5095 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5096 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5099 mutex_lock(&cfg
->usr_sync
);
5100 err
= __brcmf_cfg80211_down(ifp
);
5101 mutex_unlock(&cfg
->usr_sync
);
5106 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
5108 struct brcmf_cfg80211_vif
*vif
;
5111 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
5112 if (test_bit(state
, &vif
->sme_state
))
5118 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
5123 mutex_lock(&event
->vif_event_lock
);
5124 evt_action
= event
->action
;
5125 mutex_unlock(&event
->vif_event_lock
);
5126 return evt_action
== action
;
5129 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
5130 struct brcmf_cfg80211_vif
*vif
)
5132 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5134 mutex_lock(&event
->vif_event_lock
);
5137 mutex_unlock(&event
->vif_event_lock
);
5140 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
5142 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5145 mutex_lock(&event
->vif_event_lock
);
5146 armed
= event
->vif
!= NULL
;
5147 mutex_unlock(&event
->vif_event_lock
);
5151 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
5152 u8 action
, ulong timeout
)
5154 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5156 return wait_event_timeout(event
->vif_wq
,
5157 vif_event_equals(event
, action
), timeout
);
5160 void brcmf_cfg80211_vif_complete(struct brcmf_cfg80211_info
*cfg
)
5162 complete(&cfg
->vif_event
.vif_complete
);