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_PASSIVE_SCAN and NL80211_RRF_NO_IBSS for 5GHz channels (for
206 * 36..48 and 149..165). With respect to these flags, wpa_supplicant doesn't
207 * start p2p 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
);
1098 cfg80211_disconnected(vif
->wdev
.netdev
, 0,
1099 NULL
, 0, GFP_KERNEL
);
1101 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
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
);
1762 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1763 scbval
.val
= cpu_to_le32(reason_code
);
1764 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1765 &scbval
, sizeof(scbval
));
1767 brcmf_err("error (%d)\n", err
);
1769 brcmf_dbg(TRACE
, "Exit\n");
1774 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1775 enum nl80211_tx_power_setting type
, s32 mbm
)
1778 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1779 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1780 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1784 s32 dbm
= MBM_TO_DBM(mbm
);
1786 brcmf_dbg(TRACE
, "Enter\n");
1787 if (!check_vif_up(ifp
->vif
))
1791 case NL80211_TX_POWER_AUTOMATIC
:
1793 case NL80211_TX_POWER_LIMITED
:
1794 case NL80211_TX_POWER_FIXED
:
1796 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1802 /* Make sure radio is off or on as far as software is concerned */
1803 disable
= WL_RADIO_SW_DISABLE
<< 16;
1804 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1806 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1811 txpwrmw
= (u16
) dbm
;
1812 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1813 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1815 brcmf_err("qtxpower error (%d)\n", err
);
1816 cfg
->conf
->tx_power
= dbm
;
1819 brcmf_dbg(TRACE
, "Exit\n");
1823 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1824 struct wireless_dev
*wdev
,
1827 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1828 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1833 brcmf_dbg(TRACE
, "Enter\n");
1834 if (!check_vif_up(ifp
->vif
))
1837 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1839 brcmf_err("error (%d)\n", err
);
1843 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1844 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1847 brcmf_dbg(TRACE
, "Exit\n");
1852 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1853 u8 key_idx
, bool unicast
, bool multicast
)
1855 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1860 brcmf_dbg(TRACE
, "Enter\n");
1861 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1862 if (!check_vif_up(ifp
->vif
))
1865 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1867 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1871 if (wsec
& WEP_ENABLED
) {
1872 /* Just select a new current key */
1874 err
= brcmf_fil_cmd_int_set(ifp
,
1875 BRCMF_C_SET_KEY_PRIMARY
, index
);
1877 brcmf_err("error (%d)\n", err
);
1880 brcmf_dbg(TRACE
, "Exit\n");
1885 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1886 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1888 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1889 struct brcmf_wsec_key key
;
1893 memset(&key
, 0, sizeof(key
));
1894 key
.index
= (u32
) key_idx
;
1895 /* Instead of bcast for ea address for default wep keys,
1896 driver needs it to be Null */
1897 if (!is_multicast_ether_addr(mac_addr
))
1898 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1899 key
.len
= (u32
) params
->key_len
;
1900 /* check for key index change */
1903 err
= send_key_to_dongle(ndev
, &key
);
1905 brcmf_err("key delete error (%d)\n", err
);
1907 if (key
.len
> sizeof(key
.data
)) {
1908 brcmf_err("Invalid key length (%d)\n", key
.len
);
1912 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1913 memcpy(key
.data
, params
->key
, key
.len
);
1915 if ((ifp
->vif
->mode
!= WL_MODE_AP
) &&
1916 (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)) {
1917 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
1918 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1919 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1920 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1923 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1924 if (params
->seq
&& params
->seq_len
== 6) {
1927 ivptr
= (u8
*) params
->seq
;
1928 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1929 (ivptr
[3] << 8) | ivptr
[2];
1930 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1931 key
.iv_initialized
= true;
1934 switch (params
->cipher
) {
1935 case WLAN_CIPHER_SUITE_WEP40
:
1936 key
.algo
= CRYPTO_ALGO_WEP1
;
1937 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1939 case WLAN_CIPHER_SUITE_WEP104
:
1940 key
.algo
= CRYPTO_ALGO_WEP128
;
1941 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1943 case WLAN_CIPHER_SUITE_TKIP
:
1944 key
.algo
= CRYPTO_ALGO_TKIP
;
1945 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1947 case WLAN_CIPHER_SUITE_AES_CMAC
:
1948 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1949 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1951 case WLAN_CIPHER_SUITE_CCMP
:
1952 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1953 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1956 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1959 err
= send_key_to_dongle(ndev
, &key
);
1961 brcmf_err("wsec_key error (%d)\n", err
);
1967 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1968 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1969 struct key_params
*params
)
1971 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1972 struct brcmf_wsec_key key
;
1978 brcmf_dbg(TRACE
, "Enter\n");
1979 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1980 if (!check_vif_up(ifp
->vif
))
1984 brcmf_dbg(TRACE
, "Exit");
1985 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
1987 memset(&key
, 0, sizeof(key
));
1989 key
.len
= (u32
) params
->key_len
;
1990 key
.index
= (u32
) key_idx
;
1992 if (key
.len
> sizeof(key
.data
)) {
1993 brcmf_err("Too long key length (%u)\n", key
.len
);
1997 memcpy(key
.data
, params
->key
, key
.len
);
1999 key
.flags
= BRCMF_PRIMARY_KEY
;
2000 switch (params
->cipher
) {
2001 case WLAN_CIPHER_SUITE_WEP40
:
2002 key
.algo
= CRYPTO_ALGO_WEP1
;
2004 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2006 case WLAN_CIPHER_SUITE_WEP104
:
2007 key
.algo
= CRYPTO_ALGO_WEP128
;
2009 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2011 case WLAN_CIPHER_SUITE_TKIP
:
2012 if (ifp
->vif
->mode
!= WL_MODE_AP
) {
2013 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2014 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2015 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2016 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2018 key
.algo
= CRYPTO_ALGO_TKIP
;
2020 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2022 case WLAN_CIPHER_SUITE_AES_CMAC
:
2023 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2025 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2027 case WLAN_CIPHER_SUITE_CCMP
:
2028 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2030 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2033 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2038 err
= send_key_to_dongle(ndev
, &key
);
2042 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2044 brcmf_err("get wsec error (%d)\n", err
);
2048 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2050 brcmf_err("set wsec error (%d)\n", err
);
2055 brcmf_dbg(TRACE
, "Exit\n");
2060 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2061 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2063 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2064 struct brcmf_wsec_key key
;
2067 brcmf_dbg(TRACE
, "Enter\n");
2068 if (!check_vif_up(ifp
->vif
))
2071 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
2072 /* we ignore this key index in this case */
2073 brcmf_err("invalid key index (%d)\n", key_idx
);
2077 memset(&key
, 0, sizeof(key
));
2079 key
.index
= (u32
) key_idx
;
2080 key
.flags
= BRCMF_PRIMARY_KEY
;
2081 key
.algo
= CRYPTO_ALGO_OFF
;
2083 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2085 /* Set the new key/index */
2086 err
= send_key_to_dongle(ndev
, &key
);
2088 brcmf_dbg(TRACE
, "Exit\n");
2093 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2094 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2095 void (*callback
) (void *cookie
, struct key_params
* params
))
2097 struct key_params params
;
2098 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2099 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2100 struct brcmf_cfg80211_security
*sec
;
2104 brcmf_dbg(TRACE
, "Enter\n");
2105 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2106 if (!check_vif_up(ifp
->vif
))
2109 memset(¶ms
, 0, sizeof(params
));
2111 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2113 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2114 /* Ignore this error, may happen during DISASSOC */
2118 if (wsec
& WEP_ENABLED
) {
2119 sec
= &profile
->sec
;
2120 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2121 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2122 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2123 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2124 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2125 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2127 } else if (wsec
& TKIP_ENABLED
) {
2128 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2129 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2130 } else if (wsec
& AES_ENABLED
) {
2131 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2132 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2134 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2138 callback(cookie
, ¶ms
);
2141 brcmf_dbg(TRACE
, "Exit\n");
2146 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2147 struct net_device
*ndev
, u8 key_idx
)
2149 brcmf_dbg(INFO
, "Not supported\n");
2155 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2156 u8
*mac
, struct station_info
*sinfo
)
2158 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2159 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2160 struct brcmf_scb_val_le scb_val
;
2164 u8
*bssid
= profile
->bssid
;
2165 struct brcmf_sta_info_le sta_info_le
;
2167 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2168 if (!check_vif_up(ifp
->vif
))
2171 if (ifp
->vif
->mode
== WL_MODE_AP
) {
2172 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2173 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2175 sizeof(sta_info_le
));
2177 brcmf_err("GET STA INFO failed, %d\n", err
);
2180 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2181 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2182 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2183 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2184 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2186 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
2187 sinfo
->inactive_time
, sinfo
->connected_time
);
2188 } else if (ifp
->vif
->mode
== WL_MODE_BSS
) {
2189 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2190 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2195 /* Report the current tx rate */
2196 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2198 brcmf_err("Could not get rate (%d)\n", err
);
2201 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2202 sinfo
->txrate
.legacy
= rate
* 5;
2203 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
2206 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2207 &ifp
->vif
->sme_state
)) {
2208 memset(&scb_val
, 0, sizeof(scb_val
));
2209 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2210 &scb_val
, sizeof(scb_val
));
2212 brcmf_err("Could not get rssi (%d)\n", err
);
2215 rssi
= le32_to_cpu(scb_val
.val
);
2216 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2217 sinfo
->signal
= rssi
;
2218 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2224 brcmf_dbg(TRACE
, "Exit\n");
2229 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2230 bool enabled
, s32 timeout
)
2234 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2235 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2237 brcmf_dbg(TRACE
, "Enter\n");
2240 * Powersave enable/disable request is coming from the
2241 * cfg80211 even before the interface is up. In that
2242 * scenario, driver will be storing the power save
2243 * preference in cfg struct to apply this to
2244 * FW later while initializing the dongle
2246 cfg
->pwr_save
= enabled
;
2247 if (!check_vif_up(ifp
->vif
)) {
2249 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2253 pm
= enabled
? PM_FAST
: PM_OFF
;
2254 /* Do not enable the power save after assoc if it is a p2p interface */
2255 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2256 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2259 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2261 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2264 brcmf_err("net_device is not ready yet\n");
2266 brcmf_err("error (%d)\n", err
);
2269 brcmf_dbg(TRACE
, "Exit\n");
2273 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2274 struct brcmf_bss_info_le
*bi
)
2276 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2277 struct ieee80211_channel
*notify_channel
;
2278 struct cfg80211_bss
*bss
;
2279 struct ieee80211_supported_band
*band
;
2280 struct brcmu_chan ch
;
2284 u16 notify_capability
;
2285 u16 notify_interval
;
2287 size_t notify_ielen
;
2290 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2291 brcmf_err("Bss info is larger than buffer. Discarding\n");
2296 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2297 cfg
->d11inf
.decchspec(&ch
);
2298 bi
->ctl_ch
= ch
.chnum
;
2300 channel
= bi
->ctl_ch
;
2302 if (channel
<= CH_MAX_2G_CHANNEL
)
2303 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2305 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2307 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2308 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2310 notify_capability
= le16_to_cpu(bi
->capability
);
2311 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2312 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2313 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2314 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2316 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2317 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2318 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2319 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2320 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2322 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2323 0, notify_capability
, notify_interval
, notify_ie
,
2324 notify_ielen
, notify_signal
, GFP_KERNEL
);
2329 cfg80211_put_bss(wiphy
, bss
);
2334 static struct brcmf_bss_info_le
*
2335 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2338 return list
->bss_info_le
;
2339 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2340 le32_to_cpu(bss
->length
));
2343 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2345 struct brcmf_scan_results
*bss_list
;
2346 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2350 bss_list
= cfg
->bss_list
;
2351 if (bss_list
->count
!= 0 &&
2352 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2353 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2357 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2358 for (i
= 0; i
< bss_list
->count
; i
++) {
2359 bi
= next_bss_le(bss_list
, bi
);
2360 err
= brcmf_inform_single_bss(cfg
, bi
);
2367 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2368 struct net_device
*ndev
, const u8
*bssid
)
2370 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2371 struct ieee80211_channel
*notify_channel
;
2372 struct brcmf_bss_info_le
*bi
= NULL
;
2373 struct ieee80211_supported_band
*band
;
2374 struct cfg80211_bss
*bss
;
2375 struct brcmu_chan ch
;
2379 u16 notify_capability
;
2380 u16 notify_interval
;
2382 size_t notify_ielen
;
2385 brcmf_dbg(TRACE
, "Enter\n");
2387 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2393 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2395 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2396 buf
, WL_BSS_INFO_MAX
);
2398 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2402 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2404 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2405 cfg
->d11inf
.decchspec(&ch
);
2407 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2408 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2410 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2412 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2413 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2415 notify_capability
= le16_to_cpu(bi
->capability
);
2416 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2417 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2418 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2419 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2421 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2422 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2423 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2424 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2426 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2427 0, notify_capability
, notify_interval
,
2428 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2435 cfg80211_put_bss(wiphy
, bss
);
2441 brcmf_dbg(TRACE
, "Exit\n");
2446 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
2448 return vif
->mode
== WL_MODE_IBSS
;
2451 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2452 struct brcmf_if
*ifp
)
2454 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ifp
->ndev
);
2455 struct brcmf_bss_info_le
*bi
;
2456 struct brcmf_ssid
*ssid
;
2457 struct brcmf_tlv
*tim
;
2458 u16 beacon_interval
;
2464 brcmf_dbg(TRACE
, "Enter\n");
2465 if (brcmf_is_ibssmode(ifp
->vif
))
2468 ssid
= &profile
->ssid
;
2470 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2471 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2472 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2474 brcmf_err("Could not get bss info %d\n", err
);
2475 goto update_bss_info_out
;
2478 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2479 err
= brcmf_inform_single_bss(cfg
, bi
);
2481 goto update_bss_info_out
;
2483 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2484 ie_len
= le32_to_cpu(bi
->ie_length
);
2485 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2487 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2489 dtim_period
= tim
->data
[1];
2492 * active scan was done so we could not get dtim
2493 * information out of probe response.
2494 * so we speficially query dtim information to dongle.
2497 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2499 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2500 goto update_bss_info_out
;
2502 dtim_period
= (u8
)var
;
2505 update_bss_info_out
:
2506 brcmf_dbg(TRACE
, "Exit");
2510 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2512 struct escan_info
*escan
= &cfg
->escan_info
;
2514 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2515 if (cfg
->scan_request
) {
2516 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2517 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2519 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2520 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2523 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2525 struct brcmf_cfg80211_info
*cfg
=
2526 container_of(work
, struct brcmf_cfg80211_info
,
2527 escan_timeout_work
);
2529 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2532 static void brcmf_escan_timeout(unsigned long data
)
2534 struct brcmf_cfg80211_info
*cfg
=
2535 (struct brcmf_cfg80211_info
*)data
;
2537 if (cfg
->scan_request
) {
2538 brcmf_err("timer expired\n");
2539 schedule_work(&cfg
->escan_timeout_work
);
2544 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2545 struct brcmf_bss_info_le
*bss
,
2546 struct brcmf_bss_info_le
*bss_info_le
)
2548 struct brcmu_chan ch_bss
, ch_bss_info_le
;
2550 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
2551 cfg
->d11inf
.decchspec(&ch_bss
);
2552 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
2553 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
2555 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2556 ch_bss
.band
== ch_bss_info_le
.band
&&
2557 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2558 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2559 if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) ==
2560 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
)) {
2561 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2562 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2564 /* preserve max RSSI if the measurements are
2565 * both on-channel or both off-channel
2567 if (bss_info_rssi
> bss_rssi
)
2568 bss
->RSSI
= bss_info_le
->RSSI
;
2569 } else if ((bss
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) &&
2570 (bss_info_le
->flags
& WLC_BSS_RSSI_ON_CHANNEL
) == 0) {
2571 /* preserve the on-channel rssi measurement
2572 * if the new measurement is off channel
2574 bss
->RSSI
= bss_info_le
->RSSI
;
2575 bss
->flags
|= WLC_BSS_RSSI_ON_CHANNEL
;
2583 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2584 const struct brcmf_event_msg
*e
, void *data
)
2586 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2589 struct brcmf_escan_result_le
*escan_result_le
;
2590 struct brcmf_bss_info_le
*bss_info_le
;
2591 struct brcmf_bss_info_le
*bss
= NULL
;
2593 struct brcmf_scan_results
*list
;
2599 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2600 brcmf_err("scan not ready, bssidx=%d\n", ifp
->bssidx
);
2604 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2605 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2606 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2607 if (!escan_result_le
) {
2608 brcmf_err("Invalid escan result (NULL pointer)\n");
2611 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2612 brcmf_err("Invalid bss_count %d: ignoring\n",
2613 escan_result_le
->bss_count
);
2616 bss_info_le
= &escan_result_le
->bss_info_le
;
2618 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
2621 if (!cfg
->scan_request
) {
2622 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2626 bi_length
= le32_to_cpu(bss_info_le
->length
);
2627 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2628 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2629 brcmf_err("Invalid bss_info length %d: ignoring\n",
2634 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2635 BIT(NL80211_IFTYPE_ADHOC
))) {
2636 if (le16_to_cpu(bss_info_le
->capability
) &
2637 WLAN_CAPABILITY_IBSS
) {
2638 brcmf_err("Ignoring IBSS result\n");
2643 list
= (struct brcmf_scan_results
*)
2644 cfg
->escan_info
.escan_buf
;
2645 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2646 brcmf_err("Buffer is too small: ignoring\n");
2650 for (i
= 0; i
< list
->count
; i
++) {
2651 bss
= bss
? (struct brcmf_bss_info_le
*)
2652 ((unsigned char *)bss
+
2653 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2654 if (brcmf_compare_update_same_bss(cfg
, bss
,
2658 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2659 bss_info_le
, bi_length
);
2660 list
->version
= le32_to_cpu(bss_info_le
->version
);
2661 list
->buflen
+= bi_length
;
2664 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2665 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
2667 if (cfg
->scan_request
) {
2668 cfg
->bss_list
= (struct brcmf_scan_results
*)
2669 cfg
->escan_info
.escan_buf
;
2670 brcmf_inform_bss(cfg
);
2671 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2672 brcmf_notify_escan_complete(cfg
, ifp
, aborted
,
2675 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
2682 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2684 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2685 brcmf_cfg80211_escan_handler
);
2686 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2687 /* Init scan_timeout timer */
2688 init_timer(&cfg
->escan_timeout
);
2689 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2690 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2691 INIT_WORK(&cfg
->escan_timeout_work
,
2692 brcmf_cfg80211_escan_timeout_worker
);
2695 static __always_inline
void brcmf_delay(u32 ms
)
2697 if (ms
< 1000 / HZ
) {
2705 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2707 brcmf_dbg(TRACE
, "Enter\n");
2712 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2713 struct cfg80211_wowlan
*wow
)
2715 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2716 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2717 struct brcmf_cfg80211_vif
*vif
;
2719 brcmf_dbg(TRACE
, "Enter\n");
2722 * if the primary net_device is not READY there is nothing
2723 * we can do but pray resume goes smoothly.
2725 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2726 if (!check_vif_up(vif
))
2729 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2730 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2733 * While going to suspend if associated with AP disassociate
2734 * from AP to save power while system is in suspended state
2736 brcmf_link_down(vif
);
2738 /* Make sure WPA_Supplicant receives all the event
2739 * generated due to DISASSOC call to the fw to keep
2740 * the state fw and WPA_Supplicant state consistent
2745 /* end any scanning */
2746 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2747 brcmf_abort_scanning(cfg
);
2749 /* Turn off watchdog timer */
2750 brcmf_set_mpc(netdev_priv(ndev
), 1);
2753 brcmf_dbg(TRACE
, "Exit\n");
2754 /* clear any scanning activity */
2755 cfg
->scan_status
= 0;
2760 brcmf_update_pmklist(struct net_device
*ndev
,
2761 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2766 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2768 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2769 for (i
= 0; i
< pmkid_len
; i
++) {
2770 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2771 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2772 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2773 brcmf_dbg(CONN
, "%02x\n",
2774 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2778 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2779 (char *)pmk_list
, sizeof(*pmk_list
));
2785 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2786 struct cfg80211_pmksa
*pmksa
)
2788 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2789 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2790 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2795 brcmf_dbg(TRACE
, "Enter\n");
2796 if (!check_vif_up(ifp
->vif
))
2799 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2800 for (i
= 0; i
< pmkid_len
; i
++)
2801 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2803 if (i
< WL_NUM_PMKIDS_MAX
) {
2804 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2805 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2806 if (i
== pmkid_len
) {
2808 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2813 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2814 pmkids
->pmkid
[pmkid_len
].BSSID
);
2815 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2816 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2818 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2820 brcmf_dbg(TRACE
, "Exit\n");
2825 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2826 struct cfg80211_pmksa
*pmksa
)
2828 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2829 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2830 struct pmkid_list pmkid
;
2834 brcmf_dbg(TRACE
, "Enter\n");
2835 if (!check_vif_up(ifp
->vif
))
2838 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2839 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2841 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2842 &pmkid
.pmkid
[0].BSSID
);
2843 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2844 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2846 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2847 for (i
= 0; i
< pmkid_len
; i
++)
2849 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2854 && (i
< pmkid_len
)) {
2855 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2856 sizeof(struct pmkid
));
2857 for (; i
< (pmkid_len
- 1); i
++) {
2858 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2859 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2861 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2862 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2865 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2869 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2871 brcmf_dbg(TRACE
, "Exit\n");
2877 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2879 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2880 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2883 brcmf_dbg(TRACE
, "Enter\n");
2884 if (!check_vif_up(ifp
->vif
))
2887 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2888 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2890 brcmf_dbg(TRACE
, "Exit\n");
2896 * PFN result doesn't have all the info which are
2897 * required by the supplicant
2898 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2899 * via wl_inform_single_bss in the required format. Escan does require the
2900 * scan request in the form of cfg80211_scan_request. For timebeing, create
2901 * cfg80211_scan_request one out of the received PNO event.
2904 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2905 const struct brcmf_event_msg
*e
, void *data
)
2907 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2908 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2909 struct cfg80211_scan_request
*request
= NULL
;
2910 struct cfg80211_ssid
*ssid
= NULL
;
2911 struct ieee80211_channel
*channel
= NULL
;
2912 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2914 int channel_req
= 0;
2916 struct brcmf_pno_scanresults_le
*pfn_result
;
2920 brcmf_dbg(SCAN
, "Enter\n");
2922 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2923 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2927 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2928 result_count
= le32_to_cpu(pfn_result
->count
);
2929 status
= le32_to_cpu(pfn_result
->status
);
2932 * PFN event is limited to fit 512 bytes so we may get
2933 * multiple NET_FOUND events. For now place a warning here.
2935 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2936 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2937 if (result_count
> 0) {
2940 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2941 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2942 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2943 if (!request
|| !ssid
|| !channel
) {
2948 request
->wiphy
= wiphy
;
2949 data
+= sizeof(struct brcmf_pno_scanresults_le
);
2950 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
2952 for (i
= 0; i
< result_count
; i
++) {
2953 netinfo
= &netinfo_start
[i
];
2955 brcmf_err("Invalid netinfo ptr. index: %d\n",
2961 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
2962 netinfo
->SSID
, netinfo
->channel
);
2963 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
2964 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
2967 channel_req
= netinfo
->channel
;
2968 if (channel_req
<= CH_MAX_2G_CHANNEL
)
2969 band
= NL80211_BAND_2GHZ
;
2971 band
= NL80211_BAND_5GHZ
;
2972 channel
[i
].center_freq
=
2973 ieee80211_channel_to_frequency(channel_req
,
2975 channel
[i
].band
= band
;
2976 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
2977 request
->channels
[i
] = &channel
[i
];
2978 request
->n_channels
++;
2981 /* assign parsed ssid array */
2982 if (request
->n_ssids
)
2983 request
->ssids
= &ssid
[0];
2985 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2986 /* Abort any on-going scan */
2987 brcmf_abort_scanning(cfg
);
2990 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2991 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
2993 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2996 cfg
->sched_escan
= true;
2997 cfg
->scan_request
= request
;
2999 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3012 cfg80211_sched_scan_stopped(wiphy
);
3016 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3021 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3024 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3028 brcmf_err("failed code %d\n", ret
);
3033 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3035 struct brcmf_pno_param_le pfn_param
;
3037 memset(&pfn_param
, 0, sizeof(pfn_param
));
3038 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3040 /* set extra pno params */
3041 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3042 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3043 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3045 /* set up pno scan fr */
3046 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3048 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3049 &pfn_param
, sizeof(pfn_param
));
3053 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3054 struct net_device
*ndev
,
3055 struct cfg80211_sched_scan_request
*request
)
3057 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3058 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3059 struct brcmf_pno_net_param_le pfn
;
3063 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3064 request
->n_match_sets
, request
->n_ssids
);
3065 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3066 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3069 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3070 brcmf_err("Scanning suppressed: status (%lu)\n",
3075 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3076 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3081 if (request
->n_ssids
> 0) {
3082 for (i
= 0; i
< request
->n_ssids
; i
++) {
3083 /* Active scan req for ssids */
3084 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3085 request
->ssids
[i
].ssid
);
3088 * match_set ssids is a supert set of n_ssid list,
3089 * so we need not add these set seperately.
3094 if (request
->n_match_sets
> 0) {
3095 /* clean up everything */
3096 ret
= brcmf_dev_pno_clean(ndev
);
3098 brcmf_err("failed error=%d\n", ret
);
3103 ret
= brcmf_dev_pno_config(ndev
);
3105 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
3109 /* configure each match set */
3110 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3111 struct cfg80211_ssid
*ssid
;
3114 ssid
= &request
->match_sets
[i
].ssid
;
3115 ssid_len
= ssid
->ssid_len
;
3118 brcmf_err("skip broadcast ssid\n");
3121 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3122 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3123 pfn
.wsec
= cpu_to_le32(0);
3124 pfn
.infra
= cpu_to_le32(1);
3125 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3126 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3127 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3128 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3130 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3131 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3133 /* Enable the PNO */
3134 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3135 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3145 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3146 struct net_device
*ndev
)
3148 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3150 brcmf_dbg(SCAN
, "enter\n");
3151 brcmf_dev_pno_clean(ndev
);
3152 if (cfg
->sched_escan
)
3153 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3157 #ifdef CONFIG_NL80211_TESTMODE
3158 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
,
3159 struct wireless_dev
*wdev
,
3160 void *data
, int len
)
3162 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3163 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3164 struct brcmf_dcmd
*dcmd
= data
;
3165 struct sk_buff
*reply
;
3168 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3169 dcmd
->buf
, dcmd
->len
);
3172 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3173 dcmd
->buf
, dcmd
->len
);
3175 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3176 dcmd
->buf
, dcmd
->len
);
3178 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3179 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3180 ret
= cfg80211_testmode_reply(reply
);
3186 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3191 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3193 brcmf_err("auth error %d\n", err
);
3197 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3199 brcmf_err("wsec error %d\n", err
);
3202 /* set upper-layer auth */
3203 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3205 brcmf_err("wpa_auth error %d\n", err
);
3212 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3215 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3217 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3221 brcmf_configure_wpaie(struct net_device
*ndev
, struct brcmf_vs_tlv
*wpa_ie
,
3224 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3225 u32 auth
= 0; /* d11 open authentication */
3237 u32 wme_bss_disable
;
3239 brcmf_dbg(TRACE
, "Enter\n");
3243 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3244 data
= (u8
*)wpa_ie
;
3245 offset
= TLV_HDR_LEN
;
3247 offset
+= VS_IE_FIXED_HDR_LEN
;
3249 offset
+= WPA_IE_VERSION_LEN
;
3251 /* check for multicast cipher suite */
3252 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3254 brcmf_err("no multicast cipher suite\n");
3258 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3260 brcmf_err("ivalid OUI\n");
3263 offset
+= TLV_OUI_LEN
;
3265 /* pick up multicast cipher */
3266 switch (data
[offset
]) {
3267 case WPA_CIPHER_NONE
:
3270 case WPA_CIPHER_WEP_40
:
3271 case WPA_CIPHER_WEP_104
:
3274 case WPA_CIPHER_TKIP
:
3275 gval
= TKIP_ENABLED
;
3277 case WPA_CIPHER_AES_CCM
:
3282 brcmf_err("Invalid multi cast cipher info\n");
3287 /* walk thru unicast cipher list and pick up what we recognize */
3288 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3289 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3290 /* Check for unicast suite(s) */
3291 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3293 brcmf_err("no unicast cipher suite\n");
3296 for (i
= 0; i
< count
; i
++) {
3297 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3299 brcmf_err("ivalid OUI\n");
3302 offset
+= TLV_OUI_LEN
;
3303 switch (data
[offset
]) {
3304 case WPA_CIPHER_NONE
:
3306 case WPA_CIPHER_WEP_40
:
3307 case WPA_CIPHER_WEP_104
:
3308 pval
|= WEP_ENABLED
;
3310 case WPA_CIPHER_TKIP
:
3311 pval
|= TKIP_ENABLED
;
3313 case WPA_CIPHER_AES_CCM
:
3314 pval
|= AES_ENABLED
;
3317 brcmf_err("Ivalid unicast security info\n");
3321 /* walk thru auth management suite list and pick up what we recognize */
3322 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3323 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3324 /* Check for auth key management suite(s) */
3325 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3327 brcmf_err("no auth key mgmt suite\n");
3330 for (i
= 0; i
< count
; i
++) {
3331 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3333 brcmf_err("ivalid OUI\n");
3336 offset
+= TLV_OUI_LEN
;
3337 switch (data
[offset
]) {
3339 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3340 wpa_auth
|= WPA_AUTH_NONE
;
3342 case RSN_AKM_UNSPECIFIED
:
3343 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3344 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3345 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3348 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3349 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3350 (wpa_auth
|= WPA_AUTH_PSK
);
3353 brcmf_err("Ivalid key mgmt info\n");
3359 wme_bss_disable
= 1;
3360 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3361 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3362 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3363 wme_bss_disable
= 0;
3365 /* set wme_bss_disable to sync RSN Capabilities */
3366 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3369 brcmf_err("wme_bss_disable error %d\n", err
);
3373 /* FOR WPS , set SES_OW_ENABLED */
3374 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3377 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3379 brcmf_err("auth error %d\n", err
);
3383 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3385 brcmf_err("wsec error %d\n", err
);
3388 /* set upper-layer auth */
3389 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3391 brcmf_err("wpa_auth error %d\n", err
);
3400 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3401 struct parsed_vndr_ies
*vndr_ies
)
3404 struct brcmf_vs_tlv
*vndrie
;
3405 struct brcmf_tlv
*ie
;
3406 struct parsed_vndr_ie_info
*parsed_info
;
3409 remaining_len
= (s32
)vndr_ie_len
;
3410 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3412 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3414 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3416 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3417 /* len should be bigger than OUI length + one */
3418 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3419 brcmf_err("invalid vndr ie. length is too small %d\n",
3423 /* if wpa or wme ie, do not add ie */
3424 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3425 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3426 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3427 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3431 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3433 /* save vndr ie information */
3434 parsed_info
->ie_ptr
= (char *)vndrie
;
3435 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3436 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3440 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3441 parsed_info
->vndrie
.oui
[0],
3442 parsed_info
->vndrie
.oui
[1],
3443 parsed_info
->vndrie
.oui
[2],
3444 parsed_info
->vndrie
.oui_type
);
3446 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3449 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3450 if (remaining_len
<= TLV_HDR_LEN
)
3453 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3460 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3466 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3467 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3469 iecount_le
= cpu_to_le32(1);
3470 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3472 pktflag_le
= cpu_to_le32(pktflag
);
3473 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3475 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3477 return ie_len
+ VNDR_IE_HDR_SIZE
;
3480 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3481 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3483 struct brcmf_if
*ifp
;
3484 struct vif_saved_ie
*saved_ie
;
3488 u8
*mgmt_ie_buf
= NULL
;
3489 int mgmt_ie_buf_len
;
3491 u32 del_add_ie_buf_len
= 0;
3492 u32 total_ie_buf_len
= 0;
3493 u32 parsed_ie_buf_len
= 0;
3494 struct parsed_vndr_ies old_vndr_ies
;
3495 struct parsed_vndr_ies new_vndr_ies
;
3496 struct parsed_vndr_ie_info
*vndrie_info
;
3499 int remained_buf_len
;
3504 saved_ie
= &vif
->saved_ie
;
3506 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3507 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3510 curr_ie_buf
= iovar_ie_buf
;
3512 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3513 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3514 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3515 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3517 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3518 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3519 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3520 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3522 case BRCMF_VNDR_IE_BEACON_FLAG
:
3523 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3524 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3525 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3527 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
3528 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
3529 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
3530 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
3534 brcmf_err("not suitable type\n");
3538 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3540 brcmf_err("extra IE size too big\n");
3544 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3545 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3547 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3548 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3549 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3550 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3551 vndrie_info
->ie_len
);
3552 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3556 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3557 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3558 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3559 parsed_ie_buf_len
) == 0)) {
3560 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3564 /* parse old vndr_ie */
3565 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3567 /* make a command to delete old ie */
3568 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3569 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3571 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3572 vndrie_info
->vndrie
.id
,
3573 vndrie_info
->vndrie
.len
,
3574 vndrie_info
->vndrie
.oui
[0],
3575 vndrie_info
->vndrie
.oui
[1],
3576 vndrie_info
->vndrie
.oui
[2]);
3578 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3579 vndrie_info
->ie_ptr
,
3580 vndrie_info
->ie_len
,
3582 curr_ie_buf
+= del_add_ie_buf_len
;
3583 total_ie_buf_len
+= del_add_ie_buf_len
;
3588 /* Add if there is any extra IE */
3589 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3592 remained_buf_len
= mgmt_ie_buf_len
;
3594 /* make a command to add new ie */
3595 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3596 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3598 /* verify remained buf size before copy data */
3599 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3600 VNDR_IE_VSIE_OFFSET
)) {
3601 brcmf_err("no space in mgmt_ie_buf: len left %d",
3605 remained_buf_len
-= (vndrie_info
->ie_len
+
3606 VNDR_IE_VSIE_OFFSET
);
3608 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3609 vndrie_info
->vndrie
.id
,
3610 vndrie_info
->vndrie
.len
,
3611 vndrie_info
->vndrie
.oui
[0],
3612 vndrie_info
->vndrie
.oui
[1],
3613 vndrie_info
->vndrie
.oui
[2]);
3615 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3616 vndrie_info
->ie_ptr
,
3617 vndrie_info
->ie_len
,
3620 /* save the parsed IE in wl struct */
3621 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3622 vndrie_info
->ie_len
);
3623 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3625 curr_ie_buf
+= del_add_ie_buf_len
;
3626 total_ie_buf_len
+= del_add_ie_buf_len
;
3629 if (total_ie_buf_len
) {
3630 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3633 brcmf_err("vndr ie set error : %d\n", err
);
3637 kfree(iovar_ie_buf
);
3641 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
3644 BRCMF_VNDR_IE_PRBREQ_FLAG
,
3645 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3646 BRCMF_VNDR_IE_BEACON_FLAG
3650 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
3651 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
3653 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
3658 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
3659 struct cfg80211_beacon_data
*beacon
)
3663 /* Set Beacon IEs to FW */
3664 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
3665 beacon
->tail
, beacon
->tail_len
);
3667 brcmf_err("Set Beacon IE Failed\n");
3670 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3672 /* Set Probe Response IEs to FW */
3673 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
3674 beacon
->proberesp_ies
,
3675 beacon
->proberesp_ies_len
);
3677 brcmf_err("Set Probe Resp IE Failed\n");
3679 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3685 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info
*cfg
,
3686 struct brcmf_if
*ifp
,
3687 struct ieee80211_channel
*channel
)
3692 brcmf_dbg(TRACE
, "band=%d, center_freq=%d\n", channel
->band
,
3693 channel
->center_freq
);
3695 chanspec
= channel_to_chanspec(&cfg
->d11inf
, channel
);
3696 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
3702 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3703 struct cfg80211_ap_settings
*settings
)
3706 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3707 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3708 struct brcmf_tlv
*ssid_ie
;
3709 struct brcmf_ssid_le ssid_le
;
3711 struct brcmf_tlv
*rsn_ie
;
3712 struct brcmf_vs_tlv
*wpa_ie
;
3713 struct brcmf_join_params join_params
;
3714 enum nl80211_iftype dev_role
;
3715 struct brcmf_fil_bss_enable_le bss_enable
;
3717 brcmf_dbg(TRACE
, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3718 cfg80211_get_chandef_type(&settings
->chandef
),
3719 settings
->beacon_interval
,
3720 settings
->dtim_period
);
3721 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3722 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3723 settings
->inactivity_timeout
);
3725 dev_role
= ifp
->vif
->wdev
.iftype
;
3727 memset(&ssid_le
, 0, sizeof(ssid_le
));
3728 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3729 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3730 ssid_ie
= brcmf_parse_tlvs(
3731 (u8
*)&settings
->beacon
.head
[ie_offset
],
3732 settings
->beacon
.head_len
- ie_offset
,
3737 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3738 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3739 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3741 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3742 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3745 brcmf_set_mpc(ifp
, 0);
3746 brcmf_configure_arp_offload(ifp
, false);
3748 /* find the RSN_IE */
3749 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3750 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3752 /* find the WPA_IE */
3753 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3754 settings
->beacon
.tail_len
);
3756 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3757 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3758 if (wpa_ie
!= NULL
) {
3760 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3765 err
= brcmf_configure_wpaie(ndev
,
3766 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3771 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3772 brcmf_configure_opensecurity(ifp
);
3775 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
3777 err
= brcmf_cfg80211_set_channel(cfg
, ifp
, settings
->chandef
.chan
);
3779 brcmf_err("Set Channel failed, %d\n", err
);
3783 if (settings
->beacon_interval
) {
3784 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3785 settings
->beacon_interval
);
3787 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3791 if (settings
->dtim_period
) {
3792 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3793 settings
->dtim_period
);
3795 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3800 if (dev_role
== NL80211_IFTYPE_AP
) {
3801 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3803 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3806 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3809 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3811 brcmf_err("SET INFRA error %d\n", err
);
3814 if (dev_role
== NL80211_IFTYPE_AP
) {
3815 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3817 brcmf_err("setting AP mode failed %d\n", err
);
3820 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3822 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3826 memset(&join_params
, 0, sizeof(join_params
));
3827 /* join parameters starts with ssid */
3828 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
3830 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3831 &join_params
, sizeof(join_params
));
3833 brcmf_err("SET SSID error (%d)\n", err
);
3836 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
3838 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
3841 brcmf_err("setting ssid failed %d\n", err
);
3844 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3845 bss_enable
.enable
= cpu_to_le32(1);
3846 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3847 sizeof(bss_enable
));
3849 brcmf_err("bss_enable config failed %d\n", err
);
3853 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
3855 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3856 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3860 brcmf_set_mpc(ifp
, 1);
3861 brcmf_configure_arp_offload(ifp
, true);
3866 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3868 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3870 struct brcmf_fil_bss_enable_le bss_enable
;
3871 struct brcmf_join_params join_params
;
3873 brcmf_dbg(TRACE
, "Enter\n");
3875 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
3876 /* Due to most likely deauths outstanding we sleep */
3877 /* first to make sure they get processed by fw. */
3880 memset(&join_params
, 0, sizeof(join_params
));
3881 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3882 &join_params
, sizeof(join_params
));
3884 brcmf_err("SET SSID error (%d)\n", err
);
3885 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3887 brcmf_err("BRCMF_C_UP error %d\n", err
);
3888 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3890 brcmf_err("setting AP mode failed %d\n", err
);
3891 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
3893 brcmf_err("setting INFRA mode failed %d\n", err
);
3895 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3896 bss_enable
.enable
= cpu_to_le32(0);
3897 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3898 sizeof(bss_enable
));
3900 brcmf_err("bss_enable config failed %d\n", err
);
3902 brcmf_set_mpc(ifp
, 1);
3903 brcmf_configure_arp_offload(ifp
, true);
3904 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3905 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3911 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3912 struct cfg80211_beacon_data
*info
)
3914 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3917 brcmf_dbg(TRACE
, "Enter\n");
3919 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
3925 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3928 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3929 struct brcmf_scb_val_le scbval
;
3930 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3936 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3938 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
3939 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3940 if (!check_vif_up(ifp
->vif
))
3943 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3944 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3945 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3946 &scbval
, sizeof(scbval
));
3948 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
3950 brcmf_dbg(TRACE
, "Exit\n");
3956 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
3957 struct wireless_dev
*wdev
,
3958 u16 frame_type
, bool reg
)
3960 struct brcmf_cfg80211_vif
*vif
;
3963 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
3965 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
3966 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
3968 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
3970 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
3975 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
3976 struct ieee80211_channel
*chan
, bool offchan
,
3977 unsigned int wait
, const u8
*buf
, size_t len
,
3978 bool no_cck
, bool dont_wait_for_ack
, u64
*cookie
)
3980 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3981 const struct ieee80211_mgmt
*mgmt
;
3982 struct brcmf_cfg80211_vif
*vif
;
3986 struct brcmf_fil_action_frame_le
*action_frame
;
3987 struct brcmf_fil_af_params_le
*af_params
;
3992 brcmf_dbg(TRACE
, "Enter\n");
3996 mgmt
= (const struct ieee80211_mgmt
*)buf
;
3998 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
3999 brcmf_err("Driver only allows MGMT packet type\n");
4003 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4005 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4006 /* Right now the only reason to get a probe response */
4007 /* is for p2p listen response or for p2p GO from */
4008 /* wpa_supplicant. Unfortunately the probe is send */
4009 /* on primary ndev, while dongle wants it on the p2p */
4010 /* vif. Since this is only reason for a probe */
4011 /* response to be sent, the vif is taken from cfg. */
4012 /* If ever desired to send proberesp for non p2p */
4013 /* response then data should be checked for */
4014 /* "DIRECT-". Note in future supplicant will take */
4015 /* dedicated p2p wdev to do this and then this 'hack'*/
4016 /* is not needed anymore. */
4017 ie_offset
= DOT11_MGMT_HDR_LEN
+
4018 DOT11_BCN_PRB_FIXED_LEN
;
4019 ie_len
= len
- ie_offset
;
4020 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4021 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4022 err
= brcmf_vif_set_mgmt_ie(vif
,
4023 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4026 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4028 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4029 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4030 if (af_params
== NULL
) {
4031 brcmf_err("unable to allocate frame\n");
4035 action_frame
= &af_params
->action_frame
;
4036 /* Add the packet Id */
4037 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4039 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4040 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4041 /* Add the length exepted for 802.11 header */
4042 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4043 /* Add the channel. Use the one specified as parameter if any or
4044 * the current one (got from the firmware) otherwise
4047 freq
= chan
->center_freq
;
4049 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4051 chan_nr
= ieee80211_frequency_to_channel(freq
);
4052 af_params
->channel
= cpu_to_le32(chan_nr
);
4054 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4055 le16_to_cpu(action_frame
->len
));
4057 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4058 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4060 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4063 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4067 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4068 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4077 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4078 struct wireless_dev
*wdev
,
4081 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4082 struct brcmf_cfg80211_vif
*vif
;
4085 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4087 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4089 brcmf_err("No p2p device available for probe response\n");
4093 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4098 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4099 struct wireless_dev
*wdev
,
4100 enum nl80211_crit_proto_id proto
,
4103 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4104 struct brcmf_cfg80211_vif
*vif
;
4106 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4108 /* only DHCP support for now */
4109 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4112 /* suppress and abort scanning */
4113 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4114 brcmf_abort_scanning(cfg
);
4116 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4119 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4120 struct wireless_dev
*wdev
)
4122 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4123 struct brcmf_cfg80211_vif
*vif
;
4125 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4127 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4128 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4131 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4136 case NL80211_TDLS_DISCOVERY_REQ
:
4137 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4139 case NL80211_TDLS_SETUP
:
4140 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4142 case NL80211_TDLS_TEARDOWN
:
4143 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4146 brcmf_err("unsupported operation: %d\n", oper
);
4152 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4153 struct net_device
*ndev
, u8
*peer
,
4154 enum nl80211_tdls_operation oper
)
4156 struct brcmf_if
*ifp
;
4157 struct brcmf_tdls_iovar_le info
;
4160 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4164 ifp
= netdev_priv(ndev
);
4165 memset(&info
, 0, sizeof(info
));
4166 info
.mode
= (u8
)ret
;
4168 memcpy(info
.ea
, peer
, ETH_ALEN
);
4170 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
4171 &info
, sizeof(info
));
4173 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
4178 static struct cfg80211_ops wl_cfg80211_ops
= {
4179 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4180 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4181 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4182 .scan
= brcmf_cfg80211_scan
,
4183 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4184 .join_ibss
= brcmf_cfg80211_join_ibss
,
4185 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4186 .get_station
= brcmf_cfg80211_get_station
,
4187 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4188 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4189 .add_key
= brcmf_cfg80211_add_key
,
4190 .del_key
= brcmf_cfg80211_del_key
,
4191 .get_key
= brcmf_cfg80211_get_key
,
4192 .set_default_key
= brcmf_cfg80211_config_default_key
,
4193 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4194 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4195 .connect
= brcmf_cfg80211_connect
,
4196 .disconnect
= brcmf_cfg80211_disconnect
,
4197 .suspend
= brcmf_cfg80211_suspend
,
4198 .resume
= brcmf_cfg80211_resume
,
4199 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4200 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4201 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4202 .start_ap
= brcmf_cfg80211_start_ap
,
4203 .stop_ap
= brcmf_cfg80211_stop_ap
,
4204 .change_beacon
= brcmf_cfg80211_change_beacon
,
4205 .del_station
= brcmf_cfg80211_del_station
,
4206 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4207 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4208 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4209 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4210 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4211 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4212 .start_p2p_device
= brcmf_p2p_start_device
,
4213 .stop_p2p_device
= brcmf_p2p_stop_device
,
4214 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
4215 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
4216 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
4217 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode
)
4220 static s32
brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type
)
4223 case NL80211_IFTYPE_AP_VLAN
:
4224 case NL80211_IFTYPE_WDS
:
4225 case NL80211_IFTYPE_MONITOR
:
4226 case NL80211_IFTYPE_MESH_POINT
:
4228 case NL80211_IFTYPE_ADHOC
:
4229 return WL_MODE_IBSS
;
4230 case NL80211_IFTYPE_STATION
:
4231 case NL80211_IFTYPE_P2P_CLIENT
:
4233 case NL80211_IFTYPE_AP
:
4234 case NL80211_IFTYPE_P2P_GO
:
4236 case NL80211_IFTYPE_P2P_DEVICE
:
4238 case NL80211_IFTYPE_UNSPECIFIED
:
4246 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4248 /* scheduled scan settings */
4249 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4250 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4251 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4252 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4255 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
4258 .types
= BIT(NL80211_IFTYPE_STATION
) |
4259 BIT(NL80211_IFTYPE_ADHOC
) |
4260 BIT(NL80211_IFTYPE_AP
)
4264 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4265 BIT(NL80211_IFTYPE_P2P_GO
)
4269 .types
= BIT(NL80211_IFTYPE_P2P_DEVICE
)
4272 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
4274 .max_interfaces
= BRCMF_IFACE_MAX_CNT
,
4275 .num_different_channels
= 2,
4276 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
4277 .limits
= brcmf_iface_limits
4281 static const struct ieee80211_txrx_stypes
4282 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
4283 [NL80211_IFTYPE_STATION
] = {
4285 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4286 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4288 [NL80211_IFTYPE_P2P_CLIENT
] = {
4290 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4291 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4293 [NL80211_IFTYPE_P2P_GO
] = {
4295 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
4296 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
4297 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
4298 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
4299 BIT(IEEE80211_STYPE_AUTH
>> 4) |
4300 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
4301 BIT(IEEE80211_STYPE_ACTION
>> 4)
4303 [NL80211_IFTYPE_P2P_DEVICE
] = {
4305 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4306 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4310 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
4312 struct wiphy
*wiphy
;
4315 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
4317 brcmf_err("Could not allocate wiphy device\n");
4318 return ERR_PTR(-ENOMEM
);
4320 set_wiphy_dev(wiphy
, phydev
);
4321 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4322 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4323 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4324 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4325 BIT(NL80211_IFTYPE_ADHOC
) |
4326 BIT(NL80211_IFTYPE_AP
) |
4327 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4328 BIT(NL80211_IFTYPE_P2P_GO
) |
4329 BIT(NL80211_IFTYPE_P2P_DEVICE
);
4330 wiphy
->iface_combinations
= brcmf_iface_combos
;
4331 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
4332 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4333 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4334 wiphy
->cipher_suites
= __wl_cipher_suites
;
4335 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4336 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
4337 WIPHY_FLAG_OFFCHAN_TX
|
4338 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
|
4339 WIPHY_FLAG_SUPPORTS_TDLS
;
4340 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
4341 wiphy
->max_remain_on_channel_duration
= 5000;
4342 brcmf_wiphy_pno_params(wiphy
);
4343 brcmf_dbg(INFO
, "Registering custom regulatory\n");
4344 wiphy
->flags
|= WIPHY_FLAG_CUSTOM_REGULATORY
;
4345 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
4346 err
= wiphy_register(wiphy
);
4348 brcmf_err("Could not register wiphy device (%d)\n", err
);
4350 return ERR_PTR(err
);
4355 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4356 enum nl80211_iftype type
,
4359 struct brcmf_cfg80211_vif
*vif
;
4361 if (cfg
->vif_cnt
== BRCMF_IFACE_MAX_CNT
)
4362 return ERR_PTR(-ENOSPC
);
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
);
4384 void brcmf_free_vif(struct brcmf_cfg80211_info
*cfg
,
4385 struct brcmf_cfg80211_vif
*vif
)
4387 list_del(&vif
->list
);
4391 if (!cfg
->vif_cnt
) {
4392 wiphy_unregister(cfg
->wiphy
);
4393 wiphy_free(cfg
->wiphy
);
4397 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4399 u32 event
= e
->event_code
;
4400 u32 status
= e
->status
;
4402 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4403 brcmf_dbg(CONN
, "Processing set ssid\n");
4410 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4412 u32 event
= e
->event_code
;
4413 u16 flags
= e
->flags
;
4415 if (event
== BRCMF_E_LINK
&& (!(flags
& BRCMF_EVENT_MSG_LINK
))) {
4416 brcmf_dbg(CONN
, "Processing link down\n");
4422 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4423 const struct brcmf_event_msg
*e
)
4425 u32 event
= e
->event_code
;
4426 u32 status
= e
->status
;
4428 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4429 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
4430 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
4434 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4435 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
4442 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4444 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4446 kfree(conn_info
->req_ie
);
4447 conn_info
->req_ie
= NULL
;
4448 conn_info
->req_ie_len
= 0;
4449 kfree(conn_info
->resp_ie
);
4450 conn_info
->resp_ie
= NULL
;
4451 conn_info
->resp_ie_len
= 0;
4454 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
4455 struct brcmf_if
*ifp
)
4457 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4458 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4463 brcmf_clear_assoc_ies(cfg
);
4465 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4466 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4468 brcmf_err("could not get assoc info (%d)\n", err
);
4472 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4473 req_len
= le32_to_cpu(assoc_info
->req_len
);
4474 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4476 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4480 brcmf_err("could not get assoc req (%d)\n", err
);
4483 conn_info
->req_ie_len
= req_len
;
4485 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4488 conn_info
->req_ie_len
= 0;
4489 conn_info
->req_ie
= NULL
;
4492 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4496 brcmf_err("could not get assoc resp (%d)\n", err
);
4499 conn_info
->resp_ie_len
= resp_len
;
4500 conn_info
->resp_ie
=
4501 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4504 conn_info
->resp_ie_len
= 0;
4505 conn_info
->resp_ie
= NULL
;
4507 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
4508 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4514 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4515 struct net_device
*ndev
,
4516 const struct brcmf_event_msg
*e
)
4518 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4519 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4520 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4521 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4522 struct ieee80211_channel
*notify_channel
= NULL
;
4523 struct ieee80211_supported_band
*band
;
4524 struct brcmf_bss_info_le
*bi
;
4525 struct brcmu_chan ch
;
4530 brcmf_dbg(TRACE
, "Enter\n");
4532 brcmf_get_assoc_ies(cfg
, ifp
);
4533 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4534 brcmf_update_bss_info(cfg
, ifp
);
4536 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4542 /* data sent to dongle has to be little endian */
4543 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4544 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4545 buf
, WL_BSS_INFO_MAX
);
4550 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4551 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
4552 cfg
->d11inf
.decchspec(&ch
);
4554 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
4555 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4557 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4559 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
4560 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4564 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4565 conn_info
->req_ie
, conn_info
->req_ie_len
,
4566 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4567 brcmf_dbg(CONN
, "Report roaming result\n");
4569 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4570 brcmf_dbg(TRACE
, "Exit\n");
4575 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4576 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4579 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4580 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4581 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4584 brcmf_dbg(TRACE
, "Enter\n");
4586 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4587 &ifp
->vif
->sme_state
)) {
4589 brcmf_get_assoc_ies(cfg
, ifp
);
4590 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4591 brcmf_update_bss_info(cfg
, ifp
);
4592 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4593 &ifp
->vif
->sme_state
);
4595 cfg80211_connect_result(ndev
,
4596 (u8
*)profile
->bssid
,
4598 conn_info
->req_ie_len
,
4600 conn_info
->resp_ie_len
,
4601 completed
? WLAN_STATUS_SUCCESS
:
4602 WLAN_STATUS_AUTH_TIMEOUT
,
4604 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4605 completed
? "succeeded" : "failed");
4607 brcmf_dbg(TRACE
, "Exit\n");
4612 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4613 struct net_device
*ndev
,
4614 const struct brcmf_event_msg
*e
, void *data
)
4616 static int generation
;
4617 u32 event
= e
->event_code
;
4618 u32 reason
= e
->reason
;
4619 struct station_info sinfo
;
4621 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4622 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
4623 ndev
!= cfg_to_ndev(cfg
)) {
4624 brcmf_dbg(CONN
, "AP mode link down\n");
4625 complete(&cfg
->vif_disabled
);
4629 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4630 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4631 memset(&sinfo
, 0, sizeof(sinfo
));
4632 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4634 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4637 sinfo
.assoc_req_ies
= data
;
4638 sinfo
.assoc_req_ies_len
= e
->datalen
;
4640 sinfo
.generation
= generation
;
4641 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4642 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4643 (event
== BRCMF_E_DEAUTH_IND
) ||
4644 (event
== BRCMF_E_DEAUTH
)) {
4645 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4651 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4652 const struct brcmf_event_msg
*e
, void *data
)
4654 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4655 struct net_device
*ndev
= ifp
->ndev
;
4656 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4659 if (ifp
->vif
->mode
== WL_MODE_AP
) {
4660 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4661 } else if (brcmf_is_linkup(e
)) {
4662 brcmf_dbg(CONN
, "Linkup\n");
4663 if (brcmf_is_ibssmode(ifp
->vif
)) {
4664 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4665 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4666 cfg80211_ibss_joined(ndev
, e
->addr
, GFP_KERNEL
);
4667 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4668 &ifp
->vif
->sme_state
);
4669 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4670 &ifp
->vif
->sme_state
);
4672 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4673 } else if (brcmf_is_linkdown(e
)) {
4674 brcmf_dbg(CONN
, "Linkdown\n");
4675 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4676 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4677 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
,
4678 &ifp
->vif
->sme_state
))
4679 cfg80211_disconnected(ndev
, 0, NULL
, 0,
4682 brcmf_link_down(ifp
->vif
);
4683 brcmf_init_prof(ndev_to_prof(ndev
));
4684 if (ndev
!= cfg_to_ndev(cfg
))
4685 complete(&cfg
->vif_disabled
);
4686 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4687 if (brcmf_is_ibssmode(ifp
->vif
))
4688 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4689 &ifp
->vif
->sme_state
);
4691 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4698 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4699 const struct brcmf_event_msg
*e
, void *data
)
4701 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4703 u32 event
= e
->event_code
;
4704 u32 status
= e
->status
;
4706 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4707 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4708 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4710 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4717 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4718 const struct brcmf_event_msg
*e
, void *data
)
4720 u16 flags
= e
->flags
;
4721 enum nl80211_key_type key_type
;
4723 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4724 key_type
= NL80211_KEYTYPE_GROUP
;
4726 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4728 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4734 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4735 const struct brcmf_event_msg
*e
, void *data
)
4737 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4738 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4739 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4740 struct brcmf_cfg80211_vif
*vif
;
4742 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4743 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4746 mutex_lock(&event
->vif_event_lock
);
4747 event
->action
= ifevent
->action
;
4750 switch (ifevent
->action
) {
4751 case BRCMF_E_IF_ADD
:
4752 /* waiting process may have timed out */
4753 if (!cfg
->vif_event
.vif
) {
4754 mutex_unlock(&event
->vif_event_lock
);
4761 vif
->wdev
.netdev
= ifp
->ndev
;
4762 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4763 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4765 mutex_unlock(&event
->vif_event_lock
);
4766 wake_up(&event
->vif_wq
);
4769 case BRCMF_E_IF_DEL
:
4770 mutex_unlock(&event
->vif_event_lock
);
4771 /* event may not be upon user request */
4772 if (brcmf_cfg80211_vif_event_armed(cfg
))
4773 wake_up(&event
->vif_wq
);
4776 case BRCMF_E_IF_CHANGE
:
4777 mutex_unlock(&event
->vif_event_lock
);
4778 wake_up(&event
->vif_wq
);
4782 mutex_unlock(&event
->vif_event_lock
);
4788 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4790 conf
->frag_threshold
= (u32
)-1;
4791 conf
->rts_threshold
= (u32
)-1;
4792 conf
->retry_short
= (u32
)-1;
4793 conf
->retry_long
= (u32
)-1;
4794 conf
->tx_power
= -1;
4797 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4799 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4800 brcmf_notify_connect_status
);
4801 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4802 brcmf_notify_connect_status
);
4803 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4804 brcmf_notify_connect_status
);
4805 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4806 brcmf_notify_connect_status
);
4807 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4808 brcmf_notify_connect_status
);
4809 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4810 brcmf_notify_connect_status
);
4811 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4812 brcmf_notify_roaming_status
);
4813 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4814 brcmf_notify_mic_status
);
4815 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4816 brcmf_notify_connect_status
);
4817 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4818 brcmf_notify_sched_scan_results
);
4819 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4820 brcmf_notify_vif_event
);
4821 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
4822 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
4823 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
4824 brcmf_p2p_notify_listen_complete
);
4825 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
4826 brcmf_p2p_notify_action_frame_rx
);
4827 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
4828 brcmf_p2p_notify_action_tx_complete
);
4829 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
4830 brcmf_p2p_notify_action_tx_complete
);
4833 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4837 kfree(cfg
->escan_ioctl_buf
);
4838 cfg
->escan_ioctl_buf
= NULL
;
4839 kfree(cfg
->extra_buf
);
4840 cfg
->extra_buf
= NULL
;
4841 kfree(cfg
->pmk_list
);
4842 cfg
->pmk_list
= NULL
;
4845 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4847 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4849 goto init_priv_mem_out
;
4850 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4851 if (!cfg
->escan_ioctl_buf
)
4852 goto init_priv_mem_out
;
4853 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4854 if (!cfg
->extra_buf
)
4855 goto init_priv_mem_out
;
4856 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4858 goto init_priv_mem_out
;
4863 brcmf_deinit_priv_mem(cfg
);
4868 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4872 cfg
->scan_request
= NULL
;
4873 cfg
->pwr_save
= true;
4874 cfg
->roam_on
= true; /* roam on & off switch.
4875 we enable roam per default */
4876 cfg
->active_scan
= true; /* we do active scan for
4877 specific scan per default */
4878 cfg
->dongle_up
= false; /* dongle is not up yet */
4879 err
= brcmf_init_priv_mem(cfg
);
4882 brcmf_register_event_handlers(cfg
);
4883 mutex_init(&cfg
->usr_sync
);
4884 brcmf_init_escan(cfg
);
4885 brcmf_init_conf(cfg
->conf
);
4886 init_completion(&cfg
->vif_disabled
);
4890 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4892 cfg
->dongle_up
= false; /* dongle down */
4893 brcmf_abort_scanning(cfg
);
4894 brcmf_deinit_priv_mem(cfg
);
4897 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4899 init_waitqueue_head(&event
->vif_wq
);
4900 mutex_init(&event
->vif_event_lock
);
4903 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4904 struct device
*busdev
)
4906 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4907 struct brcmf_cfg80211_info
*cfg
;
4908 struct wiphy
*wiphy
;
4909 struct brcmf_cfg80211_vif
*vif
;
4910 struct brcmf_if
*ifp
;
4915 brcmf_err("ndev is invalid\n");
4919 ifp
= netdev_priv(ndev
);
4920 wiphy
= brcmf_setup_wiphy(busdev
);
4924 cfg
= wiphy_priv(wiphy
);
4927 init_vif_event(&cfg
->vif_event
);
4928 INIT_LIST_HEAD(&cfg
->vif_list
);
4930 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4937 vif
->wdev
.netdev
= ndev
;
4938 ndev
->ieee80211_ptr
= &vif
->wdev
;
4939 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4941 err
= wl_init_priv(cfg
);
4943 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4944 goto cfg80211_attach_out
;
4948 err
= brcmf_p2p_attach(cfg
);
4950 brcmf_err("P2P initilisation failed (%d)\n", err
);
4951 goto cfg80211_p2p_attach_out
;
4953 err
= brcmf_btcoex_attach(cfg
);
4955 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
4956 brcmf_p2p_detach(&cfg
->p2p
);
4957 goto cfg80211_p2p_attach_out
;
4960 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
4962 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
4963 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
4966 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
,
4969 brcmf_err("Failed to get D11 version (%d)\n", err
);
4970 goto cfg80211_p2p_attach_out
;
4972 cfg
->d11inf
.io_type
= (u8
)io_type
;
4973 brcmu_d11_attach(&cfg
->d11inf
);
4977 cfg80211_p2p_attach_out
:
4978 wl_deinit_priv(cfg
);
4980 cfg80211_attach_out
:
4981 brcmf_free_vif(cfg
, vif
);
4985 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
4987 struct brcmf_cfg80211_vif
*vif
;
4988 struct brcmf_cfg80211_vif
*tmp
;
4990 wl_deinit_priv(cfg
);
4991 brcmf_btcoex_detach(cfg
);
4992 list_for_each_entry_safe(vif
, tmp
, &cfg
->vif_list
, list
) {
4993 brcmf_free_vif(cfg
, vif
);
4998 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 roamvar
, u32 bcn_timeout
)
5001 __le32 roamtrigger
[2];
5002 __le32 roam_delta
[2];
5005 * Setup timeout if Beacons are lost and roam is
5006 * off to report link down
5009 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5011 brcmf_err("bcn_timeout error (%d)\n", err
);
5012 goto dongle_rom_out
;
5017 * Enable/Disable built-in roaming to allow supplicant
5018 * to take care of roaming
5020 brcmf_dbg(INFO
, "Internal Roaming = %s\n", roamvar
? "Off" : "On");
5021 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", roamvar
);
5023 brcmf_err("roam_off error (%d)\n", err
);
5024 goto dongle_rom_out
;
5027 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5028 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5029 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5030 (void *)roamtrigger
, sizeof(roamtrigger
));
5032 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5033 goto dongle_rom_out
;
5036 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5037 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5038 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5039 (void *)roam_delta
, sizeof(roam_delta
));
5041 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5042 goto dongle_rom_out
;
5050 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
5051 s32 scan_unassoc_time
, s32 scan_passive_time
)
5055 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5058 if (err
== -EOPNOTSUPP
)
5059 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
5061 brcmf_err("Scan assoc time error (%d)\n", err
);
5062 goto dongle_scantime_out
;
5064 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5067 if (err
== -EOPNOTSUPP
)
5068 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
5070 brcmf_err("Scan unassoc time error (%d)\n", err
);
5071 goto dongle_scantime_out
;
5074 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5077 if (err
== -EOPNOTSUPP
)
5078 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
5080 brcmf_err("Scan passive time error (%d)\n", err
);
5081 goto dongle_scantime_out
;
5084 dongle_scantime_out
:
5089 static s32
brcmf_construct_reginfo(struct brcmf_cfg80211_info
*cfg
, u32 bw_cap
)
5091 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5092 struct ieee80211_channel
*band_chan_arr
;
5093 struct brcmf_chanspec_list
*list
;
5094 struct brcmu_chan ch
;
5099 enum ieee80211_band band
;
5108 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5113 list
= (struct brcmf_chanspec_list
*)pbuf
;
5115 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5118 brcmf_err("get chanspecs error (%d)\n", err
);
5122 __wl_band_2ghz
.n_channels
= 0;
5123 __wl_band_5ghz_a
.n_channels
= 0;
5125 total
= le32_to_cpu(list
->count
);
5126 for (i
= 0; i
< total
; i
++) {
5127 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5128 cfg
->d11inf
.decchspec(&ch
);
5130 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5131 band_chan_arr
= __wl_2ghz_channels
;
5132 array_size
= ARRAY_SIZE(__wl_2ghz_channels
);
5133 n_cnt
= &__wl_band_2ghz
.n_channels
;
5134 band
= IEEE80211_BAND_2GHZ
;
5135 ht40_allowed
= (bw_cap
== WLC_N_BW_40ALL
);
5136 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5137 band_chan_arr
= __wl_5ghz_a_channels
;
5138 array_size
= ARRAY_SIZE(__wl_5ghz_a_channels
);
5139 n_cnt
= &__wl_band_5ghz_a
.n_channels
;
5140 band
= IEEE80211_BAND_5GHZ
;
5141 ht40_allowed
= !(bw_cap
== WLC_N_BW_20ALL
);
5143 brcmf_err("Invalid channel Sepc. 0x%x.\n", ch
.chspec
);
5146 if (!ht40_allowed
&& ch
.bw
== BRCMU_CHAN_BW_40
)
5149 for (j
= 0; (j
< *n_cnt
&& (*n_cnt
< array_size
)); j
++) {
5150 if (band_chan_arr
[j
].hw_value
== ch
.chnum
) {
5159 if (index
< array_size
) {
5160 band_chan_arr
[index
].center_freq
=
5161 ieee80211_channel_to_frequency(ch
.chnum
, band
);
5162 band_chan_arr
[index
].hw_value
= ch
.chnum
;
5164 if (ch
.bw
== BRCMU_CHAN_BW_40
&& ht40_allowed
) {
5165 /* assuming the order is HT20, HT40 Upper,
5166 * HT40 lower from chanspecs
5168 ht40_flag
= band_chan_arr
[index
].flags
&
5169 IEEE80211_CHAN_NO_HT40
;
5170 if (ch
.sb
== BRCMU_CHAN_SB_U
) {
5171 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5172 band_chan_arr
[index
].flags
&=
5173 ~IEEE80211_CHAN_NO_HT40
;
5174 band_chan_arr
[index
].flags
|=
5175 IEEE80211_CHAN_NO_HT40PLUS
;
5177 /* It should be one of
5178 * IEEE80211_CHAN_NO_HT40 or
5179 * IEEE80211_CHAN_NO_HT40PLUS
5181 band_chan_arr
[index
].flags
&=
5182 ~IEEE80211_CHAN_NO_HT40
;
5183 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5184 band_chan_arr
[index
].flags
|=
5185 IEEE80211_CHAN_NO_HT40MINUS
;
5188 band_chan_arr
[index
].flags
=
5189 IEEE80211_CHAN_NO_HT40
;
5190 ch
.bw
= BRCMU_CHAN_BW_20
;
5191 cfg
->d11inf
.encchspec(&ch
);
5192 channel
= ch
.chspec
;
5193 err
= brcmf_fil_bsscfg_int_get(ifp
,
5197 if (channel
& WL_CHAN_RADAR
)
5198 band_chan_arr
[index
].flags
|=
5199 (IEEE80211_CHAN_RADAR
|
5200 IEEE80211_CHAN_NO_IBSS
);
5201 if (channel
& WL_CHAN_PASSIVE
)
5202 band_chan_arr
[index
].flags
|=
5203 IEEE80211_CHAN_PASSIVE_SCAN
;
5216 static s32
brcmf_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
5218 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5219 struct wiphy
*wiphy
;
5228 struct ieee80211_supported_band
*bands
[IEEE80211_NUM_BANDS
];
5231 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
5232 &phy_list
, sizeof(phy_list
));
5234 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err
);
5238 phy
= ((char *)&phy_list
)[0];
5239 brcmf_dbg(INFO
, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy
);
5242 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
,
5243 &band_list
, sizeof(band_list
));
5245 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err
);
5248 brcmf_dbg(INFO
, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5249 band_list
[0], band_list
[1], band_list
[2]);
5251 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
5253 brcmf_err("nmode error (%d)\n", err
);
5255 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &bw_cap
);
5257 brcmf_err("mimo_bw_cap error (%d)\n", err
);
5259 brcmf_dbg(INFO
, "nmode=%d, mimo_bw_cap=%d\n", nmode
, bw_cap
);
5261 err
= brcmf_construct_reginfo(cfg
, bw_cap
);
5263 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err
);
5267 nband
= band_list
[0];
5268 memset(bands
, 0, sizeof(bands
));
5270 for (i
= 1; i
<= nband
&& i
< ARRAY_SIZE(band_list
); i
++) {
5272 if ((band_list
[i
] == WLC_BAND_5G
) &&
5273 (__wl_band_5ghz_a
.n_channels
> 0)) {
5274 index
= IEEE80211_BAND_5GHZ
;
5275 bands
[index
] = &__wl_band_5ghz_a
;
5276 if ((bw_cap
== WLC_N_BW_40ALL
) ||
5277 (bw_cap
== WLC_N_BW_20IN2G_40IN5G
))
5278 bands
[index
]->ht_cap
.cap
|=
5279 IEEE80211_HT_CAP_SGI_40
;
5280 } else if ((band_list
[i
] == WLC_BAND_2G
) &&
5281 (__wl_band_2ghz
.n_channels
> 0)) {
5282 index
= IEEE80211_BAND_2GHZ
;
5283 bands
[index
] = &__wl_band_2ghz
;
5284 if (bw_cap
== WLC_N_BW_40ALL
)
5285 bands
[index
]->ht_cap
.cap
|=
5286 IEEE80211_HT_CAP_SGI_40
;
5289 if ((index
>= 0) && nmode
) {
5290 bands
[index
]->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5291 bands
[index
]->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5292 bands
[index
]->ht_cap
.ht_supported
= true;
5293 bands
[index
]->ht_cap
.ampdu_factor
=
5294 IEEE80211_HT_MAX_AMPDU_64K
;
5295 bands
[index
]->ht_cap
.ampdu_density
=
5296 IEEE80211_HT_MPDU_DENSITY_16
;
5297 /* An HT shall support all EQM rates for one spatial
5300 bands
[index
]->ht_cap
.mcs
.rx_mask
[0] = 0xff;
5304 wiphy
= cfg_to_wiphy(cfg
);
5305 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = bands
[IEEE80211_BAND_2GHZ
];
5306 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = bands
[IEEE80211_BAND_5GHZ
];
5307 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
5313 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5315 return brcmf_update_wiphybands(cfg
);
5318 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5320 struct net_device
*ndev
;
5321 struct wireless_dev
*wdev
;
5322 struct brcmf_if
*ifp
;
5329 ndev
= cfg_to_ndev(cfg
);
5330 wdev
= ndev
->ieee80211_ptr
;
5331 ifp
= netdev_priv(ndev
);
5333 /* make sure RF is ready for work */
5334 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
5336 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
5337 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5339 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5340 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
5342 goto default_conf_out
;
5343 brcmf_dbg(INFO
, "power save set to %s\n",
5344 (power_mode
? "enabled" : "disabled"));
5346 err
= brcmf_dongle_roam(ifp
, (cfg
->roam_on
? 0 : 1), WL_BEACON_TIMEOUT
);
5348 goto default_conf_out
;
5349 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5352 goto default_conf_out
;
5353 err
= brcmf_dongle_probecap(cfg
);
5355 goto default_conf_out
;
5357 brcmf_configure_arp_offload(ifp
, true);
5359 cfg
->dongle_up
= true;
5366 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
5368 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5370 return brcmf_config_dongle(ifp
->drvr
->config
);
5373 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
5375 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5378 * While going down, if associated with AP disassociate
5379 * from AP to save power
5381 if (check_vif_up(ifp
->vif
)) {
5382 brcmf_link_down(ifp
->vif
);
5384 /* Make sure WPA_Supplicant receives all the event
5385 generated due to DISASSOC call to the fw to keep
5386 the state fw and WPA_Supplicant state consistent
5391 brcmf_abort_scanning(cfg
);
5392 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5397 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
5399 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5400 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5403 mutex_lock(&cfg
->usr_sync
);
5404 err
= __brcmf_cfg80211_up(ifp
);
5405 mutex_unlock(&cfg
->usr_sync
);
5410 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
5412 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5413 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5416 mutex_lock(&cfg
->usr_sync
);
5417 err
= __brcmf_cfg80211_down(ifp
);
5418 mutex_unlock(&cfg
->usr_sync
);
5423 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
5425 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
5427 return wdev
->iftype
;
5430 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
5432 struct brcmf_cfg80211_vif
*vif
;
5435 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
5436 if (test_bit(state
, &vif
->sme_state
))
5442 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
5447 mutex_lock(&event
->vif_event_lock
);
5448 evt_action
= event
->action
;
5449 mutex_unlock(&event
->vif_event_lock
);
5450 return evt_action
== action
;
5453 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
5454 struct brcmf_cfg80211_vif
*vif
)
5456 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5458 mutex_lock(&event
->vif_event_lock
);
5461 mutex_unlock(&event
->vif_event_lock
);
5464 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
5466 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5469 mutex_lock(&event
->vif_event_lock
);
5470 armed
= event
->vif
!= NULL
;
5471 mutex_unlock(&event
->vif_event_lock
);
5475 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
5476 u8 action
, ulong timeout
)
5478 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5480 return wait_event_timeout(event
->vif_wq
,
5481 vif_event_equals(event
, action
), timeout
);