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 <linux/vmalloc.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
26 #include <brcmu_utils.h>
28 #include <brcmu_wifi.h>
31 #include "tracepoint.h"
32 #include "fwil_types.h"
43 #define BRCMF_SCAN_IE_LEN_MAX 2048
44 #define BRCMF_PNO_VERSION 2
45 #define BRCMF_PNO_TIME 30
46 #define BRCMF_PNO_REPEAT 4
47 #define BRCMF_PNO_FREQ_EXPO_MAX 3
48 #define BRCMF_PNO_MAX_PFN_COUNT 16
49 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
50 #define BRCMF_PNO_HIDDEN_BIT 2
51 #define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
52 #define BRCMF_PNO_SCAN_COMPLETE 1
53 #define BRCMF_PNO_SCAN_INCOMPLETE 0
55 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
56 #define WPA_OUI_TYPE 1
57 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
58 #define WME_OUI_TYPE 2
59 #define WPS_OUI_TYPE 4
61 #define VS_IE_FIXED_HDR_LEN 6
62 #define WPA_IE_VERSION_LEN 2
63 #define WPA_IE_MIN_OUI_LEN 4
64 #define WPA_IE_SUITE_COUNT_LEN 2
66 #define WPA_CIPHER_NONE 0 /* None */
67 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
72 #define RSN_AKM_NONE 0 /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
74 #define RSN_AKM_PSK 2 /* Pre-shared Key */
75 #define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
76 #define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
77 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
78 #define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
79 #define RSN_CAP_MFPR_MASK BIT(6)
80 #define RSN_CAP_MFPC_MASK BIT(7)
81 #define RSN_PMKID_COUNT_LEN 2
83 #define VNDR_IE_CMD_LEN 4 /* length of the set command
84 * string :"add", "del" (+ NUL)
86 #define VNDR_IE_COUNT_OFFSET 4
87 #define VNDR_IE_PKTFLAG_OFFSET 8
88 #define VNDR_IE_VSIE_OFFSET 12
89 #define VNDR_IE_HDR_SIZE 12
90 #define VNDR_IE_PARSE_LIMIT 5
92 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
93 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
95 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
96 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
97 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
99 #define BRCMF_SCAN_CHANNEL_TIME 40
100 #define BRCMF_SCAN_UNASSOC_TIME 40
101 #define BRCMF_SCAN_PASSIVE_TIME 120
103 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
105 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
106 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
108 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
110 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
111 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
118 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
119 #define RATETAB_ENT(_rateid, _flags) \
121 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
122 .hw_value = (_rateid), \
126 static struct ieee80211_rate __wl_rates
[] = {
127 RATETAB_ENT(BRCM_RATE_1M
, 0),
128 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
129 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
130 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
131 RATETAB_ENT(BRCM_RATE_6M
, 0),
132 RATETAB_ENT(BRCM_RATE_9M
, 0),
133 RATETAB_ENT(BRCM_RATE_12M
, 0),
134 RATETAB_ENT(BRCM_RATE_18M
, 0),
135 RATETAB_ENT(BRCM_RATE_24M
, 0),
136 RATETAB_ENT(BRCM_RATE_36M
, 0),
137 RATETAB_ENT(BRCM_RATE_48M
, 0),
138 RATETAB_ENT(BRCM_RATE_54M
, 0),
141 #define wl_g_rates (__wl_rates + 0)
142 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
143 #define wl_a_rates (__wl_rates + 4)
144 #define wl_a_rates_size (wl_g_rates_size - 4)
146 #define CHAN2G(_channel, _freq) { \
147 .band = NL80211_BAND_2GHZ, \
148 .center_freq = (_freq), \
149 .hw_value = (_channel), \
150 .flags = IEEE80211_CHAN_DISABLED, \
151 .max_antenna_gain = 0, \
155 #define CHAN5G(_channel) { \
156 .band = NL80211_BAND_5GHZ, \
157 .center_freq = 5000 + (5 * (_channel)), \
158 .hw_value = (_channel), \
159 .flags = IEEE80211_CHAN_DISABLED, \
160 .max_antenna_gain = 0, \
164 static struct ieee80211_channel __wl_2ghz_channels
[] = {
165 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
166 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
167 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
168 CHAN2G(13, 2472), CHAN2G(14, 2484)
171 static struct ieee80211_channel __wl_5ghz_channels
[] = {
172 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
173 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
174 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
175 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
176 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
177 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
180 /* Band templates duplicated per wiphy. The channel info
181 * above is added to the band during setup.
183 static const struct ieee80211_supported_band __wl_band_2ghz
= {
184 .band
= NL80211_BAND_2GHZ
,
185 .bitrates
= wl_g_rates
,
186 .n_bitrates
= wl_g_rates_size
,
189 static const struct ieee80211_supported_band __wl_band_5ghz
= {
190 .band
= NL80211_BAND_5GHZ
,
191 .bitrates
= wl_a_rates
,
192 .n_bitrates
= wl_a_rates_size
,
195 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
196 * By default world regulatory domain defined in reg.c puts the flags
197 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
198 * With respect to these flags, wpa_supplicant doesn't * start p2p
199 * operations on 5GHz channels. All the changes in world regulatory
200 * domain are to be done here.
202 static const struct ieee80211_regdomain brcmf_regdom
= {
206 /* IEEE 802.11b/g, channels 1..11 */
207 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
209 /* IEEE 802.11 channel 14 - Only JP enables
210 * this and for 802.11b only
212 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
213 /* IEEE 802.11a, channel 36..64 */
214 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
215 /* IEEE 802.11a, channel 100..165 */
216 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
219 /* Note: brcmf_cipher_suites is an array of int defining which cipher suites
220 * are supported. A pointer to this array and the number of entries is passed
221 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
222 * So the cipher suite AES_CMAC has to be the last one in the array, and when
223 * device does not support MFP then the number of suites will be decreased by 1
225 static const u32 brcmf_cipher_suites
[] = {
226 WLAN_CIPHER_SUITE_WEP40
,
227 WLAN_CIPHER_SUITE_WEP104
,
228 WLAN_CIPHER_SUITE_TKIP
,
229 WLAN_CIPHER_SUITE_CCMP
,
230 /* Keep as last entry: */
231 WLAN_CIPHER_SUITE_AES_CMAC
234 /* Vendor specific ie. id = 221, oui and type defines exact ie */
235 struct brcmf_vs_tlv
{
242 struct parsed_vndr_ie_info
{
244 u32 ie_len
; /* total length including id & length field */
245 struct brcmf_vs_tlv vndrie
;
248 struct parsed_vndr_ies
{
250 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
253 static u8
nl80211_band_to_fwil(enum nl80211_band band
)
256 case NL80211_BAND_2GHZ
:
258 case NL80211_BAND_5GHZ
:
267 static u16
chandef_to_chanspec(struct brcmu_d11inf
*d11inf
,
268 struct cfg80211_chan_def
*ch
)
270 struct brcmu_chan ch_inf
;
273 brcmf_dbg(TRACE
, "chandef: control %d center %d width %d\n",
274 ch
->chan
->center_freq
, ch
->center_freq1
, ch
->width
);
275 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq1
);
276 primary_offset
= ch
->chan
->center_freq
- ch
->center_freq1
;
278 case NL80211_CHAN_WIDTH_20
:
279 case NL80211_CHAN_WIDTH_20_NOHT
:
280 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
281 WARN_ON(primary_offset
!= 0);
283 case NL80211_CHAN_WIDTH_40
:
284 ch_inf
.bw
= BRCMU_CHAN_BW_40
;
285 if (primary_offset
> 0)
286 ch_inf
.sb
= BRCMU_CHAN_SB_U
;
288 ch_inf
.sb
= BRCMU_CHAN_SB_L
;
290 case NL80211_CHAN_WIDTH_80
:
291 ch_inf
.bw
= BRCMU_CHAN_BW_80
;
292 if (primary_offset
== -30)
293 ch_inf
.sb
= BRCMU_CHAN_SB_LL
;
294 else if (primary_offset
== -10)
295 ch_inf
.sb
= BRCMU_CHAN_SB_LU
;
296 else if (primary_offset
== 10)
297 ch_inf
.sb
= BRCMU_CHAN_SB_UL
;
299 ch_inf
.sb
= BRCMU_CHAN_SB_UU
;
301 case NL80211_CHAN_WIDTH_80P80
:
302 case NL80211_CHAN_WIDTH_160
:
303 case NL80211_CHAN_WIDTH_5
:
304 case NL80211_CHAN_WIDTH_10
:
308 switch (ch
->chan
->band
) {
309 case NL80211_BAND_2GHZ
:
310 ch_inf
.band
= BRCMU_CHAN_BAND_2G
;
312 case NL80211_BAND_5GHZ
:
313 ch_inf
.band
= BRCMU_CHAN_BAND_5G
;
315 case NL80211_BAND_60GHZ
:
319 d11inf
->encchspec(&ch_inf
);
321 return ch_inf
.chspec
;
324 u16
channel_to_chanspec(struct brcmu_d11inf
*d11inf
,
325 struct ieee80211_channel
*ch
)
327 struct brcmu_chan ch_inf
;
329 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq
);
330 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
331 d11inf
->encchspec(&ch_inf
);
333 return ch_inf
.chspec
;
336 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
337 * triples, returning a pointer to the substring whose first element
340 const struct brcmf_tlv
*
341 brcmf_parse_tlvs(const void *buf
, int buflen
, uint key
)
343 const struct brcmf_tlv
*elt
= buf
;
346 /* find tagged parameter */
347 while (totlen
>= TLV_HDR_LEN
) {
350 /* validate remaining totlen */
351 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
354 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
355 totlen
-= (len
+ TLV_HDR_LEN
);
361 /* Is any of the tlvs the expected entry? If
362 * not update the tlvs buffer pointer/length.
365 brcmf_tlv_has_ie(const u8
*ie
, const u8
**tlvs
, u32
*tlvs_len
,
366 const u8
*oui
, u32 oui_len
, u8 type
)
368 /* If the contents match the OUI and the type */
369 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
370 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
371 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
377 /* point to the next ie */
378 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
379 /* calculate the length of the rest of the buffer */
380 *tlvs_len
-= (int)(ie
- *tlvs
);
381 /* update the pointer to the start of the buffer */
387 static struct brcmf_vs_tlv
*
388 brcmf_find_wpaie(const u8
*parse
, u32 len
)
390 const struct brcmf_tlv
*ie
;
392 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
393 if (brcmf_tlv_has_ie((const u8
*)ie
, &parse
, &len
,
394 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
395 return (struct brcmf_vs_tlv
*)ie
;
400 static struct brcmf_vs_tlv
*
401 brcmf_find_wpsie(const u8
*parse
, u32 len
)
403 const struct brcmf_tlv
*ie
;
405 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
406 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
407 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
408 return (struct brcmf_vs_tlv
*)ie
;
413 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info
*cfg
,
414 struct brcmf_cfg80211_vif
*vif
,
415 enum nl80211_iftype new_type
)
417 int iftype_num
[NUM_NL80211_IFTYPES
];
418 struct brcmf_cfg80211_vif
*pos
;
419 bool check_combos
= false;
422 memset(&iftype_num
[0], 0, sizeof(iftype_num
));
423 list_for_each_entry(pos
, &cfg
->vif_list
, list
)
425 iftype_num
[new_type
]++;
427 /* concurrent interfaces so need check combinations */
429 iftype_num
[pos
->wdev
.iftype
]++;
433 ret
= cfg80211_check_combinations(cfg
->wiphy
, 1, 0, iftype_num
);
438 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info
*cfg
,
439 enum nl80211_iftype new_type
)
441 int iftype_num
[NUM_NL80211_IFTYPES
];
442 struct brcmf_cfg80211_vif
*pos
;
444 memset(&iftype_num
[0], 0, sizeof(iftype_num
));
445 list_for_each_entry(pos
, &cfg
->vif_list
, list
)
446 iftype_num
[pos
->wdev
.iftype
]++;
448 iftype_num
[new_type
]++;
449 return cfg80211_check_combinations(cfg
->wiphy
, 1, 0, iftype_num
);
452 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
453 struct brcmf_wsec_key_le
*key_le
)
455 key_le
->index
= cpu_to_le32(key
->index
);
456 key_le
->len
= cpu_to_le32(key
->len
);
457 key_le
->algo
= cpu_to_le32(key
->algo
);
458 key_le
->flags
= cpu_to_le32(key
->flags
);
459 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
460 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
461 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
462 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
463 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
467 send_key_to_dongle(struct brcmf_if
*ifp
, struct brcmf_wsec_key
*key
)
470 struct brcmf_wsec_key_le key_le
;
472 convert_key_from_CPU(key
, &key_le
);
474 brcmf_netdev_wait_pend8021x(ifp
);
476 err
= brcmf_fil_bsscfg_data_set(ifp
, "wsec_key", &key_le
,
480 brcmf_err("wsec_key error (%d)\n", err
);
485 brcmf_configure_arp_nd_offload(struct brcmf_if
*ifp
, bool enable
)
491 mode
= BRCMF_ARP_OL_AGENT
| BRCMF_ARP_OL_PEER_AUTO_REPLY
;
495 /* Try to set and enable ARP offload feature, this may fail, then it */
496 /* is simply not supported and err 0 will be returned */
497 err
= brcmf_fil_iovar_int_set(ifp
, "arp_ol", mode
);
499 brcmf_dbg(TRACE
, "failed to set ARP offload mode to 0x%x, err = %d\n",
503 err
= brcmf_fil_iovar_int_set(ifp
, "arpoe", enable
);
505 brcmf_dbg(TRACE
, "failed to configure (%d) ARP offload err = %d\n",
509 brcmf_dbg(TRACE
, "successfully configured (%d) ARP offload to 0x%x\n",
513 err
= brcmf_fil_iovar_int_set(ifp
, "ndoe", enable
);
515 brcmf_dbg(TRACE
, "failed to configure (%d) ND offload err = %d\n",
519 brcmf_dbg(TRACE
, "successfully configured (%d) ND offload to 0x%x\n",
526 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev
*wdev
)
528 struct brcmf_cfg80211_vif
*vif
;
529 struct brcmf_if
*ifp
;
531 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
534 if ((wdev
->iftype
== NL80211_IFTYPE_ADHOC
) ||
535 (wdev
->iftype
== NL80211_IFTYPE_AP
) ||
536 (wdev
->iftype
== NL80211_IFTYPE_P2P_GO
))
537 brcmf_proto_configure_addr_mode(ifp
->drvr
, ifp
->ifidx
,
540 brcmf_proto_configure_addr_mode(ifp
->drvr
, ifp
->ifidx
,
544 static int brcmf_cfg80211_request_ap_if(struct brcmf_if
*ifp
)
546 struct brcmf_mbss_ssid_le mbss_ssid_le
;
550 memset(&mbss_ssid_le
, 0, sizeof(mbss_ssid_le
));
551 bsscfgidx
= brcmf_get_next_free_bsscfgidx(ifp
->drvr
);
555 mbss_ssid_le
.bsscfgidx
= cpu_to_le32(bsscfgidx
);
556 mbss_ssid_le
.SSID_len
= cpu_to_le32(5);
557 sprintf(mbss_ssid_le
.SSID
, "ssid%d" , bsscfgidx
);
559 err
= brcmf_fil_bsscfg_data_set(ifp
, "bsscfg:ssid", &mbss_ssid_le
,
560 sizeof(mbss_ssid_le
));
562 brcmf_err("setting ssid failed %d\n", err
);
568 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
570 * @wiphy: wiphy device of new interface.
571 * @name: name of the new interface.
573 * @params: contains mac address for AP device.
576 struct wireless_dev
*brcmf_ap_add_vif(struct wiphy
*wiphy
, const char *name
,
577 u32
*flags
, struct vif_params
*params
)
579 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
580 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
581 struct brcmf_cfg80211_vif
*vif
;
584 if (brcmf_cfg80211_vif_event_armed(cfg
))
585 return ERR_PTR(-EBUSY
);
587 brcmf_dbg(INFO
, "Adding vif \"%s\"\n", name
);
589 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_AP
, false);
591 return (struct wireless_dev
*)vif
;
593 brcmf_cfg80211_arm_vif_event(cfg
, vif
);
595 err
= brcmf_cfg80211_request_ap_if(ifp
);
597 brcmf_cfg80211_arm_vif_event(cfg
, NULL
);
601 /* wait for firmware event */
602 err
= brcmf_cfg80211_wait_vif_event(cfg
, BRCMF_E_IF_ADD
,
603 BRCMF_VIF_EVENT_TIMEOUT
);
604 brcmf_cfg80211_arm_vif_event(cfg
, NULL
);
606 brcmf_err("timeout occurred\n");
611 /* interface created in firmware */
614 brcmf_err("no if pointer provided\n");
619 strncpy(ifp
->ndev
->name
, name
, sizeof(ifp
->ndev
->name
) - 1);
620 err
= brcmf_net_attach(ifp
, true);
622 brcmf_err("Registering netdevice failed\n");
626 return &ifp
->vif
->wdev
;
633 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif
*vif
)
635 enum nl80211_iftype iftype
;
637 iftype
= vif
->wdev
.iftype
;
638 return iftype
== NL80211_IFTYPE_AP
|| iftype
== NL80211_IFTYPE_P2P_GO
;
641 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
643 return vif
->wdev
.iftype
== NL80211_IFTYPE_ADHOC
;
646 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
648 unsigned char name_assign_type
,
649 enum nl80211_iftype type
,
651 struct vif_params
*params
)
653 struct wireless_dev
*wdev
;
656 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
657 err
= brcmf_vif_add_validate(wiphy_to_cfg(wiphy
), type
);
659 brcmf_err("iface validation failed: err=%d\n", err
);
663 case NL80211_IFTYPE_ADHOC
:
664 case NL80211_IFTYPE_STATION
:
665 case NL80211_IFTYPE_AP_VLAN
:
666 case NL80211_IFTYPE_WDS
:
667 case NL80211_IFTYPE_MONITOR
:
668 case NL80211_IFTYPE_MESH_POINT
:
669 return ERR_PTR(-EOPNOTSUPP
);
670 case NL80211_IFTYPE_AP
:
671 wdev
= brcmf_ap_add_vif(wiphy
, name
, flags
, params
);
673 brcmf_cfg80211_update_proto_addr_mode(wdev
);
675 case NL80211_IFTYPE_P2P_CLIENT
:
676 case NL80211_IFTYPE_P2P_GO
:
677 case NL80211_IFTYPE_P2P_DEVICE
:
678 wdev
= brcmf_p2p_add_vif(wiphy
, name
, name_assign_type
, type
, flags
, params
);
680 brcmf_cfg80211_update_proto_addr_mode(wdev
);
682 case NL80211_IFTYPE_UNSPECIFIED
:
684 return ERR_PTR(-EINVAL
);
688 static void brcmf_scan_config_mpc(struct brcmf_if
*ifp
, int mpc
)
690 if (brcmf_feat_is_quirk_enabled(ifp
, BRCMF_FEAT_QUIRK_NEED_MPC
))
691 brcmf_set_mpc(ifp
, mpc
);
694 void brcmf_set_mpc(struct brcmf_if
*ifp
, int mpc
)
698 if (check_vif_up(ifp
->vif
)) {
699 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
701 brcmf_err("fail to set mpc\n");
704 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
708 s32
brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
709 struct brcmf_if
*ifp
, bool aborted
,
712 struct brcmf_scan_params_le params_le
;
713 struct cfg80211_scan_request
*scan_request
;
716 brcmf_dbg(SCAN
, "Enter\n");
718 /* clear scan request, because the FW abort can cause a second call */
719 /* to this functon and might cause a double cfg80211_scan_done */
720 scan_request
= cfg
->scan_request
;
721 cfg
->scan_request
= NULL
;
723 if (timer_pending(&cfg
->escan_timeout
))
724 del_timer_sync(&cfg
->escan_timeout
);
727 /* Do a scan abort to stop the driver's scan engine */
728 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
729 memset(¶ms_le
, 0, sizeof(params_le
));
730 eth_broadcast_addr(params_le
.bssid
);
731 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
732 params_le
.scan_type
= 0;
733 params_le
.channel_num
= cpu_to_le32(1);
734 params_le
.nprobes
= cpu_to_le32(1);
735 params_le
.active_time
= cpu_to_le32(-1);
736 params_le
.passive_time
= cpu_to_le32(-1);
737 params_le
.home_time
= cpu_to_le32(-1);
738 /* Scan is aborted by setting channel_list[0] to -1 */
739 params_le
.channel_list
[0] = cpu_to_le16(-1);
740 /* E-Scan (or anyother type) can be aborted by SCAN */
741 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
742 ¶ms_le
, sizeof(params_le
));
744 brcmf_err("Scan abort failed\n");
747 brcmf_scan_config_mpc(ifp
, 1);
750 * e-scan can be initiated by scheduled scan
751 * which takes precedence.
753 if (cfg
->sched_escan
) {
754 brcmf_dbg(SCAN
, "scheduled scan completed\n");
755 cfg
->sched_escan
= false;
757 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
758 } else if (scan_request
) {
759 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
760 aborted
? "Aborted" : "Done");
761 cfg80211_scan_done(scan_request
, aborted
);
763 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
764 brcmf_dbg(SCAN
, "Scan complete, probably P2P scan\n");
770 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
772 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
773 struct net_device
*ndev
= wdev
->netdev
;
775 /* vif event pending in firmware */
776 if (brcmf_cfg80211_vif_event_armed(cfg
))
780 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
781 cfg
->escan_info
.ifp
== netdev_priv(ndev
))
782 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
),
785 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
788 switch (wdev
->iftype
) {
789 case NL80211_IFTYPE_ADHOC
:
790 case NL80211_IFTYPE_STATION
:
791 case NL80211_IFTYPE_AP
:
792 case NL80211_IFTYPE_AP_VLAN
:
793 case NL80211_IFTYPE_WDS
:
794 case NL80211_IFTYPE_MONITOR
:
795 case NL80211_IFTYPE_MESH_POINT
:
797 case NL80211_IFTYPE_P2P_CLIENT
:
798 case NL80211_IFTYPE_P2P_GO
:
799 case NL80211_IFTYPE_P2P_DEVICE
:
800 return brcmf_p2p_del_vif(wiphy
, wdev
);
801 case NL80211_IFTYPE_UNSPECIFIED
:
809 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
810 enum nl80211_iftype type
, u32
*flags
,
811 struct vif_params
*params
)
813 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
814 struct brcmf_if
*ifp
= netdev_priv(ndev
);
815 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
820 brcmf_dbg(TRACE
, "Enter, bsscfgidx=%d, type=%d\n", ifp
->bsscfgidx
,
823 /* WAR: There are a number of p2p interface related problems which
824 * need to be handled initially (before doing the validate).
825 * wpa_supplicant tends to do iface changes on p2p device/client/go
826 * which are not always possible/allowed. However we need to return
827 * OK otherwise the wpa_supplicant wont start. The situation differs
828 * on configuration and setup (p2pon=1 module param). The first check
829 * is to see if the request is a change to station for p2p iface.
831 if ((type
== NL80211_IFTYPE_STATION
) &&
832 ((vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) ||
833 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
) ||
834 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_DEVICE
))) {
835 brcmf_dbg(TRACE
, "Ignoring cmd for p2p if\n");
836 /* Now depending on whether module param p2pon=1 was used the
837 * response needs to be either 0 or EOPNOTSUPP. The reason is
838 * that if p2pon=1 is used, but a newer supplicant is used then
839 * we should return an error, as this combination wont work.
840 * In other situations 0 is returned and supplicant will start
841 * normally. It will give a trace in cfg80211, but it is the
842 * only way to get it working. Unfortunately this will result
843 * in situation where we wont support new supplicant in
844 * combination with module param p2pon=1, but that is the way
845 * it is. If the user tries this then unloading of driver might
848 if (cfg
->p2p
.p2pdev_dynamically
)
853 err
= brcmf_vif_change_validate(wiphy_to_cfg(wiphy
), vif
, type
);
855 brcmf_err("iface validation failed: err=%d\n", err
);
859 case NL80211_IFTYPE_MONITOR
:
860 case NL80211_IFTYPE_WDS
:
861 brcmf_err("type (%d) : currently we do not support this type\n",
864 case NL80211_IFTYPE_ADHOC
:
867 case NL80211_IFTYPE_STATION
:
870 case NL80211_IFTYPE_AP
:
871 case NL80211_IFTYPE_P2P_GO
:
880 if (type
== NL80211_IFTYPE_P2P_GO
) {
881 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
882 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
885 brcmf_dbg(INFO
, "IF Type = AP\n");
888 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
890 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
894 brcmf_dbg(INFO
, "IF Type = %s\n", brcmf_is_ibssmode(vif
) ?
897 ndev
->ieee80211_ptr
->iftype
= type
;
899 brcmf_cfg80211_update_proto_addr_mode(&vif
->wdev
);
902 brcmf_dbg(TRACE
, "Exit\n");
907 static void brcmf_escan_prep(struct brcmf_cfg80211_info
*cfg
,
908 struct brcmf_scan_params_le
*params_le
,
909 struct cfg80211_scan_request
*request
)
917 struct brcmf_ssid_le ssid_le
;
919 eth_broadcast_addr(params_le
->bssid
);
920 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
921 params_le
->scan_type
= 0;
922 params_le
->channel_num
= 0;
923 params_le
->nprobes
= cpu_to_le32(-1);
924 params_le
->active_time
= cpu_to_le32(-1);
925 params_le
->passive_time
= cpu_to_le32(-1);
926 params_le
->home_time
= cpu_to_le32(-1);
927 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
929 /* if request is null exit so it will be all channel broadcast scan */
933 n_ssids
= request
->n_ssids
;
934 n_channels
= request
->n_channels
;
935 /* Copy channel array if applicable */
936 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
938 if (n_channels
> 0) {
939 for (i
= 0; i
< n_channels
; i
++) {
940 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
941 request
->channels
[i
]);
942 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
943 request
->channels
[i
]->hw_value
, chanspec
);
944 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
947 brcmf_dbg(SCAN
, "Scanning all channels\n");
949 /* Copy ssid array if applicable */
950 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
952 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
953 n_channels
* sizeof(u16
);
954 offset
= roundup(offset
, sizeof(u32
));
955 ptr
= (char *)params_le
+ offset
;
956 for (i
= 0; i
< n_ssids
; i
++) {
957 memset(&ssid_le
, 0, sizeof(ssid_le
));
959 cpu_to_le32(request
->ssids
[i
].ssid_len
);
960 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
961 request
->ssids
[i
].ssid_len
);
962 if (!ssid_le
.SSID_len
)
963 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
965 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
966 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
967 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
968 ptr
+= sizeof(ssid_le
);
971 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
972 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
973 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
974 params_le
->ssid_le
.SSID
,
975 request
->ssids
->ssid_len
);
976 params_le
->ssid_le
.SSID_len
=
977 cpu_to_le32(request
->ssids
->ssid_len
);
978 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
979 request
->ssids
->ssid_len
);
982 /* Adding mask to channel numbers */
983 params_le
->channel_num
=
984 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
985 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
989 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
,
990 struct cfg80211_scan_request
*request
)
992 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
993 offsetof(struct brcmf_escan_params_le
, params_le
);
994 struct brcmf_escan_params_le
*params
;
997 brcmf_dbg(SCAN
, "E-SCAN START\n");
999 if (request
!= NULL
) {
1000 /* Allocate space for populating ssids in struct */
1001 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
1003 /* Allocate space for populating ssids in struct */
1004 params_size
+= sizeof(struct brcmf_ssid_le
) * request
->n_ssids
;
1007 params
= kzalloc(params_size
, GFP_KERNEL
);
1012 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
1013 brcmf_escan_prep(cfg
, ¶ms
->params_le
, request
);
1014 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
1015 params
->action
= cpu_to_le16(WL_ESCAN_ACTION_START
);
1016 params
->sync_id
= cpu_to_le16(0x1234);
1018 err
= brcmf_fil_iovar_data_set(ifp
, "escan", params
, params_size
);
1021 brcmf_dbg(INFO
, "system busy : escan canceled\n");
1023 brcmf_err("error (%d)\n", err
);
1032 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
1033 struct brcmf_if
*ifp
, struct cfg80211_scan_request
*request
)
1037 struct brcmf_scan_results
*results
;
1038 struct escan_info
*escan
= &cfg
->escan_info
;
1040 brcmf_dbg(SCAN
, "Enter\n");
1042 escan
->wiphy
= wiphy
;
1043 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
1044 passive_scan
= cfg
->active_scan
? 0 : 1;
1045 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
1048 brcmf_err("error (%d)\n", err
);
1051 brcmf_scan_config_mpc(ifp
, 0);
1052 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
1053 results
->version
= 0;
1055 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
1057 err
= escan
->run(cfg
, ifp
, request
);
1059 brcmf_scan_config_mpc(ifp
, 1);
1064 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct brcmf_cfg80211_vif
*vif
,
1065 struct cfg80211_scan_request
*request
,
1066 struct cfg80211_ssid
*this_ssid
)
1068 struct brcmf_if
*ifp
= vif
->ifp
;
1069 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1070 struct cfg80211_ssid
*ssids
;
1075 struct brcmf_ssid_le ssid_le
;
1078 brcmf_dbg(SCAN
, "START ESCAN\n");
1080 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
1081 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
1084 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
1085 brcmf_err("Scanning being aborted: status (%lu)\n",
1089 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
1090 brcmf_err("Scanning suppressed: status (%lu)\n",
1094 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
1095 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
1099 /* If scan req comes for p2p0, send it over primary I/F */
1100 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
1101 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
;
1106 ssids
= request
->ssids
;
1110 /* we don't do escan in ibss */
1114 cfg
->scan_request
= request
;
1115 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
1117 cfg
->escan_info
.run
= brcmf_run_escan
;
1118 err
= brcmf_p2p_scan_prep(wiphy
, request
, vif
);
1122 err
= brcmf_do_escan(cfg
, wiphy
, vif
->ifp
, request
);
1126 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
1127 ssids
->ssid
, ssids
->ssid_len
);
1128 memset(&ssid_le
, 0, sizeof(ssid_le
));
1129 SSID_len
= min_t(u8
, sizeof(ssid_le
.SSID
), ssids
->ssid_len
);
1130 ssid_le
.SSID_len
= cpu_to_le32(0);
1133 memcpy(ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
1134 ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
1137 brcmf_dbg(SCAN
, "Broadcast scan\n");
1139 passive_scan
= cfg
->active_scan
? 0 : 1;
1140 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
1143 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
1146 brcmf_scan_config_mpc(ifp
, 0);
1147 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
, &ssid_le
,
1151 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
1154 brcmf_err("WLC_SCAN error (%d)\n", err
);
1156 brcmf_scan_config_mpc(ifp
, 1);
1161 /* Arm scan timeout timer */
1162 mod_timer(&cfg
->escan_timeout
, jiffies
+
1163 BRCMF_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
1168 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
1169 cfg
->scan_request
= NULL
;
1174 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
1176 struct brcmf_cfg80211_vif
*vif
;
1179 brcmf_dbg(TRACE
, "Enter\n");
1180 vif
= container_of(request
->wdev
, struct brcmf_cfg80211_vif
, wdev
);
1181 if (!check_vif_up(vif
))
1184 err
= brcmf_cfg80211_escan(wiphy
, vif
, request
, NULL
);
1187 brcmf_err("scan error (%d)\n", err
);
1189 brcmf_dbg(TRACE
, "Exit\n");
1193 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1197 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1200 brcmf_err("Error (%d)\n", err
);
1205 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1209 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1212 brcmf_err("Error (%d)\n", err
);
1217 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1220 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1222 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1224 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1230 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1232 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1233 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1234 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1237 brcmf_dbg(TRACE
, "Enter\n");
1238 if (!check_vif_up(ifp
->vif
))
1241 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1242 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1243 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1244 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1248 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1249 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1250 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1251 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1255 if (changed
& WIPHY_PARAM_RETRY_LONG
1256 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1257 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1258 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1262 if (changed
& WIPHY_PARAM_RETRY_SHORT
1263 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1264 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1265 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1271 brcmf_dbg(TRACE
, "Exit\n");
1275 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1277 memset(prof
, 0, sizeof(*prof
));
1280 static u16
brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg
*e
)
1284 switch (e
->event_code
) {
1285 case BRCMF_E_DEAUTH
:
1286 case BRCMF_E_DEAUTH_IND
:
1287 case BRCMF_E_DISASSOC_IND
:
1298 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
, u16 reason
)
1300 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(vif
->wdev
.wiphy
);
1303 brcmf_dbg(TRACE
, "Enter\n");
1305 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1306 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1307 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1308 BRCMF_C_DISASSOC
, NULL
, 0);
1310 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1312 if ((vif
->wdev
.iftype
== NL80211_IFTYPE_STATION
) ||
1313 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
))
1314 cfg80211_disconnected(vif
->wdev
.netdev
, reason
, NULL
, 0,
1317 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1318 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
1319 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
1320 brcmf_dbg(TRACE
, "Exit\n");
1324 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1325 struct cfg80211_ibss_params
*params
)
1327 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1328 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1329 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1330 struct brcmf_join_params join_params
;
1331 size_t join_params_size
= 0;
1338 brcmf_dbg(TRACE
, "Enter\n");
1339 if (!check_vif_up(ifp
->vif
))
1343 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1345 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1349 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1352 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1354 brcmf_dbg(CONN
, "No BSSID specified\n");
1356 if (params
->chandef
.chan
)
1357 brcmf_dbg(CONN
, "channel: %d\n",
1358 params
->chandef
.chan
->center_freq
);
1360 brcmf_dbg(CONN
, "no channel specified\n");
1362 if (params
->channel_fixed
)
1363 brcmf_dbg(CONN
, "fixed channel required\n");
1365 brcmf_dbg(CONN
, "no fixed channel required\n");
1367 if (params
->ie
&& params
->ie_len
)
1368 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1370 brcmf_dbg(CONN
, "no ie specified\n");
1372 if (params
->beacon_interval
)
1373 brcmf_dbg(CONN
, "beacon interval: %d\n",
1374 params
->beacon_interval
);
1376 brcmf_dbg(CONN
, "no beacon interval specified\n");
1378 if (params
->basic_rates
)
1379 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1381 brcmf_dbg(CONN
, "no basic rates specified\n");
1383 if (params
->privacy
)
1384 brcmf_dbg(CONN
, "privacy required\n");
1386 brcmf_dbg(CONN
, "no privacy required\n");
1388 /* Configure Privacy for starter */
1389 if (params
->privacy
)
1390 wsec
|= WEP_ENABLED
;
1392 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1394 brcmf_err("wsec failed (%d)\n", err
);
1398 /* Configure Beacon Interval for starter */
1399 if (params
->beacon_interval
)
1400 bcnprd
= params
->beacon_interval
;
1404 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1406 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1410 /* Configure required join parameter */
1411 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1414 ssid_len
= min_t(u32
, params
->ssid_len
, IEEE80211_MAX_SSID_LEN
);
1415 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, ssid_len
);
1416 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
1417 join_params_size
= sizeof(join_params
.ssid_le
);
1420 if (params
->bssid
) {
1421 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1422 join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1423 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1425 eth_broadcast_addr(join_params
.params_le
.bssid
);
1426 eth_zero_addr(profile
->bssid
);
1430 if (params
->chandef
.chan
) {
1434 ieee80211_frequency_to_channel(
1435 params
->chandef
.chan
->center_freq
);
1436 if (params
->channel_fixed
) {
1437 /* adding chanspec */
1438 chanspec
= chandef_to_chanspec(&cfg
->d11inf
,
1440 join_params
.params_le
.chanspec_list
[0] =
1441 cpu_to_le16(chanspec
);
1442 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1443 join_params_size
+= sizeof(join_params
.params_le
);
1446 /* set channel for starter */
1447 target_channel
= cfg
->channel
;
1448 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1451 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1457 cfg
->ibss_starter
= false;
1460 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1461 &join_params
, join_params_size
);
1463 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1469 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1470 brcmf_dbg(TRACE
, "Exit\n");
1475 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1477 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1479 brcmf_dbg(TRACE
, "Enter\n");
1480 if (!check_vif_up(ifp
->vif
)) {
1481 /* When driver is being unloaded, it can end up here. If an
1482 * error is returned then later on a debug trace in the wireless
1483 * core module will be printed. To avoid this 0 is returned.
1488 brcmf_link_down(ifp
->vif
, WLAN_REASON_DEAUTH_LEAVING
);
1489 brcmf_net_setcarrier(ifp
, false);
1491 brcmf_dbg(TRACE
, "Exit\n");
1496 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1497 struct cfg80211_connect_params
*sme
)
1499 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1500 struct brcmf_cfg80211_security
*sec
;
1504 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1505 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1506 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1507 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1509 val
= WPA_AUTH_DISABLED
;
1510 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1511 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1513 brcmf_err("set wpa_auth failed (%d)\n", err
);
1516 sec
= &profile
->sec
;
1517 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1521 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1522 struct cfg80211_connect_params
*sme
)
1524 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1525 struct brcmf_cfg80211_security
*sec
;
1529 switch (sme
->auth_type
) {
1530 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1532 brcmf_dbg(CONN
, "open system\n");
1534 case NL80211_AUTHTYPE_SHARED_KEY
:
1536 brcmf_dbg(CONN
, "shared key\n");
1538 case NL80211_AUTHTYPE_AUTOMATIC
:
1540 brcmf_dbg(CONN
, "automatic\n");
1542 case NL80211_AUTHTYPE_NETWORK_EAP
:
1543 brcmf_dbg(CONN
, "network eap\n");
1546 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1550 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1552 brcmf_err("set auth failed (%d)\n", err
);
1555 sec
= &profile
->sec
;
1556 sec
->auth_type
= sme
->auth_type
;
1561 brcmf_set_wsec_mode(struct net_device
*ndev
,
1562 struct cfg80211_connect_params
*sme
)
1564 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1565 struct brcmf_cfg80211_security
*sec
;
1571 if (sme
->crypto
.n_ciphers_pairwise
) {
1572 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1573 case WLAN_CIPHER_SUITE_WEP40
:
1574 case WLAN_CIPHER_SUITE_WEP104
:
1577 case WLAN_CIPHER_SUITE_TKIP
:
1578 pval
= TKIP_ENABLED
;
1580 case WLAN_CIPHER_SUITE_CCMP
:
1583 case WLAN_CIPHER_SUITE_AES_CMAC
:
1587 brcmf_err("invalid cipher pairwise (%d)\n",
1588 sme
->crypto
.ciphers_pairwise
[0]);
1592 if (sme
->crypto
.cipher_group
) {
1593 switch (sme
->crypto
.cipher_group
) {
1594 case WLAN_CIPHER_SUITE_WEP40
:
1595 case WLAN_CIPHER_SUITE_WEP104
:
1598 case WLAN_CIPHER_SUITE_TKIP
:
1599 gval
= TKIP_ENABLED
;
1601 case WLAN_CIPHER_SUITE_CCMP
:
1604 case WLAN_CIPHER_SUITE_AES_CMAC
:
1608 brcmf_err("invalid cipher group (%d)\n",
1609 sme
->crypto
.cipher_group
);
1614 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1615 /* In case of privacy, but no security and WPS then simulate */
1616 /* setting AES. WPS-2.0 allows no security */
1617 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1622 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", wsec
);
1624 brcmf_err("error (%d)\n", err
);
1628 sec
= &profile
->sec
;
1629 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1630 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1636 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1638 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1641 const struct brcmf_tlv
*rsn_ie
;
1649 if (!sme
->crypto
.n_akm_suites
)
1652 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
), "wpa_auth", &val
);
1654 brcmf_err("could not get wpa_auth (%d)\n", err
);
1657 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1658 switch (sme
->crypto
.akm_suites
[0]) {
1659 case WLAN_AKM_SUITE_8021X
:
1660 val
= WPA_AUTH_UNSPECIFIED
;
1662 case WLAN_AKM_SUITE_PSK
:
1666 brcmf_err("invalid cipher group (%d)\n",
1667 sme
->crypto
.cipher_group
);
1670 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1671 switch (sme
->crypto
.akm_suites
[0]) {
1672 case WLAN_AKM_SUITE_8021X
:
1673 val
= WPA2_AUTH_UNSPECIFIED
;
1675 case WLAN_AKM_SUITE_8021X_SHA256
:
1676 val
= WPA2_AUTH_1X_SHA256
;
1678 case WLAN_AKM_SUITE_PSK_SHA256
:
1679 val
= WPA2_AUTH_PSK_SHA256
;
1681 case WLAN_AKM_SUITE_PSK
:
1682 val
= WPA2_AUTH_PSK
;
1685 brcmf_err("invalid cipher group (%d)\n",
1686 sme
->crypto
.cipher_group
);
1691 if (!brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MFP
))
1692 goto skip_mfp_config
;
1693 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
1694 * IE will not be verified, just a quick search for MFP config
1696 rsn_ie
= brcmf_parse_tlvs((const u8
*)sme
->ie
, sme
->ie_len
,
1699 goto skip_mfp_config
;
1700 ie
= (const u8
*)rsn_ie
;
1701 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1702 /* Skip unicast suite */
1703 offset
= TLV_HDR_LEN
+ WPA_IE_VERSION_LEN
+ WPA_IE_MIN_OUI_LEN
;
1704 if (offset
+ WPA_IE_SUITE_COUNT_LEN
>= ie_len
)
1705 goto skip_mfp_config
;
1706 /* Skip multicast suite */
1707 count
= ie
[offset
] + (ie
[offset
+ 1] << 8);
1708 offset
+= WPA_IE_SUITE_COUNT_LEN
+ (count
* WPA_IE_MIN_OUI_LEN
);
1709 if (offset
+ WPA_IE_SUITE_COUNT_LEN
>= ie_len
)
1710 goto skip_mfp_config
;
1711 /* Skip auth key management suite(s) */
1712 count
= ie
[offset
] + (ie
[offset
+ 1] << 8);
1713 offset
+= WPA_IE_SUITE_COUNT_LEN
+ (count
* WPA_IE_MIN_OUI_LEN
);
1714 if (offset
+ WPA_IE_SUITE_COUNT_LEN
> ie_len
)
1715 goto skip_mfp_config
;
1716 /* Ready to read capabilities */
1717 mfp
= BRCMF_MFP_NONE
;
1718 rsn_cap
= ie
[offset
] + (ie
[offset
+ 1] << 8);
1719 if (rsn_cap
& RSN_CAP_MFPR_MASK
)
1720 mfp
= BRCMF_MFP_REQUIRED
;
1721 else if (rsn_cap
& RSN_CAP_MFPC_MASK
)
1722 mfp
= BRCMF_MFP_CAPABLE
;
1723 brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "mfp", mfp
);
1726 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1727 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1729 brcmf_err("could not set wpa_auth (%d)\n", err
);
1737 brcmf_set_sharedkey(struct net_device
*ndev
,
1738 struct cfg80211_connect_params
*sme
)
1740 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1741 struct brcmf_cfg80211_security
*sec
;
1742 struct brcmf_wsec_key key
;
1746 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1748 if (sme
->key_len
== 0)
1751 sec
= &profile
->sec
;
1752 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1753 sec
->wpa_versions
, sec
->cipher_pairwise
);
1755 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1758 if (!(sec
->cipher_pairwise
&
1759 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1762 memset(&key
, 0, sizeof(key
));
1763 key
.len
= (u32
) sme
->key_len
;
1764 key
.index
= (u32
) sme
->key_idx
;
1765 if (key
.len
> sizeof(key
.data
)) {
1766 brcmf_err("Too long key length (%u)\n", key
.len
);
1769 memcpy(key
.data
, sme
->key
, key
.len
);
1770 key
.flags
= BRCMF_PRIMARY_KEY
;
1771 switch (sec
->cipher_pairwise
) {
1772 case WLAN_CIPHER_SUITE_WEP40
:
1773 key
.algo
= CRYPTO_ALGO_WEP1
;
1775 case WLAN_CIPHER_SUITE_WEP104
:
1776 key
.algo
= CRYPTO_ALGO_WEP128
;
1779 brcmf_err("Invalid algorithm (%d)\n",
1780 sme
->crypto
.ciphers_pairwise
[0]);
1783 /* Set the new key/index */
1784 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1785 key
.len
, key
.index
, key
.algo
);
1786 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1787 err
= send_key_to_dongle(netdev_priv(ndev
), &key
);
1791 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1792 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1793 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1794 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1796 brcmf_err("set auth failed (%d)\n", err
);
1802 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1803 enum nl80211_auth_type type
)
1805 if (type
== NL80211_AUTHTYPE_AUTOMATIC
&&
1806 brcmf_feat_is_quirk_enabled(ifp
, BRCMF_FEAT_QUIRK_AUTO_AUTH
)) {
1807 brcmf_dbg(CONN
, "WAR: use OPEN instead of AUTO\n");
1808 type
= NL80211_AUTHTYPE_OPEN_SYSTEM
;
1813 static void brcmf_set_join_pref(struct brcmf_if
*ifp
,
1814 struct cfg80211_bss_selection
*bss_select
)
1816 struct brcmf_join_pref_params join_pref_params
[2];
1817 enum nl80211_band band
;
1820 join_pref_params
[i
].len
= 2;
1821 join_pref_params
[i
].rssi_gain
= 0;
1823 if (bss_select
->behaviour
!= NL80211_BSS_SELECT_ATTR_BAND_PREF
)
1824 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_ASSOC_PREFER
, WLC_BAND_AUTO
);
1826 switch (bss_select
->behaviour
) {
1827 case __NL80211_BSS_SELECT_ATTR_INVALID
:
1828 brcmf_c_set_joinpref_default(ifp
);
1830 case NL80211_BSS_SELECT_ATTR_BAND_PREF
:
1831 join_pref_params
[i
].type
= BRCMF_JOIN_PREF_BAND
;
1832 band
= bss_select
->param
.band_pref
;
1833 join_pref_params
[i
].band
= nl80211_band_to_fwil(band
);
1836 case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST
:
1837 join_pref_params
[i
].type
= BRCMF_JOIN_PREF_RSSI_DELTA
;
1838 band
= bss_select
->param
.adjust
.band
;
1839 join_pref_params
[i
].band
= nl80211_band_to_fwil(band
);
1840 join_pref_params
[i
].rssi_gain
= bss_select
->param
.adjust
.delta
;
1843 case NL80211_BSS_SELECT_ATTR_RSSI
:
1847 join_pref_params
[i
].type
= BRCMF_JOIN_PREF_RSSI
;
1848 join_pref_params
[i
].len
= 2;
1849 join_pref_params
[i
].rssi_gain
= 0;
1850 join_pref_params
[i
].band
= 0;
1851 err
= brcmf_fil_iovar_data_set(ifp
, "join_pref", join_pref_params
,
1852 sizeof(join_pref_params
));
1854 brcmf_err("Set join_pref error (%d)\n", err
);
1858 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1859 struct cfg80211_connect_params
*sme
)
1861 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1862 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1863 struct ieee80211_channel
*chan
= sme
->channel
;
1864 struct brcmf_join_params join_params
;
1865 size_t join_params_size
;
1866 const struct brcmf_tlv
*rsn_ie
;
1867 const struct brcmf_vs_tlv
*wpa_ie
;
1870 struct brcmf_ext_join_params_le
*ext_join_params
;
1875 brcmf_dbg(TRACE
, "Enter\n");
1876 if (!check_vif_up(ifp
->vif
))
1880 brcmf_err("Invalid ssid\n");
1884 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1885 /* A normal (non P2P) connection request setup. */
1888 /* find the WPA_IE */
1889 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1892 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1894 /* find the RSN_IE */
1895 rsn_ie
= brcmf_parse_tlvs((const u8
*)sme
->ie
,
1900 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1903 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1906 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1907 sme
->ie
, sme
->ie_len
);
1909 brcmf_err("Set Assoc REQ IE Failed\n");
1911 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1913 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1917 ieee80211_frequency_to_channel(chan
->center_freq
);
1918 chanspec
= channel_to_chanspec(&cfg
->d11inf
, chan
);
1919 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1920 cfg
->channel
, chan
->center_freq
, chanspec
);
1926 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1928 err
= brcmf_set_wpa_version(ndev
, sme
);
1930 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1934 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1935 err
= brcmf_set_auth_type(ndev
, sme
);
1937 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1941 err
= brcmf_set_wsec_mode(ndev
, sme
);
1943 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1947 err
= brcmf_set_key_mgmt(ndev
, sme
);
1949 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1953 err
= brcmf_set_sharedkey(ndev
, sme
);
1955 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1959 /* Join with specific BSSID and cached SSID
1960 * If SSID is zero join based on BSSID only
1962 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1963 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1965 join_params_size
+= sizeof(u16
);
1966 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1967 if (ext_join_params
== NULL
) {
1971 ssid_len
= min_t(u32
, sme
->ssid_len
, IEEE80211_MAX_SSID_LEN
);
1972 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
1973 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
, ssid_len
);
1974 if (ssid_len
< IEEE80211_MAX_SSID_LEN
)
1975 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n",
1976 ext_join_params
->ssid_le
.SSID
, ssid_len
);
1978 /* Set up join scan parameters */
1979 ext_join_params
->scan_le
.scan_type
= -1;
1980 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1983 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1985 eth_broadcast_addr(ext_join_params
->assoc_le
.bssid
);
1988 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1990 ext_join_params
->assoc_le
.chanspec_list
[0] =
1991 cpu_to_le16(chanspec
);
1992 /* Increase dwell time to receive probe response or detect
1993 * beacon from target AP at a noisy air only during connect
1996 ext_join_params
->scan_le
.active_time
=
1997 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1998 ext_join_params
->scan_le
.passive_time
=
1999 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
2000 /* To sync with presence period of VSDB GO send probe request
2001 * more frequently. Probe request will be stopped when it gets
2002 * probe response from target AP/GO.
2004 ext_join_params
->scan_le
.nprobes
=
2005 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
2006 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
2008 ext_join_params
->scan_le
.active_time
= cpu_to_le32(-1);
2009 ext_join_params
->scan_le
.passive_time
= cpu_to_le32(-1);
2010 ext_join_params
->scan_le
.nprobes
= cpu_to_le32(-1);
2013 brcmf_set_join_pref(ifp
, &sme
->bss_select
);
2015 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
2017 kfree(ext_join_params
);
2019 /* This is it. join command worked, we are done */
2022 /* join command failed, fallback to set ssid */
2023 memset(&join_params
, 0, sizeof(join_params
));
2024 join_params_size
= sizeof(join_params
.ssid_le
);
2026 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, ssid_len
);
2027 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
2030 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
2032 eth_broadcast_addr(join_params
.params_le
.bssid
);
2035 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
2036 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
2037 join_params_size
+= sizeof(join_params
.params_le
);
2039 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
2040 &join_params
, join_params_size
);
2042 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
2046 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
2047 brcmf_dbg(TRACE
, "Exit\n");
2052 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
2055 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2056 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2057 struct brcmf_scb_val_le scbval
;
2060 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
2061 if (!check_vif_up(ifp
->vif
))
2064 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
2065 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
2066 cfg80211_disconnected(ndev
, reason_code
, NULL
, 0, true, GFP_KERNEL
);
2068 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
2069 scbval
.val
= cpu_to_le32(reason_code
);
2070 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
2071 &scbval
, sizeof(scbval
));
2073 brcmf_err("error (%d)\n", err
);
2075 brcmf_dbg(TRACE
, "Exit\n");
2080 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
2081 enum nl80211_tx_power_setting type
, s32 mbm
)
2083 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2084 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2085 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2090 brcmf_dbg(TRACE
, "Enter %d %d\n", type
, mbm
);
2091 if (!check_vif_up(ifp
->vif
))
2095 case NL80211_TX_POWER_AUTOMATIC
:
2097 case NL80211_TX_POWER_LIMITED
:
2098 case NL80211_TX_POWER_FIXED
:
2100 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2104 qdbm
= MBM_TO_DBM(4 * mbm
);
2107 qdbm
|= WL_TXPWR_OVERRIDE
;
2110 brcmf_err("Unsupported type %d\n", type
);
2114 /* Make sure radio is off or on as far as software is concerned */
2115 disable
= WL_RADIO_SW_DISABLE
<< 16;
2116 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
2118 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
2120 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower", qdbm
);
2122 brcmf_err("qtxpower error (%d)\n", err
);
2125 brcmf_dbg(TRACE
, "Exit %d (qdbm)\n", qdbm
& ~WL_TXPWR_OVERRIDE
);
2130 brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
2133 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2134 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2135 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2139 brcmf_dbg(TRACE
, "Enter\n");
2140 if (!check_vif_up(ifp
->vif
))
2143 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &qdbm
);
2145 brcmf_err("error (%d)\n", err
);
2148 *dbm
= (qdbm
& ~WL_TXPWR_OVERRIDE
) / 4;
2151 brcmf_dbg(TRACE
, "Exit (0x%x %d)\n", qdbm
, *dbm
);
2156 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2157 u8 key_idx
, bool unicast
, bool multicast
)
2159 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2164 brcmf_dbg(TRACE
, "Enter\n");
2165 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2166 if (!check_vif_up(ifp
->vif
))
2169 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2171 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2175 if (wsec
& WEP_ENABLED
) {
2176 /* Just select a new current key */
2178 err
= brcmf_fil_cmd_int_set(ifp
,
2179 BRCMF_C_SET_KEY_PRIMARY
, index
);
2181 brcmf_err("error (%d)\n", err
);
2184 brcmf_dbg(TRACE
, "Exit\n");
2189 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2190 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2192 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2193 struct brcmf_wsec_key
*key
;
2196 brcmf_dbg(TRACE
, "Enter\n");
2197 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2199 if (!check_vif_up(ifp
->vif
))
2202 if (key_idx
>= BRCMF_MAX_DEFAULT_KEYS
) {
2203 /* we ignore this key index in this case */
2207 key
= &ifp
->vif
->profile
.key
[key_idx
];
2209 if (key
->algo
== CRYPTO_ALGO_OFF
) {
2210 brcmf_dbg(CONN
, "Ignore clearing of (never configured) key\n");
2214 memset(key
, 0, sizeof(*key
));
2215 key
->index
= (u32
)key_idx
;
2216 key
->flags
= BRCMF_PRIMARY_KEY
;
2218 /* Clear the key/index */
2219 err
= send_key_to_dongle(ifp
, key
);
2221 brcmf_dbg(TRACE
, "Exit\n");
2226 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2227 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
2228 struct key_params
*params
)
2230 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2231 struct brcmf_wsec_key
*key
;
2238 brcmf_dbg(TRACE
, "Enter\n");
2239 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2240 if (!check_vif_up(ifp
->vif
))
2243 if (key_idx
>= BRCMF_MAX_DEFAULT_KEYS
) {
2244 /* we ignore this key index in this case */
2245 brcmf_err("invalid key index (%d)\n", key_idx
);
2249 if (params
->key_len
== 0)
2250 return brcmf_cfg80211_del_key(wiphy
, ndev
, key_idx
, pairwise
,
2253 if (params
->key_len
> sizeof(key
->data
)) {
2254 brcmf_err("Too long key length (%u)\n", params
->key_len
);
2259 if (mac_addr
&& (params
->cipher
!= WLAN_CIPHER_SUITE_WEP40
) &&
2260 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP104
)) {
2261 brcmf_dbg(TRACE
, "Ext key, mac %pM", mac_addr
);
2265 key
= &ifp
->vif
->profile
.key
[key_idx
];
2266 memset(key
, 0, sizeof(*key
));
2267 if ((ext_key
) && (!is_multicast_ether_addr(mac_addr
)))
2268 memcpy((char *)&key
->ea
, (void *)mac_addr
, ETH_ALEN
);
2269 key
->len
= params
->key_len
;
2270 key
->index
= key_idx
;
2271 memcpy(key
->data
, params
->key
, key
->len
);
2273 key
->flags
= BRCMF_PRIMARY_KEY
;
2275 switch (params
->cipher
) {
2276 case WLAN_CIPHER_SUITE_WEP40
:
2277 key
->algo
= CRYPTO_ALGO_WEP1
;
2279 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2281 case WLAN_CIPHER_SUITE_WEP104
:
2282 key
->algo
= CRYPTO_ALGO_WEP128
;
2284 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2286 case WLAN_CIPHER_SUITE_TKIP
:
2287 if (!brcmf_is_apmode(ifp
->vif
)) {
2288 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2289 memcpy(keybuf
, &key
->data
[24], sizeof(keybuf
));
2290 memcpy(&key
->data
[24], &key
->data
[16], sizeof(keybuf
));
2291 memcpy(&key
->data
[16], keybuf
, sizeof(keybuf
));
2293 key
->algo
= CRYPTO_ALGO_TKIP
;
2295 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2297 case WLAN_CIPHER_SUITE_AES_CMAC
:
2298 key
->algo
= CRYPTO_ALGO_AES_CCM
;
2300 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2302 case WLAN_CIPHER_SUITE_CCMP
:
2303 key
->algo
= CRYPTO_ALGO_AES_CCM
;
2305 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2308 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2313 err
= send_key_to_dongle(ifp
, key
);
2317 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2319 brcmf_err("get wsec error (%d)\n", err
);
2323 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2325 brcmf_err("set wsec error (%d)\n", err
);
2330 brcmf_dbg(TRACE
, "Exit\n");
2335 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
, u8 key_idx
,
2336 bool pairwise
, const u8
*mac_addr
, void *cookie
,
2337 void (*callback
)(void *cookie
,
2338 struct key_params
*params
))
2340 struct key_params params
;
2341 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2342 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2343 struct brcmf_cfg80211_security
*sec
;
2347 brcmf_dbg(TRACE
, "Enter\n");
2348 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2349 if (!check_vif_up(ifp
->vif
))
2352 memset(¶ms
, 0, sizeof(params
));
2354 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2356 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2357 /* Ignore this error, may happen during DISASSOC */
2361 if (wsec
& WEP_ENABLED
) {
2362 sec
= &profile
->sec
;
2363 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2364 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2365 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2366 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2367 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2368 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2370 } else if (wsec
& TKIP_ENABLED
) {
2371 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2372 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2373 } else if (wsec
& AES_ENABLED
) {
2374 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2375 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2377 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2381 callback(cookie
, ¶ms
);
2384 brcmf_dbg(TRACE
, "Exit\n");
2389 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2390 struct net_device
*ndev
, u8 key_idx
)
2392 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2394 brcmf_dbg(TRACE
, "Enter key_idx %d\n", key_idx
);
2396 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MFP
))
2399 brcmf_dbg(INFO
, "Not supported\n");
2405 brcmf_cfg80211_reconfigure_wep(struct brcmf_if
*ifp
)
2409 struct brcmf_wsec_key
*key
;
2412 for (key_idx
= 0; key_idx
< BRCMF_MAX_DEFAULT_KEYS
; key_idx
++) {
2413 key
= &ifp
->vif
->profile
.key
[key_idx
];
2414 if ((key
->algo
== CRYPTO_ALGO_WEP1
) ||
2415 (key
->algo
== CRYPTO_ALGO_WEP128
))
2418 if (key_idx
== BRCMF_MAX_DEFAULT_KEYS
)
2421 err
= send_key_to_dongle(ifp
, key
);
2423 brcmf_err("Setting WEP key failed (%d)\n", err
);
2426 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2428 brcmf_err("get wsec error (%d)\n", err
);
2431 wsec
|= WEP_ENABLED
;
2432 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2434 brcmf_err("set wsec error (%d)\n", err
);
2437 static void brcmf_convert_sta_flags(u32 fw_sta_flags
, struct station_info
*si
)
2439 struct nl80211_sta_flag_update
*sfu
;
2441 brcmf_dbg(TRACE
, "flags %08x\n", fw_sta_flags
);
2442 si
->filled
|= BIT(NL80211_STA_INFO_STA_FLAGS
);
2443 sfu
= &si
->sta_flags
;
2444 sfu
->mask
= BIT(NL80211_STA_FLAG_WME
) |
2445 BIT(NL80211_STA_FLAG_AUTHENTICATED
) |
2446 BIT(NL80211_STA_FLAG_ASSOCIATED
) |
2447 BIT(NL80211_STA_FLAG_AUTHORIZED
);
2448 if (fw_sta_flags
& BRCMF_STA_WME
)
2449 sfu
->set
|= BIT(NL80211_STA_FLAG_WME
);
2450 if (fw_sta_flags
& BRCMF_STA_AUTHE
)
2451 sfu
->set
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
2452 if (fw_sta_flags
& BRCMF_STA_ASSOC
)
2453 sfu
->set
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
2454 if (fw_sta_flags
& BRCMF_STA_AUTHO
)
2455 sfu
->set
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
2458 static void brcmf_fill_bss_param(struct brcmf_if
*ifp
, struct station_info
*si
)
2462 struct brcmf_bss_info_le bss_le
;
2467 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2471 buf
->len
= cpu_to_le32(WL_BSS_INFO_MAX
);
2472 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
, buf
,
2475 brcmf_err("Failed to get bss info (%d)\n", err
);
2478 si
->filled
|= BIT(NL80211_STA_INFO_BSS_PARAM
);
2479 si
->bss_param
.beacon_interval
= le16_to_cpu(buf
->bss_le
.beacon_period
);
2480 si
->bss_param
.dtim_period
= buf
->bss_le
.dtim_period
;
2481 capability
= le16_to_cpu(buf
->bss_le
.capability
);
2482 if (capability
& IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT
)
2483 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_CTS_PROT
;
2484 if (capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
2485 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_SHORT_PREAMBLE
;
2486 if (capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
)
2487 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_SHORT_SLOT_TIME
;
2491 brcmf_cfg80211_get_station_ibss(struct brcmf_if
*ifp
,
2492 struct station_info
*sinfo
)
2494 struct brcmf_scb_val_le scbval
;
2495 struct brcmf_pktcnt_le pktcnt
;
2500 /* Get the current tx rate */
2501 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2503 brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err
);
2506 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BITRATE
);
2507 sinfo
->txrate
.legacy
= rate
* 5;
2509 memset(&scbval
, 0, sizeof(scbval
));
2510 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
, &scbval
,
2513 brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err
);
2516 rssi
= le32_to_cpu(scbval
.val
);
2517 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2518 sinfo
->signal
= rssi
;
2520 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_GET_PKTCNTS
, &pktcnt
,
2523 brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err
);
2526 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_PACKETS
) |
2527 BIT(NL80211_STA_INFO_RX_DROP_MISC
) |
2528 BIT(NL80211_STA_INFO_TX_PACKETS
) |
2529 BIT(NL80211_STA_INFO_TX_FAILED
);
2530 sinfo
->rx_packets
= le32_to_cpu(pktcnt
.rx_good_pkt
);
2531 sinfo
->rx_dropped_misc
= le32_to_cpu(pktcnt
.rx_bad_pkt
);
2532 sinfo
->tx_packets
= le32_to_cpu(pktcnt
.tx_good_pkt
);
2533 sinfo
->tx_failed
= le32_to_cpu(pktcnt
.tx_bad_pkt
);
2539 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2540 const u8
*mac
, struct station_info
*sinfo
)
2542 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2543 struct brcmf_scb_val_le scb_val
;
2545 struct brcmf_sta_info_le sta_info_le
;
2553 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2554 if (!check_vif_up(ifp
->vif
))
2557 if (brcmf_is_ibssmode(ifp
->vif
))
2558 return brcmf_cfg80211_get_station_ibss(ifp
, sinfo
);
2560 memset(&sta_info_le
, 0, sizeof(sta_info_le
));
2561 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2562 err
= brcmf_fil_iovar_data_get(ifp
, "tdls_sta_info",
2564 sizeof(sta_info_le
));
2565 is_tdls_peer
= !err
;
2567 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2569 sizeof(sta_info_le
));
2571 brcmf_err("GET STA INFO failed, %d\n", err
);
2575 brcmf_dbg(TRACE
, "version %d\n", le16_to_cpu(sta_info_le
.ver
));
2576 sinfo
->filled
= BIT(NL80211_STA_INFO_INACTIVE_TIME
);
2577 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2578 sta_flags
= le32_to_cpu(sta_info_le
.flags
);
2579 brcmf_convert_sta_flags(sta_flags
, sinfo
);
2580 sinfo
->sta_flags
.mask
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
2582 sinfo
->sta_flags
.set
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
2584 sinfo
->sta_flags
.set
&= ~BIT(NL80211_STA_FLAG_TDLS_PEER
);
2585 if (sta_flags
& BRCMF_STA_ASSOC
) {
2586 sinfo
->filled
|= BIT(NL80211_STA_INFO_CONNECTED_TIME
);
2587 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2588 brcmf_fill_bss_param(ifp
, sinfo
);
2590 if (sta_flags
& BRCMF_STA_SCBSTATS
) {
2591 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_FAILED
);
2592 sinfo
->tx_failed
= le32_to_cpu(sta_info_le
.tx_failures
);
2593 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_PACKETS
);
2594 sinfo
->tx_packets
= le32_to_cpu(sta_info_le
.tx_pkts
);
2595 sinfo
->tx_packets
+= le32_to_cpu(sta_info_le
.tx_mcast_pkts
);
2596 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_PACKETS
);
2597 sinfo
->rx_packets
= le32_to_cpu(sta_info_le
.rx_ucast_pkts
);
2598 sinfo
->rx_packets
+= le32_to_cpu(sta_info_le
.rx_mcast_pkts
);
2599 if (sinfo
->tx_packets
) {
2600 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BITRATE
);
2601 sinfo
->txrate
.legacy
=
2602 le32_to_cpu(sta_info_le
.tx_rate
) / 100;
2604 if (sinfo
->rx_packets
) {
2605 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_BITRATE
);
2606 sinfo
->rxrate
.legacy
=
2607 le32_to_cpu(sta_info_le
.rx_rate
) / 100;
2609 if (le16_to_cpu(sta_info_le
.ver
) >= 4) {
2610 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BYTES
);
2611 sinfo
->tx_bytes
= le64_to_cpu(sta_info_le
.tx_tot_bytes
);
2612 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_BYTES
);
2613 sinfo
->rx_bytes
= le64_to_cpu(sta_info_le
.rx_tot_bytes
);
2617 for (i
= 0; i
< BRCMF_ANT_MAX
; i
++) {
2618 if (sta_info_le
.rssi
[i
]) {
2619 sinfo
->chain_signal_avg
[count_rssi
] =
2620 sta_info_le
.rssi
[i
];
2621 sinfo
->chain_signal
[count_rssi
] =
2622 sta_info_le
.rssi
[i
];
2623 total_rssi
+= sta_info_le
.rssi
[i
];
2628 sinfo
->filled
|= BIT(NL80211_STA_INFO_CHAIN_SIGNAL
);
2629 sinfo
->chains
= count_rssi
;
2631 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2632 total_rssi
/= count_rssi
;
2633 sinfo
->signal
= total_rssi
;
2634 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED
,
2635 &ifp
->vif
->sme_state
)) {
2636 memset(&scb_val
, 0, sizeof(scb_val
));
2637 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
,
2638 &scb_val
, sizeof(scb_val
));
2640 brcmf_err("Could not get rssi (%d)\n", err
);
2643 rssi
= le32_to_cpu(scb_val
.val
);
2644 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2645 sinfo
->signal
= rssi
;
2646 brcmf_dbg(CONN
, "RSSI %d dBm\n", rssi
);
2651 brcmf_dbg(TRACE
, "Exit\n");
2656 brcmf_cfg80211_dump_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2657 int idx
, u8
*mac
, struct station_info
*sinfo
)
2659 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2660 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2663 brcmf_dbg(TRACE
, "Enter, idx %d\n", idx
);
2666 cfg
->assoclist
.count
= cpu_to_le32(BRCMF_MAX_ASSOCLIST
);
2667 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_ASSOCLIST
,
2669 sizeof(cfg
->assoclist
));
2671 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2673 cfg
->assoclist
.count
= 0;
2677 if (idx
< le32_to_cpu(cfg
->assoclist
.count
)) {
2678 memcpy(mac
, cfg
->assoclist
.mac
[idx
], ETH_ALEN
);
2679 return brcmf_cfg80211_get_station(wiphy
, ndev
, mac
, sinfo
);
2685 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2686 bool enabled
, s32 timeout
)
2690 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2691 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2693 brcmf_dbg(TRACE
, "Enter\n");
2696 * Powersave enable/disable request is coming from the
2697 * cfg80211 even before the interface is up. In that
2698 * scenario, driver will be storing the power save
2699 * preference in cfg struct to apply this to
2700 * FW later while initializing the dongle
2702 cfg
->pwr_save
= enabled
;
2703 if (!check_vif_up(ifp
->vif
)) {
2705 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2709 pm
= enabled
? PM_FAST
: PM_OFF
;
2710 /* Do not enable the power save after assoc if it is a p2p interface */
2711 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2712 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2715 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2717 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2720 brcmf_err("net_device is not ready yet\n");
2722 brcmf_err("error (%d)\n", err
);
2725 brcmf_dbg(TRACE
, "Exit\n");
2729 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2730 struct brcmf_bss_info_le
*bi
)
2732 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2733 struct ieee80211_channel
*notify_channel
;
2734 struct cfg80211_bss
*bss
;
2735 struct ieee80211_supported_band
*band
;
2736 struct brcmu_chan ch
;
2739 u16 notify_capability
;
2740 u16 notify_interval
;
2742 size_t notify_ielen
;
2745 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2746 brcmf_err("Bss info is larger than buffer. Discarding\n");
2751 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2752 cfg
->d11inf
.decchspec(&ch
);
2753 bi
->ctl_ch
= ch
.chnum
;
2755 channel
= bi
->ctl_ch
;
2757 if (channel
<= CH_MAX_2G_CHANNEL
)
2758 band
= wiphy
->bands
[NL80211_BAND_2GHZ
];
2760 band
= wiphy
->bands
[NL80211_BAND_5GHZ
];
2762 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2763 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2765 notify_capability
= le16_to_cpu(bi
->capability
);
2766 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2767 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2768 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2769 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2771 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2772 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2773 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2774 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2775 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2777 bss
= cfg80211_inform_bss(wiphy
, notify_channel
,
2778 CFG80211_BSS_FTYPE_UNKNOWN
,
2779 (const u8
*)bi
->BSSID
,
2780 0, notify_capability
,
2781 notify_interval
, notify_ie
,
2782 notify_ielen
, notify_signal
,
2788 cfg80211_put_bss(wiphy
, bss
);
2793 static struct brcmf_bss_info_le
*
2794 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2797 return list
->bss_info_le
;
2798 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2799 le32_to_cpu(bss
->length
));
2802 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2804 struct brcmf_scan_results
*bss_list
;
2805 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2809 bss_list
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
2810 if (bss_list
->count
!= 0 &&
2811 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2812 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2816 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2817 for (i
= 0; i
< bss_list
->count
; i
++) {
2818 bi
= next_bss_le(bss_list
, bi
);
2819 err
= brcmf_inform_single_bss(cfg
, bi
);
2826 static s32
brcmf_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2827 struct net_device
*ndev
, const u8
*bssid
)
2829 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2830 struct ieee80211_channel
*notify_channel
;
2831 struct brcmf_bss_info_le
*bi
= NULL
;
2832 struct ieee80211_supported_band
*band
;
2833 struct cfg80211_bss
*bss
;
2834 struct brcmu_chan ch
;
2838 u16 notify_capability
;
2839 u16 notify_interval
;
2841 size_t notify_ielen
;
2844 brcmf_dbg(TRACE
, "Enter\n");
2846 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2852 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2854 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2855 buf
, WL_BSS_INFO_MAX
);
2857 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2861 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2863 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2864 cfg
->d11inf
.decchspec(&ch
);
2866 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2867 band
= wiphy
->bands
[NL80211_BAND_2GHZ
];
2869 band
= wiphy
->bands
[NL80211_BAND_5GHZ
];
2871 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2872 cfg
->channel
= freq
;
2873 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2875 notify_capability
= le16_to_cpu(bi
->capability
);
2876 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2877 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2878 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2879 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2881 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2882 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2883 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2884 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2886 bss
= cfg80211_inform_bss(wiphy
, notify_channel
,
2887 CFG80211_BSS_FTYPE_UNKNOWN
, bssid
, 0,
2888 notify_capability
, notify_interval
,
2889 notify_ie
, notify_ielen
, notify_signal
,
2897 cfg80211_put_bss(wiphy
, bss
);
2903 brcmf_dbg(TRACE
, "Exit\n");
2908 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2909 struct brcmf_if
*ifp
)
2911 struct brcmf_bss_info_le
*bi
;
2912 const struct brcmf_tlv
*tim
;
2913 u16 beacon_interval
;
2919 brcmf_dbg(TRACE
, "Enter\n");
2920 if (brcmf_is_ibssmode(ifp
->vif
))
2923 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2924 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2925 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2927 brcmf_err("Could not get bss info %d\n", err
);
2928 goto update_bss_info_out
;
2931 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2932 err
= brcmf_inform_single_bss(cfg
, bi
);
2934 goto update_bss_info_out
;
2936 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2937 ie_len
= le32_to_cpu(bi
->ie_length
);
2938 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2940 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2942 dtim_period
= tim
->data
[1];
2945 * active scan was done so we could not get dtim
2946 * information out of probe response.
2947 * so we speficially query dtim information to dongle.
2950 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2952 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2953 goto update_bss_info_out
;
2955 dtim_period
= (u8
)var
;
2958 update_bss_info_out
:
2959 brcmf_dbg(TRACE
, "Exit");
2963 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2965 struct escan_info
*escan
= &cfg
->escan_info
;
2967 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2968 if (cfg
->scan_request
) {
2969 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2970 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2972 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2973 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2976 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2978 struct brcmf_cfg80211_info
*cfg
=
2979 container_of(work
, struct brcmf_cfg80211_info
,
2980 escan_timeout_work
);
2982 brcmf_inform_bss(cfg
);
2983 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2986 static void brcmf_escan_timeout(unsigned long data
)
2988 struct brcmf_cfg80211_info
*cfg
=
2989 (struct brcmf_cfg80211_info
*)data
;
2991 if (cfg
->scan_request
) {
2992 brcmf_err("timer expired\n");
2993 schedule_work(&cfg
->escan_timeout_work
);
2998 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2999 struct brcmf_bss_info_le
*bss
,
3000 struct brcmf_bss_info_le
*bss_info_le
)
3002 struct brcmu_chan ch_bss
, ch_bss_info_le
;
3004 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
3005 cfg
->d11inf
.decchspec(&ch_bss
);
3006 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
3007 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
3009 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
3010 ch_bss
.band
== ch_bss_info_le
.band
&&
3011 bss_info_le
->SSID_len
== bss
->SSID_len
&&
3012 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
3013 if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) ==
3014 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
)) {
3015 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
3016 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
3018 /* preserve max RSSI if the measurements are
3019 * both on-channel or both off-channel
3021 if (bss_info_rssi
> bss_rssi
)
3022 bss
->RSSI
= bss_info_le
->RSSI
;
3023 } else if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) &&
3024 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) == 0) {
3025 /* preserve the on-channel rssi measurement
3026 * if the new measurement is off channel
3028 bss
->RSSI
= bss_info_le
->RSSI
;
3029 bss
->flags
|= BRCMF_BSS_RSSI_ON_CHANNEL
;
3037 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
3038 const struct brcmf_event_msg
*e
, void *data
)
3040 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
3042 struct brcmf_escan_result_le
*escan_result_le
;
3043 struct brcmf_bss_info_le
*bss_info_le
;
3044 struct brcmf_bss_info_le
*bss
= NULL
;
3046 struct brcmf_scan_results
*list
;
3052 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3053 brcmf_err("scan not ready, bsscfgidx=%d\n", ifp
->bsscfgidx
);
3057 if (status
== BRCMF_E_STATUS_PARTIAL
) {
3058 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
3059 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
3060 if (!escan_result_le
) {
3061 brcmf_err("Invalid escan result (NULL pointer)\n");
3064 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
3065 brcmf_err("Invalid bss_count %d: ignoring\n",
3066 escan_result_le
->bss_count
);
3069 bss_info_le
= &escan_result_le
->bss_info_le
;
3071 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
3074 if (!cfg
->scan_request
) {
3075 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
3079 bi_length
= le32_to_cpu(bss_info_le
->length
);
3080 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
3081 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
3082 brcmf_err("Invalid bss_info length %d: ignoring\n",
3087 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
3088 BIT(NL80211_IFTYPE_ADHOC
))) {
3089 if (le16_to_cpu(bss_info_le
->capability
) &
3090 WLAN_CAPABILITY_IBSS
) {
3091 brcmf_err("Ignoring IBSS result\n");
3096 list
= (struct brcmf_scan_results
*)
3097 cfg
->escan_info
.escan_buf
;
3098 if (bi_length
> BRCMF_ESCAN_BUF_SIZE
- list
->buflen
) {
3099 brcmf_err("Buffer is too small: ignoring\n");
3103 for (i
= 0; i
< list
->count
; i
++) {
3104 bss
= bss
? (struct brcmf_bss_info_le
*)
3105 ((unsigned char *)bss
+
3106 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
3107 if (brcmf_compare_update_same_bss(cfg
, bss
,
3111 memcpy(&cfg
->escan_info
.escan_buf
[list
->buflen
], bss_info_le
,
3113 list
->version
= le32_to_cpu(bss_info_le
->version
);
3114 list
->buflen
+= bi_length
;
3117 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
3118 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
3120 if (cfg
->scan_request
) {
3121 brcmf_inform_bss(cfg
);
3122 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
3123 brcmf_notify_escan_complete(cfg
, ifp
, aborted
, false);
3125 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
3132 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
3134 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
3135 brcmf_cfg80211_escan_handler
);
3136 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
3137 /* Init scan_timeout timer */
3138 init_timer(&cfg
->escan_timeout
);
3139 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
3140 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
3141 INIT_WORK(&cfg
->escan_timeout_work
,
3142 brcmf_cfg80211_escan_timeout_worker
);
3145 /* PFN result doesn't have all the info which are required by the supplicant
3146 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3147 * via wl_inform_single_bss in the required format. Escan does require the
3148 * scan request in the form of cfg80211_scan_request. For timebeing, create
3149 * cfg80211_scan_request one out of the received PNO event.
3152 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
3153 const struct brcmf_event_msg
*e
, void *data
)
3155 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
3156 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
3157 struct cfg80211_scan_request
*request
= NULL
;
3158 struct cfg80211_ssid
*ssid
= NULL
;
3159 struct ieee80211_channel
*channel
= NULL
;
3160 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3162 int channel_req
= 0;
3164 struct brcmf_pno_scanresults_le
*pfn_result
;
3168 brcmf_dbg(SCAN
, "Enter\n");
3170 if (e
->datalen
< (sizeof(*pfn_result
) + sizeof(*netinfo
))) {
3171 brcmf_dbg(SCAN
, "Event data to small. Ignore\n");
3175 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
3176 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
3180 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
3181 result_count
= le32_to_cpu(pfn_result
->count
);
3182 status
= le32_to_cpu(pfn_result
->status
);
3184 /* PFN event is limited to fit 512 bytes so we may get
3185 * multiple NET_FOUND events. For now place a warning here.
3187 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
3188 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
3189 if (result_count
> 0) {
3192 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
3193 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
3194 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
3195 if (!request
|| !ssid
|| !channel
) {
3200 request
->wiphy
= wiphy
;
3201 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3202 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
3204 for (i
= 0; i
< result_count
; i
++) {
3205 netinfo
= &netinfo_start
[i
];
3207 brcmf_err("Invalid netinfo ptr. index: %d\n",
3213 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
3214 netinfo
->SSID
, netinfo
->channel
);
3215 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3216 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
3219 channel_req
= netinfo
->channel
;
3220 if (channel_req
<= CH_MAX_2G_CHANNEL
)
3221 band
= NL80211_BAND_2GHZ
;
3223 band
= NL80211_BAND_5GHZ
;
3224 channel
[i
].center_freq
=
3225 ieee80211_channel_to_frequency(channel_req
,
3227 channel
[i
].band
= band
;
3228 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
3229 request
->channels
[i
] = &channel
[i
];
3230 request
->n_channels
++;
3233 /* assign parsed ssid array */
3234 if (request
->n_ssids
)
3235 request
->ssids
= &ssid
[0];
3237 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3238 /* Abort any on-going scan */
3239 brcmf_abort_scanning(cfg
);
3242 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3243 cfg
->escan_info
.run
= brcmf_run_escan
;
3244 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
3246 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3249 cfg
->sched_escan
= true;
3250 cfg
->scan_request
= request
;
3252 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3265 cfg80211_sched_scan_stopped(wiphy
);
3269 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3274 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3277 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3281 brcmf_err("failed code %d\n", ret
);
3286 static int brcmf_dev_pno_config(struct brcmf_if
*ifp
,
3287 struct cfg80211_sched_scan_request
*request
)
3289 struct brcmf_pno_param_le pfn_param
;
3290 struct brcmf_pno_macaddr_le pfn_mac
;
3295 memset(&pfn_param
, 0, sizeof(pfn_param
));
3296 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3298 /* set extra pno params */
3299 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3300 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3301 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3303 /* set up pno scan fr */
3304 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3306 err
= brcmf_fil_iovar_data_set(ifp
, "pfn_set", &pfn_param
,
3309 brcmf_err("pfn_set failed, err=%d\n", err
);
3313 /* Find out if mac randomization should be turned on */
3314 if (!(request
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
))
3317 pfn_mac
.version
= BRCMF_PFN_MACADDR_CFG_VER
;
3318 pfn_mac
.flags
= BRCMF_PFN_MAC_OUI_ONLY
| BRCMF_PFN_SET_MAC_UNASSOC
;
3320 memcpy(pfn_mac
.mac
, request
->mac_addr
, ETH_ALEN
);
3321 mac_mask
= request
->mac_addr_mask
;
3322 for (i
= 0; i
< ETH_ALEN
; i
++) {
3323 pfn_mac
.mac
[i
] &= mac_mask
[i
];
3324 pfn_mac
.mac
[i
] |= get_random_int() & ~(mac_mask
[i
]);
3326 /* Clear multi bit */
3327 pfn_mac
.mac
[0] &= 0xFE;
3328 /* Set locally administered */
3329 pfn_mac
.mac
[0] |= 0x02;
3331 err
= brcmf_fil_iovar_data_set(ifp
, "pfn_macaddr", &pfn_mac
,
3334 brcmf_err("pfn_macaddr failed, err=%d\n", err
);
3340 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3341 struct net_device
*ndev
,
3342 struct cfg80211_sched_scan_request
*request
)
3344 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3345 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3346 struct brcmf_pno_net_param_le pfn
;
3350 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3351 request
->n_match_sets
, request
->n_ssids
);
3352 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3353 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3356 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3357 brcmf_err("Scanning suppressed: status (%lu)\n",
3362 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3363 brcmf_dbg(SCAN
, "Invalid sched scan req!! n_ssids:%d\n",
3368 if (request
->n_ssids
> 0) {
3369 for (i
= 0; i
< request
->n_ssids
; i
++) {
3370 /* Active scan req for ssids */
3371 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3372 request
->ssids
[i
].ssid
);
3374 /* match_set ssids is a supert set of n_ssid list,
3375 * so we need not add these set separately.
3380 if (request
->n_match_sets
> 0) {
3381 /* clean up everything */
3382 ret
= brcmf_dev_pno_clean(ndev
);
3384 brcmf_err("failed error=%d\n", ret
);
3389 if (brcmf_dev_pno_config(ifp
, request
))
3392 /* configure each match set */
3393 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3394 struct cfg80211_ssid
*ssid
;
3397 ssid
= &request
->match_sets
[i
].ssid
;
3398 ssid_len
= ssid
->ssid_len
;
3401 brcmf_err("skip broadcast ssid\n");
3404 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3405 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3406 pfn
.wsec
= cpu_to_le32(0);
3407 pfn
.infra
= cpu_to_le32(1);
3408 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3409 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3410 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3411 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3413 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3414 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3416 /* Enable the PNO */
3417 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3418 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3428 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3429 struct net_device
*ndev
)
3431 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3433 brcmf_dbg(SCAN
, "enter\n");
3434 brcmf_dev_pno_clean(ndev
);
3435 if (cfg
->sched_escan
)
3436 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3440 static __always_inline
void brcmf_delay(u32 ms
)
3442 if (ms
< 1000 / HZ
) {
3450 static s32
brcmf_config_wowl_pattern(struct brcmf_if
*ifp
, u8 cmd
[4],
3451 u8
*pattern
, u32 patternsize
, u8
*mask
,
3454 struct brcmf_fil_wowl_pattern_le
*filter
;
3461 masksize
= (patternsize
+ 7) / 8;
3462 patternoffset
= sizeof(*filter
) - sizeof(filter
->cmd
) + masksize
;
3464 bufsize
= sizeof(*filter
) + patternsize
+ masksize
;
3465 buf
= kzalloc(bufsize
, GFP_KERNEL
);
3468 filter
= (struct brcmf_fil_wowl_pattern_le
*)buf
;
3470 memcpy(filter
->cmd
, cmd
, 4);
3471 filter
->masksize
= cpu_to_le32(masksize
);
3472 filter
->offset
= cpu_to_le32(packet_offset
);
3473 filter
->patternoffset
= cpu_to_le32(patternoffset
);
3474 filter
->patternsize
= cpu_to_le32(patternsize
);
3475 filter
->type
= cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP
);
3477 if ((mask
) && (masksize
))
3478 memcpy(buf
+ sizeof(*filter
), mask
, masksize
);
3479 if ((pattern
) && (patternsize
))
3480 memcpy(buf
+ sizeof(*filter
) + masksize
, pattern
, patternsize
);
3482 ret
= brcmf_fil_iovar_data_set(ifp
, "wowl_pattern", buf
, bufsize
);
3489 brcmf_wowl_nd_results(struct brcmf_if
*ifp
, const struct brcmf_event_msg
*e
,
3492 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
3493 struct brcmf_pno_scanresults_le
*pfn_result
;
3494 struct brcmf_pno_net_info_le
*netinfo
;
3496 brcmf_dbg(SCAN
, "Enter\n");
3498 if (e
->datalen
< (sizeof(*pfn_result
) + sizeof(*netinfo
))) {
3499 brcmf_dbg(SCAN
, "Event data to small. Ignore\n");
3503 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
3505 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
3506 brcmf_dbg(SCAN
, "PFN NET LOST event. Ignore\n");
3510 if (le32_to_cpu(pfn_result
->count
) < 1) {
3511 brcmf_err("Invalid result count, expected 1 (%d)\n",
3512 le32_to_cpu(pfn_result
->count
));
3516 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3517 netinfo
= (struct brcmf_pno_net_info_le
*)data
;
3518 memcpy(cfg
->wowl
.nd
->ssid
.ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3519 cfg
->wowl
.nd
->ssid
.ssid_len
= netinfo
->SSID_len
;
3520 cfg
->wowl
.nd
->n_channels
= 1;
3521 cfg
->wowl
.nd
->channels
[0] =
3522 ieee80211_channel_to_frequency(netinfo
->channel
,
3523 netinfo
->channel
<= CH_MAX_2G_CHANNEL
?
3524 NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
);
3525 cfg
->wowl
.nd_info
->n_matches
= 1;
3526 cfg
->wowl
.nd_info
->matches
[0] = cfg
->wowl
.nd
;
3528 /* Inform (the resume task) that the net detect information was recvd */
3529 cfg
->wowl
.nd_data_completed
= true;
3530 wake_up(&cfg
->wowl
.nd_data_wait
);
3537 static void brcmf_report_wowl_wakeind(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
3539 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3540 struct brcmf_wowl_wakeind_le wake_ind_le
;
3541 struct cfg80211_wowlan_wakeup wakeup_data
;
3542 struct cfg80211_wowlan_wakeup
*wakeup
;
3547 err
= brcmf_fil_iovar_data_get(ifp
, "wowl_wakeind", &wake_ind_le
,
3548 sizeof(wake_ind_le
));
3550 brcmf_err("Get wowl_wakeind failed, err = %d\n", err
);
3554 wakeind
= le32_to_cpu(wake_ind_le
.ucode_wakeind
);
3555 if (wakeind
& (BRCMF_WOWL_MAGIC
| BRCMF_WOWL_DIS
| BRCMF_WOWL_BCN
|
3556 BRCMF_WOWL_RETR
| BRCMF_WOWL_NET
|
3557 BRCMF_WOWL_PFN_FOUND
)) {
3558 wakeup
= &wakeup_data
;
3559 memset(&wakeup_data
, 0, sizeof(wakeup_data
));
3560 wakeup_data
.pattern_idx
= -1;
3562 if (wakeind
& BRCMF_WOWL_MAGIC
) {
3563 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3564 wakeup_data
.magic_pkt
= true;
3566 if (wakeind
& BRCMF_WOWL_DIS
) {
3567 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3568 wakeup_data
.disconnect
= true;
3570 if (wakeind
& BRCMF_WOWL_BCN
) {
3571 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3572 wakeup_data
.disconnect
= true;
3574 if (wakeind
& BRCMF_WOWL_RETR
) {
3575 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3576 wakeup_data
.disconnect
= true;
3578 if (wakeind
& BRCMF_WOWL_NET
) {
3579 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3580 /* For now always map to pattern 0, no API to get
3581 * correct information available at the moment.
3583 wakeup_data
.pattern_idx
= 0;
3585 if (wakeind
& BRCMF_WOWL_PFN_FOUND
) {
3586 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3587 timeout
= wait_event_timeout(cfg
->wowl
.nd_data_wait
,
3588 cfg
->wowl
.nd_data_completed
,
3589 BRCMF_ND_INFO_TIMEOUT
);
3591 brcmf_err("No result for wowl net detect\n");
3593 wakeup_data
.net_detect
= cfg
->wowl
.nd_info
;
3595 if (wakeind
& BRCMF_WOWL_GTK_FAILURE
) {
3596 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
3597 wakeup_data
.gtk_rekey_failure
= true;
3602 cfg80211_report_wowlan_wakeup(&ifp
->vif
->wdev
, wakeup
, GFP_KERNEL
);
3607 static void brcmf_report_wowl_wakeind(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
3611 #endif /* CONFIG_PM */
3613 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
3615 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3616 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3617 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3619 brcmf_dbg(TRACE
, "Enter\n");
3621 if (cfg
->wowl
.active
) {
3622 brcmf_report_wowl_wakeind(wiphy
, ifp
);
3623 brcmf_fil_iovar_int_set(ifp
, "wowl_clear", 0);
3624 brcmf_config_wowl_pattern(ifp
, "clr", NULL
, 0, NULL
, 0);
3625 if (!brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL_ARP_ND
))
3626 brcmf_configure_arp_nd_offload(ifp
, true);
3627 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
,
3628 cfg
->wowl
.pre_pmmode
);
3629 cfg
->wowl
.active
= false;
3630 if (cfg
->wowl
.nd_enabled
) {
3631 brcmf_cfg80211_sched_scan_stop(cfg
->wiphy
, ifp
->ndev
);
3632 brcmf_fweh_unregister(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
);
3633 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
3634 brcmf_notify_sched_scan_results
);
3635 cfg
->wowl
.nd_enabled
= false;
3641 static void brcmf_configure_wowl(struct brcmf_cfg80211_info
*cfg
,
3642 struct brcmf_if
*ifp
,
3643 struct cfg80211_wowlan
*wowl
)
3648 brcmf_dbg(TRACE
, "Suspend, wowl config.\n");
3650 if (!brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL_ARP_ND
))
3651 brcmf_configure_arp_nd_offload(ifp
, false);
3652 brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_PM
, &cfg
->wowl
.pre_pmmode
);
3653 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, PM_MAX
);
3656 if (wowl
->disconnect
)
3657 wowl_config
= BRCMF_WOWL_DIS
| BRCMF_WOWL_BCN
| BRCMF_WOWL_RETR
;
3658 if (wowl
->magic_pkt
)
3659 wowl_config
|= BRCMF_WOWL_MAGIC
;
3660 if ((wowl
->patterns
) && (wowl
->n_patterns
)) {
3661 wowl_config
|= BRCMF_WOWL_NET
;
3662 for (i
= 0; i
< wowl
->n_patterns
; i
++) {
3663 brcmf_config_wowl_pattern(ifp
, "add",
3664 (u8
*)wowl
->patterns
[i
].pattern
,
3665 wowl
->patterns
[i
].pattern_len
,
3666 (u8
*)wowl
->patterns
[i
].mask
,
3667 wowl
->patterns
[i
].pkt_offset
);
3670 if (wowl
->nd_config
) {
3671 brcmf_cfg80211_sched_scan_start(cfg
->wiphy
, ifp
->ndev
,
3673 wowl_config
|= BRCMF_WOWL_PFN_FOUND
;
3675 cfg
->wowl
.nd_data_completed
= false;
3676 cfg
->wowl
.nd_enabled
= true;
3677 /* Now reroute the event for PFN to the wowl function. */
3678 brcmf_fweh_unregister(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
);
3679 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
3680 brcmf_wowl_nd_results
);
3682 if (wowl
->gtk_rekey_failure
)
3683 wowl_config
|= BRCMF_WOWL_GTK_FAILURE
;
3684 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
3685 wowl_config
|= BRCMF_WOWL_UNASSOC
;
3687 brcmf_fil_iovar_data_set(ifp
, "wowl_wakeind", "clear",
3688 sizeof(struct brcmf_wowl_wakeind_le
));
3689 brcmf_fil_iovar_int_set(ifp
, "wowl", wowl_config
);
3690 brcmf_fil_iovar_int_set(ifp
, "wowl_activate", 1);
3691 brcmf_bus_wowl_config(cfg
->pub
->bus_if
, true);
3692 cfg
->wowl
.active
= true;
3695 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
3696 struct cfg80211_wowlan
*wowl
)
3698 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3699 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3700 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3701 struct brcmf_cfg80211_vif
*vif
;
3703 brcmf_dbg(TRACE
, "Enter\n");
3705 /* if the primary net_device is not READY there is nothing
3706 * we can do but pray resume goes smoothly.
3708 if (!check_vif_up(ifp
->vif
))
3711 /* Stop scheduled scan */
3712 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
))
3713 brcmf_cfg80211_sched_scan_stop(wiphy
, ndev
);
3715 /* end any scanning */
3716 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
3717 brcmf_abort_scanning(cfg
);
3720 brcmf_bus_wowl_config(cfg
->pub
->bus_if
, false);
3721 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
3722 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
3724 /* While going to suspend if associated with AP
3725 * disassociate from AP to save power while system is
3726 * in suspended state
3728 brcmf_link_down(vif
, WLAN_REASON_UNSPECIFIED
);
3729 /* Make sure WPA_Supplicant receives all the event
3730 * generated due to DISASSOC call to the fw to keep
3731 * the state fw and WPA_Supplicant state consistent
3736 brcmf_set_mpc(ifp
, 1);
3739 /* Configure WOWL paramaters */
3740 brcmf_configure_wowl(cfg
, ifp
, wowl
);
3744 brcmf_dbg(TRACE
, "Exit\n");
3745 /* clear any scanning activity */
3746 cfg
->scan_status
= 0;
3751 brcmf_update_pmklist(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
)
3753 struct brcmf_pmk_list_le
*pmk_list
;
3758 pmk_list
= &cfg
->pmk_list
;
3759 npmk
= le32_to_cpu(pmk_list
->npmk
);
3761 brcmf_dbg(CONN
, "No of elements %d\n", npmk
);
3762 for (i
= 0; i
< npmk
; i
++)
3763 brcmf_dbg(CONN
, "PMK[%d]: %pM\n", i
, &pmk_list
->pmk
[i
].bssid
);
3765 err
= brcmf_fil_iovar_data_set(ifp
, "pmkid_info", pmk_list
,
3772 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3773 struct cfg80211_pmksa
*pmksa
)
3775 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3776 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3777 struct brcmf_pmksa
*pmk
= &cfg
->pmk_list
.pmk
[0];
3781 brcmf_dbg(TRACE
, "Enter\n");
3782 if (!check_vif_up(ifp
->vif
))
3785 npmk
= le32_to_cpu(cfg
->pmk_list
.npmk
);
3786 for (i
= 0; i
< npmk
; i
++)
3787 if (!memcmp(pmksa
->bssid
, pmk
[i
].bssid
, ETH_ALEN
))
3789 if (i
< BRCMF_MAXPMKID
) {
3790 memcpy(pmk
[i
].bssid
, pmksa
->bssid
, ETH_ALEN
);
3791 memcpy(pmk
[i
].pmkid
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3794 cfg
->pmk_list
.npmk
= cpu_to_le32(npmk
);
3797 brcmf_err("Too many PMKSA entries cached %d\n", npmk
);
3801 brcmf_dbg(CONN
, "set_pmksa - PMK bssid: %pM =\n", pmk
[npmk
].bssid
);
3802 for (i
= 0; i
< WLAN_PMKID_LEN
; i
+= 4)
3803 brcmf_dbg(CONN
, "%02x %02x %02x %02x\n", pmk
[npmk
].pmkid
[i
],
3804 pmk
[npmk
].pmkid
[i
+ 1], pmk
[npmk
].pmkid
[i
+ 2],
3805 pmk
[npmk
].pmkid
[i
+ 3]);
3807 err
= brcmf_update_pmklist(cfg
, ifp
);
3809 brcmf_dbg(TRACE
, "Exit\n");
3814 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3815 struct cfg80211_pmksa
*pmksa
)
3817 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3818 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3819 struct brcmf_pmksa
*pmk
= &cfg
->pmk_list
.pmk
[0];
3823 brcmf_dbg(TRACE
, "Enter\n");
3824 if (!check_vif_up(ifp
->vif
))
3827 brcmf_dbg(CONN
, "del_pmksa - PMK bssid = %pM\n", &pmksa
->bssid
);
3829 npmk
= le32_to_cpu(cfg
->pmk_list
.npmk
);
3830 for (i
= 0; i
< npmk
; i
++)
3831 if (!memcmp(&pmksa
->bssid
, &pmk
[i
].bssid
, ETH_ALEN
))
3834 if ((npmk
> 0) && (i
< npmk
)) {
3835 for (; i
< (npmk
- 1); i
++) {
3836 memcpy(&pmk
[i
].bssid
, &pmk
[i
+ 1].bssid
, ETH_ALEN
);
3837 memcpy(&pmk
[i
].pmkid
, &pmk
[i
+ 1].pmkid
,
3840 memset(&pmk
[i
], 0, sizeof(*pmk
));
3841 cfg
->pmk_list
.npmk
= cpu_to_le32(npmk
- 1);
3843 brcmf_err("Cache entry not found\n");
3847 err
= brcmf_update_pmklist(cfg
, ifp
);
3849 brcmf_dbg(TRACE
, "Exit\n");
3855 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
3857 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3858 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3861 brcmf_dbg(TRACE
, "Enter\n");
3862 if (!check_vif_up(ifp
->vif
))
3865 memset(&cfg
->pmk_list
, 0, sizeof(cfg
->pmk_list
));
3866 err
= brcmf_update_pmklist(cfg
, ifp
);
3868 brcmf_dbg(TRACE
, "Exit\n");
3873 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3878 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3880 brcmf_err("auth error %d\n", err
);
3884 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3886 brcmf_err("wsec error %d\n", err
);
3889 /* set upper-layer auth */
3890 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3892 brcmf_err("wpa_auth error %d\n", err
);
3899 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3902 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3904 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3908 brcmf_configure_wpaie(struct brcmf_if
*ifp
,
3909 const struct brcmf_vs_tlv
*wpa_ie
,
3912 u32 auth
= 0; /* d11 open authentication */
3924 u32 wme_bss_disable
;
3927 brcmf_dbg(TRACE
, "Enter\n");
3931 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3932 data
= (u8
*)wpa_ie
;
3933 offset
= TLV_HDR_LEN
;
3935 offset
+= VS_IE_FIXED_HDR_LEN
;
3937 offset
+= WPA_IE_VERSION_LEN
;
3939 /* check for multicast cipher suite */
3940 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3942 brcmf_err("no multicast cipher suite\n");
3946 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3948 brcmf_err("ivalid OUI\n");
3951 offset
+= TLV_OUI_LEN
;
3953 /* pick up multicast cipher */
3954 switch (data
[offset
]) {
3955 case WPA_CIPHER_NONE
:
3958 case WPA_CIPHER_WEP_40
:
3959 case WPA_CIPHER_WEP_104
:
3962 case WPA_CIPHER_TKIP
:
3963 gval
= TKIP_ENABLED
;
3965 case WPA_CIPHER_AES_CCM
:
3970 brcmf_err("Invalid multi cast cipher info\n");
3975 /* walk thru unicast cipher list and pick up what we recognize */
3976 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3977 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3978 /* Check for unicast suite(s) */
3979 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3981 brcmf_err("no unicast cipher suite\n");
3984 for (i
= 0; i
< count
; i
++) {
3985 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3987 brcmf_err("ivalid OUI\n");
3990 offset
+= TLV_OUI_LEN
;
3991 switch (data
[offset
]) {
3992 case WPA_CIPHER_NONE
:
3994 case WPA_CIPHER_WEP_40
:
3995 case WPA_CIPHER_WEP_104
:
3996 pval
|= WEP_ENABLED
;
3998 case WPA_CIPHER_TKIP
:
3999 pval
|= TKIP_ENABLED
;
4001 case WPA_CIPHER_AES_CCM
:
4002 pval
|= AES_ENABLED
;
4005 brcmf_err("Ivalid unicast security info\n");
4009 /* walk thru auth management suite list and pick up what we recognize */
4010 count
= data
[offset
] + (data
[offset
+ 1] << 8);
4011 offset
+= WPA_IE_SUITE_COUNT_LEN
;
4012 /* Check for auth key management suite(s) */
4013 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
4015 brcmf_err("no auth key mgmt suite\n");
4018 for (i
= 0; i
< count
; i
++) {
4019 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
4021 brcmf_err("ivalid OUI\n");
4024 offset
+= TLV_OUI_LEN
;
4025 switch (data
[offset
]) {
4027 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
4028 wpa_auth
|= WPA_AUTH_NONE
;
4030 case RSN_AKM_UNSPECIFIED
:
4031 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
4032 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
4033 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
4036 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
4037 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
4038 (wpa_auth
|= WPA_AUTH_PSK
);
4040 case RSN_AKM_SHA256_PSK
:
4041 brcmf_dbg(TRACE
, "RSN_AKM_MFP_PSK\n");
4042 wpa_auth
|= WPA2_AUTH_PSK_SHA256
;
4044 case RSN_AKM_SHA256_1X
:
4045 brcmf_dbg(TRACE
, "RSN_AKM_MFP_1X\n");
4046 wpa_auth
|= WPA2_AUTH_1X_SHA256
;
4049 brcmf_err("Ivalid key mgmt info\n");
4054 mfp
= BRCMF_MFP_NONE
;
4056 wme_bss_disable
= 1;
4057 if ((offset
+ RSN_CAP_LEN
) <= len
) {
4058 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
4059 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
4060 wme_bss_disable
= 0;
4061 if (rsn_cap
& RSN_CAP_MFPR_MASK
) {
4062 brcmf_dbg(TRACE
, "MFP Required\n");
4063 mfp
= BRCMF_MFP_REQUIRED
;
4064 /* Firmware only supports mfp required in
4065 * combination with WPA2_AUTH_PSK_SHA256 or
4066 * WPA2_AUTH_1X_SHA256.
4068 if (!(wpa_auth
& (WPA2_AUTH_PSK_SHA256
|
4069 WPA2_AUTH_1X_SHA256
))) {
4073 /* Firmware has requirement that WPA2_AUTH_PSK/
4074 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4075 * is to be included in the rsn ie.
4077 if (wpa_auth
& WPA2_AUTH_PSK_SHA256
)
4078 wpa_auth
|= WPA2_AUTH_PSK
;
4079 else if (wpa_auth
& WPA2_AUTH_1X_SHA256
)
4080 wpa_auth
|= WPA2_AUTH_UNSPECIFIED
;
4081 } else if (rsn_cap
& RSN_CAP_MFPC_MASK
) {
4082 brcmf_dbg(TRACE
, "MFP Capable\n");
4083 mfp
= BRCMF_MFP_CAPABLE
;
4086 offset
+= RSN_CAP_LEN
;
4087 /* set wme_bss_disable to sync RSN Capabilities */
4088 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
4091 brcmf_err("wme_bss_disable error %d\n", err
);
4095 /* Skip PMKID cnt as it is know to be 0 for AP. */
4096 offset
+= RSN_PMKID_COUNT_LEN
;
4098 /* See if there is BIP wpa suite left for MFP */
4099 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MFP
) &&
4100 ((offset
+ WPA_IE_MIN_OUI_LEN
) <= len
)) {
4101 err
= brcmf_fil_bsscfg_data_set(ifp
, "bip",
4103 WPA_IE_MIN_OUI_LEN
);
4105 brcmf_err("bip error %d\n", err
);
4110 /* FOR WPS , set SES_OW_ENABLED */
4111 wsec
= (pval
| gval
| SES_OW_ENABLED
);
4114 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
4116 brcmf_err("auth error %d\n", err
);
4120 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
4122 brcmf_err("wsec error %d\n", err
);
4125 /* Configure MFP, this needs to go after wsec otherwise the wsec command
4126 * will overwrite the values set by MFP
4128 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MFP
)) {
4129 err
= brcmf_fil_bsscfg_int_set(ifp
, "mfp", mfp
);
4131 brcmf_err("mfp error %d\n", err
);
4135 /* set upper-layer auth */
4136 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
4138 brcmf_err("wpa_auth error %d\n", err
);
4147 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
4148 struct parsed_vndr_ies
*vndr_ies
)
4150 struct brcmf_vs_tlv
*vndrie
;
4151 struct brcmf_tlv
*ie
;
4152 struct parsed_vndr_ie_info
*parsed_info
;
4155 remaining_len
= (s32
)vndr_ie_len
;
4156 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
4158 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
4160 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
4162 vndrie
= (struct brcmf_vs_tlv
*)ie
;
4163 /* len should be bigger than OUI length + one */
4164 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
4165 brcmf_err("invalid vndr ie. length is too small %d\n",
4169 /* if wpa or wme ie, do not add ie */
4170 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
4171 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
4172 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
4173 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
4177 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
4179 /* save vndr ie information */
4180 parsed_info
->ie_ptr
= (char *)vndrie
;
4181 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
4182 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
4186 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
4187 parsed_info
->vndrie
.oui
[0],
4188 parsed_info
->vndrie
.oui
[1],
4189 parsed_info
->vndrie
.oui
[2],
4190 parsed_info
->vndrie
.oui_type
);
4192 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
4195 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
4196 if (remaining_len
<= TLV_HDR_LEN
)
4199 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
4206 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
4209 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
4210 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
4212 put_unaligned_le32(1, &iebuf
[VNDR_IE_COUNT_OFFSET
]);
4214 put_unaligned_le32(pktflag
, &iebuf
[VNDR_IE_PKTFLAG_OFFSET
]);
4216 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
4218 return ie_len
+ VNDR_IE_HDR_SIZE
;
4221 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
4222 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
4224 struct brcmf_if
*ifp
;
4225 struct vif_saved_ie
*saved_ie
;
4229 u8
*mgmt_ie_buf
= NULL
;
4230 int mgmt_ie_buf_len
;
4232 u32 del_add_ie_buf_len
= 0;
4233 u32 total_ie_buf_len
= 0;
4234 u32 parsed_ie_buf_len
= 0;
4235 struct parsed_vndr_ies old_vndr_ies
;
4236 struct parsed_vndr_ies new_vndr_ies
;
4237 struct parsed_vndr_ie_info
*vndrie_info
;
4240 int remained_buf_len
;
4245 saved_ie
= &vif
->saved_ie
;
4247 brcmf_dbg(TRACE
, "bsscfgidx %d, pktflag : 0x%02X\n", ifp
->bsscfgidx
,
4249 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4252 curr_ie_buf
= iovar_ie_buf
;
4254 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
4255 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
4256 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
4257 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
4259 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
4260 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
4261 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
4262 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
4264 case BRCMF_VNDR_IE_BEACON_FLAG
:
4265 mgmt_ie_buf
= saved_ie
->beacon_ie
;
4266 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
4267 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
4269 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
4270 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
4271 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
4272 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
4276 brcmf_err("not suitable type\n");
4280 if (vndr_ie_len
> mgmt_ie_buf_len
) {
4282 brcmf_err("extra IE size too big\n");
4286 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4287 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
4289 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
4290 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
4291 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
4292 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
4293 vndrie_info
->ie_len
);
4294 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
4298 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
4299 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
4300 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
4301 parsed_ie_buf_len
) == 0)) {
4302 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
4306 /* parse old vndr_ie */
4307 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
4309 /* make a command to delete old ie */
4310 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
4311 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
4313 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4314 vndrie_info
->vndrie
.id
,
4315 vndrie_info
->vndrie
.len
,
4316 vndrie_info
->vndrie
.oui
[0],
4317 vndrie_info
->vndrie
.oui
[1],
4318 vndrie_info
->vndrie
.oui
[2]);
4320 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
4321 vndrie_info
->ie_ptr
,
4322 vndrie_info
->ie_len
,
4324 curr_ie_buf
+= del_add_ie_buf_len
;
4325 total_ie_buf_len
+= del_add_ie_buf_len
;
4330 /* Add if there is any extra IE */
4331 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
4334 remained_buf_len
= mgmt_ie_buf_len
;
4336 /* make a command to add new ie */
4337 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
4338 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
4340 /* verify remained buf size before copy data */
4341 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
4342 VNDR_IE_VSIE_OFFSET
)) {
4343 brcmf_err("no space in mgmt_ie_buf: len left %d",
4347 remained_buf_len
-= (vndrie_info
->ie_len
+
4348 VNDR_IE_VSIE_OFFSET
);
4350 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4351 vndrie_info
->vndrie
.id
,
4352 vndrie_info
->vndrie
.len
,
4353 vndrie_info
->vndrie
.oui
[0],
4354 vndrie_info
->vndrie
.oui
[1],
4355 vndrie_info
->vndrie
.oui
[2]);
4357 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
4358 vndrie_info
->ie_ptr
,
4359 vndrie_info
->ie_len
,
4362 /* save the parsed IE in wl struct */
4363 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
4364 vndrie_info
->ie_len
);
4365 *mgmt_ie_len
+= vndrie_info
->ie_len
;
4367 curr_ie_buf
+= del_add_ie_buf_len
;
4368 total_ie_buf_len
+= del_add_ie_buf_len
;
4371 if (total_ie_buf_len
) {
4372 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
4375 brcmf_err("vndr ie set error : %d\n", err
);
4379 kfree(iovar_ie_buf
);
4383 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
4386 BRCMF_VNDR_IE_PRBREQ_FLAG
,
4387 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4388 BRCMF_VNDR_IE_BEACON_FLAG
4392 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
4393 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
4395 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
4400 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
4401 struct cfg80211_beacon_data
*beacon
)
4405 /* Set Beacon IEs to FW */
4406 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
4407 beacon
->tail
, beacon
->tail_len
);
4409 brcmf_err("Set Beacon IE Failed\n");
4412 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
4414 /* Set Probe Response IEs to FW */
4415 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
4416 beacon
->proberesp_ies
,
4417 beacon
->proberesp_ies_len
);
4419 brcmf_err("Set Probe Resp IE Failed\n");
4421 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
4427 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
4428 struct cfg80211_ap_settings
*settings
)
4431 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4432 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4433 const struct brcmf_tlv
*ssid_ie
;
4434 const struct brcmf_tlv
*country_ie
;
4435 struct brcmf_ssid_le ssid_le
;
4437 const struct brcmf_tlv
*rsn_ie
;
4438 const struct brcmf_vs_tlv
*wpa_ie
;
4439 struct brcmf_join_params join_params
;
4440 enum nl80211_iftype dev_role
;
4441 struct brcmf_fil_bss_enable_le bss_enable
;
4446 brcmf_dbg(TRACE
, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4447 settings
->chandef
.chan
->hw_value
,
4448 settings
->chandef
.center_freq1
, settings
->chandef
.width
,
4449 settings
->beacon_interval
, settings
->dtim_period
);
4450 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4451 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
4452 settings
->inactivity_timeout
);
4453 dev_role
= ifp
->vif
->wdev
.iftype
;
4454 mbss
= ifp
->vif
->mbss
;
4456 /* store current 11d setting */
4457 brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_REGULATORY
, &ifp
->vif
->is_11d
);
4458 country_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
4459 settings
->beacon
.tail_len
,
4461 is_11d
= country_ie
? 1 : 0;
4463 memset(&ssid_le
, 0, sizeof(ssid_le
));
4464 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
4465 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
4466 ssid_ie
= brcmf_parse_tlvs(
4467 (u8
*)&settings
->beacon
.head
[ie_offset
],
4468 settings
->beacon
.head_len
- ie_offset
,
4473 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
4474 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
4475 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
4477 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
4478 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
4482 brcmf_set_mpc(ifp
, 0);
4483 brcmf_configure_arp_nd_offload(ifp
, false);
4486 /* find the RSN_IE */
4487 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
4488 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
4490 /* find the WPA_IE */
4491 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
4492 settings
->beacon
.tail_len
);
4494 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
4495 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
4496 if (wpa_ie
!= NULL
) {
4498 err
= brcmf_configure_wpaie(ifp
, wpa_ie
, false);
4502 struct brcmf_vs_tlv
*tmp_ie
;
4504 tmp_ie
= (struct brcmf_vs_tlv
*)rsn_ie
;
4507 err
= brcmf_configure_wpaie(ifp
, tmp_ie
, true);
4512 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
4513 brcmf_configure_opensecurity(ifp
);
4516 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
4519 chanspec
= chandef_to_chanspec(&cfg
->d11inf
,
4520 &settings
->chandef
);
4521 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
4523 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4528 if (is_11d
!= ifp
->vif
->is_11d
) {
4529 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_REGULATORY
,
4532 brcmf_err("Regulatory Set Error, %d\n", err
);
4536 if (settings
->beacon_interval
) {
4537 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
4538 settings
->beacon_interval
);
4540 brcmf_err("Beacon Interval Set Error, %d\n",
4545 if (settings
->dtim_period
) {
4546 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
4547 settings
->dtim_period
);
4549 brcmf_err("DTIM Interval Set Error, %d\n", err
);
4554 if ((dev_role
== NL80211_IFTYPE_AP
) &&
4555 ((ifp
->ifidx
== 0) ||
4556 !brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_RSDB
))) {
4557 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4559 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
4562 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
4565 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
4567 brcmf_err("SET INFRA error %d\n", err
);
4570 } else if (WARN_ON(is_11d
!= ifp
->vif
->is_11d
)) {
4571 /* Multiple-BSS should use same 11d configuration */
4575 if (dev_role
== NL80211_IFTYPE_AP
) {
4576 if ((brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
)) && (!mbss
))
4577 brcmf_fil_iovar_int_set(ifp
, "mbss", 1);
4579 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
4581 brcmf_err("setting AP mode failed %d\n", err
);
4584 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
4586 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
4589 /* On DOWN the firmware removes the WEP keys, reconfigure
4590 * them if they were set.
4592 brcmf_cfg80211_reconfigure_wep(ifp
);
4594 memset(&join_params
, 0, sizeof(join_params
));
4595 /* join parameters starts with ssid */
4596 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
4598 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
4599 &join_params
, sizeof(join_params
));
4601 brcmf_err("SET SSID error (%d)\n", err
);
4604 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
4606 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
4609 brcmf_err("setting ssid failed %d\n", err
);
4612 bss_enable
.bsscfgidx
= cpu_to_le32(ifp
->bsscfgidx
);
4613 bss_enable
.enable
= cpu_to_le32(1);
4614 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
4615 sizeof(bss_enable
));
4617 brcmf_err("bss_enable config failed %d\n", err
);
4621 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
4623 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
4624 brcmf_net_setcarrier(ifp
, true);
4627 if ((err
) && (!mbss
)) {
4628 brcmf_set_mpc(ifp
, 1);
4629 brcmf_configure_arp_nd_offload(ifp
, true);
4634 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
4636 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4638 struct brcmf_fil_bss_enable_le bss_enable
;
4639 struct brcmf_join_params join_params
;
4641 brcmf_dbg(TRACE
, "Enter\n");
4643 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
4644 /* Due to most likely deauths outstanding we sleep */
4645 /* first to make sure they get processed by fw. */
4648 if (ifp
->vif
->mbss
) {
4649 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4653 memset(&join_params
, 0, sizeof(join_params
));
4654 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
4655 &join_params
, sizeof(join_params
));
4657 brcmf_err("SET SSID error (%d)\n", err
);
4658 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4660 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
4661 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
4663 brcmf_err("setting AP mode failed %d\n", err
);
4664 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
4666 brcmf_err("setting INFRA mode failed %d\n", err
);
4667 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
))
4668 brcmf_fil_iovar_int_set(ifp
, "mbss", 0);
4669 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_REGULATORY
,
4672 brcmf_err("restoring REGULATORY setting failed %d\n",
4674 /* Bring device back up so it can be used again */
4675 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
4677 brcmf_err("BRCMF_C_UP error %d\n", err
);
4679 bss_enable
.bsscfgidx
= cpu_to_le32(ifp
->bsscfgidx
);
4680 bss_enable
.enable
= cpu_to_le32(0);
4681 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
4682 sizeof(bss_enable
));
4684 brcmf_err("bss_enable config failed %d\n", err
);
4686 brcmf_set_mpc(ifp
, 1);
4687 brcmf_configure_arp_nd_offload(ifp
, true);
4688 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
4689 brcmf_net_setcarrier(ifp
, false);
4695 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
4696 struct cfg80211_beacon_data
*info
)
4698 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4701 brcmf_dbg(TRACE
, "Enter\n");
4703 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
4709 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
4710 struct station_del_parameters
*params
)
4712 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4713 struct brcmf_scb_val_le scbval
;
4714 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4720 brcmf_dbg(TRACE
, "Enter %pM\n", params
->mac
);
4722 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
4723 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
4724 if (!check_vif_up(ifp
->vif
))
4727 memcpy(&scbval
.ea
, params
->mac
, ETH_ALEN
);
4728 scbval
.val
= cpu_to_le32(params
->reason_code
);
4729 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
4730 &scbval
, sizeof(scbval
));
4732 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
4734 brcmf_dbg(TRACE
, "Exit\n");
4739 brcmf_cfg80211_change_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
4740 const u8
*mac
, struct station_parameters
*params
)
4742 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4745 brcmf_dbg(TRACE
, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac
,
4746 params
->sta_flags_mask
, params
->sta_flags_set
);
4748 /* Ignore all 00 MAC */
4749 if (is_zero_ether_addr(mac
))
4752 if (!(params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_AUTHORIZED
)))
4755 if (params
->sta_flags_set
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
4756 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SCB_AUTHORIZE
,
4757 (void *)mac
, ETH_ALEN
);
4759 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SCB_DEAUTHORIZE
,
4760 (void *)mac
, ETH_ALEN
);
4762 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err
);
4768 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
4769 struct wireless_dev
*wdev
,
4770 u16 frame_type
, bool reg
)
4772 struct brcmf_cfg80211_vif
*vif
;
4775 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
4777 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
4778 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4780 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
4782 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
4787 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
4788 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
4790 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4791 struct ieee80211_channel
*chan
= params
->chan
;
4792 const u8
*buf
= params
->buf
;
4793 size_t len
= params
->len
;
4794 const struct ieee80211_mgmt
*mgmt
;
4795 struct brcmf_cfg80211_vif
*vif
;
4799 struct brcmf_fil_action_frame_le
*action_frame
;
4800 struct brcmf_fil_af_params_le
*af_params
;
4805 brcmf_dbg(TRACE
, "Enter\n");
4809 mgmt
= (const struct ieee80211_mgmt
*)buf
;
4811 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
4812 brcmf_err("Driver only allows MGMT packet type\n");
4816 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4818 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4819 /* Right now the only reason to get a probe response */
4820 /* is for p2p listen response or for p2p GO from */
4821 /* wpa_supplicant. Unfortunately the probe is send */
4822 /* on primary ndev, while dongle wants it on the p2p */
4823 /* vif. Since this is only reason for a probe */
4824 /* response to be sent, the vif is taken from cfg. */
4825 /* If ever desired to send proberesp for non p2p */
4826 /* response then data should be checked for */
4827 /* "DIRECT-". Note in future supplicant will take */
4828 /* dedicated p2p wdev to do this and then this 'hack'*/
4829 /* is not needed anymore. */
4830 ie_offset
= DOT11_MGMT_HDR_LEN
+
4831 DOT11_BCN_PRB_FIXED_LEN
;
4832 ie_len
= len
- ie_offset
;
4833 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4834 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4835 err
= brcmf_vif_set_mgmt_ie(vif
,
4836 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4839 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4841 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4842 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4843 if (af_params
== NULL
) {
4844 brcmf_err("unable to allocate frame\n");
4848 action_frame
= &af_params
->action_frame
;
4849 /* Add the packet Id */
4850 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4852 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4853 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4854 /* Add the length exepted for 802.11 header */
4855 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4856 /* Add the channel. Use the one specified as parameter if any or
4857 * the current one (got from the firmware) otherwise
4860 freq
= chan
->center_freq
;
4862 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4864 chan_nr
= ieee80211_frequency_to_channel(freq
);
4865 af_params
->channel
= cpu_to_le32(chan_nr
);
4867 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4868 le16_to_cpu(action_frame
->len
));
4870 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4871 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4873 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4876 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4880 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4881 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4890 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4891 struct wireless_dev
*wdev
,
4894 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4895 struct brcmf_cfg80211_vif
*vif
;
4898 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4900 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4902 brcmf_err("No p2p device available for probe response\n");
4906 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4911 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4912 struct wireless_dev
*wdev
,
4913 enum nl80211_crit_proto_id proto
,
4916 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4917 struct brcmf_cfg80211_vif
*vif
;
4919 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4921 /* only DHCP support for now */
4922 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4925 /* suppress and abort scanning */
4926 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4927 brcmf_abort_scanning(cfg
);
4929 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4932 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4933 struct wireless_dev
*wdev
)
4935 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4936 struct brcmf_cfg80211_vif
*vif
;
4938 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4940 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4941 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4945 brcmf_notify_tdls_peer_event(struct brcmf_if
*ifp
,
4946 const struct brcmf_event_msg
*e
, void *data
)
4948 switch (e
->reason
) {
4949 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED
:
4950 brcmf_dbg(TRACE
, "TDLS Peer Discovered\n");
4952 case BRCMF_E_REASON_TDLS_PEER_CONNECTED
:
4953 brcmf_dbg(TRACE
, "TDLS Peer Connected\n");
4954 brcmf_proto_add_tdls_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
4956 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED
:
4957 brcmf_dbg(TRACE
, "TDLS Peer Disconnected\n");
4958 brcmf_proto_delete_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
4965 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4970 case NL80211_TDLS_DISCOVERY_REQ
:
4971 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4973 case NL80211_TDLS_SETUP
:
4974 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4976 case NL80211_TDLS_TEARDOWN
:
4977 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4980 brcmf_err("unsupported operation: %d\n", oper
);
4986 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4987 struct net_device
*ndev
, const u8
*peer
,
4988 enum nl80211_tdls_operation oper
)
4990 struct brcmf_if
*ifp
;
4991 struct brcmf_tdls_iovar_le info
;
4994 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4998 ifp
= netdev_priv(ndev
);
4999 memset(&info
, 0, sizeof(info
));
5000 info
.mode
= (u8
)ret
;
5002 memcpy(info
.ea
, peer
, ETH_ALEN
);
5004 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
5005 &info
, sizeof(info
));
5007 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
5014 brcmf_cfg80211_set_rekey_data(struct wiphy
*wiphy
, struct net_device
*ndev
,
5015 struct cfg80211_gtk_rekey_data
*gtk
)
5017 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5018 struct brcmf_gtk_keyinfo_le gtk_le
;
5021 brcmf_dbg(TRACE
, "Enter, bssidx=%d\n", ifp
->bsscfgidx
);
5023 memcpy(gtk_le
.kck
, gtk
->kck
, sizeof(gtk_le
.kck
));
5024 memcpy(gtk_le
.kek
, gtk
->kek
, sizeof(gtk_le
.kek
));
5025 memcpy(gtk_le
.replay_counter
, gtk
->replay_ctr
,
5026 sizeof(gtk_le
.replay_counter
));
5028 ret
= brcmf_fil_iovar_data_set(ifp
, "gtk_key_info", >k_le
,
5031 brcmf_err("gtk_key_info iovar failed: ret=%d\n", ret
);
5037 static struct cfg80211_ops brcmf_cfg80211_ops
= {
5038 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
5039 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
5040 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
5041 .scan
= brcmf_cfg80211_scan
,
5042 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
5043 .join_ibss
= brcmf_cfg80211_join_ibss
,
5044 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
5045 .get_station
= brcmf_cfg80211_get_station
,
5046 .dump_station
= brcmf_cfg80211_dump_station
,
5047 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
5048 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
5049 .add_key
= brcmf_cfg80211_add_key
,
5050 .del_key
= brcmf_cfg80211_del_key
,
5051 .get_key
= brcmf_cfg80211_get_key
,
5052 .set_default_key
= brcmf_cfg80211_config_default_key
,
5053 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
5054 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
5055 .connect
= brcmf_cfg80211_connect
,
5056 .disconnect
= brcmf_cfg80211_disconnect
,
5057 .suspend
= brcmf_cfg80211_suspend
,
5058 .resume
= brcmf_cfg80211_resume
,
5059 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
5060 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
5061 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
5062 .start_ap
= brcmf_cfg80211_start_ap
,
5063 .stop_ap
= brcmf_cfg80211_stop_ap
,
5064 .change_beacon
= brcmf_cfg80211_change_beacon
,
5065 .del_station
= brcmf_cfg80211_del_station
,
5066 .change_station
= brcmf_cfg80211_change_station
,
5067 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
5068 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
5069 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
5070 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
5071 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
5072 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
5073 .start_p2p_device
= brcmf_p2p_start_device
,
5074 .stop_p2p_device
= brcmf_p2p_stop_device
,
5075 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
5076 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
5077 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
5080 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
5081 enum nl80211_iftype type
,
5084 struct brcmf_cfg80211_vif
*vif_walk
;
5085 struct brcmf_cfg80211_vif
*vif
;
5088 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
5090 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
5092 return ERR_PTR(-ENOMEM
);
5094 vif
->wdev
.wiphy
= cfg
->wiphy
;
5095 vif
->wdev
.iftype
= type
;
5097 vif
->pm_block
= pm_block
;
5099 brcmf_init_prof(&vif
->profile
);
5101 if (type
== NL80211_IFTYPE_AP
) {
5103 list_for_each_entry(vif_walk
, &cfg
->vif_list
, list
) {
5104 if (vif_walk
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
5112 list_add_tail(&vif
->list
, &cfg
->vif_list
);
5116 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
5118 list_del(&vif
->list
);
5122 void brcmf_cfg80211_free_netdev(struct net_device
*ndev
)
5124 struct brcmf_cfg80211_vif
*vif
;
5125 struct brcmf_if
*ifp
;
5127 ifp
= netdev_priv(ndev
);
5131 brcmf_free_vif(vif
);
5135 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
5137 u32 event
= e
->event_code
;
5138 u32 status
= e
->status
;
5140 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
5141 brcmf_dbg(CONN
, "Processing set ssid\n");
5148 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
5150 u32 event
= e
->event_code
;
5151 u16 flags
= e
->flags
;
5153 if ((event
== BRCMF_E_DEAUTH
) || (event
== BRCMF_E_DEAUTH_IND
) ||
5154 (event
== BRCMF_E_DISASSOC_IND
) ||
5155 ((event
== BRCMF_E_LINK
) && (!(flags
& BRCMF_EVENT_MSG_LINK
)))) {
5156 brcmf_dbg(CONN
, "Processing link down\n");
5162 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
5163 const struct brcmf_event_msg
*e
)
5165 u32 event
= e
->event_code
;
5166 u32 status
= e
->status
;
5168 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
5169 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
5170 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
5174 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
5175 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
5182 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
5184 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5186 kfree(conn_info
->req_ie
);
5187 conn_info
->req_ie
= NULL
;
5188 conn_info
->req_ie_len
= 0;
5189 kfree(conn_info
->resp_ie
);
5190 conn_info
->resp_ie
= NULL
;
5191 conn_info
->resp_ie_len
= 0;
5194 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
5195 struct brcmf_if
*ifp
)
5197 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
5198 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5203 brcmf_clear_assoc_ies(cfg
);
5205 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
5206 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
5208 brcmf_err("could not get assoc info (%d)\n", err
);
5212 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
5213 req_len
= le32_to_cpu(assoc_info
->req_len
);
5214 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
5216 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
5220 brcmf_err("could not get assoc req (%d)\n", err
);
5223 conn_info
->req_ie_len
= req_len
;
5225 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
5228 conn_info
->req_ie_len
= 0;
5229 conn_info
->req_ie
= NULL
;
5232 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
5236 brcmf_err("could not get assoc resp (%d)\n", err
);
5239 conn_info
->resp_ie_len
= resp_len
;
5240 conn_info
->resp_ie
=
5241 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
5244 conn_info
->resp_ie_len
= 0;
5245 conn_info
->resp_ie
= NULL
;
5247 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
5248 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
5254 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
5255 struct net_device
*ndev
,
5256 const struct brcmf_event_msg
*e
)
5258 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5259 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5260 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5261 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
5262 struct ieee80211_channel
*notify_channel
= NULL
;
5263 struct ieee80211_supported_band
*band
;
5264 struct brcmf_bss_info_le
*bi
;
5265 struct brcmu_chan ch
;
5270 brcmf_dbg(TRACE
, "Enter\n");
5272 brcmf_get_assoc_ies(cfg
, ifp
);
5273 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5274 brcmf_update_bss_info(cfg
, ifp
);
5276 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
5282 /* data sent to dongle has to be little endian */
5283 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
5284 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
5285 buf
, WL_BSS_INFO_MAX
);
5290 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
5291 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
5292 cfg
->d11inf
.decchspec(&ch
);
5294 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
5295 band
= wiphy
->bands
[NL80211_BAND_2GHZ
];
5297 band
= wiphy
->bands
[NL80211_BAND_5GHZ
];
5299 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
5300 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
5304 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
5305 conn_info
->req_ie
, conn_info
->req_ie_len
,
5306 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
5307 brcmf_dbg(CONN
, "Report roaming result\n");
5309 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
5310 brcmf_dbg(TRACE
, "Exit\n");
5315 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
5316 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
5319 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5320 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5321 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5323 brcmf_dbg(TRACE
, "Enter\n");
5325 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5326 &ifp
->vif
->sme_state
)) {
5328 brcmf_get_assoc_ies(cfg
, ifp
);
5329 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5330 brcmf_update_bss_info(cfg
, ifp
);
5331 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
5332 &ifp
->vif
->sme_state
);
5334 cfg80211_connect_result(ndev
,
5335 (u8
*)profile
->bssid
,
5337 conn_info
->req_ie_len
,
5339 conn_info
->resp_ie_len
,
5340 completed
? WLAN_STATUS_SUCCESS
:
5341 WLAN_STATUS_AUTH_TIMEOUT
,
5343 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
5344 completed
? "succeeded" : "failed");
5346 brcmf_dbg(TRACE
, "Exit\n");
5351 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
5352 struct net_device
*ndev
,
5353 const struct brcmf_event_msg
*e
, void *data
)
5355 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5356 static int generation
;
5357 u32 event
= e
->event_code
;
5358 u32 reason
= e
->reason
;
5359 struct station_info sinfo
;
5361 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
5362 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
5363 ndev
!= cfg_to_ndev(cfg
)) {
5364 brcmf_dbg(CONN
, "AP mode link down\n");
5365 complete(&cfg
->vif_disabled
);
5367 brcmf_remove_interface(ifp
);
5371 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
5372 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
5373 memset(&sinfo
, 0, sizeof(sinfo
));
5375 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5378 sinfo
.assoc_req_ies
= data
;
5379 sinfo
.assoc_req_ies_len
= e
->datalen
;
5381 sinfo
.generation
= generation
;
5382 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
5383 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
5384 (event
== BRCMF_E_DEAUTH_IND
) ||
5385 (event
== BRCMF_E_DEAUTH
)) {
5386 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
5392 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
5393 const struct brcmf_event_msg
*e
, void *data
)
5395 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5396 struct net_device
*ndev
= ifp
->ndev
;
5397 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5398 struct ieee80211_channel
*chan
;
5401 if ((e
->event_code
== BRCMF_E_DEAUTH
) ||
5402 (e
->event_code
== BRCMF_E_DEAUTH_IND
) ||
5403 (e
->event_code
== BRCMF_E_DISASSOC_IND
) ||
5404 ((e
->event_code
== BRCMF_E_LINK
) && (!e
->flags
))) {
5405 brcmf_proto_delete_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
5408 if (brcmf_is_apmode(ifp
->vif
)) {
5409 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
5410 } else if (brcmf_is_linkup(e
)) {
5411 brcmf_dbg(CONN
, "Linkup\n");
5412 if (brcmf_is_ibssmode(ifp
->vif
)) {
5413 brcmf_inform_ibss(cfg
, ndev
, e
->addr
);
5414 chan
= ieee80211_get_channel(cfg
->wiphy
, cfg
->channel
);
5415 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5416 cfg80211_ibss_joined(ndev
, e
->addr
, chan
, GFP_KERNEL
);
5417 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5418 &ifp
->vif
->sme_state
);
5419 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
5420 &ifp
->vif
->sme_state
);
5422 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
5423 brcmf_net_setcarrier(ifp
, true);
5424 } else if (brcmf_is_linkdown(e
)) {
5425 brcmf_dbg(CONN
, "Linkdown\n");
5426 if (!brcmf_is_ibssmode(ifp
->vif
)) {
5427 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
5428 brcmf_link_down(ifp
->vif
,
5429 brcmf_map_fw_linkdown_reason(e
));
5430 brcmf_init_prof(ndev_to_prof(ndev
));
5431 if (ndev
!= cfg_to_ndev(cfg
))
5432 complete(&cfg
->vif_disabled
);
5433 brcmf_net_setcarrier(ifp
, false);
5435 } else if (brcmf_is_nonetwork(cfg
, e
)) {
5436 if (brcmf_is_ibssmode(ifp
->vif
))
5437 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5438 &ifp
->vif
->sme_state
);
5440 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
5447 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
5448 const struct brcmf_event_msg
*e
, void *data
)
5450 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5451 u32 event
= e
->event_code
;
5452 u32 status
= e
->status
;
5454 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
5455 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
5456 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
5458 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
5465 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
5466 const struct brcmf_event_msg
*e
, void *data
)
5468 u16 flags
= e
->flags
;
5469 enum nl80211_key_type key_type
;
5471 if (flags
& BRCMF_EVENT_MSG_GROUP
)
5472 key_type
= NL80211_KEYTYPE_GROUP
;
5474 key_type
= NL80211_KEYTYPE_PAIRWISE
;
5476 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
5482 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
5483 const struct brcmf_event_msg
*e
, void *data
)
5485 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5486 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
5487 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5488 struct brcmf_cfg80211_vif
*vif
;
5490 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5491 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
5492 ifevent
->bsscfgidx
);
5494 mutex_lock(&event
->vif_event_lock
);
5495 event
->action
= ifevent
->action
;
5498 switch (ifevent
->action
) {
5499 case BRCMF_E_IF_ADD
:
5500 /* waiting process may have timed out */
5501 if (!cfg
->vif_event
.vif
) {
5502 mutex_unlock(&event
->vif_event_lock
);
5509 vif
->wdev
.netdev
= ifp
->ndev
;
5510 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
5511 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
5513 mutex_unlock(&event
->vif_event_lock
);
5514 wake_up(&event
->vif_wq
);
5517 case BRCMF_E_IF_DEL
:
5518 mutex_unlock(&event
->vif_event_lock
);
5519 /* event may not be upon user request */
5520 if (brcmf_cfg80211_vif_event_armed(cfg
))
5521 wake_up(&event
->vif_wq
);
5524 case BRCMF_E_IF_CHANGE
:
5525 mutex_unlock(&event
->vif_event_lock
);
5526 wake_up(&event
->vif_wq
);
5530 mutex_unlock(&event
->vif_event_lock
);
5536 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
5538 conf
->frag_threshold
= (u32
)-1;
5539 conf
->rts_threshold
= (u32
)-1;
5540 conf
->retry_short
= (u32
)-1;
5541 conf
->retry_long
= (u32
)-1;
5544 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
5546 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
5547 brcmf_notify_connect_status
);
5548 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
5549 brcmf_notify_connect_status
);
5550 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
5551 brcmf_notify_connect_status
);
5552 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
5553 brcmf_notify_connect_status
);
5554 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
5555 brcmf_notify_connect_status
);
5556 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
5557 brcmf_notify_connect_status
);
5558 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
5559 brcmf_notify_roaming_status
);
5560 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
5561 brcmf_notify_mic_status
);
5562 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
5563 brcmf_notify_connect_status
);
5564 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
5565 brcmf_notify_sched_scan_results
);
5566 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
5567 brcmf_notify_vif_event
);
5568 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
5569 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
5570 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
5571 brcmf_p2p_notify_listen_complete
);
5572 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
5573 brcmf_p2p_notify_action_frame_rx
);
5574 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
5575 brcmf_p2p_notify_action_tx_complete
);
5576 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
5577 brcmf_p2p_notify_action_tx_complete
);
5580 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
5584 kfree(cfg
->extra_buf
);
5585 cfg
->extra_buf
= NULL
;
5586 kfree(cfg
->wowl
.nd
);
5587 cfg
->wowl
.nd
= NULL
;
5588 kfree(cfg
->wowl
.nd_info
);
5589 cfg
->wowl
.nd_info
= NULL
;
5590 kfree(cfg
->escan_info
.escan_buf
);
5591 cfg
->escan_info
.escan_buf
= NULL
;
5594 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
5596 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
5598 goto init_priv_mem_out
;
5599 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
5600 if (!cfg
->extra_buf
)
5601 goto init_priv_mem_out
;
5602 cfg
->wowl
.nd
= kzalloc(sizeof(*cfg
->wowl
.nd
) + sizeof(u32
), GFP_KERNEL
);
5604 goto init_priv_mem_out
;
5605 cfg
->wowl
.nd_info
= kzalloc(sizeof(*cfg
->wowl
.nd_info
) +
5606 sizeof(struct cfg80211_wowlan_nd_match
*),
5608 if (!cfg
->wowl
.nd_info
)
5609 goto init_priv_mem_out
;
5610 cfg
->escan_info
.escan_buf
= kzalloc(BRCMF_ESCAN_BUF_SIZE
, GFP_KERNEL
);
5611 if (!cfg
->escan_info
.escan_buf
)
5612 goto init_priv_mem_out
;
5617 brcmf_deinit_priv_mem(cfg
);
5622 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
5626 cfg
->scan_request
= NULL
;
5627 cfg
->pwr_save
= true;
5628 cfg
->active_scan
= true; /* we do active scan per default */
5629 cfg
->dongle_up
= false; /* dongle is not up yet */
5630 err
= brcmf_init_priv_mem(cfg
);
5633 brcmf_register_event_handlers(cfg
);
5634 mutex_init(&cfg
->usr_sync
);
5635 brcmf_init_escan(cfg
);
5636 brcmf_init_conf(cfg
->conf
);
5637 init_completion(&cfg
->vif_disabled
);
5641 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
5643 cfg
->dongle_up
= false; /* dongle down */
5644 brcmf_abort_scanning(cfg
);
5645 brcmf_deinit_priv_mem(cfg
);
5648 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
5650 init_waitqueue_head(&event
->vif_wq
);
5651 mutex_init(&event
->vif_event_lock
);
5654 static s32
brcmf_dongle_roam(struct brcmf_if
*ifp
)
5658 __le32 roamtrigger
[2];
5659 __le32 roam_delta
[2];
5661 /* Configure beacon timeout value based upon roaming setting */
5662 if (ifp
->drvr
->settings
->roamoff
)
5663 bcn_timeout
= BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF
;
5665 bcn_timeout
= BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON
;
5666 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5668 brcmf_err("bcn_timeout error (%d)\n", err
);
5669 goto roam_setup_done
;
5672 /* Enable/Disable built-in roaming to allow supplicant to take care of
5675 brcmf_dbg(INFO
, "Internal Roaming = %s\n",
5676 ifp
->drvr
->settings
->roamoff
? "Off" : "On");
5677 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off",
5678 ifp
->drvr
->settings
->roamoff
);
5680 brcmf_err("roam_off error (%d)\n", err
);
5681 goto roam_setup_done
;
5684 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5685 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5686 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5687 (void *)roamtrigger
, sizeof(roamtrigger
));
5689 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5690 goto roam_setup_done
;
5693 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5694 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5695 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5696 (void *)roam_delta
, sizeof(roam_delta
));
5698 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5699 goto roam_setup_done
;
5707 brcmf_dongle_scantime(struct brcmf_if
*ifp
)
5711 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5712 BRCMF_SCAN_CHANNEL_TIME
);
5714 brcmf_err("Scan assoc time error (%d)\n", err
);
5715 goto dongle_scantime_out
;
5717 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5718 BRCMF_SCAN_UNASSOC_TIME
);
5720 brcmf_err("Scan unassoc time error (%d)\n", err
);
5721 goto dongle_scantime_out
;
5724 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5725 BRCMF_SCAN_PASSIVE_TIME
);
5727 brcmf_err("Scan passive time error (%d)\n", err
);
5728 goto dongle_scantime_out
;
5731 dongle_scantime_out
:
5735 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel
*channel
,
5736 struct brcmu_chan
*ch
)
5740 ht40_flag
= channel
->flags
& IEEE80211_CHAN_NO_HT40
;
5741 if (ch
->sb
== BRCMU_CHAN_SB_U
) {
5742 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5743 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40
;
5744 channel
->flags
|= IEEE80211_CHAN_NO_HT40PLUS
;
5746 /* It should be one of
5747 * IEEE80211_CHAN_NO_HT40 or
5748 * IEEE80211_CHAN_NO_HT40PLUS
5750 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40
;
5751 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5752 channel
->flags
|= IEEE80211_CHAN_NO_HT40MINUS
;
5756 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info
*cfg
,
5759 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5760 struct ieee80211_supported_band
*band
;
5761 struct ieee80211_channel
*channel
;
5762 struct wiphy
*wiphy
;
5763 struct brcmf_chanspec_list
*list
;
5764 struct brcmu_chan ch
;
5772 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5777 list
= (struct brcmf_chanspec_list
*)pbuf
;
5779 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5782 brcmf_err("get chanspecs error (%d)\n", err
);
5786 wiphy
= cfg_to_wiphy(cfg
);
5787 band
= wiphy
->bands
[NL80211_BAND_2GHZ
];
5789 for (i
= 0; i
< band
->n_channels
; i
++)
5790 band
->channels
[i
].flags
= IEEE80211_CHAN_DISABLED
;
5791 band
= wiphy
->bands
[NL80211_BAND_5GHZ
];
5793 for (i
= 0; i
< band
->n_channels
; i
++)
5794 band
->channels
[i
].flags
= IEEE80211_CHAN_DISABLED
;
5796 total
= le32_to_cpu(list
->count
);
5797 for (i
= 0; i
< total
; i
++) {
5798 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5799 cfg
->d11inf
.decchspec(&ch
);
5801 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5802 band
= wiphy
->bands
[NL80211_BAND_2GHZ
];
5803 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5804 band
= wiphy
->bands
[NL80211_BAND_5GHZ
];
5806 brcmf_err("Invalid channel Spec. 0x%x.\n", ch
.chspec
);
5811 if (!(bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) &&
5812 ch
.bw
== BRCMU_CHAN_BW_40
)
5814 if (!(bw_cap
[band
->band
] & WLC_BW_80MHZ_BIT
) &&
5815 ch
.bw
== BRCMU_CHAN_BW_80
)
5818 channel
= band
->channels
;
5819 index
= band
->n_channels
;
5820 for (j
= 0; j
< band
->n_channels
; j
++) {
5821 if (channel
[j
].hw_value
== ch
.chnum
) {
5826 channel
[index
].center_freq
=
5827 ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
5828 channel
[index
].hw_value
= ch
.chnum
;
5830 /* assuming the chanspecs order is HT20,
5831 * HT40 upper, HT40 lower, and VHT80.
5833 if (ch
.bw
== BRCMU_CHAN_BW_80
) {
5834 channel
[index
].flags
&= ~IEEE80211_CHAN_NO_80MHZ
;
5835 } else if (ch
.bw
== BRCMU_CHAN_BW_40
) {
5836 brcmf_update_bw40_channel_flag(&channel
[index
], &ch
);
5838 /* enable the channel and disable other bandwidths
5839 * for now as mentioned order assure they are enabled
5840 * for subsequent chanspecs.
5842 channel
[index
].flags
= IEEE80211_CHAN_NO_HT40
|
5843 IEEE80211_CHAN_NO_80MHZ
;
5844 ch
.bw
= BRCMU_CHAN_BW_20
;
5845 cfg
->d11inf
.encchspec(&ch
);
5846 chaninfo
= ch
.chspec
;
5847 err
= brcmf_fil_bsscfg_int_get(ifp
, "per_chan_info",
5850 if (chaninfo
& WL_CHAN_RADAR
)
5851 channel
[index
].flags
|=
5852 (IEEE80211_CHAN_RADAR
|
5853 IEEE80211_CHAN_NO_IR
);
5854 if (chaninfo
& WL_CHAN_PASSIVE
)
5855 channel
[index
].flags
|=
5856 IEEE80211_CHAN_NO_IR
;
5866 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info
*cfg
)
5868 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5869 struct ieee80211_supported_band
*band
;
5870 struct brcmf_fil_bwcap_le band_bwcap
;
5871 struct brcmf_chanspec_list
*list
;
5875 struct brcmu_chan ch
;
5879 /* verify support for bw_cap command */
5881 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &val
);
5884 /* only set 2G bandwidth using bw_cap command */
5885 band_bwcap
.band
= cpu_to_le32(WLC_BAND_2G
);
5886 band_bwcap
.bw_cap
= cpu_to_le32(WLC_BW_CAP_40MHZ
);
5887 err
= brcmf_fil_iovar_data_set(ifp
, "bw_cap", &band_bwcap
,
5888 sizeof(band_bwcap
));
5890 brcmf_dbg(INFO
, "fallback to mimo_bw_cap\n");
5891 val
= WLC_N_BW_40ALL
;
5892 err
= brcmf_fil_iovar_int_set(ifp
, "mimo_bw_cap", val
);
5896 /* update channel info in 2G band */
5897 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5902 ch
.band
= BRCMU_CHAN_BAND_2G
;
5903 ch
.bw
= BRCMU_CHAN_BW_40
;
5904 ch
.sb
= BRCMU_CHAN_SB_NONE
;
5906 cfg
->d11inf
.encchspec(&ch
);
5908 /* pass encoded chanspec in query */
5909 *(__le16
*)pbuf
= cpu_to_le16(ch
.chspec
);
5911 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5914 brcmf_err("get chanspecs error (%d)\n", err
);
5919 band
= cfg_to_wiphy(cfg
)->bands
[NL80211_BAND_2GHZ
];
5920 list
= (struct brcmf_chanspec_list
*)pbuf
;
5921 num_chan
= le32_to_cpu(list
->count
);
5922 for (i
= 0; i
< num_chan
; i
++) {
5923 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5924 cfg
->d11inf
.decchspec(&ch
);
5925 if (WARN_ON(ch
.band
!= BRCMU_CHAN_BAND_2G
))
5927 if (WARN_ON(ch
.bw
!= BRCMU_CHAN_BW_40
))
5929 for (j
= 0; j
< band
->n_channels
; j
++) {
5930 if (band
->channels
[j
].hw_value
== ch
.chnum
)
5933 if (WARN_ON(j
== band
->n_channels
))
5936 brcmf_update_bw40_channel_flag(&band
->channels
[j
], &ch
);
5943 static void brcmf_get_bwcap(struct brcmf_if
*ifp
, u32 bw_cap
[])
5945 u32 band
, mimo_bwcap
;
5949 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5951 bw_cap
[NL80211_BAND_2GHZ
] = band
;
5953 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5955 bw_cap
[NL80211_BAND_5GHZ
] = band
;
5961 brcmf_dbg(INFO
, "fallback to mimo_bw_cap info\n");
5963 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &mimo_bwcap
);
5965 /* assume 20MHz if firmware does not give a clue */
5966 mimo_bwcap
= WLC_N_BW_20ALL
;
5968 switch (mimo_bwcap
) {
5969 case WLC_N_BW_40ALL
:
5970 bw_cap
[NL80211_BAND_2GHZ
] |= WLC_BW_40MHZ_BIT
;
5972 case WLC_N_BW_20IN2G_40IN5G
:
5973 bw_cap
[NL80211_BAND_5GHZ
] |= WLC_BW_40MHZ_BIT
;
5975 case WLC_N_BW_20ALL
:
5976 bw_cap
[NL80211_BAND_2GHZ
] |= WLC_BW_20MHZ_BIT
;
5977 bw_cap
[NL80211_BAND_5GHZ
] |= WLC_BW_20MHZ_BIT
;
5980 brcmf_err("invalid mimo_bw_cap value\n");
5984 static void brcmf_update_ht_cap(struct ieee80211_supported_band
*band
,
5985 u32 bw_cap
[2], u32 nchain
)
5987 band
->ht_cap
.ht_supported
= true;
5988 if (bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) {
5989 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_40
;
5990 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
5992 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5993 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5994 band
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5995 band
->ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5996 memset(band
->ht_cap
.mcs
.rx_mask
, 0xff, nchain
);
5997 band
->ht_cap
.mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
6000 static __le16
brcmf_get_mcs_map(u32 nchain
, enum ieee80211_vht_mcs_support supp
)
6005 for (i
= 0, mcs_map
= 0xFFFF; i
< nchain
; i
++)
6006 mcs_map
= (mcs_map
<< 2) | supp
;
6008 return cpu_to_le16(mcs_map
);
6011 static void brcmf_update_vht_cap(struct ieee80211_supported_band
*band
,
6012 u32 bw_cap
[2], u32 nchain
, u32 txstreams
,
6013 u32 txbf_bfe_cap
, u32 txbf_bfr_cap
)
6017 /* not allowed in 2.4G band */
6018 if (band
->band
== NL80211_BAND_2GHZ
)
6021 band
->vht_cap
.vht_supported
= true;
6022 /* 80MHz is mandatory */
6023 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SHORT_GI_80
;
6024 if (bw_cap
[band
->band
] & WLC_BW_160MHZ_BIT
) {
6025 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ
;
6026 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SHORT_GI_160
;
6028 /* all support 256-QAM */
6029 mcs_map
= brcmf_get_mcs_map(nchain
, IEEE80211_VHT_MCS_SUPPORT_0_9
);
6030 band
->vht_cap
.vht_mcs
.rx_mcs_map
= mcs_map
;
6031 band
->vht_cap
.vht_mcs
.tx_mcs_map
= mcs_map
;
6033 /* Beamforming support information */
6034 if (txbf_bfe_cap
& BRCMF_TXBF_SU_BFE_CAP
)
6035 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE
;
6036 if (txbf_bfe_cap
& BRCMF_TXBF_MU_BFE_CAP
)
6037 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
6038 if (txbf_bfr_cap
& BRCMF_TXBF_SU_BFR_CAP
)
6039 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE
;
6040 if (txbf_bfr_cap
& BRCMF_TXBF_MU_BFR_CAP
)
6041 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE
;
6043 if ((txbf_bfe_cap
|| txbf_bfr_cap
) && (txstreams
> 1)) {
6044 band
->vht_cap
.cap
|=
6045 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
);
6046 band
->vht_cap
.cap
|= ((txstreams
- 1) <<
6047 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT
);
6048 band
->vht_cap
.cap
|=
6049 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB
;
6053 static int brcmf_setup_wiphybands(struct wiphy
*wiphy
)
6055 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
6056 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
6059 u32 bw_cap
[2] = { WLC_BW_20MHZ_BIT
, WLC_BW_20MHZ_BIT
};
6064 struct ieee80211_supported_band
*band
;
6066 u32 txbf_bfe_cap
= 0;
6067 u32 txbf_bfr_cap
= 0;
6069 (void)brcmf_fil_iovar_int_get(ifp
, "vhtmode", &vhtmode
);
6070 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
6072 brcmf_err("nmode error (%d)\n", err
);
6074 brcmf_get_bwcap(ifp
, bw_cap
);
6076 brcmf_dbg(INFO
, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
6077 nmode
, vhtmode
, bw_cap
[NL80211_BAND_2GHZ
],
6078 bw_cap
[NL80211_BAND_5GHZ
]);
6080 err
= brcmf_fil_iovar_int_get(ifp
, "rxchain", &rxchain
);
6082 brcmf_err("rxchain error (%d)\n", err
);
6085 for (nchain
= 0; rxchain
; nchain
++)
6086 rxchain
= rxchain
& (rxchain
- 1);
6088 brcmf_dbg(INFO
, "nchain=%d\n", nchain
);
6090 err
= brcmf_construct_chaninfo(cfg
, bw_cap
);
6092 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err
);
6097 (void)brcmf_fil_iovar_int_get(ifp
, "txstreams", &txstreams
);
6098 (void)brcmf_fil_iovar_int_get(ifp
, "txbf_bfe_cap",
6100 (void)brcmf_fil_iovar_int_get(ifp
, "txbf_bfr_cap",
6104 wiphy
= cfg_to_wiphy(cfg
);
6105 for (i
= 0; i
< ARRAY_SIZE(wiphy
->bands
); i
++) {
6106 band
= wiphy
->bands
[i
];
6111 brcmf_update_ht_cap(band
, bw_cap
, nchain
);
6113 brcmf_update_vht_cap(band
, bw_cap
, nchain
, txstreams
,
6114 txbf_bfe_cap
, txbf_bfr_cap
);
6120 static const struct ieee80211_txrx_stypes
6121 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
6122 [NL80211_IFTYPE_STATION
] = {
6124 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
6125 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
6127 [NL80211_IFTYPE_P2P_CLIENT
] = {
6129 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
6130 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
6132 [NL80211_IFTYPE_P2P_GO
] = {
6134 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
6135 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
6136 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
6137 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
6138 BIT(IEEE80211_STYPE_AUTH
>> 4) |
6139 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
6140 BIT(IEEE80211_STYPE_ACTION
>> 4)
6142 [NL80211_IFTYPE_P2P_DEVICE
] = {
6144 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
6145 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
6150 * brcmf_setup_ifmodes() - determine interface modes and combinations.
6152 * @wiphy: wiphy object.
6153 * @ifp: interface object needed for feat module api.
6155 * The interface modes and combinations are determined dynamically here
6156 * based on firmware functionality.
6158 * no p2p and no mbss:
6160 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6164 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6165 * #AP <= 4, matching BI, channels = 1, 4 total
6167 * p2p, no mchan, and mbss:
6169 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
6170 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6171 * #AP <= 4, matching BI, channels = 1, 4 total
6173 * p2p, mchan, and mbss:
6175 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6176 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6177 * #AP <= 4, matching BI, channels = 1, 4 total
6179 static int brcmf_setup_ifmodes(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6181 struct ieee80211_iface_combination
*combo
= NULL
;
6182 struct ieee80211_iface_limit
*c0_limits
= NULL
;
6183 struct ieee80211_iface_limit
*p2p_limits
= NULL
;
6184 struct ieee80211_iface_limit
*mbss_limits
= NULL
;
6188 mbss
= brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
);
6189 p2p
= brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_P2P
);
6191 n_combos
= 1 + !!p2p
+ !!mbss
;
6192 combo
= kcalloc(n_combos
, sizeof(*combo
), GFP_KERNEL
);
6196 c0_limits
= kcalloc(p2p
? 3 : 2, sizeof(*c0_limits
), GFP_KERNEL
);
6201 p2p_limits
= kcalloc(4, sizeof(*p2p_limits
), GFP_KERNEL
);
6207 mbss_limits
= kcalloc(1, sizeof(*mbss_limits
), GFP_KERNEL
);
6212 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
6213 BIT(NL80211_IFTYPE_ADHOC
) |
6214 BIT(NL80211_IFTYPE_AP
);
6218 combo
[c
].num_different_channels
= 1;
6219 c0_limits
[i
].max
= 1;
6220 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_STATION
);
6222 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MCHAN
))
6223 combo
[c
].num_different_channels
= 2;
6224 wiphy
->interface_modes
|= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
6225 BIT(NL80211_IFTYPE_P2P_GO
) |
6226 BIT(NL80211_IFTYPE_P2P_DEVICE
);
6227 c0_limits
[i
].max
= 1;
6228 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_DEVICE
);
6229 c0_limits
[i
].max
= 1;
6230 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
6231 BIT(NL80211_IFTYPE_P2P_GO
);
6233 c0_limits
[i
].max
= 1;
6234 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_AP
);
6236 combo
[c
].max_interfaces
= i
;
6237 combo
[c
].n_limits
= i
;
6238 combo
[c
].limits
= c0_limits
;
6243 combo
[c
].num_different_channels
= 1;
6244 p2p_limits
[i
].max
= 1;
6245 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_STATION
);
6246 p2p_limits
[i
].max
= 1;
6247 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_AP
);
6248 p2p_limits
[i
].max
= 1;
6249 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_CLIENT
);
6250 p2p_limits
[i
].max
= 1;
6251 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_DEVICE
);
6252 combo
[c
].max_interfaces
= i
;
6253 combo
[c
].n_limits
= i
;
6254 combo
[c
].limits
= p2p_limits
;
6259 combo
[c
].beacon_int_infra_match
= true;
6260 combo
[c
].num_different_channels
= 1;
6261 mbss_limits
[0].max
= 4;
6262 mbss_limits
[0].types
= BIT(NL80211_IFTYPE_AP
);
6263 combo
[c
].max_interfaces
= 4;
6264 combo
[c
].n_limits
= 1;
6265 combo
[c
].limits
= mbss_limits
;
6267 wiphy
->n_iface_combinations
= n_combos
;
6268 wiphy
->iface_combinations
= combo
;
6279 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
6281 /* scheduled scan settings */
6282 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
6283 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
6284 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
6285 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
6289 static struct wiphy_wowlan_support brcmf_wowlan_support
= {
6290 .flags
= WIPHY_WOWLAN_MAGIC_PKT
| WIPHY_WOWLAN_DISCONNECT
,
6291 .n_patterns
= BRCMF_WOWL_MAXPATTERNS
,
6292 .pattern_max_len
= BRCMF_WOWL_MAXPATTERNSIZE
,
6293 .pattern_min_len
= 1,
6294 .max_pkt_offset
= 1500,
6298 static void brcmf_wiphy_wowl_params(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6301 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
6303 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
)) {
6304 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL_ND
)) {
6305 brcmf_wowlan_support
.flags
|= WIPHY_WOWLAN_NET_DETECT
;
6306 init_waitqueue_head(&cfg
->wowl
.nd_data_wait
);
6309 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL_GTK
)) {
6310 brcmf_wowlan_support
.flags
|= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY
;
6311 brcmf_wowlan_support
.flags
|= WIPHY_WOWLAN_GTK_REKEY_FAILURE
;
6314 wiphy
->wowlan
= &brcmf_wowlan_support
;
6318 static int brcmf_setup_wiphy(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6320 struct brcmf_pub
*drvr
= ifp
->drvr
;
6321 const struct ieee80211_iface_combination
*combo
;
6322 struct ieee80211_supported_band
*band
;
6323 u16 max_interfaces
= 0;
6328 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
6329 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
6330 wiphy
->max_num_pmkids
= BRCMF_MAXPMKID
;
6332 err
= brcmf_setup_ifmodes(wiphy
, ifp
);
6336 for (i
= 0, combo
= wiphy
->iface_combinations
;
6337 i
< wiphy
->n_iface_combinations
; i
++, combo
++) {
6338 max_interfaces
= max(max_interfaces
, combo
->max_interfaces
);
6341 for (i
= 0; i
< max_interfaces
&& i
< ARRAY_SIZE(drvr
->addresses
);
6343 u8
*addr
= drvr
->addresses
[i
].addr
;
6345 memcpy(addr
, drvr
->mac
, ETH_ALEN
);
6348 addr
[ETH_ALEN
- 1] ^= i
;
6351 wiphy
->addresses
= drvr
->addresses
;
6352 wiphy
->n_addresses
= i
;
6354 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
6355 wiphy
->cipher_suites
= brcmf_cipher_suites
;
6356 wiphy
->n_cipher_suites
= ARRAY_SIZE(brcmf_cipher_suites
);
6357 if (!brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MFP
))
6358 wiphy
->n_cipher_suites
--;
6359 wiphy
->bss_select_support
= BIT(NL80211_BSS_SELECT_ATTR_RSSI
) |
6360 BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF
) |
6361 BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST
);
6363 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
6364 WIPHY_FLAG_OFFCHAN_TX
|
6365 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
6366 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_TDLS
))
6367 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_TDLS
;
6368 if (!ifp
->drvr
->settings
->roamoff
)
6369 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_FW_ROAM
;
6370 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
6371 wiphy
->max_remain_on_channel_duration
= 5000;
6372 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
))
6373 brcmf_wiphy_pno_params(wiphy
);
6375 /* vendor commands/events support */
6376 wiphy
->vendor_commands
= brcmf_vendor_cmds
;
6377 wiphy
->n_vendor_commands
= BRCMF_VNDR_CMDS_LAST
- 1;
6379 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL
))
6380 brcmf_wiphy_wowl_params(wiphy
, ifp
);
6381 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
, &bandlist
,
6384 brcmf_err("could not obtain band info: err=%d\n", err
);
6387 /* first entry in bandlist is number of bands */
6388 n_bands
= le32_to_cpu(bandlist
[0]);
6389 for (i
= 1; i
<= n_bands
&& i
< ARRAY_SIZE(bandlist
); i
++) {
6390 if (bandlist
[i
] == cpu_to_le32(WLC_BAND_2G
)) {
6391 band
= kmemdup(&__wl_band_2ghz
, sizeof(__wl_band_2ghz
),
6396 band
->channels
= kmemdup(&__wl_2ghz_channels
,
6397 sizeof(__wl_2ghz_channels
),
6399 if (!band
->channels
) {
6404 band
->n_channels
= ARRAY_SIZE(__wl_2ghz_channels
);
6405 wiphy
->bands
[NL80211_BAND_2GHZ
] = band
;
6407 if (bandlist
[i
] == cpu_to_le32(WLC_BAND_5G
)) {
6408 band
= kmemdup(&__wl_band_5ghz
, sizeof(__wl_band_5ghz
),
6413 band
->channels
= kmemdup(&__wl_5ghz_channels
,
6414 sizeof(__wl_5ghz_channels
),
6416 if (!band
->channels
) {
6421 band
->n_channels
= ARRAY_SIZE(__wl_5ghz_channels
);
6422 wiphy
->bands
[NL80211_BAND_5GHZ
] = band
;
6425 err
= brcmf_setup_wiphybands(wiphy
);
6429 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
6431 struct net_device
*ndev
;
6432 struct wireless_dev
*wdev
;
6433 struct brcmf_if
*ifp
;
6440 ndev
= cfg_to_ndev(cfg
);
6441 wdev
= ndev
->ieee80211_ptr
;
6442 ifp
= netdev_priv(ndev
);
6444 /* make sure RF is ready for work */
6445 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
6447 brcmf_dongle_scantime(ifp
);
6449 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
6450 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
6452 goto default_conf_out
;
6453 brcmf_dbg(INFO
, "power save set to %s\n",
6454 (power_mode
? "enabled" : "disabled"));
6456 err
= brcmf_dongle_roam(ifp
);
6458 goto default_conf_out
;
6459 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
6462 goto default_conf_out
;
6464 brcmf_configure_arp_nd_offload(ifp
, true);
6466 cfg
->dongle_up
= true;
6473 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
6475 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
6477 return brcmf_config_dongle(ifp
->drvr
->config
);
6480 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
6482 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6485 * While going down, if associated with AP disassociate
6486 * from AP to save power
6488 if (check_vif_up(ifp
->vif
)) {
6489 brcmf_link_down(ifp
->vif
, WLAN_REASON_UNSPECIFIED
);
6491 /* Make sure WPA_Supplicant receives all the event
6492 generated due to DISASSOC call to the fw to keep
6493 the state fw and WPA_Supplicant state consistent
6498 brcmf_abort_scanning(cfg
);
6499 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
6504 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
6506 struct brcmf_if
*ifp
= netdev_priv(ndev
);
6507 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6510 mutex_lock(&cfg
->usr_sync
);
6511 err
= __brcmf_cfg80211_up(ifp
);
6512 mutex_unlock(&cfg
->usr_sync
);
6517 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
6519 struct brcmf_if
*ifp
= netdev_priv(ndev
);
6520 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6523 mutex_lock(&cfg
->usr_sync
);
6524 err
= __brcmf_cfg80211_down(ifp
);
6525 mutex_unlock(&cfg
->usr_sync
);
6530 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
6532 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
6534 return wdev
->iftype
;
6537 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info
*cfg
,
6538 unsigned long state
)
6540 struct brcmf_cfg80211_vif
*vif
;
6542 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
6543 if (test_bit(state
, &vif
->sme_state
))
6549 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
6554 mutex_lock(&event
->vif_event_lock
);
6555 evt_action
= event
->action
;
6556 mutex_unlock(&event
->vif_event_lock
);
6557 return evt_action
== action
;
6560 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
6561 struct brcmf_cfg80211_vif
*vif
)
6563 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6565 mutex_lock(&event
->vif_event_lock
);
6568 mutex_unlock(&event
->vif_event_lock
);
6571 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
6573 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6576 mutex_lock(&event
->vif_event_lock
);
6577 armed
= event
->vif
!= NULL
;
6578 mutex_unlock(&event
->vif_event_lock
);
6583 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info
*cfg
,
6584 u8 action
, ulong timeout
)
6586 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6588 return wait_event_timeout(event
->vif_wq
,
6589 vif_event_equals(event
, action
), timeout
);
6592 static s32
brcmf_translate_country_code(struct brcmf_pub
*drvr
, char alpha2
[2],
6593 struct brcmf_fil_country_le
*ccreq
)
6595 struct brcmfmac_pd_cc
*country_codes
;
6596 struct brcmfmac_pd_cc_entry
*cc
;
6600 country_codes
= drvr
->settings
->country_codes
;
6601 if (!country_codes
) {
6602 brcmf_dbg(TRACE
, "No country codes configured for device\n");
6606 if ((alpha2
[0] == ccreq
->country_abbrev
[0]) &&
6607 (alpha2
[1] == ccreq
->country_abbrev
[1])) {
6608 brcmf_dbg(TRACE
, "Country code already set\n");
6613 for (i
= 0; i
< country_codes
->table_size
; i
++) {
6614 cc
= &country_codes
->table
[i
];
6615 if ((cc
->iso3166
[0] == '\0') && (found_index
== -1))
6617 if ((cc
->iso3166
[0] == alpha2
[0]) &&
6618 (cc
->iso3166
[1] == alpha2
[1])) {
6623 if (found_index
== -1) {
6624 brcmf_dbg(TRACE
, "No country code match found\n");
6627 memset(ccreq
, 0, sizeof(*ccreq
));
6628 ccreq
->rev
= cpu_to_le32(country_codes
->table
[found_index
].rev
);
6629 memcpy(ccreq
->ccode
, country_codes
->table
[found_index
].cc
,
6630 BRCMF_COUNTRY_BUF_SZ
);
6631 ccreq
->country_abbrev
[0] = alpha2
[0];
6632 ccreq
->country_abbrev
[1] = alpha2
[1];
6633 ccreq
->country_abbrev
[2] = 0;
6638 static void brcmf_cfg80211_reg_notifier(struct wiphy
*wiphy
,
6639 struct regulatory_request
*req
)
6641 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
6642 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
6643 struct brcmf_fil_country_le ccreq
;
6647 /* ignore non-ISO3166 country codes */
6648 for (i
= 0; i
< sizeof(req
->alpha2
); i
++)
6649 if (req
->alpha2
[i
] < 'A' || req
->alpha2
[i
] > 'Z') {
6650 brcmf_err("not a ISO3166 code (0x%02x 0x%02x)\n",
6651 req
->alpha2
[0], req
->alpha2
[1]);
6655 brcmf_dbg(TRACE
, "Enter: initiator=%d, alpha=%c%c\n", req
->initiator
,
6656 req
->alpha2
[0], req
->alpha2
[1]);
6658 err
= brcmf_fil_iovar_data_get(ifp
, "country", &ccreq
, sizeof(ccreq
));
6660 brcmf_err("Country code iovar returned err = %d\n", err
);
6664 err
= brcmf_translate_country_code(ifp
->drvr
, req
->alpha2
, &ccreq
);
6668 err
= brcmf_fil_iovar_data_set(ifp
, "country", &ccreq
, sizeof(ccreq
));
6670 brcmf_err("Firmware rejected country setting\n");
6673 brcmf_setup_wiphybands(wiphy
);
6676 static void brcmf_free_wiphy(struct wiphy
*wiphy
)
6683 if (wiphy
->iface_combinations
) {
6684 for (i
= 0; i
< wiphy
->n_iface_combinations
; i
++)
6685 kfree(wiphy
->iface_combinations
[i
].limits
);
6687 kfree(wiphy
->iface_combinations
);
6688 if (wiphy
->bands
[NL80211_BAND_2GHZ
]) {
6689 kfree(wiphy
->bands
[NL80211_BAND_2GHZ
]->channels
);
6690 kfree(wiphy
->bands
[NL80211_BAND_2GHZ
]);
6692 if (wiphy
->bands
[NL80211_BAND_5GHZ
]) {
6693 kfree(wiphy
->bands
[NL80211_BAND_5GHZ
]->channels
);
6694 kfree(wiphy
->bands
[NL80211_BAND_5GHZ
]);
6699 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
6700 struct device
*busdev
,
6703 struct net_device
*ndev
= brcmf_get_ifp(drvr
, 0)->ndev
;
6704 struct brcmf_cfg80211_info
*cfg
;
6705 struct wiphy
*wiphy
;
6706 struct cfg80211_ops
*ops
;
6707 struct brcmf_cfg80211_vif
*vif
;
6708 struct brcmf_if
*ifp
;
6714 brcmf_err("ndev is invalid\n");
6718 ops
= kzalloc(sizeof(*ops
), GFP_KERNEL
);
6722 memcpy(ops
, &brcmf_cfg80211_ops
, sizeof(*ops
));
6723 ifp
= netdev_priv(ndev
);
6725 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL_GTK
))
6726 ops
->set_rekey_data
= brcmf_cfg80211_set_rekey_data
;
6728 wiphy
= wiphy_new(ops
, sizeof(struct brcmf_cfg80211_info
));
6730 brcmf_err("Could not allocate wiphy device\n");
6733 memcpy(wiphy
->perm_addr
, drvr
->mac
, ETH_ALEN
);
6734 set_wiphy_dev(wiphy
, busdev
);
6736 cfg
= wiphy_priv(wiphy
);
6740 init_vif_event(&cfg
->vif_event
);
6741 INIT_LIST_HEAD(&cfg
->vif_list
);
6743 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
6748 vif
->wdev
.netdev
= ndev
;
6749 ndev
->ieee80211_ptr
= &vif
->wdev
;
6750 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
6752 err
= wl_init_priv(cfg
);
6754 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
6755 brcmf_free_vif(vif
);
6760 /* determine d11 io type before wiphy setup */
6761 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
, &io_type
);
6763 brcmf_err("Failed to get D11 version (%d)\n", err
);
6766 cfg
->d11inf
.io_type
= (u8
)io_type
;
6767 brcmu_d11_attach(&cfg
->d11inf
);
6769 err
= brcmf_setup_wiphy(wiphy
, ifp
);
6773 brcmf_dbg(INFO
, "Registering custom regulatory\n");
6774 wiphy
->reg_notifier
= brcmf_cfg80211_reg_notifier
;
6775 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
6776 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
6778 /* firmware defaults to 40MHz disabled in 2G band. We signal
6779 * cfg80211 here that we do and have it decide we can enable
6780 * it. But first check if device does support 2G operation.
6782 if (wiphy
->bands
[NL80211_BAND_2GHZ
]) {
6783 cap
= &wiphy
->bands
[NL80211_BAND_2GHZ
]->ht_cap
.cap
;
6784 *cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
6786 err
= wiphy_register(wiphy
);
6788 brcmf_err("Could not register wiphy device (%d)\n", err
);
6792 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6793 * setup 40MHz in 2GHz band and enable OBSS scanning.
6795 if (cap
&& (*cap
& IEEE80211_HT_CAP_SUP_WIDTH_20_40
)) {
6796 err
= brcmf_enable_bw40_2g(cfg
);
6798 err
= brcmf_fil_iovar_int_set(ifp
, "obss_coex",
6799 BRCMF_OBSS_COEX_AUTO
);
6801 *cap
&= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
6803 /* p2p might require that "if-events" get processed by fweh. So
6804 * activate the already registered event handlers now and activate
6805 * the rest when initialization has completed. drvr->config needs to
6806 * be assigned before activating events.
6809 err
= brcmf_fweh_activate_events(ifp
);
6811 brcmf_err("FWEH activation failed (%d)\n", err
);
6812 goto wiphy_unreg_out
;
6815 err
= brcmf_p2p_attach(cfg
, p2pdev_forced
);
6817 brcmf_err("P2P initilisation failed (%d)\n", err
);
6818 goto wiphy_unreg_out
;
6820 err
= brcmf_btcoex_attach(cfg
);
6822 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
6823 brcmf_p2p_detach(&cfg
->p2p
);
6824 goto wiphy_unreg_out
;
6827 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_TDLS
)) {
6828 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
6830 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
6831 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
6833 brcmf_fweh_register(cfg
->pub
, BRCMF_E_TDLS_PEER_EVENT
,
6834 brcmf_notify_tdls_peer_event
);
6838 /* (re-) activate FWEH event handling */
6839 err
= brcmf_fweh_activate_events(ifp
);
6841 brcmf_err("FWEH activation failed (%d)\n", err
);
6842 goto wiphy_unreg_out
;
6845 /* Fill in some of the advertised nl80211 supported features */
6846 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_SCAN_RANDOM_MAC
)) {
6847 wiphy
->features
|= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR
;
6849 if (wiphy
->wowlan
&&
6850 wiphy
->wowlan
->flags
& WIPHY_WOWLAN_NET_DETECT
)
6851 wiphy
->features
|= NL80211_FEATURE_ND_RANDOM_MAC_ADDR
;
6858 wiphy_unregister(cfg
->wiphy
);
6860 wl_deinit_priv(cfg
);
6861 brcmf_free_vif(vif
);
6864 brcmf_free_wiphy(wiphy
);
6869 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
6874 brcmf_btcoex_detach(cfg
);
6875 wiphy_unregister(cfg
->wiphy
);
6877 wl_deinit_priv(cfg
);
6878 brcmf_free_wiphy(cfg
->wiphy
);