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 struct brcmf_tlv
*brcmf_parse_tlvs(void *buf
, int buflen
, uint key
)
356 struct brcmf_tlv
*elt
;
359 elt
= (struct brcmf_tlv
*)buf
;
362 /* find tagged parameter */
363 while (totlen
>= TLV_HDR_LEN
) {
366 /* validate remaining totlen */
367 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
370 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
371 totlen
-= (len
+ TLV_HDR_LEN
);
377 /* Is any of the tlvs the expected entry? If
378 * not update the tlvs buffer pointer/length.
381 brcmf_tlv_has_ie(u8
*ie
, u8
**tlvs
, u32
*tlvs_len
,
382 u8
*oui
, u32 oui_len
, u8 type
)
384 /* If the contents match the OUI and the type */
385 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
386 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
387 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
393 /* point to the next ie */
394 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
395 /* calculate the length of the rest of the buffer */
396 *tlvs_len
-= (int)(ie
- *tlvs
);
397 /* update the pointer to the start of the buffer */
403 static struct brcmf_vs_tlv
*
404 brcmf_find_wpaie(u8
*parse
, u32 len
)
406 struct brcmf_tlv
*ie
;
408 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
409 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
410 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
411 return (struct brcmf_vs_tlv
*)ie
;
416 static struct brcmf_vs_tlv
*
417 brcmf_find_wpsie(u8
*parse
, u32 len
)
419 struct brcmf_tlv
*ie
;
421 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
422 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
423 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
424 return (struct brcmf_vs_tlv
*)ie
;
430 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
431 struct brcmf_wsec_key_le
*key_le
)
433 key_le
->index
= cpu_to_le32(key
->index
);
434 key_le
->len
= cpu_to_le32(key
->len
);
435 key_le
->algo
= cpu_to_le32(key
->algo
);
436 key_le
->flags
= cpu_to_le32(key
->flags
);
437 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
438 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
439 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
440 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
441 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
445 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
448 struct brcmf_wsec_key_le key_le
;
450 convert_key_from_CPU(key
, &key_le
);
452 brcmf_netdev_wait_pend8021x(ndev
);
454 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
458 brcmf_err("wsec_key error (%d)\n", err
);
463 brcmf_configure_arp_offload(struct brcmf_if
*ifp
, bool enable
)
469 mode
= BRCMF_ARP_OL_AGENT
| BRCMF_ARP_OL_PEER_AUTO_REPLY
;
473 /* Try to set and enable ARP offload feature, this may fail, then it */
474 /* is simply not supported and err 0 will be returned */
475 err
= brcmf_fil_iovar_int_set(ifp
, "arp_ol", mode
);
477 brcmf_dbg(TRACE
, "failed to set ARP offload mode to 0x%x, err = %d\n",
481 err
= brcmf_fil_iovar_int_set(ifp
, "arpoe", enable
);
483 brcmf_dbg(TRACE
, "failed to configure (%d) ARP offload err = %d\n",
487 brcmf_dbg(TRACE
, "successfully configured (%d) ARP offload to 0x%x\n",
494 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
496 enum nl80211_iftype type
,
498 struct vif_params
*params
)
500 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
502 case NL80211_IFTYPE_ADHOC
:
503 case NL80211_IFTYPE_STATION
:
504 case NL80211_IFTYPE_AP
:
505 case NL80211_IFTYPE_AP_VLAN
:
506 case NL80211_IFTYPE_WDS
:
507 case NL80211_IFTYPE_MONITOR
:
508 case NL80211_IFTYPE_MESH_POINT
:
509 return ERR_PTR(-EOPNOTSUPP
);
510 case NL80211_IFTYPE_P2P_CLIENT
:
511 case NL80211_IFTYPE_P2P_GO
:
512 case NL80211_IFTYPE_P2P_DEVICE
:
513 return brcmf_p2p_add_vif(wiphy
, name
, type
, flags
, params
);
514 case NL80211_IFTYPE_UNSPECIFIED
:
516 return ERR_PTR(-EINVAL
);
520 void brcmf_set_mpc(struct brcmf_if
*ifp
, int mpc
)
524 if (check_vif_up(ifp
->vif
)) {
525 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
527 brcmf_err("fail to set mpc\n");
530 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
534 s32
brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
535 struct brcmf_if
*ifp
, bool aborted
,
538 struct brcmf_scan_params_le params_le
;
539 struct cfg80211_scan_request
*scan_request
;
542 brcmf_dbg(SCAN
, "Enter\n");
544 /* clear scan request, because the FW abort can cause a second call */
545 /* to this functon and might cause a double cfg80211_scan_done */
546 scan_request
= cfg
->scan_request
;
547 cfg
->scan_request
= NULL
;
549 if (timer_pending(&cfg
->escan_timeout
))
550 del_timer_sync(&cfg
->escan_timeout
);
553 /* Do a scan abort to stop the driver's scan engine */
554 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
555 memset(¶ms_le
, 0, sizeof(params_le
));
556 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
557 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
558 params_le
.scan_type
= 0;
559 params_le
.channel_num
= cpu_to_le32(1);
560 params_le
.nprobes
= cpu_to_le32(1);
561 params_le
.active_time
= cpu_to_le32(-1);
562 params_le
.passive_time
= cpu_to_le32(-1);
563 params_le
.home_time
= cpu_to_le32(-1);
564 /* Scan is aborted by setting channel_list[0] to -1 */
565 params_le
.channel_list
[0] = cpu_to_le16(-1);
566 /* E-Scan (or anyother type) can be aborted by SCAN */
567 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
568 ¶ms_le
, sizeof(params_le
));
570 brcmf_err("Scan abort failed\n");
573 * e-scan can be initiated by scheduled scan
574 * which takes precedence.
576 if (cfg
->sched_escan
) {
577 brcmf_dbg(SCAN
, "scheduled scan completed\n");
578 cfg
->sched_escan
= false;
580 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
581 brcmf_set_mpc(ifp
, 1);
582 } else if (scan_request
) {
583 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
584 aborted
? "Aborted" : "Done");
585 cfg80211_scan_done(scan_request
, aborted
);
586 brcmf_set_mpc(ifp
, 1);
588 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
589 brcmf_dbg(SCAN
, "Scan complete, probably P2P scan\n");
595 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
597 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
598 struct net_device
*ndev
= wdev
->netdev
;
600 /* vif event pending in firmware */
601 if (brcmf_cfg80211_vif_event_armed(cfg
))
605 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
606 cfg
->escan_info
.ifp
== netdev_priv(ndev
))
607 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
),
610 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
613 switch (wdev
->iftype
) {
614 case NL80211_IFTYPE_ADHOC
:
615 case NL80211_IFTYPE_STATION
:
616 case NL80211_IFTYPE_AP
:
617 case NL80211_IFTYPE_AP_VLAN
:
618 case NL80211_IFTYPE_WDS
:
619 case NL80211_IFTYPE_MONITOR
:
620 case NL80211_IFTYPE_MESH_POINT
:
622 case NL80211_IFTYPE_P2P_CLIENT
:
623 case NL80211_IFTYPE_P2P_GO
:
624 case NL80211_IFTYPE_P2P_DEVICE
:
625 return brcmf_p2p_del_vif(wiphy
, wdev
);
626 case NL80211_IFTYPE_UNSPECIFIED
:
634 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
635 enum nl80211_iftype type
, u32
*flags
,
636 struct vif_params
*params
)
638 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
639 struct brcmf_if
*ifp
= netdev_priv(ndev
);
640 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
645 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
648 case NL80211_IFTYPE_MONITOR
:
649 case NL80211_IFTYPE_WDS
:
650 brcmf_err("type (%d) : currently we do not support this type\n",
653 case NL80211_IFTYPE_ADHOC
:
654 vif
->mode
= WL_MODE_IBSS
;
657 case NL80211_IFTYPE_STATION
:
658 /* Ignore change for p2p IF. Unclear why supplicant does this */
659 if ((vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) ||
660 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
)) {
661 brcmf_dbg(TRACE
, "Ignoring cmd for p2p if\n");
662 /* WAR: It is unexpected to get a change of VIF for P2P
663 * IF, but it happens. The request can not be handled
664 * but returning EPERM causes a crash. Returning 0
665 * without setting ieee80211_ptr->iftype causes trace
666 * (WARN_ON) but it works with wpa_supplicant
670 vif
->mode
= WL_MODE_BSS
;
673 case NL80211_IFTYPE_AP
:
674 case NL80211_IFTYPE_P2P_GO
:
675 vif
->mode
= WL_MODE_AP
;
684 if (type
== NL80211_IFTYPE_P2P_GO
) {
685 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
686 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
689 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
690 brcmf_dbg(INFO
, "IF Type = AP\n");
693 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
695 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
699 brcmf_dbg(INFO
, "IF Type = %s\n", (vif
->mode
== WL_MODE_IBSS
) ?
702 ndev
->ieee80211_ptr
->iftype
= type
;
705 brcmf_dbg(TRACE
, "Exit\n");
710 static void brcmf_escan_prep(struct brcmf_cfg80211_info
*cfg
,
711 struct brcmf_scan_params_le
*params_le
,
712 struct cfg80211_scan_request
*request
)
720 struct brcmf_ssid_le ssid_le
;
722 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
723 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
724 params_le
->scan_type
= 0;
725 params_le
->channel_num
= 0;
726 params_le
->nprobes
= cpu_to_le32(-1);
727 params_le
->active_time
= cpu_to_le32(-1);
728 params_le
->passive_time
= cpu_to_le32(-1);
729 params_le
->home_time
= cpu_to_le32(-1);
730 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
732 /* if request is null exit so it will be all channel broadcast scan */
736 n_ssids
= request
->n_ssids
;
737 n_channels
= request
->n_channels
;
738 /* Copy channel array if applicable */
739 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
741 if (n_channels
> 0) {
742 for (i
= 0; i
< n_channels
; i
++) {
743 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
744 request
->channels
[i
]);
745 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
746 request
->channels
[i
]->hw_value
, chanspec
);
747 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
750 brcmf_dbg(SCAN
, "Scanning all channels\n");
752 /* Copy ssid array if applicable */
753 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
755 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
756 n_channels
* sizeof(u16
);
757 offset
= roundup(offset
, sizeof(u32
));
758 ptr
= (char *)params_le
+ offset
;
759 for (i
= 0; i
< n_ssids
; i
++) {
760 memset(&ssid_le
, 0, sizeof(ssid_le
));
762 cpu_to_le32(request
->ssids
[i
].ssid_len
);
763 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
764 request
->ssids
[i
].ssid_len
);
765 if (!ssid_le
.SSID_len
)
766 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
768 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
769 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
770 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
771 ptr
+= sizeof(ssid_le
);
774 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
775 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
776 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
777 params_le
->ssid_le
.SSID
,
778 request
->ssids
->ssid_len
);
779 params_le
->ssid_le
.SSID_len
=
780 cpu_to_le32(request
->ssids
->ssid_len
);
781 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
782 request
->ssids
->ssid_len
);
785 /* Adding mask to channel numbers */
786 params_le
->channel_num
=
787 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
788 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
792 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
,
793 struct cfg80211_scan_request
*request
, u16 action
)
795 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
796 offsetof(struct brcmf_escan_params_le
, params_le
);
797 struct brcmf_escan_params_le
*params
;
800 brcmf_dbg(SCAN
, "E-SCAN START\n");
802 if (request
!= NULL
) {
803 /* Allocate space for populating ssids in struct */
804 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
806 /* Allocate space for populating ssids in struct */
807 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
810 params
= kzalloc(params_size
, GFP_KERNEL
);
815 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
816 brcmf_escan_prep(cfg
, ¶ms
->params_le
, request
);
817 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
818 params
->action
= cpu_to_le16(action
);
819 params
->sync_id
= cpu_to_le16(0x1234);
821 err
= brcmf_fil_iovar_data_set(ifp
, "escan", params
, params_size
);
824 brcmf_dbg(INFO
, "system busy : escan canceled\n");
826 brcmf_err("error (%d)\n", err
);
835 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
836 struct brcmf_if
*ifp
, struct cfg80211_scan_request
*request
)
840 struct brcmf_scan_results
*results
;
841 struct escan_info
*escan
= &cfg
->escan_info
;
843 brcmf_dbg(SCAN
, "Enter\n");
845 escan
->wiphy
= wiphy
;
846 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
847 passive_scan
= cfg
->active_scan
? 0 : 1;
848 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
851 brcmf_err("error (%d)\n", err
);
854 brcmf_set_mpc(ifp
, 0);
855 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
856 results
->version
= 0;
858 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
860 err
= escan
->run(cfg
, ifp
, request
, WL_ESCAN_ACTION_START
);
862 brcmf_set_mpc(ifp
, 1);
867 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct brcmf_cfg80211_vif
*vif
,
868 struct cfg80211_scan_request
*request
,
869 struct cfg80211_ssid
*this_ssid
)
871 struct brcmf_if
*ifp
= vif
->ifp
;
872 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
873 struct cfg80211_ssid
*ssids
;
874 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
881 brcmf_dbg(SCAN
, "START ESCAN\n");
883 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
884 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
887 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
888 brcmf_err("Scanning being aborted: status (%lu)\n",
892 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
893 brcmf_err("Scanning suppressed: status (%lu)\n",
897 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
898 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
902 /* If scan req comes for p2p0, send it over primary I/F */
903 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
904 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
;
906 /* Arm scan timeout timer */
907 mod_timer(&cfg
->escan_timeout
, jiffies
+
908 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
913 ssids
= request
->ssids
;
917 /* we don't do escan in ibss */
921 cfg
->scan_request
= request
;
922 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
924 cfg
->escan_info
.run
= brcmf_run_escan
;
925 err
= brcmf_p2p_scan_prep(wiphy
, request
, vif
);
929 err
= brcmf_do_escan(cfg
, wiphy
, vif
->ifp
, request
);
933 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
934 ssids
->ssid
, ssids
->ssid_len
);
935 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
936 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
937 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
940 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
941 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
944 brcmf_dbg(SCAN
, "Broadcast scan\n");
946 passive_scan
= cfg
->active_scan
? 0 : 1;
947 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
950 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
953 brcmf_set_mpc(ifp
, 0);
954 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
955 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
958 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
961 brcmf_err("WLC_SCAN error (%d)\n", err
);
963 brcmf_set_mpc(ifp
, 1);
971 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
972 if (timer_pending(&cfg
->escan_timeout
))
973 del_timer_sync(&cfg
->escan_timeout
);
974 cfg
->scan_request
= NULL
;
979 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
981 struct brcmf_cfg80211_vif
*vif
;
984 brcmf_dbg(TRACE
, "Enter\n");
985 vif
= container_of(request
->wdev
, struct brcmf_cfg80211_vif
, wdev
);
986 if (!check_vif_up(vif
))
989 err
= brcmf_cfg80211_escan(wiphy
, vif
, request
, NULL
);
992 brcmf_err("scan error (%d)\n", err
);
994 brcmf_dbg(TRACE
, "Exit\n");
998 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1002 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1005 brcmf_err("Error (%d)\n", err
);
1010 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1014 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1017 brcmf_err("Error (%d)\n", err
);
1022 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1025 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1027 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1029 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1035 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1037 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1038 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1039 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1042 brcmf_dbg(TRACE
, "Enter\n");
1043 if (!check_vif_up(ifp
->vif
))
1046 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1047 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1048 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1049 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1053 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1054 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1055 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1056 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1060 if (changed
& WIPHY_PARAM_RETRY_LONG
1061 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1062 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1063 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1067 if (changed
& WIPHY_PARAM_RETRY_SHORT
1068 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1069 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1070 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1076 brcmf_dbg(TRACE
, "Exit\n");
1080 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1082 memset(prof
, 0, sizeof(*prof
));
1085 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
1087 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(vif
->wdev
.wiphy
);
1090 brcmf_dbg(TRACE
, "Enter\n");
1092 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1093 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1094 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1095 BRCMF_C_DISASSOC
, NULL
, 0);
1097 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1099 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
1100 cfg80211_disconnected(vif
->wdev
.netdev
, 0, NULL
, 0, GFP_KERNEL
);
1103 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1104 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
1105 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
1106 brcmf_dbg(TRACE
, "Exit\n");
1110 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1111 struct cfg80211_ibss_params
*params
)
1113 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1114 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1115 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1116 struct brcmf_join_params join_params
;
1117 size_t join_params_size
= 0;
1123 brcmf_dbg(TRACE
, "Enter\n");
1124 if (!check_vif_up(ifp
->vif
))
1128 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1130 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1134 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1137 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1139 brcmf_dbg(CONN
, "No BSSID specified\n");
1141 if (params
->chandef
.chan
)
1142 brcmf_dbg(CONN
, "channel: %d\n",
1143 params
->chandef
.chan
->center_freq
);
1145 brcmf_dbg(CONN
, "no channel specified\n");
1147 if (params
->channel_fixed
)
1148 brcmf_dbg(CONN
, "fixed channel required\n");
1150 brcmf_dbg(CONN
, "no fixed channel required\n");
1152 if (params
->ie
&& params
->ie_len
)
1153 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1155 brcmf_dbg(CONN
, "no ie specified\n");
1157 if (params
->beacon_interval
)
1158 brcmf_dbg(CONN
, "beacon interval: %d\n",
1159 params
->beacon_interval
);
1161 brcmf_dbg(CONN
, "no beacon interval specified\n");
1163 if (params
->basic_rates
)
1164 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1166 brcmf_dbg(CONN
, "no basic rates specified\n");
1168 if (params
->privacy
)
1169 brcmf_dbg(CONN
, "privacy required\n");
1171 brcmf_dbg(CONN
, "no privacy required\n");
1173 /* Configure Privacy for starter */
1174 if (params
->privacy
)
1175 wsec
|= WEP_ENABLED
;
1177 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1179 brcmf_err("wsec failed (%d)\n", err
);
1183 /* Configure Beacon Interval for starter */
1184 if (params
->beacon_interval
)
1185 bcnprd
= params
->beacon_interval
;
1189 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1191 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1195 /* Configure required join parameter */
1196 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1199 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1200 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1201 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1202 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1203 join_params_size
= sizeof(join_params
.ssid_le
);
1206 if (params
->bssid
) {
1207 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1208 join_params_size
= sizeof(join_params
.ssid_le
) +
1209 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1210 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1212 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1213 memset(profile
->bssid
, 0, ETH_ALEN
);
1217 if (params
->chandef
.chan
) {
1221 ieee80211_frequency_to_channel(
1222 params
->chandef
.chan
->center_freq
);
1223 if (params
->channel_fixed
) {
1224 /* adding chanspec */
1225 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
1226 params
->chandef
.chan
);
1227 join_params
.params_le
.chanspec_list
[0] =
1228 cpu_to_le16(chanspec
);
1229 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1230 join_params_size
+= sizeof(join_params
.params_le
);
1233 /* set channel for starter */
1234 target_channel
= cfg
->channel
;
1235 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1238 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1244 cfg
->ibss_starter
= false;
1247 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1248 &join_params
, join_params_size
);
1250 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1256 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1257 brcmf_dbg(TRACE
, "Exit\n");
1262 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1264 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1267 brcmf_dbg(TRACE
, "Enter\n");
1268 if (!check_vif_up(ifp
->vif
))
1271 brcmf_link_down(ifp
->vif
);
1273 brcmf_dbg(TRACE
, "Exit\n");
1278 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1279 struct cfg80211_connect_params
*sme
)
1281 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1282 struct brcmf_cfg80211_security
*sec
;
1286 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1287 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1288 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1289 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1291 val
= WPA_AUTH_DISABLED
;
1292 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1293 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1295 brcmf_err("set wpa_auth failed (%d)\n", err
);
1298 sec
= &profile
->sec
;
1299 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1303 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1304 struct cfg80211_connect_params
*sme
)
1306 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1307 struct brcmf_cfg80211_security
*sec
;
1311 switch (sme
->auth_type
) {
1312 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1314 brcmf_dbg(CONN
, "open system\n");
1316 case NL80211_AUTHTYPE_SHARED_KEY
:
1318 brcmf_dbg(CONN
, "shared key\n");
1320 case NL80211_AUTHTYPE_AUTOMATIC
:
1322 brcmf_dbg(CONN
, "automatic\n");
1324 case NL80211_AUTHTYPE_NETWORK_EAP
:
1325 brcmf_dbg(CONN
, "network eap\n");
1328 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1332 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1334 brcmf_err("set auth failed (%d)\n", err
);
1337 sec
= &profile
->sec
;
1338 sec
->auth_type
= sme
->auth_type
;
1343 brcmf_set_set_cipher(struct net_device
*ndev
,
1344 struct cfg80211_connect_params
*sme
)
1346 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1347 struct brcmf_cfg80211_security
*sec
;
1352 if (sme
->crypto
.n_ciphers_pairwise
) {
1353 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1354 case WLAN_CIPHER_SUITE_WEP40
:
1355 case WLAN_CIPHER_SUITE_WEP104
:
1358 case WLAN_CIPHER_SUITE_TKIP
:
1359 pval
= TKIP_ENABLED
;
1361 case WLAN_CIPHER_SUITE_CCMP
:
1364 case WLAN_CIPHER_SUITE_AES_CMAC
:
1368 brcmf_err("invalid cipher pairwise (%d)\n",
1369 sme
->crypto
.ciphers_pairwise
[0]);
1373 if (sme
->crypto
.cipher_group
) {
1374 switch (sme
->crypto
.cipher_group
) {
1375 case WLAN_CIPHER_SUITE_WEP40
:
1376 case WLAN_CIPHER_SUITE_WEP104
:
1379 case WLAN_CIPHER_SUITE_TKIP
:
1380 gval
= TKIP_ENABLED
;
1382 case WLAN_CIPHER_SUITE_CCMP
:
1385 case WLAN_CIPHER_SUITE_AES_CMAC
:
1389 brcmf_err("invalid cipher group (%d)\n",
1390 sme
->crypto
.cipher_group
);
1395 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1396 /* In case of privacy, but no security and WPS then simulate */
1397 /* setting AES. WPS-2.0 allows no security */
1398 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1401 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", pval
| gval
);
1403 brcmf_err("error (%d)\n", err
);
1407 sec
= &profile
->sec
;
1408 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1409 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1415 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1417 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1418 struct brcmf_cfg80211_security
*sec
;
1422 if (sme
->crypto
.n_akm_suites
) {
1423 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
),
1426 brcmf_err("could not get wpa_auth (%d)\n", err
);
1429 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1430 switch (sme
->crypto
.akm_suites
[0]) {
1431 case WLAN_AKM_SUITE_8021X
:
1432 val
= WPA_AUTH_UNSPECIFIED
;
1434 case WLAN_AKM_SUITE_PSK
:
1438 brcmf_err("invalid cipher group (%d)\n",
1439 sme
->crypto
.cipher_group
);
1442 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1443 switch (sme
->crypto
.akm_suites
[0]) {
1444 case WLAN_AKM_SUITE_8021X
:
1445 val
= WPA2_AUTH_UNSPECIFIED
;
1447 case WLAN_AKM_SUITE_PSK
:
1448 val
= WPA2_AUTH_PSK
;
1451 brcmf_err("invalid cipher group (%d)\n",
1452 sme
->crypto
.cipher_group
);
1457 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1458 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
),
1461 brcmf_err("could not set wpa_auth (%d)\n", err
);
1465 sec
= &profile
->sec
;
1466 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1472 brcmf_set_sharedkey(struct net_device
*ndev
,
1473 struct cfg80211_connect_params
*sme
)
1475 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1476 struct brcmf_cfg80211_security
*sec
;
1477 struct brcmf_wsec_key key
;
1481 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1483 if (sme
->key_len
== 0)
1486 sec
= &profile
->sec
;
1487 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1488 sec
->wpa_versions
, sec
->cipher_pairwise
);
1490 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1493 if (!(sec
->cipher_pairwise
&
1494 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1497 memset(&key
, 0, sizeof(key
));
1498 key
.len
= (u32
) sme
->key_len
;
1499 key
.index
= (u32
) sme
->key_idx
;
1500 if (key
.len
> sizeof(key
.data
)) {
1501 brcmf_err("Too long key length (%u)\n", key
.len
);
1504 memcpy(key
.data
, sme
->key
, key
.len
);
1505 key
.flags
= BRCMF_PRIMARY_KEY
;
1506 switch (sec
->cipher_pairwise
) {
1507 case WLAN_CIPHER_SUITE_WEP40
:
1508 key
.algo
= CRYPTO_ALGO_WEP1
;
1510 case WLAN_CIPHER_SUITE_WEP104
:
1511 key
.algo
= CRYPTO_ALGO_WEP128
;
1514 brcmf_err("Invalid algorithm (%d)\n",
1515 sme
->crypto
.ciphers_pairwise
[0]);
1518 /* Set the new key/index */
1519 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1520 key
.len
, key
.index
, key
.algo
);
1521 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1522 err
= send_key_to_dongle(ndev
, &key
);
1526 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1527 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1528 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1529 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1531 brcmf_err("set auth failed (%d)\n", err
);
1537 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1538 enum nl80211_auth_type type
)
1541 if (type
== NL80211_AUTHTYPE_AUTOMATIC
) {
1542 /* shift to ignore chip revision */
1543 ci
= brcmf_get_chip_info(ifp
) >> 4;
1546 brcmf_dbg(CONN
, "43236 WAR: use OPEN instead of AUTO\n");
1547 return NL80211_AUTHTYPE_OPEN_SYSTEM
;
1556 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1557 struct cfg80211_connect_params
*sme
)
1559 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1560 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1561 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1562 struct ieee80211_channel
*chan
= sme
->channel
;
1563 struct brcmf_join_params join_params
;
1564 size_t join_params_size
;
1565 struct brcmf_tlv
*rsn_ie
;
1566 struct brcmf_vs_tlv
*wpa_ie
;
1569 struct brcmf_ext_join_params_le
*ext_join_params
;
1574 brcmf_dbg(TRACE
, "Enter\n");
1575 if (!check_vif_up(ifp
->vif
))
1579 brcmf_err("Invalid ssid\n");
1583 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1584 /* A normal (non P2P) connection request setup. */
1587 /* find the WPA_IE */
1588 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1591 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1593 /* find the RSN_IE */
1594 rsn_ie
= brcmf_parse_tlvs((u8
*)sme
->ie
, sme
->ie_len
,
1598 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1601 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1604 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1605 sme
->ie
, sme
->ie_len
);
1607 brcmf_err("Set Assoc REQ IE Failed\n");
1609 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1611 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1615 ieee80211_frequency_to_channel(chan
->center_freq
);
1616 chanspec
= channel_to_chanspec(&cfg
->d11inf
, chan
);
1617 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1618 cfg
->channel
, chan
->center_freq
, chanspec
);
1624 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1626 err
= brcmf_set_wpa_version(ndev
, sme
);
1628 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1632 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1633 err
= brcmf_set_auth_type(ndev
, sme
);
1635 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1639 err
= brcmf_set_set_cipher(ndev
, sme
);
1641 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1645 err
= brcmf_set_key_mgmt(ndev
, sme
);
1647 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1651 err
= brcmf_set_sharedkey(ndev
, sme
);
1653 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1657 profile
->ssid
.SSID_len
= min_t(u32
, (u32
)sizeof(profile
->ssid
.SSID
),
1658 (u32
)sme
->ssid_len
);
1659 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1660 if (profile
->ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1661 profile
->ssid
.SSID
[profile
->ssid
.SSID_len
] = 0;
1662 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n", profile
->ssid
.SSID
,
1663 profile
->ssid
.SSID_len
);
1666 /* Join with specific BSSID and cached SSID
1667 * If SSID is zero join based on BSSID only
1669 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1670 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1672 join_params_size
+= sizeof(u16
);
1673 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1674 if (ext_join_params
== NULL
) {
1678 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1679 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
,
1680 profile
->ssid
.SSID_len
);
1681 /*increase dwell time to receive probe response or detect Beacon
1682 * from target AP at a noisy air only during connect command
1684 ext_join_params
->scan_le
.active_time
=
1685 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1686 ext_join_params
->scan_le
.passive_time
=
1687 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
1688 /* Set up join scan parameters */
1689 ext_join_params
->scan_le
.scan_type
= -1;
1690 /* to sync with presence period of VSDB GO.
1691 * Send probe request more frequently. Probe request will be stopped
1692 * when it gets probe response from target AP/GO.
1694 ext_join_params
->scan_le
.nprobes
=
1695 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
1696 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
1697 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1700 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1702 memset(&ext_join_params
->assoc_le
.bssid
, 0xFF, ETH_ALEN
);
1705 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1707 ext_join_params
->assoc_le
.chanspec_list
[0] =
1708 cpu_to_le16(chanspec
);
1711 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
1713 kfree(ext_join_params
);
1715 /* This is it. join command worked, we are done */
1718 /* join command failed, fallback to set ssid */
1719 memset(&join_params
, 0, sizeof(join_params
));
1720 join_params_size
= sizeof(join_params
.ssid_le
);
1722 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1723 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1726 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1728 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1731 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1732 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1733 join_params_size
+= sizeof(join_params
.params_le
);
1735 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1736 &join_params
, join_params_size
);
1738 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
1742 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1743 brcmf_dbg(TRACE
, "Exit\n");
1748 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1751 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1752 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1753 struct brcmf_scb_val_le scbval
;
1756 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1757 if (!check_vif_up(ifp
->vif
))
1760 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1761 cfg80211_disconnected(ndev
, reason_code
, NULL
, 0, GFP_KERNEL
);
1763 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1764 scbval
.val
= cpu_to_le32(reason_code
);
1765 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1766 &scbval
, sizeof(scbval
));
1768 brcmf_err("error (%d)\n", err
);
1770 brcmf_dbg(TRACE
, "Exit\n");
1775 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1776 enum nl80211_tx_power_setting type
, s32 mbm
)
1779 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1780 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1781 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1785 s32 dbm
= MBM_TO_DBM(mbm
);
1787 brcmf_dbg(TRACE
, "Enter\n");
1788 if (!check_vif_up(ifp
->vif
))
1792 case NL80211_TX_POWER_AUTOMATIC
:
1794 case NL80211_TX_POWER_LIMITED
:
1795 case NL80211_TX_POWER_FIXED
:
1797 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1803 /* Make sure radio is off or on as far as software is concerned */
1804 disable
= WL_RADIO_SW_DISABLE
<< 16;
1805 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1807 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1812 txpwrmw
= (u16
) dbm
;
1813 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1814 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1816 brcmf_err("qtxpower error (%d)\n", err
);
1817 cfg
->conf
->tx_power
= dbm
;
1820 brcmf_dbg(TRACE
, "Exit\n");
1824 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1825 struct wireless_dev
*wdev
,
1828 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1829 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1834 brcmf_dbg(TRACE
, "Enter\n");
1835 if (!check_vif_up(ifp
->vif
))
1838 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1840 brcmf_err("error (%d)\n", err
);
1844 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1845 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1848 brcmf_dbg(TRACE
, "Exit\n");
1853 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1854 u8 key_idx
, bool unicast
, bool multicast
)
1856 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1861 brcmf_dbg(TRACE
, "Enter\n");
1862 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1863 if (!check_vif_up(ifp
->vif
))
1866 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1868 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1872 if (wsec
& WEP_ENABLED
) {
1873 /* Just select a new current key */
1875 err
= brcmf_fil_cmd_int_set(ifp
,
1876 BRCMF_C_SET_KEY_PRIMARY
, index
);
1878 brcmf_err("error (%d)\n", err
);
1881 brcmf_dbg(TRACE
, "Exit\n");
1886 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1887 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1889 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1890 struct brcmf_wsec_key key
;
1894 memset(&key
, 0, sizeof(key
));
1895 key
.index
= (u32
) key_idx
;
1896 /* Instead of bcast for ea address for default wep keys,
1897 driver needs it to be Null */
1898 if (!is_multicast_ether_addr(mac_addr
))
1899 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1900 key
.len
= (u32
) params
->key_len
;
1901 /* check for key index change */
1904 err
= send_key_to_dongle(ndev
, &key
);
1906 brcmf_err("key delete error (%d)\n", err
);
1908 if (key
.len
> sizeof(key
.data
)) {
1909 brcmf_err("Invalid key length (%d)\n", key
.len
);
1913 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1914 memcpy(key
.data
, params
->key
, key
.len
);
1916 if ((ifp
->vif
->mode
!= WL_MODE_AP
) &&
1917 (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)) {
1918 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
1919 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1920 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1921 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1924 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1925 if (params
->seq
&& params
->seq_len
== 6) {
1928 ivptr
= (u8
*) params
->seq
;
1929 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1930 (ivptr
[3] << 8) | ivptr
[2];
1931 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1932 key
.iv_initialized
= true;
1935 switch (params
->cipher
) {
1936 case WLAN_CIPHER_SUITE_WEP40
:
1937 key
.algo
= CRYPTO_ALGO_WEP1
;
1938 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1940 case WLAN_CIPHER_SUITE_WEP104
:
1941 key
.algo
= CRYPTO_ALGO_WEP128
;
1942 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1944 case WLAN_CIPHER_SUITE_TKIP
:
1945 key
.algo
= CRYPTO_ALGO_TKIP
;
1946 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1948 case WLAN_CIPHER_SUITE_AES_CMAC
:
1949 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1950 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1952 case WLAN_CIPHER_SUITE_CCMP
:
1953 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1954 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1957 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1960 err
= send_key_to_dongle(ndev
, &key
);
1962 brcmf_err("wsec_key error (%d)\n", err
);
1968 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1969 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1970 struct key_params
*params
)
1972 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1973 struct brcmf_wsec_key key
;
1979 brcmf_dbg(TRACE
, "Enter\n");
1980 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1981 if (!check_vif_up(ifp
->vif
))
1985 brcmf_dbg(TRACE
, "Exit");
1986 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1988 memset(&key
, 0, sizeof(key
));
1990 key
.len
= (u32
) params
->key_len
;
1991 key
.index
= (u32
) key_idx
;
1993 if (key
.len
> sizeof(key
.data
)) {
1994 brcmf_err("Too long key length (%u)\n", key
.len
);
1998 memcpy(key
.data
, params
->key
, key
.len
);
2000 key
.flags
= BRCMF_PRIMARY_KEY
;
2001 switch (params
->cipher
) {
2002 case WLAN_CIPHER_SUITE_WEP40
:
2003 key
.algo
= CRYPTO_ALGO_WEP1
;
2005 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2007 case WLAN_CIPHER_SUITE_WEP104
:
2008 key
.algo
= CRYPTO_ALGO_WEP128
;
2010 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2012 case WLAN_CIPHER_SUITE_TKIP
:
2013 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
2014 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2015 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2016 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2017 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2019 key
.algo
= CRYPTO_ALGO_TKIP
;
2021 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2023 case WLAN_CIPHER_SUITE_AES_CMAC
:
2024 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2026 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2028 case WLAN_CIPHER_SUITE_CCMP
:
2029 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2031 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2034 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2039 err
= send_key_to_dongle(ndev
, &key
);
2043 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2045 brcmf_err("get wsec error (%d)\n", err
);
2049 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2051 brcmf_err("set wsec error (%d)\n", err
);
2056 brcmf_dbg(TRACE
, "Exit\n");
2061 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2062 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2064 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2065 struct brcmf_wsec_key key
;
2068 brcmf_dbg(TRACE
, "Enter\n");
2069 if (!check_vif_up(ifp
->vif
))
2072 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
2073 /* we ignore this key index in this case */
2074 brcmf_err("invalid key index (%d)\n", key_idx
);
2078 memset(&key
, 0, sizeof(key
));
2080 key
.index
= (u32
) key_idx
;
2081 key
.flags
= BRCMF_PRIMARY_KEY
;
2082 key
.algo
= CRYPTO_ALGO_OFF
;
2084 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2086 /* Set the new key/index */
2087 err
= send_key_to_dongle(ndev
, &key
);
2089 brcmf_dbg(TRACE
, "Exit\n");
2094 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2095 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2096 void (*callback
) (void *cookie
, struct key_params
* params
))
2098 struct key_params params
;
2099 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2100 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2101 struct brcmf_cfg80211_security
*sec
;
2105 brcmf_dbg(TRACE
, "Enter\n");
2106 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2107 if (!check_vif_up(ifp
->vif
))
2110 memset(¶ms
, 0, sizeof(params
));
2112 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2114 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2115 /* Ignore this error, may happen during DISASSOC */
2119 if (wsec
& WEP_ENABLED
) {
2120 sec
= &profile
->sec
;
2121 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2122 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2123 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2124 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2125 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2126 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2128 } else if (wsec
& TKIP_ENABLED
) {
2129 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2130 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2131 } else if (wsec
& AES_ENABLED
) {
2132 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2133 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2135 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2139 callback(cookie
, ¶ms
);
2142 brcmf_dbg(TRACE
, "Exit\n");
2147 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2148 struct net_device
*ndev
, u8 key_idx
)
2150 brcmf_dbg(INFO
, "Not supported\n");
2156 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2157 u8
*mac
, struct station_info
*sinfo
)
2159 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2160 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2161 struct brcmf_scb_val_le scb_val
;
2165 u8
*bssid
= profile
->bssid
;
2166 struct brcmf_sta_info_le sta_info_le
;
2168 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2169 if (!check_vif_up(ifp
->vif
))
2172 if (ifp
->vif
->mode
== WL_MODE_AP
) {
2173 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2174 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2176 sizeof(sta_info_le
));
2178 brcmf_err("GET STA INFO failed, %d\n", err
);
2181 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2182 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2183 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2184 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2185 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2187 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
2188 sinfo
->inactive_time
, sinfo
->connected_time
);
2189 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
2190 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2191 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2196 /* Report the current tx rate */
2197 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2199 brcmf_err("Could not get rate (%d)\n", err
);
2202 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2203 sinfo
->txrate
.legacy
= rate
* 5;
2204 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
2207 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2208 &ifp
->vif
->sme_state
)) {
2209 memset(&scb_val
, 0, sizeof(scb_val
));
2210 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2211 &scb_val
, sizeof(scb_val
));
2213 brcmf_err("Could not get rssi (%d)\n", err
);
2216 rssi
= le32_to_cpu(scb_val
.val
);
2217 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2218 sinfo
->signal
= rssi
;
2219 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2225 brcmf_dbg(TRACE
, "Exit\n");
2230 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2231 bool enabled
, s32 timeout
)
2235 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2236 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2238 brcmf_dbg(TRACE
, "Enter\n");
2241 * Powersave enable/disable request is coming from the
2242 * cfg80211 even before the interface is up. In that
2243 * scenario, driver will be storing the power save
2244 * preference in cfg struct to apply this to
2245 * FW later while initializing the dongle
2247 cfg
->pwr_save
= enabled
;
2248 if (!check_vif_up(ifp
->vif
)) {
2250 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2254 pm
= enabled
? PM_FAST
: PM_OFF
;
2255 /* Do not enable the power save after assoc if it is a p2p interface */
2256 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2257 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2260 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2262 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2265 brcmf_err("net_device is not ready yet\n");
2267 brcmf_err("error (%d)\n", err
);
2270 brcmf_dbg(TRACE
, "Exit\n");
2274 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2275 struct brcmf_bss_info_le
*bi
)
2277 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2278 struct ieee80211_channel
*notify_channel
;
2279 struct cfg80211_bss
*bss
;
2280 struct ieee80211_supported_band
*band
;
2281 struct brcmu_chan ch
;
2285 u16 notify_capability
;
2286 u16 notify_interval
;
2288 size_t notify_ielen
;
2291 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2292 brcmf_err("Bss info is larger than buffer. Discarding\n");
2297 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2298 cfg
->d11inf
.decchspec(&ch
);
2299 bi
->ctl_ch
= ch
.chnum
;
2301 channel
= bi
->ctl_ch
;
2303 if (channel
<= CH_MAX_2G_CHANNEL
)
2304 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2306 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2308 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2309 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2311 notify_capability
= le16_to_cpu(bi
->capability
);
2312 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2313 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2314 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2315 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2317 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2318 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2319 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2320 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2321 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2323 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2324 0, notify_capability
, notify_interval
, notify_ie
,
2325 notify_ielen
, notify_signal
, GFP_KERNEL
);
2330 cfg80211_put_bss(wiphy
, bss
);
2335 static struct brcmf_bss_info_le
*
2336 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2339 return list
->bss_info_le
;
2340 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2341 le32_to_cpu(bss
->length
));
2344 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2346 struct brcmf_scan_results
*bss_list
;
2347 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2351 bss_list
= cfg
->bss_list
;
2352 if (bss_list
->count
!= 0 &&
2353 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2354 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2358 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2359 for (i
= 0; i
< bss_list
->count
; i
++) {
2360 bi
= next_bss_le(bss_list
, bi
);
2361 err
= brcmf_inform_single_bss(cfg
, bi
);
2368 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2369 struct net_device
*ndev
, const u8
*bssid
)
2371 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2372 struct ieee80211_channel
*notify_channel
;
2373 struct brcmf_bss_info_le
*bi
= NULL
;
2374 struct ieee80211_supported_band
*band
;
2375 struct cfg80211_bss
*bss
;
2376 struct brcmu_chan ch
;
2380 u16 notify_capability
;
2381 u16 notify_interval
;
2383 size_t notify_ielen
;
2386 brcmf_dbg(TRACE
, "Enter\n");
2388 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2394 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2396 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2397 buf
, WL_BSS_INFO_MAX
);
2399 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2403 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2405 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2406 cfg
->d11inf
.decchspec(&ch
);
2408 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2409 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2411 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2413 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2414 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2416 notify_capability
= le16_to_cpu(bi
->capability
);
2417 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2418 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2419 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2420 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2422 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2423 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2424 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2425 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2427 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2428 0, notify_capability
, notify_interval
,
2429 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2436 cfg80211_put_bss(wiphy
, bss
);
2442 brcmf_dbg(TRACE
, "Exit\n");
2447 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2449 return vif
->mode
== WL_MODE_IBSS
;
2452 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2453 struct brcmf_if
*ifp
)
2455 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ifp
->ndev
);
2456 struct brcmf_bss_info_le
*bi
;
2457 struct brcmf_ssid
*ssid
;
2458 struct brcmf_tlv
*tim
;
2459 u16 beacon_interval
;
2465 brcmf_dbg(TRACE
, "Enter\n");
2466 if (brcmf_is_ibssmode(ifp
->vif
))
2469 ssid
= &profile
->ssid
;
2471 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2472 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2473 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2475 brcmf_err("Could not get bss info %d\n", err
);
2476 goto update_bss_info_out
;
2479 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2480 err
= brcmf_inform_single_bss(cfg
, bi
);
2482 goto update_bss_info_out
;
2484 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2485 ie_len
= le32_to_cpu(bi
->ie_length
);
2486 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2488 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2490 dtim_period
= tim
->data
[1];
2493 * active scan was done so we could not get dtim
2494 * information out of probe response.
2495 * so we speficially query dtim information to dongle.
2498 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2500 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2501 goto update_bss_info_out
;
2503 dtim_period
= (u8
)var
;
2506 update_bss_info_out
:
2507 brcmf_dbg(TRACE
, "Exit");
2511 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2513 struct escan_info
*escan
= &cfg
->escan_info
;
2515 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2516 if (cfg
->scan_request
) {
2517 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2518 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2520 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2521 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2524 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2526 struct brcmf_cfg80211_info
*cfg
=
2527 container_of(work
, struct brcmf_cfg80211_info
,
2528 escan_timeout_work
);
2530 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2533 static void brcmf_escan_timeout(unsigned long data
)
2535 struct brcmf_cfg80211_info
*cfg
=
2536 (struct brcmf_cfg80211_info
*)data
;
2538 if (cfg
->scan_request
) {
2539 brcmf_err("timer expired\n");
2540 schedule_work(&cfg
->escan_timeout_work
);
2545 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2546 struct brcmf_bss_info_le
*bss
,
2547 struct brcmf_bss_info_le
*bss_info_le
)
2549 struct brcmu_chan ch_bss
, ch_bss_info_le
;
2551 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
2552 cfg
->d11inf
.decchspec(&ch_bss
);
2553 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
2554 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
2556 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2557 ch_bss
.band
== ch_bss_info_le
.band
&&
2558 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2559 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2560 if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) ==
2561 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
)) {
2562 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2563 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2565 /* preserve max RSSI if the measurements are
2566 * both on-channel or both off-channel
2568 if (bss_info_rssi
> bss_rssi
)
2569 bss
->RSSI
= bss_info_le
->RSSI
;
2570 } else if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) &&
2571 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) == 0) {
2572 /* preserve the on-channel rssi measurement
2573 * if the new measurement is off channel
2575 bss
->RSSI
= bss_info_le
->RSSI
;
2576 bss
->flags
|= BRCMF_BSS_RSSI_ON_CHANNEL
;
2584 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2585 const struct brcmf_event_msg
*e
, void *data
)
2587 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2590 struct brcmf_escan_result_le
*escan_result_le
;
2591 struct brcmf_bss_info_le
*bss_info_le
;
2592 struct brcmf_bss_info_le
*bss
= NULL
;
2594 struct brcmf_scan_results
*list
;
2600 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2601 brcmf_err("scan not ready, bssidx=%d\n", ifp
->bssidx
);
2605 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2606 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2607 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2608 if (!escan_result_le
) {
2609 brcmf_err("Invalid escan result (NULL pointer)\n");
2612 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2613 brcmf_err("Invalid bss_count %d: ignoring\n",
2614 escan_result_le
->bss_count
);
2617 bss_info_le
= &escan_result_le
->bss_info_le
;
2619 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
2622 if (!cfg
->scan_request
) {
2623 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2627 bi_length
= le32_to_cpu(bss_info_le
->length
);
2628 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2629 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2630 brcmf_err("Invalid bss_info length %d: ignoring\n",
2635 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2636 BIT(NL80211_IFTYPE_ADHOC
))) {
2637 if (le16_to_cpu(bss_info_le
->capability
) &
2638 WLAN_CAPABILITY_IBSS
) {
2639 brcmf_err("Ignoring IBSS result\n");
2644 list
= (struct brcmf_scan_results
*)
2645 cfg
->escan_info
.escan_buf
;
2646 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2647 brcmf_err("Buffer is too small: ignoring\n");
2651 for (i
= 0; i
< list
->count
; i
++) {
2652 bss
= bss
? (struct brcmf_bss_info_le
*)
2653 ((unsigned char *)bss
+
2654 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2655 if (brcmf_compare_update_same_bss(cfg
, bss
,
2659 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2660 bss_info_le
, bi_length
);
2661 list
->version
= le32_to_cpu(bss_info_le
->version
);
2662 list
->buflen
+= bi_length
;
2665 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2666 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
2668 if (cfg
->scan_request
) {
2669 cfg
->bss_list
= (struct brcmf_scan_results
*)
2670 cfg
->escan_info
.escan_buf
;
2671 brcmf_inform_bss(cfg
);
2672 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2673 brcmf_notify_escan_complete(cfg
, ifp
, aborted
,
2676 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
2683 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2685 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2686 brcmf_cfg80211_escan_handler
);
2687 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2688 /* Init scan_timeout timer */
2689 init_timer(&cfg
->escan_timeout
);
2690 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2691 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2692 INIT_WORK(&cfg
->escan_timeout_work
,
2693 brcmf_cfg80211_escan_timeout_worker
);
2696 static __always_inline
void brcmf_delay(u32 ms
)
2698 if (ms
< 1000 / HZ
) {
2706 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2708 brcmf_dbg(TRACE
, "Enter\n");
2713 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2714 struct cfg80211_wowlan
*wow
)
2716 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2717 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2718 struct brcmf_cfg80211_vif
*vif
;
2720 brcmf_dbg(TRACE
, "Enter\n");
2723 * if the primary net_device is not READY there is nothing
2724 * we can do but pray resume goes smoothly.
2726 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2727 if (!check_vif_up(vif
))
2730 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2731 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2734 * While going to suspend if associated with AP disassociate
2735 * from AP to save power while system is in suspended state
2737 brcmf_link_down(vif
);
2739 /* Make sure WPA_Supplicant receives all the event
2740 * generated due to DISASSOC call to the fw to keep
2741 * the state fw and WPA_Supplicant state consistent
2746 /* end any scanning */
2747 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2748 brcmf_abort_scanning(cfg
);
2750 /* Turn off watchdog timer */
2751 brcmf_set_mpc(netdev_priv(ndev
), 1);
2754 brcmf_dbg(TRACE
, "Exit\n");
2755 /* clear any scanning activity */
2756 cfg
->scan_status
= 0;
2761 brcmf_update_pmklist(struct net_device
*ndev
,
2762 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2767 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2769 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2770 for (i
= 0; i
< pmkid_len
; i
++) {
2771 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2772 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2773 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2774 brcmf_dbg(CONN
, "%02x\n",
2775 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2779 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2780 (char *)pmk_list
, sizeof(*pmk_list
));
2786 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2787 struct cfg80211_pmksa
*pmksa
)
2789 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2790 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2791 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2796 brcmf_dbg(TRACE
, "Enter\n");
2797 if (!check_vif_up(ifp
->vif
))
2800 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2801 for (i
= 0; i
< pmkid_len
; i
++)
2802 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2804 if (i
< WL_NUM_PMKIDS_MAX
) {
2805 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2806 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2807 if (i
== pmkid_len
) {
2809 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2814 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2815 pmkids
->pmkid
[pmkid_len
].BSSID
);
2816 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2817 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2819 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2821 brcmf_dbg(TRACE
, "Exit\n");
2826 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2827 struct cfg80211_pmksa
*pmksa
)
2829 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2830 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2831 struct pmkid_list pmkid
;
2835 brcmf_dbg(TRACE
, "Enter\n");
2836 if (!check_vif_up(ifp
->vif
))
2839 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2840 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2842 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2843 &pmkid
.pmkid
[0].BSSID
);
2844 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2845 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2847 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2848 for (i
= 0; i
< pmkid_len
; i
++)
2850 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2855 && (i
< pmkid_len
)) {
2856 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2857 sizeof(struct pmkid
));
2858 for (; i
< (pmkid_len
- 1); i
++) {
2859 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2860 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2862 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2863 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2866 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2870 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2872 brcmf_dbg(TRACE
, "Exit\n");
2878 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2880 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2881 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2884 brcmf_dbg(TRACE
, "Enter\n");
2885 if (!check_vif_up(ifp
->vif
))
2888 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2889 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2891 brcmf_dbg(TRACE
, "Exit\n");
2897 * PFN result doesn't have all the info which are
2898 * required by the supplicant
2899 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2900 * via wl_inform_single_bss in the required format. Escan does require the
2901 * scan request in the form of cfg80211_scan_request. For timebeing, create
2902 * cfg80211_scan_request one out of the received PNO event.
2905 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2906 const struct brcmf_event_msg
*e
, void *data
)
2908 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2909 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2910 struct cfg80211_scan_request
*request
= NULL
;
2911 struct cfg80211_ssid
*ssid
= NULL
;
2912 struct ieee80211_channel
*channel
= NULL
;
2913 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2915 int channel_req
= 0;
2917 struct brcmf_pno_scanresults_le
*pfn_result
;
2921 brcmf_dbg(SCAN
, "Enter\n");
2923 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2924 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2928 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2929 result_count
= le32_to_cpu(pfn_result
->count
);
2930 status
= le32_to_cpu(pfn_result
->status
);
2933 * PFN event is limited to fit 512 bytes so we may get
2934 * multiple NET_FOUND events. For now place a warning here.
2936 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2937 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2938 if (result_count
> 0) {
2941 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2942 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2943 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2944 if (!request
|| !ssid
|| !channel
) {
2949 request
->wiphy
= wiphy
;
2950 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2951 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2953 for (i
= 0; i
< result_count
; i
++) {
2954 netinfo
= &netinfo_start
[i
];
2956 brcmf_err("Invalid netinfo ptr. index: %d\n",
2962 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2963 netinfo
->SSID
, netinfo
->channel
);
2964 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2965 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2968 channel_req
= netinfo
->channel
;
2969 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2970 band
= NL80211_BAND_2GHZ
;
2972 band
= NL80211_BAND_5GHZ
;
2973 channel
[i
].center_freq
=
2974 ieee80211_channel_to_frequency(channel_req
,
2976 channel
[i
].band
= band
;
2977 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2978 request
->channels
[i
] = &channel
[i
];
2979 request
->n_channels
++;
2982 /* assign parsed ssid array */
2983 if (request
->n_ssids
)
2984 request
->ssids
= &ssid
[0];
2986 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2987 /* Abort any on-going scan */
2988 brcmf_abort_scanning(cfg
);
2991 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2992 cfg
->escan_info
.run
= brcmf_run_escan
;
2993 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
2995 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2998 cfg
->sched_escan
= true;
2999 cfg
->scan_request
= request
;
3001 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3014 cfg80211_sched_scan_stopped(wiphy
);
3018 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3023 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3026 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3030 brcmf_err("failed code %d\n", ret
);
3035 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3037 struct brcmf_pno_param_le pfn_param
;
3039 memset(&pfn_param
, 0, sizeof(pfn_param
));
3040 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3042 /* set extra pno params */
3043 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3044 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3045 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3047 /* set up pno scan fr */
3048 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3050 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3051 &pfn_param
, sizeof(pfn_param
));
3055 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3056 struct net_device
*ndev
,
3057 struct cfg80211_sched_scan_request
*request
)
3059 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3060 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3061 struct brcmf_pno_net_param_le pfn
;
3065 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3066 request
->n_match_sets
, request
->n_ssids
);
3067 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3068 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3071 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3072 brcmf_err("Scanning suppressed: status (%lu)\n",
3077 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3078 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3083 if (request
->n_ssids
> 0) {
3084 for (i
= 0; i
< request
->n_ssids
; i
++) {
3085 /* Active scan req for ssids */
3086 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3087 request
->ssids
[i
].ssid
);
3090 * match_set ssids is a supert set of n_ssid list,
3091 * so we need not add these set seperately.
3096 if (request
->n_match_sets
> 0) {
3097 /* clean up everything */
3098 ret
= brcmf_dev_pno_clean(ndev
);
3100 brcmf_err("failed error=%d\n", ret
);
3105 ret
= brcmf_dev_pno_config(ndev
);
3107 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
3111 /* configure each match set */
3112 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3113 struct cfg80211_ssid
*ssid
;
3116 ssid
= &request
->match_sets
[i
].ssid
;
3117 ssid_len
= ssid
->ssid_len
;
3120 brcmf_err("skip broadcast ssid\n");
3123 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3124 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3125 pfn
.wsec
= cpu_to_le32(0);
3126 pfn
.infra
= cpu_to_le32(1);
3127 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3128 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3129 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3130 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3132 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3133 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3135 /* Enable the PNO */
3136 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3137 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3147 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3148 struct net_device
*ndev
)
3150 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3152 brcmf_dbg(SCAN
, "enter\n");
3153 brcmf_dev_pno_clean(ndev
);
3154 if (cfg
->sched_escan
)
3155 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3159 #ifdef CONFIG_NL80211_TESTMODE
3160 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
,
3161 struct wireless_dev
*wdev
,
3162 void *data
, int len
)
3164 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3165 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3166 struct brcmf_dcmd
*dcmd
= data
;
3167 struct sk_buff
*reply
;
3170 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3171 dcmd
->buf
, dcmd
->len
);
3174 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3175 dcmd
->buf
, dcmd
->len
);
3177 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3178 dcmd
->buf
, dcmd
->len
);
3180 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3181 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3182 ret
= cfg80211_testmode_reply(reply
);
3188 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3193 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3195 brcmf_err("auth error %d\n", err
);
3199 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3201 brcmf_err("wsec error %d\n", err
);
3204 /* set upper-layer auth */
3205 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3207 brcmf_err("wpa_auth error %d\n", err
);
3214 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3217 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3219 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3223 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3226 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3227 u32 auth
= 0; /* d11 open authentication */
3239 u32 wme_bss_disable
;
3241 brcmf_dbg(TRACE
, "Enter\n");
3245 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3246 data
= (u8
*)wpa_ie
;
3247 offset
= TLV_HDR_LEN
;
3249 offset
+= VS_IE_FIXED_HDR_LEN
;
3251 offset
+= WPA_IE_VERSION_LEN
;
3253 /* check for multicast cipher suite */
3254 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3256 brcmf_err("no multicast cipher suite\n");
3260 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3262 brcmf_err("ivalid OUI\n");
3265 offset
+= TLV_OUI_LEN
;
3267 /* pick up multicast cipher */
3268 switch (data
[offset
]) {
3269 case WPA_CIPHER_NONE
:
3272 case WPA_CIPHER_WEP_40
:
3273 case WPA_CIPHER_WEP_104
:
3276 case WPA_CIPHER_TKIP
:
3277 gval
= TKIP_ENABLED
;
3279 case WPA_CIPHER_AES_CCM
:
3284 brcmf_err("Invalid multi cast cipher info\n");
3289 /* walk thru unicast cipher list and pick up what we recognize */
3290 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3291 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3292 /* Check for unicast suite(s) */
3293 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3295 brcmf_err("no unicast cipher suite\n");
3298 for (i
= 0; i
< count
; i
++) {
3299 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3301 brcmf_err("ivalid OUI\n");
3304 offset
+= TLV_OUI_LEN
;
3305 switch (data
[offset
]) {
3306 case WPA_CIPHER_NONE
:
3308 case WPA_CIPHER_WEP_40
:
3309 case WPA_CIPHER_WEP_104
:
3310 pval
|= WEP_ENABLED
;
3312 case WPA_CIPHER_TKIP
:
3313 pval
|= TKIP_ENABLED
;
3315 case WPA_CIPHER_AES_CCM
:
3316 pval
|= AES_ENABLED
;
3319 brcmf_err("Ivalid unicast security info\n");
3323 /* walk thru auth management suite list and pick up what we recognize */
3324 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3325 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3326 /* Check for auth key management suite(s) */
3327 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3329 brcmf_err("no auth key mgmt suite\n");
3332 for (i
= 0; i
< count
; i
++) {
3333 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3335 brcmf_err("ivalid OUI\n");
3338 offset
+= TLV_OUI_LEN
;
3339 switch (data
[offset
]) {
3341 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3342 wpa_auth
|= WPA_AUTH_NONE
;
3344 case RSN_AKM_UNSPECIFIED
:
3345 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3346 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3347 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3350 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3351 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3352 (wpa_auth
|= WPA_AUTH_PSK
);
3355 brcmf_err("Ivalid key mgmt info\n");
3361 wme_bss_disable
= 1;
3362 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3363 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3364 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3365 wme_bss_disable
= 0;
3367 /* set wme_bss_disable to sync RSN Capabilities */
3368 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3371 brcmf_err("wme_bss_disable error %d\n", err
);
3375 /* FOR WPS , set SES_OW_ENABLED */
3376 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3379 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3381 brcmf_err("auth error %d\n", err
);
3385 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3387 brcmf_err("wsec error %d\n", err
);
3390 /* set upper-layer auth */
3391 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3393 brcmf_err("wpa_auth error %d\n", err
);
3402 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3403 struct parsed_vndr_ies
*vndr_ies
)
3406 struct brcmf_vs_tlv
*vndrie
;
3407 struct brcmf_tlv
*ie
;
3408 struct parsed_vndr_ie_info
*parsed_info
;
3411 remaining_len
= (s32
)vndr_ie_len
;
3412 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3414 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3416 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3418 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3419 /* len should be bigger than OUI length + one */
3420 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3421 brcmf_err("invalid vndr ie. length is too small %d\n",
3425 /* if wpa or wme ie, do not add ie */
3426 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3427 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3428 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3429 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3433 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3435 /* save vndr ie information */
3436 parsed_info
->ie_ptr
= (char *)vndrie
;
3437 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3438 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3442 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3443 parsed_info
->vndrie
.oui
[0],
3444 parsed_info
->vndrie
.oui
[1],
3445 parsed_info
->vndrie
.oui
[2],
3446 parsed_info
->vndrie
.oui_type
);
3448 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3451 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3452 if (remaining_len
<= TLV_HDR_LEN
)
3455 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3462 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3468 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3469 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3471 iecount_le
= cpu_to_le32(1);
3472 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3474 pktflag_le
= cpu_to_le32(pktflag
);
3475 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3477 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3479 return ie_len
+ VNDR_IE_HDR_SIZE
;
3482 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3483 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3485 struct brcmf_if
*ifp
;
3486 struct vif_saved_ie
*saved_ie
;
3490 u8
*mgmt_ie_buf
= NULL
;
3491 int mgmt_ie_buf_len
;
3493 u32 del_add_ie_buf_len
= 0;
3494 u32 total_ie_buf_len
= 0;
3495 u32 parsed_ie_buf_len
= 0;
3496 struct parsed_vndr_ies old_vndr_ies
;
3497 struct parsed_vndr_ies new_vndr_ies
;
3498 struct parsed_vndr_ie_info
*vndrie_info
;
3501 int remained_buf_len
;
3506 saved_ie
= &vif
->saved_ie
;
3508 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3509 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3512 curr_ie_buf
= iovar_ie_buf
;
3514 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3515 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3516 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3517 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3519 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3520 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3521 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3522 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3524 case BRCMF_VNDR_IE_BEACON_FLAG
:
3525 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3526 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3527 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3529 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
3530 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
3531 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
3532 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
3536 brcmf_err("not suitable type\n");
3540 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3542 brcmf_err("extra IE size too big\n");
3546 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3547 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3549 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3550 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3551 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3552 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3553 vndrie_info
->ie_len
);
3554 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3558 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3559 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3560 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3561 parsed_ie_buf_len
) == 0)) {
3562 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3566 /* parse old vndr_ie */
3567 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3569 /* make a command to delete old ie */
3570 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3571 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3573 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3574 vndrie_info
->vndrie
.id
,
3575 vndrie_info
->vndrie
.len
,
3576 vndrie_info
->vndrie
.oui
[0],
3577 vndrie_info
->vndrie
.oui
[1],
3578 vndrie_info
->vndrie
.oui
[2]);
3580 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3581 vndrie_info
->ie_ptr
,
3582 vndrie_info
->ie_len
,
3584 curr_ie_buf
+= del_add_ie_buf_len
;
3585 total_ie_buf_len
+= del_add_ie_buf_len
;
3590 /* Add if there is any extra IE */
3591 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3594 remained_buf_len
= mgmt_ie_buf_len
;
3596 /* make a command to add new ie */
3597 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3598 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3600 /* verify remained buf size before copy data */
3601 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3602 VNDR_IE_VSIE_OFFSET
)) {
3603 brcmf_err("no space in mgmt_ie_buf: len left %d",
3607 remained_buf_len
-= (vndrie_info
->ie_len
+
3608 VNDR_IE_VSIE_OFFSET
);
3610 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3611 vndrie_info
->vndrie
.id
,
3612 vndrie_info
->vndrie
.len
,
3613 vndrie_info
->vndrie
.oui
[0],
3614 vndrie_info
->vndrie
.oui
[1],
3615 vndrie_info
->vndrie
.oui
[2]);
3617 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3618 vndrie_info
->ie_ptr
,
3619 vndrie_info
->ie_len
,
3622 /* save the parsed IE in wl struct */
3623 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3624 vndrie_info
->ie_len
);
3625 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3627 curr_ie_buf
+= del_add_ie_buf_len
;
3628 total_ie_buf_len
+= del_add_ie_buf_len
;
3631 if (total_ie_buf_len
) {
3632 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3635 brcmf_err("vndr ie set error : %d\n", err
);
3639 kfree(iovar_ie_buf
);
3643 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
3646 BRCMF_VNDR_IE_PRBREQ_FLAG
,
3647 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3648 BRCMF_VNDR_IE_BEACON_FLAG
3652 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
3653 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
3655 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
3660 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
3661 struct cfg80211_beacon_data
*beacon
)
3665 /* Set Beacon IEs to FW */
3666 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
3667 beacon
->tail
, beacon
->tail_len
);
3669 brcmf_err("Set Beacon IE Failed\n");
3672 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3674 /* Set Probe Response IEs to FW */
3675 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
3676 beacon
->proberesp_ies
,
3677 beacon
->proberesp_ies_len
);
3679 brcmf_err("Set Probe Resp IE Failed\n");
3681 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3687 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info
*cfg
,
3688 struct brcmf_if
*ifp
,
3689 struct ieee80211_channel
*channel
)
3694 brcmf_dbg(TRACE
, "band=%d, center_freq=%d\n", channel
->band
,
3695 channel
->center_freq
);
3697 chanspec
= channel_to_chanspec(&cfg
->d11inf
, channel
);
3698 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
3704 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3705 struct cfg80211_ap_settings
*settings
)
3708 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3709 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3710 struct brcmf_tlv
*ssid_ie
;
3711 struct brcmf_ssid_le ssid_le
;
3713 struct brcmf_tlv
*rsn_ie
;
3714 struct brcmf_vs_tlv
*wpa_ie
;
3715 struct brcmf_join_params join_params
;
3716 enum nl80211_iftype dev_role
;
3717 struct brcmf_fil_bss_enable_le bss_enable
;
3719 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3720 cfg80211_get_chandef_type(&settings
->chandef
),
3721 settings
->beacon_interval
,
3722 settings
->dtim_period
);
3723 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3724 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3725 settings
->inactivity_timeout
);
3727 dev_role
= ifp
->vif
->wdev
.iftype
;
3729 memset(&ssid_le
, 0, sizeof(ssid_le
));
3730 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3731 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3732 ssid_ie
= brcmf_parse_tlvs(
3733 (u8
*)&settings
->beacon
.head
[ie_offset
],
3734 settings
->beacon
.head_len
- ie_offset
,
3739 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3740 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3741 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3743 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3744 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3747 brcmf_set_mpc(ifp
, 0);
3748 brcmf_configure_arp_offload(ifp
, false);
3750 /* find the RSN_IE */
3751 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3752 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3754 /* find the WPA_IE */
3755 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3756 settings
->beacon
.tail_len
);
3758 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3759 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3760 if (wpa_ie
!= NULL
) {
3762 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3767 err
= brcmf_configure_wpaie(ndev
,
3768 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3773 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3774 brcmf_configure_opensecurity(ifp
);
3777 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
3779 err
= brcmf_cfg80211_set_channel(cfg
, ifp
, settings
->chandef
.chan
);
3781 brcmf_err("Set Channel failed, %d\n", err
);
3785 if (settings
->beacon_interval
) {
3786 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3787 settings
->beacon_interval
);
3789 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3793 if (settings
->dtim_period
) {
3794 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3795 settings
->dtim_period
);
3797 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3802 if (dev_role
== NL80211_IFTYPE_AP
) {
3803 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3805 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3808 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3811 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3813 brcmf_err("SET INFRA error %d\n", err
);
3816 if (dev_role
== NL80211_IFTYPE_AP
) {
3817 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3819 brcmf_err("setting AP mode failed %d\n", err
);
3822 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3824 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3828 memset(&join_params
, 0, sizeof(join_params
));
3829 /* join parameters starts with ssid */
3830 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3832 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3833 &join_params
, sizeof(join_params
));
3835 brcmf_err("SET SSID error (%d)\n", err
);
3838 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
3840 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
3843 brcmf_err("setting ssid failed %d\n", err
);
3846 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3847 bss_enable
.enable
= cpu_to_le32(1);
3848 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3849 sizeof(bss_enable
));
3851 brcmf_err("bss_enable config failed %d\n", err
);
3855 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
3857 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3858 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3862 brcmf_set_mpc(ifp
, 1);
3863 brcmf_configure_arp_offload(ifp
, true);
3868 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3870 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3872 struct brcmf_fil_bss_enable_le bss_enable
;
3873 struct brcmf_join_params join_params
;
3875 brcmf_dbg(TRACE
, "Enter\n");
3877 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
3878 /* Due to most likely deauths outstanding we sleep */
3879 /* first to make sure they get processed by fw. */
3882 memset(&join_params
, 0, sizeof(join_params
));
3883 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3884 &join_params
, sizeof(join_params
));
3886 brcmf_err("SET SSID error (%d)\n", err
);
3887 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3889 brcmf_err("BRCMF_C_UP error %d\n", err
);
3890 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3892 brcmf_err("setting AP mode failed %d\n", err
);
3893 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
3895 brcmf_err("setting INFRA mode failed %d\n", err
);
3897 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3898 bss_enable
.enable
= cpu_to_le32(0);
3899 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3900 sizeof(bss_enable
));
3902 brcmf_err("bss_enable config failed %d\n", err
);
3904 brcmf_set_mpc(ifp
, 1);
3905 brcmf_configure_arp_offload(ifp
, true);
3906 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3907 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3913 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3914 struct cfg80211_beacon_data
*info
)
3916 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3919 brcmf_dbg(TRACE
, "Enter\n");
3921 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
3927 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3930 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3931 struct brcmf_scb_val_le scbval
;
3932 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3938 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3940 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
3941 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3942 if (!check_vif_up(ifp
->vif
))
3945 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3946 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3947 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3948 &scbval
, sizeof(scbval
));
3950 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3952 brcmf_dbg(TRACE
, "Exit\n");
3958 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
3959 struct wireless_dev
*wdev
,
3960 u16 frame_type
, bool reg
)
3962 struct brcmf_cfg80211_vif
*vif
;
3965 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
3967 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
3968 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
3970 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
3972 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
3977 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
3978 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
3980 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3981 struct ieee80211_channel
*chan
= params
->chan
;
3982 const u8
*buf
= params
->buf
;
3983 size_t len
= params
->len
;
3984 const struct ieee80211_mgmt
*mgmt
;
3985 struct brcmf_cfg80211_vif
*vif
;
3989 struct brcmf_fil_action_frame_le
*action_frame
;
3990 struct brcmf_fil_af_params_le
*af_params
;
3995 brcmf_dbg(TRACE
, "Enter\n");
3999 mgmt
= (const struct ieee80211_mgmt
*)buf
;
4001 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
4002 brcmf_err("Driver only allows MGMT packet type\n");
4006 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4008 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4009 /* Right now the only reason to get a probe response */
4010 /* is for p2p listen response or for p2p GO from */
4011 /* wpa_supplicant. Unfortunately the probe is send */
4012 /* on primary ndev, while dongle wants it on the p2p */
4013 /* vif. Since this is only reason for a probe */
4014 /* response to be sent, the vif is taken from cfg. */
4015 /* If ever desired to send proberesp for non p2p */
4016 /* response then data should be checked for */
4017 /* "DIRECT-". Note in future supplicant will take */
4018 /* dedicated p2p wdev to do this and then this 'hack'*/
4019 /* is not needed anymore. */
4020 ie_offset
= DOT11_MGMT_HDR_LEN
+
4021 DOT11_BCN_PRB_FIXED_LEN
;
4022 ie_len
= len
- ie_offset
;
4023 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4024 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4025 err
= brcmf_vif_set_mgmt_ie(vif
,
4026 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4029 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4031 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4032 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4033 if (af_params
== NULL
) {
4034 brcmf_err("unable to allocate frame\n");
4038 action_frame
= &af_params
->action_frame
;
4039 /* Add the packet Id */
4040 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4042 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4043 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4044 /* Add the length exepted for 802.11 header */
4045 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4046 /* Add the channel. Use the one specified as parameter if any or
4047 * the current one (got from the firmware) otherwise
4050 freq
= chan
->center_freq
;
4052 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4054 chan_nr
= ieee80211_frequency_to_channel(freq
);
4055 af_params
->channel
= cpu_to_le32(chan_nr
);
4057 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4058 le16_to_cpu(action_frame
->len
));
4060 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4061 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4063 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4066 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4070 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4071 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4080 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4081 struct wireless_dev
*wdev
,
4084 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4085 struct brcmf_cfg80211_vif
*vif
;
4088 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4090 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4092 brcmf_err("No p2p device available for probe response\n");
4096 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4101 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4102 struct wireless_dev
*wdev
,
4103 enum nl80211_crit_proto_id proto
,
4106 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4107 struct brcmf_cfg80211_vif
*vif
;
4109 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4111 /* only DHCP support for now */
4112 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4115 /* suppress and abort scanning */
4116 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4117 brcmf_abort_scanning(cfg
);
4119 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4122 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4123 struct wireless_dev
*wdev
)
4125 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4126 struct brcmf_cfg80211_vif
*vif
;
4128 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4130 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4131 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4134 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4139 case NL80211_TDLS_DISCOVERY_REQ
:
4140 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4142 case NL80211_TDLS_SETUP
:
4143 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4145 case NL80211_TDLS_TEARDOWN
:
4146 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4149 brcmf_err("unsupported operation: %d\n", oper
);
4155 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4156 struct net_device
*ndev
, u8
*peer
,
4157 enum nl80211_tdls_operation oper
)
4159 struct brcmf_if
*ifp
;
4160 struct brcmf_tdls_iovar_le info
;
4163 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4167 ifp
= netdev_priv(ndev
);
4168 memset(&info
, 0, sizeof(info
));
4169 info
.mode
= (u8
)ret
;
4171 memcpy(info
.ea
, peer
, ETH_ALEN
);
4173 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
4174 &info
, sizeof(info
));
4176 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
4181 static struct cfg80211_ops wl_cfg80211_ops
= {
4182 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4183 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4184 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4185 .scan
= brcmf_cfg80211_scan
,
4186 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4187 .join_ibss
= brcmf_cfg80211_join_ibss
,
4188 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4189 .get_station
= brcmf_cfg80211_get_station
,
4190 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4191 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4192 .add_key
= brcmf_cfg80211_add_key
,
4193 .del_key
= brcmf_cfg80211_del_key
,
4194 .get_key
= brcmf_cfg80211_get_key
,
4195 .set_default_key
= brcmf_cfg80211_config_default_key
,
4196 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4197 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4198 .connect
= brcmf_cfg80211_connect
,
4199 .disconnect
= brcmf_cfg80211_disconnect
,
4200 .suspend
= brcmf_cfg80211_suspend
,
4201 .resume
= brcmf_cfg80211_resume
,
4202 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4203 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4204 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4205 .start_ap
= brcmf_cfg80211_start_ap
,
4206 .stop_ap
= brcmf_cfg80211_stop_ap
,
4207 .change_beacon
= brcmf_cfg80211_change_beacon
,
4208 .del_station
= brcmf_cfg80211_del_station
,
4209 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4210 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4211 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4212 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4213 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4214 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4215 .start_p2p_device
= brcmf_p2p_start_device
,
4216 .stop_p2p_device
= brcmf_p2p_stop_device
,
4217 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
4218 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
4219 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
4220 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode
)
4223 static s32
brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type
)
4226 case NL80211_IFTYPE_AP_VLAN
:
4227 case NL80211_IFTYPE_WDS
:
4228 case NL80211_IFTYPE_MONITOR
:
4229 case NL80211_IFTYPE_MESH_POINT
:
4231 case NL80211_IFTYPE_ADHOC
:
4232 return WL_MODE_IBSS
;
4233 case NL80211_IFTYPE_STATION
:
4234 case NL80211_IFTYPE_P2P_CLIENT
:
4236 case NL80211_IFTYPE_AP
:
4237 case NL80211_IFTYPE_P2P_GO
:
4239 case NL80211_IFTYPE_P2P_DEVICE
:
4241 case NL80211_IFTYPE_UNSPECIFIED
:
4249 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4251 /* scheduled scan settings */
4252 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4253 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4254 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4255 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4258 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
4261 .types
= BIT(NL80211_IFTYPE_STATION
) |
4262 BIT(NL80211_IFTYPE_ADHOC
) |
4263 BIT(NL80211_IFTYPE_AP
)
4267 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4268 BIT(NL80211_IFTYPE_P2P_GO
)
4272 .types
= BIT(NL80211_IFTYPE_P2P_DEVICE
)
4275 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
4277 .max_interfaces
= BRCMF_IFACE_MAX_CNT
,
4278 .num_different_channels
= 2,
4279 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
4280 .limits
= brcmf_iface_limits
4284 static const struct ieee80211_txrx_stypes
4285 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
4286 [NL80211_IFTYPE_STATION
] = {
4288 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4289 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4291 [NL80211_IFTYPE_P2P_CLIENT
] = {
4293 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4294 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4296 [NL80211_IFTYPE_P2P_GO
] = {
4298 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
4299 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
4300 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
4301 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
4302 BIT(IEEE80211_STYPE_AUTH
>> 4) |
4303 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
4304 BIT(IEEE80211_STYPE_ACTION
>> 4)
4306 [NL80211_IFTYPE_P2P_DEVICE
] = {
4308 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4309 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4313 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
4315 struct wiphy
*wiphy
;
4318 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
4320 brcmf_err("Could not allocate wiphy device\n");
4321 return ERR_PTR(-ENOMEM
);
4323 set_wiphy_dev(wiphy
, phydev
);
4324 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4325 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4326 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4327 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4328 BIT(NL80211_IFTYPE_ADHOC
) |
4329 BIT(NL80211_IFTYPE_AP
) |
4330 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4331 BIT(NL80211_IFTYPE_P2P_GO
) |
4332 BIT(NL80211_IFTYPE_P2P_DEVICE
);
4333 wiphy
->iface_combinations
= brcmf_iface_combos
;
4334 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
4335 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4336 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4337 wiphy
->cipher_suites
= __wl_cipher_suites
;
4338 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4339 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
4340 WIPHY_FLAG_OFFCHAN_TX
|
4341 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
|
4342 WIPHY_FLAG_SUPPORTS_TDLS
;
4343 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
4344 wiphy
->max_remain_on_channel_duration
= 5000;
4345 brcmf_wiphy_pno_params(wiphy
);
4346 brcmf_dbg(INFO
, "Registering custom regulatory\n");
4347 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
4348 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
4349 err
= wiphy_register(wiphy
);
4351 brcmf_err("Could not register wiphy device (%d)\n", err
);
4353 return ERR_PTR(err
);
4358 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4359 enum nl80211_iftype type
,
4362 struct brcmf_cfg80211_vif
*vif
;
4364 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
4366 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
4368 return ERR_PTR(-ENOMEM
);
4370 vif
->wdev
.wiphy
= cfg
->wiphy
;
4371 vif
->wdev
.iftype
= type
;
4373 vif
->mode
= brcmf_nl80211_iftype_to_mode(type
);
4374 vif
->pm_block
= pm_block
;
4377 brcmf_init_prof(&vif
->profile
);
4379 list_add_tail(&vif
->list
, &cfg
->vif_list
);
4383 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
4385 list_del(&vif
->list
);
4389 void brcmf_cfg80211_free_netdev(struct net_device
*ndev
)
4391 struct brcmf_cfg80211_vif
*vif
;
4392 struct brcmf_if
*ifp
;
4394 ifp
= netdev_priv(ndev
);
4397 brcmf_free_vif(vif
);
4401 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4403 u32 event
= e
->event_code
;
4404 u32 status
= e
->status
;
4406 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4407 brcmf_dbg(CONN
, "Processing set ssid\n");
4414 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4416 u32 event
= e
->event_code
;
4417 u16 flags
= e
->flags
;
4419 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
4420 brcmf_dbg(CONN
, "Processing link down\n");
4426 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4427 const struct brcmf_event_msg
*e
)
4429 u32 event
= e
->event_code
;
4430 u32 status
= e
->status
;
4432 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4433 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
4434 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
4438 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4439 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
4446 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4448 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4450 kfree(conn_info
->req_ie
);
4451 conn_info
->req_ie
= NULL
;
4452 conn_info
->req_ie_len
= 0;
4453 kfree(conn_info
->resp_ie
);
4454 conn_info
->resp_ie
= NULL
;
4455 conn_info
->resp_ie_len
= 0;
4458 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
4459 struct brcmf_if
*ifp
)
4461 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4462 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4467 brcmf_clear_assoc_ies(cfg
);
4469 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4470 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4472 brcmf_err("could not get assoc info (%d)\n", err
);
4476 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4477 req_len
= le32_to_cpu(assoc_info
->req_len
);
4478 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4480 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4484 brcmf_err("could not get assoc req (%d)\n", err
);
4487 conn_info
->req_ie_len
= req_len
;
4489 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4492 conn_info
->req_ie_len
= 0;
4493 conn_info
->req_ie
= NULL
;
4496 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4500 brcmf_err("could not get assoc resp (%d)\n", err
);
4503 conn_info
->resp_ie_len
= resp_len
;
4504 conn_info
->resp_ie
=
4505 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4508 conn_info
->resp_ie_len
= 0;
4509 conn_info
->resp_ie
= NULL
;
4511 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
4512 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4518 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4519 struct net_device
*ndev
,
4520 const struct brcmf_event_msg
*e
)
4522 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4523 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4524 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4525 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4526 struct ieee80211_channel
*notify_channel
= NULL
;
4527 struct ieee80211_supported_band
*band
;
4528 struct brcmf_bss_info_le
*bi
;
4529 struct brcmu_chan ch
;
4534 brcmf_dbg(TRACE
, "Enter\n");
4536 brcmf_get_assoc_ies(cfg
, ifp
);
4537 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4538 brcmf_update_bss_info(cfg
, ifp
);
4540 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4546 /* data sent to dongle has to be little endian */
4547 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4548 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4549 buf
, WL_BSS_INFO_MAX
);
4554 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4555 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
4556 cfg
->d11inf
.decchspec(&ch
);
4558 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
4559 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4561 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4563 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
4564 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4568 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4569 conn_info
->req_ie
, conn_info
->req_ie_len
,
4570 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4571 brcmf_dbg(CONN
, "Report roaming result\n");
4573 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4574 brcmf_dbg(TRACE
, "Exit\n");
4579 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4580 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4583 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4584 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4585 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4588 brcmf_dbg(TRACE
, "Enter\n");
4590 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4591 &ifp
->vif
->sme_state
)) {
4593 brcmf_get_assoc_ies(cfg
, ifp
);
4594 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4595 brcmf_update_bss_info(cfg
, ifp
);
4596 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4597 &ifp
->vif
->sme_state
);
4599 cfg80211_connect_result(ndev
,
4600 (u8
*)profile
->bssid
,
4602 conn_info
->req_ie_len
,
4604 conn_info
->resp_ie_len
,
4605 completed
? WLAN_STATUS_SUCCESS
:
4606 WLAN_STATUS_AUTH_TIMEOUT
,
4608 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4609 completed
? "succeeded" : "failed");
4611 brcmf_dbg(TRACE
, "Exit\n");
4616 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4617 struct net_device
*ndev
,
4618 const struct brcmf_event_msg
*e
, void *data
)
4620 static int generation
;
4621 u32 event
= e
->event_code
;
4622 u32 reason
= e
->reason
;
4623 struct station_info sinfo
;
4625 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4626 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
4627 ndev
!= cfg_to_ndev(cfg
)) {
4628 brcmf_dbg(CONN
, "AP mode link down\n");
4629 complete(&cfg
->vif_disabled
);
4633 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4634 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4635 memset(&sinfo
, 0, sizeof(sinfo
));
4636 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4638 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4641 sinfo
.assoc_req_ies
= data
;
4642 sinfo
.assoc_req_ies_len
= e
->datalen
;
4644 sinfo
.generation
= generation
;
4645 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4646 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4647 (event
== BRCMF_E_DEAUTH_IND
) ||
4648 (event
== BRCMF_E_DEAUTH
)) {
4649 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4655 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4656 const struct brcmf_event_msg
*e
, void *data
)
4658 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4659 struct net_device
*ndev
= ifp
->ndev
;
4660 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4663 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4664 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4665 } else if (brcmf_is_linkup(e
)) {
4666 brcmf_dbg(CONN
, "Linkup\n");
4667 if (brcmf_is_ibssmode(ifp
->vif
)) {
4668 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4669 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4670 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4671 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4672 &ifp
->vif
->sme_state
);
4673 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4674 &ifp
->vif
->sme_state
);
4676 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4677 } else if (brcmf_is_linkdown(e
)) {
4678 brcmf_dbg(CONN
, "Linkdown\n");
4679 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4680 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4681 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4682 &ifp
->vif
->sme_state
))
4683 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4686 brcmf_link_down(ifp
->vif
);
4687 brcmf_init_prof(ndev_to_prof(ndev
));
4688 if (ndev
!= cfg_to_ndev(cfg
))
4689 complete(&cfg
->vif_disabled
);
4690 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4691 if (brcmf_is_ibssmode(ifp
->vif
))
4692 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4693 &ifp
->vif
->sme_state
);
4695 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4702 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4703 const struct brcmf_event_msg
*e
, void *data
)
4705 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4707 u32 event
= e
->event_code
;
4708 u32 status
= e
->status
;
4710 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4711 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4712 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4714 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4721 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4722 const struct brcmf_event_msg
*e
, void *data
)
4724 u16 flags
= e
->flags
;
4725 enum nl80211_key_type key_type
;
4727 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4728 key_type
= NL80211_KEYTYPE_GROUP
;
4730 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4732 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4738 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4739 const struct brcmf_event_msg
*e
, void *data
)
4741 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4742 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4743 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4744 struct brcmf_cfg80211_vif
*vif
;
4746 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4747 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4750 mutex_lock(&event
->vif_event_lock
);
4751 event
->action
= ifevent
->action
;
4754 switch (ifevent
->action
) {
4755 case BRCMF_E_IF_ADD
:
4756 /* waiting process may have timed out */
4757 if (!cfg
->vif_event
.vif
) {
4758 mutex_unlock(&event
->vif_event_lock
);
4765 vif
->wdev
.netdev
= ifp
->ndev
;
4766 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4767 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4769 mutex_unlock(&event
->vif_event_lock
);
4770 wake_up(&event
->vif_wq
);
4773 case BRCMF_E_IF_DEL
:
4774 mutex_unlock(&event
->vif_event_lock
);
4775 /* event may not be upon user request */
4776 if (brcmf_cfg80211_vif_event_armed(cfg
))
4777 wake_up(&event
->vif_wq
);
4780 case BRCMF_E_IF_CHANGE
:
4781 mutex_unlock(&event
->vif_event_lock
);
4782 wake_up(&event
->vif_wq
);
4786 mutex_unlock(&event
->vif_event_lock
);
4792 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4794 conf
->frag_threshold
= (u32
)-1;
4795 conf
->rts_threshold
= (u32
)-1;
4796 conf
->retry_short
= (u32
)-1;
4797 conf
->retry_long
= (u32
)-1;
4798 conf
->tx_power
= -1;
4801 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4803 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4804 brcmf_notify_connect_status
);
4805 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4806 brcmf_notify_connect_status
);
4807 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4808 brcmf_notify_connect_status
);
4809 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4810 brcmf_notify_connect_status
);
4811 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4812 brcmf_notify_connect_status
);
4813 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4814 brcmf_notify_connect_status
);
4815 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4816 brcmf_notify_roaming_status
);
4817 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4818 brcmf_notify_mic_status
);
4819 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4820 brcmf_notify_connect_status
);
4821 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4822 brcmf_notify_sched_scan_results
);
4823 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4824 brcmf_notify_vif_event
);
4825 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
4826 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
4827 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
4828 brcmf_p2p_notify_listen_complete
);
4829 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
4830 brcmf_p2p_notify_action_frame_rx
);
4831 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
4832 brcmf_p2p_notify_action_tx_complete
);
4833 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
4834 brcmf_p2p_notify_action_tx_complete
);
4837 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4841 kfree(cfg
->escan_ioctl_buf
);
4842 cfg
->escan_ioctl_buf
= NULL
;
4843 kfree(cfg
->extra_buf
);
4844 cfg
->extra_buf
= NULL
;
4845 kfree(cfg
->pmk_list
);
4846 cfg
->pmk_list
= NULL
;
4849 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4851 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4853 goto init_priv_mem_out
;
4854 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4855 if (!cfg
->escan_ioctl_buf
)
4856 goto init_priv_mem_out
;
4857 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4858 if (!cfg
->extra_buf
)
4859 goto init_priv_mem_out
;
4860 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4862 goto init_priv_mem_out
;
4867 brcmf_deinit_priv_mem(cfg
);
4872 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4876 cfg
->scan_request
= NULL
;
4877 cfg
->pwr_save
= true;
4878 cfg
->roam_on
= true; /* roam on & off switch.
4879 we enable roam per default */
4880 cfg
->active_scan
= true; /* we do active scan for
4881 specific scan per default */
4882 cfg
->dongle_up
= false; /* dongle is not up yet */
4883 err
= brcmf_init_priv_mem(cfg
);
4886 brcmf_register_event_handlers(cfg
);
4887 mutex_init(&cfg
->usr_sync
);
4888 brcmf_init_escan(cfg
);
4889 brcmf_init_conf(cfg
->conf
);
4890 init_completion(&cfg
->vif_disabled
);
4894 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4896 cfg
->dongle_up
= false; /* dongle down */
4897 brcmf_abort_scanning(cfg
);
4898 brcmf_deinit_priv_mem(cfg
);
4901 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4903 init_waitqueue_head(&event
->vif_wq
);
4904 mutex_init(&event
->vif_event_lock
);
4907 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4908 struct device
*busdev
)
4910 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4911 struct brcmf_cfg80211_info
*cfg
;
4912 struct wiphy
*wiphy
;
4913 struct brcmf_cfg80211_vif
*vif
;
4914 struct brcmf_if
*ifp
;
4919 brcmf_err("ndev is invalid\n");
4923 ifp
= netdev_priv(ndev
);
4924 wiphy
= brcmf_setup_wiphy(busdev
);
4928 cfg
= wiphy_priv(wiphy
);
4931 init_vif_event(&cfg
->vif_event
);
4932 INIT_LIST_HEAD(&cfg
->vif_list
);
4934 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4941 vif
->wdev
.netdev
= ndev
;
4942 ndev
->ieee80211_ptr
= &vif
->wdev
;
4943 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4945 err
= wl_init_priv(cfg
);
4947 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4948 goto cfg80211_attach_out
;
4952 err
= brcmf_p2p_attach(cfg
);
4954 brcmf_err("P2P initilisation failed (%d)\n", err
);
4955 goto cfg80211_p2p_attach_out
;
4957 err
= brcmf_btcoex_attach(cfg
);
4959 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
4960 brcmf_p2p_detach(&cfg
->p2p
);
4961 goto cfg80211_p2p_attach_out
;
4964 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
4966 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
4967 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
4970 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
,
4973 brcmf_err("Failed to get D11 version (%d)\n", err
);
4974 goto cfg80211_p2p_attach_out
;
4976 cfg
->d11inf
.io_type
= (u8
)io_type
;
4977 brcmu_d11_attach(&cfg
->d11inf
);
4981 cfg80211_p2p_attach_out
:
4982 wl_deinit_priv(cfg
);
4984 cfg80211_attach_out
:
4985 brcmf_free_vif(vif
);
4989 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4994 WARN_ON(!list_empty(&cfg
->vif_list
));
4995 wiphy_unregister(cfg
->wiphy
);
4996 brcmf_btcoex_detach(cfg
);
4997 wl_deinit_priv(cfg
);
4998 wiphy_free(cfg
->wiphy
);
5002 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
5005 __le32 roamtrigger
[2];
5006 __le32 roam_delta
[2];
5009 * Setup timeout if Beacons are lost and roam is
5010 * off to report link down
5013 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5015 brcmf_err("bcn_timeout error (%d)\n", err
);
5016 goto dongle_rom_out
;
5021 * Enable/Disable built-in roaming to allow supplicant
5022 * to take care of roaming
5024 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
5025 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
5027 brcmf_err("roam_off error (%d)\n", err
);
5028 goto dongle_rom_out
;
5031 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5032 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5033 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5034 (void *)roamtrigger
, sizeof(roamtrigger
));
5036 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5037 goto dongle_rom_out
;
5040 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5041 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5042 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5043 (void *)roam_delta
, sizeof(roam_delta
));
5045 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5046 goto dongle_rom_out
;
5054 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
5055 s32 scan_unassoc_time
, s32 scan_passive_time
)
5059 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5062 if (err
== -EOPNOTSUPP
)
5063 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
5065 brcmf_err("Scan assoc time error (%d)\n", err
);
5066 goto dongle_scantime_out
;
5068 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5071 if (err
== -EOPNOTSUPP
)
5072 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
5074 brcmf_err("Scan unassoc time error (%d)\n", err
);
5075 goto dongle_scantime_out
;
5078 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5081 if (err
== -EOPNOTSUPP
)
5082 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
5084 brcmf_err("Scan passive time error (%d)\n", err
);
5085 goto dongle_scantime_out
;
5088 dongle_scantime_out
:
5093 static s32
brcmf_construct_reginfo(struct brcmf_cfg80211_info
*cfg
,
5096 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5097 struct ieee80211_channel
*band_chan_arr
;
5098 struct brcmf_chanspec_list
*list
;
5099 struct brcmu_chan ch
;
5104 enum ieee80211_band band
;
5112 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5117 list
= (struct brcmf_chanspec_list
*)pbuf
;
5119 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5122 brcmf_err("get chanspecs error (%d)\n", err
);
5126 __wl_band_2ghz
.n_channels
= 0;
5127 __wl_band_5ghz_a
.n_channels
= 0;
5129 total
= le32_to_cpu(list
->count
);
5130 for (i
= 0; i
< total
; i
++) {
5131 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5132 cfg
->d11inf
.decchspec(&ch
);
5134 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5135 band_chan_arr
= __wl_2ghz_channels
;
5136 array_size
= ARRAY_SIZE(__wl_2ghz_channels
);
5137 n_cnt
= &__wl_band_2ghz
.n_channels
;
5138 band
= IEEE80211_BAND_2GHZ
;
5139 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5140 band_chan_arr
= __wl_5ghz_a_channels
;
5141 array_size
= ARRAY_SIZE(__wl_5ghz_a_channels
);
5142 n_cnt
= &__wl_band_5ghz_a
.n_channels
;
5143 band
= IEEE80211_BAND_5GHZ
;
5145 brcmf_err("Invalid channel Spec. 0x%x.\n", ch
.chspec
);
5148 if (!(bw_cap
[band
] & WLC_BW_40MHZ_BIT
) &&
5149 ch
.bw
== BRCMU_CHAN_BW_40
)
5152 for (j
= 0; (j
< *n_cnt
&& (*n_cnt
< array_size
)); j
++) {
5153 if (band_chan_arr
[j
].hw_value
== ch
.chnum
) {
5162 if (index
< array_size
) {
5163 band_chan_arr
[index
].center_freq
=
5164 ieee80211_channel_to_frequency(ch
.chnum
, band
);
5165 band_chan_arr
[index
].hw_value
= ch
.chnum
;
5167 brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5168 ch
.chnum
, band_chan_arr
[index
].center_freq
,
5170 if (ch
.bw
== BRCMU_CHAN_BW_40
) {
5171 /* assuming the order is HT20, HT40 Upper,
5172 * HT40 lower from chanspecs
5174 ht40_flag
= band_chan_arr
[index
].flags
&
5175 IEEE80211_CHAN_NO_HT40
;
5176 if (ch
.sb
== BRCMU_CHAN_SB_U
) {
5177 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5178 band_chan_arr
[index
].flags
&=
5179 ~IEEE80211_CHAN_NO_HT40
;
5180 band_chan_arr
[index
].flags
|=
5181 IEEE80211_CHAN_NO_HT40PLUS
;
5183 /* It should be one of
5184 * IEEE80211_CHAN_NO_HT40 or
5185 * IEEE80211_CHAN_NO_HT40PLUS
5187 band_chan_arr
[index
].flags
&=
5188 ~IEEE80211_CHAN_NO_HT40
;
5189 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5190 band_chan_arr
[index
].flags
|=
5191 IEEE80211_CHAN_NO_HT40MINUS
;
5194 band_chan_arr
[index
].flags
=
5195 IEEE80211_CHAN_NO_HT40
;
5196 ch
.bw
= BRCMU_CHAN_BW_20
;
5197 cfg
->d11inf
.encchspec(&ch
);
5198 channel
= ch
.chspec
;
5199 err
= brcmf_fil_bsscfg_int_get(ifp
,
5203 if (channel
& WL_CHAN_RADAR
)
5204 band_chan_arr
[index
].flags
|=
5205 (IEEE80211_CHAN_RADAR
|
5206 IEEE80211_CHAN_NO_IR
);
5207 if (channel
& WL_CHAN_PASSIVE
)
5208 band_chan_arr
[index
].flags
|=
5209 IEEE80211_CHAN_NO_IR
;
5221 static void brcmf_get_bwcap(struct brcmf_if
*ifp
, u32 bw_cap
[])
5223 u32 band
, mimo_bwcap
;
5227 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5229 bw_cap
[IEEE80211_BAND_2GHZ
] = band
;
5231 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5233 bw_cap
[IEEE80211_BAND_5GHZ
] = band
;
5239 brcmf_dbg(INFO
, "fallback to mimo_bw_cap info\n");
5241 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &mimo_bwcap
);
5243 /* assume 20MHz if firmware does not give a clue */
5244 mimo_bwcap
= WLC_N_BW_20ALL
;
5246 switch (mimo_bwcap
) {
5247 case WLC_N_BW_40ALL
:
5248 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_40MHZ_BIT
;
5250 case WLC_N_BW_20IN2G_40IN5G
:
5251 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_40MHZ_BIT
;
5253 case WLC_N_BW_20ALL
:
5254 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_20MHZ_BIT
;
5255 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_20MHZ_BIT
;
5258 brcmf_err("invalid mimo_bw_cap value\n");
5262 static s32
brcmf_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
5264 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5265 struct wiphy
*wiphy
;
5269 u32 bw_cap
[2] = { 0, 0 };
5274 struct ieee80211_supported_band
*bands
[2] = { NULL
, NULL
};
5275 struct ieee80211_supported_band
*band
;
5277 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
5278 &phy_list
, sizeof(phy_list
));
5280 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err
);
5284 phy
= ((char *)&phy_list
)[0];
5285 brcmf_dbg(INFO
, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy
);
5288 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
,
5289 &band_list
, sizeof(band_list
));
5291 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err
);
5294 brcmf_dbg(INFO
, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5295 band_list
[0], band_list
[1], band_list
[2]);
5297 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
5299 brcmf_err("nmode error (%d)\n", err
);
5301 brcmf_get_bwcap(ifp
, bw_cap
);
5303 brcmf_dbg(INFO
, "nmode=%d, bw_cap=(%d, %d)\n", nmode
,
5304 bw_cap
[IEEE80211_BAND_2GHZ
], bw_cap
[IEEE80211_BAND_5GHZ
]);
5306 err
= brcmf_construct_reginfo(cfg
, bw_cap
);
5308 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err
);
5312 nband
= band_list
[0];
5314 for (i
= 1; i
<= nband
&& i
< ARRAY_SIZE(band_list
); i
++) {
5316 if ((band_list
[i
] == WLC_BAND_5G
) &&
5317 (__wl_band_5ghz_a
.n_channels
> 0))
5318 band
= &__wl_band_5ghz_a
;
5319 else if ((band_list
[i
] == WLC_BAND_2G
) &&
5320 (__wl_band_2ghz
.n_channels
> 0))
5321 band
= &__wl_band_2ghz
;
5325 if (bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) {
5326 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_40
;
5327 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
5329 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5330 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5331 band
->ht_cap
.ht_supported
= true;
5332 band
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5333 band
->ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5334 /* An HT shall support all EQM rates for one spatial
5337 band
->ht_cap
.mcs
.rx_mask
[0] = 0xff;
5338 band
->ht_cap
.mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
5339 bands
[band
->band
] = band
;
5342 wiphy
= cfg_to_wiphy(cfg
);
5343 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = bands
[IEEE80211_BAND_2GHZ
];
5344 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = bands
[IEEE80211_BAND_5GHZ
];
5345 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
5351 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5353 return brcmf_update_wiphybands(cfg
);
5356 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5358 struct net_device
*ndev
;
5359 struct wireless_dev
*wdev
;
5360 struct brcmf_if
*ifp
;
5367 ndev
= cfg_to_ndev(cfg
);
5368 wdev
= ndev
->ieee80211_ptr
;
5369 ifp
= netdev_priv(ndev
);
5371 /* make sure RF is ready for work */
5372 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
5374 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
5375 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5377 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5378 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
5380 goto default_conf_out
;
5381 brcmf_dbg(INFO
, "power save set to %s\n",
5382 (power_mode
? "enabled" : "disabled"));
5384 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
5386 goto default_conf_out
;
5387 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5390 goto default_conf_out
;
5391 err
= brcmf_dongle_probecap(cfg
);
5393 goto default_conf_out
;
5395 brcmf_configure_arp_offload(ifp
, true);
5397 cfg
->dongle_up
= true;
5404 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
5406 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5408 return brcmf_config_dongle(ifp
->drvr
->config
);
5411 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
5413 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5416 * While going down, if associated with AP disassociate
5417 * from AP to save power
5419 if (check_vif_up(ifp
->vif
)) {
5420 brcmf_link_down(ifp
->vif
);
5422 /* Make sure WPA_Supplicant receives all the event
5423 generated due to DISASSOC call to the fw to keep
5424 the state fw and WPA_Supplicant state consistent
5429 brcmf_abort_scanning(cfg
);
5430 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5435 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
5437 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5438 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5441 mutex_lock(&cfg
->usr_sync
);
5442 err
= __brcmf_cfg80211_up(ifp
);
5443 mutex_unlock(&cfg
->usr_sync
);
5448 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
5450 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5451 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5454 mutex_lock(&cfg
->usr_sync
);
5455 err
= __brcmf_cfg80211_down(ifp
);
5456 mutex_unlock(&cfg
->usr_sync
);
5461 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
5463 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
5465 return wdev
->iftype
;
5468 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
5470 struct brcmf_cfg80211_vif
*vif
;
5473 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
5474 if (test_bit(state
, &vif
->sme_state
))
5480 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
5485 mutex_lock(&event
->vif_event_lock
);
5486 evt_action
= event
->action
;
5487 mutex_unlock(&event
->vif_event_lock
);
5488 return evt_action
== action
;
5491 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
5492 struct brcmf_cfg80211_vif
*vif
)
5494 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5496 mutex_lock(&event
->vif_event_lock
);
5499 mutex_unlock(&event
->vif_event_lock
);
5502 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
5504 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5507 mutex_lock(&event
->vif_event_lock
);
5508 armed
= event
->vif
!= NULL
;
5509 mutex_unlock(&event
->vif_event_lock
);
5513 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
5514 u8 action
, ulong timeout
)
5516 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5518 return wait_event_timeout(event
->vif_wq
,
5519 vif_event_equals(event
, action
), timeout
);