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 <linux/module.h>
22 #include <net/cfg80211.h>
23 #include <net/netlink.h>
25 #include <brcmu_utils.h>
27 #include <brcmu_wifi.h>
30 #include "tracepoint.h"
31 #include "fwil_types.h"
34 #include "wl_cfg80211.h"
37 #define BRCMF_SCAN_IE_LEN_MAX 2048
38 #define BRCMF_PNO_VERSION 2
39 #define BRCMF_PNO_TIME 30
40 #define BRCMF_PNO_REPEAT 4
41 #define BRCMF_PNO_FREQ_EXPO_MAX 3
42 #define BRCMF_PNO_MAX_PFN_COUNT 16
43 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
44 #define BRCMF_PNO_HIDDEN_BIT 2
45 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
46 #define BRCMF_PNO_SCAN_COMPLETE 1
47 #define BRCMF_PNO_SCAN_INCOMPLETE 0
49 #define BRCMF_IFACE_MAX_CNT 3
51 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
52 #define WPA_OUI_TYPE 1
53 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
54 #define WME_OUI_TYPE 2
55 #define WPS_OUI_TYPE 4
57 #define VS_IE_FIXED_HDR_LEN 6
58 #define WPA_IE_VERSION_LEN 2
59 #define WPA_IE_MIN_OUI_LEN 4
60 #define WPA_IE_SUITE_COUNT_LEN 2
62 #define WPA_CIPHER_NONE 0 /* None */
63 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
64 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
65 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
66 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
68 #define RSN_AKM_NONE 0 /* None (IBSS) */
69 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
70 #define RSN_AKM_PSK 2 /* Pre-shared Key */
71 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
72 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
74 #define VNDR_IE_CMD_LEN 4 /* length of the set command
75 * string :"add", "del" (+ NUL)
77 #define VNDR_IE_COUNT_OFFSET 4
78 #define VNDR_IE_PKTFLAG_OFFSET 8
79 #define VNDR_IE_VSIE_OFFSET 12
80 #define VNDR_IE_HDR_SIZE 12
81 #define VNDR_IE_PARSE_LIMIT 5
83 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
84 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
86 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
87 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
88 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
90 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
91 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
93 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
95 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
96 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
103 #define CHAN2G(_channel, _freq, _flags) { \
104 .band = IEEE80211_BAND_2GHZ, \
105 .center_freq = (_freq), \
106 .hw_value = (_channel), \
108 .max_antenna_gain = 0, \
112 #define CHAN5G(_channel, _flags) { \
113 .band = IEEE80211_BAND_5GHZ, \
114 .center_freq = 5000 + (5 * (_channel)), \
115 .hw_value = (_channel), \
117 .max_antenna_gain = 0, \
121 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
122 #define RATETAB_ENT(_rateid, _flags) \
124 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
125 .hw_value = (_rateid), \
129 static struct ieee80211_rate __wl_rates
[] = {
130 RATETAB_ENT(BRCM_RATE_1M
, 0),
131 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
132 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
133 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
134 RATETAB_ENT(BRCM_RATE_6M
, 0),
135 RATETAB_ENT(BRCM_RATE_9M
, 0),
136 RATETAB_ENT(BRCM_RATE_12M
, 0),
137 RATETAB_ENT(BRCM_RATE_18M
, 0),
138 RATETAB_ENT(BRCM_RATE_24M
, 0),
139 RATETAB_ENT(BRCM_RATE_36M
, 0),
140 RATETAB_ENT(BRCM_RATE_48M
, 0),
141 RATETAB_ENT(BRCM_RATE_54M
, 0),
144 #define wl_a_rates (__wl_rates + 4)
145 #define wl_a_rates_size 8
146 #define wl_g_rates (__wl_rates + 0)
147 #define wl_g_rates_size 12
149 static struct ieee80211_channel __wl_2ghz_channels
[] = {
166 static struct ieee80211_channel __wl_5ghz_a_channels
[] = {
167 CHAN5G(34, 0), CHAN5G(36, 0),
168 CHAN5G(38, 0), CHAN5G(40, 0),
169 CHAN5G(42, 0), CHAN5G(44, 0),
170 CHAN5G(46, 0), CHAN5G(48, 0),
171 CHAN5G(52, 0), CHAN5G(56, 0),
172 CHAN5G(60, 0), CHAN5G(64, 0),
173 CHAN5G(100, 0), CHAN5G(104, 0),
174 CHAN5G(108, 0), CHAN5G(112, 0),
175 CHAN5G(116, 0), CHAN5G(120, 0),
176 CHAN5G(124, 0), CHAN5G(128, 0),
177 CHAN5G(132, 0), CHAN5G(136, 0),
178 CHAN5G(140, 0), CHAN5G(149, 0),
179 CHAN5G(153, 0), CHAN5G(157, 0),
180 CHAN5G(161, 0), CHAN5G(165, 0),
181 CHAN5G(184, 0), CHAN5G(188, 0),
182 CHAN5G(192, 0), CHAN5G(196, 0),
183 CHAN5G(200, 0), CHAN5G(204, 0),
184 CHAN5G(208, 0), CHAN5G(212, 0),
188 static struct ieee80211_supported_band __wl_band_2ghz
= {
189 .band
= IEEE80211_BAND_2GHZ
,
190 .channels
= __wl_2ghz_channels
,
191 .n_channels
= ARRAY_SIZE(__wl_2ghz_channels
),
192 .bitrates
= wl_g_rates
,
193 .n_bitrates
= wl_g_rates_size
,
194 .ht_cap
= {IEEE80211_HT_CAP_SUP_WIDTH_20_40
, true},
197 static struct ieee80211_supported_band __wl_band_5ghz_a
= {
198 .band
= IEEE80211_BAND_5GHZ
,
199 .channels
= __wl_5ghz_a_channels
,
200 .n_channels
= ARRAY_SIZE(__wl_5ghz_a_channels
),
201 .bitrates
= wl_a_rates
,
202 .n_bitrates
= wl_a_rates_size
,
205 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
206 * By default world regulatory domain defined in reg.c puts the flags
207 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
208 * With respect to these flags, wpa_supplicant doesn't * start p2p
209 * operations on 5GHz channels. All the changes in world regulatory
210 * domain are to be done here.
212 static const struct ieee80211_regdomain brcmf_regdom
= {
216 /* IEEE 802.11b/g, channels 1..11 */
217 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
219 /* IEEE 802.11 channel 14 - Only JP enables
220 * this and for 802.11b only
222 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
223 /* IEEE 802.11a, channel 36..64 */
224 REG_RULE(5150-10, 5350+10, 40, 6, 20, 0),
225 /* IEEE 802.11a, channel 100..165 */
226 REG_RULE(5470-10, 5850+10, 40, 6, 20, 0), }
229 static const u32 __wl_cipher_suites
[] = {
230 WLAN_CIPHER_SUITE_WEP40
,
231 WLAN_CIPHER_SUITE_WEP104
,
232 WLAN_CIPHER_SUITE_TKIP
,
233 WLAN_CIPHER_SUITE_CCMP
,
234 WLAN_CIPHER_SUITE_AES_CMAC
,
237 /* Vendor specific ie. id = 221, oui and type defines exact ie */
238 struct brcmf_vs_tlv
{
245 struct parsed_vndr_ie_info
{
247 u32 ie_len
; /* total length including id & length field */
248 struct brcmf_vs_tlv vndrie
;
251 struct parsed_vndr_ies
{
253 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
256 static int brcmf_roamoff
;
257 module_param_named(roamoff
, brcmf_roamoff
, int, S_IRUSR
);
258 MODULE_PARM_DESC(roamoff
, "do not use internal roaming engine");
260 /* Quarter dBm units to mW
261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
262 * Table is offset so the last entry is largest mW value that fits in
266 #define QDBM_OFFSET 153 /* Offset for first entry */
267 #define QDBM_TABLE_LEN 40 /* Table size */
269 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
270 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
272 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
274 /* Largest mW value that will round down to the last table entry,
275 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
276 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
277 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
279 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
281 static const u16 nqdBm_to_mW_map
[QDBM_TABLE_LEN
] = {
282 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
283 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
284 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
285 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
286 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
287 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
290 static u16
brcmf_qdbm_to_mw(u8 qdbm
)
293 int idx
= qdbm
- QDBM_OFFSET
;
295 if (idx
>= QDBM_TABLE_LEN
)
296 /* clamp to max u16 mW value */
299 /* scale the qdBm index up to the range of the table 0-40
300 * where an offset of 40 qdBm equals a factor of 10 mW.
307 /* return the mW value scaled down to the correct factor of 10,
308 * adding in factor/2 to get proper rounding.
310 return (nqdBm_to_mW_map
[idx
] + factor
/ 2) / factor
;
313 static u8
brcmf_mw_to_qdbm(u16 mw
)
320 /* handle boundary case */
324 offset
= QDBM_OFFSET
;
326 /* move mw into the range of the table */
327 while (mw_uint
< QDBM_TABLE_LOW_BOUND
) {
332 for (qdbm
= 0; qdbm
< QDBM_TABLE_LEN
- 1; qdbm
++) {
333 boundary
= nqdBm_to_mW_map
[qdbm
] + (nqdBm_to_mW_map
[qdbm
+ 1] -
334 nqdBm_to_mW_map
[qdbm
]) / 2;
335 if (mw_uint
< boundary
)
344 u16
channel_to_chanspec(struct brcmu_d11inf
*d11inf
,
345 struct ieee80211_channel
*ch
)
347 struct brcmu_chan ch_inf
;
349 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq
);
350 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
351 d11inf
->encchspec(&ch_inf
);
353 return ch_inf
.chspec
;
356 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
357 * triples, returning a pointer to the substring whose first element
360 const struct brcmf_tlv
*
361 brcmf_parse_tlvs(const void *buf
, int buflen
, uint key
)
363 const struct brcmf_tlv
*elt
= buf
;
366 /* find tagged parameter */
367 while (totlen
>= TLV_HDR_LEN
) {
370 /* validate remaining totlen */
371 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
374 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
375 totlen
-= (len
+ TLV_HDR_LEN
);
381 /* Is any of the tlvs the expected entry? If
382 * not update the tlvs buffer pointer/length.
385 brcmf_tlv_has_ie(const u8
*ie
, const u8
**tlvs
, u32
*tlvs_len
,
386 const u8
*oui
, u32 oui_len
, u8 type
)
388 /* If the contents match the OUI and the type */
389 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
390 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
391 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
397 /* point to the next ie */
398 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
399 /* calculate the length of the rest of the buffer */
400 *tlvs_len
-= (int)(ie
- *tlvs
);
401 /* update the pointer to the start of the buffer */
407 static struct brcmf_vs_tlv
*
408 brcmf_find_wpaie(const u8
*parse
, u32 len
)
410 const struct brcmf_tlv
*ie
;
412 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
413 if (brcmf_tlv_has_ie((const u8
*)ie
, &parse
, &len
,
414 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
415 return (struct brcmf_vs_tlv
*)ie
;
420 static struct brcmf_vs_tlv
*
421 brcmf_find_wpsie(const u8
*parse
, u32 len
)
423 const struct brcmf_tlv
*ie
;
425 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
426 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
427 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
428 return (struct brcmf_vs_tlv
*)ie
;
434 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
435 struct brcmf_wsec_key_le
*key_le
)
437 key_le
->index
= cpu_to_le32(key
->index
);
438 key_le
->len
= cpu_to_le32(key
->len
);
439 key_le
->algo
= cpu_to_le32(key
->algo
);
440 key_le
->flags
= cpu_to_le32(key
->flags
);
441 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
442 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
443 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
444 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
445 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
449 send_key_to_dongle(struct net_device
*ndev
, struct brcmf_wsec_key
*key
)
452 struct brcmf_wsec_key_le key_le
;
454 convert_key_from_CPU(key
, &key_le
);
456 brcmf_netdev_wait_pend8021x(ndev
);
458 err
= brcmf_fil_bsscfg_data_set(netdev_priv(ndev
), "wsec_key", &key_le
,
462 brcmf_err("wsec_key error (%d)\n", err
);
467 brcmf_configure_arp_offload(struct brcmf_if
*ifp
, bool enable
)
473 mode
= BRCMF_ARP_OL_AGENT
| BRCMF_ARP_OL_PEER_AUTO_REPLY
;
477 /* Try to set and enable ARP offload feature, this may fail, then it */
478 /* is simply not supported and err 0 will be returned */
479 err
= brcmf_fil_iovar_int_set(ifp
, "arp_ol", mode
);
481 brcmf_dbg(TRACE
, "failed to set ARP offload mode to 0x%x, err = %d\n",
485 err
= brcmf_fil_iovar_int_set(ifp
, "arpoe", enable
);
487 brcmf_dbg(TRACE
, "failed to configure (%d) ARP offload err = %d\n",
491 brcmf_dbg(TRACE
, "successfully configured (%d) ARP offload to 0x%x\n",
498 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif
*vif
)
500 enum nl80211_iftype iftype
;
502 iftype
= vif
->wdev
.iftype
;
503 return iftype
== NL80211_IFTYPE_AP
|| iftype
== NL80211_IFTYPE_P2P_GO
;
506 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
508 return vif
->wdev
.iftype
== NL80211_IFTYPE_ADHOC
;
511 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
513 enum nl80211_iftype type
,
515 struct vif_params
*params
)
517 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
519 case NL80211_IFTYPE_ADHOC
:
520 case NL80211_IFTYPE_STATION
:
521 case NL80211_IFTYPE_AP
:
522 case NL80211_IFTYPE_AP_VLAN
:
523 case NL80211_IFTYPE_WDS
:
524 case NL80211_IFTYPE_MONITOR
:
525 case NL80211_IFTYPE_MESH_POINT
:
526 return ERR_PTR(-EOPNOTSUPP
);
527 case NL80211_IFTYPE_P2P_CLIENT
:
528 case NL80211_IFTYPE_P2P_GO
:
529 case NL80211_IFTYPE_P2P_DEVICE
:
530 return brcmf_p2p_add_vif(wiphy
, name
, type
, flags
, params
);
531 case NL80211_IFTYPE_UNSPECIFIED
:
533 return ERR_PTR(-EINVAL
);
537 void brcmf_set_mpc(struct brcmf_if
*ifp
, int mpc
)
541 if (check_vif_up(ifp
->vif
)) {
542 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
544 brcmf_err("fail to set mpc\n");
547 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
551 s32
brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
552 struct brcmf_if
*ifp
, bool aborted
,
555 struct brcmf_scan_params_le params_le
;
556 struct cfg80211_scan_request
*scan_request
;
559 brcmf_dbg(SCAN
, "Enter\n");
561 /* clear scan request, because the FW abort can cause a second call */
562 /* to this functon and might cause a double cfg80211_scan_done */
563 scan_request
= cfg
->scan_request
;
564 cfg
->scan_request
= NULL
;
566 if (timer_pending(&cfg
->escan_timeout
))
567 del_timer_sync(&cfg
->escan_timeout
);
570 /* Do a scan abort to stop the driver's scan engine */
571 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
572 memset(¶ms_le
, 0, sizeof(params_le
));
573 memset(params_le
.bssid
, 0xFF, ETH_ALEN
);
574 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
575 params_le
.scan_type
= 0;
576 params_le
.channel_num
= cpu_to_le32(1);
577 params_le
.nprobes
= cpu_to_le32(1);
578 params_le
.active_time
= cpu_to_le32(-1);
579 params_le
.passive_time
= cpu_to_le32(-1);
580 params_le
.home_time
= cpu_to_le32(-1);
581 /* Scan is aborted by setting channel_list[0] to -1 */
582 params_le
.channel_list
[0] = cpu_to_le16(-1);
583 /* E-Scan (or anyother type) can be aborted by SCAN */
584 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
585 ¶ms_le
, sizeof(params_le
));
587 brcmf_err("Scan abort failed\n");
590 * e-scan can be initiated by scheduled scan
591 * which takes precedence.
593 if (cfg
->sched_escan
) {
594 brcmf_dbg(SCAN
, "scheduled scan completed\n");
595 cfg
->sched_escan
= false;
597 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
598 brcmf_set_mpc(ifp
, 1);
599 } else if (scan_request
) {
600 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
601 aborted
? "Aborted" : "Done");
602 cfg80211_scan_done(scan_request
, aborted
);
603 brcmf_set_mpc(ifp
, 1);
605 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
606 brcmf_dbg(SCAN
, "Scan complete, probably P2P scan\n");
612 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
614 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
615 struct net_device
*ndev
= wdev
->netdev
;
617 /* vif event pending in firmware */
618 if (brcmf_cfg80211_vif_event_armed(cfg
))
622 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
623 cfg
->escan_info
.ifp
== netdev_priv(ndev
))
624 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
),
627 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
630 switch (wdev
->iftype
) {
631 case NL80211_IFTYPE_ADHOC
:
632 case NL80211_IFTYPE_STATION
:
633 case NL80211_IFTYPE_AP
:
634 case NL80211_IFTYPE_AP_VLAN
:
635 case NL80211_IFTYPE_WDS
:
636 case NL80211_IFTYPE_MONITOR
:
637 case NL80211_IFTYPE_MESH_POINT
:
639 case NL80211_IFTYPE_P2P_CLIENT
:
640 case NL80211_IFTYPE_P2P_GO
:
641 case NL80211_IFTYPE_P2P_DEVICE
:
642 return brcmf_p2p_del_vif(wiphy
, wdev
);
643 case NL80211_IFTYPE_UNSPECIFIED
:
651 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
652 enum nl80211_iftype type
, u32
*flags
,
653 struct vif_params
*params
)
655 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
656 struct brcmf_if
*ifp
= netdev_priv(ndev
);
657 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
662 brcmf_dbg(TRACE
, "Enter, ndev=%p, type=%d\n", ndev
, type
);
665 case NL80211_IFTYPE_MONITOR
:
666 case NL80211_IFTYPE_WDS
:
667 brcmf_err("type (%d) : currently we do not support this type\n",
670 case NL80211_IFTYPE_ADHOC
:
673 case NL80211_IFTYPE_STATION
:
674 /* Ignore change for p2p IF. Unclear why supplicant does this */
675 if ((vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) ||
676 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
)) {
677 brcmf_dbg(TRACE
, "Ignoring cmd for p2p if\n");
678 /* WAR: It is unexpected to get a change of VIF for P2P
679 * IF, but it happens. The request can not be handled
680 * but returning EPERM causes a crash. Returning 0
681 * without setting ieee80211_ptr->iftype causes trace
682 * (WARN_ON) but it works with wpa_supplicant
688 case NL80211_IFTYPE_AP
:
689 case NL80211_IFTYPE_P2P_GO
:
698 if (type
== NL80211_IFTYPE_P2P_GO
) {
699 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
700 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
703 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &vif
->sme_state
);
704 brcmf_dbg(INFO
, "IF Type = AP\n");
707 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
709 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
713 brcmf_dbg(INFO
, "IF Type = %s\n", brcmf_is_ibssmode(vif
) ?
716 ndev
->ieee80211_ptr
->iftype
= type
;
719 brcmf_dbg(TRACE
, "Exit\n");
724 static void brcmf_escan_prep(struct brcmf_cfg80211_info
*cfg
,
725 struct brcmf_scan_params_le
*params_le
,
726 struct cfg80211_scan_request
*request
)
734 struct brcmf_ssid_le ssid_le
;
736 memset(params_le
->bssid
, 0xFF, ETH_ALEN
);
737 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
738 params_le
->scan_type
= 0;
739 params_le
->channel_num
= 0;
740 params_le
->nprobes
= cpu_to_le32(-1);
741 params_le
->active_time
= cpu_to_le32(-1);
742 params_le
->passive_time
= cpu_to_le32(-1);
743 params_le
->home_time
= cpu_to_le32(-1);
744 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
746 /* if request is null exit so it will be all channel broadcast scan */
750 n_ssids
= request
->n_ssids
;
751 n_channels
= request
->n_channels
;
752 /* Copy channel array if applicable */
753 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
755 if (n_channels
> 0) {
756 for (i
= 0; i
< n_channels
; i
++) {
757 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
758 request
->channels
[i
]);
759 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
760 request
->channels
[i
]->hw_value
, chanspec
);
761 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
764 brcmf_dbg(SCAN
, "Scanning all channels\n");
766 /* Copy ssid array if applicable */
767 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
769 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
770 n_channels
* sizeof(u16
);
771 offset
= roundup(offset
, sizeof(u32
));
772 ptr
= (char *)params_le
+ offset
;
773 for (i
= 0; i
< n_ssids
; i
++) {
774 memset(&ssid_le
, 0, sizeof(ssid_le
));
776 cpu_to_le32(request
->ssids
[i
].ssid_len
);
777 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
778 request
->ssids
[i
].ssid_len
);
779 if (!ssid_le
.SSID_len
)
780 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
782 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
783 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
784 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
785 ptr
+= sizeof(ssid_le
);
788 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
789 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
790 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
791 params_le
->ssid_le
.SSID
,
792 request
->ssids
->ssid_len
);
793 params_le
->ssid_le
.SSID_len
=
794 cpu_to_le32(request
->ssids
->ssid_len
);
795 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
796 request
->ssids
->ssid_len
);
799 /* Adding mask to channel numbers */
800 params_le
->channel_num
=
801 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
802 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
806 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
,
807 struct cfg80211_scan_request
*request
, u16 action
)
809 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
810 offsetof(struct brcmf_escan_params_le
, params_le
);
811 struct brcmf_escan_params_le
*params
;
814 brcmf_dbg(SCAN
, "E-SCAN START\n");
816 if (request
!= NULL
) {
817 /* Allocate space for populating ssids in struct */
818 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
820 /* Allocate space for populating ssids in struct */
821 params_size
+= sizeof(struct brcmf_ssid
) * request
->n_ssids
;
824 params
= kzalloc(params_size
, GFP_KERNEL
);
829 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
830 brcmf_escan_prep(cfg
, ¶ms
->params_le
, request
);
831 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
832 params
->action
= cpu_to_le16(action
);
833 params
->sync_id
= cpu_to_le16(0x1234);
835 err
= brcmf_fil_iovar_data_set(ifp
, "escan", params
, params_size
);
838 brcmf_dbg(INFO
, "system busy : escan canceled\n");
840 brcmf_err("error (%d)\n", err
);
849 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
850 struct brcmf_if
*ifp
, struct cfg80211_scan_request
*request
)
854 struct brcmf_scan_results
*results
;
855 struct escan_info
*escan
= &cfg
->escan_info
;
857 brcmf_dbg(SCAN
, "Enter\n");
859 escan
->wiphy
= wiphy
;
860 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
861 passive_scan
= cfg
->active_scan
? 0 : 1;
862 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
865 brcmf_err("error (%d)\n", err
);
868 brcmf_set_mpc(ifp
, 0);
869 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
870 results
->version
= 0;
872 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
874 err
= escan
->run(cfg
, ifp
, request
, WL_ESCAN_ACTION_START
);
876 brcmf_set_mpc(ifp
, 1);
881 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct brcmf_cfg80211_vif
*vif
,
882 struct cfg80211_scan_request
*request
,
883 struct cfg80211_ssid
*this_ssid
)
885 struct brcmf_if
*ifp
= vif
->ifp
;
886 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
887 struct cfg80211_ssid
*ssids
;
888 struct brcmf_cfg80211_scan_req
*sr
= &cfg
->scan_req_int
;
895 brcmf_dbg(SCAN
, "START ESCAN\n");
897 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
898 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
901 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
902 brcmf_err("Scanning being aborted: status (%lu)\n",
906 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
907 brcmf_err("Scanning suppressed: status (%lu)\n",
911 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
912 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
916 /* If scan req comes for p2p0, send it over primary I/F */
917 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
918 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
;
920 /* Arm scan timeout timer */
921 mod_timer(&cfg
->escan_timeout
, jiffies
+
922 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
927 ssids
= request
->ssids
;
931 /* we don't do escan in ibss */
935 cfg
->scan_request
= request
;
936 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
938 cfg
->escan_info
.run
= brcmf_run_escan
;
939 err
= brcmf_p2p_scan_prep(wiphy
, request
, vif
);
943 err
= brcmf_do_escan(cfg
, wiphy
, vif
->ifp
, request
);
947 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
948 ssids
->ssid
, ssids
->ssid_len
);
949 memset(&sr
->ssid_le
, 0, sizeof(sr
->ssid_le
));
950 SSID_len
= min_t(u8
, sizeof(sr
->ssid_le
.SSID
), ssids
->ssid_len
);
951 sr
->ssid_le
.SSID_len
= cpu_to_le32(0);
954 memcpy(sr
->ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
955 sr
->ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
958 brcmf_dbg(SCAN
, "Broadcast scan\n");
960 passive_scan
= cfg
->active_scan
? 0 : 1;
961 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
964 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
967 brcmf_set_mpc(ifp
, 0);
968 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
969 &sr
->ssid_le
, sizeof(sr
->ssid_le
));
972 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
975 brcmf_err("WLC_SCAN error (%d)\n", err
);
977 brcmf_set_mpc(ifp
, 1);
985 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
986 if (timer_pending(&cfg
->escan_timeout
))
987 del_timer_sync(&cfg
->escan_timeout
);
988 cfg
->scan_request
= NULL
;
993 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
995 struct brcmf_cfg80211_vif
*vif
;
998 brcmf_dbg(TRACE
, "Enter\n");
999 vif
= container_of(request
->wdev
, struct brcmf_cfg80211_vif
, wdev
);
1000 if (!check_vif_up(vif
))
1003 err
= brcmf_cfg80211_escan(wiphy
, vif
, request
, NULL
);
1006 brcmf_err("scan error (%d)\n", err
);
1008 brcmf_dbg(TRACE
, "Exit\n");
1012 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1016 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1019 brcmf_err("Error (%d)\n", err
);
1024 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1028 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1031 brcmf_err("Error (%d)\n", err
);
1036 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1039 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1041 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1043 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1049 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1051 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1052 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1053 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1056 brcmf_dbg(TRACE
, "Enter\n");
1057 if (!check_vif_up(ifp
->vif
))
1060 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1061 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1062 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1063 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1067 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1068 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1069 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1070 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1074 if (changed
& WIPHY_PARAM_RETRY_LONG
1075 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1076 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1077 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1081 if (changed
& WIPHY_PARAM_RETRY_SHORT
1082 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1083 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1084 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1090 brcmf_dbg(TRACE
, "Exit\n");
1094 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1096 memset(prof
, 0, sizeof(*prof
));
1099 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
)
1101 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(vif
->wdev
.wiphy
);
1104 brcmf_dbg(TRACE
, "Enter\n");
1106 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1107 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1108 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1109 BRCMF_C_DISASSOC
, NULL
, 0);
1111 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1113 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
);
1114 cfg80211_disconnected(vif
->wdev
.netdev
, 0, NULL
, 0, GFP_KERNEL
);
1117 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1118 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
1119 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
1120 brcmf_dbg(TRACE
, "Exit\n");
1124 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1125 struct cfg80211_ibss_params
*params
)
1127 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1128 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1129 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1130 struct brcmf_join_params join_params
;
1131 size_t join_params_size
= 0;
1137 brcmf_dbg(TRACE
, "Enter\n");
1138 if (!check_vif_up(ifp
->vif
))
1142 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1144 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1148 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1151 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1153 brcmf_dbg(CONN
, "No BSSID specified\n");
1155 if (params
->chandef
.chan
)
1156 brcmf_dbg(CONN
, "channel: %d\n",
1157 params
->chandef
.chan
->center_freq
);
1159 brcmf_dbg(CONN
, "no channel specified\n");
1161 if (params
->channel_fixed
)
1162 brcmf_dbg(CONN
, "fixed channel required\n");
1164 brcmf_dbg(CONN
, "no fixed channel required\n");
1166 if (params
->ie
&& params
->ie_len
)
1167 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1169 brcmf_dbg(CONN
, "no ie specified\n");
1171 if (params
->beacon_interval
)
1172 brcmf_dbg(CONN
, "beacon interval: %d\n",
1173 params
->beacon_interval
);
1175 brcmf_dbg(CONN
, "no beacon interval specified\n");
1177 if (params
->basic_rates
)
1178 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1180 brcmf_dbg(CONN
, "no basic rates specified\n");
1182 if (params
->privacy
)
1183 brcmf_dbg(CONN
, "privacy required\n");
1185 brcmf_dbg(CONN
, "no privacy required\n");
1187 /* Configure Privacy for starter */
1188 if (params
->privacy
)
1189 wsec
|= WEP_ENABLED
;
1191 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1193 brcmf_err("wsec failed (%d)\n", err
);
1197 /* Configure Beacon Interval for starter */
1198 if (params
->beacon_interval
)
1199 bcnprd
= params
->beacon_interval
;
1203 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1205 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1209 /* Configure required join parameter */
1210 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1213 profile
->ssid
.SSID_len
= min_t(u32
, params
->ssid_len
, 32);
1214 memcpy(profile
->ssid
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1215 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, profile
->ssid
.SSID_len
);
1216 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1217 join_params_size
= sizeof(join_params
.ssid_le
);
1220 if (params
->bssid
) {
1221 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1222 join_params_size
= sizeof(join_params
.ssid_le
) +
1223 BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1224 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1226 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1227 memset(profile
->bssid
, 0, ETH_ALEN
);
1231 if (params
->chandef
.chan
) {
1235 ieee80211_frequency_to_channel(
1236 params
->chandef
.chan
->center_freq
);
1237 if (params
->channel_fixed
) {
1238 /* adding chanspec */
1239 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
1240 params
->chandef
.chan
);
1241 join_params
.params_le
.chanspec_list
[0] =
1242 cpu_to_le16(chanspec
);
1243 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1244 join_params_size
+= sizeof(join_params
.params_le
);
1247 /* set channel for starter */
1248 target_channel
= cfg
->channel
;
1249 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1252 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1258 cfg
->ibss_starter
= false;
1261 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1262 &join_params
, join_params_size
);
1264 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1270 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1271 brcmf_dbg(TRACE
, "Exit\n");
1276 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1278 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1281 brcmf_dbg(TRACE
, "Enter\n");
1282 if (!check_vif_up(ifp
->vif
))
1285 brcmf_link_down(ifp
->vif
);
1287 brcmf_dbg(TRACE
, "Exit\n");
1292 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1293 struct cfg80211_connect_params
*sme
)
1295 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1296 struct brcmf_cfg80211_security
*sec
;
1300 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1301 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1302 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1303 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1305 val
= WPA_AUTH_DISABLED
;
1306 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1307 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1309 brcmf_err("set wpa_auth failed (%d)\n", err
);
1312 sec
= &profile
->sec
;
1313 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1317 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1318 struct cfg80211_connect_params
*sme
)
1320 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1321 struct brcmf_cfg80211_security
*sec
;
1325 switch (sme
->auth_type
) {
1326 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1328 brcmf_dbg(CONN
, "open system\n");
1330 case NL80211_AUTHTYPE_SHARED_KEY
:
1332 brcmf_dbg(CONN
, "shared key\n");
1334 case NL80211_AUTHTYPE_AUTOMATIC
:
1336 brcmf_dbg(CONN
, "automatic\n");
1338 case NL80211_AUTHTYPE_NETWORK_EAP
:
1339 brcmf_dbg(CONN
, "network eap\n");
1342 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1346 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1348 brcmf_err("set auth failed (%d)\n", err
);
1351 sec
= &profile
->sec
;
1352 sec
->auth_type
= sme
->auth_type
;
1357 brcmf_set_wsec_mode(struct net_device
*ndev
,
1358 struct cfg80211_connect_params
*sme
, bool mfp
)
1360 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1361 struct brcmf_cfg80211_security
*sec
;
1367 if (sme
->crypto
.n_ciphers_pairwise
) {
1368 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1369 case WLAN_CIPHER_SUITE_WEP40
:
1370 case WLAN_CIPHER_SUITE_WEP104
:
1373 case WLAN_CIPHER_SUITE_TKIP
:
1374 pval
= TKIP_ENABLED
;
1376 case WLAN_CIPHER_SUITE_CCMP
:
1379 case WLAN_CIPHER_SUITE_AES_CMAC
:
1383 brcmf_err("invalid cipher pairwise (%d)\n",
1384 sme
->crypto
.ciphers_pairwise
[0]);
1388 if (sme
->crypto
.cipher_group
) {
1389 switch (sme
->crypto
.cipher_group
) {
1390 case WLAN_CIPHER_SUITE_WEP40
:
1391 case WLAN_CIPHER_SUITE_WEP104
:
1394 case WLAN_CIPHER_SUITE_TKIP
:
1395 gval
= TKIP_ENABLED
;
1397 case WLAN_CIPHER_SUITE_CCMP
:
1400 case WLAN_CIPHER_SUITE_AES_CMAC
:
1404 brcmf_err("invalid cipher group (%d)\n",
1405 sme
->crypto
.cipher_group
);
1410 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1411 /* In case of privacy, but no security and WPS then simulate */
1412 /* setting AES. WPS-2.0 allows no security */
1413 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1418 wsec
= pval
| gval
| MFP_CAPABLE
;
1421 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", wsec
);
1423 brcmf_err("error (%d)\n", err
);
1427 sec
= &profile
->sec
;
1428 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1429 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1435 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1437 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1438 struct brcmf_cfg80211_security
*sec
;
1442 if (sme
->crypto
.n_akm_suites
) {
1443 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
),
1446 brcmf_err("could not get wpa_auth (%d)\n", err
);
1449 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1450 switch (sme
->crypto
.akm_suites
[0]) {
1451 case WLAN_AKM_SUITE_8021X
:
1452 val
= WPA_AUTH_UNSPECIFIED
;
1454 case WLAN_AKM_SUITE_PSK
:
1458 brcmf_err("invalid cipher group (%d)\n",
1459 sme
->crypto
.cipher_group
);
1462 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1463 switch (sme
->crypto
.akm_suites
[0]) {
1464 case WLAN_AKM_SUITE_8021X
:
1465 val
= WPA2_AUTH_UNSPECIFIED
;
1467 case WLAN_AKM_SUITE_PSK
:
1468 val
= WPA2_AUTH_PSK
;
1471 brcmf_err("invalid cipher group (%d)\n",
1472 sme
->crypto
.cipher_group
);
1477 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1478 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
),
1481 brcmf_err("could not set wpa_auth (%d)\n", err
);
1485 sec
= &profile
->sec
;
1486 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1492 brcmf_set_sharedkey(struct net_device
*ndev
,
1493 struct cfg80211_connect_params
*sme
)
1495 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1496 struct brcmf_cfg80211_security
*sec
;
1497 struct brcmf_wsec_key key
;
1501 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1503 if (sme
->key_len
== 0)
1506 sec
= &profile
->sec
;
1507 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1508 sec
->wpa_versions
, sec
->cipher_pairwise
);
1510 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1513 if (!(sec
->cipher_pairwise
&
1514 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1517 memset(&key
, 0, sizeof(key
));
1518 key
.len
= (u32
) sme
->key_len
;
1519 key
.index
= (u32
) sme
->key_idx
;
1520 if (key
.len
> sizeof(key
.data
)) {
1521 brcmf_err("Too long key length (%u)\n", key
.len
);
1524 memcpy(key
.data
, sme
->key
, key
.len
);
1525 key
.flags
= BRCMF_PRIMARY_KEY
;
1526 switch (sec
->cipher_pairwise
) {
1527 case WLAN_CIPHER_SUITE_WEP40
:
1528 key
.algo
= CRYPTO_ALGO_WEP1
;
1530 case WLAN_CIPHER_SUITE_WEP104
:
1531 key
.algo
= CRYPTO_ALGO_WEP128
;
1534 brcmf_err("Invalid algorithm (%d)\n",
1535 sme
->crypto
.ciphers_pairwise
[0]);
1538 /* Set the new key/index */
1539 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1540 key
.len
, key
.index
, key
.algo
);
1541 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1542 err
= send_key_to_dongle(ndev
, &key
);
1546 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1547 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1548 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1549 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1551 brcmf_err("set auth failed (%d)\n", err
);
1557 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1558 enum nl80211_auth_type type
)
1561 if (type
== NL80211_AUTHTYPE_AUTOMATIC
) {
1562 /* shift to ignore chip revision */
1563 ci
= brcmf_get_chip_info(ifp
) >> 4;
1566 brcmf_dbg(CONN
, "43236 WAR: use OPEN instead of AUTO\n");
1567 return NL80211_AUTHTYPE_OPEN_SYSTEM
;
1576 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1577 struct cfg80211_connect_params
*sme
)
1579 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1580 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1581 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1582 struct ieee80211_channel
*chan
= sme
->channel
;
1583 struct brcmf_join_params join_params
;
1584 size_t join_params_size
;
1585 const struct brcmf_tlv
*rsn_ie
;
1586 const struct brcmf_vs_tlv
*wpa_ie
;
1589 struct brcmf_ext_join_params_le
*ext_join_params
;
1593 brcmf_dbg(TRACE
, "Enter\n");
1594 if (!check_vif_up(ifp
->vif
))
1598 brcmf_err("Invalid ssid\n");
1602 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1603 /* A normal (non P2P) connection request setup. */
1606 /* find the WPA_IE */
1607 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1610 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1612 /* find the RSN_IE */
1613 rsn_ie
= brcmf_parse_tlvs((const u8
*)sme
->ie
,
1618 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1621 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1624 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1625 sme
->ie
, sme
->ie_len
);
1627 brcmf_err("Set Assoc REQ IE Failed\n");
1629 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1631 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1635 ieee80211_frequency_to_channel(chan
->center_freq
);
1636 chanspec
= channel_to_chanspec(&cfg
->d11inf
, chan
);
1637 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1638 cfg
->channel
, chan
->center_freq
, chanspec
);
1644 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1646 err
= brcmf_set_wpa_version(ndev
, sme
);
1648 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1652 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1653 err
= brcmf_set_auth_type(ndev
, sme
);
1655 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1659 err
= brcmf_set_wsec_mode(ndev
, sme
, sme
->mfp
== NL80211_MFP_REQUIRED
);
1661 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1665 err
= brcmf_set_key_mgmt(ndev
, sme
);
1667 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1671 err
= brcmf_set_sharedkey(ndev
, sme
);
1673 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1677 profile
->ssid
.SSID_len
= min_t(u32
, (u32
)sizeof(profile
->ssid
.SSID
),
1678 (u32
)sme
->ssid_len
);
1679 memcpy(&profile
->ssid
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1680 if (profile
->ssid
.SSID_len
< IEEE80211_MAX_SSID_LEN
) {
1681 profile
->ssid
.SSID
[profile
->ssid
.SSID_len
] = 0;
1682 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n", profile
->ssid
.SSID
,
1683 profile
->ssid
.SSID_len
);
1686 /* Join with specific BSSID and cached SSID
1687 * If SSID is zero join based on BSSID only
1689 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1690 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1692 join_params_size
+= sizeof(u16
);
1693 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1694 if (ext_join_params
== NULL
) {
1698 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1699 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
,
1700 profile
->ssid
.SSID_len
);
1702 /* Set up join scan parameters */
1703 ext_join_params
->scan_le
.scan_type
= -1;
1704 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1707 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1709 memset(&ext_join_params
->assoc_le
.bssid
, 0xFF, ETH_ALEN
);
1712 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1714 ext_join_params
->assoc_le
.chanspec_list
[0] =
1715 cpu_to_le16(chanspec
);
1716 /* Increase dwell time to receive probe response or detect
1717 * beacon from target AP at a noisy air only during connect
1720 ext_join_params
->scan_le
.active_time
=
1721 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1722 ext_join_params
->scan_le
.passive_time
=
1723 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
1724 /* To sync with presence period of VSDB GO send probe request
1725 * more frequently. Probe request will be stopped when it gets
1726 * probe response from target AP/GO.
1728 ext_join_params
->scan_le
.nprobes
=
1729 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
1730 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
1732 ext_join_params
->scan_le
.active_time
= cpu_to_le32(-1);
1733 ext_join_params
->scan_le
.passive_time
= cpu_to_le32(-1);
1734 ext_join_params
->scan_le
.nprobes
= cpu_to_le32(-1);
1737 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
1739 kfree(ext_join_params
);
1741 /* This is it. join command worked, we are done */
1744 /* join command failed, fallback to set ssid */
1745 memset(&join_params
, 0, sizeof(join_params
));
1746 join_params_size
= sizeof(join_params
.ssid_le
);
1748 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, profile
->ssid
.SSID_len
);
1749 join_params
.ssid_le
.SSID_len
= cpu_to_le32(profile
->ssid
.SSID_len
);
1752 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1754 memset(join_params
.params_le
.bssid
, 0xFF, ETH_ALEN
);
1757 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1758 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1759 join_params_size
+= sizeof(join_params
.params_le
);
1761 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1762 &join_params
, join_params_size
);
1764 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
1768 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1769 brcmf_dbg(TRACE
, "Exit\n");
1774 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1777 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1778 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1779 struct brcmf_scb_val_le scbval
;
1782 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1783 if (!check_vif_up(ifp
->vif
))
1786 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1787 cfg80211_disconnected(ndev
, reason_code
, NULL
, 0, GFP_KERNEL
);
1789 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1790 scbval
.val
= cpu_to_le32(reason_code
);
1791 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1792 &scbval
, sizeof(scbval
));
1794 brcmf_err("error (%d)\n", err
);
1796 brcmf_dbg(TRACE
, "Exit\n");
1801 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1802 enum nl80211_tx_power_setting type
, s32 mbm
)
1805 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1806 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1807 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1811 s32 dbm
= MBM_TO_DBM(mbm
);
1813 brcmf_dbg(TRACE
, "Enter\n");
1814 if (!check_vif_up(ifp
->vif
))
1818 case NL80211_TX_POWER_AUTOMATIC
:
1820 case NL80211_TX_POWER_LIMITED
:
1821 case NL80211_TX_POWER_FIXED
:
1823 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1829 /* Make sure radio is off or on as far as software is concerned */
1830 disable
= WL_RADIO_SW_DISABLE
<< 16;
1831 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
1833 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
1838 txpwrmw
= (u16
) dbm
;
1839 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower",
1840 (s32
)brcmf_mw_to_qdbm(txpwrmw
));
1842 brcmf_err("qtxpower error (%d)\n", err
);
1843 cfg
->conf
->tx_power
= dbm
;
1846 brcmf_dbg(TRACE
, "Exit\n");
1850 static s32
brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
,
1851 struct wireless_dev
*wdev
,
1854 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1855 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
1860 brcmf_dbg(TRACE
, "Enter\n");
1861 if (!check_vif_up(ifp
->vif
))
1864 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &txpwrdbm
);
1866 brcmf_err("error (%d)\n", err
);
1870 result
= (u8
) (txpwrdbm
& ~WL_TXPWR_OVERRIDE
);
1871 *dbm
= (s32
) brcmf_qdbm_to_mw(result
);
1874 brcmf_dbg(TRACE
, "Exit\n");
1879 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1880 u8 key_idx
, bool unicast
, bool multicast
)
1882 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1887 brcmf_dbg(TRACE
, "Enter\n");
1888 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
1889 if (!check_vif_up(ifp
->vif
))
1892 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
1894 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
1898 if (wsec
& WEP_ENABLED
) {
1899 /* Just select a new current key */
1901 err
= brcmf_fil_cmd_int_set(ifp
,
1902 BRCMF_C_SET_KEY_PRIMARY
, index
);
1904 brcmf_err("error (%d)\n", err
);
1907 brcmf_dbg(TRACE
, "Exit\n");
1912 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
1913 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
1915 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1916 struct brcmf_wsec_key key
;
1920 memset(&key
, 0, sizeof(key
));
1921 key
.index
= (u32
) key_idx
;
1922 /* Instead of bcast for ea address for default wep keys,
1923 driver needs it to be Null */
1924 if (!is_multicast_ether_addr(mac_addr
))
1925 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
1926 key
.len
= (u32
) params
->key_len
;
1927 /* check for key index change */
1930 err
= send_key_to_dongle(ndev
, &key
);
1932 brcmf_err("key delete error (%d)\n", err
);
1934 if (key
.len
> sizeof(key
.data
)) {
1935 brcmf_err("Invalid key length (%d)\n", key
.len
);
1939 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
1940 memcpy(key
.data
, params
->key
, key
.len
);
1942 if (!brcmf_is_apmode(ifp
->vif
) &&
1943 (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)) {
1944 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
1945 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
1946 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
1947 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
1950 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1951 if (params
->seq
&& params
->seq_len
== 6) {
1954 ivptr
= (u8
*) params
->seq
;
1955 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
1956 (ivptr
[3] << 8) | ivptr
[2];
1957 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
1958 key
.iv_initialized
= true;
1961 switch (params
->cipher
) {
1962 case WLAN_CIPHER_SUITE_WEP40
:
1963 key
.algo
= CRYPTO_ALGO_WEP1
;
1964 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
1966 case WLAN_CIPHER_SUITE_WEP104
:
1967 key
.algo
= CRYPTO_ALGO_WEP128
;
1968 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
1970 case WLAN_CIPHER_SUITE_TKIP
:
1971 key
.algo
= CRYPTO_ALGO_TKIP
;
1972 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
1974 case WLAN_CIPHER_SUITE_AES_CMAC
:
1975 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1976 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1978 case WLAN_CIPHER_SUITE_CCMP
:
1979 key
.algo
= CRYPTO_ALGO_AES_CCM
;
1980 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
1983 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
1986 err
= send_key_to_dongle(ndev
, &key
);
1988 brcmf_err("wsec_key error (%d)\n", err
);
1994 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
1995 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
1996 struct key_params
*params
)
1998 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1999 struct brcmf_wsec_key key
;
2005 brcmf_dbg(TRACE
, "Enter\n");
2006 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2007 if (!check_vif_up(ifp
->vif
))
2011 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP40
) &&
2012 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP104
)) {
2013 brcmf_dbg(TRACE
, "Exit");
2014 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
2016 memset(&key
, 0, sizeof(key
));
2018 key
.len
= (u32
) params
->key_len
;
2019 key
.index
= (u32
) key_idx
;
2021 if (key
.len
> sizeof(key
.data
)) {
2022 brcmf_err("Too long key length (%u)\n", key
.len
);
2026 memcpy(key
.data
, params
->key
, key
.len
);
2028 key
.flags
= BRCMF_PRIMARY_KEY
;
2029 switch (params
->cipher
) {
2030 case WLAN_CIPHER_SUITE_WEP40
:
2031 key
.algo
= CRYPTO_ALGO_WEP1
;
2033 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2035 case WLAN_CIPHER_SUITE_WEP104
:
2036 key
.algo
= CRYPTO_ALGO_WEP128
;
2038 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2040 case WLAN_CIPHER_SUITE_TKIP
:
2041 if (!brcmf_is_apmode(ifp
->vif
)) {
2042 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2043 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2044 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2045 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2047 key
.algo
= CRYPTO_ALGO_TKIP
;
2049 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2051 case WLAN_CIPHER_SUITE_AES_CMAC
:
2052 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2054 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2056 case WLAN_CIPHER_SUITE_CCMP
:
2057 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2059 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2062 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2067 err
= send_key_to_dongle(ndev
, &key
);
2071 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2073 brcmf_err("get wsec error (%d)\n", err
);
2077 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2079 brcmf_err("set wsec error (%d)\n", err
);
2084 brcmf_dbg(TRACE
, "Exit\n");
2089 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2090 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2092 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2093 struct brcmf_wsec_key key
;
2096 brcmf_dbg(TRACE
, "Enter\n");
2097 if (!check_vif_up(ifp
->vif
))
2100 if (key_idx
>= DOT11_MAX_DEFAULT_KEYS
) {
2101 /* we ignore this key index in this case */
2102 brcmf_err("invalid key index (%d)\n", key_idx
);
2106 memset(&key
, 0, sizeof(key
));
2108 key
.index
= (u32
) key_idx
;
2109 key
.flags
= BRCMF_PRIMARY_KEY
;
2110 key
.algo
= CRYPTO_ALGO_OFF
;
2112 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2114 /* Set the new key/index */
2115 err
= send_key_to_dongle(ndev
, &key
);
2117 brcmf_dbg(TRACE
, "Exit\n");
2122 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2123 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2124 void (*callback
) (void *cookie
, struct key_params
* params
))
2126 struct key_params params
;
2127 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2128 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2129 struct brcmf_cfg80211_security
*sec
;
2133 brcmf_dbg(TRACE
, "Enter\n");
2134 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2135 if (!check_vif_up(ifp
->vif
))
2138 memset(¶ms
, 0, sizeof(params
));
2140 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2142 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2143 /* Ignore this error, may happen during DISASSOC */
2147 if (wsec
& WEP_ENABLED
) {
2148 sec
= &profile
->sec
;
2149 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2150 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2151 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2152 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2153 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2154 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2156 } else if (wsec
& TKIP_ENABLED
) {
2157 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2158 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2159 } else if (wsec
& AES_ENABLED
) {
2160 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2161 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2163 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2167 callback(cookie
, ¶ms
);
2170 brcmf_dbg(TRACE
, "Exit\n");
2175 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2176 struct net_device
*ndev
, u8 key_idx
)
2178 brcmf_dbg(INFO
, "Not supported\n");
2184 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2185 u8
*mac
, struct station_info
*sinfo
)
2187 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2188 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2189 struct brcmf_scb_val_le scb_val
;
2193 u8
*bssid
= profile
->bssid
;
2194 struct brcmf_sta_info_le sta_info_le
;
2198 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2199 if (!check_vif_up(ifp
->vif
))
2202 if (brcmf_is_apmode(ifp
->vif
)) {
2203 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2204 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2206 sizeof(sta_info_le
));
2208 brcmf_err("GET STA INFO failed, %d\n", err
);
2211 sinfo
->filled
= STATION_INFO_INACTIVE_TIME
;
2212 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2213 if (le32_to_cpu(sta_info_le
.flags
) & BRCMF_STA_ASSOC
) {
2214 sinfo
->filled
|= STATION_INFO_CONNECTED_TIME
;
2215 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2217 brcmf_dbg(TRACE
, "STA idle time : %d ms, connected time :%d sec\n",
2218 sinfo
->inactive_time
, sinfo
->connected_time
);
2219 } else if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_STATION
) {
2220 if (memcmp(mac
, bssid
, ETH_ALEN
)) {
2221 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2226 /* Report the current tx rate */
2227 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2229 brcmf_err("Could not get rate (%d)\n", err
);
2232 sinfo
->filled
|= STATION_INFO_TX_BITRATE
;
2233 sinfo
->txrate
.legacy
= rate
* 5;
2234 brcmf_dbg(CONN
, "Rate %d Mbps\n", rate
/ 2);
2237 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2238 &ifp
->vif
->sme_state
)) {
2239 memset(&scb_val
, 0, sizeof(scb_val
));
2240 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2241 &scb_val
, sizeof(scb_val
));
2243 brcmf_err("Could not get rssi (%d)\n", err
);
2246 rssi
= le32_to_cpu(scb_val
.val
);
2247 sinfo
->filled
|= STATION_INFO_SIGNAL
;
2248 sinfo
->signal
= rssi
;
2249 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2251 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_BCNPRD
,
2254 brcmf_err("Could not get beacon period (%d)\n",
2258 sinfo
->bss_param
.beacon_interval
=
2260 brcmf_dbg(CONN
, "Beacon peroid %d\n",
2263 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_DTIMPRD
,
2266 brcmf_err("Could not get DTIM period (%d)\n",
2270 sinfo
->bss_param
.dtim_period
= dtim_period
;
2271 brcmf_dbg(CONN
, "DTIM peroid %d\n",
2274 sinfo
->filled
|= STATION_INFO_BSS_PARAM
;
2279 brcmf_dbg(TRACE
, "Exit\n");
2284 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2285 bool enabled
, s32 timeout
)
2289 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2290 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2292 brcmf_dbg(TRACE
, "Enter\n");
2295 * Powersave enable/disable request is coming from the
2296 * cfg80211 even before the interface is up. In that
2297 * scenario, driver will be storing the power save
2298 * preference in cfg struct to apply this to
2299 * FW later while initializing the dongle
2301 cfg
->pwr_save
= enabled
;
2302 if (!check_vif_up(ifp
->vif
)) {
2304 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2308 pm
= enabled
? PM_FAST
: PM_OFF
;
2309 /* Do not enable the power save after assoc if it is a p2p interface */
2310 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2311 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2314 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2316 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2319 brcmf_err("net_device is not ready yet\n");
2321 brcmf_err("error (%d)\n", err
);
2324 brcmf_dbg(TRACE
, "Exit\n");
2328 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2329 struct brcmf_bss_info_le
*bi
)
2331 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2332 struct ieee80211_channel
*notify_channel
;
2333 struct cfg80211_bss
*bss
;
2334 struct ieee80211_supported_band
*band
;
2335 struct brcmu_chan ch
;
2339 u16 notify_capability
;
2340 u16 notify_interval
;
2342 size_t notify_ielen
;
2345 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2346 brcmf_err("Bss info is larger than buffer. Discarding\n");
2351 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2352 cfg
->d11inf
.decchspec(&ch
);
2353 bi
->ctl_ch
= ch
.chnum
;
2355 channel
= bi
->ctl_ch
;
2357 if (channel
<= CH_MAX_2G_CHANNEL
)
2358 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2360 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2362 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2363 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2365 notify_capability
= le16_to_cpu(bi
->capability
);
2366 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2367 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2368 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2369 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2371 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2372 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2373 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2374 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2375 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2377 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, (const u8
*)bi
->BSSID
,
2378 0, notify_capability
, notify_interval
, notify_ie
,
2379 notify_ielen
, notify_signal
, GFP_KERNEL
);
2384 cfg80211_put_bss(wiphy
, bss
);
2389 static struct brcmf_bss_info_le
*
2390 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2393 return list
->bss_info_le
;
2394 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2395 le32_to_cpu(bss
->length
));
2398 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2400 struct brcmf_scan_results
*bss_list
;
2401 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2405 bss_list
= cfg
->bss_list
;
2406 if (bss_list
->count
!= 0 &&
2407 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2408 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2412 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2413 for (i
= 0; i
< bss_list
->count
; i
++) {
2414 bi
= next_bss_le(bss_list
, bi
);
2415 err
= brcmf_inform_single_bss(cfg
, bi
);
2422 static s32
wl_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2423 struct net_device
*ndev
, const u8
*bssid
)
2425 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2426 struct ieee80211_channel
*notify_channel
;
2427 struct brcmf_bss_info_le
*bi
= NULL
;
2428 struct ieee80211_supported_band
*band
;
2429 struct cfg80211_bss
*bss
;
2430 struct brcmu_chan ch
;
2434 u16 notify_capability
;
2435 u16 notify_interval
;
2437 size_t notify_ielen
;
2440 brcmf_dbg(TRACE
, "Enter\n");
2442 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2448 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2450 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2451 buf
, WL_BSS_INFO_MAX
);
2453 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2457 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2459 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2460 cfg
->d11inf
.decchspec(&ch
);
2462 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2463 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2465 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2467 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2468 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2470 notify_capability
= le16_to_cpu(bi
->capability
);
2471 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2472 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2473 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2474 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2476 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2477 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2478 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2479 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2481 bss
= cfg80211_inform_bss(wiphy
, notify_channel
, bssid
,
2482 0, notify_capability
, notify_interval
,
2483 notify_ie
, notify_ielen
, notify_signal
, GFP_KERNEL
);
2490 cfg80211_put_bss(wiphy
, bss
);
2496 brcmf_dbg(TRACE
, "Exit\n");
2501 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2502 struct brcmf_if
*ifp
)
2504 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ifp
->ndev
);
2505 struct brcmf_bss_info_le
*bi
;
2506 struct brcmf_ssid
*ssid
;
2507 const struct brcmf_tlv
*tim
;
2508 u16 beacon_interval
;
2514 brcmf_dbg(TRACE
, "Enter\n");
2515 if (brcmf_is_ibssmode(ifp
->vif
))
2518 ssid
= &profile
->ssid
;
2520 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2521 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2522 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2524 brcmf_err("Could not get bss info %d\n", err
);
2525 goto update_bss_info_out
;
2528 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2529 err
= brcmf_inform_single_bss(cfg
, bi
);
2531 goto update_bss_info_out
;
2533 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2534 ie_len
= le32_to_cpu(bi
->ie_length
);
2535 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2537 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2539 dtim_period
= tim
->data
[1];
2542 * active scan was done so we could not get dtim
2543 * information out of probe response.
2544 * so we speficially query dtim information to dongle.
2547 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2549 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2550 goto update_bss_info_out
;
2552 dtim_period
= (u8
)var
;
2555 update_bss_info_out
:
2556 brcmf_dbg(TRACE
, "Exit");
2560 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2562 struct escan_info
*escan
= &cfg
->escan_info
;
2564 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2565 if (cfg
->scan_request
) {
2566 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2567 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2569 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2570 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2573 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2575 struct brcmf_cfg80211_info
*cfg
=
2576 container_of(work
, struct brcmf_cfg80211_info
,
2577 escan_timeout_work
);
2579 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2582 static void brcmf_escan_timeout(unsigned long data
)
2584 struct brcmf_cfg80211_info
*cfg
=
2585 (struct brcmf_cfg80211_info
*)data
;
2587 if (cfg
->scan_request
) {
2588 brcmf_err("timer expired\n");
2589 schedule_work(&cfg
->escan_timeout_work
);
2594 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2595 struct brcmf_bss_info_le
*bss
,
2596 struct brcmf_bss_info_le
*bss_info_le
)
2598 struct brcmu_chan ch_bss
, ch_bss_info_le
;
2600 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
2601 cfg
->d11inf
.decchspec(&ch_bss
);
2602 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
2603 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
2605 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2606 ch_bss
.band
== ch_bss_info_le
.band
&&
2607 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2608 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2609 if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) ==
2610 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
)) {
2611 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2612 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2614 /* preserve max RSSI if the measurements are
2615 * both on-channel or both off-channel
2617 if (bss_info_rssi
> bss_rssi
)
2618 bss
->RSSI
= bss_info_le
->RSSI
;
2619 } else if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) &&
2620 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) == 0) {
2621 /* preserve the on-channel rssi measurement
2622 * if the new measurement is off channel
2624 bss
->RSSI
= bss_info_le
->RSSI
;
2625 bss
->flags
|= BRCMF_BSS_RSSI_ON_CHANNEL
;
2633 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2634 const struct brcmf_event_msg
*e
, void *data
)
2636 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2639 struct brcmf_escan_result_le
*escan_result_le
;
2640 struct brcmf_bss_info_le
*bss_info_le
;
2641 struct brcmf_bss_info_le
*bss
= NULL
;
2643 struct brcmf_scan_results
*list
;
2649 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2650 brcmf_err("scan not ready, bssidx=%d\n", ifp
->bssidx
);
2654 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2655 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2656 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2657 if (!escan_result_le
) {
2658 brcmf_err("Invalid escan result (NULL pointer)\n");
2661 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
2662 brcmf_err("Invalid bss_count %d: ignoring\n",
2663 escan_result_le
->bss_count
);
2666 bss_info_le
= &escan_result_le
->bss_info_le
;
2668 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
2671 if (!cfg
->scan_request
) {
2672 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
2676 bi_length
= le32_to_cpu(bss_info_le
->length
);
2677 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
2678 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
2679 brcmf_err("Invalid bss_info length %d: ignoring\n",
2684 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
2685 BIT(NL80211_IFTYPE_ADHOC
))) {
2686 if (le16_to_cpu(bss_info_le
->capability
) &
2687 WLAN_CAPABILITY_IBSS
) {
2688 brcmf_err("Ignoring IBSS result\n");
2693 list
= (struct brcmf_scan_results
*)
2694 cfg
->escan_info
.escan_buf
;
2695 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
2696 brcmf_err("Buffer is too small: ignoring\n");
2700 for (i
= 0; i
< list
->count
; i
++) {
2701 bss
= bss
? (struct brcmf_bss_info_le
*)
2702 ((unsigned char *)bss
+
2703 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
2704 if (brcmf_compare_update_same_bss(cfg
, bss
,
2708 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
2709 bss_info_le
, bi_length
);
2710 list
->version
= le32_to_cpu(bss_info_le
->version
);
2711 list
->buflen
+= bi_length
;
2714 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2715 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
2717 if (cfg
->scan_request
) {
2718 cfg
->bss_list
= (struct brcmf_scan_results
*)
2719 cfg
->escan_info
.escan_buf
;
2720 brcmf_inform_bss(cfg
);
2721 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
2722 brcmf_notify_escan_complete(cfg
, ifp
, aborted
,
2725 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
2732 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
2734 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
2735 brcmf_cfg80211_escan_handler
);
2736 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
2737 /* Init scan_timeout timer */
2738 init_timer(&cfg
->escan_timeout
);
2739 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
2740 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
2741 INIT_WORK(&cfg
->escan_timeout_work
,
2742 brcmf_cfg80211_escan_timeout_worker
);
2745 static __always_inline
void brcmf_delay(u32 ms
)
2747 if (ms
< 1000 / HZ
) {
2755 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
2757 brcmf_dbg(TRACE
, "Enter\n");
2762 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
2763 struct cfg80211_wowlan
*wow
)
2765 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2766 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2767 struct brcmf_cfg80211_vif
*vif
;
2769 brcmf_dbg(TRACE
, "Enter\n");
2772 * if the primary net_device is not READY there is nothing
2773 * we can do but pray resume goes smoothly.
2775 vif
= ((struct brcmf_if
*)netdev_priv(ndev
))->vif
;
2776 if (!check_vif_up(vif
))
2779 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
2780 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
2783 * While going to suspend if associated with AP disassociate
2784 * from AP to save power while system is in suspended state
2786 brcmf_link_down(vif
);
2788 /* Make sure WPA_Supplicant receives all the event
2789 * generated due to DISASSOC call to the fw to keep
2790 * the state fw and WPA_Supplicant state consistent
2795 /* end any scanning */
2796 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
2797 brcmf_abort_scanning(cfg
);
2799 /* Turn off watchdog timer */
2800 brcmf_set_mpc(netdev_priv(ndev
), 1);
2803 brcmf_dbg(TRACE
, "Exit\n");
2804 /* clear any scanning activity */
2805 cfg
->scan_status
= 0;
2810 brcmf_update_pmklist(struct net_device
*ndev
,
2811 struct brcmf_cfg80211_pmk_list
*pmk_list
, s32 err
)
2816 pmkid_len
= le32_to_cpu(pmk_list
->pmkids
.npmkid
);
2818 brcmf_dbg(CONN
, "No of elements %d\n", pmkid_len
);
2819 for (i
= 0; i
< pmkid_len
; i
++) {
2820 brcmf_dbg(CONN
, "PMKID[%d]: %pM =\n", i
,
2821 &pmk_list
->pmkids
.pmkid
[i
].BSSID
);
2822 for (j
= 0; j
< WLAN_PMKID_LEN
; j
++)
2823 brcmf_dbg(CONN
, "%02x\n",
2824 pmk_list
->pmkids
.pmkid
[i
].PMKID
[j
]);
2828 brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pmkid_info",
2829 (char *)pmk_list
, sizeof(*pmk_list
));
2835 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2836 struct cfg80211_pmksa
*pmksa
)
2838 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2839 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2840 struct pmkid_list
*pmkids
= &cfg
->pmk_list
->pmkids
;
2845 brcmf_dbg(TRACE
, "Enter\n");
2846 if (!check_vif_up(ifp
->vif
))
2849 pmkid_len
= le32_to_cpu(pmkids
->npmkid
);
2850 for (i
= 0; i
< pmkid_len
; i
++)
2851 if (!memcmp(pmksa
->bssid
, pmkids
->pmkid
[i
].BSSID
, ETH_ALEN
))
2853 if (i
< WL_NUM_PMKIDS_MAX
) {
2854 memcpy(pmkids
->pmkid
[i
].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2855 memcpy(pmkids
->pmkid
[i
].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2856 if (i
== pmkid_len
) {
2858 pmkids
->npmkid
= cpu_to_le32(pmkid_len
);
2863 brcmf_dbg(CONN
, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2864 pmkids
->pmkid
[pmkid_len
].BSSID
);
2865 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2866 brcmf_dbg(CONN
, "%02x\n", pmkids
->pmkid
[pmkid_len
].PMKID
[i
]);
2868 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2870 brcmf_dbg(TRACE
, "Exit\n");
2875 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
2876 struct cfg80211_pmksa
*pmksa
)
2878 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2879 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2880 struct pmkid_list pmkid
;
2884 brcmf_dbg(TRACE
, "Enter\n");
2885 if (!check_vif_up(ifp
->vif
))
2888 memcpy(&pmkid
.pmkid
[0].BSSID
, pmksa
->bssid
, ETH_ALEN
);
2889 memcpy(&pmkid
.pmkid
[0].PMKID
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
2891 brcmf_dbg(CONN
, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2892 &pmkid
.pmkid
[0].BSSID
);
2893 for (i
= 0; i
< WLAN_PMKID_LEN
; i
++)
2894 brcmf_dbg(CONN
, "%02x\n", pmkid
.pmkid
[0].PMKID
[i
]);
2896 pmkid_len
= le32_to_cpu(cfg
->pmk_list
->pmkids
.npmkid
);
2897 for (i
= 0; i
< pmkid_len
; i
++)
2899 (pmksa
->bssid
, &cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2904 && (i
< pmkid_len
)) {
2905 memset(&cfg
->pmk_list
->pmkids
.pmkid
[i
], 0,
2906 sizeof(struct pmkid
));
2907 for (; i
< (pmkid_len
- 1); i
++) {
2908 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].BSSID
,
2909 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].BSSID
,
2911 memcpy(&cfg
->pmk_list
->pmkids
.pmkid
[i
].PMKID
,
2912 &cfg
->pmk_list
->pmkids
.pmkid
[i
+ 1].PMKID
,
2915 cfg
->pmk_list
->pmkids
.npmkid
= cpu_to_le32(pmkid_len
- 1);
2919 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2921 brcmf_dbg(TRACE
, "Exit\n");
2927 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
2929 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2930 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2933 brcmf_dbg(TRACE
, "Enter\n");
2934 if (!check_vif_up(ifp
->vif
))
2937 memset(cfg
->pmk_list
, 0, sizeof(*cfg
->pmk_list
));
2938 err
= brcmf_update_pmklist(ndev
, cfg
->pmk_list
, err
);
2940 brcmf_dbg(TRACE
, "Exit\n");
2946 * PFN result doesn't have all the info which are
2947 * required by the supplicant
2948 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2949 * via wl_inform_single_bss in the required format. Escan does require the
2950 * scan request in the form of cfg80211_scan_request. For timebeing, create
2951 * cfg80211_scan_request one out of the received PNO event.
2954 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
2955 const struct brcmf_event_msg
*e
, void *data
)
2957 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2958 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
2959 struct cfg80211_scan_request
*request
= NULL
;
2960 struct cfg80211_ssid
*ssid
= NULL
;
2961 struct ieee80211_channel
*channel
= NULL
;
2962 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2964 int channel_req
= 0;
2966 struct brcmf_pno_scanresults_le
*pfn_result
;
2970 brcmf_dbg(SCAN
, "Enter\n");
2972 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
2973 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
2977 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
2978 result_count
= le32_to_cpu(pfn_result
->count
);
2979 status
= le32_to_cpu(pfn_result
->status
);
2982 * PFN event is limited to fit 512 bytes so we may get
2983 * multiple NET_FOUND events. For now place a warning here.
2985 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
2986 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
2987 if (result_count
> 0) {
2990 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
2991 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
2992 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
2993 if (!request
|| !ssid
|| !channel
) {
2998 request
->wiphy
= wiphy
;
2999 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3000 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
3002 for (i
= 0; i
< result_count
; i
++) {
3003 netinfo
= &netinfo_start
[i
];
3005 brcmf_err("Invalid netinfo ptr. index: %d\n",
3011 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
3012 netinfo
->SSID
, netinfo
->channel
);
3013 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3014 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
3017 channel_req
= netinfo
->channel
;
3018 if (channel_req
<= CH_MAX_2G_CHANNEL
)
3019 band
= NL80211_BAND_2GHZ
;
3021 band
= NL80211_BAND_5GHZ
;
3022 channel
[i
].center_freq
=
3023 ieee80211_channel_to_frequency(channel_req
,
3025 channel
[i
].band
= band
;
3026 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
3027 request
->channels
[i
] = &channel
[i
];
3028 request
->n_channels
++;
3031 /* assign parsed ssid array */
3032 if (request
->n_ssids
)
3033 request
->ssids
= &ssid
[0];
3035 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3036 /* Abort any on-going scan */
3037 brcmf_abort_scanning(cfg
);
3040 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3041 cfg
->escan_info
.run
= brcmf_run_escan
;
3042 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
3044 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3047 cfg
->sched_escan
= true;
3048 cfg
->scan_request
= request
;
3050 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3063 cfg80211_sched_scan_stopped(wiphy
);
3067 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3072 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3075 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3079 brcmf_err("failed code %d\n", ret
);
3084 static int brcmf_dev_pno_config(struct net_device
*ndev
)
3086 struct brcmf_pno_param_le pfn_param
;
3088 memset(&pfn_param
, 0, sizeof(pfn_param
));
3089 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3091 /* set extra pno params */
3092 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3093 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3094 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3096 /* set up pno scan fr */
3097 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3099 return brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfn_set",
3100 &pfn_param
, sizeof(pfn_param
));
3104 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3105 struct net_device
*ndev
,
3106 struct cfg80211_sched_scan_request
*request
)
3108 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3109 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3110 struct brcmf_pno_net_param_le pfn
;
3114 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3115 request
->n_match_sets
, request
->n_ssids
);
3116 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3117 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3120 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3121 brcmf_err("Scanning suppressed: status (%lu)\n",
3126 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3127 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3132 if (request
->n_ssids
> 0) {
3133 for (i
= 0; i
< request
->n_ssids
; i
++) {
3134 /* Active scan req for ssids */
3135 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3136 request
->ssids
[i
].ssid
);
3139 * match_set ssids is a supert set of n_ssid list,
3140 * so we need not add these set seperately.
3145 if (request
->n_match_sets
> 0) {
3146 /* clean up everything */
3147 ret
= brcmf_dev_pno_clean(ndev
);
3149 brcmf_err("failed error=%d\n", ret
);
3154 ret
= brcmf_dev_pno_config(ndev
);
3156 brcmf_err("PNO setup failed!! ret=%d\n", ret
);
3160 /* configure each match set */
3161 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3162 struct cfg80211_ssid
*ssid
;
3165 ssid
= &request
->match_sets
[i
].ssid
;
3166 ssid_len
= ssid
->ssid_len
;
3169 brcmf_err("skip broadcast ssid\n");
3172 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3173 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3174 pfn
.wsec
= cpu_to_le32(0);
3175 pfn
.infra
= cpu_to_le32(1);
3176 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3177 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3178 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3179 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3181 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3182 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3184 /* Enable the PNO */
3185 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3186 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3196 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3197 struct net_device
*ndev
)
3199 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3201 brcmf_dbg(SCAN
, "enter\n");
3202 brcmf_dev_pno_clean(ndev
);
3203 if (cfg
->sched_escan
)
3204 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3208 #ifdef CONFIG_NL80211_TESTMODE
3209 static int brcmf_cfg80211_testmode(struct wiphy
*wiphy
,
3210 struct wireless_dev
*wdev
,
3211 void *data
, int len
)
3213 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3214 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3215 struct brcmf_dcmd
*dcmd
= data
;
3216 struct sk_buff
*reply
;
3219 brcmf_dbg(TRACE
, "cmd %x set %d buf %p len %d\n", dcmd
->cmd
, dcmd
->set
,
3220 dcmd
->buf
, dcmd
->len
);
3223 ret
= brcmf_fil_cmd_data_set(netdev_priv(ndev
), dcmd
->cmd
,
3224 dcmd
->buf
, dcmd
->len
);
3226 ret
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), dcmd
->cmd
,
3227 dcmd
->buf
, dcmd
->len
);
3229 reply
= cfg80211_testmode_alloc_reply_skb(wiphy
, sizeof(*dcmd
));
3230 nla_put(reply
, NL80211_ATTR_TESTDATA
, sizeof(*dcmd
), dcmd
);
3231 ret
= cfg80211_testmode_reply(reply
);
3237 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3242 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3244 brcmf_err("auth error %d\n", err
);
3248 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3250 brcmf_err("wsec error %d\n", err
);
3253 /* set upper-layer auth */
3254 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3256 brcmf_err("wpa_auth error %d\n", err
);
3263 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3266 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3268 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3272 brcmf_configure_wpaie(struct net_device
*ndev
,
3273 const struct brcmf_vs_tlv
*wpa_ie
,
3276 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3277 u32 auth
= 0; /* d11 open authentication */
3289 u32 wme_bss_disable
;
3291 brcmf_dbg(TRACE
, "Enter\n");
3295 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3296 data
= (u8
*)wpa_ie
;
3297 offset
= TLV_HDR_LEN
;
3299 offset
+= VS_IE_FIXED_HDR_LEN
;
3301 offset
+= WPA_IE_VERSION_LEN
;
3303 /* check for multicast cipher suite */
3304 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3306 brcmf_err("no multicast cipher suite\n");
3310 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3312 brcmf_err("ivalid OUI\n");
3315 offset
+= TLV_OUI_LEN
;
3317 /* pick up multicast cipher */
3318 switch (data
[offset
]) {
3319 case WPA_CIPHER_NONE
:
3322 case WPA_CIPHER_WEP_40
:
3323 case WPA_CIPHER_WEP_104
:
3326 case WPA_CIPHER_TKIP
:
3327 gval
= TKIP_ENABLED
;
3329 case WPA_CIPHER_AES_CCM
:
3334 brcmf_err("Invalid multi cast cipher info\n");
3339 /* walk thru unicast cipher list and pick up what we recognize */
3340 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3341 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3342 /* Check for unicast suite(s) */
3343 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3345 brcmf_err("no unicast cipher suite\n");
3348 for (i
= 0; i
< count
; i
++) {
3349 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3351 brcmf_err("ivalid OUI\n");
3354 offset
+= TLV_OUI_LEN
;
3355 switch (data
[offset
]) {
3356 case WPA_CIPHER_NONE
:
3358 case WPA_CIPHER_WEP_40
:
3359 case WPA_CIPHER_WEP_104
:
3360 pval
|= WEP_ENABLED
;
3362 case WPA_CIPHER_TKIP
:
3363 pval
|= TKIP_ENABLED
;
3365 case WPA_CIPHER_AES_CCM
:
3366 pval
|= AES_ENABLED
;
3369 brcmf_err("Ivalid unicast security info\n");
3373 /* walk thru auth management suite list and pick up what we recognize */
3374 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3375 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3376 /* Check for auth key management suite(s) */
3377 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3379 brcmf_err("no auth key mgmt suite\n");
3382 for (i
= 0; i
< count
; i
++) {
3383 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3385 brcmf_err("ivalid OUI\n");
3388 offset
+= TLV_OUI_LEN
;
3389 switch (data
[offset
]) {
3391 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3392 wpa_auth
|= WPA_AUTH_NONE
;
3394 case RSN_AKM_UNSPECIFIED
:
3395 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3396 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3397 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3400 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3401 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3402 (wpa_auth
|= WPA_AUTH_PSK
);
3405 brcmf_err("Ivalid key mgmt info\n");
3411 wme_bss_disable
= 1;
3412 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3413 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3414 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3415 wme_bss_disable
= 0;
3417 /* set wme_bss_disable to sync RSN Capabilities */
3418 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3421 brcmf_err("wme_bss_disable error %d\n", err
);
3425 /* FOR WPS , set SES_OW_ENABLED */
3426 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3429 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3431 brcmf_err("auth error %d\n", err
);
3435 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3437 brcmf_err("wsec error %d\n", err
);
3440 /* set upper-layer auth */
3441 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
3443 brcmf_err("wpa_auth error %d\n", err
);
3452 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
3453 struct parsed_vndr_ies
*vndr_ies
)
3456 struct brcmf_vs_tlv
*vndrie
;
3457 struct brcmf_tlv
*ie
;
3458 struct parsed_vndr_ie_info
*parsed_info
;
3461 remaining_len
= (s32
)vndr_ie_len
;
3462 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
3464 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
3466 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
3468 vndrie
= (struct brcmf_vs_tlv
*)ie
;
3469 /* len should be bigger than OUI length + one */
3470 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
3471 brcmf_err("invalid vndr ie. length is too small %d\n",
3475 /* if wpa or wme ie, do not add ie */
3476 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
3477 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
3478 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
3479 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
3483 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
3485 /* save vndr ie information */
3486 parsed_info
->ie_ptr
= (char *)vndrie
;
3487 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
3488 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
3492 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
3493 parsed_info
->vndrie
.oui
[0],
3494 parsed_info
->vndrie
.oui
[1],
3495 parsed_info
->vndrie
.oui
[2],
3496 parsed_info
->vndrie
.oui_type
);
3498 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
3501 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
3502 if (remaining_len
<= TLV_HDR_LEN
)
3505 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
3512 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
3518 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
3519 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
3521 iecount_le
= cpu_to_le32(1);
3522 memcpy(&iebuf
[VNDR_IE_COUNT_OFFSET
], &iecount_le
, sizeof(iecount_le
));
3524 pktflag_le
= cpu_to_le32(pktflag
);
3525 memcpy(&iebuf
[VNDR_IE_PKTFLAG_OFFSET
], &pktflag_le
, sizeof(pktflag_le
));
3527 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
3529 return ie_len
+ VNDR_IE_HDR_SIZE
;
3532 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
3533 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
3535 struct brcmf_if
*ifp
;
3536 struct vif_saved_ie
*saved_ie
;
3540 u8
*mgmt_ie_buf
= NULL
;
3541 int mgmt_ie_buf_len
;
3543 u32 del_add_ie_buf_len
= 0;
3544 u32 total_ie_buf_len
= 0;
3545 u32 parsed_ie_buf_len
= 0;
3546 struct parsed_vndr_ies old_vndr_ies
;
3547 struct parsed_vndr_ies new_vndr_ies
;
3548 struct parsed_vndr_ie_info
*vndrie_info
;
3551 int remained_buf_len
;
3556 saved_ie
= &vif
->saved_ie
;
3558 brcmf_dbg(TRACE
, "bssidx %d, pktflag : 0x%02X\n", ifp
->bssidx
, pktflag
);
3559 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
3562 curr_ie_buf
= iovar_ie_buf
;
3564 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
3565 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
3566 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
3567 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
3569 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
3570 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
3571 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
3572 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
3574 case BRCMF_VNDR_IE_BEACON_FLAG
:
3575 mgmt_ie_buf
= saved_ie
->beacon_ie
;
3576 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
3577 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
3579 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
3580 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
3581 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
3582 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
3586 brcmf_err("not suitable type\n");
3590 if (vndr_ie_len
> mgmt_ie_buf_len
) {
3592 brcmf_err("extra IE size too big\n");
3596 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3597 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
3599 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
3600 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3601 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3602 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
3603 vndrie_info
->ie_len
);
3604 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
3608 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
3609 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
3610 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
3611 parsed_ie_buf_len
) == 0)) {
3612 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
3616 /* parse old vndr_ie */
3617 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
3619 /* make a command to delete old ie */
3620 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
3621 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
3623 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3624 vndrie_info
->vndrie
.id
,
3625 vndrie_info
->vndrie
.len
,
3626 vndrie_info
->vndrie
.oui
[0],
3627 vndrie_info
->vndrie
.oui
[1],
3628 vndrie_info
->vndrie
.oui
[2]);
3630 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3631 vndrie_info
->ie_ptr
,
3632 vndrie_info
->ie_len
,
3634 curr_ie_buf
+= del_add_ie_buf_len
;
3635 total_ie_buf_len
+= del_add_ie_buf_len
;
3640 /* Add if there is any extra IE */
3641 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
3644 remained_buf_len
= mgmt_ie_buf_len
;
3646 /* make a command to add new ie */
3647 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
3648 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
3650 /* verify remained buf size before copy data */
3651 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
3652 VNDR_IE_VSIE_OFFSET
)) {
3653 brcmf_err("no space in mgmt_ie_buf: len left %d",
3657 remained_buf_len
-= (vndrie_info
->ie_len
+
3658 VNDR_IE_VSIE_OFFSET
);
3660 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3661 vndrie_info
->vndrie
.id
,
3662 vndrie_info
->vndrie
.len
,
3663 vndrie_info
->vndrie
.oui
[0],
3664 vndrie_info
->vndrie
.oui
[1],
3665 vndrie_info
->vndrie
.oui
[2]);
3667 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
3668 vndrie_info
->ie_ptr
,
3669 vndrie_info
->ie_len
,
3672 /* save the parsed IE in wl struct */
3673 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
3674 vndrie_info
->ie_len
);
3675 *mgmt_ie_len
+= vndrie_info
->ie_len
;
3677 curr_ie_buf
+= del_add_ie_buf_len
;
3678 total_ie_buf_len
+= del_add_ie_buf_len
;
3681 if (total_ie_buf_len
) {
3682 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
3685 brcmf_err("vndr ie set error : %d\n", err
);
3689 kfree(iovar_ie_buf
);
3693 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
3696 BRCMF_VNDR_IE_PRBREQ_FLAG
,
3697 BRCMF_VNDR_IE_PRBRSP_FLAG
,
3698 BRCMF_VNDR_IE_BEACON_FLAG
3702 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
3703 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
3705 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
3710 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
3711 struct cfg80211_beacon_data
*beacon
)
3715 /* Set Beacon IEs to FW */
3716 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
3717 beacon
->tail
, beacon
->tail_len
);
3719 brcmf_err("Set Beacon IE Failed\n");
3722 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
3724 /* Set Probe Response IEs to FW */
3725 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
3726 beacon
->proberesp_ies
,
3727 beacon
->proberesp_ies_len
);
3729 brcmf_err("Set Probe Resp IE Failed\n");
3731 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
3737 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info
*cfg
,
3738 struct brcmf_if
*ifp
,
3739 struct ieee80211_channel
*channel
)
3744 brcmf_dbg(TRACE
, "band=%d, center_freq=%d\n", channel
->band
,
3745 channel
->center_freq
);
3747 chanspec
= channel_to_chanspec(&cfg
->d11inf
, channel
);
3748 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
3754 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
3755 struct cfg80211_ap_settings
*settings
)
3758 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3759 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3760 const struct brcmf_tlv
*ssid_ie
;
3761 struct brcmf_ssid_le ssid_le
;
3763 const struct brcmf_tlv
*rsn_ie
;
3764 const struct brcmf_vs_tlv
*wpa_ie
;
3765 struct brcmf_join_params join_params
;
3766 enum nl80211_iftype dev_role
;
3767 struct brcmf_fil_bss_enable_le bss_enable
;
3769 brcmf_dbg(TRACE
, "channel=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
3770 settings
->chandef
.chan
->hw_value
, settings
->chandef
.width
,
3771 settings
->beacon_interval
, settings
->dtim_period
);
3772 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3773 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
3774 settings
->inactivity_timeout
);
3776 dev_role
= ifp
->vif
->wdev
.iftype
;
3778 memset(&ssid_le
, 0, sizeof(ssid_le
));
3779 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
3780 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
3781 ssid_ie
= brcmf_parse_tlvs(
3782 (u8
*)&settings
->beacon
.head
[ie_offset
],
3783 settings
->beacon
.head_len
- ie_offset
,
3788 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
3789 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
3790 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
3792 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
3793 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
3796 brcmf_set_mpc(ifp
, 0);
3797 brcmf_configure_arp_offload(ifp
, false);
3799 /* find the RSN_IE */
3800 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
3801 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
3803 /* find the WPA_IE */
3804 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
3805 settings
->beacon
.tail_len
);
3807 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
3808 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
3809 if (wpa_ie
!= NULL
) {
3811 err
= brcmf_configure_wpaie(ndev
, wpa_ie
, false);
3816 err
= brcmf_configure_wpaie(ndev
,
3817 (struct brcmf_vs_tlv
*)rsn_ie
, true);
3822 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
3823 brcmf_configure_opensecurity(ifp
);
3826 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
3828 err
= brcmf_cfg80211_set_channel(cfg
, ifp
, settings
->chandef
.chan
);
3830 brcmf_err("Set Channel failed, %d\n", err
);
3834 if (settings
->beacon_interval
) {
3835 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
3836 settings
->beacon_interval
);
3838 brcmf_err("Beacon Interval Set Error, %d\n", err
);
3842 if (settings
->dtim_period
) {
3843 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
3844 settings
->dtim_period
);
3846 brcmf_err("DTIM Interval Set Error, %d\n", err
);
3851 if (dev_role
== NL80211_IFTYPE_AP
) {
3852 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
3854 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
3857 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
3860 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
3862 brcmf_err("SET INFRA error %d\n", err
);
3865 if (dev_role
== NL80211_IFTYPE_AP
) {
3866 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
3868 brcmf_err("setting AP mode failed %d\n", err
);
3871 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
3873 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
3877 memset(&join_params
, 0, sizeof(join_params
));
3878 /* join parameters starts with ssid */
3879 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
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
);
3887 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
3889 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
3892 brcmf_err("setting ssid failed %d\n", err
);
3895 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3896 bss_enable
.enable
= cpu_to_le32(1);
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
);
3904 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
3906 clear_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3907 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3911 brcmf_set_mpc(ifp
, 1);
3912 brcmf_configure_arp_offload(ifp
, true);
3917 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
3919 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3921 struct brcmf_fil_bss_enable_le bss_enable
;
3922 struct brcmf_join_params join_params
;
3924 brcmf_dbg(TRACE
, "Enter\n");
3926 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
3927 /* Due to most likely deauths outstanding we sleep */
3928 /* first to make sure they get processed by fw. */
3931 memset(&join_params
, 0, sizeof(join_params
));
3932 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
3933 &join_params
, sizeof(join_params
));
3935 brcmf_err("SET SSID error (%d)\n", err
);
3936 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
3938 brcmf_err("BRCMF_C_UP error %d\n", err
);
3939 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
3941 brcmf_err("setting AP mode failed %d\n", err
);
3942 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
3944 brcmf_err("setting INFRA mode failed %d\n", err
);
3946 bss_enable
.bsscfg_idx
= cpu_to_le32(ifp
->bssidx
);
3947 bss_enable
.enable
= cpu_to_le32(0);
3948 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
3949 sizeof(bss_enable
));
3951 brcmf_err("bss_enable config failed %d\n", err
);
3953 brcmf_set_mpc(ifp
, 1);
3954 brcmf_configure_arp_offload(ifp
, true);
3955 set_bit(BRCMF_VIF_STATUS_AP_CREATING
, &ifp
->vif
->sme_state
);
3956 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
3962 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
3963 struct cfg80211_beacon_data
*info
)
3965 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3968 brcmf_dbg(TRACE
, "Enter\n");
3970 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
3976 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
3979 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3980 struct brcmf_scb_val_le scbval
;
3981 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3987 brcmf_dbg(TRACE
, "Enter %pM\n", mac
);
3989 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
3990 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
3991 if (!check_vif_up(ifp
->vif
))
3994 memcpy(&scbval
.ea
, mac
, ETH_ALEN
);
3995 scbval
.val
= cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING
);
3996 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
3997 &scbval
, sizeof(scbval
));
3999 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
4001 brcmf_dbg(TRACE
, "Exit\n");
4007 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
4008 struct wireless_dev
*wdev
,
4009 u16 frame_type
, bool reg
)
4011 struct brcmf_cfg80211_vif
*vif
;
4014 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
4016 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
4017 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4019 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
4021 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
4026 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
4027 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
4029 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4030 struct ieee80211_channel
*chan
= params
->chan
;
4031 const u8
*buf
= params
->buf
;
4032 size_t len
= params
->len
;
4033 const struct ieee80211_mgmt
*mgmt
;
4034 struct brcmf_cfg80211_vif
*vif
;
4038 struct brcmf_fil_action_frame_le
*action_frame
;
4039 struct brcmf_fil_af_params_le
*af_params
;
4044 brcmf_dbg(TRACE
, "Enter\n");
4048 mgmt
= (const struct ieee80211_mgmt
*)buf
;
4050 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
4051 brcmf_err("Driver only allows MGMT packet type\n");
4055 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4057 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4058 /* Right now the only reason to get a probe response */
4059 /* is for p2p listen response or for p2p GO from */
4060 /* wpa_supplicant. Unfortunately the probe is send */
4061 /* on primary ndev, while dongle wants it on the p2p */
4062 /* vif. Since this is only reason for a probe */
4063 /* response to be sent, the vif is taken from cfg. */
4064 /* If ever desired to send proberesp for non p2p */
4065 /* response then data should be checked for */
4066 /* "DIRECT-". Note in future supplicant will take */
4067 /* dedicated p2p wdev to do this and then this 'hack'*/
4068 /* is not needed anymore. */
4069 ie_offset
= DOT11_MGMT_HDR_LEN
+
4070 DOT11_BCN_PRB_FIXED_LEN
;
4071 ie_len
= len
- ie_offset
;
4072 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4073 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4074 err
= brcmf_vif_set_mgmt_ie(vif
,
4075 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4078 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4080 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4081 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4082 if (af_params
== NULL
) {
4083 brcmf_err("unable to allocate frame\n");
4087 action_frame
= &af_params
->action_frame
;
4088 /* Add the packet Id */
4089 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4091 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4092 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4093 /* Add the length exepted for 802.11 header */
4094 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4095 /* Add the channel. Use the one specified as parameter if any or
4096 * the current one (got from the firmware) otherwise
4099 freq
= chan
->center_freq
;
4101 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4103 chan_nr
= ieee80211_frequency_to_channel(freq
);
4104 af_params
->channel
= cpu_to_le32(chan_nr
);
4106 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4107 le16_to_cpu(action_frame
->len
));
4109 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4110 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4112 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4115 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4119 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4120 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4129 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4130 struct wireless_dev
*wdev
,
4133 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4134 struct brcmf_cfg80211_vif
*vif
;
4137 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4139 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4141 brcmf_err("No p2p device available for probe response\n");
4145 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4150 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4151 struct wireless_dev
*wdev
,
4152 enum nl80211_crit_proto_id proto
,
4155 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4156 struct brcmf_cfg80211_vif
*vif
;
4158 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4160 /* only DHCP support for now */
4161 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4164 /* suppress and abort scanning */
4165 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4166 brcmf_abort_scanning(cfg
);
4168 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4171 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4172 struct wireless_dev
*wdev
)
4174 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4175 struct brcmf_cfg80211_vif
*vif
;
4177 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4179 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4180 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4183 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4188 case NL80211_TDLS_DISCOVERY_REQ
:
4189 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4191 case NL80211_TDLS_SETUP
:
4192 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4194 case NL80211_TDLS_TEARDOWN
:
4195 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4198 brcmf_err("unsupported operation: %d\n", oper
);
4204 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4205 struct net_device
*ndev
, u8
*peer
,
4206 enum nl80211_tdls_operation oper
)
4208 struct brcmf_if
*ifp
;
4209 struct brcmf_tdls_iovar_le info
;
4212 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4216 ifp
= netdev_priv(ndev
);
4217 memset(&info
, 0, sizeof(info
));
4218 info
.mode
= (u8
)ret
;
4220 memcpy(info
.ea
, peer
, ETH_ALEN
);
4222 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
4223 &info
, sizeof(info
));
4225 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
4230 static struct cfg80211_ops wl_cfg80211_ops
= {
4231 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4232 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4233 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4234 .scan
= brcmf_cfg80211_scan
,
4235 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4236 .join_ibss
= brcmf_cfg80211_join_ibss
,
4237 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4238 .get_station
= brcmf_cfg80211_get_station
,
4239 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4240 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4241 .add_key
= brcmf_cfg80211_add_key
,
4242 .del_key
= brcmf_cfg80211_del_key
,
4243 .get_key
= brcmf_cfg80211_get_key
,
4244 .set_default_key
= brcmf_cfg80211_config_default_key
,
4245 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4246 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4247 .connect
= brcmf_cfg80211_connect
,
4248 .disconnect
= brcmf_cfg80211_disconnect
,
4249 .suspend
= brcmf_cfg80211_suspend
,
4250 .resume
= brcmf_cfg80211_resume
,
4251 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4252 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4253 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4254 .start_ap
= brcmf_cfg80211_start_ap
,
4255 .stop_ap
= brcmf_cfg80211_stop_ap
,
4256 .change_beacon
= brcmf_cfg80211_change_beacon
,
4257 .del_station
= brcmf_cfg80211_del_station
,
4258 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4259 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4260 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4261 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4262 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4263 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4264 .start_p2p_device
= brcmf_p2p_start_device
,
4265 .stop_p2p_device
= brcmf_p2p_stop_device
,
4266 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
4267 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
4268 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
4269 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode
)
4272 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
4274 /* scheduled scan settings */
4275 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
4276 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
4277 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4278 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
4281 static const struct ieee80211_iface_limit brcmf_iface_limits
[] = {
4284 .types
= BIT(NL80211_IFTYPE_STATION
) |
4285 BIT(NL80211_IFTYPE_ADHOC
) |
4286 BIT(NL80211_IFTYPE_AP
)
4290 .types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4291 BIT(NL80211_IFTYPE_P2P_GO
)
4295 .types
= BIT(NL80211_IFTYPE_P2P_DEVICE
)
4298 static const struct ieee80211_iface_combination brcmf_iface_combos
[] = {
4300 .max_interfaces
= BRCMF_IFACE_MAX_CNT
,
4301 .num_different_channels
= 2,
4302 .n_limits
= ARRAY_SIZE(brcmf_iface_limits
),
4303 .limits
= brcmf_iface_limits
4307 static const struct ieee80211_txrx_stypes
4308 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
4309 [NL80211_IFTYPE_STATION
] = {
4311 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4312 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4314 [NL80211_IFTYPE_P2P_CLIENT
] = {
4316 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4317 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4319 [NL80211_IFTYPE_P2P_GO
] = {
4321 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
4322 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
4323 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
4324 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
4325 BIT(IEEE80211_STYPE_AUTH
>> 4) |
4326 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
4327 BIT(IEEE80211_STYPE_ACTION
>> 4)
4329 [NL80211_IFTYPE_P2P_DEVICE
] = {
4331 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
4332 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
4336 static struct wiphy
*brcmf_setup_wiphy(struct device
*phydev
)
4338 struct wiphy
*wiphy
;
4341 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
4343 brcmf_err("Could not allocate wiphy device\n");
4344 return ERR_PTR(-ENOMEM
);
4346 set_wiphy_dev(wiphy
, phydev
);
4347 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
4348 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
4349 wiphy
->max_num_pmkids
= WL_NUM_PMKIDS_MAX
;
4350 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
4351 BIT(NL80211_IFTYPE_ADHOC
) |
4352 BIT(NL80211_IFTYPE_AP
) |
4353 BIT(NL80211_IFTYPE_P2P_CLIENT
) |
4354 BIT(NL80211_IFTYPE_P2P_GO
) |
4355 BIT(NL80211_IFTYPE_P2P_DEVICE
);
4356 wiphy
->iface_combinations
= brcmf_iface_combos
;
4357 wiphy
->n_iface_combinations
= ARRAY_SIZE(brcmf_iface_combos
);
4358 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = &__wl_band_2ghz
;
4359 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
4360 wiphy
->cipher_suites
= __wl_cipher_suites
;
4361 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
4362 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
4363 WIPHY_FLAG_OFFCHAN_TX
|
4364 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
|
4365 WIPHY_FLAG_SUPPORTS_TDLS
;
4367 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_FW_ROAM
;
4368 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
4369 wiphy
->max_remain_on_channel_duration
= 5000;
4370 brcmf_wiphy_pno_params(wiphy
);
4371 brcmf_dbg(INFO
, "Registering custom regulatory\n");
4372 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
4373 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
4374 err
= wiphy_register(wiphy
);
4376 brcmf_err("Could not register wiphy device (%d)\n", err
);
4378 return ERR_PTR(err
);
4383 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4384 enum nl80211_iftype type
,
4387 struct brcmf_cfg80211_vif
*vif
;
4389 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
4391 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
4393 return ERR_PTR(-ENOMEM
);
4395 vif
->wdev
.wiphy
= cfg
->wiphy
;
4396 vif
->wdev
.iftype
= type
;
4398 vif
->pm_block
= pm_block
;
4401 brcmf_init_prof(&vif
->profile
);
4403 list_add_tail(&vif
->list
, &cfg
->vif_list
);
4407 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
4409 list_del(&vif
->list
);
4413 void brcmf_cfg80211_free_netdev(struct net_device
*ndev
)
4415 struct brcmf_cfg80211_vif
*vif
;
4416 struct brcmf_if
*ifp
;
4418 ifp
= netdev_priv(ndev
);
4421 brcmf_free_vif(vif
);
4425 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4427 u32 event
= e
->event_code
;
4428 u32 status
= e
->status
;
4430 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4431 brcmf_dbg(CONN
, "Processing set ssid\n");
4438 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4440 u32 event
= e
->event_code
;
4441 u16 flags
= e
->flags
;
4443 if ((event
== BRCMF_E_DEAUTH
) || (event
== BRCMF_E_DEAUTH_IND
) ||
4444 (event
== BRCMF_E_DISASSOC_IND
) ||
4445 ((event
== BRCMF_E_LINK
) && (!(flags
& BRCMF_EVENT_MSG_LINK
)))) {
4446 brcmf_dbg(CONN
, "Processing link down\n");
4452 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
4453 const struct brcmf_event_msg
*e
)
4455 u32 event
= e
->event_code
;
4456 u32 status
= e
->status
;
4458 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
4459 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
4460 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
4464 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
4465 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
4472 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
4474 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4476 kfree(conn_info
->req_ie
);
4477 conn_info
->req_ie
= NULL
;
4478 conn_info
->req_ie_len
= 0;
4479 kfree(conn_info
->resp_ie
);
4480 conn_info
->resp_ie
= NULL
;
4481 conn_info
->resp_ie_len
= 0;
4484 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
4485 struct brcmf_if
*ifp
)
4487 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
4488 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4493 brcmf_clear_assoc_ies(cfg
);
4495 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
4496 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
4498 brcmf_err("could not get assoc info (%d)\n", err
);
4502 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
4503 req_len
= le32_to_cpu(assoc_info
->req_len
);
4504 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
4506 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
4510 brcmf_err("could not get assoc req (%d)\n", err
);
4513 conn_info
->req_ie_len
= req_len
;
4515 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
4518 conn_info
->req_ie_len
= 0;
4519 conn_info
->req_ie
= NULL
;
4522 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
4526 brcmf_err("could not get assoc resp (%d)\n", err
);
4529 conn_info
->resp_ie_len
= resp_len
;
4530 conn_info
->resp_ie
=
4531 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
4534 conn_info
->resp_ie_len
= 0;
4535 conn_info
->resp_ie
= NULL
;
4537 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
4538 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
4544 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
4545 struct net_device
*ndev
,
4546 const struct brcmf_event_msg
*e
)
4548 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4549 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4550 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4551 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
4552 struct ieee80211_channel
*notify_channel
= NULL
;
4553 struct ieee80211_supported_band
*band
;
4554 struct brcmf_bss_info_le
*bi
;
4555 struct brcmu_chan ch
;
4560 brcmf_dbg(TRACE
, "Enter\n");
4562 brcmf_get_assoc_ies(cfg
, ifp
);
4563 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4564 brcmf_update_bss_info(cfg
, ifp
);
4566 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
4572 /* data sent to dongle has to be little endian */
4573 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
4574 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
4575 buf
, WL_BSS_INFO_MAX
);
4580 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
4581 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
4582 cfg
->d11inf
.decchspec(&ch
);
4584 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
4585 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
4587 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
4589 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
4590 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
4594 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
4595 conn_info
->req_ie
, conn_info
->req_ie_len
,
4596 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
4597 brcmf_dbg(CONN
, "Report roaming result\n");
4599 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
4600 brcmf_dbg(TRACE
, "Exit\n");
4605 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
4606 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
4609 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4610 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4611 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
4614 brcmf_dbg(TRACE
, "Enter\n");
4616 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4617 &ifp
->vif
->sme_state
)) {
4619 brcmf_get_assoc_ies(cfg
, ifp
);
4620 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4621 brcmf_update_bss_info(cfg
, ifp
);
4622 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4623 &ifp
->vif
->sme_state
);
4625 cfg80211_connect_result(ndev
,
4626 (u8
*)profile
->bssid
,
4628 conn_info
->req_ie_len
,
4630 conn_info
->resp_ie_len
,
4631 completed
? WLAN_STATUS_SUCCESS
:
4632 WLAN_STATUS_AUTH_TIMEOUT
,
4634 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
4635 completed
? "succeeded" : "failed");
4637 brcmf_dbg(TRACE
, "Exit\n");
4642 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
4643 struct net_device
*ndev
,
4644 const struct brcmf_event_msg
*e
, void *data
)
4646 static int generation
;
4647 u32 event
= e
->event_code
;
4648 u32 reason
= e
->reason
;
4649 struct station_info sinfo
;
4651 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
4652 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
4653 ndev
!= cfg_to_ndev(cfg
)) {
4654 brcmf_dbg(CONN
, "AP mode link down\n");
4655 complete(&cfg
->vif_disabled
);
4659 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
4660 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
4661 memset(&sinfo
, 0, sizeof(sinfo
));
4662 sinfo
.filled
= STATION_INFO_ASSOC_REQ_IES
;
4664 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4667 sinfo
.assoc_req_ies
= data
;
4668 sinfo
.assoc_req_ies_len
= e
->datalen
;
4670 sinfo
.generation
= generation
;
4671 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
4672 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
4673 (event
== BRCMF_E_DEAUTH_IND
) ||
4674 (event
== BRCMF_E_DEAUTH
)) {
4675 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
4681 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
4682 const struct brcmf_event_msg
*e
, void *data
)
4684 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4685 struct net_device
*ndev
= ifp
->ndev
;
4686 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
4687 struct ieee80211_channel
*chan
;
4690 if (brcmf_is_apmode(ifp
->vif
)) {
4691 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
4692 } else if (brcmf_is_linkup(e
)) {
4693 brcmf_dbg(CONN
, "Linkup\n");
4694 if (brcmf_is_ibssmode(ifp
->vif
)) {
4695 chan
= ieee80211_get_channel(cfg
->wiphy
, cfg
->channel
);
4696 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
4697 wl_inform_ibss(cfg
, ndev
, e
->addr
);
4698 cfg80211_ibss_joined(ndev
, e
->addr
, chan
, GFP_KERNEL
);
4699 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4700 &ifp
->vif
->sme_state
);
4701 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
4702 &ifp
->vif
->sme_state
);
4704 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
4705 } else if (brcmf_is_linkdown(e
)) {
4706 brcmf_dbg(CONN
, "Linkdown\n");
4707 if (!brcmf_is_ibssmode(ifp
->vif
)) {
4708 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4710 brcmf_link_down(ifp
->vif
);
4711 brcmf_init_prof(ndev_to_prof(ndev
));
4712 if (ndev
!= cfg_to_ndev(cfg
))
4713 complete(&cfg
->vif_disabled
);
4714 } else if (brcmf_is_nonetwork(cfg
, e
)) {
4715 if (brcmf_is_ibssmode(ifp
->vif
))
4716 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
4717 &ifp
->vif
->sme_state
);
4719 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
4726 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
4727 const struct brcmf_event_msg
*e
, void *data
)
4729 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4731 u32 event
= e
->event_code
;
4732 u32 status
= e
->status
;
4734 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4735 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
4736 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
4738 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
4745 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
4746 const struct brcmf_event_msg
*e
, void *data
)
4748 u16 flags
= e
->flags
;
4749 enum nl80211_key_type key_type
;
4751 if (flags
& BRCMF_EVENT_MSG_GROUP
)
4752 key_type
= NL80211_KEYTYPE_GROUP
;
4754 key_type
= NL80211_KEYTYPE_PAIRWISE
;
4756 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
4762 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
4763 const struct brcmf_event_msg
*e
, void *data
)
4765 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
4766 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
4767 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
4768 struct brcmf_cfg80211_vif
*vif
;
4770 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4771 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
4774 mutex_lock(&event
->vif_event_lock
);
4775 event
->action
= ifevent
->action
;
4778 switch (ifevent
->action
) {
4779 case BRCMF_E_IF_ADD
:
4780 /* waiting process may have timed out */
4781 if (!cfg
->vif_event
.vif
) {
4782 mutex_unlock(&event
->vif_event_lock
);
4789 vif
->wdev
.netdev
= ifp
->ndev
;
4790 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
4791 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
4793 mutex_unlock(&event
->vif_event_lock
);
4794 wake_up(&event
->vif_wq
);
4797 case BRCMF_E_IF_DEL
:
4798 mutex_unlock(&event
->vif_event_lock
);
4799 /* event may not be upon user request */
4800 if (brcmf_cfg80211_vif_event_armed(cfg
))
4801 wake_up(&event
->vif_wq
);
4804 case BRCMF_E_IF_CHANGE
:
4805 mutex_unlock(&event
->vif_event_lock
);
4806 wake_up(&event
->vif_wq
);
4810 mutex_unlock(&event
->vif_event_lock
);
4816 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
4818 conf
->frag_threshold
= (u32
)-1;
4819 conf
->rts_threshold
= (u32
)-1;
4820 conf
->retry_short
= (u32
)-1;
4821 conf
->retry_long
= (u32
)-1;
4822 conf
->tx_power
= -1;
4825 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
4827 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
4828 brcmf_notify_connect_status
);
4829 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
4830 brcmf_notify_connect_status
);
4831 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
4832 brcmf_notify_connect_status
);
4833 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
4834 brcmf_notify_connect_status
);
4835 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
4836 brcmf_notify_connect_status
);
4837 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
4838 brcmf_notify_connect_status
);
4839 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
4840 brcmf_notify_roaming_status
);
4841 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
4842 brcmf_notify_mic_status
);
4843 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
4844 brcmf_notify_connect_status
);
4845 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
4846 brcmf_notify_sched_scan_results
);
4847 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
4848 brcmf_notify_vif_event
);
4849 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
4850 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
4851 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
4852 brcmf_p2p_notify_listen_complete
);
4853 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
4854 brcmf_p2p_notify_action_frame_rx
);
4855 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
4856 brcmf_p2p_notify_action_tx_complete
);
4857 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
4858 brcmf_p2p_notify_action_tx_complete
);
4861 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4865 kfree(cfg
->escan_ioctl_buf
);
4866 cfg
->escan_ioctl_buf
= NULL
;
4867 kfree(cfg
->extra_buf
);
4868 cfg
->extra_buf
= NULL
;
4869 kfree(cfg
->pmk_list
);
4870 cfg
->pmk_list
= NULL
;
4873 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
4875 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
4877 goto init_priv_mem_out
;
4878 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
4879 if (!cfg
->escan_ioctl_buf
)
4880 goto init_priv_mem_out
;
4881 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4882 if (!cfg
->extra_buf
)
4883 goto init_priv_mem_out
;
4884 cfg
->pmk_list
= kzalloc(sizeof(*cfg
->pmk_list
), GFP_KERNEL
);
4886 goto init_priv_mem_out
;
4891 brcmf_deinit_priv_mem(cfg
);
4896 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
4900 cfg
->scan_request
= NULL
;
4901 cfg
->pwr_save
= true;
4902 cfg
->active_scan
= true; /* we do active scan per default */
4903 cfg
->dongle_up
= false; /* dongle is not up yet */
4904 err
= brcmf_init_priv_mem(cfg
);
4907 brcmf_register_event_handlers(cfg
);
4908 mutex_init(&cfg
->usr_sync
);
4909 brcmf_init_escan(cfg
);
4910 brcmf_init_conf(cfg
->conf
);
4911 init_completion(&cfg
->vif_disabled
);
4915 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
4917 cfg
->dongle_up
= false; /* dongle down */
4918 brcmf_abort_scanning(cfg
);
4919 brcmf_deinit_priv_mem(cfg
);
4922 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
4924 init_waitqueue_head(&event
->vif_wq
);
4925 mutex_init(&event
->vif_event_lock
);
4928 static int brcmf_enable_bw40_2g(struct brcmf_if
*ifp
)
4930 struct brcmf_fil_bwcap_le band_bwcap
;
4934 /* verify support for bw_cap command */
4936 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &val
);
4939 /* only set 2G bandwidth using bw_cap command */
4940 band_bwcap
.band
= cpu_to_le32(WLC_BAND_2G
);
4941 band_bwcap
.bw_cap
= cpu_to_le32(WLC_BW_CAP_40MHZ
);
4942 err
= brcmf_fil_iovar_data_set(ifp
, "bw_cap", &band_bwcap
,
4943 sizeof(band_bwcap
));
4945 brcmf_dbg(INFO
, "fallback to mimo_bw_cap\n");
4946 val
= WLC_N_BW_40ALL
;
4947 err
= brcmf_fil_iovar_int_set(ifp
, "mimo_bw_cap", val
);
4952 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
4953 struct device
*busdev
)
4955 struct net_device
*ndev
= drvr
->iflist
[0]->ndev
;
4956 struct brcmf_cfg80211_info
*cfg
;
4957 struct wiphy
*wiphy
;
4958 struct brcmf_cfg80211_vif
*vif
;
4959 struct brcmf_if
*ifp
;
4964 brcmf_err("ndev is invalid\n");
4968 ifp
= netdev_priv(ndev
);
4969 wiphy
= brcmf_setup_wiphy(busdev
);
4973 cfg
= wiphy_priv(wiphy
);
4976 init_vif_event(&cfg
->vif_event
);
4977 INIT_LIST_HEAD(&cfg
->vif_list
);
4979 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
4986 vif
->wdev
.netdev
= ndev
;
4987 ndev
->ieee80211_ptr
= &vif
->wdev
;
4988 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
4990 err
= wl_init_priv(cfg
);
4992 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
4993 goto cfg80211_attach_out
;
4997 err
= brcmf_p2p_attach(cfg
);
4999 brcmf_err("P2P initilisation failed (%d)\n", err
);
5000 goto cfg80211_p2p_attach_out
;
5002 err
= brcmf_btcoex_attach(cfg
);
5004 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
5005 brcmf_p2p_detach(&cfg
->p2p
);
5006 goto cfg80211_p2p_attach_out
;
5009 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
5010 * setup 40MHz in 2GHz band and enable OBSS scanning.
5012 if (wiphy
->bands
[IEEE80211_BAND_2GHZ
]->ht_cap
.cap
&
5013 IEEE80211_HT_CAP_SUP_WIDTH_20_40
) {
5014 err
= brcmf_enable_bw40_2g(ifp
);
5016 err
= brcmf_fil_iovar_int_set(ifp
, "obss_coex",
5017 BRCMF_OBSS_COEX_AUTO
);
5020 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
5022 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
5023 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
5026 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
,
5029 brcmf_err("Failed to get D11 version (%d)\n", err
);
5030 goto cfg80211_p2p_attach_out
;
5032 cfg
->d11inf
.io_type
= (u8
)io_type
;
5033 brcmu_d11_attach(&cfg
->d11inf
);
5037 cfg80211_p2p_attach_out
:
5038 wl_deinit_priv(cfg
);
5040 cfg80211_attach_out
:
5041 brcmf_free_vif(vif
);
5045 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
5050 WARN_ON(!list_empty(&cfg
->vif_list
));
5051 wiphy_unregister(cfg
->wiphy
);
5052 brcmf_btcoex_detach(cfg
);
5053 wl_deinit_priv(cfg
);
5054 wiphy_free(cfg
->wiphy
);
5058 brcmf_dongle_roam(struct brcmf_if
*ifp
, u32 bcn_timeout
)
5061 __le32 roamtrigger
[2];
5062 __le32 roam_delta
[2];
5065 * Setup timeout if Beacons are lost and roam is
5066 * off to report link down
5068 if (brcmf_roamoff
) {
5069 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5071 brcmf_err("bcn_timeout error (%d)\n", err
);
5072 goto dongle_rom_out
;
5077 * Enable/Disable built-in roaming to allow supplicant
5078 * to take care of roaming
5080 brcmf_dbg(INFO
, "Internal Roaming = %s\n",
5081 brcmf_roamoff
? "Off" : "On");
5082 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off", !!(brcmf_roamoff
));
5084 brcmf_err("roam_off error (%d)\n", err
);
5085 goto dongle_rom_out
;
5088 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5089 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5090 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5091 (void *)roamtrigger
, sizeof(roamtrigger
));
5093 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5094 goto dongle_rom_out
;
5097 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5098 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5099 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5100 (void *)roam_delta
, sizeof(roam_delta
));
5102 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5103 goto dongle_rom_out
;
5111 brcmf_dongle_scantime(struct brcmf_if
*ifp
, s32 scan_assoc_time
,
5112 s32 scan_unassoc_time
, s32 scan_passive_time
)
5116 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5119 if (err
== -EOPNOTSUPP
)
5120 brcmf_dbg(INFO
, "Scan assoc time is not supported\n");
5122 brcmf_err("Scan assoc time error (%d)\n", err
);
5123 goto dongle_scantime_out
;
5125 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5128 if (err
== -EOPNOTSUPP
)
5129 brcmf_dbg(INFO
, "Scan unassoc time is not supported\n");
5131 brcmf_err("Scan unassoc time error (%d)\n", err
);
5132 goto dongle_scantime_out
;
5135 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5138 if (err
== -EOPNOTSUPP
)
5139 brcmf_dbg(INFO
, "Scan passive time is not supported\n");
5141 brcmf_err("Scan passive time error (%d)\n", err
);
5142 goto dongle_scantime_out
;
5145 dongle_scantime_out
:
5150 static s32
brcmf_construct_reginfo(struct brcmf_cfg80211_info
*cfg
,
5153 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5154 struct ieee80211_channel
*band_chan_arr
;
5155 struct brcmf_chanspec_list
*list
;
5156 struct brcmu_chan ch
;
5161 enum ieee80211_band band
;
5169 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5174 list
= (struct brcmf_chanspec_list
*)pbuf
;
5176 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5179 brcmf_err("get chanspecs error (%d)\n", err
);
5183 __wl_band_2ghz
.n_channels
= 0;
5184 __wl_band_5ghz_a
.n_channels
= 0;
5186 total
= le32_to_cpu(list
->count
);
5187 for (i
= 0; i
< total
; i
++) {
5188 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5189 cfg
->d11inf
.decchspec(&ch
);
5191 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5192 band_chan_arr
= __wl_2ghz_channels
;
5193 array_size
= ARRAY_SIZE(__wl_2ghz_channels
);
5194 n_cnt
= &__wl_band_2ghz
.n_channels
;
5195 band
= IEEE80211_BAND_2GHZ
;
5196 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5197 band_chan_arr
= __wl_5ghz_a_channels
;
5198 array_size
= ARRAY_SIZE(__wl_5ghz_a_channels
);
5199 n_cnt
= &__wl_band_5ghz_a
.n_channels
;
5200 band
= IEEE80211_BAND_5GHZ
;
5202 brcmf_err("Invalid channel Spec. 0x%x.\n", ch
.chspec
);
5205 if (!(bw_cap
[band
] & WLC_BW_40MHZ_BIT
) &&
5206 ch
.bw
== BRCMU_CHAN_BW_40
)
5209 for (j
= 0; (j
< *n_cnt
&& (*n_cnt
< array_size
)); j
++) {
5210 if (band_chan_arr
[j
].hw_value
== ch
.chnum
) {
5219 if (index
< array_size
) {
5220 band_chan_arr
[index
].center_freq
=
5221 ieee80211_channel_to_frequency(ch
.chnum
, band
);
5222 band_chan_arr
[index
].hw_value
= ch
.chnum
;
5224 if (ch
.bw
== BRCMU_CHAN_BW_40
) {
5225 /* assuming the order is HT20, HT40 Upper,
5226 * HT40 lower from chanspecs
5228 ht40_flag
= band_chan_arr
[index
].flags
&
5229 IEEE80211_CHAN_NO_HT40
;
5230 if (ch
.sb
== BRCMU_CHAN_SB_U
) {
5231 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5232 band_chan_arr
[index
].flags
&=
5233 ~IEEE80211_CHAN_NO_HT40
;
5234 band_chan_arr
[index
].flags
|=
5235 IEEE80211_CHAN_NO_HT40PLUS
;
5237 /* It should be one of
5238 * IEEE80211_CHAN_NO_HT40 or
5239 * IEEE80211_CHAN_NO_HT40PLUS
5241 band_chan_arr
[index
].flags
&=
5242 ~IEEE80211_CHAN_NO_HT40
;
5243 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5244 band_chan_arr
[index
].flags
|=
5245 IEEE80211_CHAN_NO_HT40MINUS
;
5248 band_chan_arr
[index
].flags
=
5249 IEEE80211_CHAN_NO_HT40
;
5250 ch
.bw
= BRCMU_CHAN_BW_20
;
5251 cfg
->d11inf
.encchspec(&ch
);
5252 channel
= ch
.chspec
;
5253 err
= brcmf_fil_bsscfg_int_get(ifp
,
5257 if (channel
& WL_CHAN_RADAR
)
5258 band_chan_arr
[index
].flags
|=
5259 (IEEE80211_CHAN_RADAR
|
5260 IEEE80211_CHAN_NO_IR
);
5261 if (channel
& WL_CHAN_PASSIVE
)
5262 band_chan_arr
[index
].flags
|=
5263 IEEE80211_CHAN_NO_IR
;
5275 static void brcmf_get_bwcap(struct brcmf_if
*ifp
, u32 bw_cap
[])
5277 u32 band
, mimo_bwcap
;
5281 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5283 bw_cap
[IEEE80211_BAND_2GHZ
] = band
;
5285 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5287 bw_cap
[IEEE80211_BAND_5GHZ
] = band
;
5293 brcmf_dbg(INFO
, "fallback to mimo_bw_cap info\n");
5295 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &mimo_bwcap
);
5297 /* assume 20MHz if firmware does not give a clue */
5298 mimo_bwcap
= WLC_N_BW_20ALL
;
5300 switch (mimo_bwcap
) {
5301 case WLC_N_BW_40ALL
:
5302 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_40MHZ_BIT
;
5304 case WLC_N_BW_20IN2G_40IN5G
:
5305 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_40MHZ_BIT
;
5307 case WLC_N_BW_20ALL
:
5308 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_20MHZ_BIT
;
5309 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_20MHZ_BIT
;
5312 brcmf_err("invalid mimo_bw_cap value\n");
5316 static s32
brcmf_update_wiphybands(struct brcmf_cfg80211_info
*cfg
)
5318 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5319 struct wiphy
*wiphy
;
5323 u32 bw_cap
[2] = { 0, 0 };
5330 struct ieee80211_supported_band
*bands
[2] = { NULL
, NULL
};
5331 struct ieee80211_supported_band
*band
;
5333 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_PHYLIST
,
5334 &phy_list
, sizeof(phy_list
));
5336 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err
);
5340 phy
= ((char *)&phy_list
)[0];
5341 brcmf_dbg(INFO
, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy
);
5344 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
,
5345 &band_list
, sizeof(band_list
));
5347 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err
);
5350 brcmf_dbg(INFO
, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5351 band_list
[0], band_list
[1], band_list
[2]);
5353 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
5355 brcmf_err("nmode error (%d)\n", err
);
5357 brcmf_get_bwcap(ifp
, bw_cap
);
5359 brcmf_dbg(INFO
, "nmode=%d, bw_cap=(%d, %d)\n", nmode
,
5360 bw_cap
[IEEE80211_BAND_2GHZ
], bw_cap
[IEEE80211_BAND_5GHZ
]);
5362 err
= brcmf_fil_iovar_int_get(ifp
, "rxchain", &rxchain
);
5364 brcmf_err("rxchain error (%d)\n", err
);
5367 for (nchain
= 0; rxchain
; nchain
++)
5368 rxchain
= rxchain
& (rxchain
- 1);
5370 brcmf_dbg(INFO
, "nchain=%d\n", nchain
);
5372 err
= brcmf_construct_reginfo(cfg
, bw_cap
);
5374 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err
);
5378 nband
= band_list
[0];
5380 for (i
= 1; i
<= nband
&& i
< ARRAY_SIZE(band_list
); i
++) {
5382 if ((band_list
[i
] == WLC_BAND_5G
) &&
5383 (__wl_band_5ghz_a
.n_channels
> 0))
5384 band
= &__wl_band_5ghz_a
;
5385 else if ((band_list
[i
] == WLC_BAND_2G
) &&
5386 (__wl_band_2ghz
.n_channels
> 0))
5387 band
= &__wl_band_2ghz
;
5391 if (bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) {
5392 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_40
;
5393 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
5395 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5396 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5397 band
->ht_cap
.ht_supported
= true;
5398 band
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5399 band
->ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5400 memset(band
->ht_cap
.mcs
.rx_mask
, 0xff, nchain
);
5401 band
->ht_cap
.mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
5402 bands
[band
->band
] = band
;
5405 wiphy
= cfg_to_wiphy(cfg
);
5406 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = bands
[IEEE80211_BAND_2GHZ
];
5407 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = bands
[IEEE80211_BAND_5GHZ
];
5408 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
5414 static s32
brcmf_dongle_probecap(struct brcmf_cfg80211_info
*cfg
)
5416 return brcmf_update_wiphybands(cfg
);
5419 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
5421 struct net_device
*ndev
;
5422 struct wireless_dev
*wdev
;
5423 struct brcmf_if
*ifp
;
5430 ndev
= cfg_to_ndev(cfg
);
5431 wdev
= ndev
->ieee80211_ptr
;
5432 ifp
= netdev_priv(ndev
);
5434 /* make sure RF is ready for work */
5435 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
5437 brcmf_dongle_scantime(ifp
, WL_SCAN_CHANNEL_TIME
,
5438 WL_SCAN_UNASSOC_TIME
, WL_SCAN_PASSIVE_TIME
);
5440 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
5441 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
5443 goto default_conf_out
;
5444 brcmf_dbg(INFO
, "power save set to %s\n",
5445 (power_mode
? "enabled" : "disabled"));
5447 err
= brcmf_dongle_roam(ifp
, WL_BEACON_TIMEOUT
);
5449 goto default_conf_out
;
5450 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
5453 goto default_conf_out
;
5454 err
= brcmf_dongle_probecap(cfg
);
5456 goto default_conf_out
;
5458 brcmf_configure_arp_offload(ifp
, true);
5460 cfg
->dongle_up
= true;
5467 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
5469 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5471 return brcmf_config_dongle(ifp
->drvr
->config
);
5474 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
5476 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5479 * While going down, if associated with AP disassociate
5480 * from AP to save power
5482 if (check_vif_up(ifp
->vif
)) {
5483 brcmf_link_down(ifp
->vif
);
5485 /* Make sure WPA_Supplicant receives all the event
5486 generated due to DISASSOC call to the fw to keep
5487 the state fw and WPA_Supplicant state consistent
5492 brcmf_abort_scanning(cfg
);
5493 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
5498 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
5500 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5501 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5504 mutex_lock(&cfg
->usr_sync
);
5505 err
= __brcmf_cfg80211_up(ifp
);
5506 mutex_unlock(&cfg
->usr_sync
);
5511 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
5513 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5514 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5517 mutex_lock(&cfg
->usr_sync
);
5518 err
= __brcmf_cfg80211_down(ifp
);
5519 mutex_unlock(&cfg
->usr_sync
);
5524 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
5526 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
5528 return wdev
->iftype
;
5531 u32
wl_get_vif_state_all(struct brcmf_cfg80211_info
*cfg
, unsigned long state
)
5533 struct brcmf_cfg80211_vif
*vif
;
5536 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
5537 if (test_bit(state
, &vif
->sme_state
))
5543 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
5548 mutex_lock(&event
->vif_event_lock
);
5549 evt_action
= event
->action
;
5550 mutex_unlock(&event
->vif_event_lock
);
5551 return evt_action
== action
;
5554 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
5555 struct brcmf_cfg80211_vif
*vif
)
5557 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5559 mutex_lock(&event
->vif_event_lock
);
5562 mutex_unlock(&event
->vif_event_lock
);
5565 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
5567 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5570 mutex_lock(&event
->vif_event_lock
);
5571 armed
= event
->vif
!= NULL
;
5572 mutex_unlock(&event
->vif_event_lock
);
5576 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
5577 u8 action
, ulong timeout
)
5579 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5581 return wait_event_timeout(event
->vif_wq
,
5582 vif_event_equals(event
, action
), timeout
);