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 "tracepoint.h"
30 #include "fwil_types.h"
33 #include "wl_cfg80211.h"
36 #define BRCMF_SCAN_IE_LEN_MAX 2048
37 #define BRCMF_PNO_VERSION 2
38 #define BRCMF_PNO_TIME 30
39 #define BRCMF_PNO_REPEAT 4
40 #define BRCMF_PNO_FREQ_EXPO_MAX 3
41 #define BRCMF_PNO_MAX_PFN_COUNT 16
42 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
43 #define BRCMF_PNO_HIDDEN_BIT 2
44 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
45 #define BRCMF_PNO_SCAN_COMPLETE 1
46 #define BRCMF_PNO_SCAN_INCOMPLETE 0
48 #define BRCMF_IFACE_MAX_CNT 3
50 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
51 #define WPA_OUI_TYPE 1
52 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
53 #define WME_OUI_TYPE 2
54 #define WPS_OUI_TYPE 4
56 #define VS_IE_FIXED_HDR_LEN 6
57 #define WPA_IE_VERSION_LEN 2
58 #define WPA_IE_MIN_OUI_LEN 4
59 #define WPA_IE_SUITE_COUNT_LEN 2
61 #define WPA_CIPHER_NONE 0 /* None */
62 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
63 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
64 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
65 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
67 #define RSN_AKM_NONE 0 /* None (IBSS) */
68 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
69 #define RSN_AKM_PSK 2 /* Pre-shared Key */
70 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
71 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
73 #define VNDR_IE_CMD_LEN 4 /* length of the set command
74 * string :"add", "del" (+ NUL)
76 #define VNDR_IE_COUNT_OFFSET 4
77 #define VNDR_IE_PKTFLAG_OFFSET 8
78 #define VNDR_IE_VSIE_OFFSET 12
79 #define VNDR_IE_HDR_SIZE 12
80 #define VNDR_IE_PARSE_LIMIT 5
82 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
83 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
85 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
86 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
87 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
89 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
90 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
92 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
94 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
95 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
102 #define CHAN2G(_channel, _freq, _flags) { \
103 .band = IEEE80211_BAND_2GHZ, \
104 .center_freq = (_freq), \
105 .hw_value = (_channel), \
107 .max_antenna_gain = 0, \
111 #define CHAN5G(_channel, _flags) { \
112 .band = IEEE80211_BAND_5GHZ, \
113 .center_freq = 5000 + (5 * (_channel)), \
114 .hw_value = (_channel), \
116 .max_antenna_gain = 0, \
120 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
121 #define RATETAB_ENT(_rateid, _flags) \
123 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
124 .hw_value = (_rateid), \
128 static struct ieee80211_rate __wl_rates
[] = {
129 RATETAB_ENT(BRCM_RATE_1M
, 0),
130 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
131 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
132 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
133 RATETAB_ENT(BRCM_RATE_6M
, 0),
134 RATETAB_ENT(BRCM_RATE_9M
, 0),
135 RATETAB_ENT(BRCM_RATE_12M
, 0),
136 RATETAB_ENT(BRCM_RATE_18M
, 0),
137 RATETAB_ENT(BRCM_RATE_24M
, 0),
138 RATETAB_ENT(BRCM_RATE_36M
, 0),
139 RATETAB_ENT(BRCM_RATE_48M
, 0),
140 RATETAB_ENT(BRCM_RATE_54M
, 0),
143 #define wl_a_rates (__wl_rates + 4)
144 #define wl_a_rates_size 8
145 #define wl_g_rates (__wl_rates + 0)
146 #define wl_g_rates_size 12
148 static struct ieee80211_channel __wl_2ghz_channels
[] = {
165 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
166 CHAN5G(34, 0), CHAN5G(36, 0),
167 CHAN5G(38, 0), CHAN5G(40, 0),
168 CHAN5G(42, 0), CHAN5G(44, 0),
169 CHAN5G(46, 0), CHAN5G(48, 0),
170 CHAN5G(52, 0), CHAN5G(56, 0),
171 CHAN5G(60, 0), CHAN5G(64, 0),
172 CHAN5G(100, 0), CHAN5G(104, 0),
173 CHAN5G(108, 0), CHAN5G(112, 0),
174 CHAN5G(116, 0), CHAN5G(120, 0),
175 CHAN5G(124, 0), CHAN5G(128, 0),
176 CHAN5G(132, 0), CHAN5G(136, 0),
177 CHAN5G(140, 0), CHAN5G(149, 0),
178 CHAN5G(153, 0), CHAN5G(157, 0),
179 CHAN5G(161, 0), CHAN5G(165, 0),
180 CHAN5G(184, 0), CHAN5G(188, 0),
181 CHAN5G(192, 0), CHAN5G(196, 0),
182 CHAN5G(200, 0), CHAN5G(204, 0),
183 CHAN5G(208, 0), CHAN5G(212, 0),
187 static struct ieee80211_supported_band __wl_band_2ghz
= {
188 .band
= IEEE80211_BAND_2GHZ
,
189 .channels
= __wl_2ghz_channels
,
190 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
191 .bitrates
= wl_g_rates
,
192 .n_bitrates
= wl_g_rates_size
,
195 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
196 .band
= IEEE80211_BAND_5GHZ
,
197 .channels
= __wl_5ghz_a_channels
,
198 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
199 .bitrates
= wl_a_rates
,
200 .n_bitrates
= wl_a_rates_size
,
203 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
204 * By default world regulatory domain defined in reg.c puts the flags
205 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206 * With respect to these flags, wpa_supplicant doesn't * start p2p
207 * operations on 5GHz channels. All the changes in world regulatory
208 * domain are to be done here.
210 static const struct ieee80211_regdomain brcmf_regdom
= {
214 /* IEEE 802.11b/g, channels 1..11 */
215 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
217 /* IEEE 802.11 channel 14 - Only JP enables
218 * this and for 802.11b only
220 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
221 /* IEEE 802.11a, channel 36..64 */
222 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
223 /* IEEE 802.11a, channel 100..165 */
224 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
227 static const u32 __wl_cipher_suites
[] = {
228 WLAN_CIPHER_SUITE_WEP40
,
229 WLAN_CIPHER_SUITE_WEP104
,
230 WLAN_CIPHER_SUITE_TKIP
,
231 WLAN_CIPHER_SUITE_CCMP
,
232 WLAN_CIPHER_SUITE_AES_CMAC
,
235 /* Vendor specific ie. id = 221, oui and type defines exact ie */
236 struct brcmf_vs_tlv
{
243 struct parsed_vndr_ie_info
{
245 u32 ie_len
; /* total length including id & length field */
246 struct brcmf_vs_tlv vndrie
;
249 struct parsed_vndr_ies
{
251 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
254 /* Quarter dBm units to mW
255 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
256 * Table is offset so the last entry is largest mW value that fits in
260 #define QDBM_OFFSET 153 /* Offset for first entry */
261 #define QDBM_TABLE_LEN 40 /* Table size */
263 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
264 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
266 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
268 /* Largest mW value that will round down to the last table entry,
269 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
270 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
271 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
273 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
275 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
276 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
277 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
278 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
279 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
280 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
281 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
284 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
287 int idx
= qdbm
- QDBM_OFFSET
;
289 if (idx
>= QDBM_TABLE_LEN
)
290 /* clamp to max u16 mW value */
293 /* scale the qdBm index up to the range of the table 0-40
294 * where an offset of 40 qdBm equals a factor of 10 mW.
301 /* return the mW value scaled down to the correct factor of 10,
302 * adding in factor/2 to get proper rounding.
304 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
307 static u8
brcmf_mw_to_qdbm(u16 mw
)
314 /* handle boundary case */
318 offset
= QDBM_OFFSET
;
320 /* move mw into the range of the table */
321 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
326 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
327 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
328 nqdBm_to_mW_map
[qdbm
]) / 2;
329 if (mw_uint
< boundary
)
338 u16
channel_to_chanspec(struct brcmu_d11inf
*d11inf
,
339 struct ieee80211_channel
*ch
)
341 struct brcmu_chan ch_inf
;
343 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq
);
344 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
345 d11inf
->encchspec(&ch_inf
);
347 return ch_inf
.chspec
;
350 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
351 * triples, returning a pointer to the substring whose first element
354 const struct brcmf_tlv
*
355 brcmf_parse_tlvs(const void *buf
, int buflen
, uint key
)
357 const struct brcmf_tlv
*elt
= buf
;
360 /* find tagged parameter */
361 while (totlen
>= TLV_HDR_LEN
) {
364 /* validate remaining totlen */
365 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
368 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
369 totlen
-= (len
+ TLV_HDR_LEN
);
375 /* Is any of the tlvs the expected entry? If
376 * not update the tlvs buffer pointer/length.
379 brcmf_tlv_has_ie(const u8
*ie
, const u8
**tlvs
, u32
*tlvs_len
,
380 const u8
*oui
, u32 oui_len
, u8 type
)
382 /* If the contents match the OUI and the type */
383 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
384 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
385 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
391 /* point to the next ie */
392 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
393 /* calculate the length of the rest of the buffer */
394 *tlvs_len
-= (int)(ie
- *tlvs
);
395 /* update the pointer to the start of the buffer */
401 static struct brcmf_vs_tlv
*
402 brcmf_find_wpaie(const u8
*parse
, u32 len
)
404 const struct brcmf_tlv
*ie
;
406 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
407 if (brcmf_tlv_has_ie((const u8
*)ie
, &parse
, &len
,
408 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
409 return (struct brcmf_vs_tlv
*)ie
;
414 static struct brcmf_vs_tlv
*
415 brcmf_find_wpsie(const u8
*parse
, u32 len
)
417 const struct brcmf_tlv
*ie
;
419 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
420 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
421 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
422 return (struct brcmf_vs_tlv
*)ie
;
428 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
429 struct brcmf_wsec_key_le
*key_le
)
431 key_le
->index
= cpu_to_le32(key
->index
);
432 key_le
->len
= cpu_to_le32(key
->len
);
433 key_le
->algo
= cpu_to_le32(key
->algo
);
434 key_le
->flags
= cpu_to_le32(key
->flags
);
435 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
436 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
437 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
438 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
439 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
443 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
446 struct brcmf_wsec_key_le key_le
;
448 convert_key_from_CPU(key
, &key_le
);
450 brcmf_netdev_wait_pend8021x(ndev
);
452 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
456 brcmf_err("wsec_key error (%d)\n", err
);
461 brcmf_configure_arp_offload(struct brcmf_if
*ifp
, bool enable
)
467 mode
= BRCMF_ARP_OL_AGENT
| BRCMF_ARP_OL_PEER_AUTO_REPLY
;
471 /* Try to set and enable ARP offload feature, this may fail, then it */
472 /* is simply not supported and err 0 will be returned */
473 err
= brcmf_fil_iovar_int_set(ifp
, "arp_ol", mode
);
475 brcmf_dbg(TRACE
, "failed to set ARP offload mode to 0x%x, err = %d\n",
479 err
= brcmf_fil_iovar_int_set(ifp
, "arpoe", enable
);
481 brcmf_dbg(TRACE
, "failed to configure (%d) ARP offload err = %d\n",
485 brcmf_dbg(TRACE
, "successfully configured (%d) ARP offload to 0x%x\n",
492 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
494 enum nl80211_iftype type
,
496 struct vif_params
*params
)
498 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
500 case NL80211_IFTYPE_ADHOC
:
501 case NL80211_IFTYPE_STATION
:
502 case NL80211_IFTYPE_AP
:
503 case NL80211_IFTYPE_AP_VLAN
:
504 case NL80211_IFTYPE_WDS
:
505 case NL80211_IFTYPE_MONITOR
:
506 case NL80211_IFTYPE_MESH_POINT
:
507 return ERR_PTR(-EOPNOTSUPP
);
508 case NL80211_IFTYPE_P2P_CLIENT
:
509 case NL80211_IFTYPE_P2P_GO
:
510 case NL80211_IFTYPE_P2P_DEVICE
:
511 return brcmf_p2p_add_vif(wiphy
, name
, type
, flags
, params
);
512 case NL80211_IFTYPE_UNSPECIFIED
:
514 return ERR_PTR(-EINVAL
);
518 void brcmf_set_mpc(struct brcmf_if
*ifp
, int mpc
)
522 if (check_vif_up(ifp
->vif
)) {
523 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
525 brcmf_err("fail to set mpc\n");
528 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
532 s32
brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
533 struct brcmf_if
*ifp
, bool aborted
,
536 struct brcmf_scan_params_le params_le
;
537 struct cfg80211_scan_request
*scan_request
;
540 brcmf_dbg(SCAN
, "Enter\n");
542 /* clear scan request, because the FW abort can cause a second call */
543 /* to this functon and might cause a double cfg80211_scan_done */
544 scan_request
= cfg
->scan_request
;
545 cfg
->scan_request
= NULL
;
547 if (timer_pending(&cfg
->escan_timeout
))
548 del_timer_sync(&cfg
->escan_timeout
);
551 /* Do a scan abort to stop the driver's scan engine */
552 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
553 memset(¶ms_le
, 0, sizeof(params_le
));
554 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
555 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
556 params_le
.scan_type
= 0;
557 params_le
.channel_num
= cpu_to_le32(1);
558 params_le
.nprobes
= cpu_to_le32(1);
559 params_le
.active_time
= cpu_to_le32(-1);
560 params_le
.passive_time
= cpu_to_le32(-1);
561 params_le
.home_time
= cpu_to_le32(-1);
562 /* Scan is aborted by setting channel_list[0] to -1 */
563 params_le
.channel_list
[0] = cpu_to_le16(-1);
564 /* E-Scan (or anyother type) can be aborted by SCAN */
565 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
566 ¶ms_le
, sizeof(params_le
));
568 brcmf_err("Scan abort failed\n");
571 * e-scan can be initiated by scheduled scan
572 * which takes precedence.
574 if (cfg
->sched_escan
) {
575 brcmf_dbg(SCAN
, "scheduled scan completed\n");
576 cfg
->sched_escan
= false;
578 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
579 brcmf_set_mpc(ifp
, 1);
580 } else if (scan_request
) {
581 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
582 aborted
? "Aborted" : "Done");
583 cfg80211_scan_done(scan_request
, aborted
);
584 brcmf_set_mpc(ifp
, 1);
586 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
587 brcmf_dbg(SCAN
, "Scan complete, probably P2P scan\n");
593 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
595 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
596 struct net_device
*ndev
= wdev
->netdev
;
598 /* vif event pending in firmware */
599 if (brcmf_cfg80211_vif_event_armed(cfg
))
603 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
604 cfg
->escan_info
.ifp
== netdev_priv(ndev
))
605 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
),
608 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
611 switch (wdev
->iftype
) {
612 case NL80211_IFTYPE_ADHOC
:
613 case NL80211_IFTYPE_STATION
:
614 case NL80211_IFTYPE_AP
:
615 case NL80211_IFTYPE_AP_VLAN
:
616 case NL80211_IFTYPE_WDS
:
617 case NL80211_IFTYPE_MONITOR
:
618 case NL80211_IFTYPE_MESH_POINT
:
620 case NL80211_IFTYPE_P2P_CLIENT
:
621 case NL80211_IFTYPE_P2P_GO
:
622 case NL80211_IFTYPE_P2P_DEVICE
:
623 return brcmf_p2p_del_vif(wiphy
, wdev
);
624 case NL80211_IFTYPE_UNSPECIFIED
:
632 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
633 enum nl80211_iftype type
, u32
*flags
,
634 struct vif_params
*params
)
636 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
637 struct brcmf_if
*ifp
= netdev_priv(ndev
);
638 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
643 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
646 case NL80211_IFTYPE_MONITOR
:
647 case NL80211_IFTYPE_WDS
:
648 brcmf_err("type (%d) : currently we do not support this type\n",
651 case NL80211_IFTYPE_ADHOC
:
652 vif
->mode
= WL_MODE_IBSS
;
655 case NL80211_IFTYPE_STATION
:
656 /* Ignore change for p2p IF. Unclear why supplicant does this */
657 if ((vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) ||
658 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
)) {
659 brcmf_dbg(TRACE
, "Ignoring cmd for p2p if\n");
660 /* WAR: It is unexpected to get a change of VIF for P2P
661 * IF, but it happens. The request can not be handled
662 * but returning EPERM causes a crash. Returning 0
663 * without setting ieee80211_ptr->iftype causes trace
664 * (WARN_ON) but it works with wpa_supplicant
668 vif
->mode
= WL_MODE_BSS
;
671 case NL80211_IFTYPE_AP
:
672 case NL80211_IFTYPE_P2P_GO
:
673 vif
->mode
= WL_MODE_AP
;
682 if (type
== NL80211_IFTYPE_P2P_GO
) {
683 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
684 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
687 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
688 brcmf_dbg(INFO
, "IF Type = AP\n");
691 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
693 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
697 brcmf_dbg(INFO
, "IF Type = %s\n", (vif
->mode
== WL_MODE_IBSS
) ?
700 ndev
->ieee80211_ptr
->iftype
= type
;
703 brcmf_dbg(TRACE
, "Exit\n");
708 static void brcmf_escan_prep(struct brcmf_cfg80211_info
*cfg
,
709 struct brcmf_scan_params_le
*params_le
,
710 struct cfg80211_scan_request
*request
)
718 struct brcmf_ssid_le ssid_le
;
720 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
721 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
722 params_le
->scan_type
= 0;
723 params_le
->channel_num
= 0;
724 params_le
->nprobes
= cpu_to_le32(-1);
725 params_le
->active_time
= cpu_to_le32(-1);
726 params_le
->passive_time
= cpu_to_le32(-1);
727 params_le
->home_time
= cpu_to_le32(-1);
728 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
730 /* if request is null exit so it will be all channel broadcast scan */
734 n_ssids
= request
->n_ssids
;
735 n_channels
= request
->n_channels
;
736 /* Copy channel array if applicable */
737 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
739 if (n_channels
> 0) {
740 for (i
= 0; i
< n_channels
; i
++) {
741 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
742 request
->channels
[i
]);
743 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
744 request
->channels
[i
]->hw_value
, chanspec
);
745 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
748 brcmf_dbg(SCAN
, "Scanning all channels\n");
750 /* Copy ssid array if applicable */
751 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
753 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
754 n_channels
* sizeof(u16
);
755 offset
= roundup(offset
, sizeof(u32
));
756 ptr
= (char *)params_le
+ offset
;
757 for (i
= 0; i
< n_ssids
; i
++) {
758 memset(&ssid_le
, 0, sizeof(ssid_le
));
760 cpu_to_le32(request
->ssids
[i
].ssid_len
);
761 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
762 request
->ssids
[i
].ssid_len
);
763 if (!ssid_le
.SSID_len
)
764 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
766 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
767 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
768 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
769 ptr
+= sizeof(ssid_le
);
772 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
773 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
774 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
775 params_le
->ssid_le
.SSID
,
776 request
->ssids
->ssid_len
);
777 params_le
->ssid_le
.SSID_len
=
778 cpu_to_le32(request
->ssids
->ssid_len
);
779 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
780 request
->ssids
->ssid_len
);
783 /* Adding mask to channel numbers */
784 params_le
->channel_num
=
785 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
786 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
790 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
,
791 struct cfg80211_scan_request
*request
, u16 action
)
793 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
794 offsetof(struct brcmf_escan_params_le
, params_le
);
795 struct brcmf_escan_params_le
*params
;
798 brcmf_dbg(SCAN
, "E-SCAN START\n");
800 if (request
!= NULL
) {
801 /* Allocate space for populating ssids in struct */
802 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
804 /* Allocate space for populating ssids in struct */
805 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
808 params
= kzalloc(params_size
, GFP_KERNEL
);
813 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
814 brcmf_escan_prep(cfg
, ¶ms
->params_le
, request
);
815 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
816 params
->action
= cpu_to_le16(action
);
817 params
->sync_id
= cpu_to_le16(0x1234);
819 err
= brcmf_fil_iovar_data_set(ifp
, "escan", params
, params_size
);
822 brcmf_dbg(INFO
, "system busy : escan canceled\n");
824 brcmf_err("error (%d)\n", err
);
833 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
834 struct brcmf_if
*ifp
, struct cfg80211_scan_request
*request
)
838 struct brcmf_scan_results
*results
;
839 struct escan_info
*escan
= &cfg
->escan_info
;
841 brcmf_dbg(SCAN
, "Enter\n");
843 escan
->wiphy
= wiphy
;
844 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
845 passive_scan
= cfg
->active_scan
? 0 : 1;
846 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
849 brcmf_err("error (%d)\n", err
);
852 brcmf_set_mpc(ifp
, 0);
853 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
854 results
->version
= 0;
856 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
858 err
= escan
->run(cfg
, ifp
, request
, WL_ESCAN_ACTION_START
);
860 brcmf_set_mpc(ifp
, 1);
865 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct brcmf_cfg80211_vif
*vif
,
866 struct cfg80211_scan_request
*request
,
867 struct cfg80211_ssid
*this_ssid
)
869 struct brcmf_if
*ifp
= vif
->ifp
;
870 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
871 struct cfg80211_ssid
*ssids
;
872 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
879 brcmf_dbg(SCAN
, "START ESCAN\n");
881 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
882 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
885 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
886 brcmf_err("Scanning being aborted: status (%lu)\n",
890 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
891 brcmf_err("Scanning suppressed: status (%lu)\n",
895 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
896 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
900 /* If scan req comes for p2p0, send it over primary I/F */
901 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
902 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
;
904 /* Arm scan timeout timer */
905 mod_timer(&cfg
->escan_timeout
, jiffies
+
906 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
911 ssids
= request
->ssids
;
915 /* we don't do escan in ibss */
919 cfg
->scan_request
= request
;
920 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
922 cfg
->escan_info
.run
= brcmf_run_escan
;
923 err
= brcmf_p2p_scan_prep(wiphy
, request
, vif
);
927 err
= brcmf_do_escan(cfg
, wiphy
, vif
->ifp
, request
);
931 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
932 ssids
->ssid
, ssids
->ssid_len
);
933 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
934 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
935 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
938 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
939 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
942 brcmf_dbg(SCAN
, "Broadcast scan\n");
944 passive_scan
= cfg
->active_scan
? 0 : 1;
945 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
948 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
951 brcmf_set_mpc(ifp
, 0);
952 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
953 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
956 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
959 brcmf_err("WLC_SCAN error (%d)\n", err
);
961 brcmf_set_mpc(ifp
, 1);
969 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
970 if (timer_pending(&cfg
->escan_timeout
))
971 del_timer_sync(&cfg
->escan_timeout
);
972 cfg
->scan_request
= NULL
;
977 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
979 struct brcmf_cfg80211_vif
*vif
;
982 brcmf_dbg(TRACE
, "Enter\n");
983 vif
= container_of(request
->wdev
, struct brcmf_cfg80211_vif
, wdev
);
984 if (!check_vif_up(vif
))
987 err
= brcmf_cfg80211_escan(wiphy
, vif
, request
, NULL
);
990 brcmf_err("scan error (%d)\n", err
);
992 brcmf_dbg(TRACE
, "Exit\n");
996 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1000 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1003 brcmf_err("Error (%d)\n", err
);
1008 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1012 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1015 brcmf_err("Error (%d)\n", err
);
1020 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1023 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1025 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1027 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1033 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1035 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1036 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1037 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1040 brcmf_dbg(TRACE
, "Enter\n");
1041 if (!check_vif_up(ifp
->vif
))
1044 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1045 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1046 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1047 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1051 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1052 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1053 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1054 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1058 if (changed
& WIPHY_PARAM_RETRY_LONG
1059 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1060 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1061 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1065 if (changed
& WIPHY_PARAM_RETRY_SHORT
1066 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1067 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1068 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1074 brcmf_dbg(TRACE
, "Exit\n");
1078 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1080 memset(prof
, 0, sizeof(*prof
));
1083 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
1085 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(vif
->wdev
.wiphy
);
1088 brcmf_dbg(TRACE
, "Enter\n");
1090 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1091 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1092 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1093 BRCMF_C_DISASSOC
, NULL
, 0);
1095 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1097 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
1098 cfg80211_disconnected(vif
->wdev
.netdev
, 0, NULL
, 0, GFP_KERNEL
);
1101 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1102 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
1103 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
1104 brcmf_dbg(TRACE
, "Exit\n");
1108 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1109 struct cfg80211_ibss_params
*params
)
1111 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1112 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1113 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1114 struct brcmf_join_params join_params
;
1115 size_t join_params_size
= 0;
1121 brcmf_dbg(TRACE
, "Enter\n");
1122 if (!check_vif_up(ifp
->vif
))
1126 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1128 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1132 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1135 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1137 brcmf_dbg(CONN
, "No BSSID specified\n");
1139 if (params
->chandef
.chan
)
1140 brcmf_dbg(CONN
, "channel: %d\n",
1141 params
->chandef
.chan
->center_freq
);
1143 brcmf_dbg(CONN
, "no channel specified\n");
1145 if (params
->channel_fixed
)
1146 brcmf_dbg(CONN
, "fixed channel required\n");
1148 brcmf_dbg(CONN
, "no fixed channel required\n");
1150 if (params
->ie
&& params
->ie_len
)
1151 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1153 brcmf_dbg(CONN
, "no ie specified\n");
1155 if (params
->beacon_interval
)
1156 brcmf_dbg(CONN
, "beacon interval: %d\n",
1157 params
->beacon_interval
);
1159 brcmf_dbg(CONN
, "no beacon interval specified\n");
1161 if (params
->basic_rates
)
1162 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1164 brcmf_dbg(CONN
, "no basic rates specified\n");
1166 if (params
->privacy
)
1167 brcmf_dbg(CONN
, "privacy required\n");
1169 brcmf_dbg(CONN
, "no privacy required\n");
1171 /* Configure Privacy for starter */
1172 if (params
->privacy
)
1173 wsec
|= WEP_ENABLED
;
1175 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1177 brcmf_err("wsec failed (%d)\n", err
);
1181 /* Configure Beacon Interval for starter */
1182 if (params
->beacon_interval
)
1183 bcnprd
= params
->beacon_interval
;
1187 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1189 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1193 /* Configure required join parameter */
1194 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1197 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1198 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1199 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1200 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1201 join_params_size
= sizeof(join_params
.ssid_le
);
1204 if (params
->bssid
) {
1205 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1206 join_params_size
= sizeof(join_params
.ssid_le
) +
1207 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1208 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1210 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1211 memset(profile
->bssid
, 0, ETH_ALEN
);
1215 if (params
->chandef
.chan
) {
1219 ieee80211_frequency_to_channel(
1220 params
->chandef
.chan
->center_freq
);
1221 if (params
->channel_fixed
) {
1222 /* adding chanspec */
1223 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
1224 params
->chandef
.chan
);
1225 join_params
.params_le
.chanspec_list
[0] =
1226 cpu_to_le16(chanspec
);
1227 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1228 join_params_size
+= sizeof(join_params
.params_le
);
1231 /* set channel for starter */
1232 target_channel
= cfg
->channel
;
1233 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1236 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1242 cfg
->ibss_starter
= false;
1245 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1246 &join_params
, join_params_size
);
1248 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1254 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1255 brcmf_dbg(TRACE
, "Exit\n");
1260 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1262 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1265 brcmf_dbg(TRACE
, "Enter\n");
1266 if (!check_vif_up(ifp
->vif
))
1269 brcmf_link_down(ifp
->vif
);
1271 brcmf_dbg(TRACE
, "Exit\n");
1276 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1277 struct cfg80211_connect_params
*sme
)
1279 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1280 struct brcmf_cfg80211_security
*sec
;
1284 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1285 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1286 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1287 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1289 val
= WPA_AUTH_DISABLED
;
1290 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1291 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1293 brcmf_err("set wpa_auth failed (%d)\n", err
);
1296 sec
= &profile
->sec
;
1297 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1301 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1302 struct cfg80211_connect_params
*sme
)
1304 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1305 struct brcmf_cfg80211_security
*sec
;
1309 switch (sme
->auth_type
) {
1310 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1312 brcmf_dbg(CONN
, "open system\n");
1314 case NL80211_AUTHTYPE_SHARED_KEY
:
1316 brcmf_dbg(CONN
, "shared key\n");
1318 case NL80211_AUTHTYPE_AUTOMATIC
:
1320 brcmf_dbg(CONN
, "automatic\n");
1322 case NL80211_AUTHTYPE_NETWORK_EAP
:
1323 brcmf_dbg(CONN
, "network eap\n");
1326 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1330 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1332 brcmf_err("set auth failed (%d)\n", err
);
1335 sec
= &profile
->sec
;
1336 sec
->auth_type
= sme
->auth_type
;
1341 brcmf_set_set_cipher(struct net_device
*ndev
,
1342 struct cfg80211_connect_params
*sme
)
1344 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1345 struct brcmf_cfg80211_security
*sec
;
1350 if (sme
->crypto
.n_ciphers_pairwise
) {
1351 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1352 case WLAN_CIPHER_SUITE_WEP40
:
1353 case WLAN_CIPHER_SUITE_WEP104
:
1356 case WLAN_CIPHER_SUITE_TKIP
:
1357 pval
= TKIP_ENABLED
;
1359 case WLAN_CIPHER_SUITE_CCMP
:
1362 case WLAN_CIPHER_SUITE_AES_CMAC
:
1366 brcmf_err("invalid cipher pairwise (%d)\n",
1367 sme
->crypto
.ciphers_pairwise
[0]);
1371 if (sme
->crypto
.cipher_group
) {
1372 switch (sme
->crypto
.cipher_group
) {
1373 case WLAN_CIPHER_SUITE_WEP40
:
1374 case WLAN_CIPHER_SUITE_WEP104
:
1377 case WLAN_CIPHER_SUITE_TKIP
:
1378 gval
= TKIP_ENABLED
;
1380 case WLAN_CIPHER_SUITE_CCMP
:
1383 case WLAN_CIPHER_SUITE_AES_CMAC
:
1387 brcmf_err("invalid cipher group (%d)\n",
1388 sme
->crypto
.cipher_group
);
1393 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1394 /* In case of privacy, but no security and WPS then simulate */
1395 /* setting AES. WPS-2.0 allows no security */
1396 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1399 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1401 brcmf_err("error (%d)\n", err
);
1405 sec
= &profile
->sec
;
1406 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1407 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1413 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1415 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1416 struct brcmf_cfg80211_security
*sec
;
1420 if (sme
->crypto
.n_akm_suites
) {
1421 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
),
1424 brcmf_err("could not get wpa_auth (%d)\n", err
);
1427 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1428 switch (sme
->crypto
.akm_suites
[0]) {
1429 case WLAN_AKM_SUITE_8021X
:
1430 val
= WPA_AUTH_UNSPECIFIED
;
1432 case WLAN_AKM_SUITE_PSK
:
1436 brcmf_err("invalid cipher group (%d)\n",
1437 sme
->crypto
.cipher_group
);
1440 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1441 switch (sme
->crypto
.akm_suites
[0]) {
1442 case WLAN_AKM_SUITE_8021X
:
1443 val
= WPA2_AUTH_UNSPECIFIED
;
1445 case WLAN_AKM_SUITE_PSK
:
1446 val
= WPA2_AUTH_PSK
;
1449 brcmf_err("invalid cipher group (%d)\n",
1450 sme
->crypto
.cipher_group
);
1455 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1456 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
),
1459 brcmf_err("could not set wpa_auth (%d)\n", err
);
1463 sec
= &profile
->sec
;
1464 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1470 brcmf_set_sharedkey(struct net_device
*ndev
,
1471 struct cfg80211_connect_params
*sme
)
1473 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1474 struct brcmf_cfg80211_security
*sec
;
1475 struct brcmf_wsec_key key
;
1479 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1481 if (sme
->key_len
== 0)
1484 sec
= &profile
->sec
;
1485 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1486 sec
->wpa_versions
, sec
->cipher_pairwise
);
1488 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1491 if (!(sec
->cipher_pairwise
&
1492 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1495 memset(&key
, 0, sizeof(key
));
1496 key
.len
= (u32
) sme
->key_len
;
1497 key
.index
= (u32
) sme
->key_idx
;
1498 if (key
.len
> sizeof(key
.data
)) {
1499 brcmf_err("Too long key length (%u)\n", key
.len
);
1502 memcpy(key
.data
, sme
->key
, key
.len
);
1503 key
.flags
= BRCMF_PRIMARY_KEY
;
1504 switch (sec
->cipher_pairwise
) {
1505 case WLAN_CIPHER_SUITE_WEP40
:
1506 key
.algo
= CRYPTO_ALGO_WEP1
;
1508 case WLAN_CIPHER_SUITE_WEP104
:
1509 key
.algo
= CRYPTO_ALGO_WEP128
;
1512 brcmf_err("Invalid algorithm (%d)\n",
1513 sme
->crypto
.ciphers_pairwise
[0]);
1516 /* Set the new key/index */
1517 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1518 key
.len
, key
.index
, key
.algo
);
1519 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1520 err
= send_key_to_dongle(ndev
, &key
);
1524 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1525 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1526 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1527 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1529 brcmf_err("set auth failed (%d)\n", err
);
1535 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1536 enum nl80211_auth_type type
)
1539 if (type
== NL80211_AUTHTYPE_AUTOMATIC
) {
1540 /* shift to ignore chip revision */
1541 ci
= brcmf_get_chip_info(ifp
) >> 4;
1544 brcmf_dbg(CONN
, "43236 WAR: use OPEN instead of AUTO\n");
1545 return NL80211_AUTHTYPE_OPEN_SYSTEM
;
1554 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1555 struct cfg80211_connect_params
*sme
)
1557 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1558 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1559 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1560 struct ieee80211_channel
*chan
= sme
->channel
;
1561 struct brcmf_join_params join_params
;
1562 size_t join_params_size
;
1563 const struct brcmf_tlv
*rsn_ie
;
1564 const struct brcmf_vs_tlv
*wpa_ie
;
1567 struct brcmf_ext_join_params_le
*ext_join_params
;
1572 brcmf_dbg(TRACE
, "Enter\n");
1573 if (!check_vif_up(ifp
->vif
))
1577 brcmf_err("Invalid ssid\n");
1581 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1582 /* A normal (non P2P) connection request setup. */
1585 /* find the WPA_IE */
1586 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1589 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1591 /* find the RSN_IE */
1592 rsn_ie
= brcmf_parse_tlvs((const u8
*)sme
->ie
,
1597 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1600 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1603 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1604 sme
->ie
, sme
->ie_len
);
1606 brcmf_err("Set Assoc REQ IE Failed\n");
1608 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1610 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1614 ieee80211_frequency_to_channel(chan
->center_freq
);
1615 chanspec
= channel_to_chanspec(&cfg
->d11inf
, chan
);
1616 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1617 cfg
->channel
, chan
->center_freq
, chanspec
);
1623 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1625 err
= brcmf_set_wpa_version(ndev
, sme
);
1627 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1631 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1632 err
= brcmf_set_auth_type(ndev
, sme
);
1634 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1638 err
= brcmf_set_set_cipher(ndev
, sme
);
1640 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1644 err
= brcmf_set_key_mgmt(ndev
, sme
);
1646 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1650 err
= brcmf_set_sharedkey(ndev
, sme
);
1652 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1656 profile
->ssid
.SSID_len
= min_t(u32
, (u32
)sizeof(profile
->ssid
.SSID
),
1657 (u32
)sme
->ssid_len
);
1658 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1659 if (profile
->ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1660 profile
->ssid
.SSID
[profile
->ssid
.SSID_len
] = 0;
1661 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n", profile
->ssid
.SSID
,
1662 profile
->ssid
.SSID_len
);
1665 /* Join with specific BSSID and cached SSID
1666 * If SSID is zero join based on BSSID only
1668 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1669 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1671 join_params_size
+= sizeof(u16
);
1672 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1673 if (ext_join_params
== NULL
) {
1677 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1678 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
,
1679 profile
->ssid
.SSID_len
);
1680 /*increase dwell time to receive probe response or detect Beacon
1681 * from target AP at a noisy air only during connect command
1683 ext_join_params
->scan_le
.active_time
=
1684 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1685 ext_join_params
->scan_le
.passive_time
=
1686 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
1687 /* Set up join scan parameters */
1688 ext_join_params
->scan_le
.scan_type
= -1;
1689 /* to sync with presence period of VSDB GO.
1690 * Send probe request more frequently. Probe request will be stopped
1691 * when it gets probe response from target AP/GO.
1693 ext_join_params
->scan_le
.nprobes
=
1694 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
1695 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
1696 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1699 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1701 memset(&ext_join_params
->assoc_le
.bssid
, 0xFF, ETH_ALEN
);
1704 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1706 ext_join_params
->assoc_le
.chanspec_list
[0] =
1707 cpu_to_le16(chanspec
);
1710 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
1712 kfree(ext_join_params
);
1714 /* This is it. join command worked, we are done */
1717 /* join command failed, fallback to set ssid */
1718 memset(&join_params
, 0, sizeof(join_params
));
1719 join_params_size
= sizeof(join_params
.ssid_le
);
1721 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1722 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1725 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1727 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1730 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1731 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1732 join_params_size
+= sizeof(join_params
.params_le
);
1734 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1735 &join_params
, join_params_size
);
1737 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
1741 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1742 brcmf_dbg(TRACE
, "Exit\n");
1747 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1750 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1751 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1752 struct brcmf_scb_val_le scbval
;
1755 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1756 if (!check_vif_up(ifp
->vif
))
1759 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1760 cfg80211_disconnected(ndev
, reason_code
, NULL
, 0, GFP_KERNEL
);
1762 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1763 scbval
.val
= cpu_to_le32(reason_code
);
1764 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1765 &scbval
, sizeof(scbval
));
1767 brcmf_err("error (%d)\n", err
);
1769 brcmf_dbg(TRACE
, "Exit\n");
1774 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1775 enum nl80211_tx_power_setting type
, s32 mbm
)
1778 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1779 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1780 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1784 s32 dbm
= MBM_TO_DBM(mbm
);
1786 brcmf_dbg(TRACE
, "Enter\n");
1787 if (!check_vif_up(ifp
->vif
))
1791 case NL80211_TX_POWER_AUTOMATIC
:
1793 case NL80211_TX_POWER_LIMITED
:
1794 case NL80211_TX_POWER_FIXED
:
1796 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1802 /* Make sure radio is off or on as far as software is concerned */
1803 disable
= WL_RADIO_SW_DISABLE
<< 16;
1804 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1806 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1811 txpwrmw
= (u16
) dbm
;
1812 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1813 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1815 brcmf_err("qtxpower error (%d)\n", err
);
1816 cfg
->conf
->tx_power
= dbm
;
1819 brcmf_dbg(TRACE
, "Exit\n");
1823 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1824 struct wireless_dev
*wdev
,
1827 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1828 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1833 brcmf_dbg(TRACE
, "Enter\n");
1834 if (!check_vif_up(ifp
->vif
))
1837 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1839 brcmf_err("error (%d)\n", err
);
1843 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1844 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1847 brcmf_dbg(TRACE
, "Exit\n");
1852 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1853 u8 key_idx
, bool unicast
, bool multicast
)
1855 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1860 brcmf_dbg(TRACE
, "Enter\n");
1861 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1862 if (!check_vif_up(ifp
->vif
))
1865 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1867 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1871 if (wsec
& WEP_ENABLED
) {
1872 /* Just select a new current key */
1874 err
= brcmf_fil_cmd_int_set(ifp
,
1875 BRCMF_C_SET_KEY_PRIMARY
, index
);
1877 brcmf_err("error (%d)\n", err
);
1880 brcmf_dbg(TRACE
, "Exit\n");
1885 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1886 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1888 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1889 struct brcmf_wsec_key key
;
1893 memset(&key
, 0, sizeof(key
));
1894 key
.index
= (u32
) key_idx
;
1895 /* Instead of bcast for ea address for default wep keys,
1896 driver needs it to be Null */
1897 if (!is_multicast_ether_addr(mac_addr
))
1898 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1899 key
.len
= (u32
) params
->key_len
;
1900 /* check for key index change */
1903 err
= send_key_to_dongle(ndev
, &key
);
1905 brcmf_err("key delete error (%d)\n", err
);
1907 if (key
.len
> sizeof(key
.data
)) {
1908 brcmf_err("Invalid key length (%d)\n", key
.len
);
1912 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1913 memcpy(key
.data
, params
->key
, key
.len
);
1915 if ((ifp
->vif
->mode
!= WL_MODE_AP
) &&
1916 (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)) {
1917 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
1918 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1919 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1920 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1923 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1924 if (params
->seq
&& params
->seq_len
== 6) {
1927 ivptr
= (u8
*) params
->seq
;
1928 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1929 (ivptr
[3] << 8) | ivptr
[2];
1930 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1931 key
.iv_initialized
= true;
1934 switch (params
->cipher
) {
1935 case WLAN_CIPHER_SUITE_WEP40
:
1936 key
.algo
= CRYPTO_ALGO_WEP1
;
1937 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1939 case WLAN_CIPHER_SUITE_WEP104
:
1940 key
.algo
= CRYPTO_ALGO_WEP128
;
1941 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1943 case WLAN_CIPHER_SUITE_TKIP
:
1944 key
.algo
= CRYPTO_ALGO_TKIP
;
1945 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1947 case WLAN_CIPHER_SUITE_AES_CMAC
:
1948 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1949 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1951 case WLAN_CIPHER_SUITE_CCMP
:
1952 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1953 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1956 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1959 err
= send_key_to_dongle(ndev
, &key
);
1961 brcmf_err("wsec_key error (%d)\n", err
);
1967 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1968 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1969 struct key_params
*params
)
1971 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1972 struct brcmf_wsec_key key
;
1978 brcmf_dbg(TRACE
, "Enter\n");
1979 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1980 if (!check_vif_up(ifp
->vif
))
1984 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP40
) &&
1985 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP104
)) {
1986 brcmf_dbg(TRACE
, "Exit");
1987 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1989 memset(&key
, 0, sizeof(key
));
1991 key
.len
= (u32
) params
->key_len
;
1992 key
.index
= (u32
) key_idx
;
1994 if (key
.len
> sizeof(key
.data
)) {
1995 brcmf_err("Too long key length (%u)\n", key
.len
);
1999 memcpy(key
.data
, params
->key
, key
.len
);
2001 key
.flags
= BRCMF_PRIMARY_KEY
;
2002 switch (params
->cipher
) {
2003 case WLAN_CIPHER_SUITE_WEP40
:
2004 key
.algo
= CRYPTO_ALGO_WEP1
;
2006 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2008 case WLAN_CIPHER_SUITE_WEP104
:
2009 key
.algo
= CRYPTO_ALGO_WEP128
;
2011 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2013 case WLAN_CIPHER_SUITE_TKIP
:
2014 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
2015 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2016 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2017 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2018 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2020 key
.algo
= CRYPTO_ALGO_TKIP
;
2022 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2024 case WLAN_CIPHER_SUITE_AES_CMAC
:
2025 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2027 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2029 case WLAN_CIPHER_SUITE_CCMP
:
2030 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2032 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2035 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2040 err
= send_key_to_dongle(ndev
, &key
);
2044 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2046 brcmf_err("get wsec error (%d)\n", err
);
2050 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2052 brcmf_err("set wsec error (%d)\n", err
);
2057 brcmf_dbg(TRACE
, "Exit\n");
2062 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2063 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2065 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2066 struct brcmf_wsec_key key
;
2069 brcmf_dbg(TRACE
, "Enter\n");
2070 if (!check_vif_up(ifp
->vif
))
2073 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
2074 /* we ignore this key index in this case */
2075 brcmf_err("invalid key index (%d)\n", key_idx
);
2079 memset(&key
, 0, sizeof(key
));
2081 key
.index
= (u32
) key_idx
;
2082 key
.flags
= BRCMF_PRIMARY_KEY
;
2083 key
.algo
= CRYPTO_ALGO_OFF
;
2085 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2087 /* Set the new key/index */
2088 err
= send_key_to_dongle(ndev
, &key
);
2090 brcmf_dbg(TRACE
, "Exit\n");
2095 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2096 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2097 void (*callback
) (void *cookie
, struct key_params
* params
))
2099 struct key_params params
;
2100 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2101 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2102 struct brcmf_cfg80211_security
*sec
;
2106 brcmf_dbg(TRACE
, "Enter\n");
2107 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2108 if (!check_vif_up(ifp
->vif
))
2111 memset(¶ms
, 0, sizeof(params
));
2113 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2115 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2116 /* Ignore this error, may happen during DISASSOC */
2120 if (wsec
& WEP_ENABLED
) {
2121 sec
= &profile
->sec
;
2122 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2123 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2124 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2125 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2126 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2127 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2129 } else if (wsec
& TKIP_ENABLED
) {
2130 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2131 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2132 } else if (wsec
& AES_ENABLED
) {
2133 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2134 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2136 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2140 callback(cookie
, ¶ms
);
2143 brcmf_dbg(TRACE
, "Exit\n");
2148 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2149 struct net_device
*ndev
, u8 key_idx
)
2151 brcmf_dbg(INFO
, "Not supported\n");
2157 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2158 u8
*mac
, struct station_info
*sinfo
)
2160 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2161 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2162 struct brcmf_scb_val_le scb_val
;
2166 u8
*bssid
= profile
->bssid
;
2167 struct brcmf_sta_info_le sta_info_le
;
2171 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2172 if (!check_vif_up(ifp
->vif
))
2175 if (ifp
->vif
->mode
== WL_MODE_AP
) {
2176 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2177 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2179 sizeof(sta_info_le
));
2181 brcmf_err("GET STA INFO failed, %d\n", err
);
2184 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2185 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2186 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2187 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2188 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2190 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
2191 sinfo
->inactive_time
, sinfo
->connected_time
);
2192 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
2193 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2194 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2199 /* Report the current tx rate */
2200 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2202 brcmf_err("Could not get rate (%d)\n", err
);
2205 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2206 sinfo
->txrate
.legacy
= rate
* 5;
2207 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
2210 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2211 &ifp
->vif
->sme_state
)) {
2212 memset(&scb_val
, 0, sizeof(scb_val
));
2213 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2214 &scb_val
, sizeof(scb_val
));
2216 brcmf_err("Could not get rssi (%d)\n", err
);
2219 rssi
= le32_to_cpu(scb_val
.val
);
2220 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2221 sinfo
->signal
= rssi
;
2222 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2224 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_BCNPRD
,
2227 brcmf_err("Could not get beacon period (%d)\n",
2231 sinfo
->bss_param
.beacon_interval
=
2233 brcmf_dbg(CONN
, "Beacon peroid %d\n",
2236 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_DTIMPRD
,
2239 brcmf_err("Could not get DTIM period (%d)\n",
2243 sinfo
->bss_param
.dtim_period
= dtim_period
;
2244 brcmf_dbg(CONN
, "DTIM peroid %d\n",
2247 sinfo
->filled
|= STATION_INFO_BSS_PARAM
;
2252 brcmf_dbg(TRACE
, "Exit\n");
2257 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2258 bool enabled
, s32 timeout
)
2262 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2263 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2265 brcmf_dbg(TRACE
, "Enter\n");
2268 * Powersave enable/disable request is coming from the
2269 * cfg80211 even before the interface is up. In that
2270 * scenario, driver will be storing the power save
2271 * preference in cfg struct to apply this to
2272 * FW later while initializing the dongle
2274 cfg
->pwr_save
= enabled
;
2275 if (!check_vif_up(ifp
->vif
)) {
2277 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2281 pm
= enabled
? PM_FAST
: PM_OFF
;
2282 /* Do not enable the power save after assoc if it is a p2p interface */
2283 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2284 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2287 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2289 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2292 brcmf_err("net_device is not ready yet\n");
2294 brcmf_err("error (%d)\n", err
);
2297 brcmf_dbg(TRACE
, "Exit\n");
2301 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2302 struct brcmf_bss_info_le
*bi
)
2304 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2305 struct ieee80211_channel
*notify_channel
;
2306 struct cfg80211_bss
*bss
;
2307 struct ieee80211_supported_band
*band
;
2308 struct brcmu_chan ch
;
2312 u16 notify_capability
;
2313 u16 notify_interval
;
2315 size_t notify_ielen
;
2318 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2319 brcmf_err("Bss info is larger than buffer. Discarding\n");
2324 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2325 cfg
->d11inf
.decchspec(&ch
);
2326 bi
->ctl_ch
= ch
.chnum
;
2328 channel
= bi
->ctl_ch
;
2330 if (channel
<= CH_MAX_2G_CHANNEL
)
2331 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2333 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2335 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2336 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2338 notify_capability
= le16_to_cpu(bi
->capability
);
2339 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2340 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2341 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2342 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2344 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2345 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2346 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2347 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2348 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2350 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2351 0, notify_capability
, notify_interval
, notify_ie
,
2352 notify_ielen
, notify_signal
, GFP_KERNEL
);
2357 cfg80211_put_bss(wiphy
, bss
);
2362 static struct brcmf_bss_info_le
*
2363 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2366 return list
->bss_info_le
;
2367 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2368 le32_to_cpu(bss
->length
));
2371 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2373 struct brcmf_scan_results
*bss_list
;
2374 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2378 bss_list
= cfg
->bss_list
;
2379 if (bss_list
->count
!= 0 &&
2380 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2381 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2385 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2386 for (i
= 0; i
< bss_list
->count
; i
++) {
2387 bi
= next_bss_le(bss_list
, bi
);
2388 err
= brcmf_inform_single_bss(cfg
, bi
);
2395 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2396 struct net_device
*ndev
, const u8
*bssid
)
2398 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2399 struct ieee80211_channel
*notify_channel
;
2400 struct brcmf_bss_info_le
*bi
= NULL
;
2401 struct ieee80211_supported_band
*band
;
2402 struct cfg80211_bss
*bss
;
2403 struct brcmu_chan ch
;
2407 u16 notify_capability
;
2408 u16 notify_interval
;
2410 size_t notify_ielen
;
2413 brcmf_dbg(TRACE
, "Enter\n");
2415 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2421 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2423 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2424 buf
, WL_BSS_INFO_MAX
);
2426 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2430 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2432 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2433 cfg
->d11inf
.decchspec(&ch
);
2435 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2436 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2438 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2440 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2441 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2443 notify_capability
= le16_to_cpu(bi
->capability
);
2444 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2445 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2446 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2447 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2449 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2450 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2451 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2452 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2454 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2455 0, notify_capability
, notify_interval
,
2456 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2463 cfg80211_put_bss(wiphy
, bss
);
2469 brcmf_dbg(TRACE
, "Exit\n");
2474 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2476 return vif
->mode
== WL_MODE_IBSS
;
2479 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2480 struct brcmf_if
*ifp
)
2482 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ifp
->ndev
);
2483 struct brcmf_bss_info_le
*bi
;
2484 struct brcmf_ssid
*ssid
;
2485 const struct brcmf_tlv
*tim
;
2486 u16 beacon_interval
;
2492 brcmf_dbg(TRACE
, "Enter\n");
2493 if (brcmf_is_ibssmode(ifp
->vif
))
2496 ssid
= &profile
->ssid
;
2498 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2499 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2500 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2502 brcmf_err("Could not get bss info %d\n", err
);
2503 goto update_bss_info_out
;
2506 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2507 err
= brcmf_inform_single_bss(cfg
, bi
);
2509 goto update_bss_info_out
;
2511 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2512 ie_len
= le32_to_cpu(bi
->ie_length
);
2513 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2515 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2517 dtim_period
= tim
->data
[1];
2520 * active scan was done so we could not get dtim
2521 * information out of probe response.
2522 * so we speficially query dtim information to dongle.
2525 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2527 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2528 goto update_bss_info_out
;
2530 dtim_period
= (u8
)var
;
2533 update_bss_info_out
:
2534 brcmf_dbg(TRACE
, "Exit");
2538 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2540 struct escan_info
*escan
= &cfg
->escan_info
;
2542 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2543 if (cfg
->scan_request
) {
2544 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2545 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2547 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2548 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2551 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2553 struct brcmf_cfg80211_info
*cfg
=
2554 container_of(work
, struct brcmf_cfg80211_info
,
2555 escan_timeout_work
);
2557 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2560 static void brcmf_escan_timeout(unsigned long data
)
2562 struct brcmf_cfg80211_info
*cfg
=
2563 (struct brcmf_cfg80211_info
*)data
;
2565 if (cfg
->scan_request
) {
2566 brcmf_err("timer expired\n");
2567 schedule_work(&cfg
->escan_timeout_work
);
2572 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2573 struct brcmf_bss_info_le
*bss
,
2574 struct brcmf_bss_info_le
*bss_info_le
)
2576 struct brcmu_chan ch_bss
, ch_bss_info_le
;
2578 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
2579 cfg
->d11inf
.decchspec(&ch_bss
);
2580 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
2581 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
2583 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2584 ch_bss
.band
== ch_bss_info_le
.band
&&
2585 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2586 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2587 if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) ==
2588 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
)) {
2589 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2590 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2592 /* preserve max RSSI if the measurements are
2593 * both on-channel or both off-channel
2595 if (bss_info_rssi
> bss_rssi
)
2596 bss
->RSSI
= bss_info_le
->RSSI
;
2597 } else if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) &&
2598 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) == 0) {
2599 /* preserve the on-channel rssi measurement
2600 * if the new measurement is off channel
2602 bss
->RSSI
= bss_info_le
->RSSI
;
2603 bss
->flags
|= BRCMF_BSS_RSSI_ON_CHANNEL
;
2611 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2612 const struct brcmf_event_msg
*e
, void *data
)
2614 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2617 struct brcmf_escan_result_le
*escan_result_le
;
2618 struct brcmf_bss_info_le
*bss_info_le
;
2619 struct brcmf_bss_info_le
*bss
= NULL
;
2621 struct brcmf_scan_results
*list
;
2627 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2628 brcmf_err("scan not ready, bssidx=%d\n", ifp
->bssidx
);
2632 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2633 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2634 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2635 if (!escan_result_le
) {
2636 brcmf_err("Invalid escan result (NULL pointer)\n");
2639 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2640 brcmf_err("Invalid bss_count %d: ignoring\n",
2641 escan_result_le
->bss_count
);
2644 bss_info_le
= &escan_result_le
->bss_info_le
;
2646 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
2649 if (!cfg
->scan_request
) {
2650 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2654 bi_length
= le32_to_cpu(bss_info_le
->length
);
2655 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2656 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2657 brcmf_err("Invalid bss_info length %d: ignoring\n",
2662 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2663 BIT(NL80211_IFTYPE_ADHOC
))) {
2664 if (le16_to_cpu(bss_info_le
->capability
) &
2665 WLAN_CAPABILITY_IBSS
) {
2666 brcmf_err("Ignoring IBSS result\n");
2671 list
= (struct brcmf_scan_results
*)
2672 cfg
->escan_info
.escan_buf
;
2673 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2674 brcmf_err("Buffer is too small: ignoring\n");
2678 for (i
= 0; i
< list
->count
; i
++) {
2679 bss
= bss
? (struct brcmf_bss_info_le
*)
2680 ((unsigned char *)bss
+
2681 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2682 if (brcmf_compare_update_same_bss(cfg
, bss
,
2686 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2687 bss_info_le
, bi_length
);
2688 list
->version
= le32_to_cpu(bss_info_le
->version
);
2689 list
->buflen
+= bi_length
;
2692 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2693 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
2695 if (cfg
->scan_request
) {
2696 cfg
->bss_list
= (struct brcmf_scan_results
*)
2697 cfg
->escan_info
.escan_buf
;
2698 brcmf_inform_bss(cfg
);
2699 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2700 brcmf_notify_escan_complete(cfg
, ifp
, aborted
,
2703 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
2710 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2712 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2713 brcmf_cfg80211_escan_handler
);
2714 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2715 /* Init scan_timeout timer */
2716 init_timer(&cfg
->escan_timeout
);
2717 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2718 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2719 INIT_WORK(&cfg
->escan_timeout_work
,
2720 brcmf_cfg80211_escan_timeout_worker
);
2723 static __always_inline
void brcmf_delay(u32 ms
)
2725 if (ms
< 1000 / HZ
) {
2733 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2735 brcmf_dbg(TRACE
, "Enter\n");
2740 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2741 struct cfg80211_wowlan
*wow
)
2743 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2744 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2745 struct brcmf_cfg80211_vif
*vif
;
2747 brcmf_dbg(TRACE
, "Enter\n");
2750 * if the primary net_device is not READY there is nothing
2751 * we can do but pray resume goes smoothly.
2753 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2754 if (!check_vif_up(vif
))
2757 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2758 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2761 * While going to suspend if associated with AP disassociate
2762 * from AP to save power while system is in suspended state
2764 brcmf_link_down(vif
);
2766 /* Make sure WPA_Supplicant receives all the event
2767 * generated due to DISASSOC call to the fw to keep
2768 * the state fw and WPA_Supplicant state consistent
2773 /* end any scanning */
2774 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2775 brcmf_abort_scanning(cfg
);
2777 /* Turn off watchdog timer */
2778 brcmf_set_mpc(netdev_priv(ndev
), 1);
2781 brcmf_dbg(TRACE
, "Exit\n");
2782 /* clear any scanning activity */
2783 cfg
->scan_status
= 0;
2788 brcmf_update_pmklist(struct net_device
*ndev
,
2789 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2794 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2796 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2797 for (i
= 0; i
< pmkid_len
; i
++) {
2798 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2799 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2800 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2801 brcmf_dbg(CONN
, "%02x\n",
2802 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2806 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2807 (char *)pmk_list
, sizeof(*pmk_list
));
2813 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2814 struct cfg80211_pmksa
*pmksa
)
2816 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2817 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2818 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2823 brcmf_dbg(TRACE
, "Enter\n");
2824 if (!check_vif_up(ifp
->vif
))
2827 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2828 for (i
= 0; i
< pmkid_len
; i
++)
2829 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2831 if (i
< WL_NUM_PMKIDS_MAX
) {
2832 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2833 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2834 if (i
== pmkid_len
) {
2836 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2841 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2842 pmkids
->pmkid
[pmkid_len
].BSSID
);
2843 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2844 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2846 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2848 brcmf_dbg(TRACE
, "Exit\n");
2853 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2854 struct cfg80211_pmksa
*pmksa
)
2856 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2857 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2858 struct pmkid_list pmkid
;
2862 brcmf_dbg(TRACE
, "Enter\n");
2863 if (!check_vif_up(ifp
->vif
))
2866 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2867 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2869 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2870 &pmkid
.pmkid
[0].BSSID
);
2871 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2872 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2874 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2875 for (i
= 0; i
< pmkid_len
; i
++)
2877 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2882 && (i
< pmkid_len
)) {
2883 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2884 sizeof(struct pmkid
));
2885 for (; i
< (pmkid_len
- 1); i
++) {
2886 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2887 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2889 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2890 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2893 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2897 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2899 brcmf_dbg(TRACE
, "Exit\n");
2905 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2907 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2908 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2911 brcmf_dbg(TRACE
, "Enter\n");
2912 if (!check_vif_up(ifp
->vif
))
2915 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2916 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2918 brcmf_dbg(TRACE
, "Exit\n");
2924 * PFN result doesn't have all the info which are
2925 * required by the supplicant
2926 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2927 * via wl_inform_single_bss in the required format. Escan does require the
2928 * scan request in the form of cfg80211_scan_request. For timebeing, create
2929 * cfg80211_scan_request one out of the received PNO event.
2932 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2933 const struct brcmf_event_msg
*e
, void *data
)
2935 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2936 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2937 struct cfg80211_scan_request
*request
= NULL
;
2938 struct cfg80211_ssid
*ssid
= NULL
;
2939 struct ieee80211_channel
*channel
= NULL
;
2940 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2942 int channel_req
= 0;
2944 struct brcmf_pno_scanresults_le
*pfn_result
;
2948 brcmf_dbg(SCAN
, "Enter\n");
2950 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2951 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2955 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2956 result_count
= le32_to_cpu(pfn_result
->count
);
2957 status
= le32_to_cpu(pfn_result
->status
);
2960 * PFN event is limited to fit 512 bytes so we may get
2961 * multiple NET_FOUND events. For now place a warning here.
2963 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2964 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2965 if (result_count
> 0) {
2968 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2969 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2970 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2971 if (!request
|| !ssid
|| !channel
) {
2976 request
->wiphy
= wiphy
;
2977 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2978 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2980 for (i
= 0; i
< result_count
; i
++) {
2981 netinfo
= &netinfo_start
[i
];
2983 brcmf_err("Invalid netinfo ptr. index: %d\n",
2989 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2990 netinfo
->SSID
, netinfo
->channel
);
2991 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2992 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2995 channel_req
= netinfo
->channel
;
2996 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2997 band
= NL80211_BAND_2GHZ
;
2999 band
= NL80211_BAND_5GHZ
;
3000 channel
[i
].center_freq
=
3001 ieee80211_channel_to_frequency(channel_req
,
3003 channel
[i
].band
= band
;
3004 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
3005 request
->channels
[i
] = &channel
[i
];
3006 request
->n_channels
++;
3009 /* assign parsed ssid array */
3010 if (request
->n_ssids
)
3011 request
->ssids
= &ssid
[0];
3013 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3014 /* Abort any on-going scan */
3015 brcmf_abort_scanning(cfg
);
3018 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3019 cfg
->escan_info
.run
= brcmf_run_escan
;
3020 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
3022 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3025 cfg
->sched_escan
= true;
3026 cfg
->scan_request
= request
;
3028 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3041 cfg80211_sched_scan_stopped(wiphy
);
3045 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3050 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3053 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3057 brcmf_err("failed code %d\n", ret
);
3062 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3064 struct brcmf_pno_param_le pfn_param
;
3066 memset(&pfn_param
, 0, sizeof(pfn_param
));
3067 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3069 /* set extra pno params */
3070 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3071 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3072 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3074 /* set up pno scan fr */
3075 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3077 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3078 &pfn_param
, sizeof(pfn_param
));
3082 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3083 struct net_device
*ndev
,
3084 struct cfg80211_sched_scan_request
*request
)
3086 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3087 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3088 struct brcmf_pno_net_param_le pfn
;
3092 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3093 request
->n_match_sets
, request
->n_ssids
);
3094 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3095 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3098 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3099 brcmf_err("Scanning suppressed: status (%lu)\n",
3104 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3105 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3110 if (request
->n_ssids
> 0) {
3111 for (i
= 0; i
< request
->n_ssids
; i
++) {
3112 /* Active scan req for ssids */
3113 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3114 request
->ssids
[i
].ssid
);
3117 * match_set ssids is a supert set of n_ssid list,
3118 * so we need not add these set seperately.
3123 if (request
->n_match_sets
> 0) {
3124 /* clean up everything */
3125 ret
= brcmf_dev_pno_clean(ndev
);
3127 brcmf_err("failed error=%d\n", ret
);
3132 ret
= brcmf_dev_pno_config(ndev
);
3134 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
3138 /* configure each match set */
3139 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3140 struct cfg80211_ssid
*ssid
;
3143 ssid
= &request
->match_sets
[i
].ssid
;
3144 ssid_len
= ssid
->ssid_len
;
3147 brcmf_err("skip broadcast ssid\n");
3150 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3151 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3152 pfn
.wsec
= cpu_to_le32(0);
3153 pfn
.infra
= cpu_to_le32(1);
3154 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3155 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3156 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3157 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3159 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3160 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3162 /* Enable the PNO */
3163 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3164 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3174 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3175 struct net_device
*ndev
)
3177 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3179 brcmf_dbg(SCAN
, "enter\n");
3180 brcmf_dev_pno_clean(ndev
);
3181 if (cfg
->sched_escan
)
3182 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3186 #ifdef CONFIG_NL80211_TESTMODE
3187 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
,
3188 struct wireless_dev
*wdev
,
3189 void *data
, int len
)
3191 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3192 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3193 struct brcmf_dcmd
*dcmd
= data
;
3194 struct sk_buff
*reply
;
3197 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3198 dcmd
->buf
, dcmd
->len
);
3201 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3202 dcmd
->buf
, dcmd
->len
);
3204 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3205 dcmd
->buf
, dcmd
->len
);
3207 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3208 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3209 ret
= cfg80211_testmode_reply(reply
);
3215 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3220 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3222 brcmf_err("auth error %d\n", err
);
3226 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3228 brcmf_err("wsec error %d\n", err
);
3231 /* set upper-layer auth */
3232 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3234 brcmf_err("wpa_auth error %d\n", err
);
3241 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3244 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3246 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3250 brcmf_configure_wpaie(struct net_device
*ndev
,
3251 const struct brcmf_vs_tlv
*wpa_ie
,
3254 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3255 u32 auth
= 0; /* d11 open authentication */
3267 u32 wme_bss_disable
;
3269 brcmf_dbg(TRACE
, "Enter\n");
3273 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3274 data
= (u8
*)wpa_ie
;
3275 offset
= TLV_HDR_LEN
;
3277 offset
+= VS_IE_FIXED_HDR_LEN
;
3279 offset
+= WPA_IE_VERSION_LEN
;
3281 /* check for multicast cipher suite */
3282 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3284 brcmf_err("no multicast cipher suite\n");
3288 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3290 brcmf_err("ivalid OUI\n");
3293 offset
+= TLV_OUI_LEN
;
3295 /* pick up multicast cipher */
3296 switch (data
[offset
]) {
3297 case WPA_CIPHER_NONE
:
3300 case WPA_CIPHER_WEP_40
:
3301 case WPA_CIPHER_WEP_104
:
3304 case WPA_CIPHER_TKIP
:
3305 gval
= TKIP_ENABLED
;
3307 case WPA_CIPHER_AES_CCM
:
3312 brcmf_err("Invalid multi cast cipher info\n");
3317 /* walk thru unicast cipher list and pick up what we recognize */
3318 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3319 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3320 /* Check for unicast suite(s) */
3321 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3323 brcmf_err("no unicast cipher suite\n");
3326 for (i
= 0; i
< count
; i
++) {
3327 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3329 brcmf_err("ivalid OUI\n");
3332 offset
+= TLV_OUI_LEN
;
3333 switch (data
[offset
]) {
3334 case WPA_CIPHER_NONE
:
3336 case WPA_CIPHER_WEP_40
:
3337 case WPA_CIPHER_WEP_104
:
3338 pval
|= WEP_ENABLED
;
3340 case WPA_CIPHER_TKIP
:
3341 pval
|= TKIP_ENABLED
;
3343 case WPA_CIPHER_AES_CCM
:
3344 pval
|= AES_ENABLED
;
3347 brcmf_err("Ivalid unicast security info\n");
3351 /* walk thru auth management suite list and pick up what we recognize */
3352 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3353 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3354 /* Check for auth key management suite(s) */
3355 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3357 brcmf_err("no auth key mgmt suite\n");
3360 for (i
= 0; i
< count
; i
++) {
3361 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3363 brcmf_err("ivalid OUI\n");
3366 offset
+= TLV_OUI_LEN
;
3367 switch (data
[offset
]) {
3369 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3370 wpa_auth
|= WPA_AUTH_NONE
;
3372 case RSN_AKM_UNSPECIFIED
:
3373 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3374 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3375 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3378 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3379 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3380 (wpa_auth
|= WPA_AUTH_PSK
);
3383 brcmf_err("Ivalid key mgmt info\n");
3389 wme_bss_disable
= 1;
3390 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3391 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3392 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3393 wme_bss_disable
= 0;
3395 /* set wme_bss_disable to sync RSN Capabilities */
3396 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3399 brcmf_err("wme_bss_disable error %d\n", err
);
3403 /* FOR WPS , set SES_OW_ENABLED */
3404 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3407 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3409 brcmf_err("auth error %d\n", err
);
3413 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3415 brcmf_err("wsec error %d\n", err
);
3418 /* set upper-layer auth */
3419 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3421 brcmf_err("wpa_auth error %d\n", err
);
3430 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3431 struct parsed_vndr_ies
*vndr_ies
)
3434 struct brcmf_vs_tlv
*vndrie
;
3435 struct brcmf_tlv
*ie
;
3436 struct parsed_vndr_ie_info
*parsed_info
;
3439 remaining_len
= (s32
)vndr_ie_len
;
3440 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3442 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3444 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3446 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3447 /* len should be bigger than OUI length + one */
3448 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3449 brcmf_err("invalid vndr ie. length is too small %d\n",
3453 /* if wpa or wme ie, do not add ie */
3454 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3455 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3456 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3457 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3461 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3463 /* save vndr ie information */
3464 parsed_info
->ie_ptr
= (char *)vndrie
;
3465 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3466 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3470 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3471 parsed_info
->vndrie
.oui
[0],
3472 parsed_info
->vndrie
.oui
[1],
3473 parsed_info
->vndrie
.oui
[2],
3474 parsed_info
->vndrie
.oui_type
);
3476 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3479 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3480 if (remaining_len
<= TLV_HDR_LEN
)
3483 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3490 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3496 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3497 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3499 iecount_le
= cpu_to_le32(1);
3500 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3502 pktflag_le
= cpu_to_le32(pktflag
);
3503 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3505 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3507 return ie_len
+ VNDR_IE_HDR_SIZE
;
3510 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3511 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3513 struct brcmf_if
*ifp
;
3514 struct vif_saved_ie
*saved_ie
;
3518 u8
*mgmt_ie_buf
= NULL
;
3519 int mgmt_ie_buf_len
;
3521 u32 del_add_ie_buf_len
= 0;
3522 u32 total_ie_buf_len
= 0;
3523 u32 parsed_ie_buf_len
= 0;
3524 struct parsed_vndr_ies old_vndr_ies
;
3525 struct parsed_vndr_ies new_vndr_ies
;
3526 struct parsed_vndr_ie_info
*vndrie_info
;
3529 int remained_buf_len
;
3534 saved_ie
= &vif
->saved_ie
;
3536 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3537 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3540 curr_ie_buf
= iovar_ie_buf
;
3542 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3543 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3544 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3545 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3547 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3548 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3549 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3550 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3552 case BRCMF_VNDR_IE_BEACON_FLAG
:
3553 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3554 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3555 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3557 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
3558 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
3559 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
3560 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
3564 brcmf_err("not suitable type\n");
3568 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3570 brcmf_err("extra IE size too big\n");
3574 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3575 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3577 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3578 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3579 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3580 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3581 vndrie_info
->ie_len
);
3582 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3586 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3587 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3588 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3589 parsed_ie_buf_len
) == 0)) {
3590 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3594 /* parse old vndr_ie */
3595 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3597 /* make a command to delete old ie */
3598 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3599 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3601 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3602 vndrie_info
->vndrie
.id
,
3603 vndrie_info
->vndrie
.len
,
3604 vndrie_info
->vndrie
.oui
[0],
3605 vndrie_info
->vndrie
.oui
[1],
3606 vndrie_info
->vndrie
.oui
[2]);
3608 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3609 vndrie_info
->ie_ptr
,
3610 vndrie_info
->ie_len
,
3612 curr_ie_buf
+= del_add_ie_buf_len
;
3613 total_ie_buf_len
+= del_add_ie_buf_len
;
3618 /* Add if there is any extra IE */
3619 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3622 remained_buf_len
= mgmt_ie_buf_len
;
3624 /* make a command to add new ie */
3625 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3626 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3628 /* verify remained buf size before copy data */
3629 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3630 VNDR_IE_VSIE_OFFSET
)) {
3631 brcmf_err("no space in mgmt_ie_buf: len left %d",
3635 remained_buf_len
-= (vndrie_info
->ie_len
+
3636 VNDR_IE_VSIE_OFFSET
);
3638 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3639 vndrie_info
->vndrie
.id
,
3640 vndrie_info
->vndrie
.len
,
3641 vndrie_info
->vndrie
.oui
[0],
3642 vndrie_info
->vndrie
.oui
[1],
3643 vndrie_info
->vndrie
.oui
[2]);
3645 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3646 vndrie_info
->ie_ptr
,
3647 vndrie_info
->ie_len
,
3650 /* save the parsed IE in wl struct */
3651 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3652 vndrie_info
->ie_len
);
3653 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3655 curr_ie_buf
+= del_add_ie_buf_len
;
3656 total_ie_buf_len
+= del_add_ie_buf_len
;
3659 if (total_ie_buf_len
) {
3660 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3663 brcmf_err("vndr ie set error : %d\n", err
);
3667 kfree(iovar_ie_buf
);
3671 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
3674 BRCMF_VNDR_IE_PRBREQ_FLAG
,
3675 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3676 BRCMF_VNDR_IE_BEACON_FLAG
3680 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
3681 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
3683 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
3688 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
3689 struct cfg80211_beacon_data
*beacon
)
3693 /* Set Beacon IEs to FW */
3694 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
3695 beacon
->tail
, beacon
->tail_len
);
3697 brcmf_err("Set Beacon IE Failed\n");
3700 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3702 /* Set Probe Response IEs to FW */
3703 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
3704 beacon
->proberesp_ies
,
3705 beacon
->proberesp_ies_len
);
3707 brcmf_err("Set Probe Resp IE Failed\n");
3709 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3715 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info
*cfg
,
3716 struct brcmf_if
*ifp
,
3717 struct ieee80211_channel
*channel
)
3722 brcmf_dbg(TRACE
, "band=%d, center_freq=%d\n", channel
->band
,
3723 channel
->center_freq
);
3725 chanspec
= channel_to_chanspec(&cfg
->d11inf
, channel
);
3726 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
3732 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3733 struct cfg80211_ap_settings
*settings
)
3736 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3737 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3738 const struct brcmf_tlv
*ssid_ie
;
3739 struct brcmf_ssid_le ssid_le
;
3741 const struct brcmf_tlv
*rsn_ie
;
3742 const struct brcmf_vs_tlv
*wpa_ie
;
3743 struct brcmf_join_params join_params
;
3744 enum nl80211_iftype dev_role
;
3745 struct brcmf_fil_bss_enable_le bss_enable
;
3747 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3748 cfg80211_get_chandef_type(&settings
->chandef
),
3749 settings
->beacon_interval
,
3750 settings
->dtim_period
);
3751 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3752 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3753 settings
->inactivity_timeout
);
3755 dev_role
= ifp
->vif
->wdev
.iftype
;
3757 memset(&ssid_le
, 0, sizeof(ssid_le
));
3758 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3759 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3760 ssid_ie
= brcmf_parse_tlvs(
3761 (u8
*)&settings
->beacon
.head
[ie_offset
],
3762 settings
->beacon
.head_len
- ie_offset
,
3767 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3768 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3769 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3771 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3772 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3775 brcmf_set_mpc(ifp
, 0);
3776 brcmf_configure_arp_offload(ifp
, false);
3778 /* find the RSN_IE */
3779 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3780 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3782 /* find the WPA_IE */
3783 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3784 settings
->beacon
.tail_len
);
3786 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3787 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3788 if (wpa_ie
!= NULL
) {
3790 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3795 err
= brcmf_configure_wpaie(ndev
,
3796 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3801 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3802 brcmf_configure_opensecurity(ifp
);
3805 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
3807 err
= brcmf_cfg80211_set_channel(cfg
, ifp
, settings
->chandef
.chan
);
3809 brcmf_err("Set Channel failed, %d\n", err
);
3813 if (settings
->beacon_interval
) {
3814 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3815 settings
->beacon_interval
);
3817 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3821 if (settings
->dtim_period
) {
3822 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3823 settings
->dtim_period
);
3825 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3830 if (dev_role
== NL80211_IFTYPE_AP
) {
3831 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3833 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3836 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3839 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3841 brcmf_err("SET INFRA error %d\n", err
);
3844 if (dev_role
== NL80211_IFTYPE_AP
) {
3845 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3847 brcmf_err("setting AP mode failed %d\n", err
);
3850 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3852 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3856 memset(&join_params
, 0, sizeof(join_params
));
3857 /* join parameters starts with ssid */
3858 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3860 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3861 &join_params
, sizeof(join_params
));
3863 brcmf_err("SET SSID error (%d)\n", err
);
3866 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
3868 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
3871 brcmf_err("setting ssid failed %d\n", err
);
3874 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3875 bss_enable
.enable
= cpu_to_le32(1);
3876 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3877 sizeof(bss_enable
));
3879 brcmf_err("bss_enable config failed %d\n", err
);
3883 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
3885 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3886 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3890 brcmf_set_mpc(ifp
, 1);
3891 brcmf_configure_arp_offload(ifp
, true);
3896 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3898 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3900 struct brcmf_fil_bss_enable_le bss_enable
;
3901 struct brcmf_join_params join_params
;
3903 brcmf_dbg(TRACE
, "Enter\n");
3905 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
3906 /* Due to most likely deauths outstanding we sleep */
3907 /* first to make sure they get processed by fw. */
3910 memset(&join_params
, 0, sizeof(join_params
));
3911 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3912 &join_params
, sizeof(join_params
));
3914 brcmf_err("SET SSID error (%d)\n", err
);
3915 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3917 brcmf_err("BRCMF_C_UP error %d\n", err
);
3918 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3920 brcmf_err("setting AP mode failed %d\n", err
);
3921 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
3923 brcmf_err("setting INFRA mode failed %d\n", err
);
3925 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3926 bss_enable
.enable
= cpu_to_le32(0);
3927 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3928 sizeof(bss_enable
));
3930 brcmf_err("bss_enable config failed %d\n", err
);
3932 brcmf_set_mpc(ifp
, 1);
3933 brcmf_configure_arp_offload(ifp
, true);
3934 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3935 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3941 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3942 struct cfg80211_beacon_data
*info
)
3944 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3947 brcmf_dbg(TRACE
, "Enter\n");
3949 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
3955 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3958 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3959 struct brcmf_scb_val_le scbval
;
3960 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3966 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3968 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
3969 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3970 if (!check_vif_up(ifp
->vif
))
3973 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3974 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3975 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3976 &scbval
, sizeof(scbval
));
3978 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3980 brcmf_dbg(TRACE
, "Exit\n");
3986 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
3987 struct wireless_dev
*wdev
,
3988 u16 frame_type
, bool reg
)
3990 struct brcmf_cfg80211_vif
*vif
;
3993 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
3995 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
3996 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
3998 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
4000 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
4005 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
4006 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
4008 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4009 struct ieee80211_channel
*chan
= params
->chan
;
4010 const u8
*buf
= params
->buf
;
4011 size_t len
= params
->len
;
4012 const struct ieee80211_mgmt
*mgmt
;
4013 struct brcmf_cfg80211_vif
*vif
;
4017 struct brcmf_fil_action_frame_le
*action_frame
;
4018 struct brcmf_fil_af_params_le
*af_params
;
4023 brcmf_dbg(TRACE
, "Enter\n");
4027 mgmt
= (const struct ieee80211_mgmt
*)buf
;
4029 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
4030 brcmf_err("Driver only allows MGMT packet type\n");
4034 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4036 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4037 /* Right now the only reason to get a probe response */
4038 /* is for p2p listen response or for p2p GO from */
4039 /* wpa_supplicant. Unfortunately the probe is send */
4040 /* on primary ndev, while dongle wants it on the p2p */
4041 /* vif. Since this is only reason for a probe */
4042 /* response to be sent, the vif is taken from cfg. */
4043 /* If ever desired to send proberesp for non p2p */
4044 /* response then data should be checked for */
4045 /* "DIRECT-". Note in future supplicant will take */
4046 /* dedicated p2p wdev to do this and then this 'hack'*/
4047 /* is not needed anymore. */
4048 ie_offset
= DOT11_MGMT_HDR_LEN
+
4049 DOT11_BCN_PRB_FIXED_LEN
;
4050 ie_len
= len
- ie_offset
;
4051 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4052 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4053 err
= brcmf_vif_set_mgmt_ie(vif
,
4054 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4057 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4059 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4060 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4061 if (af_params
== NULL
) {
4062 brcmf_err("unable to allocate frame\n");
4066 action_frame
= &af_params
->action_frame
;
4067 /* Add the packet Id */
4068 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4070 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4071 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4072 /* Add the length exepted for 802.11 header */
4073 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4074 /* Add the channel. Use the one specified as parameter if any or
4075 * the current one (got from the firmware) otherwise
4078 freq
= chan
->center_freq
;
4080 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4082 chan_nr
= ieee80211_frequency_to_channel(freq
);
4083 af_params
->channel
= cpu_to_le32(chan_nr
);
4085 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4086 le16_to_cpu(action_frame
->len
));
4088 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4089 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4091 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4094 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4098 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4099 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4108 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4109 struct wireless_dev
*wdev
,
4112 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4113 struct brcmf_cfg80211_vif
*vif
;
4116 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4118 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4120 brcmf_err("No p2p device available for probe response\n");
4124 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4129 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4130 struct wireless_dev
*wdev
,
4131 enum nl80211_crit_proto_id proto
,
4134 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4135 struct brcmf_cfg80211_vif
*vif
;
4137 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4139 /* only DHCP support for now */
4140 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4143 /* suppress and abort scanning */
4144 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4145 brcmf_abort_scanning(cfg
);
4147 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4150 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4151 struct wireless_dev
*wdev
)
4153 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4154 struct brcmf_cfg80211_vif
*vif
;
4156 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4158 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4159 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4162 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4167 case NL80211_TDLS_DISCOVERY_REQ
:
4168 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4170 case NL80211_TDLS_SETUP
:
4171 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4173 case NL80211_TDLS_TEARDOWN
:
4174 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4177 brcmf_err("unsupported operation: %d\n", oper
);
4183 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4184 struct net_device
*ndev
, u8
*peer
,
4185 enum nl80211_tdls_operation oper
)
4187 struct brcmf_if
*ifp
;
4188 struct brcmf_tdls_iovar_le info
;
4191 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4195 ifp
= netdev_priv(ndev
);
4196 memset(&info
, 0, sizeof(info
));
4197 info
.mode
= (u8
)ret
;
4199 memcpy(info
.ea
, peer
, ETH_ALEN
);
4201 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
4202 &info
, sizeof(info
));
4204 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
4209 static struct cfg80211_ops wl_cfg80211_ops
= {
4210 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4211 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4212 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4213 .scan
= brcmf_cfg80211_scan
,
4214 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4215 .join_ibss
= brcmf_cfg80211_join_ibss
,
4216 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4217 .get_station
= brcmf_cfg80211_get_station
,
4218 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4219 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4220 .add_key
= brcmf_cfg80211_add_key
,
4221 .del_key
= brcmf_cfg80211_del_key
,
4222 .get_key
= brcmf_cfg80211_get_key
,
4223 .set_default_key
= brcmf_cfg80211_config_default_key
,
4224 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4225 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4226 .connect
= brcmf_cfg80211_connect
,
4227 .disconnect
= brcmf_cfg80211_disconnect
,
4228 .suspend
= brcmf_cfg80211_suspend
,
4229 .resume
= brcmf_cfg80211_resume
,
4230 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4231 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4232 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4233 .start_ap
= brcmf_cfg80211_start_ap
,
4234 .stop_ap
= brcmf_cfg80211_stop_ap
,
4235 .change_beacon
= brcmf_cfg80211_change_beacon
,
4236 .del_station
= brcmf_cfg80211_del_station
,
4237 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4238 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4239 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4240 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4241 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4242 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4243 .start_p2p_device
= brcmf_p2p_start_device
,
4244 .stop_p2p_device
= brcmf_p2p_stop_device
,
4245 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
4246 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
4247 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
4248 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode
)
4251 static s32
brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type
)
4254 case NL80211_IFTYPE_AP_VLAN
:
4255 case NL80211_IFTYPE_WDS
:
4256 case NL80211_IFTYPE_MONITOR
:
4257 case NL80211_IFTYPE_MESH_POINT
:
4259 case NL80211_IFTYPE_ADHOC
:
4260 return WL_MODE_IBSS
;
4261 case NL80211_IFTYPE_STATION
:
4262 case NL80211_IFTYPE_P2P_CLIENT
:
4264 case NL80211_IFTYPE_AP
:
4265 case NL80211_IFTYPE_P2P_GO
:
4267 case NL80211_IFTYPE_P2P_DEVICE
:
4269 case NL80211_IFTYPE_UNSPECIFIED
:
4277 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4279 /* scheduled scan settings */
4280 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4281 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4282 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4283 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4286 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
4289 .types
= BIT(NL80211_IFTYPE_STATION
) |
4290 BIT(NL80211_IFTYPE_ADHOC
) |
4291 BIT(NL80211_IFTYPE_AP
)
4295 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4296 BIT(NL80211_IFTYPE_P2P_GO
)
4300 .types
= BIT(NL80211_IFTYPE_P2P_DEVICE
)
4303 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
4305 .max_interfaces
= BRCMF_IFACE_MAX_CNT
,
4306 .num_different_channels
= 2,
4307 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
4308 .limits
= brcmf_iface_limits
4312 static const struct ieee80211_txrx_stypes
4313 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
4314 [NL80211_IFTYPE_STATION
] = {
4316 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4317 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4319 [NL80211_IFTYPE_P2P_CLIENT
] = {
4321 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4322 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4324 [NL80211_IFTYPE_P2P_GO
] = {
4326 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
4327 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
4328 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
4329 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
4330 BIT(IEEE80211_STYPE_AUTH
>> 4) |
4331 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
4332 BIT(IEEE80211_STYPE_ACTION
>> 4)
4334 [NL80211_IFTYPE_P2P_DEVICE
] = {
4336 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4337 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4341 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
4343 struct wiphy
*wiphy
;
4346 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
4348 brcmf_err("Could not allocate wiphy device\n");
4349 return ERR_PTR(-ENOMEM
);
4351 set_wiphy_dev(wiphy
, phydev
);
4352 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4353 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4354 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4355 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4356 BIT(NL80211_IFTYPE_ADHOC
) |
4357 BIT(NL80211_IFTYPE_AP
) |
4358 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4359 BIT(NL80211_IFTYPE_P2P_GO
) |
4360 BIT(NL80211_IFTYPE_P2P_DEVICE
);
4361 wiphy
->iface_combinations
= brcmf_iface_combos
;
4362 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
4363 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4364 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4365 wiphy
->cipher_suites
= __wl_cipher_suites
;
4366 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4367 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
4368 WIPHY_FLAG_OFFCHAN_TX
|
4369 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
|
4370 WIPHY_FLAG_SUPPORTS_TDLS
;
4371 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
4372 wiphy
->max_remain_on_channel_duration
= 5000;
4373 brcmf_wiphy_pno_params(wiphy
);
4374 brcmf_dbg(INFO
, "Registering custom regulatory\n");
4375 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
4376 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
4377 err
= wiphy_register(wiphy
);
4379 brcmf_err("Could not register wiphy device (%d)\n", err
);
4381 return ERR_PTR(err
);
4386 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4387 enum nl80211_iftype type
,
4390 struct brcmf_cfg80211_vif
*vif
;
4392 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
4394 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
4396 return ERR_PTR(-ENOMEM
);
4398 vif
->wdev
.wiphy
= cfg
->wiphy
;
4399 vif
->wdev
.iftype
= type
;
4401 vif
->mode
= brcmf_nl80211_iftype_to_mode(type
);
4402 vif
->pm_block
= pm_block
;
4405 brcmf_init_prof(&vif
->profile
);
4407 list_add_tail(&vif
->list
, &cfg
->vif_list
);
4411 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
4413 list_del(&vif
->list
);
4417 void brcmf_cfg80211_free_netdev(struct net_device
*ndev
)
4419 struct brcmf_cfg80211_vif
*vif
;
4420 struct brcmf_if
*ifp
;
4422 ifp
= netdev_priv(ndev
);
4425 brcmf_free_vif(vif
);
4429 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4431 u32 event
= e
->event_code
;
4432 u32 status
= e
->status
;
4434 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4435 brcmf_dbg(CONN
, "Processing set ssid\n");
4442 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4444 u32 event
= e
->event_code
;
4445 u16 flags
= e
->flags
;
4447 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
4448 brcmf_dbg(CONN
, "Processing link down\n");
4454 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4455 const struct brcmf_event_msg
*e
)
4457 u32 event
= e
->event_code
;
4458 u32 status
= e
->status
;
4460 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4461 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
4462 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
4466 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4467 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
4474 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4476 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4478 kfree(conn_info
->req_ie
);
4479 conn_info
->req_ie
= NULL
;
4480 conn_info
->req_ie_len
= 0;
4481 kfree(conn_info
->resp_ie
);
4482 conn_info
->resp_ie
= NULL
;
4483 conn_info
->resp_ie_len
= 0;
4486 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
4487 struct brcmf_if
*ifp
)
4489 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4490 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4495 brcmf_clear_assoc_ies(cfg
);
4497 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4498 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4500 brcmf_err("could not get assoc info (%d)\n", err
);
4504 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4505 req_len
= le32_to_cpu(assoc_info
->req_len
);
4506 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4508 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4512 brcmf_err("could not get assoc req (%d)\n", err
);
4515 conn_info
->req_ie_len
= req_len
;
4517 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4520 conn_info
->req_ie_len
= 0;
4521 conn_info
->req_ie
= NULL
;
4524 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4528 brcmf_err("could not get assoc resp (%d)\n", err
);
4531 conn_info
->resp_ie_len
= resp_len
;
4532 conn_info
->resp_ie
=
4533 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4536 conn_info
->resp_ie_len
= 0;
4537 conn_info
->resp_ie
= NULL
;
4539 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
4540 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4546 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4547 struct net_device
*ndev
,
4548 const struct brcmf_event_msg
*e
)
4550 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4551 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4552 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4553 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4554 struct ieee80211_channel
*notify_channel
= NULL
;
4555 struct ieee80211_supported_band
*band
;
4556 struct brcmf_bss_info_le
*bi
;
4557 struct brcmu_chan ch
;
4562 brcmf_dbg(TRACE
, "Enter\n");
4564 brcmf_get_assoc_ies(cfg
, ifp
);
4565 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4566 brcmf_update_bss_info(cfg
, ifp
);
4568 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4574 /* data sent to dongle has to be little endian */
4575 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4576 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4577 buf
, WL_BSS_INFO_MAX
);
4582 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4583 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
4584 cfg
->d11inf
.decchspec(&ch
);
4586 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
4587 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4589 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4591 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
4592 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4596 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4597 conn_info
->req_ie
, conn_info
->req_ie_len
,
4598 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4599 brcmf_dbg(CONN
, "Report roaming result\n");
4601 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4602 brcmf_dbg(TRACE
, "Exit\n");
4607 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4608 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4611 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4612 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4613 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4616 brcmf_dbg(TRACE
, "Enter\n");
4618 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4619 &ifp
->vif
->sme_state
)) {
4621 brcmf_get_assoc_ies(cfg
, ifp
);
4622 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4623 brcmf_update_bss_info(cfg
, ifp
);
4624 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4625 &ifp
->vif
->sme_state
);
4627 cfg80211_connect_result(ndev
,
4628 (u8
*)profile
->bssid
,
4630 conn_info
->req_ie_len
,
4632 conn_info
->resp_ie_len
,
4633 completed
? WLAN_STATUS_SUCCESS
:
4634 WLAN_STATUS_AUTH_TIMEOUT
,
4636 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4637 completed
? "succeeded" : "failed");
4639 brcmf_dbg(TRACE
, "Exit\n");
4644 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4645 struct net_device
*ndev
,
4646 const struct brcmf_event_msg
*e
, void *data
)
4648 static int generation
;
4649 u32 event
= e
->event_code
;
4650 u32 reason
= e
->reason
;
4651 struct station_info sinfo
;
4653 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4654 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
4655 ndev
!= cfg_to_ndev(cfg
)) {
4656 brcmf_dbg(CONN
, "AP mode link down\n");
4657 complete(&cfg
->vif_disabled
);
4661 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4662 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4663 memset(&sinfo
, 0, sizeof(sinfo
));
4664 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4666 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4669 sinfo
.assoc_req_ies
= data
;
4670 sinfo
.assoc_req_ies_len
= e
->datalen
;
4672 sinfo
.generation
= generation
;
4673 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4674 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4675 (event
== BRCMF_E_DEAUTH_IND
) ||
4676 (event
== BRCMF_E_DEAUTH
)) {
4677 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4683 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4684 const struct brcmf_event_msg
*e
, void *data
)
4686 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4687 struct net_device
*ndev
= ifp
->ndev
;
4688 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4689 struct ieee80211_channel
*chan
;
4692 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4693 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4694 } else if (brcmf_is_linkup(e
)) {
4695 brcmf_dbg(CONN
, "Linkup\n");
4696 if (brcmf_is_ibssmode(ifp
->vif
)) {
4697 chan
= ieee80211_get_channel(cfg
->wiphy
, cfg
->channel
);
4698 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4699 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4700 cfg80211_ibss_joined(ndev
, e
->addr
, chan
, GFP_KERNEL
);
4701 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4702 &ifp
->vif
->sme_state
);
4703 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4704 &ifp
->vif
->sme_state
);
4706 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4707 } else if (brcmf_is_linkdown(e
)) {
4708 brcmf_dbg(CONN
, "Linkdown\n");
4709 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4710 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4711 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4712 &ifp
->vif
->sme_state
))
4713 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4716 brcmf_link_down(ifp
->vif
);
4717 brcmf_init_prof(ndev_to_prof(ndev
));
4718 if (ndev
!= cfg_to_ndev(cfg
))
4719 complete(&cfg
->vif_disabled
);
4720 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4721 if (brcmf_is_ibssmode(ifp
->vif
))
4722 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4723 &ifp
->vif
->sme_state
);
4725 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4732 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4733 const struct brcmf_event_msg
*e
, void *data
)
4735 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4737 u32 event
= e
->event_code
;
4738 u32 status
= e
->status
;
4740 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4741 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4742 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4744 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4751 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4752 const struct brcmf_event_msg
*e
, void *data
)
4754 u16 flags
= e
->flags
;
4755 enum nl80211_key_type key_type
;
4757 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4758 key_type
= NL80211_KEYTYPE_GROUP
;
4760 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4762 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4768 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4769 const struct brcmf_event_msg
*e
, void *data
)
4771 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4772 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4773 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4774 struct brcmf_cfg80211_vif
*vif
;
4776 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4777 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4780 mutex_lock(&event
->vif_event_lock
);
4781 event
->action
= ifevent
->action
;
4784 switch (ifevent
->action
) {
4785 case BRCMF_E_IF_ADD
:
4786 /* waiting process may have timed out */
4787 if (!cfg
->vif_event
.vif
) {
4788 mutex_unlock(&event
->vif_event_lock
);
4795 vif
->wdev
.netdev
= ifp
->ndev
;
4796 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4797 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4799 mutex_unlock(&event
->vif_event_lock
);
4800 wake_up(&event
->vif_wq
);
4803 case BRCMF_E_IF_DEL
:
4804 mutex_unlock(&event
->vif_event_lock
);
4805 /* event may not be upon user request */
4806 if (brcmf_cfg80211_vif_event_armed(cfg
))
4807 wake_up(&event
->vif_wq
);
4810 case BRCMF_E_IF_CHANGE
:
4811 mutex_unlock(&event
->vif_event_lock
);
4812 wake_up(&event
->vif_wq
);
4816 mutex_unlock(&event
->vif_event_lock
);
4822 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4824 conf
->frag_threshold
= (u32
)-1;
4825 conf
->rts_threshold
= (u32
)-1;
4826 conf
->retry_short
= (u32
)-1;
4827 conf
->retry_long
= (u32
)-1;
4828 conf
->tx_power
= -1;
4831 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4833 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4834 brcmf_notify_connect_status
);
4835 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4836 brcmf_notify_connect_status
);
4837 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4838 brcmf_notify_connect_status
);
4839 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4840 brcmf_notify_connect_status
);
4841 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4842 brcmf_notify_connect_status
);
4843 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4844 brcmf_notify_connect_status
);
4845 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4846 brcmf_notify_roaming_status
);
4847 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4848 brcmf_notify_mic_status
);
4849 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4850 brcmf_notify_connect_status
);
4851 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4852 brcmf_notify_sched_scan_results
);
4853 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4854 brcmf_notify_vif_event
);
4855 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
4856 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
4857 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
4858 brcmf_p2p_notify_listen_complete
);
4859 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
4860 brcmf_p2p_notify_action_frame_rx
);
4861 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
4862 brcmf_p2p_notify_action_tx_complete
);
4863 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
4864 brcmf_p2p_notify_action_tx_complete
);
4867 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4871 kfree(cfg
->escan_ioctl_buf
);
4872 cfg
->escan_ioctl_buf
= NULL
;
4873 kfree(cfg
->extra_buf
);
4874 cfg
->extra_buf
= NULL
;
4875 kfree(cfg
->pmk_list
);
4876 cfg
->pmk_list
= NULL
;
4879 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4881 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4883 goto init_priv_mem_out
;
4884 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4885 if (!cfg
->escan_ioctl_buf
)
4886 goto init_priv_mem_out
;
4887 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4888 if (!cfg
->extra_buf
)
4889 goto init_priv_mem_out
;
4890 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4892 goto init_priv_mem_out
;
4897 brcmf_deinit_priv_mem(cfg
);
4902 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4906 cfg
->scan_request
= NULL
;
4907 cfg
->pwr_save
= true;
4908 cfg
->roam_on
= true; /* roam on & off switch.
4909 we enable roam per default */
4910 cfg
->active_scan
= true; /* we do active scan for
4911 specific scan per default */
4912 cfg
->dongle_up
= false; /* dongle is not up yet */
4913 err
= brcmf_init_priv_mem(cfg
);
4916 brcmf_register_event_handlers(cfg
);
4917 mutex_init(&cfg
->usr_sync
);
4918 brcmf_init_escan(cfg
);
4919 brcmf_init_conf(cfg
->conf
);
4920 init_completion(&cfg
->vif_disabled
);
4924 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4926 cfg
->dongle_up
= false; /* dongle down */
4927 brcmf_abort_scanning(cfg
);
4928 brcmf_deinit_priv_mem(cfg
);
4931 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4933 init_waitqueue_head(&event
->vif_wq
);
4934 mutex_init(&event
->vif_event_lock
);
4937 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4938 struct device
*busdev
)
4940 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4941 struct brcmf_cfg80211_info
*cfg
;
4942 struct wiphy
*wiphy
;
4943 struct brcmf_cfg80211_vif
*vif
;
4944 struct brcmf_if
*ifp
;
4949 brcmf_err("ndev is invalid\n");
4953 ifp
= netdev_priv(ndev
);
4954 wiphy
= brcmf_setup_wiphy(busdev
);
4958 cfg
= wiphy_priv(wiphy
);
4961 init_vif_event(&cfg
->vif_event
);
4962 INIT_LIST_HEAD(&cfg
->vif_list
);
4964 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4971 vif
->wdev
.netdev
= ndev
;
4972 ndev
->ieee80211_ptr
= &vif
->wdev
;
4973 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4975 err
= wl_init_priv(cfg
);
4977 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4978 goto cfg80211_attach_out
;
4982 err
= brcmf_p2p_attach(cfg
);
4984 brcmf_err("P2P initilisation failed (%d)\n", err
);
4985 goto cfg80211_p2p_attach_out
;
4987 err
= brcmf_btcoex_attach(cfg
);
4989 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
4990 brcmf_p2p_detach(&cfg
->p2p
);
4991 goto cfg80211_p2p_attach_out
;
4994 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
4996 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
4997 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
5000 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
,
5003 brcmf_err("Failed to get D11 version (%d)\n", err
);
5004 goto cfg80211_p2p_attach_out
;
5006 cfg
->d11inf
.io_type
= (u8
)io_type
;
5007 brcmu_d11_attach(&cfg
->d11inf
);
5011 cfg80211_p2p_attach_out
:
5012 wl_deinit_priv(cfg
);
5014 cfg80211_attach_out
:
5015 brcmf_free_vif(vif
);
5019 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
5024 WARN_ON(!list_empty(&cfg
->vif_list
));
5025 wiphy_unregister(cfg
->wiphy
);
5026 brcmf_btcoex_detach(cfg
);
5027 wl_deinit_priv(cfg
);
5028 wiphy_free(cfg
->wiphy
);
5032 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
5035 __le32 roamtrigger
[2];
5036 __le32 roam_delta
[2];
5039 * Setup timeout if Beacons are lost and roam is
5040 * off to report link down
5043 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5045 brcmf_err("bcn_timeout error (%d)\n", err
);
5046 goto dongle_rom_out
;
5051 * Enable/Disable built-in roaming to allow supplicant
5052 * to take care of roaming
5054 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
5055 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
5057 brcmf_err("roam_off error (%d)\n", err
);
5058 goto dongle_rom_out
;
5061 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5062 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5063 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5064 (void *)roamtrigger
, sizeof(roamtrigger
));
5066 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5067 goto dongle_rom_out
;
5070 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5071 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5072 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5073 (void *)roam_delta
, sizeof(roam_delta
));
5075 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5076 goto dongle_rom_out
;
5084 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
5085 s32 scan_unassoc_time
, s32 scan_passive_time
)
5089 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5092 if (err
== -EOPNOTSUPP
)
5093 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
5095 brcmf_err("Scan assoc time error (%d)\n", err
);
5096 goto dongle_scantime_out
;
5098 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5101 if (err
== -EOPNOTSUPP
)
5102 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
5104 brcmf_err("Scan unassoc time error (%d)\n", err
);
5105 goto dongle_scantime_out
;
5108 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5111 if (err
== -EOPNOTSUPP
)
5112 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
5114 brcmf_err("Scan passive time error (%d)\n", err
);
5115 goto dongle_scantime_out
;
5118 dongle_scantime_out
:
5123 static s32
brcmf_construct_reginfo(struct brcmf_cfg80211_info
*cfg
,
5126 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5127 struct ieee80211_channel
*band_chan_arr
;
5128 struct brcmf_chanspec_list
*list
;
5129 struct brcmu_chan ch
;
5134 enum ieee80211_band band
;
5142 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5147 list
= (struct brcmf_chanspec_list
*)pbuf
;
5149 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5152 brcmf_err("get chanspecs error (%d)\n", err
);
5156 __wl_band_2ghz
.n_channels
= 0;
5157 __wl_band_5ghz_a
.n_channels
= 0;
5159 total
= le32_to_cpu(list
->count
);
5160 for (i
= 0; i
< total
; i
++) {
5161 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5162 cfg
->d11inf
.decchspec(&ch
);
5164 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5165 band_chan_arr
= __wl_2ghz_channels
;
5166 array_size
= ARRAY_SIZE(__wl_2ghz_channels
);
5167 n_cnt
= &__wl_band_2ghz
.n_channels
;
5168 band
= IEEE80211_BAND_2GHZ
;
5169 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5170 band_chan_arr
= __wl_5ghz_a_channels
;
5171 array_size
= ARRAY_SIZE(__wl_5ghz_a_channels
);
5172 n_cnt
= &__wl_band_5ghz_a
.n_channels
;
5173 band
= IEEE80211_BAND_5GHZ
;
5175 brcmf_err("Invalid channel Spec. 0x%x.\n", ch
.chspec
);
5178 if (!(bw_cap
[band
] & WLC_BW_40MHZ_BIT
) &&
5179 ch
.bw
== BRCMU_CHAN_BW_40
)
5182 for (j
= 0; (j
< *n_cnt
&& (*n_cnt
< array_size
)); j
++) {
5183 if (band_chan_arr
[j
].hw_value
== ch
.chnum
) {
5192 if (index
< array_size
) {
5193 band_chan_arr
[index
].center_freq
=
5194 ieee80211_channel_to_frequency(ch
.chnum
, band
);
5195 band_chan_arr
[index
].hw_value
= ch
.chnum
;
5197 if (ch
.bw
== BRCMU_CHAN_BW_40
) {
5198 /* assuming the order is HT20, HT40 Upper,
5199 * HT40 lower from chanspecs
5201 ht40_flag
= band_chan_arr
[index
].flags
&
5202 IEEE80211_CHAN_NO_HT40
;
5203 if (ch
.sb
== BRCMU_CHAN_SB_U
) {
5204 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5205 band_chan_arr
[index
].flags
&=
5206 ~IEEE80211_CHAN_NO_HT40
;
5207 band_chan_arr
[index
].flags
|=
5208 IEEE80211_CHAN_NO_HT40PLUS
;
5210 /* It should be one of
5211 * IEEE80211_CHAN_NO_HT40 or
5212 * IEEE80211_CHAN_NO_HT40PLUS
5214 band_chan_arr
[index
].flags
&=
5215 ~IEEE80211_CHAN_NO_HT40
;
5216 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5217 band_chan_arr
[index
].flags
|=
5218 IEEE80211_CHAN_NO_HT40MINUS
;
5221 band_chan_arr
[index
].flags
=
5222 IEEE80211_CHAN_NO_HT40
;
5223 ch
.bw
= BRCMU_CHAN_BW_20
;
5224 cfg
->d11inf
.encchspec(&ch
);
5225 channel
= ch
.chspec
;
5226 err
= brcmf_fil_bsscfg_int_get(ifp
,
5230 if (channel
& WL_CHAN_RADAR
)
5231 band_chan_arr
[index
].flags
|=
5232 (IEEE80211_CHAN_RADAR
|
5233 IEEE80211_CHAN_NO_IR
);
5234 if (channel
& WL_CHAN_PASSIVE
)
5235 band_chan_arr
[index
].flags
|=
5236 IEEE80211_CHAN_NO_IR
;
5248 static void brcmf_get_bwcap(struct brcmf_if
*ifp
, u32 bw_cap
[])
5250 u32 band
, mimo_bwcap
;
5254 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5256 bw_cap
[IEEE80211_BAND_2GHZ
] = band
;
5258 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5260 bw_cap
[IEEE80211_BAND_5GHZ
] = band
;
5266 brcmf_dbg(INFO
, "fallback to mimo_bw_cap info\n");
5268 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &mimo_bwcap
);
5270 /* assume 20MHz if firmware does not give a clue */
5271 mimo_bwcap
= WLC_N_BW_20ALL
;
5273 switch (mimo_bwcap
) {
5274 case WLC_N_BW_40ALL
:
5275 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_40MHZ_BIT
;
5277 case WLC_N_BW_20IN2G_40IN5G
:
5278 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_40MHZ_BIT
;
5280 case WLC_N_BW_20ALL
:
5281 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_20MHZ_BIT
;
5282 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_20MHZ_BIT
;
5285 brcmf_err("invalid mimo_bw_cap value\n");
5289 static s32
brcmf_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
5291 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5292 struct wiphy
*wiphy
;
5296 u32 bw_cap
[2] = { 0, 0 };
5301 struct ieee80211_supported_band
*bands
[2] = { NULL
, NULL
};
5302 struct ieee80211_supported_band
*band
;
5304 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
5305 &phy_list
, sizeof(phy_list
));
5307 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err
);
5311 phy
= ((char *)&phy_list
)[0];
5312 brcmf_dbg(INFO
, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy
);
5315 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
,
5316 &band_list
, sizeof(band_list
));
5318 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err
);
5321 brcmf_dbg(INFO
, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5322 band_list
[0], band_list
[1], band_list
[2]);
5324 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
5326 brcmf_err("nmode error (%d)\n", err
);
5328 brcmf_get_bwcap(ifp
, bw_cap
);
5330 brcmf_dbg(INFO
, "nmode=%d, bw_cap=(%d, %d)\n", nmode
,
5331 bw_cap
[IEEE80211_BAND_2GHZ
], bw_cap
[IEEE80211_BAND_5GHZ
]);
5333 err
= brcmf_construct_reginfo(cfg
, bw_cap
);
5335 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err
);
5339 nband
= band_list
[0];
5341 for (i
= 1; i
<= nband
&& i
< ARRAY_SIZE(band_list
); i
++) {
5343 if ((band_list
[i
] == WLC_BAND_5G
) &&
5344 (__wl_band_5ghz_a
.n_channels
> 0))
5345 band
= &__wl_band_5ghz_a
;
5346 else if ((band_list
[i
] == WLC_BAND_2G
) &&
5347 (__wl_band_2ghz
.n_channels
> 0))
5348 band
= &__wl_band_2ghz
;
5352 if (bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) {
5353 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_40
;
5354 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
5356 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5357 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5358 band
->ht_cap
.ht_supported
= true;
5359 band
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5360 band
->ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5361 /* An HT shall support all EQM rates for one spatial
5364 band
->ht_cap
.mcs
.rx_mask
[0] = 0xff;
5365 band
->ht_cap
.mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
5366 bands
[band
->band
] = band
;
5369 wiphy
= cfg_to_wiphy(cfg
);
5370 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = bands
[IEEE80211_BAND_2GHZ
];
5371 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = bands
[IEEE80211_BAND_5GHZ
];
5372 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
5378 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5380 return brcmf_update_wiphybands(cfg
);
5383 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5385 struct net_device
*ndev
;
5386 struct wireless_dev
*wdev
;
5387 struct brcmf_if
*ifp
;
5394 ndev
= cfg_to_ndev(cfg
);
5395 wdev
= ndev
->ieee80211_ptr
;
5396 ifp
= netdev_priv(ndev
);
5398 /* make sure RF is ready for work */
5399 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
5401 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
5402 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5404 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5405 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
5407 goto default_conf_out
;
5408 brcmf_dbg(INFO
, "power save set to %s\n",
5409 (power_mode
? "enabled" : "disabled"));
5411 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
5413 goto default_conf_out
;
5414 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5417 goto default_conf_out
;
5418 err
= brcmf_dongle_probecap(cfg
);
5420 goto default_conf_out
;
5422 brcmf_configure_arp_offload(ifp
, true);
5424 cfg
->dongle_up
= true;
5431 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
5433 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5435 return brcmf_config_dongle(ifp
->drvr
->config
);
5438 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
5440 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5443 * While going down, if associated with AP disassociate
5444 * from AP to save power
5446 if (check_vif_up(ifp
->vif
)) {
5447 brcmf_link_down(ifp
->vif
);
5449 /* Make sure WPA_Supplicant receives all the event
5450 generated due to DISASSOC call to the fw to keep
5451 the state fw and WPA_Supplicant state consistent
5456 brcmf_abort_scanning(cfg
);
5457 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5462 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
5464 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5465 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5468 mutex_lock(&cfg
->usr_sync
);
5469 err
= __brcmf_cfg80211_up(ifp
);
5470 mutex_unlock(&cfg
->usr_sync
);
5475 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
5477 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5478 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5481 mutex_lock(&cfg
->usr_sync
);
5482 err
= __brcmf_cfg80211_down(ifp
);
5483 mutex_unlock(&cfg
->usr_sync
);
5488 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
5490 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
5492 return wdev
->iftype
;
5495 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
5497 struct brcmf_cfg80211_vif
*vif
;
5500 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
5501 if (test_bit(state
, &vif
->sme_state
))
5507 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
5512 mutex_lock(&event
->vif_event_lock
);
5513 evt_action
= event
->action
;
5514 mutex_unlock(&event
->vif_event_lock
);
5515 return evt_action
== action
;
5518 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
5519 struct brcmf_cfg80211_vif
*vif
)
5521 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5523 mutex_lock(&event
->vif_event_lock
);
5526 mutex_unlock(&event
->vif_event_lock
);
5529 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
5531 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5534 mutex_lock(&event
->vif_event_lock
);
5535 armed
= event
->vif
!= NULL
;
5536 mutex_unlock(&event
->vif_event_lock
);
5540 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
5541 u8 action
, ulong timeout
)
5543 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5545 return wait_event_timeout(event
->vif_wq
,
5546 vif_event_equals(event
, action
), timeout
);