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_CAP_LEN 2 /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
81 #define VNDR_IE_COUNT_OFFSET 4
82 #define VNDR_IE_PKTFLAG_OFFSET 8
83 #define VNDR_IE_VSIE_OFFSET 12
84 #define VNDR_IE_HDR_SIZE 12
85 #define VNDR_IE_PARSE_LIMIT 5
87 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
90 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
91 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
92 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
94 #define BRCMF_SCAN_CHANNEL_TIME 40
95 #define BRCMF_SCAN_UNASSOC_TIME 40
96 #define BRCMF_SCAN_PASSIVE_TIME 120
98 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
100 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
101 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
103 static bool check_vif_up(struct brcmf_cfg80211_vif
*vif
)
105 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
)) {
106 brcmf_dbg(INFO
, "device is not ready : status (%lu)\n",
113 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
114 #define RATETAB_ENT(_rateid, _flags) \
116 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
117 .hw_value = (_rateid), \
121 static struct ieee80211_rate __wl_rates
[] = {
122 RATETAB_ENT(BRCM_RATE_1M
, 0),
123 RATETAB_ENT(BRCM_RATE_2M
, IEEE80211_RATE_SHORT_PREAMBLE
),
124 RATETAB_ENT(BRCM_RATE_5M5
, IEEE80211_RATE_SHORT_PREAMBLE
),
125 RATETAB_ENT(BRCM_RATE_11M
, IEEE80211_RATE_SHORT_PREAMBLE
),
126 RATETAB_ENT(BRCM_RATE_6M
, 0),
127 RATETAB_ENT(BRCM_RATE_9M
, 0),
128 RATETAB_ENT(BRCM_RATE_12M
, 0),
129 RATETAB_ENT(BRCM_RATE_18M
, 0),
130 RATETAB_ENT(BRCM_RATE_24M
, 0),
131 RATETAB_ENT(BRCM_RATE_36M
, 0),
132 RATETAB_ENT(BRCM_RATE_48M
, 0),
133 RATETAB_ENT(BRCM_RATE_54M
, 0),
136 #define wl_g_rates (__wl_rates + 0)
137 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
138 #define wl_a_rates (__wl_rates + 4)
139 #define wl_a_rates_size (wl_g_rates_size - 4)
141 #define CHAN2G(_channel, _freq) { \
142 .band = IEEE80211_BAND_2GHZ, \
143 .center_freq = (_freq), \
144 .hw_value = (_channel), \
145 .flags = IEEE80211_CHAN_DISABLED, \
146 .max_antenna_gain = 0, \
150 #define CHAN5G(_channel) { \
151 .band = IEEE80211_BAND_5GHZ, \
152 .center_freq = 5000 + (5 * (_channel)), \
153 .hw_value = (_channel), \
154 .flags = IEEE80211_CHAN_DISABLED, \
155 .max_antenna_gain = 0, \
159 static struct ieee80211_channel __wl_2ghz_channels
[] = {
160 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
161 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
162 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
163 CHAN2G(13, 2472), CHAN2G(14, 2484)
166 static struct ieee80211_channel __wl_5ghz_channels
[] = {
167 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
168 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
169 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
170 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
171 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
172 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
175 /* Band templates duplicated per wiphy. The channel info
176 * above is added to the band during setup.
178 static const struct ieee80211_supported_band __wl_band_2ghz
= {
179 .band
= IEEE80211_BAND_2GHZ
,
180 .bitrates
= wl_g_rates
,
181 .n_bitrates
= wl_g_rates_size
,
184 static const struct ieee80211_supported_band __wl_band_5ghz
= {
185 .band
= IEEE80211_BAND_5GHZ
,
186 .bitrates
= wl_a_rates
,
187 .n_bitrates
= wl_a_rates_size
,
190 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
191 * By default world regulatory domain defined in reg.c puts the flags
192 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
193 * With respect to these flags, wpa_supplicant doesn't * start p2p
194 * operations on 5GHz channels. All the changes in world regulatory
195 * domain are to be done here.
197 static const struct ieee80211_regdomain brcmf_regdom
= {
201 /* IEEE 802.11b/g, channels 1..11 */
202 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
204 /* IEEE 802.11 channel 14 - Only JP enables
205 * this and for 802.11b only
207 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
208 /* IEEE 802.11a, channel 36..64 */
209 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
210 /* IEEE 802.11a, channel 100..165 */
211 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
214 static const u32 __wl_cipher_suites
[] = {
215 WLAN_CIPHER_SUITE_WEP40
,
216 WLAN_CIPHER_SUITE_WEP104
,
217 WLAN_CIPHER_SUITE_TKIP
,
218 WLAN_CIPHER_SUITE_CCMP
,
219 WLAN_CIPHER_SUITE_AES_CMAC
,
222 /* Vendor specific ie. id = 221, oui and type defines exact ie */
223 struct brcmf_vs_tlv
{
230 struct parsed_vndr_ie_info
{
232 u32 ie_len
; /* total length including id & length field */
233 struct brcmf_vs_tlv vndrie
;
236 struct parsed_vndr_ies
{
238 struct parsed_vndr_ie_info ie_info
[VNDR_IE_PARSE_LIMIT
];
241 /* Function prototype forward declarations */
243 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
244 struct net_device
*ndev
,
245 struct cfg80211_sched_scan_request
*request
);
246 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
247 struct net_device
*ndev
);
249 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
250 const struct brcmf_event_msg
*e
, void *data
);
253 static u16
chandef_to_chanspec(struct brcmu_d11inf
*d11inf
,
254 struct cfg80211_chan_def
*ch
)
256 struct brcmu_chan ch_inf
;
259 brcmf_dbg(TRACE
, "chandef: control %d center %d width %d\n",
260 ch
->chan
->center_freq
, ch
->center_freq1
, ch
->width
);
261 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq1
);
262 primary_offset
= ch
->center_freq1
- ch
->chan
->center_freq
;
264 case NL80211_CHAN_WIDTH_20
:
265 case NL80211_CHAN_WIDTH_20_NOHT
:
266 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
267 WARN_ON(primary_offset
!= 0);
269 case NL80211_CHAN_WIDTH_40
:
270 ch_inf
.bw
= BRCMU_CHAN_BW_40
;
271 if (primary_offset
< 0)
272 ch_inf
.sb
= BRCMU_CHAN_SB_U
;
274 ch_inf
.sb
= BRCMU_CHAN_SB_L
;
276 case NL80211_CHAN_WIDTH_80
:
277 ch_inf
.bw
= BRCMU_CHAN_BW_80
;
278 if (primary_offset
< 0) {
279 if (primary_offset
< -CH_10MHZ_APART
)
280 ch_inf
.sb
= BRCMU_CHAN_SB_UU
;
282 ch_inf
.sb
= BRCMU_CHAN_SB_UL
;
284 if (primary_offset
> CH_10MHZ_APART
)
285 ch_inf
.sb
= BRCMU_CHAN_SB_LL
;
287 ch_inf
.sb
= BRCMU_CHAN_SB_LU
;
290 case NL80211_CHAN_WIDTH_80P80
:
291 case NL80211_CHAN_WIDTH_160
:
292 case NL80211_CHAN_WIDTH_5
:
293 case NL80211_CHAN_WIDTH_10
:
297 switch (ch
->chan
->band
) {
298 case IEEE80211_BAND_2GHZ
:
299 ch_inf
.band
= BRCMU_CHAN_BAND_2G
;
301 case IEEE80211_BAND_5GHZ
:
302 ch_inf
.band
= BRCMU_CHAN_BAND_5G
;
304 case IEEE80211_BAND_60GHZ
:
308 d11inf
->encchspec(&ch_inf
);
310 return ch_inf
.chspec
;
313 u16
channel_to_chanspec(struct brcmu_d11inf
*d11inf
,
314 struct ieee80211_channel
*ch
)
316 struct brcmu_chan ch_inf
;
318 ch_inf
.chnum
= ieee80211_frequency_to_channel(ch
->center_freq
);
319 ch_inf
.bw
= BRCMU_CHAN_BW_20
;
320 d11inf
->encchspec(&ch_inf
);
322 return ch_inf
.chspec
;
325 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
326 * triples, returning a pointer to the substring whose first element
329 const struct brcmf_tlv
*
330 brcmf_parse_tlvs(const void *buf
, int buflen
, uint key
)
332 const struct brcmf_tlv
*elt
= buf
;
335 /* find tagged parameter */
336 while (totlen
>= TLV_HDR_LEN
) {
339 /* validate remaining totlen */
340 if ((elt
->id
== key
) && (totlen
>= (len
+ TLV_HDR_LEN
)))
343 elt
= (struct brcmf_tlv
*)((u8
*)elt
+ (len
+ TLV_HDR_LEN
));
344 totlen
-= (len
+ TLV_HDR_LEN
);
350 /* Is any of the tlvs the expected entry? If
351 * not update the tlvs buffer pointer/length.
354 brcmf_tlv_has_ie(const u8
*ie
, const u8
**tlvs
, u32
*tlvs_len
,
355 const u8
*oui
, u32 oui_len
, u8 type
)
357 /* If the contents match the OUI and the type */
358 if (ie
[TLV_LEN_OFF
] >= oui_len
+ 1 &&
359 !memcmp(&ie
[TLV_BODY_OFF
], oui
, oui_len
) &&
360 type
== ie
[TLV_BODY_OFF
+ oui_len
]) {
366 /* point to the next ie */
367 ie
+= ie
[TLV_LEN_OFF
] + TLV_HDR_LEN
;
368 /* calculate the length of the rest of the buffer */
369 *tlvs_len
-= (int)(ie
- *tlvs
);
370 /* update the pointer to the start of the buffer */
376 static struct brcmf_vs_tlv
*
377 brcmf_find_wpaie(const u8
*parse
, u32 len
)
379 const struct brcmf_tlv
*ie
;
381 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
382 if (brcmf_tlv_has_ie((const u8
*)ie
, &parse
, &len
,
383 WPA_OUI
, TLV_OUI_LEN
, WPA_OUI_TYPE
))
384 return (struct brcmf_vs_tlv
*)ie
;
389 static struct brcmf_vs_tlv
*
390 brcmf_find_wpsie(const u8
*parse
, u32 len
)
392 const struct brcmf_tlv
*ie
;
394 while ((ie
= brcmf_parse_tlvs(parse
, len
, WLAN_EID_VENDOR_SPECIFIC
))) {
395 if (brcmf_tlv_has_ie((u8
*)ie
, &parse
, &len
,
396 WPA_OUI
, TLV_OUI_LEN
, WPS_OUI_TYPE
))
397 return (struct brcmf_vs_tlv
*)ie
;
402 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info
*cfg
,
403 struct brcmf_cfg80211_vif
*vif
,
404 enum nl80211_iftype new_type
)
406 int iftype_num
[NUM_NL80211_IFTYPES
];
407 struct brcmf_cfg80211_vif
*pos
;
408 bool check_combos
= false;
411 memset(&iftype_num
[0], 0, sizeof(iftype_num
));
412 list_for_each_entry(pos
, &cfg
->vif_list
, list
)
414 iftype_num
[new_type
]++;
416 /* concurrent interfaces so need check combinations */
418 iftype_num
[pos
->wdev
.iftype
]++;
422 ret
= cfg80211_check_combinations(cfg
->wiphy
, 1, 0, iftype_num
);
427 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info
*cfg
,
428 enum nl80211_iftype new_type
)
430 int iftype_num
[NUM_NL80211_IFTYPES
];
431 struct brcmf_cfg80211_vif
*pos
;
433 memset(&iftype_num
[0], 0, sizeof(iftype_num
));
434 list_for_each_entry(pos
, &cfg
->vif_list
, list
)
435 iftype_num
[pos
->wdev
.iftype
]++;
437 iftype_num
[new_type
]++;
438 return cfg80211_check_combinations(cfg
->wiphy
, 1, 0, iftype_num
);
441 static void convert_key_from_CPU(struct brcmf_wsec_key
*key
,
442 struct brcmf_wsec_key_le
*key_le
)
444 key_le
->index
= cpu_to_le32(key
->index
);
445 key_le
->len
= cpu_to_le32(key
->len
);
446 key_le
->algo
= cpu_to_le32(key
->algo
);
447 key_le
->flags
= cpu_to_le32(key
->flags
);
448 key_le
->rxiv
.hi
= cpu_to_le32(key
->rxiv
.hi
);
449 key_le
->rxiv
.lo
= cpu_to_le16(key
->rxiv
.lo
);
450 key_le
->iv_initialized
= cpu_to_le32(key
->iv_initialized
);
451 memcpy(key_le
->data
, key
->data
, sizeof(key
->data
));
452 memcpy(key_le
->ea
, key
->ea
, sizeof(key
->ea
));
456 send_key_to_dongle(struct brcmf_if
*ifp
, struct brcmf_wsec_key
*key
)
459 struct brcmf_wsec_key_le key_le
;
461 convert_key_from_CPU(key
, &key_le
);
463 brcmf_netdev_wait_pend8021x(ifp
);
465 err
= brcmf_fil_bsscfg_data_set(ifp
, "wsec_key", &key_le
,
469 brcmf_err("wsec_key error (%d)\n", err
);
474 brcmf_configure_arp_offload(struct brcmf_if
*ifp
, bool enable
)
480 mode
= BRCMF_ARP_OL_AGENT
| BRCMF_ARP_OL_PEER_AUTO_REPLY
;
484 /* Try to set and enable ARP offload feature, this may fail, then it */
485 /* is simply not supported and err 0 will be returned */
486 err
= brcmf_fil_iovar_int_set(ifp
, "arp_ol", mode
);
488 brcmf_dbg(TRACE
, "failed to set ARP offload mode to 0x%x, err = %d\n",
492 err
= brcmf_fil_iovar_int_set(ifp
, "arpoe", enable
);
494 brcmf_dbg(TRACE
, "failed to configure (%d) ARP offload err = %d\n",
498 brcmf_dbg(TRACE
, "successfully configured (%d) ARP offload to 0x%x\n",
506 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev
*wdev
)
508 struct brcmf_cfg80211_vif
*vif
;
509 struct brcmf_if
*ifp
;
511 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
514 if ((wdev
->iftype
== NL80211_IFTYPE_ADHOC
) ||
515 (wdev
->iftype
== NL80211_IFTYPE_AP
) ||
516 (wdev
->iftype
== NL80211_IFTYPE_P2P_GO
))
517 brcmf_proto_configure_addr_mode(ifp
->drvr
, ifp
->ifidx
,
520 brcmf_proto_configure_addr_mode(ifp
->drvr
, ifp
->ifidx
,
524 static int brcmf_cfg80211_request_ap_if(struct brcmf_if
*ifp
)
526 struct brcmf_mbss_ssid_le mbss_ssid_le
;
530 memset(&mbss_ssid_le
, 0, sizeof(mbss_ssid_le
));
531 bsscfgidx
= brcmf_get_next_free_bsscfgidx(ifp
->drvr
);
535 mbss_ssid_le
.bsscfgidx
= cpu_to_le32(bsscfgidx
);
536 mbss_ssid_le
.SSID_len
= cpu_to_le32(5);
537 sprintf(mbss_ssid_le
.SSID
, "ssid%d" , bsscfgidx
);
539 err
= brcmf_fil_bsscfg_data_set(ifp
, "bsscfg:ssid", &mbss_ssid_le
,
540 sizeof(mbss_ssid_le
));
542 brcmf_err("setting ssid failed %d\n", err
);
548 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
550 * @wiphy: wiphy device of new interface.
551 * @name: name of the new interface.
553 * @params: contains mac address for AP device.
556 struct wireless_dev
*brcmf_ap_add_vif(struct wiphy
*wiphy
, const char *name
,
557 u32
*flags
, struct vif_params
*params
)
559 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
560 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
561 struct brcmf_cfg80211_vif
*vif
;
564 if (brcmf_cfg80211_vif_event_armed(cfg
))
565 return ERR_PTR(-EBUSY
);
567 brcmf_dbg(INFO
, "Adding vif \"%s\"\n", name
);
569 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_AP
, false);
571 return (struct wireless_dev
*)vif
;
573 brcmf_cfg80211_arm_vif_event(cfg
, vif
);
575 err
= brcmf_cfg80211_request_ap_if(ifp
);
577 brcmf_cfg80211_arm_vif_event(cfg
, NULL
);
581 /* wait for firmware event */
582 err
= brcmf_cfg80211_wait_vif_event_timeout(cfg
, BRCMF_E_IF_ADD
,
583 msecs_to_jiffies(1500));
584 brcmf_cfg80211_arm_vif_event(cfg
, NULL
);
586 brcmf_err("timeout occurred\n");
591 /* interface created in firmware */
594 brcmf_err("no if pointer provided\n");
599 strncpy(ifp
->ndev
->name
, name
, sizeof(ifp
->ndev
->name
) - 1);
600 err
= brcmf_net_attach(ifp
, true);
602 brcmf_err("Registering netdevice failed\n");
606 return &ifp
->vif
->wdev
;
613 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif
*vif
)
615 enum nl80211_iftype iftype
;
617 iftype
= vif
->wdev
.iftype
;
618 return iftype
== NL80211_IFTYPE_AP
|| iftype
== NL80211_IFTYPE_P2P_GO
;
621 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif
*vif
)
623 return vif
->wdev
.iftype
== NL80211_IFTYPE_ADHOC
;
626 static struct wireless_dev
*brcmf_cfg80211_add_iface(struct wiphy
*wiphy
,
628 unsigned char name_assign_type
,
629 enum nl80211_iftype type
,
631 struct vif_params
*params
)
633 struct wireless_dev
*wdev
;
636 brcmf_dbg(TRACE
, "enter: %s type %d\n", name
, type
);
637 err
= brcmf_vif_add_validate(wiphy_to_cfg(wiphy
), type
);
639 brcmf_err("iface validation failed: err=%d\n", err
);
643 case NL80211_IFTYPE_ADHOC
:
644 case NL80211_IFTYPE_STATION
:
645 case NL80211_IFTYPE_AP_VLAN
:
646 case NL80211_IFTYPE_WDS
:
647 case NL80211_IFTYPE_MONITOR
:
648 case NL80211_IFTYPE_MESH_POINT
:
649 return ERR_PTR(-EOPNOTSUPP
);
650 case NL80211_IFTYPE_AP
:
651 wdev
= brcmf_ap_add_vif(wiphy
, name
, flags
, params
);
653 brcmf_cfg80211_update_proto_addr_mode(wdev
);
655 case NL80211_IFTYPE_P2P_CLIENT
:
656 case NL80211_IFTYPE_P2P_GO
:
657 case NL80211_IFTYPE_P2P_DEVICE
:
658 wdev
= brcmf_p2p_add_vif(wiphy
, name
, name_assign_type
, type
, flags
, params
);
660 brcmf_cfg80211_update_proto_addr_mode(wdev
);
662 case NL80211_IFTYPE_UNSPECIFIED
:
664 return ERR_PTR(-EINVAL
);
668 static void brcmf_scan_config_mpc(struct brcmf_if
*ifp
, int mpc
)
670 if (brcmf_feat_is_quirk_enabled(ifp
, BRCMF_FEAT_QUIRK_NEED_MPC
))
671 brcmf_set_mpc(ifp
, mpc
);
674 void brcmf_set_mpc(struct brcmf_if
*ifp
, int mpc
)
678 if (check_vif_up(ifp
->vif
)) {
679 err
= brcmf_fil_iovar_int_set(ifp
, "mpc", mpc
);
681 brcmf_err("fail to set mpc\n");
684 brcmf_dbg(INFO
, "MPC : %d\n", mpc
);
688 s32
brcmf_notify_escan_complete(struct brcmf_cfg80211_info
*cfg
,
689 struct brcmf_if
*ifp
, bool aborted
,
692 struct brcmf_scan_params_le params_le
;
693 struct cfg80211_scan_request
*scan_request
;
696 brcmf_dbg(SCAN
, "Enter\n");
698 /* clear scan request, because the FW abort can cause a second call */
699 /* to this functon and might cause a double cfg80211_scan_done */
700 scan_request
= cfg
->scan_request
;
701 cfg
->scan_request
= NULL
;
703 if (timer_pending(&cfg
->escan_timeout
))
704 del_timer_sync(&cfg
->escan_timeout
);
707 /* Do a scan abort to stop the driver's scan engine */
708 brcmf_dbg(SCAN
, "ABORT scan in firmware\n");
709 memset(¶ms_le
, 0, sizeof(params_le
));
710 eth_broadcast_addr(params_le
.bssid
);
711 params_le
.bss_type
= DOT11_BSSTYPE_ANY
;
712 params_le
.scan_type
= 0;
713 params_le
.channel_num
= cpu_to_le32(1);
714 params_le
.nprobes
= cpu_to_le32(1);
715 params_le
.active_time
= cpu_to_le32(-1);
716 params_le
.passive_time
= cpu_to_le32(-1);
717 params_le
.home_time
= cpu_to_le32(-1);
718 /* Scan is aborted by setting channel_list[0] to -1 */
719 params_le
.channel_list
[0] = cpu_to_le16(-1);
720 /* E-Scan (or anyother type) can be aborted by SCAN */
721 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
,
722 ¶ms_le
, sizeof(params_le
));
724 brcmf_err("Scan abort failed\n");
727 brcmf_scan_config_mpc(ifp
, 1);
730 * e-scan can be initiated by scheduled scan
731 * which takes precedence.
733 if (cfg
->sched_escan
) {
734 brcmf_dbg(SCAN
, "scheduled scan completed\n");
735 cfg
->sched_escan
= false;
737 cfg80211_sched_scan_results(cfg_to_wiphy(cfg
));
738 } else if (scan_request
) {
739 brcmf_dbg(SCAN
, "ESCAN Completed scan: %s\n",
740 aborted
? "Aborted" : "Done");
741 cfg80211_scan_done(scan_request
, aborted
);
743 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
744 brcmf_dbg(SCAN
, "Scan complete, probably P2P scan\n");
750 int brcmf_cfg80211_del_iface(struct wiphy
*wiphy
, struct wireless_dev
*wdev
)
752 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
753 struct net_device
*ndev
= wdev
->netdev
;
755 /* vif event pending in firmware */
756 if (brcmf_cfg80211_vif_event_armed(cfg
))
760 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
) &&
761 cfg
->escan_info
.ifp
== netdev_priv(ndev
))
762 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
),
765 brcmf_fil_iovar_int_set(netdev_priv(ndev
), "mpc", 1);
768 switch (wdev
->iftype
) {
769 case NL80211_IFTYPE_ADHOC
:
770 case NL80211_IFTYPE_STATION
:
771 case NL80211_IFTYPE_AP
:
772 case NL80211_IFTYPE_AP_VLAN
:
773 case NL80211_IFTYPE_WDS
:
774 case NL80211_IFTYPE_MONITOR
:
775 case NL80211_IFTYPE_MESH_POINT
:
777 case NL80211_IFTYPE_P2P_CLIENT
:
778 case NL80211_IFTYPE_P2P_GO
:
779 case NL80211_IFTYPE_P2P_DEVICE
:
780 return brcmf_p2p_del_vif(wiphy
, wdev
);
781 case NL80211_IFTYPE_UNSPECIFIED
:
789 brcmf_cfg80211_change_iface(struct wiphy
*wiphy
, struct net_device
*ndev
,
790 enum nl80211_iftype type
, u32
*flags
,
791 struct vif_params
*params
)
793 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
794 struct brcmf_if
*ifp
= netdev_priv(ndev
);
795 struct brcmf_cfg80211_vif
*vif
= ifp
->vif
;
800 brcmf_dbg(TRACE
, "Enter, bsscfgidx=%d, type=%d\n", ifp
->bsscfgidx
,
803 /* WAR: There are a number of p2p interface related problems which
804 * need to be handled initially (before doing the validate).
805 * wpa_supplicant tends to do iface changes on p2p device/client/go
806 * which are not always possible/allowed. However we need to return
807 * OK otherwise the wpa_supplicant wont start. The situation differs
808 * on configuration and setup (p2pon=1 module param). The first check
809 * is to see if the request is a change to station for p2p iface.
811 if ((type
== NL80211_IFTYPE_STATION
) &&
812 ((vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) ||
813 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_GO
) ||
814 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_DEVICE
))) {
815 brcmf_dbg(TRACE
, "Ignoring cmd for p2p if\n");
816 /* Now depending on whether module param p2pon=1 was used the
817 * response needs to be either 0 or EOPNOTSUPP. The reason is
818 * that if p2pon=1 is used, but a newer supplicant is used then
819 * we should return an error, as this combination wont work.
820 * In other situations 0 is returned and supplicant will start
821 * normally. It will give a trace in cfg80211, but it is the
822 * only way to get it working. Unfortunately this will result
823 * in situation where we wont support new supplicant in
824 * combination with module param p2pon=1, but that is the way
825 * it is. If the user tries this then unloading of driver might
828 if (cfg
->p2p
.p2pdev_dynamically
)
833 err
= brcmf_vif_change_validate(wiphy_to_cfg(wiphy
), vif
, type
);
835 brcmf_err("iface validation failed: err=%d\n", err
);
839 case NL80211_IFTYPE_MONITOR
:
840 case NL80211_IFTYPE_WDS
:
841 brcmf_err("type (%d) : currently we do not support this type\n",
844 case NL80211_IFTYPE_ADHOC
:
847 case NL80211_IFTYPE_STATION
:
850 case NL80211_IFTYPE_AP
:
851 case NL80211_IFTYPE_P2P_GO
:
860 if (type
== NL80211_IFTYPE_P2P_GO
) {
861 brcmf_dbg(INFO
, "IF Type = P2P GO\n");
862 err
= brcmf_p2p_ifchange(cfg
, BRCMF_FIL_P2P_IF_GO
);
865 brcmf_dbg(INFO
, "IF Type = AP\n");
868 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, infra
);
870 brcmf_err("WLC_SET_INFRA error (%d)\n", err
);
874 brcmf_dbg(INFO
, "IF Type = %s\n", brcmf_is_ibssmode(vif
) ?
877 ndev
->ieee80211_ptr
->iftype
= type
;
879 brcmf_cfg80211_update_proto_addr_mode(&vif
->wdev
);
882 brcmf_dbg(TRACE
, "Exit\n");
887 static void brcmf_escan_prep(struct brcmf_cfg80211_info
*cfg
,
888 struct brcmf_scan_params_le
*params_le
,
889 struct cfg80211_scan_request
*request
)
897 struct brcmf_ssid_le ssid_le
;
899 eth_broadcast_addr(params_le
->bssid
);
900 params_le
->bss_type
= DOT11_BSSTYPE_ANY
;
901 params_le
->scan_type
= 0;
902 params_le
->channel_num
= 0;
903 params_le
->nprobes
= cpu_to_le32(-1);
904 params_le
->active_time
= cpu_to_le32(-1);
905 params_le
->passive_time
= cpu_to_le32(-1);
906 params_le
->home_time
= cpu_to_le32(-1);
907 memset(¶ms_le
->ssid_le
, 0, sizeof(params_le
->ssid_le
));
909 /* if request is null exit so it will be all channel broadcast scan */
913 n_ssids
= request
->n_ssids
;
914 n_channels
= request
->n_channels
;
915 /* Copy channel array if applicable */
916 brcmf_dbg(SCAN
, "### List of channelspecs to scan ### %d\n",
918 if (n_channels
> 0) {
919 for (i
= 0; i
< n_channels
; i
++) {
920 chanspec
= channel_to_chanspec(&cfg
->d11inf
,
921 request
->channels
[i
]);
922 brcmf_dbg(SCAN
, "Chan : %d, Channel spec: %x\n",
923 request
->channels
[i
]->hw_value
, chanspec
);
924 params_le
->channel_list
[i
] = cpu_to_le16(chanspec
);
927 brcmf_dbg(SCAN
, "Scanning all channels\n");
929 /* Copy ssid array if applicable */
930 brcmf_dbg(SCAN
, "### List of SSIDs to scan ### %d\n", n_ssids
);
932 offset
= offsetof(struct brcmf_scan_params_le
, channel_list
) +
933 n_channels
* sizeof(u16
);
934 offset
= roundup(offset
, sizeof(u32
));
935 ptr
= (char *)params_le
+ offset
;
936 for (i
= 0; i
< n_ssids
; i
++) {
937 memset(&ssid_le
, 0, sizeof(ssid_le
));
939 cpu_to_le32(request
->ssids
[i
].ssid_len
);
940 memcpy(ssid_le
.SSID
, request
->ssids
[i
].ssid
,
941 request
->ssids
[i
].ssid_len
);
942 if (!ssid_le
.SSID_len
)
943 brcmf_dbg(SCAN
, "%d: Broadcast scan\n", i
);
945 brcmf_dbg(SCAN
, "%d: scan for %s size =%d\n",
946 i
, ssid_le
.SSID
, ssid_le
.SSID_len
);
947 memcpy(ptr
, &ssid_le
, sizeof(ssid_le
));
948 ptr
+= sizeof(ssid_le
);
951 brcmf_dbg(SCAN
, "Broadcast scan %p\n", request
->ssids
);
952 if ((request
->ssids
) && request
->ssids
->ssid_len
) {
953 brcmf_dbg(SCAN
, "SSID %s len=%d\n",
954 params_le
->ssid_le
.SSID
,
955 request
->ssids
->ssid_len
);
956 params_le
->ssid_le
.SSID_len
=
957 cpu_to_le32(request
->ssids
->ssid_len
);
958 memcpy(¶ms_le
->ssid_le
.SSID
, request
->ssids
->ssid
,
959 request
->ssids
->ssid_len
);
962 /* Adding mask to channel numbers */
963 params_le
->channel_num
=
964 cpu_to_le32((n_ssids
<< BRCMF_SCAN_PARAMS_NSSID_SHIFT
) |
965 (n_channels
& BRCMF_SCAN_PARAMS_COUNT_MASK
));
969 brcmf_run_escan(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
,
970 struct cfg80211_scan_request
*request
)
972 s32 params_size
= BRCMF_SCAN_PARAMS_FIXED_SIZE
+
973 offsetof(struct brcmf_escan_params_le
, params_le
);
974 struct brcmf_escan_params_le
*params
;
977 brcmf_dbg(SCAN
, "E-SCAN START\n");
979 if (request
!= NULL
) {
980 /* Allocate space for populating ssids in struct */
981 params_size
+= sizeof(u32
) * ((request
->n_channels
+ 1) / 2);
983 /* Allocate space for populating ssids in struct */
984 params_size
+= sizeof(struct brcmf_ssid_le
) * request
->n_ssids
;
987 params
= kzalloc(params_size
, GFP_KERNEL
);
992 BUG_ON(params_size
+ sizeof("escan") >= BRCMF_DCMD_MEDLEN
);
993 brcmf_escan_prep(cfg
, ¶ms
->params_le
, request
);
994 params
->version
= cpu_to_le32(BRCMF_ESCAN_REQ_VERSION
);
995 params
->action
= cpu_to_le16(WL_ESCAN_ACTION_START
);
996 params
->sync_id
= cpu_to_le16(0x1234);
998 err
= brcmf_fil_iovar_data_set(ifp
, "escan", params
, params_size
);
1001 brcmf_dbg(INFO
, "system busy : escan canceled\n");
1003 brcmf_err("error (%d)\n", err
);
1012 brcmf_do_escan(struct brcmf_cfg80211_info
*cfg
, struct wiphy
*wiphy
,
1013 struct brcmf_if
*ifp
, struct cfg80211_scan_request
*request
)
1017 struct brcmf_scan_results
*results
;
1018 struct escan_info
*escan
= &cfg
->escan_info
;
1020 brcmf_dbg(SCAN
, "Enter\n");
1022 escan
->wiphy
= wiphy
;
1023 escan
->escan_state
= WL_ESCAN_STATE_SCANNING
;
1024 passive_scan
= cfg
->active_scan
? 0 : 1;
1025 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
1028 brcmf_err("error (%d)\n", err
);
1031 brcmf_scan_config_mpc(ifp
, 0);
1032 results
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
1033 results
->version
= 0;
1035 results
->buflen
= WL_ESCAN_RESULTS_FIXED_SIZE
;
1037 err
= escan
->run(cfg
, ifp
, request
);
1039 brcmf_scan_config_mpc(ifp
, 1);
1044 brcmf_cfg80211_escan(struct wiphy
*wiphy
, struct brcmf_cfg80211_vif
*vif
,
1045 struct cfg80211_scan_request
*request
,
1046 struct cfg80211_ssid
*this_ssid
)
1048 struct brcmf_if
*ifp
= vif
->ifp
;
1049 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1050 struct cfg80211_ssid
*ssids
;
1055 struct brcmf_ssid_le ssid_le
;
1058 brcmf_dbg(SCAN
, "START ESCAN\n");
1060 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
1061 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
1064 if (test_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
)) {
1065 brcmf_err("Scanning being aborted: status (%lu)\n",
1069 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
1070 brcmf_err("Scanning suppressed: status (%lu)\n",
1074 if (test_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
)) {
1075 brcmf_err("Connecting: status (%lu)\n", ifp
->vif
->sme_state
);
1079 /* If scan req comes for p2p0, send it over primary I/F */
1080 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
1081 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
;
1086 ssids
= request
->ssids
;
1090 /* we don't do escan in ibss */
1094 cfg
->scan_request
= request
;
1095 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
1097 cfg
->escan_info
.run
= brcmf_run_escan
;
1098 err
= brcmf_p2p_scan_prep(wiphy
, request
, vif
);
1102 err
= brcmf_do_escan(cfg
, wiphy
, vif
->ifp
, request
);
1106 brcmf_dbg(SCAN
, "ssid \"%s\", ssid_len (%d)\n",
1107 ssids
->ssid
, ssids
->ssid_len
);
1108 memset(&ssid_le
, 0, sizeof(ssid_le
));
1109 SSID_len
= min_t(u8
, sizeof(ssid_le
.SSID
), ssids
->ssid_len
);
1110 ssid_le
.SSID_len
= cpu_to_le32(0);
1113 memcpy(ssid_le
.SSID
, ssids
->ssid
, SSID_len
);
1114 ssid_le
.SSID_len
= cpu_to_le32(SSID_len
);
1117 brcmf_dbg(SCAN
, "Broadcast scan\n");
1119 passive_scan
= cfg
->active_scan
? 0 : 1;
1120 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PASSIVE_SCAN
,
1123 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err
);
1126 brcmf_scan_config_mpc(ifp
, 0);
1127 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCAN
, &ssid_le
,
1131 brcmf_dbg(INFO
, "BUSY: scan for \"%s\" canceled\n",
1134 brcmf_err("WLC_SCAN error (%d)\n", err
);
1136 brcmf_scan_config_mpc(ifp
, 1);
1141 /* Arm scan timeout timer */
1142 mod_timer(&cfg
->escan_timeout
, jiffies
+
1143 WL_ESCAN_TIMER_INTERVAL_MS
* HZ
/ 1000);
1148 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
1149 cfg
->scan_request
= NULL
;
1154 brcmf_cfg80211_scan(struct wiphy
*wiphy
, struct cfg80211_scan_request
*request
)
1156 struct brcmf_cfg80211_vif
*vif
;
1159 brcmf_dbg(TRACE
, "Enter\n");
1160 vif
= container_of(request
->wdev
, struct brcmf_cfg80211_vif
, wdev
);
1161 if (!check_vif_up(vif
))
1164 err
= brcmf_cfg80211_escan(wiphy
, vif
, request
, NULL
);
1167 brcmf_err("scan error (%d)\n", err
);
1169 brcmf_dbg(TRACE
, "Exit\n");
1173 static s32
brcmf_set_rts(struct net_device
*ndev
, u32 rts_threshold
)
1177 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "rtsthresh",
1180 brcmf_err("Error (%d)\n", err
);
1185 static s32
brcmf_set_frag(struct net_device
*ndev
, u32 frag_threshold
)
1189 err
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "fragthresh",
1192 brcmf_err("Error (%d)\n", err
);
1197 static s32
brcmf_set_retry(struct net_device
*ndev
, u32 retry
, bool l
)
1200 u32 cmd
= (l
? BRCMF_C_SET_LRL
: BRCMF_C_SET_SRL
);
1202 err
= brcmf_fil_cmd_int_set(netdev_priv(ndev
), cmd
, retry
);
1204 brcmf_err("cmd (%d) , error (%d)\n", cmd
, err
);
1210 static s32
brcmf_cfg80211_set_wiphy_params(struct wiphy
*wiphy
, u32 changed
)
1212 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1213 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1214 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1217 brcmf_dbg(TRACE
, "Enter\n");
1218 if (!check_vif_up(ifp
->vif
))
1221 if (changed
& WIPHY_PARAM_RTS_THRESHOLD
&&
1222 (cfg
->conf
->rts_threshold
!= wiphy
->rts_threshold
)) {
1223 cfg
->conf
->rts_threshold
= wiphy
->rts_threshold
;
1224 err
= brcmf_set_rts(ndev
, cfg
->conf
->rts_threshold
);
1228 if (changed
& WIPHY_PARAM_FRAG_THRESHOLD
&&
1229 (cfg
->conf
->frag_threshold
!= wiphy
->frag_threshold
)) {
1230 cfg
->conf
->frag_threshold
= wiphy
->frag_threshold
;
1231 err
= brcmf_set_frag(ndev
, cfg
->conf
->frag_threshold
);
1235 if (changed
& WIPHY_PARAM_RETRY_LONG
1236 && (cfg
->conf
->retry_long
!= wiphy
->retry_long
)) {
1237 cfg
->conf
->retry_long
= wiphy
->retry_long
;
1238 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_long
, true);
1242 if (changed
& WIPHY_PARAM_RETRY_SHORT
1243 && (cfg
->conf
->retry_short
!= wiphy
->retry_short
)) {
1244 cfg
->conf
->retry_short
= wiphy
->retry_short
;
1245 err
= brcmf_set_retry(ndev
, cfg
->conf
->retry_short
, false);
1251 brcmf_dbg(TRACE
, "Exit\n");
1255 static void brcmf_init_prof(struct brcmf_cfg80211_profile
*prof
)
1257 memset(prof
, 0, sizeof(*prof
));
1260 static u16
brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg
*e
)
1264 switch (e
->event_code
) {
1265 case BRCMF_E_DEAUTH
:
1266 case BRCMF_E_DEAUTH_IND
:
1267 case BRCMF_E_DISASSOC_IND
:
1278 static void brcmf_link_down(struct brcmf_cfg80211_vif
*vif
, u16 reason
)
1280 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(vif
->wdev
.wiphy
);
1283 brcmf_dbg(TRACE
, "Enter\n");
1285 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &vif
->sme_state
)) {
1286 brcmf_dbg(INFO
, "Call WLC_DISASSOC to stop excess roaming\n ");
1287 err
= brcmf_fil_cmd_data_set(vif
->ifp
,
1288 BRCMF_C_DISASSOC
, NULL
, 0);
1290 brcmf_err("WLC_DISASSOC failed (%d)\n", err
);
1292 if ((vif
->wdev
.iftype
== NL80211_IFTYPE_STATION
) ||
1293 (vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
))
1294 cfg80211_disconnected(vif
->wdev
.netdev
, reason
, NULL
, 0,
1297 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &vif
->sme_state
);
1298 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
1299 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
1300 brcmf_dbg(TRACE
, "Exit\n");
1304 brcmf_cfg80211_join_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
,
1305 struct cfg80211_ibss_params
*params
)
1307 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1308 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1309 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1310 struct brcmf_join_params join_params
;
1311 size_t join_params_size
= 0;
1318 brcmf_dbg(TRACE
, "Enter\n");
1319 if (!check_vif_up(ifp
->vif
))
1323 brcmf_dbg(CONN
, "SSID: %s\n", params
->ssid
);
1325 brcmf_dbg(CONN
, "SSID: NULL, Not supported\n");
1329 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1332 brcmf_dbg(CONN
, "BSSID: %pM\n", params
->bssid
);
1334 brcmf_dbg(CONN
, "No BSSID specified\n");
1336 if (params
->chandef
.chan
)
1337 brcmf_dbg(CONN
, "channel: %d\n",
1338 params
->chandef
.chan
->center_freq
);
1340 brcmf_dbg(CONN
, "no channel specified\n");
1342 if (params
->channel_fixed
)
1343 brcmf_dbg(CONN
, "fixed channel required\n");
1345 brcmf_dbg(CONN
, "no fixed channel required\n");
1347 if (params
->ie
&& params
->ie_len
)
1348 brcmf_dbg(CONN
, "ie len: %d\n", params
->ie_len
);
1350 brcmf_dbg(CONN
, "no ie specified\n");
1352 if (params
->beacon_interval
)
1353 brcmf_dbg(CONN
, "beacon interval: %d\n",
1354 params
->beacon_interval
);
1356 brcmf_dbg(CONN
, "no beacon interval specified\n");
1358 if (params
->basic_rates
)
1359 brcmf_dbg(CONN
, "basic rates: %08X\n", params
->basic_rates
);
1361 brcmf_dbg(CONN
, "no basic rates specified\n");
1363 if (params
->privacy
)
1364 brcmf_dbg(CONN
, "privacy required\n");
1366 brcmf_dbg(CONN
, "no privacy required\n");
1368 /* Configure Privacy for starter */
1369 if (params
->privacy
)
1370 wsec
|= WEP_ENABLED
;
1372 err
= brcmf_fil_iovar_int_set(ifp
, "wsec", wsec
);
1374 brcmf_err("wsec failed (%d)\n", err
);
1378 /* Configure Beacon Interval for starter */
1379 if (params
->beacon_interval
)
1380 bcnprd
= params
->beacon_interval
;
1384 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
, bcnprd
);
1386 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err
);
1390 /* Configure required join parameter */
1391 memset(&join_params
, 0, sizeof(struct brcmf_join_params
));
1394 ssid_len
= min_t(u32
, params
->ssid_len
, IEEE80211_MAX_SSID_LEN
);
1395 memcpy(join_params
.ssid_le
.SSID
, params
->ssid
, ssid_len
);
1396 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
1397 join_params_size
= sizeof(join_params
.ssid_le
);
1400 if (params
->bssid
) {
1401 memcpy(join_params
.params_le
.bssid
, params
->bssid
, ETH_ALEN
);
1402 join_params_size
+= BRCMF_ASSOC_PARAMS_FIXED_SIZE
;
1403 memcpy(profile
->bssid
, params
->bssid
, ETH_ALEN
);
1405 eth_broadcast_addr(join_params
.params_le
.bssid
);
1406 eth_zero_addr(profile
->bssid
);
1410 if (params
->chandef
.chan
) {
1414 ieee80211_frequency_to_channel(
1415 params
->chandef
.chan
->center_freq
);
1416 if (params
->channel_fixed
) {
1417 /* adding chanspec */
1418 chanspec
= chandef_to_chanspec(&cfg
->d11inf
,
1420 join_params
.params_le
.chanspec_list
[0] =
1421 cpu_to_le16(chanspec
);
1422 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1423 join_params_size
+= sizeof(join_params
.params_le
);
1426 /* set channel for starter */
1427 target_channel
= cfg
->channel
;
1428 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_CHANNEL
,
1431 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err
);
1437 cfg
->ibss_starter
= false;
1440 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1441 &join_params
, join_params_size
);
1443 brcmf_err("WLC_SET_SSID failed (%d)\n", err
);
1449 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1450 brcmf_dbg(TRACE
, "Exit\n");
1455 brcmf_cfg80211_leave_ibss(struct wiphy
*wiphy
, struct net_device
*ndev
)
1457 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1459 brcmf_dbg(TRACE
, "Enter\n");
1460 if (!check_vif_up(ifp
->vif
)) {
1461 /* When driver is being unloaded, it can end up here. If an
1462 * error is returned then later on a debug trace in the wireless
1463 * core module will be printed. To avoid this 0 is returned.
1468 brcmf_link_down(ifp
->vif
, WLAN_REASON_DEAUTH_LEAVING
);
1470 brcmf_dbg(TRACE
, "Exit\n");
1475 static s32
brcmf_set_wpa_version(struct net_device
*ndev
,
1476 struct cfg80211_connect_params
*sme
)
1478 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1479 struct brcmf_cfg80211_security
*sec
;
1483 if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_1
)
1484 val
= WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
;
1485 else if (sme
->crypto
.wpa_versions
& NL80211_WPA_VERSION_2
)
1486 val
= WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
;
1488 val
= WPA_AUTH_DISABLED
;
1489 brcmf_dbg(CONN
, "setting wpa_auth to 0x%0x\n", val
);
1490 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wpa_auth", val
);
1492 brcmf_err("set wpa_auth failed (%d)\n", err
);
1495 sec
= &profile
->sec
;
1496 sec
->wpa_versions
= sme
->crypto
.wpa_versions
;
1500 static s32
brcmf_set_auth_type(struct net_device
*ndev
,
1501 struct cfg80211_connect_params
*sme
)
1503 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1504 struct brcmf_cfg80211_security
*sec
;
1508 switch (sme
->auth_type
) {
1509 case NL80211_AUTHTYPE_OPEN_SYSTEM
:
1511 brcmf_dbg(CONN
, "open system\n");
1513 case NL80211_AUTHTYPE_SHARED_KEY
:
1515 brcmf_dbg(CONN
, "shared key\n");
1517 case NL80211_AUTHTYPE_AUTOMATIC
:
1519 brcmf_dbg(CONN
, "automatic\n");
1521 case NL80211_AUTHTYPE_NETWORK_EAP
:
1522 brcmf_dbg(CONN
, "network eap\n");
1525 brcmf_err("invalid auth type (%d)\n", sme
->auth_type
);
1529 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1531 brcmf_err("set auth failed (%d)\n", err
);
1534 sec
= &profile
->sec
;
1535 sec
->auth_type
= sme
->auth_type
;
1540 brcmf_set_wsec_mode(struct net_device
*ndev
,
1541 struct cfg80211_connect_params
*sme
, bool mfp
)
1543 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1544 struct brcmf_cfg80211_security
*sec
;
1550 if (sme
->crypto
.n_ciphers_pairwise
) {
1551 switch (sme
->crypto
.ciphers_pairwise
[0]) {
1552 case WLAN_CIPHER_SUITE_WEP40
:
1553 case WLAN_CIPHER_SUITE_WEP104
:
1556 case WLAN_CIPHER_SUITE_TKIP
:
1557 pval
= TKIP_ENABLED
;
1559 case WLAN_CIPHER_SUITE_CCMP
:
1562 case WLAN_CIPHER_SUITE_AES_CMAC
:
1566 brcmf_err("invalid cipher pairwise (%d)\n",
1567 sme
->crypto
.ciphers_pairwise
[0]);
1571 if (sme
->crypto
.cipher_group
) {
1572 switch (sme
->crypto
.cipher_group
) {
1573 case WLAN_CIPHER_SUITE_WEP40
:
1574 case WLAN_CIPHER_SUITE_WEP104
:
1577 case WLAN_CIPHER_SUITE_TKIP
:
1578 gval
= TKIP_ENABLED
;
1580 case WLAN_CIPHER_SUITE_CCMP
:
1583 case WLAN_CIPHER_SUITE_AES_CMAC
:
1587 brcmf_err("invalid cipher group (%d)\n",
1588 sme
->crypto
.cipher_group
);
1593 brcmf_dbg(CONN
, "pval (%d) gval (%d)\n", pval
, gval
);
1594 /* In case of privacy, but no security and WPS then simulate */
1595 /* setting AES. WPS-2.0 allows no security */
1596 if (brcmf_find_wpsie(sme
->ie
, sme
->ie_len
) && !pval
&& !gval
&&
1601 wsec
= pval
| gval
| MFP_CAPABLE
;
1604 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "wsec", wsec
);
1606 brcmf_err("error (%d)\n", err
);
1610 sec
= &profile
->sec
;
1611 sec
->cipher_pairwise
= sme
->crypto
.ciphers_pairwise
[0];
1612 sec
->cipher_group
= sme
->crypto
.cipher_group
;
1618 brcmf_set_key_mgmt(struct net_device
*ndev
, struct cfg80211_connect_params
*sme
)
1620 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1621 struct brcmf_cfg80211_security
*sec
;
1625 if (sme
->crypto
.n_akm_suites
) {
1626 err
= brcmf_fil_bsscfg_int_get(netdev_priv(ndev
),
1629 brcmf_err("could not get wpa_auth (%d)\n", err
);
1632 if (val
& (WPA_AUTH_PSK
| WPA_AUTH_UNSPECIFIED
)) {
1633 switch (sme
->crypto
.akm_suites
[0]) {
1634 case WLAN_AKM_SUITE_8021X
:
1635 val
= WPA_AUTH_UNSPECIFIED
;
1637 case WLAN_AKM_SUITE_PSK
:
1641 brcmf_err("invalid cipher group (%d)\n",
1642 sme
->crypto
.cipher_group
);
1645 } else if (val
& (WPA2_AUTH_PSK
| WPA2_AUTH_UNSPECIFIED
)) {
1646 switch (sme
->crypto
.akm_suites
[0]) {
1647 case WLAN_AKM_SUITE_8021X
:
1648 val
= WPA2_AUTH_UNSPECIFIED
;
1650 case WLAN_AKM_SUITE_PSK
:
1651 val
= WPA2_AUTH_PSK
;
1654 brcmf_err("invalid cipher group (%d)\n",
1655 sme
->crypto
.cipher_group
);
1660 brcmf_dbg(CONN
, "setting wpa_auth to %d\n", val
);
1661 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
),
1664 brcmf_err("could not set wpa_auth (%d)\n", err
);
1668 sec
= &profile
->sec
;
1669 sec
->wpa_auth
= sme
->crypto
.akm_suites
[0];
1675 brcmf_set_sharedkey(struct net_device
*ndev
,
1676 struct cfg80211_connect_params
*sme
)
1678 struct brcmf_cfg80211_profile
*profile
= ndev_to_prof(ndev
);
1679 struct brcmf_cfg80211_security
*sec
;
1680 struct brcmf_wsec_key key
;
1684 brcmf_dbg(CONN
, "key len (%d)\n", sme
->key_len
);
1686 if (sme
->key_len
== 0)
1689 sec
= &profile
->sec
;
1690 brcmf_dbg(CONN
, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1691 sec
->wpa_versions
, sec
->cipher_pairwise
);
1693 if (sec
->wpa_versions
& (NL80211_WPA_VERSION_1
| NL80211_WPA_VERSION_2
))
1696 if (!(sec
->cipher_pairwise
&
1697 (WLAN_CIPHER_SUITE_WEP40
| WLAN_CIPHER_SUITE_WEP104
)))
1700 memset(&key
, 0, sizeof(key
));
1701 key
.len
= (u32
) sme
->key_len
;
1702 key
.index
= (u32
) sme
->key_idx
;
1703 if (key
.len
> sizeof(key
.data
)) {
1704 brcmf_err("Too long key length (%u)\n", key
.len
);
1707 memcpy(key
.data
, sme
->key
, key
.len
);
1708 key
.flags
= BRCMF_PRIMARY_KEY
;
1709 switch (sec
->cipher_pairwise
) {
1710 case WLAN_CIPHER_SUITE_WEP40
:
1711 key
.algo
= CRYPTO_ALGO_WEP1
;
1713 case WLAN_CIPHER_SUITE_WEP104
:
1714 key
.algo
= CRYPTO_ALGO_WEP128
;
1717 brcmf_err("Invalid algorithm (%d)\n",
1718 sme
->crypto
.ciphers_pairwise
[0]);
1721 /* Set the new key/index */
1722 brcmf_dbg(CONN
, "key length (%d) key index (%d) algo (%d)\n",
1723 key
.len
, key
.index
, key
.algo
);
1724 brcmf_dbg(CONN
, "key \"%s\"\n", key
.data
);
1725 err
= send_key_to_dongle(netdev_priv(ndev
), &key
);
1729 if (sec
->auth_type
== NL80211_AUTHTYPE_SHARED_KEY
) {
1730 brcmf_dbg(CONN
, "set auth_type to shared key\n");
1731 val
= WL_AUTH_SHARED_KEY
; /* shared key */
1732 err
= brcmf_fil_bsscfg_int_set(netdev_priv(ndev
), "auth", val
);
1734 brcmf_err("set auth failed (%d)\n", err
);
1740 enum nl80211_auth_type
brcmf_war_auth_type(struct brcmf_if
*ifp
,
1741 enum nl80211_auth_type type
)
1743 if (type
== NL80211_AUTHTYPE_AUTOMATIC
&&
1744 brcmf_feat_is_quirk_enabled(ifp
, BRCMF_FEAT_QUIRK_AUTO_AUTH
)) {
1745 brcmf_dbg(CONN
, "WAR: use OPEN instead of AUTO\n");
1746 type
= NL80211_AUTHTYPE_OPEN_SYSTEM
;
1752 brcmf_cfg80211_connect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1753 struct cfg80211_connect_params
*sme
)
1755 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1756 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1757 struct ieee80211_channel
*chan
= sme
->channel
;
1758 struct brcmf_join_params join_params
;
1759 size_t join_params_size
;
1760 const struct brcmf_tlv
*rsn_ie
;
1761 const struct brcmf_vs_tlv
*wpa_ie
;
1764 struct brcmf_ext_join_params_le
*ext_join_params
;
1769 brcmf_dbg(TRACE
, "Enter\n");
1770 if (!check_vif_up(ifp
->vif
))
1774 brcmf_err("Invalid ssid\n");
1778 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
) {
1779 /* A normal (non P2P) connection request setup. */
1782 /* find the WPA_IE */
1783 wpa_ie
= brcmf_find_wpaie((u8
*)sme
->ie
, sme
->ie_len
);
1786 ie_len
= wpa_ie
->len
+ TLV_HDR_LEN
;
1788 /* find the RSN_IE */
1789 rsn_ie
= brcmf_parse_tlvs((const u8
*)sme
->ie
,
1794 ie_len
= rsn_ie
->len
+ TLV_HDR_LEN
;
1797 brcmf_fil_iovar_data_set(ifp
, "wpaie", ie
, ie_len
);
1800 err
= brcmf_vif_set_mgmt_ie(ifp
->vif
, BRCMF_VNDR_IE_ASSOCREQ_FLAG
,
1801 sme
->ie
, sme
->ie_len
);
1803 brcmf_err("Set Assoc REQ IE Failed\n");
1805 brcmf_dbg(TRACE
, "Applied Vndr IEs for Assoc request\n");
1807 set_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1811 ieee80211_frequency_to_channel(chan
->center_freq
);
1812 chanspec
= channel_to_chanspec(&cfg
->d11inf
, chan
);
1813 brcmf_dbg(CONN
, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1814 cfg
->channel
, chan
->center_freq
, chanspec
);
1820 brcmf_dbg(INFO
, "ie (%p), ie_len (%zd)\n", sme
->ie
, sme
->ie_len
);
1822 err
= brcmf_set_wpa_version(ndev
, sme
);
1824 brcmf_err("wl_set_wpa_version failed (%d)\n", err
);
1828 sme
->auth_type
= brcmf_war_auth_type(ifp
, sme
->auth_type
);
1829 err
= brcmf_set_auth_type(ndev
, sme
);
1831 brcmf_err("wl_set_auth_type failed (%d)\n", err
);
1835 err
= brcmf_set_wsec_mode(ndev
, sme
, sme
->mfp
== NL80211_MFP_REQUIRED
);
1837 brcmf_err("wl_set_set_cipher failed (%d)\n", err
);
1841 err
= brcmf_set_key_mgmt(ndev
, sme
);
1843 brcmf_err("wl_set_key_mgmt failed (%d)\n", err
);
1847 err
= brcmf_set_sharedkey(ndev
, sme
);
1849 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err
);
1853 /* Join with specific BSSID and cached SSID
1854 * If SSID is zero join based on BSSID only
1856 join_params_size
= offsetof(struct brcmf_ext_join_params_le
, assoc_le
) +
1857 offsetof(struct brcmf_assoc_params_le
, chanspec_list
);
1859 join_params_size
+= sizeof(u16
);
1860 ext_join_params
= kzalloc(join_params_size
, GFP_KERNEL
);
1861 if (ext_join_params
== NULL
) {
1865 ssid_len
= min_t(u32
, sme
->ssid_len
, IEEE80211_MAX_SSID_LEN
);
1866 ext_join_params
->ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
1867 memcpy(&ext_join_params
->ssid_le
.SSID
, sme
->ssid
, ssid_len
);
1868 if (ssid_len
< IEEE80211_MAX_SSID_LEN
)
1869 brcmf_dbg(CONN
, "SSID \"%s\", len (%d)\n",
1870 ext_join_params
->ssid_le
.SSID
, ssid_len
);
1872 /* Set up join scan parameters */
1873 ext_join_params
->scan_le
.scan_type
= -1;
1874 ext_join_params
->scan_le
.home_time
= cpu_to_le32(-1);
1877 memcpy(&ext_join_params
->assoc_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1879 eth_broadcast_addr(ext_join_params
->assoc_le
.bssid
);
1882 ext_join_params
->assoc_le
.chanspec_num
= cpu_to_le32(1);
1884 ext_join_params
->assoc_le
.chanspec_list
[0] =
1885 cpu_to_le16(chanspec
);
1886 /* Increase dwell time to receive probe response or detect
1887 * beacon from target AP at a noisy air only during connect
1890 ext_join_params
->scan_le
.active_time
=
1891 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
);
1892 ext_join_params
->scan_le
.passive_time
=
1893 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS
);
1894 /* To sync with presence period of VSDB GO send probe request
1895 * more frequently. Probe request will be stopped when it gets
1896 * probe response from target AP/GO.
1898 ext_join_params
->scan_le
.nprobes
=
1899 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS
/
1900 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS
);
1902 ext_join_params
->scan_le
.active_time
= cpu_to_le32(-1);
1903 ext_join_params
->scan_le
.passive_time
= cpu_to_le32(-1);
1904 ext_join_params
->scan_le
.nprobes
= cpu_to_le32(-1);
1907 err
= brcmf_fil_bsscfg_data_set(ifp
, "join", ext_join_params
,
1909 kfree(ext_join_params
);
1911 /* This is it. join command worked, we are done */
1914 /* join command failed, fallback to set ssid */
1915 memset(&join_params
, 0, sizeof(join_params
));
1916 join_params_size
= sizeof(join_params
.ssid_le
);
1918 memcpy(&join_params
.ssid_le
.SSID
, sme
->ssid
, ssid_len
);
1919 join_params
.ssid_le
.SSID_len
= cpu_to_le32(ssid_len
);
1922 memcpy(join_params
.params_le
.bssid
, sme
->bssid
, ETH_ALEN
);
1924 eth_broadcast_addr(join_params
.params_le
.bssid
);
1927 join_params
.params_le
.chanspec_list
[0] = cpu_to_le16(chanspec
);
1928 join_params
.params_le
.chanspec_num
= cpu_to_le32(1);
1929 join_params_size
+= sizeof(join_params
.params_le
);
1931 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
1932 &join_params
, join_params_size
);
1934 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err
);
1938 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1939 brcmf_dbg(TRACE
, "Exit\n");
1944 brcmf_cfg80211_disconnect(struct wiphy
*wiphy
, struct net_device
*ndev
,
1947 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1948 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
1949 struct brcmf_scb_val_le scbval
;
1952 brcmf_dbg(TRACE
, "Enter. Reason code = %d\n", reason_code
);
1953 if (!check_vif_up(ifp
->vif
))
1956 clear_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
1957 clear_bit(BRCMF_VIF_STATUS_CONNECTING
, &ifp
->vif
->sme_state
);
1958 cfg80211_disconnected(ndev
, reason_code
, NULL
, 0, true, GFP_KERNEL
);
1960 memcpy(&scbval
.ea
, &profile
->bssid
, ETH_ALEN
);
1961 scbval
.val
= cpu_to_le32(reason_code
);
1962 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_DISASSOC
,
1963 &scbval
, sizeof(scbval
));
1965 brcmf_err("error (%d)\n", err
);
1967 brcmf_dbg(TRACE
, "Exit\n");
1972 brcmf_cfg80211_set_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
1973 enum nl80211_tx_power_setting type
, s32 mbm
)
1975 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
1976 struct net_device
*ndev
= cfg_to_ndev(cfg
);
1977 struct brcmf_if
*ifp
= netdev_priv(ndev
);
1982 brcmf_dbg(TRACE
, "Enter %d %d\n", type
, mbm
);
1983 if (!check_vif_up(ifp
->vif
))
1987 case NL80211_TX_POWER_AUTOMATIC
:
1989 case NL80211_TX_POWER_LIMITED
:
1990 case NL80211_TX_POWER_FIXED
:
1992 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1996 qdbm
= MBM_TO_DBM(4 * mbm
);
1999 qdbm
|= WL_TXPWR_OVERRIDE
;
2002 brcmf_err("Unsupported type %d\n", type
);
2006 /* Make sure radio is off or on as far as software is concerned */
2007 disable
= WL_RADIO_SW_DISABLE
<< 16;
2008 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_RADIO
, disable
);
2010 brcmf_err("WLC_SET_RADIO error (%d)\n", err
);
2012 err
= brcmf_fil_iovar_int_set(ifp
, "qtxpower", qdbm
);
2014 brcmf_err("qtxpower error (%d)\n", err
);
2017 brcmf_dbg(TRACE
, "Exit %d (qdbm)\n", qdbm
& ~WL_TXPWR_OVERRIDE
);
2022 brcmf_cfg80211_get_tx_power(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
2025 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2026 struct net_device
*ndev
= cfg_to_ndev(cfg
);
2027 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2031 brcmf_dbg(TRACE
, "Enter\n");
2032 if (!check_vif_up(ifp
->vif
))
2035 err
= brcmf_fil_iovar_int_get(ifp
, "qtxpower", &qdbm
);
2037 brcmf_err("error (%d)\n", err
);
2040 *dbm
= (qdbm
& ~WL_TXPWR_OVERRIDE
) / 4;
2043 brcmf_dbg(TRACE
, "Exit (0x%x %d)\n", qdbm
, *dbm
);
2048 brcmf_cfg80211_config_default_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2049 u8 key_idx
, bool unicast
, bool multicast
)
2051 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2056 brcmf_dbg(TRACE
, "Enter\n");
2057 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2058 if (!check_vif_up(ifp
->vif
))
2061 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2063 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2067 if (wsec
& WEP_ENABLED
) {
2068 /* Just select a new current key */
2070 err
= brcmf_fil_cmd_int_set(ifp
,
2071 BRCMF_C_SET_KEY_PRIMARY
, index
);
2073 brcmf_err("error (%d)\n", err
);
2076 brcmf_dbg(TRACE
, "Exit\n");
2081 brcmf_add_keyext(struct wiphy
*wiphy
, struct net_device
*ndev
,
2082 u8 key_idx
, const u8
*mac_addr
, struct key_params
*params
)
2084 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2085 struct brcmf_wsec_key key
;
2089 memset(&key
, 0, sizeof(key
));
2090 key
.index
= (u32
) key_idx
;
2091 /* Instead of bcast for ea address for default wep keys,
2092 driver needs it to be Null */
2093 if (!is_multicast_ether_addr(mac_addr
))
2094 memcpy((char *)&key
.ea
, (void *)mac_addr
, ETH_ALEN
);
2095 key
.len
= (u32
) params
->key_len
;
2096 /* check for key index change */
2099 err
= send_key_to_dongle(ifp
, &key
);
2101 brcmf_err("key delete error (%d)\n", err
);
2103 if (key
.len
> sizeof(key
.data
)) {
2104 brcmf_err("Invalid key length (%d)\n", key
.len
);
2108 brcmf_dbg(CONN
, "Setting the key index %d\n", key
.index
);
2109 memcpy(key
.data
, params
->key
, key
.len
);
2111 if (!brcmf_is_apmode(ifp
->vif
) &&
2112 (params
->cipher
== WLAN_CIPHER_SUITE_TKIP
)) {
2113 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2114 memcpy(keybuf
, &key
.data
[24], sizeof(keybuf
));
2115 memcpy(&key
.data
[24], &key
.data
[16], sizeof(keybuf
));
2116 memcpy(&key
.data
[16], keybuf
, sizeof(keybuf
));
2119 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2120 if (params
->seq
&& params
->seq_len
== 6) {
2123 ivptr
= (u8
*) params
->seq
;
2124 key
.rxiv
.hi
= (ivptr
[5] << 24) | (ivptr
[4] << 16) |
2125 (ivptr
[3] << 8) | ivptr
[2];
2126 key
.rxiv
.lo
= (ivptr
[1] << 8) | ivptr
[0];
2127 key
.iv_initialized
= true;
2130 switch (params
->cipher
) {
2131 case WLAN_CIPHER_SUITE_WEP40
:
2132 key
.algo
= CRYPTO_ALGO_WEP1
;
2133 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2135 case WLAN_CIPHER_SUITE_WEP104
:
2136 key
.algo
= CRYPTO_ALGO_WEP128
;
2137 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2139 case WLAN_CIPHER_SUITE_TKIP
:
2140 key
.algo
= CRYPTO_ALGO_TKIP
;
2141 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2143 case WLAN_CIPHER_SUITE_AES_CMAC
:
2144 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2145 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2147 case WLAN_CIPHER_SUITE_CCMP
:
2148 key
.algo
= CRYPTO_ALGO_AES_CCM
;
2149 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2152 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2155 err
= send_key_to_dongle(ifp
, &key
);
2157 brcmf_err("wsec_key error (%d)\n", err
);
2163 brcmf_cfg80211_add_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2164 u8 key_idx
, bool pairwise
, const u8
*mac_addr
,
2165 struct key_params
*params
)
2167 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2168 struct brcmf_wsec_key
*key
;
2174 brcmf_dbg(TRACE
, "Enter\n");
2175 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2176 if (!check_vif_up(ifp
->vif
))
2179 if (key_idx
>= BRCMF_MAX_DEFAULT_KEYS
) {
2180 /* we ignore this key index in this case */
2181 brcmf_err("invalid key index (%d)\n", key_idx
);
2186 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP40
) &&
2187 (params
->cipher
!= WLAN_CIPHER_SUITE_WEP104
)) {
2188 brcmf_dbg(TRACE
, "Exit");
2189 return brcmf_add_keyext(wiphy
, ndev
, key_idx
, mac_addr
, params
);
2192 key
= &ifp
->vif
->profile
.key
[key_idx
];
2193 memset(key
, 0, sizeof(*key
));
2195 if (params
->key_len
> sizeof(key
->data
)) {
2196 brcmf_err("Too long key length (%u)\n", params
->key_len
);
2200 key
->len
= params
->key_len
;
2201 key
->index
= key_idx
;
2203 memcpy(key
->data
, params
->key
, key
->len
);
2205 key
->flags
= BRCMF_PRIMARY_KEY
;
2206 switch (params
->cipher
) {
2207 case WLAN_CIPHER_SUITE_WEP40
:
2208 key
->algo
= CRYPTO_ALGO_WEP1
;
2210 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2212 case WLAN_CIPHER_SUITE_WEP104
:
2213 key
->algo
= CRYPTO_ALGO_WEP128
;
2215 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2217 case WLAN_CIPHER_SUITE_TKIP
:
2218 if (!brcmf_is_apmode(ifp
->vif
)) {
2219 brcmf_dbg(CONN
, "Swapping RX/TX MIC key\n");
2220 memcpy(keybuf
, &key
->data
[24], sizeof(keybuf
));
2221 memcpy(&key
->data
[24], &key
->data
[16], sizeof(keybuf
));
2222 memcpy(&key
->data
[16], keybuf
, sizeof(keybuf
));
2224 key
->algo
= CRYPTO_ALGO_TKIP
;
2226 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2228 case WLAN_CIPHER_SUITE_AES_CMAC
:
2229 key
->algo
= CRYPTO_ALGO_AES_CCM
;
2231 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2233 case WLAN_CIPHER_SUITE_CCMP
:
2234 key
->algo
= CRYPTO_ALGO_AES_CCM
;
2236 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_CCMP\n");
2239 brcmf_err("Invalid cipher (0x%x)\n", params
->cipher
);
2244 err
= send_key_to_dongle(ifp
, key
);
2248 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2250 brcmf_err("get wsec error (%d)\n", err
);
2254 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2256 brcmf_err("set wsec error (%d)\n", err
);
2261 brcmf_dbg(TRACE
, "Exit\n");
2266 brcmf_cfg80211_del_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2267 u8 key_idx
, bool pairwise
, const u8
*mac_addr
)
2269 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2270 struct brcmf_wsec_key key
;
2273 brcmf_dbg(TRACE
, "Enter\n");
2274 if (!check_vif_up(ifp
->vif
))
2277 if (key_idx
>= BRCMF_MAX_DEFAULT_KEYS
) {
2278 /* we ignore this key index in this case */
2282 memset(&key
, 0, sizeof(key
));
2284 key
.index
= (u32
) key_idx
;
2285 key
.flags
= BRCMF_PRIMARY_KEY
;
2286 key
.algo
= CRYPTO_ALGO_OFF
;
2288 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2290 /* Set the new key/index */
2291 err
= send_key_to_dongle(ifp
, &key
);
2293 brcmf_dbg(TRACE
, "Exit\n");
2298 brcmf_cfg80211_get_key(struct wiphy
*wiphy
, struct net_device
*ndev
,
2299 u8 key_idx
, bool pairwise
, const u8
*mac_addr
, void *cookie
,
2300 void (*callback
) (void *cookie
, struct key_params
* params
))
2302 struct key_params params
;
2303 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2304 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
2305 struct brcmf_cfg80211_security
*sec
;
2309 brcmf_dbg(TRACE
, "Enter\n");
2310 brcmf_dbg(CONN
, "key index (%d)\n", key_idx
);
2311 if (!check_vif_up(ifp
->vif
))
2314 memset(¶ms
, 0, sizeof(params
));
2316 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2318 brcmf_err("WLC_GET_WSEC error (%d)\n", err
);
2319 /* Ignore this error, may happen during DISASSOC */
2323 if (wsec
& WEP_ENABLED
) {
2324 sec
= &profile
->sec
;
2325 if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP40
) {
2326 params
.cipher
= WLAN_CIPHER_SUITE_WEP40
;
2327 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP40\n");
2328 } else if (sec
->cipher_pairwise
& WLAN_CIPHER_SUITE_WEP104
) {
2329 params
.cipher
= WLAN_CIPHER_SUITE_WEP104
;
2330 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_WEP104\n");
2332 } else if (wsec
& TKIP_ENABLED
) {
2333 params
.cipher
= WLAN_CIPHER_SUITE_TKIP
;
2334 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_TKIP\n");
2335 } else if (wsec
& AES_ENABLED
) {
2336 params
.cipher
= WLAN_CIPHER_SUITE_AES_CMAC
;
2337 brcmf_dbg(CONN
, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2339 brcmf_err("Invalid algo (0x%x)\n", wsec
);
2343 callback(cookie
, ¶ms
);
2346 brcmf_dbg(TRACE
, "Exit\n");
2351 brcmf_cfg80211_config_default_mgmt_key(struct wiphy
*wiphy
,
2352 struct net_device
*ndev
, u8 key_idx
)
2354 brcmf_dbg(INFO
, "Not supported\n");
2360 brcmf_cfg80211_reconfigure_wep(struct brcmf_if
*ifp
)
2364 struct brcmf_wsec_key
*key
;
2367 for (key_idx
= 0; key_idx
< BRCMF_MAX_DEFAULT_KEYS
; key_idx
++) {
2368 key
= &ifp
->vif
->profile
.key
[key_idx
];
2369 if ((key
->algo
== CRYPTO_ALGO_WEP1
) ||
2370 (key
->algo
== CRYPTO_ALGO_WEP128
))
2373 if (key_idx
== BRCMF_MAX_DEFAULT_KEYS
)
2376 err
= send_key_to_dongle(ifp
, key
);
2378 brcmf_err("Setting WEP key failed (%d)\n", err
);
2381 err
= brcmf_fil_bsscfg_int_get(ifp
, "wsec", &wsec
);
2383 brcmf_err("get wsec error (%d)\n", err
);
2386 wsec
|= WEP_ENABLED
;
2387 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
2389 brcmf_err("set wsec error (%d)\n", err
);
2392 static void brcmf_convert_sta_flags(u32 fw_sta_flags
, struct station_info
*si
)
2394 struct nl80211_sta_flag_update
*sfu
;
2396 brcmf_dbg(TRACE
, "flags %08x\n", fw_sta_flags
);
2397 si
->filled
|= BIT(NL80211_STA_INFO_STA_FLAGS
);
2398 sfu
= &si
->sta_flags
;
2399 sfu
->mask
= BIT(NL80211_STA_FLAG_WME
) |
2400 BIT(NL80211_STA_FLAG_AUTHENTICATED
) |
2401 BIT(NL80211_STA_FLAG_ASSOCIATED
) |
2402 BIT(NL80211_STA_FLAG_AUTHORIZED
);
2403 if (fw_sta_flags
& BRCMF_STA_WME
)
2404 sfu
->set
|= BIT(NL80211_STA_FLAG_WME
);
2405 if (fw_sta_flags
& BRCMF_STA_AUTHE
)
2406 sfu
->set
|= BIT(NL80211_STA_FLAG_AUTHENTICATED
);
2407 if (fw_sta_flags
& BRCMF_STA_ASSOC
)
2408 sfu
->set
|= BIT(NL80211_STA_FLAG_ASSOCIATED
);
2409 if (fw_sta_flags
& BRCMF_STA_AUTHO
)
2410 sfu
->set
|= BIT(NL80211_STA_FLAG_AUTHORIZED
);
2413 static void brcmf_fill_bss_param(struct brcmf_if
*ifp
, struct station_info
*si
)
2417 struct brcmf_bss_info_le bss_le
;
2422 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2426 buf
->len
= cpu_to_le32(WL_BSS_INFO_MAX
);
2427 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
, buf
,
2430 brcmf_err("Failed to get bss info (%d)\n", err
);
2433 si
->filled
|= BIT(NL80211_STA_INFO_BSS_PARAM
);
2434 si
->bss_param
.beacon_interval
= le16_to_cpu(buf
->bss_le
.beacon_period
);
2435 si
->bss_param
.dtim_period
= buf
->bss_le
.dtim_period
;
2436 capability
= le16_to_cpu(buf
->bss_le
.capability
);
2437 if (capability
& IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT
)
2438 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_CTS_PROT
;
2439 if (capability
& WLAN_CAPABILITY_SHORT_PREAMBLE
)
2440 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_SHORT_PREAMBLE
;
2441 if (capability
& WLAN_CAPABILITY_SHORT_SLOT_TIME
)
2442 si
->bss_param
.flags
|= BSS_PARAM_FLAGS_SHORT_SLOT_TIME
;
2446 brcmf_cfg80211_get_station_ibss(struct brcmf_if
*ifp
,
2447 struct station_info
*sinfo
)
2449 struct brcmf_scb_val_le scbval
;
2450 struct brcmf_pktcnt_le pktcnt
;
2455 /* Get the current tx rate */
2456 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_RATE
, &rate
);
2458 brcmf_err("BRCMF_C_GET_RATE error (%d)\n", err
);
2461 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BITRATE
);
2462 sinfo
->txrate
.legacy
= rate
* 5;
2464 memset(&scbval
, 0, sizeof(scbval
));
2465 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_RSSI
, &scbval
,
2468 brcmf_err("BRCMF_C_GET_RSSI error (%d)\n", err
);
2471 rssi
= le32_to_cpu(scbval
.val
);
2472 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2473 sinfo
->signal
= rssi
;
2475 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_GET_PKTCNTS
, &pktcnt
,
2478 brcmf_err("BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err
);
2481 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_PACKETS
) |
2482 BIT(NL80211_STA_INFO_RX_DROP_MISC
) |
2483 BIT(NL80211_STA_INFO_TX_PACKETS
) |
2484 BIT(NL80211_STA_INFO_TX_FAILED
);
2485 sinfo
->rx_packets
= le32_to_cpu(pktcnt
.rx_good_pkt
);
2486 sinfo
->rx_dropped_misc
= le32_to_cpu(pktcnt
.rx_bad_pkt
);
2487 sinfo
->tx_packets
= le32_to_cpu(pktcnt
.tx_good_pkt
);
2488 sinfo
->tx_failed
= le32_to_cpu(pktcnt
.tx_bad_pkt
);
2494 brcmf_cfg80211_get_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2495 const u8
*mac
, struct station_info
*sinfo
)
2497 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2499 struct brcmf_sta_info_le sta_info_le
;
2506 brcmf_dbg(TRACE
, "Enter, MAC %pM\n", mac
);
2507 if (!check_vif_up(ifp
->vif
))
2510 if (brcmf_is_ibssmode(ifp
->vif
))
2511 return brcmf_cfg80211_get_station_ibss(ifp
, sinfo
);
2513 memset(&sta_info_le
, 0, sizeof(sta_info_le
));
2514 memcpy(&sta_info_le
, mac
, ETH_ALEN
);
2515 err
= brcmf_fil_iovar_data_get(ifp
, "tdls_sta_info",
2517 sizeof(sta_info_le
));
2518 is_tdls_peer
= !err
;
2520 err
= brcmf_fil_iovar_data_get(ifp
, "sta_info",
2522 sizeof(sta_info_le
));
2524 brcmf_err("GET STA INFO failed, %d\n", err
);
2528 brcmf_dbg(TRACE
, "version %d\n", le16_to_cpu(sta_info_le
.ver
));
2529 sinfo
->filled
= BIT(NL80211_STA_INFO_INACTIVE_TIME
);
2530 sinfo
->inactive_time
= le32_to_cpu(sta_info_le
.idle
) * 1000;
2531 sta_flags
= le32_to_cpu(sta_info_le
.flags
);
2532 brcmf_convert_sta_flags(sta_flags
, sinfo
);
2533 sinfo
->sta_flags
.mask
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
2535 sinfo
->sta_flags
.set
|= BIT(NL80211_STA_FLAG_TDLS_PEER
);
2537 sinfo
->sta_flags
.set
&= ~BIT(NL80211_STA_FLAG_TDLS_PEER
);
2538 if (sta_flags
& BRCMF_STA_ASSOC
) {
2539 sinfo
->filled
|= BIT(NL80211_STA_INFO_CONNECTED_TIME
);
2540 sinfo
->connected_time
= le32_to_cpu(sta_info_le
.in
);
2541 brcmf_fill_bss_param(ifp
, sinfo
);
2543 if (sta_flags
& BRCMF_STA_SCBSTATS
) {
2544 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_FAILED
);
2545 sinfo
->tx_failed
= le32_to_cpu(sta_info_le
.tx_failures
);
2546 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_PACKETS
);
2547 sinfo
->tx_packets
= le32_to_cpu(sta_info_le
.tx_pkts
);
2548 sinfo
->tx_packets
+= le32_to_cpu(sta_info_le
.tx_mcast_pkts
);
2549 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_PACKETS
);
2550 sinfo
->rx_packets
= le32_to_cpu(sta_info_le
.rx_ucast_pkts
);
2551 sinfo
->rx_packets
+= le32_to_cpu(sta_info_le
.rx_mcast_pkts
);
2552 if (sinfo
->tx_packets
) {
2553 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BITRATE
);
2554 sinfo
->txrate
.legacy
=
2555 le32_to_cpu(sta_info_le
.tx_rate
) / 100;
2557 if (sinfo
->rx_packets
) {
2558 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_BITRATE
);
2559 sinfo
->rxrate
.legacy
=
2560 le32_to_cpu(sta_info_le
.rx_rate
) / 100;
2562 if (le16_to_cpu(sta_info_le
.ver
) >= 4) {
2563 sinfo
->filled
|= BIT(NL80211_STA_INFO_TX_BYTES
);
2564 sinfo
->tx_bytes
= le64_to_cpu(sta_info_le
.tx_tot_bytes
);
2565 sinfo
->filled
|= BIT(NL80211_STA_INFO_RX_BYTES
);
2566 sinfo
->rx_bytes
= le64_to_cpu(sta_info_le
.rx_tot_bytes
);
2570 for (i
= 0; i
< BRCMF_ANT_MAX
; i
++) {
2571 if (sta_info_le
.rssi
[i
]) {
2572 sinfo
->chain_signal_avg
[count_rssi
] =
2573 sta_info_le
.rssi
[i
];
2574 sinfo
->chain_signal
[count_rssi
] =
2575 sta_info_le
.rssi
[i
];
2576 total_rssi
+= sta_info_le
.rssi
[i
];
2581 sinfo
->filled
|= BIT(NL80211_STA_INFO_CHAIN_SIGNAL
);
2582 sinfo
->chains
= count_rssi
;
2584 sinfo
->filled
|= BIT(NL80211_STA_INFO_SIGNAL
);
2585 total_rssi
/= count_rssi
;
2586 sinfo
->signal
= total_rssi
;
2590 brcmf_dbg(TRACE
, "Exit\n");
2595 brcmf_cfg80211_dump_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
2596 int idx
, u8
*mac
, struct station_info
*sinfo
)
2598 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2599 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2602 brcmf_dbg(TRACE
, "Enter, idx %d\n", idx
);
2605 cfg
->assoclist
.count
= cpu_to_le32(BRCMF_MAX_ASSOCLIST
);
2606 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_ASSOCLIST
,
2608 sizeof(cfg
->assoclist
));
2610 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2612 cfg
->assoclist
.count
= 0;
2616 if (idx
< le32_to_cpu(cfg
->assoclist
.count
)) {
2617 memcpy(mac
, cfg
->assoclist
.mac
[idx
], ETH_ALEN
);
2618 return brcmf_cfg80211_get_station(wiphy
, ndev
, mac
, sinfo
);
2624 brcmf_cfg80211_set_power_mgmt(struct wiphy
*wiphy
, struct net_device
*ndev
,
2625 bool enabled
, s32 timeout
)
2629 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
2630 struct brcmf_if
*ifp
= netdev_priv(ndev
);
2632 brcmf_dbg(TRACE
, "Enter\n");
2635 * Powersave enable/disable request is coming from the
2636 * cfg80211 even before the interface is up. In that
2637 * scenario, driver will be storing the power save
2638 * preference in cfg struct to apply this to
2639 * FW later while initializing the dongle
2641 cfg
->pwr_save
= enabled
;
2642 if (!check_vif_up(ifp
->vif
)) {
2644 brcmf_dbg(INFO
, "Device is not ready, storing the value in cfg_info struct\n");
2648 pm
= enabled
? PM_FAST
: PM_OFF
;
2649 /* Do not enable the power save after assoc if it is a p2p interface */
2650 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_P2P_CLIENT
) {
2651 brcmf_dbg(INFO
, "Do not enable power save for P2P clients\n");
2654 brcmf_dbg(INFO
, "power save %s\n", (pm
? "enabled" : "disabled"));
2656 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, pm
);
2659 brcmf_err("net_device is not ready yet\n");
2661 brcmf_err("error (%d)\n", err
);
2664 brcmf_dbg(TRACE
, "Exit\n");
2668 static s32
brcmf_inform_single_bss(struct brcmf_cfg80211_info
*cfg
,
2669 struct brcmf_bss_info_le
*bi
)
2671 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2672 struct ieee80211_channel
*notify_channel
;
2673 struct cfg80211_bss
*bss
;
2674 struct ieee80211_supported_band
*band
;
2675 struct brcmu_chan ch
;
2678 u16 notify_capability
;
2679 u16 notify_interval
;
2681 size_t notify_ielen
;
2684 if (le32_to_cpu(bi
->length
) > WL_BSS_INFO_MAX
) {
2685 brcmf_err("Bss info is larger than buffer. Discarding\n");
2690 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2691 cfg
->d11inf
.decchspec(&ch
);
2692 bi
->ctl_ch
= ch
.chnum
;
2694 channel
= bi
->ctl_ch
;
2696 if (channel
<= CH_MAX_2G_CHANNEL
)
2697 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2699 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2701 freq
= ieee80211_channel_to_frequency(channel
, band
->band
);
2702 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2704 notify_capability
= le16_to_cpu(bi
->capability
);
2705 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2706 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2707 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2708 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2710 brcmf_dbg(CONN
, "bssid: %pM\n", bi
->BSSID
);
2711 brcmf_dbg(CONN
, "Channel: %d(%d)\n", channel
, freq
);
2712 brcmf_dbg(CONN
, "Capability: %X\n", notify_capability
);
2713 brcmf_dbg(CONN
, "Beacon interval: %d\n", notify_interval
);
2714 brcmf_dbg(CONN
, "Signal: %d\n", notify_signal
);
2716 bss
= cfg80211_inform_bss(wiphy
, notify_channel
,
2717 CFG80211_BSS_FTYPE_UNKNOWN
,
2718 (const u8
*)bi
->BSSID
,
2719 0, notify_capability
,
2720 notify_interval
, notify_ie
,
2721 notify_ielen
, notify_signal
,
2727 cfg80211_put_bss(wiphy
, bss
);
2732 static struct brcmf_bss_info_le
*
2733 next_bss_le(struct brcmf_scan_results
*list
, struct brcmf_bss_info_le
*bss
)
2736 return list
->bss_info_le
;
2737 return (struct brcmf_bss_info_le
*)((unsigned long)bss
+
2738 le32_to_cpu(bss
->length
));
2741 static s32
brcmf_inform_bss(struct brcmf_cfg80211_info
*cfg
)
2743 struct brcmf_scan_results
*bss_list
;
2744 struct brcmf_bss_info_le
*bi
= NULL
; /* must be initialized */
2748 bss_list
= (struct brcmf_scan_results
*)cfg
->escan_info
.escan_buf
;
2749 if (bss_list
->count
!= 0 &&
2750 bss_list
->version
!= BRCMF_BSS_INFO_VERSION
) {
2751 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2755 brcmf_dbg(SCAN
, "scanned AP count (%d)\n", bss_list
->count
);
2756 for (i
= 0; i
< bss_list
->count
; i
++) {
2757 bi
= next_bss_le(bss_list
, bi
);
2758 err
= brcmf_inform_single_bss(cfg
, bi
);
2765 static s32
brcmf_inform_ibss(struct brcmf_cfg80211_info
*cfg
,
2766 struct net_device
*ndev
, const u8
*bssid
)
2768 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
2769 struct ieee80211_channel
*notify_channel
;
2770 struct brcmf_bss_info_le
*bi
= NULL
;
2771 struct ieee80211_supported_band
*band
;
2772 struct cfg80211_bss
*bss
;
2773 struct brcmu_chan ch
;
2777 u16 notify_capability
;
2778 u16 notify_interval
;
2780 size_t notify_ielen
;
2783 brcmf_dbg(TRACE
, "Enter\n");
2785 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
2791 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
2793 err
= brcmf_fil_cmd_data_get(netdev_priv(ndev
), BRCMF_C_GET_BSS_INFO
,
2794 buf
, WL_BSS_INFO_MAX
);
2796 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err
);
2800 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
2802 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
2803 cfg
->d11inf
.decchspec(&ch
);
2805 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
2806 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
2808 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
2810 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
2811 cfg
->channel
= freq
;
2812 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
2814 notify_capability
= le16_to_cpu(bi
->capability
);
2815 notify_interval
= le16_to_cpu(bi
->beacon_period
);
2816 notify_ie
= (u8
*)bi
+ le16_to_cpu(bi
->ie_offset
);
2817 notify_ielen
= le32_to_cpu(bi
->ie_length
);
2818 notify_signal
= (s16
)le16_to_cpu(bi
->RSSI
) * 100;
2820 brcmf_dbg(CONN
, "channel: %d(%d)\n", ch
.chnum
, freq
);
2821 brcmf_dbg(CONN
, "capability: %X\n", notify_capability
);
2822 brcmf_dbg(CONN
, "beacon interval: %d\n", notify_interval
);
2823 brcmf_dbg(CONN
, "signal: %d\n", notify_signal
);
2825 bss
= cfg80211_inform_bss(wiphy
, notify_channel
,
2826 CFG80211_BSS_FTYPE_UNKNOWN
, bssid
, 0,
2827 notify_capability
, notify_interval
,
2828 notify_ie
, notify_ielen
, notify_signal
,
2836 cfg80211_put_bss(wiphy
, bss
);
2842 brcmf_dbg(TRACE
, "Exit\n");
2847 static s32
brcmf_update_bss_info(struct brcmf_cfg80211_info
*cfg
,
2848 struct brcmf_if
*ifp
)
2850 struct brcmf_bss_info_le
*bi
;
2851 const struct brcmf_tlv
*tim
;
2852 u16 beacon_interval
;
2858 brcmf_dbg(TRACE
, "Enter\n");
2859 if (brcmf_is_ibssmode(ifp
->vif
))
2862 *(__le32
*)cfg
->extra_buf
= cpu_to_le32(WL_EXTRA_BUF_MAX
);
2863 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
2864 cfg
->extra_buf
, WL_EXTRA_BUF_MAX
);
2866 brcmf_err("Could not get bss info %d\n", err
);
2867 goto update_bss_info_out
;
2870 bi
= (struct brcmf_bss_info_le
*)(cfg
->extra_buf
+ 4);
2871 err
= brcmf_inform_single_bss(cfg
, bi
);
2873 goto update_bss_info_out
;
2875 ie
= ((u8
*)bi
) + le16_to_cpu(bi
->ie_offset
);
2876 ie_len
= le32_to_cpu(bi
->ie_length
);
2877 beacon_interval
= le16_to_cpu(bi
->beacon_period
);
2879 tim
= brcmf_parse_tlvs(ie
, ie_len
, WLAN_EID_TIM
);
2881 dtim_period
= tim
->data
[1];
2884 * active scan was done so we could not get dtim
2885 * information out of probe response.
2886 * so we speficially query dtim information to dongle.
2889 err
= brcmf_fil_iovar_int_get(ifp
, "dtim_assoc", &var
);
2891 brcmf_err("wl dtim_assoc failed (%d)\n", err
);
2892 goto update_bss_info_out
;
2894 dtim_period
= (u8
)var
;
2897 update_bss_info_out
:
2898 brcmf_dbg(TRACE
, "Exit");
2902 void brcmf_abort_scanning(struct brcmf_cfg80211_info
*cfg
)
2904 struct escan_info
*escan
= &cfg
->escan_info
;
2906 set_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2907 if (cfg
->scan_request
) {
2908 escan
->escan_state
= WL_ESCAN_STATE_IDLE
;
2909 brcmf_notify_escan_complete(cfg
, escan
->ifp
, true, true);
2911 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
2912 clear_bit(BRCMF_SCAN_STATUS_ABORT
, &cfg
->scan_status
);
2915 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct
*work
)
2917 struct brcmf_cfg80211_info
*cfg
=
2918 container_of(work
, struct brcmf_cfg80211_info
,
2919 escan_timeout_work
);
2921 brcmf_inform_bss(cfg
);
2922 brcmf_notify_escan_complete(cfg
, cfg
->escan_info
.ifp
, true, true);
2925 static void brcmf_escan_timeout(unsigned long data
)
2927 struct brcmf_cfg80211_info
*cfg
=
2928 (struct brcmf_cfg80211_info
*)data
;
2930 if (cfg
->scan_request
) {
2931 brcmf_err("timer expired\n");
2932 schedule_work(&cfg
->escan_timeout_work
);
2937 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info
*cfg
,
2938 struct brcmf_bss_info_le
*bss
,
2939 struct brcmf_bss_info_le
*bss_info_le
)
2941 struct brcmu_chan ch_bss
, ch_bss_info_le
;
2943 ch_bss
.chspec
= le16_to_cpu(bss
->chanspec
);
2944 cfg
->d11inf
.decchspec(&ch_bss
);
2945 ch_bss_info_le
.chspec
= le16_to_cpu(bss_info_le
->chanspec
);
2946 cfg
->d11inf
.decchspec(&ch_bss_info_le
);
2948 if (!memcmp(&bss_info_le
->BSSID
, &bss
->BSSID
, ETH_ALEN
) &&
2949 ch_bss
.band
== ch_bss_info_le
.band
&&
2950 bss_info_le
->SSID_len
== bss
->SSID_len
&&
2951 !memcmp(bss_info_le
->SSID
, bss
->SSID
, bss_info_le
->SSID_len
)) {
2952 if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) ==
2953 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
)) {
2954 s16 bss_rssi
= le16_to_cpu(bss
->RSSI
);
2955 s16 bss_info_rssi
= le16_to_cpu(bss_info_le
->RSSI
);
2957 /* preserve max RSSI if the measurements are
2958 * both on-channel or both off-channel
2960 if (bss_info_rssi
> bss_rssi
)
2961 bss
->RSSI
= bss_info_le
->RSSI
;
2962 } else if ((bss
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) &&
2963 (bss_info_le
->flags
& BRCMF_BSS_RSSI_ON_CHANNEL
) == 0) {
2964 /* preserve the on-channel rssi measurement
2965 * if the new measurement is off channel
2967 bss
->RSSI
= bss_info_le
->RSSI
;
2968 bss
->flags
|= BRCMF_BSS_RSSI_ON_CHANNEL
;
2976 brcmf_cfg80211_escan_handler(struct brcmf_if
*ifp
,
2977 const struct brcmf_event_msg
*e
, void *data
)
2979 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
2981 struct brcmf_escan_result_le
*escan_result_le
;
2982 struct brcmf_bss_info_le
*bss_info_le
;
2983 struct brcmf_bss_info_le
*bss
= NULL
;
2985 struct brcmf_scan_results
*list
;
2991 if (!test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
2992 brcmf_err("scan not ready, bsscfgidx=%d\n", ifp
->bsscfgidx
);
2996 if (status
== BRCMF_E_STATUS_PARTIAL
) {
2997 brcmf_dbg(SCAN
, "ESCAN Partial result\n");
2998 escan_result_le
= (struct brcmf_escan_result_le
*) data
;
2999 if (!escan_result_le
) {
3000 brcmf_err("Invalid escan result (NULL pointer)\n");
3003 if (le16_to_cpu(escan_result_le
->bss_count
) != 1) {
3004 brcmf_err("Invalid bss_count %d: ignoring\n",
3005 escan_result_le
->bss_count
);
3008 bss_info_le
= &escan_result_le
->bss_info_le
;
3010 if (brcmf_p2p_scan_finding_common_channel(cfg
, bss_info_le
))
3013 if (!cfg
->scan_request
) {
3014 brcmf_dbg(SCAN
, "result without cfg80211 request\n");
3018 bi_length
= le32_to_cpu(bss_info_le
->length
);
3019 if (bi_length
!= (le32_to_cpu(escan_result_le
->buflen
) -
3020 WL_ESCAN_RESULTS_FIXED_SIZE
)) {
3021 brcmf_err("Invalid bss_info length %d: ignoring\n",
3026 if (!(cfg_to_wiphy(cfg
)->interface_modes
&
3027 BIT(NL80211_IFTYPE_ADHOC
))) {
3028 if (le16_to_cpu(bss_info_le
->capability
) &
3029 WLAN_CAPABILITY_IBSS
) {
3030 brcmf_err("Ignoring IBSS result\n");
3035 list
= (struct brcmf_scan_results
*)
3036 cfg
->escan_info
.escan_buf
;
3037 if (bi_length
> WL_ESCAN_BUF_SIZE
- list
->buflen
) {
3038 brcmf_err("Buffer is too small: ignoring\n");
3042 for (i
= 0; i
< list
->count
; i
++) {
3043 bss
= bss
? (struct brcmf_bss_info_le
*)
3044 ((unsigned char *)bss
+
3045 le32_to_cpu(bss
->length
)) : list
->bss_info_le
;
3046 if (brcmf_compare_update_same_bss(cfg
, bss
,
3050 memcpy(&(cfg
->escan_info
.escan_buf
[list
->buflen
]),
3051 bss_info_le
, bi_length
);
3052 list
->version
= le32_to_cpu(bss_info_le
->version
);
3053 list
->buflen
+= bi_length
;
3056 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
3057 if (brcmf_p2p_scan_finding_common_channel(cfg
, NULL
))
3059 if (cfg
->scan_request
) {
3060 brcmf_inform_bss(cfg
);
3061 aborted
= status
!= BRCMF_E_STATUS_SUCCESS
;
3062 brcmf_notify_escan_complete(cfg
, ifp
, aborted
, false);
3064 brcmf_dbg(SCAN
, "Ignored scan complete result 0x%x\n",
3071 static void brcmf_init_escan(struct brcmf_cfg80211_info
*cfg
)
3073 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ESCAN_RESULT
,
3074 brcmf_cfg80211_escan_handler
);
3075 cfg
->escan_info
.escan_state
= WL_ESCAN_STATE_IDLE
;
3076 /* Init scan_timeout timer */
3077 init_timer(&cfg
->escan_timeout
);
3078 cfg
->escan_timeout
.data
= (unsigned long) cfg
;
3079 cfg
->escan_timeout
.function
= brcmf_escan_timeout
;
3080 INIT_WORK(&cfg
->escan_timeout_work
,
3081 brcmf_cfg80211_escan_timeout_worker
);
3084 static __always_inline
void brcmf_delay(u32 ms
)
3086 if (ms
< 1000 / HZ
) {
3094 static s32
brcmf_config_wowl_pattern(struct brcmf_if
*ifp
, u8 cmd
[4],
3095 u8
*pattern
, u32 patternsize
, u8
*mask
,
3098 struct brcmf_fil_wowl_pattern_le
*filter
;
3105 masksize
= (patternsize
+ 7) / 8;
3106 patternoffset
= sizeof(*filter
) - sizeof(filter
->cmd
) + masksize
;
3108 bufsize
= sizeof(*filter
) + patternsize
+ masksize
;
3109 buf
= kzalloc(bufsize
, GFP_KERNEL
);
3112 filter
= (struct brcmf_fil_wowl_pattern_le
*)buf
;
3114 memcpy(filter
->cmd
, cmd
, 4);
3115 filter
->masksize
= cpu_to_le32(masksize
);
3116 filter
->offset
= cpu_to_le32(packet_offset
);
3117 filter
->patternoffset
= cpu_to_le32(patternoffset
);
3118 filter
->patternsize
= cpu_to_le32(patternsize
);
3119 filter
->type
= cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP
);
3121 if ((mask
) && (masksize
))
3122 memcpy(buf
+ sizeof(*filter
), mask
, masksize
);
3123 if ((pattern
) && (patternsize
))
3124 memcpy(buf
+ sizeof(*filter
) + masksize
, pattern
, patternsize
);
3126 ret
= brcmf_fil_iovar_data_set(ifp
, "wowl_pattern", buf
, bufsize
);
3133 brcmf_wowl_nd_results(struct brcmf_if
*ifp
, const struct brcmf_event_msg
*e
,
3136 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
3137 struct brcmf_pno_scanresults_le
*pfn_result
;
3138 struct brcmf_pno_net_info_le
*netinfo
;
3140 brcmf_dbg(SCAN
, "Enter\n");
3142 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
3144 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
3145 brcmf_dbg(SCAN
, "PFN NET LOST event. Ignore\n");
3149 if (le32_to_cpu(pfn_result
->count
) < 1) {
3150 brcmf_err("Invalid result count, expected 1 (%d)\n",
3151 le32_to_cpu(pfn_result
->count
));
3155 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3156 netinfo
= (struct brcmf_pno_net_info_le
*)data
;
3157 memcpy(cfg
->wowl
.nd
->ssid
.ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3158 cfg
->wowl
.nd
->ssid
.ssid_len
= netinfo
->SSID_len
;
3159 cfg
->wowl
.nd
->n_channels
= 1;
3160 cfg
->wowl
.nd
->channels
[0] =
3161 ieee80211_channel_to_frequency(netinfo
->channel
,
3162 netinfo
->channel
<= CH_MAX_2G_CHANNEL
?
3163 NL80211_BAND_2GHZ
: NL80211_BAND_5GHZ
);
3164 cfg
->wowl
.nd_info
->n_matches
= 1;
3165 cfg
->wowl
.nd_info
->matches
[0] = cfg
->wowl
.nd
;
3167 /* Inform (the resume task) that the net detect information was recvd */
3168 cfg
->wowl
.nd_data_completed
= true;
3169 wake_up(&cfg
->wowl
.nd_data_wait
);
3176 static void brcmf_report_wowl_wakeind(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
3178 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3179 struct brcmf_wowl_wakeind_le wake_ind_le
;
3180 struct cfg80211_wowlan_wakeup wakeup_data
;
3181 struct cfg80211_wowlan_wakeup
*wakeup
;
3186 err
= brcmf_fil_iovar_data_get(ifp
, "wowl_wakeind", &wake_ind_le
,
3187 sizeof(wake_ind_le
));
3189 brcmf_err("Get wowl_wakeind failed, err = %d\n", err
);
3193 wakeind
= le32_to_cpu(wake_ind_le
.ucode_wakeind
);
3194 if (wakeind
& (BRCMF_WOWL_MAGIC
| BRCMF_WOWL_DIS
| BRCMF_WOWL_BCN
|
3195 BRCMF_WOWL_RETR
| BRCMF_WOWL_NET
|
3196 BRCMF_WOWL_PFN_FOUND
)) {
3197 wakeup
= &wakeup_data
;
3198 memset(&wakeup_data
, 0, sizeof(wakeup_data
));
3199 wakeup_data
.pattern_idx
= -1;
3201 if (wakeind
& BRCMF_WOWL_MAGIC
) {
3202 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
3203 wakeup_data
.magic_pkt
= true;
3205 if (wakeind
& BRCMF_WOWL_DIS
) {
3206 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
3207 wakeup_data
.disconnect
= true;
3209 if (wakeind
& BRCMF_WOWL_BCN
) {
3210 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
3211 wakeup_data
.disconnect
= true;
3213 if (wakeind
& BRCMF_WOWL_RETR
) {
3214 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
3215 wakeup_data
.disconnect
= true;
3217 if (wakeind
& BRCMF_WOWL_NET
) {
3218 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
3219 /* For now always map to pattern 0, no API to get
3220 * correct information available at the moment.
3222 wakeup_data
.pattern_idx
= 0;
3224 if (wakeind
& BRCMF_WOWL_PFN_FOUND
) {
3225 brcmf_dbg(INFO
, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
3226 timeout
= wait_event_timeout(cfg
->wowl
.nd_data_wait
,
3227 cfg
->wowl
.nd_data_completed
,
3228 BRCMF_ND_INFO_TIMEOUT
);
3230 brcmf_err("No result for wowl net detect\n");
3232 wakeup_data
.net_detect
= cfg
->wowl
.nd_info
;
3237 cfg80211_report_wowlan_wakeup(&ifp
->vif
->wdev
, wakeup
, GFP_KERNEL
);
3242 static void brcmf_report_wowl_wakeind(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
3246 #endif /* CONFIG_PM */
3248 static s32
brcmf_cfg80211_resume(struct wiphy
*wiphy
)
3250 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3251 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3252 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3254 brcmf_dbg(TRACE
, "Enter\n");
3256 if (cfg
->wowl
.active
) {
3257 brcmf_report_wowl_wakeind(wiphy
, ifp
);
3258 brcmf_fil_iovar_int_set(ifp
, "wowl_clear", 0);
3259 brcmf_config_wowl_pattern(ifp
, "clr", NULL
, 0, NULL
, 0);
3260 brcmf_configure_arp_offload(ifp
, true);
3261 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
,
3262 cfg
->wowl
.pre_pmmode
);
3263 cfg
->wowl
.active
= false;
3264 if (cfg
->wowl
.nd_enabled
) {
3265 brcmf_cfg80211_sched_scan_stop(cfg
->wiphy
, ifp
->ndev
);
3266 brcmf_fweh_unregister(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
);
3267 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
3268 brcmf_notify_sched_scan_results
);
3269 cfg
->wowl
.nd_enabled
= false;
3275 static void brcmf_configure_wowl(struct brcmf_cfg80211_info
*cfg
,
3276 struct brcmf_if
*ifp
,
3277 struct cfg80211_wowlan
*wowl
)
3282 brcmf_dbg(TRACE
, "Suspend, wowl config.\n");
3284 brcmf_configure_arp_offload(ifp
, false);
3285 brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_PM
, &cfg
->wowl
.pre_pmmode
);
3286 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, PM_MAX
);
3289 if (wowl
->disconnect
)
3290 wowl_config
= BRCMF_WOWL_DIS
| BRCMF_WOWL_BCN
| BRCMF_WOWL_RETR
;
3291 if (wowl
->magic_pkt
)
3292 wowl_config
|= BRCMF_WOWL_MAGIC
;
3293 if ((wowl
->patterns
) && (wowl
->n_patterns
)) {
3294 wowl_config
|= BRCMF_WOWL_NET
;
3295 for (i
= 0; i
< wowl
->n_patterns
; i
++) {
3296 brcmf_config_wowl_pattern(ifp
, "add",
3297 (u8
*)wowl
->patterns
[i
].pattern
,
3298 wowl
->patterns
[i
].pattern_len
,
3299 (u8
*)wowl
->patterns
[i
].mask
,
3300 wowl
->patterns
[i
].pkt_offset
);
3303 if (wowl
->nd_config
) {
3304 brcmf_cfg80211_sched_scan_start(cfg
->wiphy
, ifp
->ndev
,
3306 wowl_config
|= BRCMF_WOWL_PFN_FOUND
;
3308 cfg
->wowl
.nd_data_completed
= false;
3309 cfg
->wowl
.nd_enabled
= true;
3310 /* Now reroute the event for PFN to the wowl function. */
3311 brcmf_fweh_unregister(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
);
3312 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
3313 brcmf_wowl_nd_results
);
3315 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
3316 wowl_config
|= BRCMF_WOWL_UNASSOC
;
3318 brcmf_fil_iovar_data_set(ifp
, "wowl_wakeind", "clear", strlen("clear"));
3319 brcmf_fil_iovar_int_set(ifp
, "wowl", wowl_config
);
3320 brcmf_fil_iovar_int_set(ifp
, "wowl_activate", 1);
3321 brcmf_bus_wowl_config(cfg
->pub
->bus_if
, true);
3322 cfg
->wowl
.active
= true;
3325 static s32
brcmf_cfg80211_suspend(struct wiphy
*wiphy
,
3326 struct cfg80211_wowlan
*wowl
)
3328 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3329 struct net_device
*ndev
= cfg_to_ndev(cfg
);
3330 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3331 struct brcmf_cfg80211_vif
*vif
;
3333 brcmf_dbg(TRACE
, "Enter\n");
3335 /* if the primary net_device is not READY there is nothing
3336 * we can do but pray resume goes smoothly.
3338 if (!check_vif_up(ifp
->vif
))
3341 /* Stop scheduled scan */
3342 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
))
3343 brcmf_cfg80211_sched_scan_stop(wiphy
, ndev
);
3345 /* end any scanning */
3346 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
))
3347 brcmf_abort_scanning(cfg
);
3350 brcmf_bus_wowl_config(cfg
->pub
->bus_if
, false);
3351 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
3352 if (!test_bit(BRCMF_VIF_STATUS_READY
, &vif
->sme_state
))
3354 /* While going to suspend if associated with AP
3355 * disassociate from AP to save power while system is
3356 * in suspended state
3358 brcmf_link_down(vif
, WLAN_REASON_UNSPECIFIED
);
3359 /* Make sure WPA_Supplicant receives all the event
3360 * generated due to DISASSOC call to the fw to keep
3361 * the state fw and WPA_Supplicant state consistent
3366 brcmf_set_mpc(ifp
, 1);
3369 /* Configure WOWL paramaters */
3370 brcmf_configure_wowl(cfg
, ifp
, wowl
);
3374 brcmf_dbg(TRACE
, "Exit\n");
3375 /* clear any scanning activity */
3376 cfg
->scan_status
= 0;
3381 brcmf_update_pmklist(struct brcmf_cfg80211_info
*cfg
, struct brcmf_if
*ifp
)
3383 struct brcmf_pmk_list_le
*pmk_list
;
3388 pmk_list
= &cfg
->pmk_list
;
3389 npmk
= le32_to_cpu(pmk_list
->npmk
);
3391 brcmf_dbg(CONN
, "No of elements %d\n", npmk
);
3392 for (i
= 0; i
< npmk
; i
++)
3393 brcmf_dbg(CONN
, "PMK[%d]: %pM\n", i
, &pmk_list
->pmk
[i
].bssid
);
3395 err
= brcmf_fil_iovar_data_set(ifp
, "pmkid_info", pmk_list
,
3402 brcmf_cfg80211_set_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3403 struct cfg80211_pmksa
*pmksa
)
3405 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3406 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3407 struct brcmf_pmksa
*pmk
= &cfg
->pmk_list
.pmk
[0];
3411 brcmf_dbg(TRACE
, "Enter\n");
3412 if (!check_vif_up(ifp
->vif
))
3415 npmk
= le32_to_cpu(cfg
->pmk_list
.npmk
);
3416 for (i
= 0; i
< npmk
; i
++)
3417 if (!memcmp(pmksa
->bssid
, pmk
[i
].bssid
, ETH_ALEN
))
3419 if (i
< BRCMF_MAXPMKID
) {
3420 memcpy(pmk
[i
].bssid
, pmksa
->bssid
, ETH_ALEN
);
3421 memcpy(pmk
[i
].pmkid
, pmksa
->pmkid
, WLAN_PMKID_LEN
);
3424 cfg
->pmk_list
.npmk
= cpu_to_le32(npmk
);
3427 brcmf_err("Too many PMKSA entries cached %d\n", npmk
);
3431 brcmf_dbg(CONN
, "set_pmksa - PMK bssid: %pM =\n", pmk
[npmk
].bssid
);
3432 for (i
= 0; i
< WLAN_PMKID_LEN
; i
+= 4)
3433 brcmf_dbg(CONN
, "%02x %02x %02x %02x\n", pmk
[npmk
].pmkid
[i
],
3434 pmk
[npmk
].pmkid
[i
+ 1], pmk
[npmk
].pmkid
[i
+ 2],
3435 pmk
[npmk
].pmkid
[i
+ 3]);
3437 err
= brcmf_update_pmklist(cfg
, ifp
);
3439 brcmf_dbg(TRACE
, "Exit\n");
3444 brcmf_cfg80211_del_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
,
3445 struct cfg80211_pmksa
*pmksa
)
3447 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3448 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3449 struct brcmf_pmksa
*pmk
= &cfg
->pmk_list
.pmk
[0];
3453 brcmf_dbg(TRACE
, "Enter\n");
3454 if (!check_vif_up(ifp
->vif
))
3457 brcmf_dbg(CONN
, "del_pmksa - PMK bssid = %pM\n", &pmksa
->bssid
);
3459 npmk
= le32_to_cpu(cfg
->pmk_list
.npmk
);
3460 for (i
= 0; i
< npmk
; i
++)
3461 if (!memcmp(&pmksa
->bssid
, &pmk
[i
].bssid
, ETH_ALEN
))
3464 if ((npmk
> 0) && (i
< npmk
)) {
3465 for (; i
< (npmk
- 1); i
++) {
3466 memcpy(&pmk
[i
].bssid
, &pmk
[i
+ 1].bssid
, ETH_ALEN
);
3467 memcpy(&pmk
[i
].pmkid
, &pmk
[i
+ 1].pmkid
,
3470 memset(&pmk
[i
], 0, sizeof(*pmk
));
3471 cfg
->pmk_list
.npmk
= cpu_to_le32(npmk
- 1);
3473 brcmf_err("Cache entry not found\n");
3477 err
= brcmf_update_pmklist(cfg
, ifp
);
3479 brcmf_dbg(TRACE
, "Exit\n");
3485 brcmf_cfg80211_flush_pmksa(struct wiphy
*wiphy
, struct net_device
*ndev
)
3487 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3488 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3491 brcmf_dbg(TRACE
, "Enter\n");
3492 if (!check_vif_up(ifp
->vif
))
3495 memset(&cfg
->pmk_list
, 0, sizeof(cfg
->pmk_list
));
3496 err
= brcmf_update_pmklist(cfg
, ifp
);
3498 brcmf_dbg(TRACE
, "Exit\n");
3504 * PFN result doesn't have all the info which are
3505 * required by the supplicant
3506 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3507 * via wl_inform_single_bss in the required format. Escan does require the
3508 * scan request in the form of cfg80211_scan_request. For timebeing, create
3509 * cfg80211_scan_request one out of the received PNO event.
3512 brcmf_notify_sched_scan_results(struct brcmf_if
*ifp
,
3513 const struct brcmf_event_msg
*e
, void *data
)
3515 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
3516 struct brcmf_pno_net_info_le
*netinfo
, *netinfo_start
;
3517 struct cfg80211_scan_request
*request
= NULL
;
3518 struct cfg80211_ssid
*ssid
= NULL
;
3519 struct ieee80211_channel
*channel
= NULL
;
3520 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
3522 int channel_req
= 0;
3524 struct brcmf_pno_scanresults_le
*pfn_result
;
3528 brcmf_dbg(SCAN
, "Enter\n");
3530 if (e
->event_code
== BRCMF_E_PFN_NET_LOST
) {
3531 brcmf_dbg(SCAN
, "PFN NET LOST event. Do Nothing\n");
3535 pfn_result
= (struct brcmf_pno_scanresults_le
*)data
;
3536 result_count
= le32_to_cpu(pfn_result
->count
);
3537 status
= le32_to_cpu(pfn_result
->status
);
3540 * PFN event is limited to fit 512 bytes so we may get
3541 * multiple NET_FOUND events. For now place a warning here.
3543 WARN_ON(status
!= BRCMF_PNO_SCAN_COMPLETE
);
3544 brcmf_dbg(SCAN
, "PFN NET FOUND event. count: %d\n", result_count
);
3545 if (result_count
> 0) {
3548 request
= kzalloc(sizeof(*request
), GFP_KERNEL
);
3549 ssid
= kcalloc(result_count
, sizeof(*ssid
), GFP_KERNEL
);
3550 channel
= kcalloc(result_count
, sizeof(*channel
), GFP_KERNEL
);
3551 if (!request
|| !ssid
|| !channel
) {
3556 request
->wiphy
= wiphy
;
3557 data
+= sizeof(struct brcmf_pno_scanresults_le
);
3558 netinfo_start
= (struct brcmf_pno_net_info_le
*)data
;
3560 for (i
= 0; i
< result_count
; i
++) {
3561 netinfo
= &netinfo_start
[i
];
3563 brcmf_err("Invalid netinfo ptr. index: %d\n",
3569 brcmf_dbg(SCAN
, "SSID:%s Channel:%d\n",
3570 netinfo
->SSID
, netinfo
->channel
);
3571 memcpy(ssid
[i
].ssid
, netinfo
->SSID
, netinfo
->SSID_len
);
3572 ssid
[i
].ssid_len
= netinfo
->SSID_len
;
3575 channel_req
= netinfo
->channel
;
3576 if (channel_req
<= CH_MAX_2G_CHANNEL
)
3577 band
= NL80211_BAND_2GHZ
;
3579 band
= NL80211_BAND_5GHZ
;
3580 channel
[i
].center_freq
=
3581 ieee80211_channel_to_frequency(channel_req
,
3583 channel
[i
].band
= band
;
3584 channel
[i
].flags
|= IEEE80211_CHAN_NO_HT40
;
3585 request
->channels
[i
] = &channel
[i
];
3586 request
->n_channels
++;
3589 /* assign parsed ssid array */
3590 if (request
->n_ssids
)
3591 request
->ssids
= &ssid
[0];
3593 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3594 /* Abort any on-going scan */
3595 brcmf_abort_scanning(cfg
);
3598 set_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3599 cfg
->escan_info
.run
= brcmf_run_escan
;
3600 err
= brcmf_do_escan(cfg
, wiphy
, ifp
, request
);
3602 clear_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
);
3605 cfg
->sched_escan
= true;
3606 cfg
->scan_request
= request
;
3608 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3621 cfg80211_sched_scan_stopped(wiphy
);
3625 static int brcmf_dev_pno_clean(struct net_device
*ndev
)
3630 ret
= brcmf_fil_iovar_int_set(netdev_priv(ndev
), "pfn", 0);
3633 ret
= brcmf_fil_iovar_data_set(netdev_priv(ndev
), "pfnclear",
3637 brcmf_err("failed code %d\n", ret
);
3642 static int brcmf_dev_pno_config(struct brcmf_if
*ifp
,
3643 struct cfg80211_sched_scan_request
*request
)
3645 struct brcmf_pno_param_le pfn_param
;
3646 struct brcmf_pno_macaddr_le pfn_mac
;
3651 memset(&pfn_param
, 0, sizeof(pfn_param
));
3652 pfn_param
.version
= cpu_to_le32(BRCMF_PNO_VERSION
);
3654 /* set extra pno params */
3655 pfn_param
.flags
= cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT
);
3656 pfn_param
.repeat
= BRCMF_PNO_REPEAT
;
3657 pfn_param
.exp
= BRCMF_PNO_FREQ_EXPO_MAX
;
3659 /* set up pno scan fr */
3660 pfn_param
.scan_freq
= cpu_to_le32(BRCMF_PNO_TIME
);
3662 err
= brcmf_fil_iovar_data_set(ifp
, "pfn_set", &pfn_param
,
3665 brcmf_err("pfn_set failed, err=%d\n", err
);
3669 /* Find out if mac randomization should be turned on */
3670 if (!(request
->flags
& NL80211_SCAN_FLAG_RANDOM_ADDR
))
3673 pfn_mac
.version
= BRCMF_PFN_MACADDR_CFG_VER
;
3674 pfn_mac
.flags
= BRCMF_PFN_MAC_OUI_ONLY
| BRCMF_PFN_SET_MAC_UNASSOC
;
3676 memcpy(pfn_mac
.mac
, request
->mac_addr
, ETH_ALEN
);
3677 mac_mask
= request
->mac_addr_mask
;
3678 for (i
= 0; i
< ETH_ALEN
; i
++) {
3679 pfn_mac
.mac
[i
] &= mac_mask
[i
];
3680 pfn_mac
.mac
[i
] |= get_random_int() & ~(mac_mask
[i
]);
3682 /* Clear multi bit */
3683 pfn_mac
.mac
[0] &= 0xFE;
3684 /* Set locally administered */
3685 pfn_mac
.mac
[0] |= 0x02;
3687 err
= brcmf_fil_iovar_data_set(ifp
, "pfn_macaddr", &pfn_mac
,
3690 brcmf_err("pfn_macaddr failed, err=%d\n", err
);
3696 brcmf_cfg80211_sched_scan_start(struct wiphy
*wiphy
,
3697 struct net_device
*ndev
,
3698 struct cfg80211_sched_scan_request
*request
)
3700 struct brcmf_if
*ifp
= netdev_priv(ndev
);
3701 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
3702 struct brcmf_pno_net_param_le pfn
;
3706 brcmf_dbg(SCAN
, "Enter n_match_sets:%d n_ssids:%d\n",
3707 request
->n_match_sets
, request
->n_ssids
);
3708 if (test_bit(BRCMF_SCAN_STATUS_BUSY
, &cfg
->scan_status
)) {
3709 brcmf_err("Scanning already: status (%lu)\n", cfg
->scan_status
);
3712 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
)) {
3713 brcmf_err("Scanning suppressed: status (%lu)\n",
3718 if (!request
->n_ssids
|| !request
->n_match_sets
) {
3719 brcmf_dbg(SCAN
, "Invalid sched scan req!! n_ssids:%d\n",
3724 if (request
->n_ssids
> 0) {
3725 for (i
= 0; i
< request
->n_ssids
; i
++) {
3726 /* Active scan req for ssids */
3727 brcmf_dbg(SCAN
, ">>> Active scan req for ssid (%s)\n",
3728 request
->ssids
[i
].ssid
);
3731 * match_set ssids is a supert set of n_ssid list,
3732 * so we need not add these set seperately.
3737 if (request
->n_match_sets
> 0) {
3738 /* clean up everything */
3739 ret
= brcmf_dev_pno_clean(ndev
);
3741 brcmf_err("failed error=%d\n", ret
);
3746 if (brcmf_dev_pno_config(ifp
, request
))
3749 /* configure each match set */
3750 for (i
= 0; i
< request
->n_match_sets
; i
++) {
3751 struct cfg80211_ssid
*ssid
;
3754 ssid
= &request
->match_sets
[i
].ssid
;
3755 ssid_len
= ssid
->ssid_len
;
3758 brcmf_err("skip broadcast ssid\n");
3761 pfn
.auth
= cpu_to_le32(WLAN_AUTH_OPEN
);
3762 pfn
.wpa_auth
= cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY
);
3763 pfn
.wsec
= cpu_to_le32(0);
3764 pfn
.infra
= cpu_to_le32(1);
3765 pfn
.flags
= cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT
);
3766 pfn
.ssid
.SSID_len
= cpu_to_le32(ssid_len
);
3767 memcpy(pfn
.ssid
.SSID
, ssid
->ssid
, ssid_len
);
3768 ret
= brcmf_fil_iovar_data_set(ifp
, "pfn_add", &pfn
,
3770 brcmf_dbg(SCAN
, ">>> PNO filter %s for ssid (%s)\n",
3771 ret
== 0 ? "set" : "failed", ssid
->ssid
);
3773 /* Enable the PNO */
3774 if (brcmf_fil_iovar_int_set(ifp
, "pfn", 1) < 0) {
3775 brcmf_err("PNO enable failed!! ret=%d\n", ret
);
3785 static int brcmf_cfg80211_sched_scan_stop(struct wiphy
*wiphy
,
3786 struct net_device
*ndev
)
3788 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
3790 brcmf_dbg(SCAN
, "enter\n");
3791 brcmf_dev_pno_clean(ndev
);
3792 if (cfg
->sched_escan
)
3793 brcmf_notify_escan_complete(cfg
, netdev_priv(ndev
), true, true);
3797 static s32
brcmf_configure_opensecurity(struct brcmf_if
*ifp
)
3802 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", 0);
3804 brcmf_err("auth error %d\n", err
);
3808 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", 0);
3810 brcmf_err("wsec error %d\n", err
);
3813 /* set upper-layer auth */
3814 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", WPA_AUTH_NONE
);
3816 brcmf_err("wpa_auth error %d\n", err
);
3823 static bool brcmf_valid_wpa_oui(u8
*oui
, bool is_rsn_ie
)
3826 return (memcmp(oui
, RSN_OUI
, TLV_OUI_LEN
) == 0);
3828 return (memcmp(oui
, WPA_OUI
, TLV_OUI_LEN
) == 0);
3832 brcmf_configure_wpaie(struct brcmf_if
*ifp
,
3833 const struct brcmf_vs_tlv
*wpa_ie
,
3836 u32 auth
= 0; /* d11 open authentication */
3848 u32 wme_bss_disable
;
3850 brcmf_dbg(TRACE
, "Enter\n");
3854 len
= wpa_ie
->len
+ TLV_HDR_LEN
;
3855 data
= (u8
*)wpa_ie
;
3856 offset
= TLV_HDR_LEN
;
3858 offset
+= VS_IE_FIXED_HDR_LEN
;
3860 offset
+= WPA_IE_VERSION_LEN
;
3862 /* check for multicast cipher suite */
3863 if (offset
+ WPA_IE_MIN_OUI_LEN
> len
) {
3865 brcmf_err("no multicast cipher suite\n");
3869 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3871 brcmf_err("ivalid OUI\n");
3874 offset
+= TLV_OUI_LEN
;
3876 /* pick up multicast cipher */
3877 switch (data
[offset
]) {
3878 case WPA_CIPHER_NONE
:
3881 case WPA_CIPHER_WEP_40
:
3882 case WPA_CIPHER_WEP_104
:
3885 case WPA_CIPHER_TKIP
:
3886 gval
= TKIP_ENABLED
;
3888 case WPA_CIPHER_AES_CCM
:
3893 brcmf_err("Invalid multi cast cipher info\n");
3898 /* walk thru unicast cipher list and pick up what we recognize */
3899 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3900 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3901 /* Check for unicast suite(s) */
3902 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3904 brcmf_err("no unicast cipher suite\n");
3907 for (i
= 0; i
< count
; i
++) {
3908 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3910 brcmf_err("ivalid OUI\n");
3913 offset
+= TLV_OUI_LEN
;
3914 switch (data
[offset
]) {
3915 case WPA_CIPHER_NONE
:
3917 case WPA_CIPHER_WEP_40
:
3918 case WPA_CIPHER_WEP_104
:
3919 pval
|= WEP_ENABLED
;
3921 case WPA_CIPHER_TKIP
:
3922 pval
|= TKIP_ENABLED
;
3924 case WPA_CIPHER_AES_CCM
:
3925 pval
|= AES_ENABLED
;
3928 brcmf_err("Ivalid unicast security info\n");
3932 /* walk thru auth management suite list and pick up what we recognize */
3933 count
= data
[offset
] + (data
[offset
+ 1] << 8);
3934 offset
+= WPA_IE_SUITE_COUNT_LEN
;
3935 /* Check for auth key management suite(s) */
3936 if (offset
+ (WPA_IE_MIN_OUI_LEN
* count
) > len
) {
3938 brcmf_err("no auth key mgmt suite\n");
3941 for (i
= 0; i
< count
; i
++) {
3942 if (!brcmf_valid_wpa_oui(&data
[offset
], is_rsn_ie
)) {
3944 brcmf_err("ivalid OUI\n");
3947 offset
+= TLV_OUI_LEN
;
3948 switch (data
[offset
]) {
3950 brcmf_dbg(TRACE
, "RSN_AKM_NONE\n");
3951 wpa_auth
|= WPA_AUTH_NONE
;
3953 case RSN_AKM_UNSPECIFIED
:
3954 brcmf_dbg(TRACE
, "RSN_AKM_UNSPECIFIED\n");
3955 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_UNSPECIFIED
) :
3956 (wpa_auth
|= WPA_AUTH_UNSPECIFIED
);
3959 brcmf_dbg(TRACE
, "RSN_AKM_PSK\n");
3960 is_rsn_ie
? (wpa_auth
|= WPA2_AUTH_PSK
) :
3961 (wpa_auth
|= WPA_AUTH_PSK
);
3964 brcmf_err("Ivalid key mgmt info\n");
3970 wme_bss_disable
= 1;
3971 if ((offset
+ RSN_CAP_LEN
) <= len
) {
3972 rsn_cap
= data
[offset
] + (data
[offset
+ 1] << 8);
3973 if (rsn_cap
& RSN_CAP_PTK_REPLAY_CNTR_MASK
)
3974 wme_bss_disable
= 0;
3976 /* set wme_bss_disable to sync RSN Capabilities */
3977 err
= brcmf_fil_bsscfg_int_set(ifp
, "wme_bss_disable",
3980 brcmf_err("wme_bss_disable error %d\n", err
);
3984 /* FOR WPS , set SES_OW_ENABLED */
3985 wsec
= (pval
| gval
| SES_OW_ENABLED
);
3988 err
= brcmf_fil_bsscfg_int_set(ifp
, "auth", auth
);
3990 brcmf_err("auth error %d\n", err
);
3994 err
= brcmf_fil_bsscfg_int_set(ifp
, "wsec", wsec
);
3996 brcmf_err("wsec error %d\n", err
);
3999 /* set upper-layer auth */
4000 err
= brcmf_fil_bsscfg_int_set(ifp
, "wpa_auth", wpa_auth
);
4002 brcmf_err("wpa_auth error %d\n", err
);
4011 brcmf_parse_vndr_ies(const u8
*vndr_ie_buf
, u32 vndr_ie_len
,
4012 struct parsed_vndr_ies
*vndr_ies
)
4014 struct brcmf_vs_tlv
*vndrie
;
4015 struct brcmf_tlv
*ie
;
4016 struct parsed_vndr_ie_info
*parsed_info
;
4019 remaining_len
= (s32
)vndr_ie_len
;
4020 memset(vndr_ies
, 0, sizeof(*vndr_ies
));
4022 ie
= (struct brcmf_tlv
*)vndr_ie_buf
;
4024 if (ie
->id
!= WLAN_EID_VENDOR_SPECIFIC
)
4026 vndrie
= (struct brcmf_vs_tlv
*)ie
;
4027 /* len should be bigger than OUI length + one */
4028 if (vndrie
->len
< (VS_IE_FIXED_HDR_LEN
- TLV_HDR_LEN
+ 1)) {
4029 brcmf_err("invalid vndr ie. length is too small %d\n",
4033 /* if wpa or wme ie, do not add ie */
4034 if (!memcmp(vndrie
->oui
, (u8
*)WPA_OUI
, TLV_OUI_LEN
) &&
4035 ((vndrie
->oui_type
== WPA_OUI_TYPE
) ||
4036 (vndrie
->oui_type
== WME_OUI_TYPE
))) {
4037 brcmf_dbg(TRACE
, "Found WPA/WME oui. Do not add it\n");
4041 parsed_info
= &vndr_ies
->ie_info
[vndr_ies
->count
];
4043 /* save vndr ie information */
4044 parsed_info
->ie_ptr
= (char *)vndrie
;
4045 parsed_info
->ie_len
= vndrie
->len
+ TLV_HDR_LEN
;
4046 memcpy(&parsed_info
->vndrie
, vndrie
, sizeof(*vndrie
));
4050 brcmf_dbg(TRACE
, "** OUI %02x %02x %02x, type 0x%02x\n",
4051 parsed_info
->vndrie
.oui
[0],
4052 parsed_info
->vndrie
.oui
[1],
4053 parsed_info
->vndrie
.oui
[2],
4054 parsed_info
->vndrie
.oui_type
);
4056 if (vndr_ies
->count
>= VNDR_IE_PARSE_LIMIT
)
4059 remaining_len
-= (ie
->len
+ TLV_HDR_LEN
);
4060 if (remaining_len
<= TLV_HDR_LEN
)
4063 ie
= (struct brcmf_tlv
*)(((u8
*)ie
) + ie
->len
+
4070 brcmf_vndr_ie(u8
*iebuf
, s32 pktflag
, u8
*ie_ptr
, u32 ie_len
, s8
*add_del_cmd
)
4073 strncpy(iebuf
, add_del_cmd
, VNDR_IE_CMD_LEN
- 1);
4074 iebuf
[VNDR_IE_CMD_LEN
- 1] = '\0';
4076 put_unaligned_le32(1, &iebuf
[VNDR_IE_COUNT_OFFSET
]);
4078 put_unaligned_le32(pktflag
, &iebuf
[VNDR_IE_PKTFLAG_OFFSET
]);
4080 memcpy(&iebuf
[VNDR_IE_VSIE_OFFSET
], ie_ptr
, ie_len
);
4082 return ie_len
+ VNDR_IE_HDR_SIZE
;
4085 s32
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif
*vif
, s32 pktflag
,
4086 const u8
*vndr_ie_buf
, u32 vndr_ie_len
)
4088 struct brcmf_if
*ifp
;
4089 struct vif_saved_ie
*saved_ie
;
4093 u8
*mgmt_ie_buf
= NULL
;
4094 int mgmt_ie_buf_len
;
4096 u32 del_add_ie_buf_len
= 0;
4097 u32 total_ie_buf_len
= 0;
4098 u32 parsed_ie_buf_len
= 0;
4099 struct parsed_vndr_ies old_vndr_ies
;
4100 struct parsed_vndr_ies new_vndr_ies
;
4101 struct parsed_vndr_ie_info
*vndrie_info
;
4104 int remained_buf_len
;
4109 saved_ie
= &vif
->saved_ie
;
4111 brcmf_dbg(TRACE
, "bsscfgidx %d, pktflag : 0x%02X\n", ifp
->bsscfgidx
,
4113 iovar_ie_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
4116 curr_ie_buf
= iovar_ie_buf
;
4118 case BRCMF_VNDR_IE_PRBREQ_FLAG
:
4119 mgmt_ie_buf
= saved_ie
->probe_req_ie
;
4120 mgmt_ie_len
= &saved_ie
->probe_req_ie_len
;
4121 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_req_ie
);
4123 case BRCMF_VNDR_IE_PRBRSP_FLAG
:
4124 mgmt_ie_buf
= saved_ie
->probe_res_ie
;
4125 mgmt_ie_len
= &saved_ie
->probe_res_ie_len
;
4126 mgmt_ie_buf_len
= sizeof(saved_ie
->probe_res_ie
);
4128 case BRCMF_VNDR_IE_BEACON_FLAG
:
4129 mgmt_ie_buf
= saved_ie
->beacon_ie
;
4130 mgmt_ie_len
= &saved_ie
->beacon_ie_len
;
4131 mgmt_ie_buf_len
= sizeof(saved_ie
->beacon_ie
);
4133 case BRCMF_VNDR_IE_ASSOCREQ_FLAG
:
4134 mgmt_ie_buf
= saved_ie
->assoc_req_ie
;
4135 mgmt_ie_len
= &saved_ie
->assoc_req_ie_len
;
4136 mgmt_ie_buf_len
= sizeof(saved_ie
->assoc_req_ie
);
4140 brcmf_err("not suitable type\n");
4144 if (vndr_ie_len
> mgmt_ie_buf_len
) {
4146 brcmf_err("extra IE size too big\n");
4150 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4151 if (vndr_ie_buf
&& vndr_ie_len
&& curr_ie_buf
) {
4153 brcmf_parse_vndr_ies(vndr_ie_buf
, vndr_ie_len
, &new_vndr_ies
);
4154 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
4155 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
4156 memcpy(ptr
+ parsed_ie_buf_len
, vndrie_info
->ie_ptr
,
4157 vndrie_info
->ie_len
);
4158 parsed_ie_buf_len
+= vndrie_info
->ie_len
;
4162 if (mgmt_ie_buf
&& *mgmt_ie_len
) {
4163 if (parsed_ie_buf_len
&& (parsed_ie_buf_len
== *mgmt_ie_len
) &&
4164 (memcmp(mgmt_ie_buf
, curr_ie_buf
,
4165 parsed_ie_buf_len
) == 0)) {
4166 brcmf_dbg(TRACE
, "Previous mgmt IE equals to current IE\n");
4170 /* parse old vndr_ie */
4171 brcmf_parse_vndr_ies(mgmt_ie_buf
, *mgmt_ie_len
, &old_vndr_ies
);
4173 /* make a command to delete old ie */
4174 for (i
= 0; i
< old_vndr_ies
.count
; i
++) {
4175 vndrie_info
= &old_vndr_ies
.ie_info
[i
];
4177 brcmf_dbg(TRACE
, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
4178 vndrie_info
->vndrie
.id
,
4179 vndrie_info
->vndrie
.len
,
4180 vndrie_info
->vndrie
.oui
[0],
4181 vndrie_info
->vndrie
.oui
[1],
4182 vndrie_info
->vndrie
.oui
[2]);
4184 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
4185 vndrie_info
->ie_ptr
,
4186 vndrie_info
->ie_len
,
4188 curr_ie_buf
+= del_add_ie_buf_len
;
4189 total_ie_buf_len
+= del_add_ie_buf_len
;
4194 /* Add if there is any extra IE */
4195 if (mgmt_ie_buf
&& parsed_ie_buf_len
) {
4198 remained_buf_len
= mgmt_ie_buf_len
;
4200 /* make a command to add new ie */
4201 for (i
= 0; i
< new_vndr_ies
.count
; i
++) {
4202 vndrie_info
= &new_vndr_ies
.ie_info
[i
];
4204 /* verify remained buf size before copy data */
4205 if (remained_buf_len
< (vndrie_info
->vndrie
.len
+
4206 VNDR_IE_VSIE_OFFSET
)) {
4207 brcmf_err("no space in mgmt_ie_buf: len left %d",
4211 remained_buf_len
-= (vndrie_info
->ie_len
+
4212 VNDR_IE_VSIE_OFFSET
);
4214 brcmf_dbg(TRACE
, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4215 vndrie_info
->vndrie
.id
,
4216 vndrie_info
->vndrie
.len
,
4217 vndrie_info
->vndrie
.oui
[0],
4218 vndrie_info
->vndrie
.oui
[1],
4219 vndrie_info
->vndrie
.oui
[2]);
4221 del_add_ie_buf_len
= brcmf_vndr_ie(curr_ie_buf
, pktflag
,
4222 vndrie_info
->ie_ptr
,
4223 vndrie_info
->ie_len
,
4226 /* save the parsed IE in wl struct */
4227 memcpy(ptr
+ (*mgmt_ie_len
), vndrie_info
->ie_ptr
,
4228 vndrie_info
->ie_len
);
4229 *mgmt_ie_len
+= vndrie_info
->ie_len
;
4231 curr_ie_buf
+= del_add_ie_buf_len
;
4232 total_ie_buf_len
+= del_add_ie_buf_len
;
4235 if (total_ie_buf_len
) {
4236 err
= brcmf_fil_bsscfg_data_set(ifp
, "vndr_ie", iovar_ie_buf
,
4239 brcmf_err("vndr ie set error : %d\n", err
);
4243 kfree(iovar_ie_buf
);
4247 s32
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif
*vif
)
4250 BRCMF_VNDR_IE_PRBREQ_FLAG
,
4251 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4252 BRCMF_VNDR_IE_BEACON_FLAG
4256 for (i
= 0; i
< ARRAY_SIZE(pktflags
); i
++)
4257 brcmf_vif_set_mgmt_ie(vif
, pktflags
[i
], NULL
, 0);
4259 memset(&vif
->saved_ie
, 0, sizeof(vif
->saved_ie
));
4264 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif
*vif
,
4265 struct cfg80211_beacon_data
*beacon
)
4269 /* Set Beacon IEs to FW */
4270 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_BEACON_FLAG
,
4271 beacon
->tail
, beacon
->tail_len
);
4273 brcmf_err("Set Beacon IE Failed\n");
4276 brcmf_dbg(TRACE
, "Applied Vndr IEs for Beacon\n");
4278 /* Set Probe Response IEs to FW */
4279 err
= brcmf_vif_set_mgmt_ie(vif
, BRCMF_VNDR_IE_PRBRSP_FLAG
,
4280 beacon
->proberesp_ies
,
4281 beacon
->proberesp_ies_len
);
4283 brcmf_err("Set Probe Resp IE Failed\n");
4285 brcmf_dbg(TRACE
, "Applied Vndr IEs for Probe Resp\n");
4291 brcmf_cfg80211_start_ap(struct wiphy
*wiphy
, struct net_device
*ndev
,
4292 struct cfg80211_ap_settings
*settings
)
4295 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4296 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4297 const struct brcmf_tlv
*ssid_ie
;
4298 const struct brcmf_tlv
*country_ie
;
4299 struct brcmf_ssid_le ssid_le
;
4301 const struct brcmf_tlv
*rsn_ie
;
4302 const struct brcmf_vs_tlv
*wpa_ie
;
4303 struct brcmf_join_params join_params
;
4304 enum nl80211_iftype dev_role
;
4305 struct brcmf_fil_bss_enable_le bss_enable
;
4310 brcmf_dbg(TRACE
, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4311 settings
->chandef
.chan
->hw_value
,
4312 settings
->chandef
.center_freq1
, settings
->chandef
.width
,
4313 settings
->beacon_interval
, settings
->dtim_period
);
4314 brcmf_dbg(TRACE
, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4315 settings
->ssid
, settings
->ssid_len
, settings
->auth_type
,
4316 settings
->inactivity_timeout
);
4317 dev_role
= ifp
->vif
->wdev
.iftype
;
4318 mbss
= ifp
->vif
->mbss
;
4320 /* store current 11d setting */
4321 brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_REGULATORY
, &ifp
->vif
->is_11d
);
4322 country_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
4323 settings
->beacon
.tail_len
,
4325 is_11d
= country_ie
? 1 : 0;
4327 memset(&ssid_le
, 0, sizeof(ssid_le
));
4328 if (settings
->ssid
== NULL
|| settings
->ssid_len
== 0) {
4329 ie_offset
= DOT11_MGMT_HDR_LEN
+ DOT11_BCN_PRB_FIXED_LEN
;
4330 ssid_ie
= brcmf_parse_tlvs(
4331 (u8
*)&settings
->beacon
.head
[ie_offset
],
4332 settings
->beacon
.head_len
- ie_offset
,
4337 memcpy(ssid_le
.SSID
, ssid_ie
->data
, ssid_ie
->len
);
4338 ssid_le
.SSID_len
= cpu_to_le32(ssid_ie
->len
);
4339 brcmf_dbg(TRACE
, "SSID is (%s) in Head\n", ssid_le
.SSID
);
4341 memcpy(ssid_le
.SSID
, settings
->ssid
, settings
->ssid_len
);
4342 ssid_le
.SSID_len
= cpu_to_le32((u32
)settings
->ssid_len
);
4346 brcmf_set_mpc(ifp
, 0);
4347 brcmf_configure_arp_offload(ifp
, false);
4350 /* find the RSN_IE */
4351 rsn_ie
= brcmf_parse_tlvs((u8
*)settings
->beacon
.tail
,
4352 settings
->beacon
.tail_len
, WLAN_EID_RSN
);
4354 /* find the WPA_IE */
4355 wpa_ie
= brcmf_find_wpaie((u8
*)settings
->beacon
.tail
,
4356 settings
->beacon
.tail_len
);
4358 if ((wpa_ie
!= NULL
|| rsn_ie
!= NULL
)) {
4359 brcmf_dbg(TRACE
, "WPA(2) IE is found\n");
4360 if (wpa_ie
!= NULL
) {
4362 err
= brcmf_configure_wpaie(ifp
, wpa_ie
, false);
4366 struct brcmf_vs_tlv
*tmp_ie
;
4368 tmp_ie
= (struct brcmf_vs_tlv
*)rsn_ie
;
4371 err
= brcmf_configure_wpaie(ifp
, tmp_ie
, true);
4376 brcmf_dbg(TRACE
, "No WPA(2) IEs found\n");
4377 brcmf_configure_opensecurity(ifp
);
4380 brcmf_config_ap_mgmt_ie(ifp
->vif
, &settings
->beacon
);
4383 chanspec
= chandef_to_chanspec(&cfg
->d11inf
,
4384 &settings
->chandef
);
4385 err
= brcmf_fil_iovar_int_set(ifp
, "chanspec", chanspec
);
4387 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4392 if (is_11d
!= ifp
->vif
->is_11d
) {
4393 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_REGULATORY
,
4396 brcmf_err("Regulatory Set Error, %d\n", err
);
4400 if (settings
->beacon_interval
) {
4401 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_BCNPRD
,
4402 settings
->beacon_interval
);
4404 brcmf_err("Beacon Interval Set Error, %d\n",
4409 if (settings
->dtim_period
) {
4410 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_DTIMPRD
,
4411 settings
->dtim_period
);
4413 brcmf_err("DTIM Interval Set Error, %d\n", err
);
4418 if ((dev_role
== NL80211_IFTYPE_AP
) &&
4419 ((ifp
->ifidx
== 0) ||
4420 !brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_RSDB
))) {
4421 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4423 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
4426 brcmf_fil_iovar_int_set(ifp
, "apsta", 0);
4429 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 1);
4431 brcmf_err("SET INFRA error %d\n", err
);
4434 } else if (WARN_ON(is_11d
!= ifp
->vif
->is_11d
)) {
4435 /* Multiple-BSS should use same 11d configuration */
4439 if (dev_role
== NL80211_IFTYPE_AP
) {
4440 if ((brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
)) && (!mbss
))
4441 brcmf_fil_iovar_int_set(ifp
, "mbss", 1);
4443 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 1);
4445 brcmf_err("setting AP mode failed %d\n", err
);
4448 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
4450 brcmf_err("BRCMF_C_UP error (%d)\n", err
);
4453 /* On DOWN the firmware removes the WEP keys, reconfigure
4454 * them if they were set.
4456 brcmf_cfg80211_reconfigure_wep(ifp
);
4458 memset(&join_params
, 0, sizeof(join_params
));
4459 /* join parameters starts with ssid */
4460 memcpy(&join_params
.ssid_le
, &ssid_le
, sizeof(ssid_le
));
4462 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
4463 &join_params
, sizeof(join_params
));
4465 brcmf_err("SET SSID error (%d)\n", err
);
4468 brcmf_dbg(TRACE
, "AP mode configuration complete\n");
4470 err
= brcmf_fil_bsscfg_data_set(ifp
, "ssid", &ssid_le
,
4473 brcmf_err("setting ssid failed %d\n", err
);
4476 bss_enable
.bsscfgidx
= cpu_to_le32(ifp
->bsscfgidx
);
4477 bss_enable
.enable
= cpu_to_le32(1);
4478 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
4479 sizeof(bss_enable
));
4481 brcmf_err("bss_enable config failed %d\n", err
);
4485 brcmf_dbg(TRACE
, "GO mode configuration complete\n");
4487 set_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
4488 brcmf_net_setcarrier(ifp
, true);
4491 if ((err
) && (!mbss
)) {
4492 brcmf_set_mpc(ifp
, 1);
4493 brcmf_configure_arp_offload(ifp
, true);
4498 static int brcmf_cfg80211_stop_ap(struct wiphy
*wiphy
, struct net_device
*ndev
)
4500 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4502 struct brcmf_fil_bss_enable_le bss_enable
;
4503 struct brcmf_join_params join_params
;
4505 brcmf_dbg(TRACE
, "Enter\n");
4507 if (ifp
->vif
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
4508 /* Due to most likely deauths outstanding we sleep */
4509 /* first to make sure they get processed by fw. */
4512 if (ifp
->vif
->mbss
) {
4513 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4517 memset(&join_params
, 0, sizeof(join_params
));
4518 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SSID
,
4519 &join_params
, sizeof(join_params
));
4521 brcmf_err("SET SSID error (%d)\n", err
);
4522 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_DOWN
, 1);
4524 brcmf_err("BRCMF_C_DOWN error %d\n", err
);
4525 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_AP
, 0);
4527 brcmf_err("setting AP mode failed %d\n", err
);
4528 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_INFRA
, 0);
4530 brcmf_err("setting INFRA mode failed %d\n", err
);
4531 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
))
4532 brcmf_fil_iovar_int_set(ifp
, "mbss", 0);
4533 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_REGULATORY
,
4536 brcmf_err("restoring REGULATORY setting failed %d\n",
4538 /* Bring device back up so it can be used again */
4539 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 1);
4541 brcmf_err("BRCMF_C_UP error %d\n", err
);
4543 bss_enable
.bsscfgidx
= cpu_to_le32(ifp
->bsscfgidx
);
4544 bss_enable
.enable
= cpu_to_le32(0);
4545 err
= brcmf_fil_iovar_data_set(ifp
, "bss", &bss_enable
,
4546 sizeof(bss_enable
));
4548 brcmf_err("bss_enable config failed %d\n", err
);
4550 brcmf_set_mpc(ifp
, 1);
4551 brcmf_configure_arp_offload(ifp
, true);
4552 clear_bit(BRCMF_VIF_STATUS_AP_CREATED
, &ifp
->vif
->sme_state
);
4553 brcmf_net_setcarrier(ifp
, false);
4559 brcmf_cfg80211_change_beacon(struct wiphy
*wiphy
, struct net_device
*ndev
,
4560 struct cfg80211_beacon_data
*info
)
4562 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4565 brcmf_dbg(TRACE
, "Enter\n");
4567 err
= brcmf_config_ap_mgmt_ie(ifp
->vif
, info
);
4573 brcmf_cfg80211_del_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
4574 struct station_del_parameters
*params
)
4576 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4577 struct brcmf_scb_val_le scbval
;
4578 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4584 brcmf_dbg(TRACE
, "Enter %pM\n", params
->mac
);
4586 if (ifp
->vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
)
4587 ifp
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
->ifp
;
4588 if (!check_vif_up(ifp
->vif
))
4591 memcpy(&scbval
.ea
, params
->mac
, ETH_ALEN
);
4592 scbval
.val
= cpu_to_le32(params
->reason_code
);
4593 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON
,
4594 &scbval
, sizeof(scbval
));
4596 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err
);
4598 brcmf_dbg(TRACE
, "Exit\n");
4603 brcmf_cfg80211_change_station(struct wiphy
*wiphy
, struct net_device
*ndev
,
4604 const u8
*mac
, struct station_parameters
*params
)
4606 struct brcmf_if
*ifp
= netdev_priv(ndev
);
4609 brcmf_dbg(TRACE
, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac
,
4610 params
->sta_flags_mask
, params
->sta_flags_set
);
4612 /* Ignore all 00 MAC */
4613 if (is_zero_ether_addr(mac
))
4616 if (!(params
->sta_flags_mask
& BIT(NL80211_STA_FLAG_AUTHORIZED
)))
4619 if (params
->sta_flags_set
& BIT(NL80211_STA_FLAG_AUTHORIZED
))
4620 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SCB_AUTHORIZE
,
4621 (void *)mac
, ETH_ALEN
);
4623 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_SCB_DEAUTHORIZE
,
4624 (void *)mac
, ETH_ALEN
);
4626 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err
);
4632 brcmf_cfg80211_mgmt_frame_register(struct wiphy
*wiphy
,
4633 struct wireless_dev
*wdev
,
4634 u16 frame_type
, bool reg
)
4636 struct brcmf_cfg80211_vif
*vif
;
4639 brcmf_dbg(TRACE
, "Enter, frame_type %04x, reg=%d\n", frame_type
, reg
);
4641 mgmt_type
= (frame_type
& IEEE80211_FCTL_STYPE
) >> 4;
4642 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4644 vif
->mgmt_rx_reg
|= BIT(mgmt_type
);
4646 vif
->mgmt_rx_reg
&= ~BIT(mgmt_type
);
4651 brcmf_cfg80211_mgmt_tx(struct wiphy
*wiphy
, struct wireless_dev
*wdev
,
4652 struct cfg80211_mgmt_tx_params
*params
, u64
*cookie
)
4654 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4655 struct ieee80211_channel
*chan
= params
->chan
;
4656 const u8
*buf
= params
->buf
;
4657 size_t len
= params
->len
;
4658 const struct ieee80211_mgmt
*mgmt
;
4659 struct brcmf_cfg80211_vif
*vif
;
4663 struct brcmf_fil_action_frame_le
*action_frame
;
4664 struct brcmf_fil_af_params_le
*af_params
;
4669 brcmf_dbg(TRACE
, "Enter\n");
4673 mgmt
= (const struct ieee80211_mgmt
*)buf
;
4675 if (!ieee80211_is_mgmt(mgmt
->frame_control
)) {
4676 brcmf_err("Driver only allows MGMT packet type\n");
4680 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4682 if (ieee80211_is_probe_resp(mgmt
->frame_control
)) {
4683 /* Right now the only reason to get a probe response */
4684 /* is for p2p listen response or for p2p GO from */
4685 /* wpa_supplicant. Unfortunately the probe is send */
4686 /* on primary ndev, while dongle wants it on the p2p */
4687 /* vif. Since this is only reason for a probe */
4688 /* response to be sent, the vif is taken from cfg. */
4689 /* If ever desired to send proberesp for non p2p */
4690 /* response then data should be checked for */
4691 /* "DIRECT-". Note in future supplicant will take */
4692 /* dedicated p2p wdev to do this and then this 'hack'*/
4693 /* is not needed anymore. */
4694 ie_offset
= DOT11_MGMT_HDR_LEN
+
4695 DOT11_BCN_PRB_FIXED_LEN
;
4696 ie_len
= len
- ie_offset
;
4697 if (vif
== cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_PRIMARY
].vif
)
4698 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4699 err
= brcmf_vif_set_mgmt_ie(vif
,
4700 BRCMF_VNDR_IE_PRBRSP_FLAG
,
4703 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, true,
4705 } else if (ieee80211_is_action(mgmt
->frame_control
)) {
4706 af_params
= kzalloc(sizeof(*af_params
), GFP_KERNEL
);
4707 if (af_params
== NULL
) {
4708 brcmf_err("unable to allocate frame\n");
4712 action_frame
= &af_params
->action_frame
;
4713 /* Add the packet Id */
4714 action_frame
->packet_id
= cpu_to_le32(*cookie
);
4716 memcpy(&action_frame
->da
[0], &mgmt
->da
[0], ETH_ALEN
);
4717 memcpy(&af_params
->bssid
[0], &mgmt
->bssid
[0], ETH_ALEN
);
4718 /* Add the length exepted for 802.11 header */
4719 action_frame
->len
= cpu_to_le16(len
- DOT11_MGMT_HDR_LEN
);
4720 /* Add the channel. Use the one specified as parameter if any or
4721 * the current one (got from the firmware) otherwise
4724 freq
= chan
->center_freq
;
4726 brcmf_fil_cmd_int_get(vif
->ifp
, BRCMF_C_GET_CHANNEL
,
4728 chan_nr
= ieee80211_frequency_to_channel(freq
);
4729 af_params
->channel
= cpu_to_le32(chan_nr
);
4731 memcpy(action_frame
->data
, &buf
[DOT11_MGMT_HDR_LEN
],
4732 le16_to_cpu(action_frame
->len
));
4734 brcmf_dbg(TRACE
, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4735 *cookie
, le16_to_cpu(action_frame
->len
), freq
);
4737 ack
= brcmf_p2p_send_action_frame(cfg
, cfg_to_ndev(cfg
),
4740 cfg80211_mgmt_tx_status(wdev
, *cookie
, buf
, len
, ack
,
4744 brcmf_dbg(TRACE
, "Unhandled, fc=%04x!!\n", mgmt
->frame_control
);
4745 brcmf_dbg_hex_dump(true, buf
, len
, "payload, len=%Zu\n", len
);
4754 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy
*wiphy
,
4755 struct wireless_dev
*wdev
,
4758 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4759 struct brcmf_cfg80211_vif
*vif
;
4762 brcmf_dbg(TRACE
, "Enter p2p listen cancel\n");
4764 vif
= cfg
->p2p
.bss_idx
[P2PAPI_BSSCFG_DEVICE
].vif
;
4766 brcmf_err("No p2p device available for probe response\n");
4770 brcmf_p2p_cancel_remain_on_channel(vif
->ifp
);
4775 static int brcmf_cfg80211_crit_proto_start(struct wiphy
*wiphy
,
4776 struct wireless_dev
*wdev
,
4777 enum nl80211_crit_proto_id proto
,
4780 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4781 struct brcmf_cfg80211_vif
*vif
;
4783 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4785 /* only DHCP support for now */
4786 if (proto
!= NL80211_CRIT_PROTO_DHCP
)
4789 /* suppress and abort scanning */
4790 set_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4791 brcmf_abort_scanning(cfg
);
4793 return brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_DISABLED
, duration
);
4796 static void brcmf_cfg80211_crit_proto_stop(struct wiphy
*wiphy
,
4797 struct wireless_dev
*wdev
)
4799 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
4800 struct brcmf_cfg80211_vif
*vif
;
4802 vif
= container_of(wdev
, struct brcmf_cfg80211_vif
, wdev
);
4804 brcmf_btcoex_set_mode(vif
, BRCMF_BTCOEX_ENABLED
, 0);
4805 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS
, &cfg
->scan_status
);
4809 brcmf_notify_tdls_peer_event(struct brcmf_if
*ifp
,
4810 const struct brcmf_event_msg
*e
, void *data
)
4812 switch (e
->reason
) {
4813 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED
:
4814 brcmf_dbg(TRACE
, "TDLS Peer Discovered\n");
4816 case BRCMF_E_REASON_TDLS_PEER_CONNECTED
:
4817 brcmf_dbg(TRACE
, "TDLS Peer Connected\n");
4818 brcmf_proto_add_tdls_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
4820 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED
:
4821 brcmf_dbg(TRACE
, "TDLS Peer Disconnected\n");
4822 brcmf_proto_delete_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
4829 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper
)
4834 case NL80211_TDLS_DISCOVERY_REQ
:
4835 ret
= BRCMF_TDLS_MANUAL_EP_DISCOVERY
;
4837 case NL80211_TDLS_SETUP
:
4838 ret
= BRCMF_TDLS_MANUAL_EP_CREATE
;
4840 case NL80211_TDLS_TEARDOWN
:
4841 ret
= BRCMF_TDLS_MANUAL_EP_DELETE
;
4844 brcmf_err("unsupported operation: %d\n", oper
);
4850 static int brcmf_cfg80211_tdls_oper(struct wiphy
*wiphy
,
4851 struct net_device
*ndev
, const u8
*peer
,
4852 enum nl80211_tdls_operation oper
)
4854 struct brcmf_if
*ifp
;
4855 struct brcmf_tdls_iovar_le info
;
4858 ret
= brcmf_convert_nl80211_tdls_oper(oper
);
4862 ifp
= netdev_priv(ndev
);
4863 memset(&info
, 0, sizeof(info
));
4864 info
.mode
= (u8
)ret
;
4866 memcpy(info
.ea
, peer
, ETH_ALEN
);
4868 ret
= brcmf_fil_iovar_data_set(ifp
, "tdls_endpoint",
4869 &info
, sizeof(info
));
4871 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret
);
4876 static struct cfg80211_ops wl_cfg80211_ops
= {
4877 .add_virtual_intf
= brcmf_cfg80211_add_iface
,
4878 .del_virtual_intf
= brcmf_cfg80211_del_iface
,
4879 .change_virtual_intf
= brcmf_cfg80211_change_iface
,
4880 .scan
= brcmf_cfg80211_scan
,
4881 .set_wiphy_params
= brcmf_cfg80211_set_wiphy_params
,
4882 .join_ibss
= brcmf_cfg80211_join_ibss
,
4883 .leave_ibss
= brcmf_cfg80211_leave_ibss
,
4884 .get_station
= brcmf_cfg80211_get_station
,
4885 .dump_station
= brcmf_cfg80211_dump_station
,
4886 .set_tx_power
= brcmf_cfg80211_set_tx_power
,
4887 .get_tx_power
= brcmf_cfg80211_get_tx_power
,
4888 .add_key
= brcmf_cfg80211_add_key
,
4889 .del_key
= brcmf_cfg80211_del_key
,
4890 .get_key
= brcmf_cfg80211_get_key
,
4891 .set_default_key
= brcmf_cfg80211_config_default_key
,
4892 .set_default_mgmt_key
= brcmf_cfg80211_config_default_mgmt_key
,
4893 .set_power_mgmt
= brcmf_cfg80211_set_power_mgmt
,
4894 .connect
= brcmf_cfg80211_connect
,
4895 .disconnect
= brcmf_cfg80211_disconnect
,
4896 .suspend
= brcmf_cfg80211_suspend
,
4897 .resume
= brcmf_cfg80211_resume
,
4898 .set_pmksa
= brcmf_cfg80211_set_pmksa
,
4899 .del_pmksa
= brcmf_cfg80211_del_pmksa
,
4900 .flush_pmksa
= brcmf_cfg80211_flush_pmksa
,
4901 .start_ap
= brcmf_cfg80211_start_ap
,
4902 .stop_ap
= brcmf_cfg80211_stop_ap
,
4903 .change_beacon
= brcmf_cfg80211_change_beacon
,
4904 .del_station
= brcmf_cfg80211_del_station
,
4905 .change_station
= brcmf_cfg80211_change_station
,
4906 .sched_scan_start
= brcmf_cfg80211_sched_scan_start
,
4907 .sched_scan_stop
= brcmf_cfg80211_sched_scan_stop
,
4908 .mgmt_frame_register
= brcmf_cfg80211_mgmt_frame_register
,
4909 .mgmt_tx
= brcmf_cfg80211_mgmt_tx
,
4910 .remain_on_channel
= brcmf_p2p_remain_on_channel
,
4911 .cancel_remain_on_channel
= brcmf_cfg80211_cancel_remain_on_channel
,
4912 .start_p2p_device
= brcmf_p2p_start_device
,
4913 .stop_p2p_device
= brcmf_p2p_stop_device
,
4914 .crit_proto_start
= brcmf_cfg80211_crit_proto_start
,
4915 .crit_proto_stop
= brcmf_cfg80211_crit_proto_stop
,
4916 .tdls_oper
= brcmf_cfg80211_tdls_oper
,
4919 struct brcmf_cfg80211_vif
*brcmf_alloc_vif(struct brcmf_cfg80211_info
*cfg
,
4920 enum nl80211_iftype type
,
4923 struct brcmf_cfg80211_vif
*vif_walk
;
4924 struct brcmf_cfg80211_vif
*vif
;
4927 brcmf_dbg(TRACE
, "allocating virtual interface (size=%zu)\n",
4929 vif
= kzalloc(sizeof(*vif
), GFP_KERNEL
);
4931 return ERR_PTR(-ENOMEM
);
4933 vif
->wdev
.wiphy
= cfg
->wiphy
;
4934 vif
->wdev
.iftype
= type
;
4936 vif
->pm_block
= pm_block
;
4938 brcmf_init_prof(&vif
->profile
);
4940 if (type
== NL80211_IFTYPE_AP
) {
4942 list_for_each_entry(vif_walk
, &cfg
->vif_list
, list
) {
4943 if (vif_walk
->wdev
.iftype
== NL80211_IFTYPE_AP
) {
4951 list_add_tail(&vif
->list
, &cfg
->vif_list
);
4955 void brcmf_free_vif(struct brcmf_cfg80211_vif
*vif
)
4957 list_del(&vif
->list
);
4961 void brcmf_cfg80211_free_netdev(struct net_device
*ndev
)
4963 struct brcmf_cfg80211_vif
*vif
;
4964 struct brcmf_if
*ifp
;
4966 ifp
= netdev_priv(ndev
);
4970 brcmf_free_vif(vif
);
4974 static bool brcmf_is_linkup(const struct brcmf_event_msg
*e
)
4976 u32 event
= e
->event_code
;
4977 u32 status
= e
->status
;
4979 if (event
== BRCMF_E_SET_SSID
&& status
== BRCMF_E_STATUS_SUCCESS
) {
4980 brcmf_dbg(CONN
, "Processing set ssid\n");
4987 static bool brcmf_is_linkdown(const struct brcmf_event_msg
*e
)
4989 u32 event
= e
->event_code
;
4990 u16 flags
= e
->flags
;
4992 if ((event
== BRCMF_E_DEAUTH
) || (event
== BRCMF_E_DEAUTH_IND
) ||
4993 (event
== BRCMF_E_DISASSOC_IND
) ||
4994 ((event
== BRCMF_E_LINK
) && (!(flags
& BRCMF_EVENT_MSG_LINK
)))) {
4995 brcmf_dbg(CONN
, "Processing link down\n");
5001 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info
*cfg
,
5002 const struct brcmf_event_msg
*e
)
5004 u32 event
= e
->event_code
;
5005 u32 status
= e
->status
;
5007 if (event
== BRCMF_E_LINK
&& status
== BRCMF_E_STATUS_NO_NETWORKS
) {
5008 brcmf_dbg(CONN
, "Processing Link %s & no network found\n",
5009 e
->flags
& BRCMF_EVENT_MSG_LINK
? "up" : "down");
5013 if (event
== BRCMF_E_SET_SSID
&& status
!= BRCMF_E_STATUS_SUCCESS
) {
5014 brcmf_dbg(CONN
, "Processing connecting & no network found\n");
5021 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info
*cfg
)
5023 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5025 kfree(conn_info
->req_ie
);
5026 conn_info
->req_ie
= NULL
;
5027 conn_info
->req_ie_len
= 0;
5028 kfree(conn_info
->resp_ie
);
5029 conn_info
->resp_ie
= NULL
;
5030 conn_info
->resp_ie_len
= 0;
5033 static s32
brcmf_get_assoc_ies(struct brcmf_cfg80211_info
*cfg
,
5034 struct brcmf_if
*ifp
)
5036 struct brcmf_cfg80211_assoc_ielen_le
*assoc_info
;
5037 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5042 brcmf_clear_assoc_ies(cfg
);
5044 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_info",
5045 cfg
->extra_buf
, WL_ASSOC_INFO_MAX
);
5047 brcmf_err("could not get assoc info (%d)\n", err
);
5051 (struct brcmf_cfg80211_assoc_ielen_le
*)cfg
->extra_buf
;
5052 req_len
= le32_to_cpu(assoc_info
->req_len
);
5053 resp_len
= le32_to_cpu(assoc_info
->resp_len
);
5055 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_req_ies",
5059 brcmf_err("could not get assoc req (%d)\n", err
);
5062 conn_info
->req_ie_len
= req_len
;
5064 kmemdup(cfg
->extra_buf
, conn_info
->req_ie_len
,
5067 conn_info
->req_ie_len
= 0;
5068 conn_info
->req_ie
= NULL
;
5071 err
= brcmf_fil_iovar_data_get(ifp
, "assoc_resp_ies",
5075 brcmf_err("could not get assoc resp (%d)\n", err
);
5078 conn_info
->resp_ie_len
= resp_len
;
5079 conn_info
->resp_ie
=
5080 kmemdup(cfg
->extra_buf
, conn_info
->resp_ie_len
,
5083 conn_info
->resp_ie_len
= 0;
5084 conn_info
->resp_ie
= NULL
;
5086 brcmf_dbg(CONN
, "req len (%d) resp len (%d)\n",
5087 conn_info
->req_ie_len
, conn_info
->resp_ie_len
);
5093 brcmf_bss_roaming_done(struct brcmf_cfg80211_info
*cfg
,
5094 struct net_device
*ndev
,
5095 const struct brcmf_event_msg
*e
)
5097 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5098 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5099 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5100 struct wiphy
*wiphy
= cfg_to_wiphy(cfg
);
5101 struct ieee80211_channel
*notify_channel
= NULL
;
5102 struct ieee80211_supported_band
*band
;
5103 struct brcmf_bss_info_le
*bi
;
5104 struct brcmu_chan ch
;
5109 brcmf_dbg(TRACE
, "Enter\n");
5111 brcmf_get_assoc_ies(cfg
, ifp
);
5112 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5113 brcmf_update_bss_info(cfg
, ifp
);
5115 buf
= kzalloc(WL_BSS_INFO_MAX
, GFP_KERNEL
);
5121 /* data sent to dongle has to be little endian */
5122 *(__le32
*)buf
= cpu_to_le32(WL_BSS_INFO_MAX
);
5123 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BSS_INFO
,
5124 buf
, WL_BSS_INFO_MAX
);
5129 bi
= (struct brcmf_bss_info_le
*)(buf
+ 4);
5130 ch
.chspec
= le16_to_cpu(bi
->chanspec
);
5131 cfg
->d11inf
.decchspec(&ch
);
5133 if (ch
.band
== BRCMU_CHAN_BAND_2G
)
5134 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
5136 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
5138 freq
= ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
5139 notify_channel
= ieee80211_get_channel(wiphy
, freq
);
5143 cfg80211_roamed(ndev
, notify_channel
, (u8
*)profile
->bssid
,
5144 conn_info
->req_ie
, conn_info
->req_ie_len
,
5145 conn_info
->resp_ie
, conn_info
->resp_ie_len
, GFP_KERNEL
);
5146 brcmf_dbg(CONN
, "Report roaming result\n");
5148 set_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
);
5149 brcmf_dbg(TRACE
, "Exit\n");
5154 brcmf_bss_connect_done(struct brcmf_cfg80211_info
*cfg
,
5155 struct net_device
*ndev
, const struct brcmf_event_msg
*e
,
5158 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5159 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5160 struct brcmf_cfg80211_connect_info
*conn_info
= cfg_to_conn(cfg
);
5162 brcmf_dbg(TRACE
, "Enter\n");
5164 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5165 &ifp
->vif
->sme_state
)) {
5167 brcmf_get_assoc_ies(cfg
, ifp
);
5168 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5169 brcmf_update_bss_info(cfg
, ifp
);
5170 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
5171 &ifp
->vif
->sme_state
);
5173 cfg80211_connect_result(ndev
,
5174 (u8
*)profile
->bssid
,
5176 conn_info
->req_ie_len
,
5178 conn_info
->resp_ie_len
,
5179 completed
? WLAN_STATUS_SUCCESS
:
5180 WLAN_STATUS_AUTH_TIMEOUT
,
5182 brcmf_dbg(CONN
, "Report connect result - connection %s\n",
5183 completed
? "succeeded" : "failed");
5185 brcmf_dbg(TRACE
, "Exit\n");
5190 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info
*cfg
,
5191 struct net_device
*ndev
,
5192 const struct brcmf_event_msg
*e
, void *data
)
5194 struct brcmf_if
*ifp
= netdev_priv(ndev
);
5195 static int generation
;
5196 u32 event
= e
->event_code
;
5197 u32 reason
= e
->reason
;
5198 struct station_info sinfo
;
5200 brcmf_dbg(CONN
, "event %d, reason %d\n", event
, reason
);
5201 if (event
== BRCMF_E_LINK
&& reason
== BRCMF_E_REASON_LINK_BSSCFG_DIS
&&
5202 ndev
!= cfg_to_ndev(cfg
)) {
5203 brcmf_dbg(CONN
, "AP mode link down\n");
5204 complete(&cfg
->vif_disabled
);
5206 brcmf_remove_interface(ifp
);
5210 if (((event
== BRCMF_E_ASSOC_IND
) || (event
== BRCMF_E_REASSOC_IND
)) &&
5211 (reason
== BRCMF_E_STATUS_SUCCESS
)) {
5212 memset(&sinfo
, 0, sizeof(sinfo
));
5214 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5217 sinfo
.assoc_req_ies
= data
;
5218 sinfo
.assoc_req_ies_len
= e
->datalen
;
5220 sinfo
.generation
= generation
;
5221 cfg80211_new_sta(ndev
, e
->addr
, &sinfo
, GFP_KERNEL
);
5222 } else if ((event
== BRCMF_E_DISASSOC_IND
) ||
5223 (event
== BRCMF_E_DEAUTH_IND
) ||
5224 (event
== BRCMF_E_DEAUTH
)) {
5225 cfg80211_del_sta(ndev
, e
->addr
, GFP_KERNEL
);
5231 brcmf_notify_connect_status(struct brcmf_if
*ifp
,
5232 const struct brcmf_event_msg
*e
, void *data
)
5234 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5235 struct net_device
*ndev
= ifp
->ndev
;
5236 struct brcmf_cfg80211_profile
*profile
= &ifp
->vif
->profile
;
5237 struct ieee80211_channel
*chan
;
5240 if ((e
->event_code
== BRCMF_E_DEAUTH
) ||
5241 (e
->event_code
== BRCMF_E_DEAUTH_IND
) ||
5242 (e
->event_code
== BRCMF_E_DISASSOC_IND
) ||
5243 ((e
->event_code
== BRCMF_E_LINK
) && (!e
->flags
))) {
5244 brcmf_proto_delete_peer(ifp
->drvr
, ifp
->ifidx
, (u8
*)e
->addr
);
5247 if (brcmf_is_apmode(ifp
->vif
)) {
5248 err
= brcmf_notify_connect_status_ap(cfg
, ndev
, e
, data
);
5249 } else if (brcmf_is_linkup(e
)) {
5250 brcmf_dbg(CONN
, "Linkup\n");
5251 if (brcmf_is_ibssmode(ifp
->vif
)) {
5252 brcmf_inform_ibss(cfg
, ndev
, e
->addr
);
5253 chan
= ieee80211_get_channel(cfg
->wiphy
, cfg
->channel
);
5254 memcpy(profile
->bssid
, e
->addr
, ETH_ALEN
);
5255 cfg80211_ibss_joined(ndev
, e
->addr
, chan
, GFP_KERNEL
);
5256 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5257 &ifp
->vif
->sme_state
);
5258 set_bit(BRCMF_VIF_STATUS_CONNECTED
,
5259 &ifp
->vif
->sme_state
);
5261 brcmf_bss_connect_done(cfg
, ndev
, e
, true);
5262 brcmf_net_setcarrier(ifp
, true);
5263 } else if (brcmf_is_linkdown(e
)) {
5264 brcmf_dbg(CONN
, "Linkdown\n");
5265 if (!brcmf_is_ibssmode(ifp
->vif
)) {
5266 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
5268 brcmf_link_down(ifp
->vif
, brcmf_map_fw_linkdown_reason(e
));
5269 brcmf_init_prof(ndev_to_prof(ndev
));
5270 if (ndev
!= cfg_to_ndev(cfg
))
5271 complete(&cfg
->vif_disabled
);
5272 brcmf_net_setcarrier(ifp
, false);
5273 } else if (brcmf_is_nonetwork(cfg
, e
)) {
5274 if (brcmf_is_ibssmode(ifp
->vif
))
5275 clear_bit(BRCMF_VIF_STATUS_CONNECTING
,
5276 &ifp
->vif
->sme_state
);
5278 brcmf_bss_connect_done(cfg
, ndev
, e
, false);
5285 brcmf_notify_roaming_status(struct brcmf_if
*ifp
,
5286 const struct brcmf_event_msg
*e
, void *data
)
5288 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5289 u32 event
= e
->event_code
;
5290 u32 status
= e
->status
;
5292 if (event
== BRCMF_E_ROAM
&& status
== BRCMF_E_STATUS_SUCCESS
) {
5293 if (test_bit(BRCMF_VIF_STATUS_CONNECTED
, &ifp
->vif
->sme_state
))
5294 brcmf_bss_roaming_done(cfg
, ifp
->ndev
, e
);
5296 brcmf_bss_connect_done(cfg
, ifp
->ndev
, e
, true);
5303 brcmf_notify_mic_status(struct brcmf_if
*ifp
,
5304 const struct brcmf_event_msg
*e
, void *data
)
5306 u16 flags
= e
->flags
;
5307 enum nl80211_key_type key_type
;
5309 if (flags
& BRCMF_EVENT_MSG_GROUP
)
5310 key_type
= NL80211_KEYTYPE_GROUP
;
5312 key_type
= NL80211_KEYTYPE_PAIRWISE
;
5314 cfg80211_michael_mic_failure(ifp
->ndev
, (u8
*)&e
->addr
, key_type
, -1,
5320 static s32
brcmf_notify_vif_event(struct brcmf_if
*ifp
,
5321 const struct brcmf_event_msg
*e
, void *data
)
5323 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
5324 struct brcmf_if_event
*ifevent
= (struct brcmf_if_event
*)data
;
5325 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
5326 struct brcmf_cfg80211_vif
*vif
;
5328 brcmf_dbg(TRACE
, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
5329 ifevent
->action
, ifevent
->flags
, ifevent
->ifidx
,
5330 ifevent
->bsscfgidx
);
5332 mutex_lock(&event
->vif_event_lock
);
5333 event
->action
= ifevent
->action
;
5336 switch (ifevent
->action
) {
5337 case BRCMF_E_IF_ADD
:
5338 /* waiting process may have timed out */
5339 if (!cfg
->vif_event
.vif
) {
5340 mutex_unlock(&event
->vif_event_lock
);
5347 vif
->wdev
.netdev
= ifp
->ndev
;
5348 ifp
->ndev
->ieee80211_ptr
= &vif
->wdev
;
5349 SET_NETDEV_DEV(ifp
->ndev
, wiphy_dev(cfg
->wiphy
));
5351 mutex_unlock(&event
->vif_event_lock
);
5352 wake_up(&event
->vif_wq
);
5355 case BRCMF_E_IF_DEL
:
5356 mutex_unlock(&event
->vif_event_lock
);
5357 /* event may not be upon user request */
5358 if (brcmf_cfg80211_vif_event_armed(cfg
))
5359 wake_up(&event
->vif_wq
);
5362 case BRCMF_E_IF_CHANGE
:
5363 mutex_unlock(&event
->vif_event_lock
);
5364 wake_up(&event
->vif_wq
);
5368 mutex_unlock(&event
->vif_event_lock
);
5374 static void brcmf_init_conf(struct brcmf_cfg80211_conf
*conf
)
5376 conf
->frag_threshold
= (u32
)-1;
5377 conf
->rts_threshold
= (u32
)-1;
5378 conf
->retry_short
= (u32
)-1;
5379 conf
->retry_long
= (u32
)-1;
5382 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info
*cfg
)
5384 brcmf_fweh_register(cfg
->pub
, BRCMF_E_LINK
,
5385 brcmf_notify_connect_status
);
5386 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH_IND
,
5387 brcmf_notify_connect_status
);
5388 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DEAUTH
,
5389 brcmf_notify_connect_status
);
5390 brcmf_fweh_register(cfg
->pub
, BRCMF_E_DISASSOC_IND
,
5391 brcmf_notify_connect_status
);
5392 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ASSOC_IND
,
5393 brcmf_notify_connect_status
);
5394 brcmf_fweh_register(cfg
->pub
, BRCMF_E_REASSOC_IND
,
5395 brcmf_notify_connect_status
);
5396 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ROAM
,
5397 brcmf_notify_roaming_status
);
5398 brcmf_fweh_register(cfg
->pub
, BRCMF_E_MIC_ERROR
,
5399 brcmf_notify_mic_status
);
5400 brcmf_fweh_register(cfg
->pub
, BRCMF_E_SET_SSID
,
5401 brcmf_notify_connect_status
);
5402 brcmf_fweh_register(cfg
->pub
, BRCMF_E_PFN_NET_FOUND
,
5403 brcmf_notify_sched_scan_results
);
5404 brcmf_fweh_register(cfg
->pub
, BRCMF_E_IF
,
5405 brcmf_notify_vif_event
);
5406 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_PROBEREQ_MSG
,
5407 brcmf_p2p_notify_rx_mgmt_p2p_probereq
);
5408 brcmf_fweh_register(cfg
->pub
, BRCMF_E_P2P_DISC_LISTEN_COMPLETE
,
5409 brcmf_p2p_notify_listen_complete
);
5410 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_RX
,
5411 brcmf_p2p_notify_action_frame_rx
);
5412 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_COMPLETE
,
5413 brcmf_p2p_notify_action_tx_complete
);
5414 brcmf_fweh_register(cfg
->pub
, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE
,
5415 brcmf_p2p_notify_action_tx_complete
);
5418 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info
*cfg
)
5422 kfree(cfg
->escan_ioctl_buf
);
5423 cfg
->escan_ioctl_buf
= NULL
;
5424 kfree(cfg
->extra_buf
);
5425 cfg
->extra_buf
= NULL
;
5426 kfree(cfg
->wowl
.nd
);
5427 cfg
->wowl
.nd
= NULL
;
5428 kfree(cfg
->wowl
.nd_info
);
5429 cfg
->wowl
.nd_info
= NULL
;
5432 static s32
brcmf_init_priv_mem(struct brcmf_cfg80211_info
*cfg
)
5434 cfg
->conf
= kzalloc(sizeof(*cfg
->conf
), GFP_KERNEL
);
5436 goto init_priv_mem_out
;
5437 cfg
->escan_ioctl_buf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5438 if (!cfg
->escan_ioctl_buf
)
5439 goto init_priv_mem_out
;
5440 cfg
->extra_buf
= kzalloc(WL_EXTRA_BUF_MAX
, GFP_KERNEL
);
5441 if (!cfg
->extra_buf
)
5442 goto init_priv_mem_out
;
5443 cfg
->wowl
.nd
= kzalloc(sizeof(*cfg
->wowl
.nd
) + sizeof(u32
), GFP_KERNEL
);
5445 goto init_priv_mem_out
;
5446 cfg
->wowl
.nd_info
= kzalloc(sizeof(*cfg
->wowl
.nd_info
) +
5447 sizeof(struct cfg80211_wowlan_nd_match
*),
5449 if (!cfg
->wowl
.nd_info
)
5450 goto init_priv_mem_out
;
5455 brcmf_deinit_priv_mem(cfg
);
5460 static s32
wl_init_priv(struct brcmf_cfg80211_info
*cfg
)
5464 cfg
->scan_request
= NULL
;
5465 cfg
->pwr_save
= true;
5466 cfg
->active_scan
= true; /* we do active scan per default */
5467 cfg
->dongle_up
= false; /* dongle is not up yet */
5468 err
= brcmf_init_priv_mem(cfg
);
5471 brcmf_register_event_handlers(cfg
);
5472 mutex_init(&cfg
->usr_sync
);
5473 brcmf_init_escan(cfg
);
5474 brcmf_init_conf(cfg
->conf
);
5475 init_completion(&cfg
->vif_disabled
);
5479 static void wl_deinit_priv(struct brcmf_cfg80211_info
*cfg
)
5481 cfg
->dongle_up
= false; /* dongle down */
5482 brcmf_abort_scanning(cfg
);
5483 brcmf_deinit_priv_mem(cfg
);
5486 static void init_vif_event(struct brcmf_cfg80211_vif_event
*event
)
5488 init_waitqueue_head(&event
->vif_wq
);
5489 mutex_init(&event
->vif_event_lock
);
5492 static s32
brcmf_dongle_roam(struct brcmf_if
*ifp
)
5496 __le32 roamtrigger
[2];
5497 __le32 roam_delta
[2];
5499 /* Configure beacon timeout value based upon roaming setting */
5500 if (ifp
->drvr
->settings
->roamoff
)
5501 bcn_timeout
= BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF
;
5503 bcn_timeout
= BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON
;
5504 err
= brcmf_fil_iovar_int_set(ifp
, "bcn_timeout", bcn_timeout
);
5506 brcmf_err("bcn_timeout error (%d)\n", err
);
5507 goto roam_setup_done
;
5510 /* Enable/Disable built-in roaming to allow supplicant to take care of
5513 brcmf_dbg(INFO
, "Internal Roaming = %s\n",
5514 ifp
->drvr
->settings
->roamoff
? "Off" : "On");
5515 err
= brcmf_fil_iovar_int_set(ifp
, "roam_off",
5516 ifp
->drvr
->settings
->roamoff
);
5518 brcmf_err("roam_off error (%d)\n", err
);
5519 goto roam_setup_done
;
5522 roamtrigger
[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL
);
5523 roamtrigger
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5524 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_TRIGGER
,
5525 (void *)roamtrigger
, sizeof(roamtrigger
));
5527 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err
);
5528 goto roam_setup_done
;
5531 roam_delta
[0] = cpu_to_le32(WL_ROAM_DELTA
);
5532 roam_delta
[1] = cpu_to_le32(BRCM_BAND_ALL
);
5533 err
= brcmf_fil_cmd_data_set(ifp
, BRCMF_C_SET_ROAM_DELTA
,
5534 (void *)roam_delta
, sizeof(roam_delta
));
5536 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err
);
5537 goto roam_setup_done
;
5545 brcmf_dongle_scantime(struct brcmf_if
*ifp
)
5549 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_CHANNEL_TIME
,
5550 BRCMF_SCAN_CHANNEL_TIME
);
5552 brcmf_err("Scan assoc time error (%d)\n", err
);
5553 goto dongle_scantime_out
;
5555 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_UNASSOC_TIME
,
5556 BRCMF_SCAN_UNASSOC_TIME
);
5558 brcmf_err("Scan unassoc time error (%d)\n", err
);
5559 goto dongle_scantime_out
;
5562 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_SCAN_PASSIVE_TIME
,
5563 BRCMF_SCAN_PASSIVE_TIME
);
5565 brcmf_err("Scan passive time error (%d)\n", err
);
5566 goto dongle_scantime_out
;
5569 dongle_scantime_out
:
5573 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel
*channel
,
5574 struct brcmu_chan
*ch
)
5578 ht40_flag
= channel
->flags
& IEEE80211_CHAN_NO_HT40
;
5579 if (ch
->sb
== BRCMU_CHAN_SB_U
) {
5580 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5581 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40
;
5582 channel
->flags
|= IEEE80211_CHAN_NO_HT40PLUS
;
5584 /* It should be one of
5585 * IEEE80211_CHAN_NO_HT40 or
5586 * IEEE80211_CHAN_NO_HT40PLUS
5588 channel
->flags
&= ~IEEE80211_CHAN_NO_HT40
;
5589 if (ht40_flag
== IEEE80211_CHAN_NO_HT40
)
5590 channel
->flags
|= IEEE80211_CHAN_NO_HT40MINUS
;
5594 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info
*cfg
,
5597 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5598 struct ieee80211_supported_band
*band
;
5599 struct ieee80211_channel
*channel
;
5600 struct wiphy
*wiphy
;
5601 struct brcmf_chanspec_list
*list
;
5602 struct brcmu_chan ch
;
5610 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5615 list
= (struct brcmf_chanspec_list
*)pbuf
;
5617 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5620 brcmf_err("get chanspecs error (%d)\n", err
);
5624 wiphy
= cfg_to_wiphy(cfg
);
5625 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
5627 for (i
= 0; i
< band
->n_channels
; i
++)
5628 band
->channels
[i
].flags
= IEEE80211_CHAN_DISABLED
;
5629 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
5631 for (i
= 0; i
< band
->n_channels
; i
++)
5632 band
->channels
[i
].flags
= IEEE80211_CHAN_DISABLED
;
5634 total
= le32_to_cpu(list
->count
);
5635 for (i
= 0; i
< total
; i
++) {
5636 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5637 cfg
->d11inf
.decchspec(&ch
);
5639 if (ch
.band
== BRCMU_CHAN_BAND_2G
) {
5640 band
= wiphy
->bands
[IEEE80211_BAND_2GHZ
];
5641 } else if (ch
.band
== BRCMU_CHAN_BAND_5G
) {
5642 band
= wiphy
->bands
[IEEE80211_BAND_5GHZ
];
5644 brcmf_err("Invalid channel Spec. 0x%x.\n", ch
.chspec
);
5649 if (!(bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) &&
5650 ch
.bw
== BRCMU_CHAN_BW_40
)
5652 if (!(bw_cap
[band
->band
] & WLC_BW_80MHZ_BIT
) &&
5653 ch
.bw
== BRCMU_CHAN_BW_80
)
5656 channel
= band
->channels
;
5657 index
= band
->n_channels
;
5658 for (j
= 0; j
< band
->n_channels
; j
++) {
5659 if (channel
[j
].hw_value
== ch
.chnum
) {
5664 channel
[index
].center_freq
=
5665 ieee80211_channel_to_frequency(ch
.chnum
, band
->band
);
5666 channel
[index
].hw_value
= ch
.chnum
;
5668 /* assuming the chanspecs order is HT20,
5669 * HT40 upper, HT40 lower, and VHT80.
5671 if (ch
.bw
== BRCMU_CHAN_BW_80
) {
5672 channel
[index
].flags
&= ~IEEE80211_CHAN_NO_80MHZ
;
5673 } else if (ch
.bw
== BRCMU_CHAN_BW_40
) {
5674 brcmf_update_bw40_channel_flag(&channel
[index
], &ch
);
5676 /* enable the channel and disable other bandwidths
5677 * for now as mentioned order assure they are enabled
5678 * for subsequent chanspecs.
5680 channel
[index
].flags
= IEEE80211_CHAN_NO_HT40
|
5681 IEEE80211_CHAN_NO_80MHZ
;
5682 ch
.bw
= BRCMU_CHAN_BW_20
;
5683 cfg
->d11inf
.encchspec(&ch
);
5684 chaninfo
= ch
.chspec
;
5685 err
= brcmf_fil_bsscfg_int_get(ifp
, "per_chan_info",
5688 if (chaninfo
& WL_CHAN_RADAR
)
5689 channel
[index
].flags
|=
5690 (IEEE80211_CHAN_RADAR
|
5691 IEEE80211_CHAN_NO_IR
);
5692 if (chaninfo
& WL_CHAN_PASSIVE
)
5693 channel
[index
].flags
|=
5694 IEEE80211_CHAN_NO_IR
;
5704 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info
*cfg
)
5706 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5707 struct ieee80211_supported_band
*band
;
5708 struct brcmf_fil_bwcap_le band_bwcap
;
5709 struct brcmf_chanspec_list
*list
;
5713 struct brcmu_chan ch
;
5717 /* verify support for bw_cap command */
5719 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &val
);
5722 /* only set 2G bandwidth using bw_cap command */
5723 band_bwcap
.band
= cpu_to_le32(WLC_BAND_2G
);
5724 band_bwcap
.bw_cap
= cpu_to_le32(WLC_BW_CAP_40MHZ
);
5725 err
= brcmf_fil_iovar_data_set(ifp
, "bw_cap", &band_bwcap
,
5726 sizeof(band_bwcap
));
5728 brcmf_dbg(INFO
, "fallback to mimo_bw_cap\n");
5729 val
= WLC_N_BW_40ALL
;
5730 err
= brcmf_fil_iovar_int_set(ifp
, "mimo_bw_cap", val
);
5734 /* update channel info in 2G band */
5735 pbuf
= kzalloc(BRCMF_DCMD_MEDLEN
, GFP_KERNEL
);
5740 ch
.band
= BRCMU_CHAN_BAND_2G
;
5741 ch
.bw
= BRCMU_CHAN_BW_40
;
5742 ch
.sb
= BRCMU_CHAN_SB_NONE
;
5744 cfg
->d11inf
.encchspec(&ch
);
5746 /* pass encoded chanspec in query */
5747 *(__le16
*)pbuf
= cpu_to_le16(ch
.chspec
);
5749 err
= brcmf_fil_iovar_data_get(ifp
, "chanspecs", pbuf
,
5752 brcmf_err("get chanspecs error (%d)\n", err
);
5757 band
= cfg_to_wiphy(cfg
)->bands
[IEEE80211_BAND_2GHZ
];
5758 list
= (struct brcmf_chanspec_list
*)pbuf
;
5759 num_chan
= le32_to_cpu(list
->count
);
5760 for (i
= 0; i
< num_chan
; i
++) {
5761 ch
.chspec
= (u16
)le32_to_cpu(list
->element
[i
]);
5762 cfg
->d11inf
.decchspec(&ch
);
5763 if (WARN_ON(ch
.band
!= BRCMU_CHAN_BAND_2G
))
5765 if (WARN_ON(ch
.bw
!= BRCMU_CHAN_BW_40
))
5767 for (j
= 0; j
< band
->n_channels
; j
++) {
5768 if (band
->channels
[j
].hw_value
== ch
.chnum
)
5771 if (WARN_ON(j
== band
->n_channels
))
5774 brcmf_update_bw40_channel_flag(&band
->channels
[j
], &ch
);
5781 static void brcmf_get_bwcap(struct brcmf_if
*ifp
, u32 bw_cap
[])
5783 u32 band
, mimo_bwcap
;
5787 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5789 bw_cap
[IEEE80211_BAND_2GHZ
] = band
;
5791 err
= brcmf_fil_iovar_int_get(ifp
, "bw_cap", &band
);
5793 bw_cap
[IEEE80211_BAND_5GHZ
] = band
;
5799 brcmf_dbg(INFO
, "fallback to mimo_bw_cap info\n");
5801 err
= brcmf_fil_iovar_int_get(ifp
, "mimo_bw_cap", &mimo_bwcap
);
5803 /* assume 20MHz if firmware does not give a clue */
5804 mimo_bwcap
= WLC_N_BW_20ALL
;
5806 switch (mimo_bwcap
) {
5807 case WLC_N_BW_40ALL
:
5808 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_40MHZ_BIT
;
5810 case WLC_N_BW_20IN2G_40IN5G
:
5811 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_40MHZ_BIT
;
5813 case WLC_N_BW_20ALL
:
5814 bw_cap
[IEEE80211_BAND_2GHZ
] |= WLC_BW_20MHZ_BIT
;
5815 bw_cap
[IEEE80211_BAND_5GHZ
] |= WLC_BW_20MHZ_BIT
;
5818 brcmf_err("invalid mimo_bw_cap value\n");
5822 static void brcmf_update_ht_cap(struct ieee80211_supported_band
*band
,
5823 u32 bw_cap
[2], u32 nchain
)
5825 band
->ht_cap
.ht_supported
= true;
5826 if (bw_cap
[band
->band
] & WLC_BW_40MHZ_BIT
) {
5827 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_40
;
5828 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
5830 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_SGI_20
;
5831 band
->ht_cap
.cap
|= IEEE80211_HT_CAP_DSSSCCK40
;
5832 band
->ht_cap
.ampdu_factor
= IEEE80211_HT_MAX_AMPDU_64K
;
5833 band
->ht_cap
.ampdu_density
= IEEE80211_HT_MPDU_DENSITY_16
;
5834 memset(band
->ht_cap
.mcs
.rx_mask
, 0xff, nchain
);
5835 band
->ht_cap
.mcs
.tx_params
= IEEE80211_HT_MCS_TX_DEFINED
;
5838 static __le16
brcmf_get_mcs_map(u32 nchain
, enum ieee80211_vht_mcs_support supp
)
5843 for (i
= 0, mcs_map
= 0xFFFF; i
< nchain
; i
++)
5844 mcs_map
= (mcs_map
<< 2) | supp
;
5846 return cpu_to_le16(mcs_map
);
5849 static void brcmf_update_vht_cap(struct ieee80211_supported_band
*band
,
5850 u32 bw_cap
[2], u32 nchain
, u32 txstreams
,
5851 u32 txbf_bfe_cap
, u32 txbf_bfr_cap
)
5855 /* not allowed in 2.4G band */
5856 if (band
->band
== IEEE80211_BAND_2GHZ
)
5859 band
->vht_cap
.vht_supported
= true;
5860 /* 80MHz is mandatory */
5861 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SHORT_GI_80
;
5862 if (bw_cap
[band
->band
] & WLC_BW_160MHZ_BIT
) {
5863 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ
;
5864 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SHORT_GI_160
;
5866 /* all support 256-QAM */
5867 mcs_map
= brcmf_get_mcs_map(nchain
, IEEE80211_VHT_MCS_SUPPORT_0_9
);
5868 band
->vht_cap
.vht_mcs
.rx_mcs_map
= mcs_map
;
5869 band
->vht_cap
.vht_mcs
.tx_mcs_map
= mcs_map
;
5871 /* Beamforming support information */
5872 if (txbf_bfe_cap
& BRCMF_TXBF_SU_BFE_CAP
)
5873 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE
;
5874 if (txbf_bfe_cap
& BRCMF_TXBF_MU_BFE_CAP
)
5875 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE
;
5876 if (txbf_bfr_cap
& BRCMF_TXBF_SU_BFR_CAP
)
5877 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE
;
5878 if (txbf_bfr_cap
& BRCMF_TXBF_MU_BFR_CAP
)
5879 band
->vht_cap
.cap
|= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE
;
5881 if ((txbf_bfe_cap
|| txbf_bfr_cap
) && (txstreams
> 1)) {
5882 band
->vht_cap
.cap
|=
5883 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT
);
5884 band
->vht_cap
.cap
|= ((txstreams
- 1) <<
5885 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT
);
5886 band
->vht_cap
.cap
|=
5887 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB
;
5891 static int brcmf_setup_wiphybands(struct wiphy
*wiphy
)
5893 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
5894 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
5897 u32 bw_cap
[2] = { WLC_BW_20MHZ_BIT
, WLC_BW_20MHZ_BIT
};
5902 struct ieee80211_supported_band
*band
;
5904 u32 txbf_bfe_cap
= 0;
5905 u32 txbf_bfr_cap
= 0;
5907 (void)brcmf_fil_iovar_int_get(ifp
, "vhtmode", &vhtmode
);
5908 err
= brcmf_fil_iovar_int_get(ifp
, "nmode", &nmode
);
5910 brcmf_err("nmode error (%d)\n", err
);
5912 brcmf_get_bwcap(ifp
, bw_cap
);
5914 brcmf_dbg(INFO
, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5915 nmode
, vhtmode
, bw_cap
[IEEE80211_BAND_2GHZ
],
5916 bw_cap
[IEEE80211_BAND_5GHZ
]);
5918 err
= brcmf_fil_iovar_int_get(ifp
, "rxchain", &rxchain
);
5920 brcmf_err("rxchain error (%d)\n", err
);
5923 for (nchain
= 0; rxchain
; nchain
++)
5924 rxchain
= rxchain
& (rxchain
- 1);
5926 brcmf_dbg(INFO
, "nchain=%d\n", nchain
);
5928 err
= brcmf_construct_chaninfo(cfg
, bw_cap
);
5930 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err
);
5935 (void)brcmf_fil_iovar_int_get(ifp
, "txstreams", &txstreams
);
5936 (void)brcmf_fil_iovar_int_get(ifp
, "txbf_bfe_cap",
5938 (void)brcmf_fil_iovar_int_get(ifp
, "txbf_bfr_cap",
5942 wiphy
= cfg_to_wiphy(cfg
);
5943 for (i
= 0; i
< ARRAY_SIZE(wiphy
->bands
); i
++) {
5944 band
= wiphy
->bands
[i
];
5949 brcmf_update_ht_cap(band
, bw_cap
, nchain
);
5951 brcmf_update_vht_cap(band
, bw_cap
, nchain
, txstreams
,
5952 txbf_bfe_cap
, txbf_bfr_cap
);
5958 static const struct ieee80211_txrx_stypes
5959 brcmf_txrx_stypes
[NUM_NL80211_IFTYPES
] = {
5960 [NL80211_IFTYPE_STATION
] = {
5962 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
5963 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
5965 [NL80211_IFTYPE_P2P_CLIENT
] = {
5967 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
5968 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
5970 [NL80211_IFTYPE_P2P_GO
] = {
5972 .rx
= BIT(IEEE80211_STYPE_ASSOC_REQ
>> 4) |
5973 BIT(IEEE80211_STYPE_REASSOC_REQ
>> 4) |
5974 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4) |
5975 BIT(IEEE80211_STYPE_DISASSOC
>> 4) |
5976 BIT(IEEE80211_STYPE_AUTH
>> 4) |
5977 BIT(IEEE80211_STYPE_DEAUTH
>> 4) |
5978 BIT(IEEE80211_STYPE_ACTION
>> 4)
5980 [NL80211_IFTYPE_P2P_DEVICE
] = {
5982 .rx
= BIT(IEEE80211_STYPE_ACTION
>> 4) |
5983 BIT(IEEE80211_STYPE_PROBE_REQ
>> 4)
5988 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5990 * @wiphy: wiphy object.
5991 * @ifp: interface object needed for feat module api.
5993 * The interface modes and combinations are determined dynamically here
5994 * based on firmware functionality.
5996 * no p2p and no mbss:
5998 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6002 * #STA <= 1, #AP <= 1, channels = 1, 2 total
6003 * #AP <= 4, matching BI, channels = 1, 4 total
6005 * p2p, no mchan, and mbss:
6007 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
6008 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6009 * #AP <= 4, matching BI, channels = 1, 4 total
6011 * p2p, mchan, and mbss:
6013 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
6014 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
6015 * #AP <= 4, matching BI, channels = 1, 4 total
6017 static int brcmf_setup_ifmodes(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6019 struct ieee80211_iface_combination
*combo
= NULL
;
6020 struct ieee80211_iface_limit
*c0_limits
= NULL
;
6021 struct ieee80211_iface_limit
*p2p_limits
= NULL
;
6022 struct ieee80211_iface_limit
*mbss_limits
= NULL
;
6026 mbss
= brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MBSS
);
6027 p2p
= brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_P2P
);
6029 n_combos
= 1 + !!p2p
+ !!mbss
;
6030 combo
= kcalloc(n_combos
, sizeof(*combo
), GFP_KERNEL
);
6034 c0_limits
= kcalloc(p2p
? 3 : 2, sizeof(*c0_limits
), GFP_KERNEL
);
6039 p2p_limits
= kcalloc(4, sizeof(*p2p_limits
), GFP_KERNEL
);
6045 mbss_limits
= kcalloc(1, sizeof(*mbss_limits
), GFP_KERNEL
);
6050 wiphy
->interface_modes
= BIT(NL80211_IFTYPE_STATION
) |
6051 BIT(NL80211_IFTYPE_ADHOC
) |
6052 BIT(NL80211_IFTYPE_AP
);
6056 combo
[c
].num_different_channels
= 1;
6057 c0_limits
[i
].max
= 1;
6058 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_STATION
);
6060 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_MCHAN
))
6061 combo
[c
].num_different_channels
= 2;
6062 wiphy
->interface_modes
|= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
6063 BIT(NL80211_IFTYPE_P2P_GO
) |
6064 BIT(NL80211_IFTYPE_P2P_DEVICE
);
6065 c0_limits
[i
].max
= 1;
6066 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_DEVICE
);
6067 c0_limits
[i
].max
= 1;
6068 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_CLIENT
) |
6069 BIT(NL80211_IFTYPE_P2P_GO
);
6071 c0_limits
[i
].max
= 1;
6072 c0_limits
[i
++].types
= BIT(NL80211_IFTYPE_AP
);
6074 combo
[c
].max_interfaces
= i
;
6075 combo
[c
].n_limits
= i
;
6076 combo
[c
].limits
= c0_limits
;
6081 combo
[c
].num_different_channels
= 1;
6082 p2p_limits
[i
].max
= 1;
6083 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_STATION
);
6084 p2p_limits
[i
].max
= 1;
6085 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_AP
);
6086 p2p_limits
[i
].max
= 1;
6087 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_CLIENT
);
6088 p2p_limits
[i
].max
= 1;
6089 p2p_limits
[i
++].types
= BIT(NL80211_IFTYPE_P2P_DEVICE
);
6090 combo
[c
].max_interfaces
= i
;
6091 combo
[c
].n_limits
= i
;
6092 combo
[c
].limits
= p2p_limits
;
6097 combo
[c
].beacon_int_infra_match
= true;
6098 combo
[c
].num_different_channels
= 1;
6099 mbss_limits
[0].max
= 4;
6100 mbss_limits
[0].types
= BIT(NL80211_IFTYPE_AP
);
6101 combo
[c
].max_interfaces
= 4;
6102 combo
[c
].n_limits
= 1;
6103 combo
[c
].limits
= mbss_limits
;
6105 wiphy
->n_iface_combinations
= n_combos
;
6106 wiphy
->iface_combinations
= combo
;
6117 static void brcmf_wiphy_pno_params(struct wiphy
*wiphy
)
6119 /* scheduled scan settings */
6120 wiphy
->max_sched_scan_ssids
= BRCMF_PNO_MAX_PFN_COUNT
;
6121 wiphy
->max_match_sets
= BRCMF_PNO_MAX_PFN_COUNT
;
6122 wiphy
->max_sched_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
6123 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_SCHED_SCAN
;
6127 static struct wiphy_wowlan_support brcmf_wowlan_support
= {
6128 .flags
= WIPHY_WOWLAN_MAGIC_PKT
| WIPHY_WOWLAN_DISCONNECT
,
6129 .n_patterns
= BRCMF_WOWL_MAXPATTERNS
,
6130 .pattern_max_len
= BRCMF_WOWL_MAXPATTERNSIZE
,
6131 .pattern_min_len
= 1,
6132 .max_pkt_offset
= 1500,
6136 static void brcmf_wiphy_wowl_params(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6139 struct brcmf_cfg80211_info
*cfg
= wiphy_to_cfg(wiphy
);
6143 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
)) {
6144 err
= brcmf_fil_iovar_int_get(ifp
, "wowl_cap", &wowl_cap
);
6146 if (wowl_cap
& BRCMF_WOWL_PFN_FOUND
) {
6147 brcmf_wowlan_support
.flags
|=
6148 WIPHY_WOWLAN_NET_DETECT
;
6149 init_waitqueue_head(&cfg
->wowl
.nd_data_wait
);
6153 wiphy
->wowlan
= &brcmf_wowlan_support
;
6157 static int brcmf_setup_wiphy(struct wiphy
*wiphy
, struct brcmf_if
*ifp
)
6159 struct brcmf_pub
*drvr
= ifp
->drvr
;
6160 const struct ieee80211_iface_combination
*combo
;
6161 struct ieee80211_supported_band
*band
;
6162 u16 max_interfaces
= 0;
6167 wiphy
->max_scan_ssids
= WL_NUM_SCAN_MAX
;
6168 wiphy
->max_scan_ie_len
= BRCMF_SCAN_IE_LEN_MAX
;
6169 wiphy
->max_num_pmkids
= BRCMF_MAXPMKID
;
6171 err
= brcmf_setup_ifmodes(wiphy
, ifp
);
6175 for (i
= 0, combo
= wiphy
->iface_combinations
;
6176 i
< wiphy
->n_iface_combinations
; i
++, combo
++) {
6177 max_interfaces
= max(max_interfaces
, combo
->max_interfaces
);
6180 for (i
= 0; i
< max_interfaces
&& i
< ARRAY_SIZE(drvr
->addresses
);
6182 u8
*addr
= drvr
->addresses
[i
].addr
;
6184 memcpy(addr
, drvr
->mac
, ETH_ALEN
);
6187 addr
[ETH_ALEN
- 1] ^= i
;
6190 wiphy
->addresses
= drvr
->addresses
;
6191 wiphy
->n_addresses
= i
;
6193 wiphy
->signal_type
= CFG80211_SIGNAL_TYPE_MBM
;
6194 wiphy
->cipher_suites
= __wl_cipher_suites
;
6195 wiphy
->n_cipher_suites
= ARRAY_SIZE(__wl_cipher_suites
);
6196 wiphy
->flags
|= WIPHY_FLAG_PS_ON_BY_DEFAULT
|
6197 WIPHY_FLAG_OFFCHAN_TX
|
6198 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL
;
6199 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_TDLS
))
6200 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_TDLS
;
6201 if (!ifp
->drvr
->settings
->roamoff
)
6202 wiphy
->flags
|= WIPHY_FLAG_SUPPORTS_FW_ROAM
;
6203 wiphy
->mgmt_stypes
= brcmf_txrx_stypes
;
6204 wiphy
->max_remain_on_channel_duration
= 5000;
6205 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_PNO
))
6206 brcmf_wiphy_pno_params(wiphy
);
6208 /* vendor commands/events support */
6209 wiphy
->vendor_commands
= brcmf_vendor_cmds
;
6210 wiphy
->n_vendor_commands
= BRCMF_VNDR_CMDS_LAST
- 1;
6212 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_WOWL
))
6213 brcmf_wiphy_wowl_params(wiphy
, ifp
);
6214 err
= brcmf_fil_cmd_data_get(ifp
, BRCMF_C_GET_BANDLIST
, &bandlist
,
6217 brcmf_err("could not obtain band info: err=%d\n", err
);
6220 /* first entry in bandlist is number of bands */
6221 n_bands
= le32_to_cpu(bandlist
[0]);
6222 for (i
= 1; i
<= n_bands
&& i
< ARRAY_SIZE(bandlist
); i
++) {
6223 if (bandlist
[i
] == cpu_to_le32(WLC_BAND_2G
)) {
6224 band
= kmemdup(&__wl_band_2ghz
, sizeof(__wl_band_2ghz
),
6229 band
->channels
= kmemdup(&__wl_2ghz_channels
,
6230 sizeof(__wl_2ghz_channels
),
6232 if (!band
->channels
) {
6237 band
->n_channels
= ARRAY_SIZE(__wl_2ghz_channels
);
6238 wiphy
->bands
[IEEE80211_BAND_2GHZ
] = band
;
6240 if (bandlist
[i
] == cpu_to_le32(WLC_BAND_5G
)) {
6241 band
= kmemdup(&__wl_band_5ghz
, sizeof(__wl_band_5ghz
),
6246 band
->channels
= kmemdup(&__wl_5ghz_channels
,
6247 sizeof(__wl_5ghz_channels
),
6249 if (!band
->channels
) {
6254 band
->n_channels
= ARRAY_SIZE(__wl_5ghz_channels
);
6255 wiphy
->bands
[IEEE80211_BAND_5GHZ
] = band
;
6258 err
= brcmf_setup_wiphybands(wiphy
);
6262 static s32
brcmf_config_dongle(struct brcmf_cfg80211_info
*cfg
)
6264 struct net_device
*ndev
;
6265 struct wireless_dev
*wdev
;
6266 struct brcmf_if
*ifp
;
6273 ndev
= cfg_to_ndev(cfg
);
6274 wdev
= ndev
->ieee80211_ptr
;
6275 ifp
= netdev_priv(ndev
);
6277 /* make sure RF is ready for work */
6278 brcmf_fil_cmd_int_set(ifp
, BRCMF_C_UP
, 0);
6280 brcmf_dongle_scantime(ifp
);
6282 power_mode
= cfg
->pwr_save
? PM_FAST
: PM_OFF
;
6283 err
= brcmf_fil_cmd_int_set(ifp
, BRCMF_C_SET_PM
, power_mode
);
6285 goto default_conf_out
;
6286 brcmf_dbg(INFO
, "power save set to %s\n",
6287 (power_mode
? "enabled" : "disabled"));
6289 err
= brcmf_dongle_roam(ifp
);
6291 goto default_conf_out
;
6292 err
= brcmf_cfg80211_change_iface(wdev
->wiphy
, ndev
, wdev
->iftype
,
6295 goto default_conf_out
;
6297 brcmf_configure_arp_offload(ifp
, true);
6299 cfg
->dongle_up
= true;
6306 static s32
__brcmf_cfg80211_up(struct brcmf_if
*ifp
)
6308 set_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
6310 return brcmf_config_dongle(ifp
->drvr
->config
);
6313 static s32
__brcmf_cfg80211_down(struct brcmf_if
*ifp
)
6315 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6318 * While going down, if associated with AP disassociate
6319 * from AP to save power
6321 if (check_vif_up(ifp
->vif
)) {
6322 brcmf_link_down(ifp
->vif
, WLAN_REASON_UNSPECIFIED
);
6324 /* Make sure WPA_Supplicant receives all the event
6325 generated due to DISASSOC call to the fw to keep
6326 the state fw and WPA_Supplicant state consistent
6331 brcmf_abort_scanning(cfg
);
6332 clear_bit(BRCMF_VIF_STATUS_READY
, &ifp
->vif
->sme_state
);
6337 s32
brcmf_cfg80211_up(struct net_device
*ndev
)
6339 struct brcmf_if
*ifp
= netdev_priv(ndev
);
6340 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6343 mutex_lock(&cfg
->usr_sync
);
6344 err
= __brcmf_cfg80211_up(ifp
);
6345 mutex_unlock(&cfg
->usr_sync
);
6350 s32
brcmf_cfg80211_down(struct net_device
*ndev
)
6352 struct brcmf_if
*ifp
= netdev_priv(ndev
);
6353 struct brcmf_cfg80211_info
*cfg
= ifp
->drvr
->config
;
6356 mutex_lock(&cfg
->usr_sync
);
6357 err
= __brcmf_cfg80211_down(ifp
);
6358 mutex_unlock(&cfg
->usr_sync
);
6363 enum nl80211_iftype
brcmf_cfg80211_get_iftype(struct brcmf_if
*ifp
)
6365 struct wireless_dev
*wdev
= &ifp
->vif
->wdev
;
6367 return wdev
->iftype
;
6370 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info
*cfg
,
6371 unsigned long state
)
6373 struct brcmf_cfg80211_vif
*vif
;
6375 list_for_each_entry(vif
, &cfg
->vif_list
, list
) {
6376 if (test_bit(state
, &vif
->sme_state
))
6382 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event
*event
,
6387 mutex_lock(&event
->vif_event_lock
);
6388 evt_action
= event
->action
;
6389 mutex_unlock(&event
->vif_event_lock
);
6390 return evt_action
== action
;
6393 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info
*cfg
,
6394 struct brcmf_cfg80211_vif
*vif
)
6396 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6398 mutex_lock(&event
->vif_event_lock
);
6401 mutex_unlock(&event
->vif_event_lock
);
6404 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info
*cfg
)
6406 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6409 mutex_lock(&event
->vif_event_lock
);
6410 armed
= event
->vif
!= NULL
;
6411 mutex_unlock(&event
->vif_event_lock
);
6415 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info
*cfg
,
6416 u8 action
, ulong timeout
)
6418 struct brcmf_cfg80211_vif_event
*event
= &cfg
->vif_event
;
6420 return wait_event_timeout(event
->vif_wq
,
6421 vif_event_equals(event
, action
), timeout
);
6424 static void brcmf_cfg80211_reg_notifier(struct wiphy
*wiphy
,
6425 struct regulatory_request
*req
)
6427 struct brcmf_cfg80211_info
*cfg
= wiphy_priv(wiphy
);
6428 struct brcmf_if
*ifp
= netdev_priv(cfg_to_ndev(cfg
));
6429 struct brcmf_fil_country_le ccreq
;
6432 brcmf_dbg(TRACE
, "enter: initiator=%d, alpha=%c%c\n", req
->initiator
,
6433 req
->alpha2
[0], req
->alpha2
[1]);
6435 /* ignore non-ISO3166 country codes */
6436 for (i
= 0; i
< sizeof(req
->alpha2
); i
++)
6437 if (req
->alpha2
[i
] < 'A' || req
->alpha2
[i
] > 'Z') {
6438 brcmf_err("not a ISO3166 code\n");
6441 memset(&ccreq
, 0, sizeof(ccreq
));
6442 ccreq
.rev
= cpu_to_le32(-1);
6443 memcpy(ccreq
.ccode
, req
->alpha2
, sizeof(req
->alpha2
));
6444 if (brcmf_fil_iovar_data_set(ifp
, "country", &ccreq
, sizeof(ccreq
))) {
6445 brcmf_err("firmware rejected country setting\n");
6448 brcmf_setup_wiphybands(wiphy
);
6451 static void brcmf_free_wiphy(struct wiphy
*wiphy
)
6458 if (wiphy
->iface_combinations
) {
6459 for (i
= 0; i
< wiphy
->n_iface_combinations
; i
++)
6460 kfree(wiphy
->iface_combinations
[i
].limits
);
6462 kfree(wiphy
->iface_combinations
);
6463 if (wiphy
->bands
[IEEE80211_BAND_2GHZ
]) {
6464 kfree(wiphy
->bands
[IEEE80211_BAND_2GHZ
]->channels
);
6465 kfree(wiphy
->bands
[IEEE80211_BAND_2GHZ
]);
6467 if (wiphy
->bands
[IEEE80211_BAND_5GHZ
]) {
6468 kfree(wiphy
->bands
[IEEE80211_BAND_5GHZ
]->channels
);
6469 kfree(wiphy
->bands
[IEEE80211_BAND_5GHZ
]);
6474 struct brcmf_cfg80211_info
*brcmf_cfg80211_attach(struct brcmf_pub
*drvr
,
6475 struct device
*busdev
,
6478 struct net_device
*ndev
= brcmf_get_ifp(drvr
, 0)->ndev
;
6479 struct brcmf_cfg80211_info
*cfg
;
6480 struct wiphy
*wiphy
;
6481 struct brcmf_cfg80211_vif
*vif
;
6482 struct brcmf_if
*ifp
;
6488 brcmf_err("ndev is invalid\n");
6492 ifp
= netdev_priv(ndev
);
6493 wiphy
= wiphy_new(&wl_cfg80211_ops
, sizeof(struct brcmf_cfg80211_info
));
6495 brcmf_err("Could not allocate wiphy device\n");
6498 memcpy(wiphy
->perm_addr
, drvr
->mac
, ETH_ALEN
);
6499 set_wiphy_dev(wiphy
, busdev
);
6501 cfg
= wiphy_priv(wiphy
);
6504 init_vif_event(&cfg
->vif_event
);
6505 INIT_LIST_HEAD(&cfg
->vif_list
);
6507 vif
= brcmf_alloc_vif(cfg
, NL80211_IFTYPE_STATION
, false);
6512 vif
->wdev
.netdev
= ndev
;
6513 ndev
->ieee80211_ptr
= &vif
->wdev
;
6514 SET_NETDEV_DEV(ndev
, wiphy_dev(cfg
->wiphy
));
6516 err
= wl_init_priv(cfg
);
6518 brcmf_err("Failed to init iwm_priv (%d)\n", err
);
6519 brcmf_free_vif(vif
);
6524 /* determine d11 io type before wiphy setup */
6525 err
= brcmf_fil_cmd_int_get(ifp
, BRCMF_C_GET_VERSION
, &io_type
);
6527 brcmf_err("Failed to get D11 version (%d)\n", err
);
6530 cfg
->d11inf
.io_type
= (u8
)io_type
;
6531 brcmu_d11_attach(&cfg
->d11inf
);
6533 err
= brcmf_setup_wiphy(wiphy
, ifp
);
6537 brcmf_dbg(INFO
, "Registering custom regulatory\n");
6538 wiphy
->reg_notifier
= brcmf_cfg80211_reg_notifier
;
6539 wiphy
->regulatory_flags
|= REGULATORY_CUSTOM_REG
;
6540 wiphy_apply_custom_regulatory(wiphy
, &brcmf_regdom
);
6542 /* firmware defaults to 40MHz disabled in 2G band. We signal
6543 * cfg80211 here that we do and have it decide we can enable
6544 * it. But first check if device does support 2G operation.
6546 if (wiphy
->bands
[IEEE80211_BAND_2GHZ
]) {
6547 cap
= &wiphy
->bands
[IEEE80211_BAND_2GHZ
]->ht_cap
.cap
;
6548 *cap
|= IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
6550 err
= wiphy_register(wiphy
);
6552 brcmf_err("Could not register wiphy device (%d)\n", err
);
6556 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6557 * setup 40MHz in 2GHz band and enable OBSS scanning.
6559 if (cap
&& (*cap
& IEEE80211_HT_CAP_SUP_WIDTH_20_40
)) {
6560 err
= brcmf_enable_bw40_2g(cfg
);
6562 err
= brcmf_fil_iovar_int_set(ifp
, "obss_coex",
6563 BRCMF_OBSS_COEX_AUTO
);
6565 *cap
&= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40
;
6567 /* p2p might require that "if-events" get processed by fweh. So
6568 * activate the already registered event handlers now and activate
6569 * the rest when initialization has completed. drvr->config needs to
6570 * be assigned before activating events.
6573 err
= brcmf_fweh_activate_events(ifp
);
6575 brcmf_err("FWEH activation failed (%d)\n", err
);
6576 goto wiphy_unreg_out
;
6579 err
= brcmf_p2p_attach(cfg
, p2pdev_forced
);
6581 brcmf_err("P2P initilisation failed (%d)\n", err
);
6582 goto wiphy_unreg_out
;
6584 err
= brcmf_btcoex_attach(cfg
);
6586 brcmf_err("BT-coex initialisation failed (%d)\n", err
);
6587 brcmf_p2p_detach(&cfg
->p2p
);
6588 goto wiphy_unreg_out
;
6591 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_TDLS
)) {
6592 err
= brcmf_fil_iovar_int_set(ifp
, "tdls_enable", 1);
6594 brcmf_dbg(INFO
, "TDLS not enabled (%d)\n", err
);
6595 wiphy
->flags
&= ~WIPHY_FLAG_SUPPORTS_TDLS
;
6597 brcmf_fweh_register(cfg
->pub
, BRCMF_E_TDLS_PEER_EVENT
,
6598 brcmf_notify_tdls_peer_event
);
6602 /* (re-) activate FWEH event handling */
6603 err
= brcmf_fweh_activate_events(ifp
);
6605 brcmf_err("FWEH activation failed (%d)\n", err
);
6606 goto wiphy_unreg_out
;
6609 /* Fill in some of the advertised nl80211 supported features */
6610 if (brcmf_feat_is_enabled(ifp
, BRCMF_FEAT_SCAN_RANDOM_MAC
)) {
6611 wiphy
->features
|= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR
;
6613 if (wiphy
->wowlan
->flags
& WIPHY_WOWLAN_NET_DETECT
)
6614 wiphy
->features
|= NL80211_FEATURE_ND_RANDOM_MAC_ADDR
;
6621 wiphy_unregister(cfg
->wiphy
);
6623 wl_deinit_priv(cfg
);
6624 brcmf_free_vif(vif
);
6627 brcmf_free_wiphy(wiphy
);
6631 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info
*cfg
)
6636 brcmf_btcoex_detach(cfg
);
6637 wiphy_unregister(cfg
->wiphy
);
6638 wl_deinit_priv(cfg
);
6639 brcmf_free_wiphy(cfg
->wiphy
);