1 /*
2 * Copyright (c) 2010 Broadcom Corporation
3 *
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.
7 *
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.
15 */
16
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
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>
25
26 #include <brcmu_utils.h>
27 #include <defs.h>
28 #include <brcmu_wifi.h>
29 #include "core.h"
30 #include "debug.h"
31 #include "tracepoint.h"
32 #include "fwil_types.h"
33 #include "p2p.h"
34 #include "btcoex.h"
35 #include "cfg80211.h"
36 #include "feature.h"
37 #include "fwil.h"
38 #include "proto.h"
39 #include "vendor.h"
40 #include "bus.h"
41 #include "common.h"
42
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
54
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
60
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
65
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) */
71
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
77
78 #define VNDR_IE_CMD_LEN 4 /* length of the set command
79 * string :"add", "del" (+ NUL)
80 */
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
86
87 #define DOT11_MGMT_HDR_LEN 24 /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
89
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
93
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
96
check_vif_up(struct brcmf_cfg80211_vif * vif)97 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
98 {
99 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
100 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
101 vif->sme_state);
102 return false;
103 }
104 return true;
105 }
106
107 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
108 #define RATETAB_ENT(_rateid, _flags) \
109 { \
110 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
111 .hw_value = (_rateid), \
112 .flags = (_flags), \
113 }
114
115 static struct ieee80211_rate __wl_rates[] = {
116 RATETAB_ENT(BRCM_RATE_1M, 0),
117 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
118 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
119 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
120 RATETAB_ENT(BRCM_RATE_6M, 0),
121 RATETAB_ENT(BRCM_RATE_9M, 0),
122 RATETAB_ENT(BRCM_RATE_12M, 0),
123 RATETAB_ENT(BRCM_RATE_18M, 0),
124 RATETAB_ENT(BRCM_RATE_24M, 0),
125 RATETAB_ENT(BRCM_RATE_36M, 0),
126 RATETAB_ENT(BRCM_RATE_48M, 0),
127 RATETAB_ENT(BRCM_RATE_54M, 0),
128 };
129
130 #define wl_g_rates (__wl_rates + 0)
131 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
132 #define wl_a_rates (__wl_rates + 4)
133 #define wl_a_rates_size (wl_g_rates_size - 4)
134
135 #define CHAN2G(_channel, _freq) { \
136 .band = IEEE80211_BAND_2GHZ, \
137 .center_freq = (_freq), \
138 .hw_value = (_channel), \
139 .flags = IEEE80211_CHAN_DISABLED, \
140 .max_antenna_gain = 0, \
141 .max_power = 30, \
142 }
143
144 #define CHAN5G(_channel) { \
145 .band = IEEE80211_BAND_5GHZ, \
146 .center_freq = 5000 + (5 * (_channel)), \
147 .hw_value = (_channel), \
148 .flags = IEEE80211_CHAN_DISABLED, \
149 .max_antenna_gain = 0, \
150 .max_power = 30, \
151 }
152
153 static struct ieee80211_channel __wl_2ghz_channels[] = {
154 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
155 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
156 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
157 CHAN2G(13, 2472), CHAN2G(14, 2484)
158 };
159
160 static struct ieee80211_channel __wl_5ghz_channels[] = {
161 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
162 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
163 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
164 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
165 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
166 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
167 };
168
169 /* Band templates duplicated per wiphy. The channel info
170 * above is added to the band during setup.
171 */
172 static const struct ieee80211_supported_band __wl_band_2ghz = {
173 .band = IEEE80211_BAND_2GHZ,
174 .bitrates = wl_g_rates,
175 .n_bitrates = wl_g_rates_size,
176 };
177
178 static const struct ieee80211_supported_band __wl_band_5ghz = {
179 .band = IEEE80211_BAND_5GHZ,
180 .bitrates = wl_a_rates,
181 .n_bitrates = wl_a_rates_size,
182 };
183
184 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
185 * By default world regulatory domain defined in reg.c puts the flags
186 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
187 * With respect to these flags, wpa_supplicant doesn't * start p2p
188 * operations on 5GHz channels. All the changes in world regulatory
189 * domain are to be done here.
190 */
191 static const struct ieee80211_regdomain brcmf_regdom = {
192 .n_reg_rules = 4,
193 .alpha2 = "99",
194 .reg_rules = {
195 /* IEEE 802.11b/g, channels 1..11 */
196 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
197 /* If any */
198 /* IEEE 802.11 channel 14 - Only JP enables
199 * this and for 802.11b only
200 */
201 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
202 /* IEEE 802.11a, channel 36..64 */
203 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
204 /* IEEE 802.11a, channel 100..165 */
205 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
206 };
207
208 static const u32 __wl_cipher_suites[] = {
209 WLAN_CIPHER_SUITE_WEP40,
210 WLAN_CIPHER_SUITE_WEP104,
211 WLAN_CIPHER_SUITE_TKIP,
212 WLAN_CIPHER_SUITE_CCMP,
213 WLAN_CIPHER_SUITE_AES_CMAC,
214 };
215
216 /* Vendor specific ie. id = 221, oui and type defines exact ie */
217 struct brcmf_vs_tlv {
218 u8 id;
219 u8 len;
220 u8 oui[3];
221 u8 oui_type;
222 };
223
224 struct parsed_vndr_ie_info {
225 u8 *ie_ptr;
226 u32 ie_len; /* total length including id & length field */
227 struct brcmf_vs_tlv vndrie;
228 };
229
230 struct parsed_vndr_ies {
231 u32 count;
232 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
233 };
234
235 static int brcmf_roamoff;
236 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
237 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
238
239
chandef_to_chanspec(struct brcmu_d11inf * d11inf,struct cfg80211_chan_def * ch)240 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
241 struct cfg80211_chan_def *ch)
242 {
243 struct brcmu_chan ch_inf;
244 s32 primary_offset;
245
246 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
247 ch->chan->center_freq, ch->center_freq1, ch->width);
248 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
249 primary_offset = ch->center_freq1 - ch->chan->center_freq;
250 switch (ch->width) {
251 case NL80211_CHAN_WIDTH_20:
252 case NL80211_CHAN_WIDTH_20_NOHT:
253 ch_inf.bw = BRCMU_CHAN_BW_20;
254 WARN_ON(primary_offset != 0);
255 break;
256 case NL80211_CHAN_WIDTH_40:
257 ch_inf.bw = BRCMU_CHAN_BW_40;
258 if (primary_offset < 0)
259 ch_inf.sb = BRCMU_CHAN_SB_U;
260 else
261 ch_inf.sb = BRCMU_CHAN_SB_L;
262 break;
263 case NL80211_CHAN_WIDTH_80:
264 ch_inf.bw = BRCMU_CHAN_BW_80;
265 if (primary_offset < 0) {
266 if (primary_offset < -CH_10MHZ_APART)
267 ch_inf.sb = BRCMU_CHAN_SB_UU;
268 else
269 ch_inf.sb = BRCMU_CHAN_SB_UL;
270 } else {
271 if (primary_offset > CH_10MHZ_APART)
272 ch_inf.sb = BRCMU_CHAN_SB_LL;
273 else
274 ch_inf.sb = BRCMU_CHAN_SB_LU;
275 }
276 break;
277 case NL80211_CHAN_WIDTH_80P80:
278 case NL80211_CHAN_WIDTH_160:
279 case NL80211_CHAN_WIDTH_5:
280 case NL80211_CHAN_WIDTH_10:
281 default:
282 WARN_ON_ONCE(1);
283 }
284 switch (ch->chan->band) {
285 case IEEE80211_BAND_2GHZ:
286 ch_inf.band = BRCMU_CHAN_BAND_2G;
287 break;
288 case IEEE80211_BAND_5GHZ:
289 ch_inf.band = BRCMU_CHAN_BAND_5G;
290 break;
291 case IEEE80211_BAND_60GHZ:
292 default:
293 WARN_ON_ONCE(1);
294 }
295 d11inf->encchspec(&ch_inf);
296
297 return ch_inf.chspec;
298 }
299
channel_to_chanspec(struct brcmu_d11inf * d11inf,struct ieee80211_channel * ch)300 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
301 struct ieee80211_channel *ch)
302 {
303 struct brcmu_chan ch_inf;
304
305 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
306 ch_inf.bw = BRCMU_CHAN_BW_20;
307 d11inf->encchspec(&ch_inf);
308
309 return ch_inf.chspec;
310 }
311
312 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
313 * triples, returning a pointer to the substring whose first element
314 * matches tag
315 */
316 const struct brcmf_tlv *
brcmf_parse_tlvs(const void * buf,int buflen,uint key)317 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
318 {
319 const struct brcmf_tlv *elt = buf;
320 int totlen = buflen;
321
322 /* find tagged parameter */
323 while (totlen >= TLV_HDR_LEN) {
324 int len = elt->len;
325
326 /* validate remaining totlen */
327 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
328 return elt;
329
330 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
331 totlen -= (len + TLV_HDR_LEN);
332 }
333
334 return NULL;
335 }
336
337 /* Is any of the tlvs the expected entry? If
338 * not update the tlvs buffer pointer/length.
339 */
340 static bool
brcmf_tlv_has_ie(const u8 * ie,const u8 ** tlvs,u32 * tlvs_len,const u8 * oui,u32 oui_len,u8 type)341 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
342 const u8 *oui, u32 oui_len, u8 type)
343 {
344 /* If the contents match the OUI and the type */
345 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
346 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
347 type == ie[TLV_BODY_OFF + oui_len]) {
348 return true;
349 }
350
351 if (tlvs == NULL)
352 return false;
353 /* point to the next ie */
354 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
355 /* calculate the length of the rest of the buffer */
356 *tlvs_len -= (int)(ie - *tlvs);
357 /* update the pointer to the start of the buffer */
358 *tlvs = ie;
359
360 return false;
361 }
362
363 static struct brcmf_vs_tlv *
brcmf_find_wpaie(const u8 * parse,u32 len)364 brcmf_find_wpaie(const u8 *parse, u32 len)
365 {
366 const struct brcmf_tlv *ie;
367
368 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
369 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
370 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
371 return (struct brcmf_vs_tlv *)ie;
372 }
373 return NULL;
374 }
375
376 static struct brcmf_vs_tlv *
brcmf_find_wpsie(const u8 * parse,u32 len)377 brcmf_find_wpsie(const u8 *parse, u32 len)
378 {
379 const struct brcmf_tlv *ie;
380
381 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
382 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
383 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
384 return (struct brcmf_vs_tlv *)ie;
385 }
386 return NULL;
387 }
388
brcmf_vif_change_validate(struct brcmf_cfg80211_info * cfg,struct brcmf_cfg80211_vif * vif,enum nl80211_iftype new_type)389 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
390 struct brcmf_cfg80211_vif *vif,
391 enum nl80211_iftype new_type)
392 {
393 int iftype_num[NUM_NL80211_IFTYPES];
394 struct brcmf_cfg80211_vif *pos;
395
396 memset(&iftype_num[0], 0, sizeof(iftype_num));
397 list_for_each_entry(pos, &cfg->vif_list, list)
398 if (pos == vif)
399 iftype_num[new_type]++;
400 else
401 iftype_num[pos->wdev.iftype]++;
402
403 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
404 }
405
brcmf_vif_add_validate(struct brcmf_cfg80211_info * cfg,enum nl80211_iftype new_type)406 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
407 enum nl80211_iftype new_type)
408 {
409 int iftype_num[NUM_NL80211_IFTYPES];
410 struct brcmf_cfg80211_vif *pos;
411
412 memset(&iftype_num[0], 0, sizeof(iftype_num));
413 list_for_each_entry(pos, &cfg->vif_list, list)
414 iftype_num[pos->wdev.iftype]++;
415
416 iftype_num[new_type]++;
417 return cfg80211_check_combinations(cfg->wiphy, 1, 0, iftype_num);
418 }
419
convert_key_from_CPU(struct brcmf_wsec_key * key,struct brcmf_wsec_key_le * key_le)420 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
421 struct brcmf_wsec_key_le *key_le)
422 {
423 key_le->index = cpu_to_le32(key->index);
424 key_le->len = cpu_to_le32(key->len);
425 key_le->algo = cpu_to_le32(key->algo);
426 key_le->flags = cpu_to_le32(key->flags);
427 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
428 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
429 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
430 memcpy(key_le->data, key->data, sizeof(key->data));
431 memcpy(key_le->ea, key->ea, sizeof(key->ea));
432 }
433
434 static int
send_key_to_dongle(struct brcmf_if * ifp,struct brcmf_wsec_key * key)435 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
436 {
437 int err;
438 struct brcmf_wsec_key_le key_le;
439
440 convert_key_from_CPU(key, &key_le);
441
442 brcmf_netdev_wait_pend8021x(ifp);
443
444 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
445 sizeof(key_le));
446
447 if (err)
448 brcmf_err("wsec_key error (%d)\n", err);
449 return err;
450 }
451
452 static s32
brcmf_configure_arp_offload(struct brcmf_if * ifp,bool enable)453 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
454 {
455 s32 err;
456 u32 mode;
457
458 if (enable)
459 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
460 else
461 mode = 0;
462
463 /* Try to set and enable ARP offload feature, this may fail, then it */
464 /* is simply not supported and err 0 will be returned */
465 err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
466 if (err) {
467 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
468 mode, err);
469 err = 0;
470 } else {
471 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
472 if (err) {
473 brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
474 enable, err);
475 err = 0;
476 } else
477 brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
478 enable, mode);
479 }
480
481 return err;
482 }
483
484 static void
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev * wdev)485 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
486 {
487 struct brcmf_cfg80211_vif *vif;
488 struct brcmf_if *ifp;
489
490 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
491 ifp = vif->ifp;
492
493 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
494 (wdev->iftype == NL80211_IFTYPE_AP) ||
495 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
496 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
497 ADDR_DIRECT);
498 else
499 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
500 ADDR_INDIRECT);
501 }
502
brcmf_cfg80211_request_ap_if(struct brcmf_if * ifp)503 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
504 {
505 struct brcmf_mbss_ssid_le mbss_ssid_le;
506 int bsscfgidx;
507 int err;
508
509 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
510 bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
511 if (bsscfgidx < 0)
512 return bsscfgidx;
513
514 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
515 mbss_ssid_le.SSID_len = cpu_to_le32(5);
516 sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
517
518 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
519 sizeof(mbss_ssid_le));
520 if (err < 0)
521 brcmf_err("setting ssid failed %d\n", err);
522
523 return err;
524 }
525
526 /**
527 * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
528 *
529 * @wiphy: wiphy device of new interface.
530 * @name: name of the new interface.
531 * @flags: not used.
532 * @params: contains mac address for AP device.
533 */
534 static
brcmf_ap_add_vif(struct wiphy * wiphy,const char * name,u32 * flags,struct vif_params * params)535 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
536 u32 *flags, struct vif_params *params)
537 {
538 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
539 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
540 struct brcmf_cfg80211_vif *vif;
541 int err;
542
543 if (brcmf_cfg80211_vif_event_armed(cfg))
544 return ERR_PTR(-EBUSY);
545
546 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
547
548 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
549 if (IS_ERR(vif))
550 return (struct wireless_dev *)vif;
551
552 brcmf_cfg80211_arm_vif_event(cfg, vif);
553
554 err = brcmf_cfg80211_request_ap_if(ifp);
555 if (err) {
556 brcmf_cfg80211_arm_vif_event(cfg, NULL);
557 goto fail;
558 }
559
560 /* wait for firmware event */
561 err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
562 msecs_to_jiffies(1500));
563 brcmf_cfg80211_arm_vif_event(cfg, NULL);
564 if (!err) {
565 brcmf_err("timeout occurred\n");
566 err = -EIO;
567 goto fail;
568 }
569
570 /* interface created in firmware */
571 ifp = vif->ifp;
572 if (!ifp) {
573 brcmf_err("no if pointer provided\n");
574 err = -ENOENT;
575 goto fail;
576 }
577
578 strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
579 err = brcmf_net_attach(ifp, true);
580 if (err) {
581 brcmf_err("Registering netdevice failed\n");
582 goto fail;
583 }
584
585 return &ifp->vif->wdev;
586
587 fail:
588 brcmf_free_vif(vif);
589 return ERR_PTR(err);
590 }
591
brcmf_is_apmode(struct brcmf_cfg80211_vif * vif)592 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
593 {
594 enum nl80211_iftype iftype;
595
596 iftype = vif->wdev.iftype;
597 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
598 }
599
brcmf_is_ibssmode(struct brcmf_cfg80211_vif * vif)600 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
601 {
602 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
603 }
604
brcmf_cfg80211_add_iface(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,u32 * flags,struct vif_params * params)605 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
606 const char *name,
607 unsigned char name_assign_type,
608 enum nl80211_iftype type,
609 u32 *flags,
610 struct vif_params *params)
611 {
612 struct wireless_dev *wdev;
613 int err;
614
615 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
616 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
617 if (err) {
618 brcmf_err("iface validation failed: err=%d\n", err);
619 return ERR_PTR(err);
620 }
621 switch (type) {
622 case NL80211_IFTYPE_ADHOC:
623 case NL80211_IFTYPE_STATION:
624 case NL80211_IFTYPE_AP_VLAN:
625 case NL80211_IFTYPE_WDS:
626 case NL80211_IFTYPE_MONITOR:
627 case NL80211_IFTYPE_MESH_POINT:
628 return ERR_PTR(-EOPNOTSUPP);
629 case NL80211_IFTYPE_AP:
630 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
631 if (!IS_ERR(wdev))
632 brcmf_cfg80211_update_proto_addr_mode(wdev);
633 return wdev;
634 case NL80211_IFTYPE_P2P_CLIENT:
635 case NL80211_IFTYPE_P2P_GO:
636 case NL80211_IFTYPE_P2P_DEVICE:
637 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
638 if (!IS_ERR(wdev))
639 brcmf_cfg80211_update_proto_addr_mode(wdev);
640 return wdev;
641 case NL80211_IFTYPE_UNSPECIFIED:
642 default:
643 return ERR_PTR(-EINVAL);
644 }
645 }
646
brcmf_scan_config_mpc(struct brcmf_if * ifp,int mpc)647 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
648 {
649 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
650 brcmf_set_mpc(ifp, mpc);
651 }
652
brcmf_set_mpc(struct brcmf_if * ifp,int mpc)653 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
654 {
655 s32 err = 0;
656
657 if (check_vif_up(ifp->vif)) {
658 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
659 if (err) {
660 brcmf_err("fail to set mpc\n");
661 return;
662 }
663 brcmf_dbg(INFO, "MPC : %d\n", mpc);
664 }
665 }
666
brcmf_notify_escan_complete(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,bool aborted,bool fw_abort)667 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
668 struct brcmf_if *ifp, bool aborted,
669 bool fw_abort)
670 {
671 struct brcmf_scan_params_le params_le;
672 struct cfg80211_scan_request *scan_request;
673 s32 err = 0;
674
675 brcmf_dbg(SCAN, "Enter\n");
676
677 /* clear scan request, because the FW abort can cause a second call */
678 /* to this functon and might cause a double cfg80211_scan_done */
679 scan_request = cfg->scan_request;
680 cfg->scan_request = NULL;
681
682 if (timer_pending(&cfg->escan_timeout))
683 del_timer_sync(&cfg->escan_timeout);
684
685 if (fw_abort) {
686 /* Do a scan abort to stop the driver's scan engine */
687 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
688 memset(¶ms_le, 0, sizeof(params_le));
689 eth_broadcast_addr(params_le.bssid);
690 params_le.bss_type = DOT11_BSSTYPE_ANY;
691 params_le.scan_type = 0;
692 params_le.channel_num = cpu_to_le32(1);
693 params_le.nprobes = cpu_to_le32(1);
694 params_le.active_time = cpu_to_le32(-1);
695 params_le.passive_time = cpu_to_le32(-1);
696 params_le.home_time = cpu_to_le32(-1);
697 /* Scan is aborted by setting channel_list[0] to -1 */
698 params_le.channel_list[0] = cpu_to_le16(-1);
699 /* E-Scan (or anyother type) can be aborted by SCAN */
700 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
701 ¶ms_le, sizeof(params_le));
702 if (err)
703 brcmf_err("Scan abort failed\n");
704 }
705
706 brcmf_scan_config_mpc(ifp, 1);
707
708 /*
709 * e-scan can be initiated by scheduled scan
710 * which takes precedence.
711 */
712 if (cfg->sched_escan) {
713 brcmf_dbg(SCAN, "scheduled scan completed\n");
714 cfg->sched_escan = false;
715 if (!aborted)
716 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
717 } else if (scan_request) {
718 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
719 aborted ? "Aborted" : "Done");
720 cfg80211_scan_done(scan_request, aborted);
721 }
722 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
723 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
724
725 return err;
726 }
727
728 static
brcmf_cfg80211_del_iface(struct wiphy * wiphy,struct wireless_dev * wdev)729 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
730 {
731 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
732 struct net_device *ndev = wdev->netdev;
733
734 /* vif event pending in firmware */
735 if (brcmf_cfg80211_vif_event_armed(cfg))
736 return -EBUSY;
737
738 if (ndev) {
739 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
740 cfg->escan_info.ifp == netdev_priv(ndev))
741 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
742 true, true);
743
744 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
745 }
746
747 switch (wdev->iftype) {
748 case NL80211_IFTYPE_ADHOC:
749 case NL80211_IFTYPE_STATION:
750 case NL80211_IFTYPE_AP:
751 case NL80211_IFTYPE_AP_VLAN:
752 case NL80211_IFTYPE_WDS:
753 case NL80211_IFTYPE_MONITOR:
754 case NL80211_IFTYPE_MESH_POINT:
755 return -EOPNOTSUPP;
756 case NL80211_IFTYPE_P2P_CLIENT:
757 case NL80211_IFTYPE_P2P_GO:
758 case NL80211_IFTYPE_P2P_DEVICE:
759 return brcmf_p2p_del_vif(wiphy, wdev);
760 case NL80211_IFTYPE_UNSPECIFIED:
761 default:
762 return -EINVAL;
763 }
764 return -EOPNOTSUPP;
765 }
766
767 static s32
brcmf_cfg80211_change_iface(struct wiphy * wiphy,struct net_device * ndev,enum nl80211_iftype type,u32 * flags,struct vif_params * params)768 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
769 enum nl80211_iftype type, u32 *flags,
770 struct vif_params *params)
771 {
772 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
773 struct brcmf_if *ifp = netdev_priv(ndev);
774 struct brcmf_cfg80211_vif *vif = ifp->vif;
775 s32 infra = 0;
776 s32 ap = 0;
777 s32 err = 0;
778
779 brcmf_dbg(TRACE, "Enter, idx=%d, type=%d\n", ifp->bssidx, type);
780
781 /* WAR: There are a number of p2p interface related problems which
782 * need to be handled initially (before doing the validate).
783 * wpa_supplicant tends to do iface changes on p2p device/client/go
784 * which are not always possible/allowed. However we need to return
785 * OK otherwise the wpa_supplicant wont start. The situation differs
786 * on configuration and setup (p2pon=1 module param). The first check
787 * is to see if the request is a change to station for p2p iface.
788 */
789 if ((type == NL80211_IFTYPE_STATION) &&
790 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
791 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
792 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
793 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
794 /* Now depending on whether module param p2pon=1 was used the
795 * response needs to be either 0 or EOPNOTSUPP. The reason is
796 * that if p2pon=1 is used, but a newer supplicant is used then
797 * we should return an error, as this combination wont work.
798 * In other situations 0 is returned and supplicant will start
799 * normally. It will give a trace in cfg80211, but it is the
800 * only way to get it working. Unfortunately this will result
801 * in situation where we wont support new supplicant in
802 * combination with module param p2pon=1, but that is the way
803 * it is. If the user tries this then unloading of driver might
804 * fail/lock.
805 */
806 if (cfg->p2p.p2pdev_dynamically)
807 return -EOPNOTSUPP;
808 else
809 return 0;
810 }
811 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
812 if (err) {
813 brcmf_err("iface validation failed: err=%d\n", err);
814 return err;
815 }
816 switch (type) {
817 case NL80211_IFTYPE_MONITOR:
818 case NL80211_IFTYPE_WDS:
819 brcmf_err("type (%d) : currently we do not support this type\n",
820 type);
821 return -EOPNOTSUPP;
822 case NL80211_IFTYPE_ADHOC:
823 infra = 0;
824 break;
825 case NL80211_IFTYPE_STATION:
826 infra = 1;
827 break;
828 case NL80211_IFTYPE_AP:
829 case NL80211_IFTYPE_P2P_GO:
830 ap = 1;
831 break;
832 default:
833 err = -EINVAL;
834 goto done;
835 }
836
837 if (ap) {
838 if (type == NL80211_IFTYPE_P2P_GO) {
839 brcmf_dbg(INFO, "IF Type = P2P GO\n");
840 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
841 }
842 if (!err) {
843 brcmf_dbg(INFO, "IF Type = AP\n");
844 }
845 } else {
846 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
847 if (err) {
848 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
849 err = -EAGAIN;
850 goto done;
851 }
852 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
853 "Adhoc" : "Infra");
854 }
855 ndev->ieee80211_ptr->iftype = type;
856
857 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
858
859 done:
860 brcmf_dbg(TRACE, "Exit\n");
861
862 return err;
863 }
864
brcmf_escan_prep(struct brcmf_cfg80211_info * cfg,struct brcmf_scan_params_le * params_le,struct cfg80211_scan_request * request)865 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
866 struct brcmf_scan_params_le *params_le,
867 struct cfg80211_scan_request *request)
868 {
869 u32 n_ssids;
870 u32 n_channels;
871 s32 i;
872 s32 offset;
873 u16 chanspec;
874 char *ptr;
875 struct brcmf_ssid_le ssid_le;
876
877 eth_broadcast_addr(params_le->bssid);
878 params_le->bss_type = DOT11_BSSTYPE_ANY;
879 params_le->scan_type = BRCMF_SCANTYPE_ACTIVE;
880 params_le->channel_num = 0;
881 params_le->nprobes = cpu_to_le32(-1);
882 params_le->active_time = cpu_to_le32(-1);
883 params_le->passive_time = cpu_to_le32(-1);
884 params_le->home_time = cpu_to_le32(-1);
885 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
886
887 n_ssids = request->n_ssids;
888 n_channels = request->n_channels;
889
890 /* Copy channel array if applicable */
891 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
892 n_channels);
893 if (n_channels > 0) {
894 for (i = 0; i < n_channels; i++) {
895 chanspec = channel_to_chanspec(&cfg->d11inf,
896 request->channels[i]);
897 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
898 request->channels[i]->hw_value, chanspec);
899 params_le->channel_list[i] = cpu_to_le16(chanspec);
900 }
901 } else {
902 brcmf_dbg(SCAN, "Scanning all channels\n");
903 }
904 /* Copy ssid array if applicable */
905 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
906 if (n_ssids > 0) {
907 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
908 n_channels * sizeof(u16);
909 offset = roundup(offset, sizeof(u32));
910 ptr = (char *)params_le + offset;
911 for (i = 0; i < n_ssids; i++) {
912 memset(&ssid_le, 0, sizeof(ssid_le));
913 ssid_le.SSID_len =
914 cpu_to_le32(request->ssids[i].ssid_len);
915 memcpy(ssid_le.SSID, request->ssids[i].ssid,
916 request->ssids[i].ssid_len);
917 if (!ssid_le.SSID_len)
918 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
919 else
920 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
921 i, ssid_le.SSID, ssid_le.SSID_len);
922 memcpy(ptr, &ssid_le, sizeof(ssid_le));
923 ptr += sizeof(ssid_le);
924 }
925 } else {
926 brcmf_dbg(SCAN, "Performing passive scan\n");
927 params_le->scan_type = BRCMF_SCANTYPE_PASSIVE;
928 }
929 /* Adding mask to channel numbers */
930 params_le->channel_num =
931 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
932 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
933 }
934
935 static s32
brcmf_run_escan(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,struct cfg80211_scan_request * request,u16 action)936 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
937 struct cfg80211_scan_request *request, u16 action)
938 {
939 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
940 offsetof(struct brcmf_escan_params_le, params_le);
941 struct brcmf_escan_params_le *params;
942 s32 err = 0;
943
944 brcmf_dbg(SCAN, "E-SCAN START\n");
945
946 if (request != NULL) {
947 /* Allocate space for populating ssids in struct */
948 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
949
950 /* Allocate space for populating ssids in struct */
951 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
952 }
953
954 params = kzalloc(params_size, GFP_KERNEL);
955 if (!params) {
956 err = -ENOMEM;
957 goto exit;
958 }
959 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
960 brcmf_escan_prep(cfg, ¶ms->params_le, request);
961 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
962 params->action = cpu_to_le16(action);
963 params->sync_id = cpu_to_le16(0x1234);
964
965 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
966 if (err) {
967 if (err == -EBUSY)
968 brcmf_dbg(INFO, "system busy : escan canceled\n");
969 else
970 brcmf_err("error (%d)\n", err);
971 }
972
973 kfree(params);
974 exit:
975 return err;
976 }
977
978 static s32
brcmf_do_escan(struct brcmf_cfg80211_info * cfg,struct wiphy * wiphy,struct brcmf_if * ifp,struct cfg80211_scan_request * request)979 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
980 struct brcmf_if *ifp, struct cfg80211_scan_request *request)
981 {
982 s32 err;
983 u32 passive_scan;
984 struct brcmf_scan_results *results;
985 struct escan_info *escan = &cfg->escan_info;
986
987 brcmf_dbg(SCAN, "Enter\n");
988 escan->ifp = ifp;
989 escan->wiphy = wiphy;
990 escan->escan_state = WL_ESCAN_STATE_SCANNING;
991 passive_scan = cfg->active_scan ? 0 : 1;
992 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
993 passive_scan);
994 if (err) {
995 brcmf_err("error (%d)\n", err);
996 return err;
997 }
998 brcmf_scan_config_mpc(ifp, 0);
999 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1000 results->version = 0;
1001 results->count = 0;
1002 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1003
1004 err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
1005 if (err)
1006 brcmf_scan_config_mpc(ifp, 1);
1007 return err;
1008 }
1009
1010 static s32
brcmf_cfg80211_escan(struct wiphy * wiphy,struct brcmf_cfg80211_vif * vif,struct cfg80211_scan_request * request,struct cfg80211_ssid * this_ssid)1011 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1012 struct cfg80211_scan_request *request,
1013 struct cfg80211_ssid *this_ssid)
1014 {
1015 struct brcmf_if *ifp = vif->ifp;
1016 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1017 struct cfg80211_ssid *ssids;
1018 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
1019 u32 passive_scan;
1020 bool escan_req;
1021 bool spec_scan;
1022 s32 err;
1023 u32 SSID_len;
1024
1025 brcmf_dbg(SCAN, "START ESCAN\n");
1026
1027 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1028 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1029 return -EAGAIN;
1030 }
1031 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1032 brcmf_err("Scanning being aborted: status (%lu)\n",
1033 cfg->scan_status);
1034 return -EAGAIN;
1035 }
1036 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1037 brcmf_err("Scanning suppressed: status (%lu)\n",
1038 cfg->scan_status);
1039 return -EAGAIN;
1040 }
1041 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1042 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1043 return -EAGAIN;
1044 }
1045
1046 /* If scan req comes for p2p0, send it over primary I/F */
1047 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1048 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1049
1050 escan_req = false;
1051 if (request) {
1052 /* scan bss */
1053 ssids = request->ssids;
1054 escan_req = true;
1055 } else {
1056 /* scan in ibss */
1057 /* we don't do escan in ibss */
1058 ssids = this_ssid;
1059 }
1060
1061 cfg->scan_request = request;
1062 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1063 if (escan_req) {
1064 cfg->escan_info.run = brcmf_run_escan;
1065 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1066 if (err)
1067 goto scan_out;
1068
1069 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1070 if (err)
1071 goto scan_out;
1072 } else {
1073 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1074 ssids->ssid, ssids->ssid_len);
1075 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1076 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1077 sr->ssid_le.SSID_len = cpu_to_le32(0);
1078 spec_scan = false;
1079 if (SSID_len) {
1080 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1081 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1082 spec_scan = true;
1083 } else
1084 brcmf_dbg(SCAN, "Broadcast scan\n");
1085
1086 passive_scan = cfg->active_scan ? 0 : 1;
1087 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1088 passive_scan);
1089 if (err) {
1090 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1091 goto scan_out;
1092 }
1093 brcmf_scan_config_mpc(ifp, 0);
1094 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1095 &sr->ssid_le, sizeof(sr->ssid_le));
1096 if (err) {
1097 if (err == -EBUSY)
1098 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1099 sr->ssid_le.SSID);
1100 else
1101 brcmf_err("WLC_SCAN error (%d)\n", err);
1102
1103 brcmf_scan_config_mpc(ifp, 1);
1104 goto scan_out;
1105 }
1106 }
1107
1108 /* Arm scan timeout timer */
1109 mod_timer(&cfg->escan_timeout, jiffies +
1110 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1111
1112 return 0;
1113
1114 scan_out:
1115 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1116 cfg->scan_request = NULL;
1117 return err;
1118 }
1119
1120 static s32
brcmf_cfg80211_scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)1121 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1122 {
1123 struct brcmf_cfg80211_vif *vif;
1124 s32 err = 0;
1125
1126 brcmf_dbg(TRACE, "Enter\n");
1127 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1128 if (!check_vif_up(vif))
1129 return -EIO;
1130
1131 err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1132
1133 if (err)
1134 brcmf_err("scan error (%d)\n", err);
1135
1136 brcmf_dbg(TRACE, "Exit\n");
1137 return err;
1138 }
1139
brcmf_set_rts(struct net_device * ndev,u32 rts_threshold)1140 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1141 {
1142 s32 err = 0;
1143
1144 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1145 rts_threshold);
1146 if (err)
1147 brcmf_err("Error (%d)\n", err);
1148
1149 return err;
1150 }
1151
brcmf_set_frag(struct net_device * ndev,u32 frag_threshold)1152 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1153 {
1154 s32 err = 0;
1155
1156 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1157 frag_threshold);
1158 if (err)
1159 brcmf_err("Error (%d)\n", err);
1160
1161 return err;
1162 }
1163
brcmf_set_retry(struct net_device * ndev,u32 retry,bool l)1164 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1165 {
1166 s32 err = 0;
1167 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1168
1169 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1170 if (err) {
1171 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1172 return err;
1173 }
1174 return err;
1175 }
1176
brcmf_cfg80211_set_wiphy_params(struct wiphy * wiphy,u32 changed)1177 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1178 {
1179 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1180 struct net_device *ndev = cfg_to_ndev(cfg);
1181 struct brcmf_if *ifp = netdev_priv(ndev);
1182 s32 err = 0;
1183
1184 brcmf_dbg(TRACE, "Enter\n");
1185 if (!check_vif_up(ifp->vif))
1186 return -EIO;
1187
1188 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1189 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1190 cfg->conf->rts_threshold = wiphy->rts_threshold;
1191 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1192 if (!err)
1193 goto done;
1194 }
1195 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1196 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1197 cfg->conf->frag_threshold = wiphy->frag_threshold;
1198 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1199 if (!err)
1200 goto done;
1201 }
1202 if (changed & WIPHY_PARAM_RETRY_LONG
1203 && (cfg->conf->retry_long != wiphy->retry_long)) {
1204 cfg->conf->retry_long = wiphy->retry_long;
1205 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1206 if (!err)
1207 goto done;
1208 }
1209 if (changed & WIPHY_PARAM_RETRY_SHORT
1210 && (cfg->conf->retry_short != wiphy->retry_short)) {
1211 cfg->conf->retry_short = wiphy->retry_short;
1212 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1213 if (!err)
1214 goto done;
1215 }
1216
1217 done:
1218 brcmf_dbg(TRACE, "Exit\n");
1219 return err;
1220 }
1221
brcmf_init_prof(struct brcmf_cfg80211_profile * prof)1222 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1223 {
1224 memset(prof, 0, sizeof(*prof));
1225 }
1226
brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg * e)1227 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1228 {
1229 u16 reason;
1230
1231 switch (e->event_code) {
1232 case BRCMF_E_DEAUTH:
1233 case BRCMF_E_DEAUTH_IND:
1234 case BRCMF_E_DISASSOC_IND:
1235 reason = e->reason;
1236 break;
1237 case BRCMF_E_LINK:
1238 default:
1239 reason = 0;
1240 break;
1241 }
1242 return reason;
1243 }
1244
brcmf_link_down(struct brcmf_cfg80211_vif * vif,u16 reason)1245 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1246 {
1247 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1248 s32 err = 0;
1249
1250 brcmf_dbg(TRACE, "Enter\n");
1251
1252 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1253 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1254 err = brcmf_fil_cmd_data_set(vif->ifp,
1255 BRCMF_C_DISASSOC, NULL, 0);
1256 if (err) {
1257 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1258 }
1259 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1260 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1261 true, GFP_KERNEL);
1262
1263 }
1264 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1265 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1266 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1267 brcmf_dbg(TRACE, "Exit\n");
1268 }
1269
1270 static s32
brcmf_cfg80211_join_ibss(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ibss_params * params)1271 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1272 struct cfg80211_ibss_params *params)
1273 {
1274 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1275 struct brcmf_if *ifp = netdev_priv(ndev);
1276 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1277 struct brcmf_join_params join_params;
1278 size_t join_params_size = 0;
1279 s32 err = 0;
1280 s32 wsec = 0;
1281 s32 bcnprd;
1282 u16 chanspec;
1283
1284 brcmf_dbg(TRACE, "Enter\n");
1285 if (!check_vif_up(ifp->vif))
1286 return -EIO;
1287
1288 if (params->ssid)
1289 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1290 else {
1291 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1292 return -EOPNOTSUPP;
1293 }
1294
1295 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1296
1297 if (params->bssid)
1298 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1299 else
1300 brcmf_dbg(CONN, "No BSSID specified\n");
1301
1302 if (params->chandef.chan)
1303 brcmf_dbg(CONN, "channel: %d\n",
1304 params->chandef.chan->center_freq);
1305 else
1306 brcmf_dbg(CONN, "no channel specified\n");
1307
1308 if (params->channel_fixed)
1309 brcmf_dbg(CONN, "fixed channel required\n");
1310 else
1311 brcmf_dbg(CONN, "no fixed channel required\n");
1312
1313 if (params->ie && params->ie_len)
1314 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1315 else
1316 brcmf_dbg(CONN, "no ie specified\n");
1317
1318 if (params->beacon_interval)
1319 brcmf_dbg(CONN, "beacon interval: %d\n",
1320 params->beacon_interval);
1321 else
1322 brcmf_dbg(CONN, "no beacon interval specified\n");
1323
1324 if (params->basic_rates)
1325 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1326 else
1327 brcmf_dbg(CONN, "no basic rates specified\n");
1328
1329 if (params->privacy)
1330 brcmf_dbg(CONN, "privacy required\n");
1331 else
1332 brcmf_dbg(CONN, "no privacy required\n");
1333
1334 /* Configure Privacy for starter */
1335 if (params->privacy)
1336 wsec |= WEP_ENABLED;
1337
1338 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1339 if (err) {
1340 brcmf_err("wsec failed (%d)\n", err);
1341 goto done;
1342 }
1343
1344 /* Configure Beacon Interval for starter */
1345 if (params->beacon_interval)
1346 bcnprd = params->beacon_interval;
1347 else
1348 bcnprd = 100;
1349
1350 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1351 if (err) {
1352 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1353 goto done;
1354 }
1355
1356 /* Configure required join parameter */
1357 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1358
1359 /* SSID */
1360 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1361 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1362 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1363 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1364 join_params_size = sizeof(join_params.ssid_le);
1365
1366 /* BSSID */
1367 if (params->bssid) {
1368 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1369 join_params_size = sizeof(join_params.ssid_le) +
1370 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1371 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1372 } else {
1373 eth_broadcast_addr(join_params.params_le.bssid);
1374 eth_zero_addr(profile->bssid);
1375 }
1376
1377 /* Channel */
1378 if (params->chandef.chan) {
1379 u32 target_channel;
1380
1381 cfg->channel =
1382 ieee80211_frequency_to_channel(
1383 params->chandef.chan->center_freq);
1384 if (params->channel_fixed) {
1385 /* adding chanspec */
1386 chanspec = chandef_to_chanspec(&cfg->d11inf,
1387 ¶ms->chandef);
1388 join_params.params_le.chanspec_list[0] =
1389 cpu_to_le16(chanspec);
1390 join_params.params_le.chanspec_num = cpu_to_le32(1);
1391 join_params_size += sizeof(join_params.params_le);
1392 }
1393
1394 /* set channel for starter */
1395 target_channel = cfg->channel;
1396 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1397 target_channel);
1398 if (err) {
1399 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1400 goto done;
1401 }
1402 } else
1403 cfg->channel = 0;
1404
1405 cfg->ibss_starter = false;
1406
1407
1408 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1409 &join_params, join_params_size);
1410 if (err) {
1411 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1412 goto done;
1413 }
1414
1415 done:
1416 if (err)
1417 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1418 brcmf_dbg(TRACE, "Exit\n");
1419 return err;
1420 }
1421
1422 static s32
brcmf_cfg80211_leave_ibss(struct wiphy * wiphy,struct net_device * ndev)1423 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1424 {
1425 struct brcmf_if *ifp = netdev_priv(ndev);
1426
1427 brcmf_dbg(TRACE, "Enter\n");
1428 if (!check_vif_up(ifp->vif))
1429 return -EIO;
1430
1431 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1432
1433 brcmf_dbg(TRACE, "Exit\n");
1434
1435 return 0;
1436 }
1437
brcmf_set_wpa_version(struct net_device * ndev,struct cfg80211_connect_params * sme)1438 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1439 struct cfg80211_connect_params *sme)
1440 {
1441 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1442 struct brcmf_cfg80211_security *sec;
1443 s32 val = 0;
1444 s32 err = 0;
1445
1446 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1447 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1448 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1449 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1450 else
1451 val = WPA_AUTH_DISABLED;
1452 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1453 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1454 if (err) {
1455 brcmf_err("set wpa_auth failed (%d)\n", err);
1456 return err;
1457 }
1458 sec = &profile->sec;
1459 sec->wpa_versions = sme->crypto.wpa_versions;
1460 return err;
1461 }
1462
brcmf_set_auth_type(struct net_device * ndev,struct cfg80211_connect_params * sme)1463 static s32 brcmf_set_auth_type(struct net_device *ndev,
1464 struct cfg80211_connect_params *sme)
1465 {
1466 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1467 struct brcmf_cfg80211_security *sec;
1468 s32 val = 0;
1469 s32 err = 0;
1470
1471 switch (sme->auth_type) {
1472 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1473 val = 0;
1474 brcmf_dbg(CONN, "open system\n");
1475 break;
1476 case NL80211_AUTHTYPE_SHARED_KEY:
1477 val = 1;
1478 brcmf_dbg(CONN, "shared key\n");
1479 break;
1480 case NL80211_AUTHTYPE_AUTOMATIC:
1481 val = 2;
1482 brcmf_dbg(CONN, "automatic\n");
1483 break;
1484 case NL80211_AUTHTYPE_NETWORK_EAP:
1485 brcmf_dbg(CONN, "network eap\n");
1486 default:
1487 val = 2;
1488 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1489 break;
1490 }
1491
1492 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1493 if (err) {
1494 brcmf_err("set auth failed (%d)\n", err);
1495 return err;
1496 }
1497 sec = &profile->sec;
1498 sec->auth_type = sme->auth_type;
1499 return err;
1500 }
1501
1502 static s32
brcmf_set_wsec_mode(struct net_device * ndev,struct cfg80211_connect_params * sme,bool mfp)1503 brcmf_set_wsec_mode(struct net_device *ndev,
1504 struct cfg80211_connect_params *sme, bool mfp)
1505 {
1506 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1507 struct brcmf_cfg80211_security *sec;
1508 s32 pval = 0;
1509 s32 gval = 0;
1510 s32 wsec;
1511 s32 err = 0;
1512
1513 if (sme->crypto.n_ciphers_pairwise) {
1514 switch (sme->crypto.ciphers_pairwise[0]) {
1515 case WLAN_CIPHER_SUITE_WEP40:
1516 case WLAN_CIPHER_SUITE_WEP104:
1517 pval = WEP_ENABLED;
1518 break;
1519 case WLAN_CIPHER_SUITE_TKIP:
1520 pval = TKIP_ENABLED;
1521 break;
1522 case WLAN_CIPHER_SUITE_CCMP:
1523 pval = AES_ENABLED;
1524 break;
1525 case WLAN_CIPHER_SUITE_AES_CMAC:
1526 pval = AES_ENABLED;
1527 break;
1528 default:
1529 brcmf_err("invalid cipher pairwise (%d)\n",
1530 sme->crypto.ciphers_pairwise[0]);
1531 return -EINVAL;
1532 }
1533 }
1534 if (sme->crypto.cipher_group) {
1535 switch (sme->crypto.cipher_group) {
1536 case WLAN_CIPHER_SUITE_WEP40:
1537 case WLAN_CIPHER_SUITE_WEP104:
1538 gval = WEP_ENABLED;
1539 break;
1540 case WLAN_CIPHER_SUITE_TKIP:
1541 gval = TKIP_ENABLED;
1542 break;
1543 case WLAN_CIPHER_SUITE_CCMP:
1544 gval = AES_ENABLED;
1545 break;
1546 case WLAN_CIPHER_SUITE_AES_CMAC:
1547 gval = AES_ENABLED;
1548 break;
1549 default:
1550 brcmf_err("invalid cipher group (%d)\n",
1551 sme->crypto.cipher_group);
1552 return -EINVAL;
1553 }
1554 }
1555
1556 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1557 /* In case of privacy, but no security and WPS then simulate */
1558 /* setting AES. WPS-2.0 allows no security */
1559 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1560 sme->privacy)
1561 pval = AES_ENABLED;
1562
1563 if (mfp)
1564 wsec = pval | gval | MFP_CAPABLE;
1565 else
1566 wsec = pval | gval;
1567 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1568 if (err) {
1569 brcmf_err("error (%d)\n", err);
1570 return err;
1571 }
1572
1573 sec = &profile->sec;
1574 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1575 sec->cipher_group = sme->crypto.cipher_group;
1576
1577 return err;
1578 }
1579
1580 static s32
brcmf_set_key_mgmt(struct net_device * ndev,struct cfg80211_connect_params * sme)1581 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1582 {
1583 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1584 struct brcmf_cfg80211_security *sec;
1585 s32 val = 0;
1586 s32 err = 0;
1587
1588 if (sme->crypto.n_akm_suites) {
1589 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1590 "wpa_auth", &val);
1591 if (err) {
1592 brcmf_err("could not get wpa_auth (%d)\n", err);
1593 return err;
1594 }
1595 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1596 switch (sme->crypto.akm_suites[0]) {
1597 case WLAN_AKM_SUITE_8021X:
1598 val = WPA_AUTH_UNSPECIFIED;
1599 break;
1600 case WLAN_AKM_SUITE_PSK:
1601 val = WPA_AUTH_PSK;
1602 break;
1603 default:
1604 brcmf_err("invalid cipher group (%d)\n",
1605 sme->crypto.cipher_group);
1606 return -EINVAL;
1607 }
1608 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1609 switch (sme->crypto.akm_suites[0]) {
1610 case WLAN_AKM_SUITE_8021X:
1611 val = WPA2_AUTH_UNSPECIFIED;
1612 break;
1613 case WLAN_AKM_SUITE_PSK:
1614 val = WPA2_AUTH_PSK;
1615 break;
1616 default:
1617 brcmf_err("invalid cipher group (%d)\n",
1618 sme->crypto.cipher_group);
1619 return -EINVAL;
1620 }
1621 }
1622
1623 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1624 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1625 "wpa_auth", val);
1626 if (err) {
1627 brcmf_err("could not set wpa_auth (%d)\n", err);
1628 return err;
1629 }
1630 }
1631 sec = &profile->sec;
1632 sec->wpa_auth = sme->crypto.akm_suites[0];
1633
1634 return err;
1635 }
1636
1637 static s32
brcmf_set_sharedkey(struct net_device * ndev,struct cfg80211_connect_params * sme)1638 brcmf_set_sharedkey(struct net_device *ndev,
1639 struct cfg80211_connect_params *sme)
1640 {
1641 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1642 struct brcmf_cfg80211_security *sec;
1643 struct brcmf_wsec_key key;
1644 s32 val;
1645 s32 err = 0;
1646
1647 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1648
1649 if (sme->key_len == 0)
1650 return 0;
1651
1652 sec = &profile->sec;
1653 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1654 sec->wpa_versions, sec->cipher_pairwise);
1655
1656 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1657 return 0;
1658
1659 if (!(sec->cipher_pairwise &
1660 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1661 return 0;
1662
1663 memset(&key, 0, sizeof(key));
1664 key.len = (u32) sme->key_len;
1665 key.index = (u32) sme->key_idx;
1666 if (key.len > sizeof(key.data)) {
1667 brcmf_err("Too long key length (%u)\n", key.len);
1668 return -EINVAL;
1669 }
1670 memcpy(key.data, sme->key, key.len);
1671 key.flags = BRCMF_PRIMARY_KEY;
1672 switch (sec->cipher_pairwise) {
1673 case WLAN_CIPHER_SUITE_WEP40:
1674 key.algo = CRYPTO_ALGO_WEP1;
1675 break;
1676 case WLAN_CIPHER_SUITE_WEP104:
1677 key.algo = CRYPTO_ALGO_WEP128;
1678 break;
1679 default:
1680 brcmf_err("Invalid algorithm (%d)\n",
1681 sme->crypto.ciphers_pairwise[0]);
1682 return -EINVAL;
1683 }
1684 /* Set the new key/index */
1685 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1686 key.len, key.index, key.algo);
1687 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1688 err = send_key_to_dongle(netdev_priv(ndev), &key);
1689 if (err)
1690 return err;
1691
1692 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1693 brcmf_dbg(CONN, "set auth_type to shared key\n");
1694 val = WL_AUTH_SHARED_KEY; /* shared key */
1695 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1696 if (err)
1697 brcmf_err("set auth failed (%d)\n", err);
1698 }
1699 return err;
1700 }
1701
1702 static
brcmf_war_auth_type(struct brcmf_if * ifp,enum nl80211_auth_type type)1703 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1704 enum nl80211_auth_type type)
1705 {
1706 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1707 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1708 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1709 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1710 }
1711 return type;
1712 }
1713
1714 static s32
brcmf_cfg80211_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * sme)1715 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1716 struct cfg80211_connect_params *sme)
1717 {
1718 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1719 struct brcmf_if *ifp = netdev_priv(ndev);
1720 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1721 struct ieee80211_channel *chan = sme->channel;
1722 struct brcmf_join_params join_params;
1723 size_t join_params_size;
1724 const struct brcmf_tlv *rsn_ie;
1725 const struct brcmf_vs_tlv *wpa_ie;
1726 const void *ie;
1727 u32 ie_len;
1728 struct brcmf_ext_join_params_le *ext_join_params;
1729 u16 chanspec;
1730 s32 err = 0;
1731
1732 brcmf_dbg(TRACE, "Enter\n");
1733 if (!check_vif_up(ifp->vif))
1734 return -EIO;
1735
1736 if (!sme->ssid) {
1737 brcmf_err("Invalid ssid\n");
1738 return -EOPNOTSUPP;
1739 }
1740
1741 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1742 /* A normal (non P2P) connection request setup. */
1743 ie = NULL;
1744 ie_len = 0;
1745 /* find the WPA_IE */
1746 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1747 if (wpa_ie) {
1748 ie = wpa_ie;
1749 ie_len = wpa_ie->len + TLV_HDR_LEN;
1750 } else {
1751 /* find the RSN_IE */
1752 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1753 sme->ie_len,
1754 WLAN_EID_RSN);
1755 if (rsn_ie) {
1756 ie = rsn_ie;
1757 ie_len = rsn_ie->len + TLV_HDR_LEN;
1758 }
1759 }
1760 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1761 }
1762
1763 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1764 sme->ie, sme->ie_len);
1765 if (err)
1766 brcmf_err("Set Assoc REQ IE Failed\n");
1767 else
1768 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1769
1770 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1771
1772 if (chan) {
1773 cfg->channel =
1774 ieee80211_frequency_to_channel(chan->center_freq);
1775 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1776 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1777 cfg->channel, chan->center_freq, chanspec);
1778 } else {
1779 cfg->channel = 0;
1780 chanspec = 0;
1781 }
1782
1783 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1784
1785 err = brcmf_set_wpa_version(ndev, sme);
1786 if (err) {
1787 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1788 goto done;
1789 }
1790
1791 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1792 err = brcmf_set_auth_type(ndev, sme);
1793 if (err) {
1794 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1795 goto done;
1796 }
1797
1798 err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1799 if (err) {
1800 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1801 goto done;
1802 }
1803
1804 err = brcmf_set_key_mgmt(ndev, sme);
1805 if (err) {
1806 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1807 goto done;
1808 }
1809
1810 err = brcmf_set_sharedkey(ndev, sme);
1811 if (err) {
1812 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1813 goto done;
1814 }
1815
1816 profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1817 (u32)sme->ssid_len);
1818 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1819 if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1820 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1821 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1822 profile->ssid.SSID_len);
1823 }
1824
1825 /* Join with specific BSSID and cached SSID
1826 * If SSID is zero join based on BSSID only
1827 */
1828 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1829 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1830 if (cfg->channel)
1831 join_params_size += sizeof(u16);
1832 ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1833 if (ext_join_params == NULL) {
1834 err = -ENOMEM;
1835 goto done;
1836 }
1837 ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1838 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1839 profile->ssid.SSID_len);
1840
1841 /* Set up join scan parameters */
1842 ext_join_params->scan_le.scan_type = -1;
1843 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1844
1845 if (sme->bssid)
1846 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1847 else
1848 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1849
1850 if (cfg->channel) {
1851 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1852
1853 ext_join_params->assoc_le.chanspec_list[0] =
1854 cpu_to_le16(chanspec);
1855 /* Increase dwell time to receive probe response or detect
1856 * beacon from target AP at a noisy air only during connect
1857 * command.
1858 */
1859 ext_join_params->scan_le.active_time =
1860 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1861 ext_join_params->scan_le.passive_time =
1862 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1863 /* To sync with presence period of VSDB GO send probe request
1864 * more frequently. Probe request will be stopped when it gets
1865 * probe response from target AP/GO.
1866 */
1867 ext_join_params->scan_le.nprobes =
1868 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1869 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1870 } else {
1871 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1872 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1873 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1874 }
1875
1876 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1877 join_params_size);
1878 kfree(ext_join_params);
1879 if (!err)
1880 /* This is it. join command worked, we are done */
1881 goto done;
1882
1883 /* join command failed, fallback to set ssid */
1884 memset(&join_params, 0, sizeof(join_params));
1885 join_params_size = sizeof(join_params.ssid_le);
1886
1887 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1888 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1889
1890 if (sme->bssid)
1891 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1892 else
1893 eth_broadcast_addr(join_params.params_le.bssid);
1894
1895 if (cfg->channel) {
1896 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1897 join_params.params_le.chanspec_num = cpu_to_le32(1);
1898 join_params_size += sizeof(join_params.params_le);
1899 }
1900 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1901 &join_params, join_params_size);
1902 if (err)
1903 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1904
1905 done:
1906 if (err)
1907 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1908 brcmf_dbg(TRACE, "Exit\n");
1909 return err;
1910 }
1911
1912 static s32
brcmf_cfg80211_disconnect(struct wiphy * wiphy,struct net_device * ndev,u16 reason_code)1913 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1914 u16 reason_code)
1915 {
1916 struct brcmf_if *ifp = netdev_priv(ndev);
1917 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1918 struct brcmf_scb_val_le scbval;
1919 s32 err = 0;
1920
1921 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1922 if (!check_vif_up(ifp->vif))
1923 return -EIO;
1924
1925 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1926 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1927 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1928
1929 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1930 scbval.val = cpu_to_le32(reason_code);
1931 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1932 &scbval, sizeof(scbval));
1933 if (err)
1934 brcmf_err("error (%d)\n", err);
1935
1936 brcmf_dbg(TRACE, "Exit\n");
1937 return err;
1938 }
1939
1940 static s32
brcmf_cfg80211_set_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_tx_power_setting type,s32 mbm)1941 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1942 enum nl80211_tx_power_setting type, s32 mbm)
1943 {
1944 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1945 struct net_device *ndev = cfg_to_ndev(cfg);
1946 struct brcmf_if *ifp = netdev_priv(ndev);
1947 s32 err;
1948 s32 disable;
1949 u32 qdbm = 127;
1950
1951 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
1952 if (!check_vif_up(ifp->vif))
1953 return -EIO;
1954
1955 switch (type) {
1956 case NL80211_TX_POWER_AUTOMATIC:
1957 break;
1958 case NL80211_TX_POWER_LIMITED:
1959 case NL80211_TX_POWER_FIXED:
1960 if (mbm < 0) {
1961 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1962 err = -EINVAL;
1963 goto done;
1964 }
1965 qdbm = MBM_TO_DBM(4 * mbm);
1966 if (qdbm > 127)
1967 qdbm = 127;
1968 qdbm |= WL_TXPWR_OVERRIDE;
1969 break;
1970 default:
1971 brcmf_err("Unsupported type %d\n", type);
1972 err = -EINVAL;
1973 goto done;
1974 }
1975 /* Make sure radio is off or on as far as software is concerned */
1976 disable = WL_RADIO_SW_DISABLE << 16;
1977 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1978 if (err)
1979 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1980
1981 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
1982 if (err)
1983 brcmf_err("qtxpower error (%d)\n", err);
1984
1985 done:
1986 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
1987 return err;
1988 }
1989
1990 static s32
brcmf_cfg80211_get_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,s32 * dbm)1991 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1992 s32 *dbm)
1993 {
1994 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1995 struct net_device *ndev = cfg_to_ndev(cfg);
1996 struct brcmf_if *ifp = netdev_priv(ndev);
1997 s32 qdbm = 0;
1998 s32 err;
1999
2000 brcmf_dbg(TRACE, "Enter\n");
2001 if (!check_vif_up(ifp->vif))
2002 return -EIO;
2003
2004 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &qdbm);
2005 if (err) {
2006 brcmf_err("error (%d)\n", err);
2007 goto done;
2008 }
2009 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2010
2011 done:
2012 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2013 return err;
2014 }
2015
2016 static s32
brcmf_cfg80211_config_default_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool unicast,bool multicast)2017 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2018 u8 key_idx, bool unicast, bool multicast)
2019 {
2020 struct brcmf_if *ifp = netdev_priv(ndev);
2021 u32 index;
2022 u32 wsec;
2023 s32 err = 0;
2024
2025 brcmf_dbg(TRACE, "Enter\n");
2026 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2027 if (!check_vif_up(ifp->vif))
2028 return -EIO;
2029
2030 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2031 if (err) {
2032 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2033 goto done;
2034 }
2035
2036 if (wsec & WEP_ENABLED) {
2037 /* Just select a new current key */
2038 index = key_idx;
2039 err = brcmf_fil_cmd_int_set(ifp,
2040 BRCMF_C_SET_KEY_PRIMARY, index);
2041 if (err)
2042 brcmf_err("error (%d)\n", err);
2043 }
2044 done:
2045 brcmf_dbg(TRACE, "Exit\n");
2046 return err;
2047 }
2048
2049 static s32
brcmf_add_keyext(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,const u8 * mac_addr,struct key_params * params)2050 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2051 u8 key_idx, const u8 *mac_addr, struct key_params *params)
2052 {
2053 struct brcmf_if *ifp = netdev_priv(ndev);
2054 struct brcmf_wsec_key key;
2055 s32 err = 0;
2056 u8 keybuf[8];
2057
2058 memset(&key, 0, sizeof(key));
2059 key.index = (u32) key_idx;
2060 /* Instead of bcast for ea address for default wep keys,
2061 driver needs it to be Null */
2062 if (!is_multicast_ether_addr(mac_addr))
2063 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2064 key.len = (u32) params->key_len;
2065 /* check for key index change */
2066 if (key.len == 0) {
2067 /* key delete */
2068 err = send_key_to_dongle(ifp, &key);
2069 if (err)
2070 brcmf_err("key delete error (%d)\n", err);
2071 } else {
2072 if (key.len > sizeof(key.data)) {
2073 brcmf_err("Invalid key length (%d)\n", key.len);
2074 return -EINVAL;
2075 }
2076
2077 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2078 memcpy(key.data, params->key, key.len);
2079
2080 if (!brcmf_is_apmode(ifp->vif) &&
2081 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2082 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2083 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2084 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2085 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2086 }
2087
2088 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2089 if (params->seq && params->seq_len == 6) {
2090 /* rx iv */
2091 u8 *ivptr;
2092 ivptr = (u8 *) params->seq;
2093 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2094 (ivptr[3] << 8) | ivptr[2];
2095 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2096 key.iv_initialized = true;
2097 }
2098
2099 switch (params->cipher) {
2100 case WLAN_CIPHER_SUITE_WEP40:
2101 key.algo = CRYPTO_ALGO_WEP1;
2102 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2103 break;
2104 case WLAN_CIPHER_SUITE_WEP104:
2105 key.algo = CRYPTO_ALGO_WEP128;
2106 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2107 break;
2108 case WLAN_CIPHER_SUITE_TKIP:
2109 key.algo = CRYPTO_ALGO_TKIP;
2110 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2111 break;
2112 case WLAN_CIPHER_SUITE_AES_CMAC:
2113 key.algo = CRYPTO_ALGO_AES_CCM;
2114 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2115 break;
2116 case WLAN_CIPHER_SUITE_CCMP:
2117 key.algo = CRYPTO_ALGO_AES_CCM;
2118 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2119 break;
2120 default:
2121 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2122 return -EINVAL;
2123 }
2124 err = send_key_to_dongle(ifp, &key);
2125 if (err)
2126 brcmf_err("wsec_key error (%d)\n", err);
2127 }
2128 return err;
2129 }
2130
2131 static s32
brcmf_cfg80211_add_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr,struct key_params * params)2132 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2133 u8 key_idx, bool pairwise, const u8 *mac_addr,
2134 struct key_params *params)
2135 {
2136 struct brcmf_if *ifp = netdev_priv(ndev);
2137 struct brcmf_wsec_key *key;
2138 s32 val;
2139 s32 wsec;
2140 s32 err = 0;
2141 u8 keybuf[8];
2142
2143 brcmf_dbg(TRACE, "Enter\n");
2144 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2145 if (!check_vif_up(ifp->vif))
2146 return -EIO;
2147
2148 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2149 /* we ignore this key index in this case */
2150 brcmf_err("invalid key index (%d)\n", key_idx);
2151 return -EINVAL;
2152 }
2153
2154 if (mac_addr &&
2155 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2156 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2157 brcmf_dbg(TRACE, "Exit");
2158 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2159 }
2160
2161 key = &ifp->vif->profile.key[key_idx];
2162 memset(key, 0, sizeof(*key));
2163
2164 if (params->key_len > sizeof(key->data)) {
2165 brcmf_err("Too long key length (%u)\n", params->key_len);
2166 err = -EINVAL;
2167 goto done;
2168 }
2169 key->len = params->key_len;
2170 key->index = key_idx;
2171
2172 memcpy(key->data, params->key, key->len);
2173
2174 key->flags = BRCMF_PRIMARY_KEY;
2175 switch (params->cipher) {
2176 case WLAN_CIPHER_SUITE_WEP40:
2177 key->algo = CRYPTO_ALGO_WEP1;
2178 val = WEP_ENABLED;
2179 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2180 break;
2181 case WLAN_CIPHER_SUITE_WEP104:
2182 key->algo = CRYPTO_ALGO_WEP128;
2183 val = WEP_ENABLED;
2184 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2185 break;
2186 case WLAN_CIPHER_SUITE_TKIP:
2187 if (!brcmf_is_apmode(ifp->vif)) {
2188 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2189 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2190 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2191 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2192 }
2193 key->algo = CRYPTO_ALGO_TKIP;
2194 val = TKIP_ENABLED;
2195 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2196 break;
2197 case WLAN_CIPHER_SUITE_AES_CMAC:
2198 key->algo = CRYPTO_ALGO_AES_CCM;
2199 val = AES_ENABLED;
2200 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2201 break;
2202 case WLAN_CIPHER_SUITE_CCMP:
2203 key->algo = CRYPTO_ALGO_AES_CCM;
2204 val = AES_ENABLED;
2205 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2206 break;
2207 default:
2208 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2209 err = -EINVAL;
2210 goto done;
2211 }
2212
2213 err = send_key_to_dongle(ifp, key);
2214 if (err)
2215 goto done;
2216
2217 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2218 if (err) {
2219 brcmf_err("get wsec error (%d)\n", err);
2220 goto done;
2221 }
2222 wsec |= val;
2223 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2224 if (err) {
2225 brcmf_err("set wsec error (%d)\n", err);
2226 goto done;
2227 }
2228
2229 done:
2230 brcmf_dbg(TRACE, "Exit\n");
2231 return err;
2232 }
2233
2234 static s32
brcmf_cfg80211_del_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr)2235 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2236 u8 key_idx, bool pairwise, const u8 *mac_addr)
2237 {
2238 struct brcmf_if *ifp = netdev_priv(ndev);
2239 struct brcmf_wsec_key key;
2240 s32 err = 0;
2241
2242 brcmf_dbg(TRACE, "Enter\n");
2243 if (!check_vif_up(ifp->vif))
2244 return -EIO;
2245
2246 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2247 /* we ignore this key index in this case */
2248 return -EINVAL;
2249 }
2250
2251 memset(&key, 0, sizeof(key));
2252
2253 key.index = (u32) key_idx;
2254 key.flags = BRCMF_PRIMARY_KEY;
2255 key.algo = CRYPTO_ALGO_OFF;
2256
2257 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2258
2259 /* Set the new key/index */
2260 err = send_key_to_dongle(ifp, &key);
2261
2262 brcmf_dbg(TRACE, "Exit\n");
2263 return err;
2264 }
2265
2266 static s32
brcmf_cfg80211_get_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params * params))2267 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2268 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2269 void (*callback) (void *cookie, struct key_params * params))
2270 {
2271 struct key_params params;
2272 struct brcmf_if *ifp = netdev_priv(ndev);
2273 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2274 struct brcmf_cfg80211_security *sec;
2275 s32 wsec;
2276 s32 err = 0;
2277
2278 brcmf_dbg(TRACE, "Enter\n");
2279 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2280 if (!check_vif_up(ifp->vif))
2281 return -EIO;
2282
2283 memset(¶ms, 0, sizeof(params));
2284
2285 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2286 if (err) {
2287 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2288 /* Ignore this error, may happen during DISASSOC */
2289 err = -EAGAIN;
2290 goto done;
2291 }
2292 if (wsec & WEP_ENABLED) {
2293 sec = &profile->sec;
2294 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2295 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2296 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2297 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2298 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2299 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2300 }
2301 } else if (wsec & TKIP_ENABLED) {
2302 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2303 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2304 } else if (wsec & AES_ENABLED) {
2305 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2306 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2307 } else {
2308 brcmf_err("Invalid algo (0x%x)\n", wsec);
2309 err = -EINVAL;
2310 goto done;
2311 }
2312 callback(cookie, ¶ms);
2313
2314 done:
2315 brcmf_dbg(TRACE, "Exit\n");
2316 return err;
2317 }
2318
2319 static s32
brcmf_cfg80211_config_default_mgmt_key(struct wiphy * wiphy,struct net_device * ndev,u8 key_idx)2320 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2321 struct net_device *ndev, u8 key_idx)
2322 {
2323 brcmf_dbg(INFO, "Not supported\n");
2324
2325 return -EOPNOTSUPP;
2326 }
2327
2328 static void
brcmf_cfg80211_reconfigure_wep(struct brcmf_if * ifp)2329 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2330 {
2331 s32 err;
2332 u8 key_idx;
2333 struct brcmf_wsec_key *key;
2334 s32 wsec;
2335
2336 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2337 key = &ifp->vif->profile.key[key_idx];
2338 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2339 (key->algo == CRYPTO_ALGO_WEP128))
2340 break;
2341 }
2342 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2343 return;
2344
2345 err = send_key_to_dongle(ifp, key);
2346 if (err) {
2347 brcmf_err("Setting WEP key failed (%d)\n", err);
2348 return;
2349 }
2350 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2351 if (err) {
2352 brcmf_err("get wsec error (%d)\n", err);
2353 return;
2354 }
2355 wsec |= WEP_ENABLED;
2356 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2357 if (err)
2358 brcmf_err("set wsec error (%d)\n", err);
2359 }
2360
brcmf_convert_sta_flags(u32 fw_sta_flags,struct station_info * si)2361 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2362 {
2363 struct nl80211_sta_flag_update *sfu;
2364
2365 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2366 si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2367 sfu = &si->sta_flags;
2368 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2369 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2370 BIT(NL80211_STA_FLAG_ASSOCIATED) |
2371 BIT(NL80211_STA_FLAG_AUTHORIZED);
2372 if (fw_sta_flags & BRCMF_STA_WME)
2373 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2374 if (fw_sta_flags & BRCMF_STA_AUTHE)
2375 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2376 if (fw_sta_flags & BRCMF_STA_ASSOC)
2377 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2378 if (fw_sta_flags & BRCMF_STA_AUTHO)
2379 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2380 }
2381
brcmf_fill_bss_param(struct brcmf_if * ifp,struct station_info * si)2382 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2383 {
2384 struct {
2385 __le32 len;
2386 struct brcmf_bss_info_le bss_le;
2387 } *buf;
2388 u16 capability;
2389 int err;
2390
2391 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2392 if (!buf)
2393 return;
2394
2395 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2396 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2397 WL_BSS_INFO_MAX);
2398 if (err) {
2399 brcmf_err("Failed to get bss info (%d)\n", err);
2400 goto out_kfree;
2401 }
2402 si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2403 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2404 si->bss_param.dtim_period = buf->bss_le.dtim_period;
2405 capability = le16_to_cpu(buf->bss_le.capability);
2406 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2407 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2408 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2409 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2410 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2411 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2412
2413 out_kfree:
2414 kfree(buf);
2415 }
2416
2417 static s32
brcmf_cfg80211_get_station(struct wiphy * wiphy,struct net_device * ndev,const u8 * mac,struct station_info * sinfo)2418 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2419 const u8 *mac, struct station_info *sinfo)
2420 {
2421 struct brcmf_if *ifp = netdev_priv(ndev);
2422 struct brcmf_scb_val_le scb_val;
2423 s32 err = 0;
2424 struct brcmf_sta_info_le sta_info_le;
2425 u32 sta_flags;
2426 u32 is_tdls_peer;
2427 s32 total_rssi;
2428 s32 count_rssi;
2429 int rssi;
2430 u32 i;
2431
2432 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2433 if (!check_vif_up(ifp->vif))
2434 return -EIO;
2435
2436 memset(&sta_info_le, 0, sizeof(sta_info_le));
2437 memcpy(&sta_info_le, mac, ETH_ALEN);
2438 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2439 &sta_info_le,
2440 sizeof(sta_info_le));
2441 is_tdls_peer = !err;
2442 if (err) {
2443 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2444 &sta_info_le,
2445 sizeof(sta_info_le));
2446 if (err < 0) {
2447 brcmf_err("GET STA INFO failed, %d\n", err);
2448 goto done;
2449 }
2450 }
2451 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2452 sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2453 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2454 sta_flags = le32_to_cpu(sta_info_le.flags);
2455 brcmf_convert_sta_flags(sta_flags, sinfo);
2456 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2457 if (is_tdls_peer)
2458 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2459 else
2460 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2461 if (sta_flags & BRCMF_STA_ASSOC) {
2462 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2463 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2464 brcmf_fill_bss_param(ifp, sinfo);
2465 }
2466 if (sta_flags & BRCMF_STA_SCBSTATS) {
2467 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2468 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2469 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2470 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2471 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2472 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2473 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2474 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2475 if (sinfo->tx_packets) {
2476 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2477 sinfo->txrate.legacy =
2478 le32_to_cpu(sta_info_le.tx_rate) / 100;
2479 }
2480 if (sinfo->rx_packets) {
2481 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2482 sinfo->rxrate.legacy =
2483 le32_to_cpu(sta_info_le.rx_rate) / 100;
2484 }
2485 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2486 sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2487 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2488 sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2489 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2490 }
2491 total_rssi = 0;
2492 count_rssi = 0;
2493 for (i = 0; i < BRCMF_ANT_MAX; i++) {
2494 if (sta_info_le.rssi[i]) {
2495 sinfo->chain_signal_avg[count_rssi] =
2496 sta_info_le.rssi[i];
2497 sinfo->chain_signal[count_rssi] =
2498 sta_info_le.rssi[i];
2499 total_rssi += sta_info_le.rssi[i];
2500 count_rssi++;
2501 }
2502 }
2503 if (count_rssi) {
2504 sinfo->filled |= BIT(NL80211_STA_INFO_CHAIN_SIGNAL);
2505 sinfo->chains = count_rssi;
2506
2507 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2508 total_rssi /= count_rssi;
2509 sinfo->signal = total_rssi;
2510 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2511 &ifp->vif->sme_state)) {
2512 memset(&scb_val, 0, sizeof(scb_val));
2513 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2514 &scb_val, sizeof(scb_val));
2515 if (err) {
2516 brcmf_err("Could not get rssi (%d)\n", err);
2517 goto done;
2518 } else {
2519 rssi = le32_to_cpu(scb_val.val);
2520 sinfo->filled |= BIT(NL80211_STA_INFO_SIGNAL);
2521 sinfo->signal = rssi;
2522 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2523 }
2524 }
2525 }
2526 done:
2527 brcmf_dbg(TRACE, "Exit\n");
2528 return err;
2529 }
2530
2531 static int
brcmf_cfg80211_dump_station(struct wiphy * wiphy,struct net_device * ndev,int idx,u8 * mac,struct station_info * sinfo)2532 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
2533 int idx, u8 *mac, struct station_info *sinfo)
2534 {
2535 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2536 struct brcmf_if *ifp = netdev_priv(ndev);
2537 s32 err;
2538
2539 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
2540
2541 if (idx == 0) {
2542 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
2543 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
2544 &cfg->assoclist,
2545 sizeof(cfg->assoclist));
2546 if (err) {
2547 brcmf_err("BRCMF_C_GET_ASSOCLIST unsupported, err=%d\n",
2548 err);
2549 cfg->assoclist.count = 0;
2550 return -EOPNOTSUPP;
2551 }
2552 }
2553 if (idx < le32_to_cpu(cfg->assoclist.count)) {
2554 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
2555 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
2556 }
2557 return -ENOENT;
2558 }
2559
2560 static s32
brcmf_cfg80211_set_power_mgmt(struct wiphy * wiphy,struct net_device * ndev,bool enabled,s32 timeout)2561 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2562 bool enabled, s32 timeout)
2563 {
2564 s32 pm;
2565 s32 err = 0;
2566 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2567 struct brcmf_if *ifp = netdev_priv(ndev);
2568
2569 brcmf_dbg(TRACE, "Enter\n");
2570
2571 /*
2572 * Powersave enable/disable request is coming from the
2573 * cfg80211 even before the interface is up. In that
2574 * scenario, driver will be storing the power save
2575 * preference in cfg struct to apply this to
2576 * FW later while initializing the dongle
2577 */
2578 cfg->pwr_save = enabled;
2579 if (!check_vif_up(ifp->vif)) {
2580
2581 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2582 goto done;
2583 }
2584
2585 pm = enabled ? PM_FAST : PM_OFF;
2586 /* Do not enable the power save after assoc if it is a p2p interface */
2587 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2588 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2589 pm = PM_OFF;
2590 }
2591 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2592
2593 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2594 if (err) {
2595 if (err == -ENODEV)
2596 brcmf_err("net_device is not ready yet\n");
2597 else
2598 brcmf_err("error (%d)\n", err);
2599 }
2600 done:
2601 brcmf_dbg(TRACE, "Exit\n");
2602 return err;
2603 }
2604
brcmf_inform_single_bss(struct brcmf_cfg80211_info * cfg,struct brcmf_bss_info_le * bi)2605 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2606 struct brcmf_bss_info_le *bi)
2607 {
2608 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2609 struct ieee80211_channel *notify_channel;
2610 struct cfg80211_bss *bss;
2611 struct ieee80211_supported_band *band;
2612 struct brcmu_chan ch;
2613 u16 channel;
2614 u32 freq;
2615 u16 notify_capability;
2616 u16 notify_interval;
2617 u8 *notify_ie;
2618 size_t notify_ielen;
2619 s32 notify_signal;
2620
2621 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2622 brcmf_err("Bss info is larger than buffer. Discarding\n");
2623 return 0;
2624 }
2625
2626 if (!bi->ctl_ch) {
2627 ch.chspec = le16_to_cpu(bi->chanspec);
2628 cfg->d11inf.decchspec(&ch);
2629 bi->ctl_ch = ch.chnum;
2630 }
2631 channel = bi->ctl_ch;
2632
2633 if (channel <= CH_MAX_2G_CHANNEL)
2634 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2635 else
2636 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2637
2638 freq = ieee80211_channel_to_frequency(channel, band->band);
2639 notify_channel = ieee80211_get_channel(wiphy, freq);
2640
2641 notify_capability = le16_to_cpu(bi->capability);
2642 notify_interval = le16_to_cpu(bi->beacon_period);
2643 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2644 notify_ielen = le32_to_cpu(bi->ie_length);
2645 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2646
2647 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2648 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2649 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2650 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2651 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2652
2653 bss = cfg80211_inform_bss(wiphy, notify_channel,
2654 CFG80211_BSS_FTYPE_UNKNOWN,
2655 (const u8 *)bi->BSSID,
2656 0, notify_capability,
2657 notify_interval, notify_ie,
2658 notify_ielen, notify_signal,
2659 GFP_KERNEL);
2660
2661 if (!bss)
2662 return -ENOMEM;
2663
2664 cfg80211_put_bss(wiphy, bss);
2665
2666 return 0;
2667 }
2668
2669 static struct brcmf_bss_info_le *
next_bss_le(struct brcmf_scan_results * list,struct brcmf_bss_info_le * bss)2670 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2671 {
2672 if (bss == NULL)
2673 return list->bss_info_le;
2674 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2675 le32_to_cpu(bss->length));
2676 }
2677
brcmf_inform_bss(struct brcmf_cfg80211_info * cfg)2678 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2679 {
2680 struct brcmf_scan_results *bss_list;
2681 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2682 s32 err = 0;
2683 int i;
2684
2685 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2686 if (bss_list->count != 0 &&
2687 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2688 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2689 bss_list->version);
2690 return -EOPNOTSUPP;
2691 }
2692 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2693 for (i = 0; i < bss_list->count; i++) {
2694 bi = next_bss_le(bss_list, bi);
2695 err = brcmf_inform_single_bss(cfg, bi);
2696 if (err)
2697 break;
2698 }
2699 return err;
2700 }
2701
wl_inform_ibss(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const u8 * bssid)2702 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2703 struct net_device *ndev, const u8 *bssid)
2704 {
2705 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2706 struct ieee80211_channel *notify_channel;
2707 struct brcmf_bss_info_le *bi = NULL;
2708 struct ieee80211_supported_band *band;
2709 struct cfg80211_bss *bss;
2710 struct brcmu_chan ch;
2711 u8 *buf = NULL;
2712 s32 err = 0;
2713 u32 freq;
2714 u16 notify_capability;
2715 u16 notify_interval;
2716 u8 *notify_ie;
2717 size_t notify_ielen;
2718 s32 notify_signal;
2719
2720 brcmf_dbg(TRACE, "Enter\n");
2721
2722 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2723 if (buf == NULL) {
2724 err = -ENOMEM;
2725 goto CleanUp;
2726 }
2727
2728 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2729
2730 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2731 buf, WL_BSS_INFO_MAX);
2732 if (err) {
2733 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2734 goto CleanUp;
2735 }
2736
2737 bi = (struct brcmf_bss_info_le *)(buf + 4);
2738
2739 ch.chspec = le16_to_cpu(bi->chanspec);
2740 cfg->d11inf.decchspec(&ch);
2741
2742 if (ch.band == BRCMU_CHAN_BAND_2G)
2743 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2744 else
2745 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2746
2747 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2748 notify_channel = ieee80211_get_channel(wiphy, freq);
2749
2750 notify_capability = le16_to_cpu(bi->capability);
2751 notify_interval = le16_to_cpu(bi->beacon_period);
2752 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2753 notify_ielen = le32_to_cpu(bi->ie_length);
2754 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2755
2756 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2757 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2758 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2759 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2760
2761 bss = cfg80211_inform_bss(wiphy, notify_channel,
2762 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2763 notify_capability, notify_interval,
2764 notify_ie, notify_ielen, notify_signal,
2765 GFP_KERNEL);
2766
2767 if (!bss) {
2768 err = -ENOMEM;
2769 goto CleanUp;
2770 }
2771
2772 cfg80211_put_bss(wiphy, bss);
2773
2774 CleanUp:
2775
2776 kfree(buf);
2777
2778 brcmf_dbg(TRACE, "Exit\n");
2779
2780 return err;
2781 }
2782
brcmf_update_bss_info(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp)2783 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2784 struct brcmf_if *ifp)
2785 {
2786 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2787 struct brcmf_bss_info_le *bi;
2788 struct brcmf_ssid *ssid;
2789 const struct brcmf_tlv *tim;
2790 u16 beacon_interval;
2791 u8 dtim_period;
2792 size_t ie_len;
2793 u8 *ie;
2794 s32 err = 0;
2795
2796 brcmf_dbg(TRACE, "Enter\n");
2797 if (brcmf_is_ibssmode(ifp->vif))
2798 return err;
2799
2800 ssid = &profile->ssid;
2801
2802 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2803 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2804 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2805 if (err) {
2806 brcmf_err("Could not get bss info %d\n", err);
2807 goto update_bss_info_out;
2808 }
2809
2810 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2811 err = brcmf_inform_single_bss(cfg, bi);
2812 if (err)
2813 goto update_bss_info_out;
2814
2815 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2816 ie_len = le32_to_cpu(bi->ie_length);
2817 beacon_interval = le16_to_cpu(bi->beacon_period);
2818
2819 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2820 if (tim)
2821 dtim_period = tim->data[1];
2822 else {
2823 /*
2824 * active scan was done so we could not get dtim
2825 * information out of probe response.
2826 * so we speficially query dtim information to dongle.
2827 */
2828 u32 var;
2829 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2830 if (err) {
2831 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2832 goto update_bss_info_out;
2833 }
2834 dtim_period = (u8)var;
2835 }
2836
2837 update_bss_info_out:
2838 brcmf_dbg(TRACE, "Exit");
2839 return err;
2840 }
2841
brcmf_abort_scanning(struct brcmf_cfg80211_info * cfg)2842 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2843 {
2844 struct escan_info *escan = &cfg->escan_info;
2845
2846 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2847 if (cfg->scan_request) {
2848 escan->escan_state = WL_ESCAN_STATE_IDLE;
2849 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2850 }
2851 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2852 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2853 }
2854
brcmf_cfg80211_escan_timeout_worker(struct work_struct * work)2855 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2856 {
2857 struct brcmf_cfg80211_info *cfg =
2858 container_of(work, struct brcmf_cfg80211_info,
2859 escan_timeout_work);
2860
2861 brcmf_inform_bss(cfg);
2862 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2863 }
2864
brcmf_escan_timeout(unsigned long data)2865 static void brcmf_escan_timeout(unsigned long data)
2866 {
2867 struct brcmf_cfg80211_info *cfg =
2868 (struct brcmf_cfg80211_info *)data;
2869
2870 if (cfg->scan_request) {
2871 brcmf_err("timer expired\n");
2872 schedule_work(&cfg->escan_timeout_work);
2873 }
2874 }
2875
2876 static s32
brcmf_compare_update_same_bss(struct brcmf_cfg80211_info * cfg,struct brcmf_bss_info_le * bss,struct brcmf_bss_info_le * bss_info_le)2877 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2878 struct brcmf_bss_info_le *bss,
2879 struct brcmf_bss_info_le *bss_info_le)
2880 {
2881 struct brcmu_chan ch_bss, ch_bss_info_le;
2882
2883 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2884 cfg->d11inf.decchspec(&ch_bss);
2885 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2886 cfg->d11inf.decchspec(&ch_bss_info_le);
2887
2888 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2889 ch_bss.band == ch_bss_info_le.band &&
2890 bss_info_le->SSID_len == bss->SSID_len &&
2891 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2892 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2893 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2894 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2895 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2896
2897 /* preserve max RSSI if the measurements are
2898 * both on-channel or both off-channel
2899 */
2900 if (bss_info_rssi > bss_rssi)
2901 bss->RSSI = bss_info_le->RSSI;
2902 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2903 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2904 /* preserve the on-channel rssi measurement
2905 * if the new measurement is off channel
2906 */
2907 bss->RSSI = bss_info_le->RSSI;
2908 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2909 }
2910 return 1;
2911 }
2912 return 0;
2913 }
2914
2915 static s32
brcmf_cfg80211_escan_handler(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)2916 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2917 const struct brcmf_event_msg *e, void *data)
2918 {
2919 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2920 s32 status;
2921 struct brcmf_escan_result_le *escan_result_le;
2922 u32 escan_buflen;
2923 struct brcmf_bss_info_le *bss_info_le;
2924 struct brcmf_bss_info_le *bss = NULL;
2925 u32 bi_length;
2926 struct brcmf_scan_results *list;
2927 u32 i;
2928 bool aborted;
2929
2930 status = e->status;
2931
2932 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2933 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2934 return -EPERM;
2935 }
2936
2937 if (status == BRCMF_E_STATUS_PARTIAL) {
2938 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2939 if (e->datalen < sizeof(*escan_result_le)) {
2940 brcmf_err("invalid event data length\n");
2941 goto exit;
2942 }
2943 escan_result_le = (struct brcmf_escan_result_le *) data;
2944 if (!escan_result_le) {
2945 brcmf_err("Invalid escan result (NULL pointer)\n");
2946 goto exit;
2947 }
2948 escan_buflen = le32_to_cpu(escan_result_le->buflen);
2949 if (escan_buflen > WL_ESCAN_BUF_SIZE ||
2950 escan_buflen > e->datalen ||
2951 escan_buflen < sizeof(*escan_result_le)) {
2952 brcmf_err("Invalid escan buffer length: %d\n",
2953 escan_buflen);
2954 goto exit;
2955 }
2956 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2957 brcmf_err("Invalid bss_count %d: ignoring\n",
2958 escan_result_le->bss_count);
2959 goto exit;
2960 }
2961 bss_info_le = &escan_result_le->bss_info_le;
2962
2963 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2964 goto exit;
2965
2966 if (!cfg->scan_request) {
2967 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2968 goto exit;
2969 }
2970
2971 bi_length = le32_to_cpu(bss_info_le->length);
2972 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
2973 brcmf_err("Ignoring invalid bss_info length: %d\n",
2974 bi_length);
2975 goto exit;
2976 }
2977
2978 if (!(cfg_to_wiphy(cfg)->interface_modes &
2979 BIT(NL80211_IFTYPE_ADHOC))) {
2980 if (le16_to_cpu(bss_info_le->capability) &
2981 WLAN_CAPABILITY_IBSS) {
2982 brcmf_err("Ignoring IBSS result\n");
2983 goto exit;
2984 }
2985 }
2986
2987 list = (struct brcmf_scan_results *)
2988 cfg->escan_info.escan_buf;
2989 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2990 brcmf_err("Buffer is too small: ignoring\n");
2991 goto exit;
2992 }
2993
2994 for (i = 0; i < list->count; i++) {
2995 bss = bss ? (struct brcmf_bss_info_le *)
2996 ((unsigned char *)bss +
2997 le32_to_cpu(bss->length)) : list->bss_info_le;
2998 if (brcmf_compare_update_same_bss(cfg, bss,
2999 bss_info_le))
3000 goto exit;
3001 }
3002 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
3003 bss_info_le, bi_length);
3004 list->version = le32_to_cpu(bss_info_le->version);
3005 list->buflen += bi_length;
3006 list->count++;
3007 } else {
3008 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3009 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3010 goto exit;
3011 if (cfg->scan_request) {
3012 brcmf_inform_bss(cfg);
3013 aborted = status != BRCMF_E_STATUS_SUCCESS;
3014 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3015 } else
3016 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3017 status);
3018 }
3019 exit:
3020 return 0;
3021 }
3022
brcmf_init_escan(struct brcmf_cfg80211_info * cfg)3023 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3024 {
3025 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3026 brcmf_cfg80211_escan_handler);
3027 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3028 /* Init scan_timeout timer */
3029 init_timer(&cfg->escan_timeout);
3030 cfg->escan_timeout.data = (unsigned long) cfg;
3031 cfg->escan_timeout.function = brcmf_escan_timeout;
3032 INIT_WORK(&cfg->escan_timeout_work,
3033 brcmf_cfg80211_escan_timeout_worker);
3034 }
3035
brcmf_delay(u32 ms)3036 static __always_inline void brcmf_delay(u32 ms)
3037 {
3038 if (ms < 1000 / HZ) {
3039 cond_resched();
3040 mdelay(ms);
3041 } else {
3042 msleep(ms);
3043 }
3044 }
3045
brcmf_config_wowl_pattern(struct brcmf_if * ifp,u8 cmd[4],u8 * pattern,u32 patternsize,u8 * mask,u32 packet_offset)3046 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3047 u8 *pattern, u32 patternsize, u8 *mask,
3048 u32 packet_offset)
3049 {
3050 struct brcmf_fil_wowl_pattern_le *filter;
3051 u32 masksize;
3052 u32 patternoffset;
3053 u8 *buf;
3054 u32 bufsize;
3055 s32 ret;
3056
3057 masksize = (patternsize + 7) / 8;
3058 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3059
3060 bufsize = sizeof(*filter) + patternsize + masksize;
3061 buf = kzalloc(bufsize, GFP_KERNEL);
3062 if (!buf)
3063 return -ENOMEM;
3064 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3065
3066 memcpy(filter->cmd, cmd, 4);
3067 filter->masksize = cpu_to_le32(masksize);
3068 filter->offset = cpu_to_le32(packet_offset);
3069 filter->patternoffset = cpu_to_le32(patternoffset);
3070 filter->patternsize = cpu_to_le32(patternsize);
3071 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3072
3073 if ((mask) && (masksize))
3074 memcpy(buf + sizeof(*filter), mask, masksize);
3075 if ((pattern) && (patternsize))
3076 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3077
3078 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3079
3080 kfree(buf);
3081 return ret;
3082 }
3083
brcmf_cfg80211_resume(struct wiphy * wiphy)3084 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3085 {
3086 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3087 struct net_device *ndev = cfg_to_ndev(cfg);
3088 struct brcmf_if *ifp = netdev_priv(ndev);
3089
3090 brcmf_dbg(TRACE, "Enter\n");
3091
3092 if (cfg->wowl_enabled) {
3093 brcmf_configure_arp_offload(ifp, true);
3094 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3095 cfg->pre_wowl_pmmode);
3096 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3097 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3098 cfg->wowl_enabled = false;
3099 }
3100 return 0;
3101 }
3102
brcmf_configure_wowl(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,struct cfg80211_wowlan * wowl)3103 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3104 struct brcmf_if *ifp,
3105 struct cfg80211_wowlan *wowl)
3106 {
3107 u32 wowl_config;
3108 u32 i;
3109
3110 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3111
3112 brcmf_configure_arp_offload(ifp, false);
3113 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
3114 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3115
3116 wowl_config = 0;
3117 if (wowl->disconnect)
3118 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3119 if (wowl->magic_pkt)
3120 wowl_config |= BRCMF_WOWL_MAGIC;
3121 if ((wowl->patterns) && (wowl->n_patterns)) {
3122 wowl_config |= BRCMF_WOWL_NET;
3123 for (i = 0; i < wowl->n_patterns; i++) {
3124 brcmf_config_wowl_pattern(ifp, "add",
3125 (u8 *)wowl->patterns[i].pattern,
3126 wowl->patterns[i].pattern_len,
3127 (u8 *)wowl->patterns[i].mask,
3128 wowl->patterns[i].pkt_offset);
3129 }
3130 }
3131 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3132 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3133 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3134 cfg->wowl_enabled = true;
3135 }
3136
brcmf_cfg80211_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wowl)3137 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3138 struct cfg80211_wowlan *wowl)
3139 {
3140 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3141 struct net_device *ndev = cfg_to_ndev(cfg);
3142 struct brcmf_if *ifp = netdev_priv(ndev);
3143 struct brcmf_cfg80211_vif *vif;
3144
3145 brcmf_dbg(TRACE, "Enter\n");
3146
3147 /* if the primary net_device is not READY there is nothing
3148 * we can do but pray resume goes smoothly.
3149 */
3150 if (!check_vif_up(ifp->vif))
3151 goto exit;
3152
3153 /* end any scanning */
3154 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3155 brcmf_abort_scanning(cfg);
3156
3157 if (wowl == NULL) {
3158 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3159 list_for_each_entry(vif, &cfg->vif_list, list) {
3160 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3161 continue;
3162 /* While going to suspend if associated with AP
3163 * disassociate from AP to save power while system is
3164 * in suspended state
3165 */
3166 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3167 /* Make sure WPA_Supplicant receives all the event
3168 * generated due to DISASSOC call to the fw to keep
3169 * the state fw and WPA_Supplicant state consistent
3170 */
3171 brcmf_delay(500);
3172 }
3173 /* Configure MPC */
3174 brcmf_set_mpc(ifp, 1);
3175
3176 } else {
3177 /* Configure WOWL paramaters */
3178 brcmf_configure_wowl(cfg, ifp, wowl);
3179 }
3180
3181 exit:
3182 brcmf_dbg(TRACE, "Exit\n");
3183 /* clear any scanning activity */
3184 cfg->scan_status = 0;
3185 return 0;
3186 }
3187
3188 static __used s32
brcmf_update_pmklist(struct net_device * ndev,struct brcmf_cfg80211_pmk_list * pmk_list,s32 err)3189 brcmf_update_pmklist(struct net_device *ndev,
3190 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3191 {
3192 int i, j;
3193 u32 pmkid_len;
3194
3195 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3196
3197 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
3198 for (i = 0; i < pmkid_len; i++) {
3199 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
3200 &pmk_list->pmkids.pmkid[i].BSSID);
3201 for (j = 0; j < WLAN_PMKID_LEN; j++)
3202 brcmf_dbg(CONN, "%02x\n",
3203 pmk_list->pmkids.pmkid[i].PMKID[j]);
3204 }
3205
3206 if (!err)
3207 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
3208 (char *)pmk_list, sizeof(*pmk_list));
3209
3210 return err;
3211 }
3212
3213 static s32
brcmf_cfg80211_set_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)3214 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3215 struct cfg80211_pmksa *pmksa)
3216 {
3217 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3218 struct brcmf_if *ifp = netdev_priv(ndev);
3219 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3220 s32 err = 0;
3221 u32 pmkid_len, i;
3222
3223 brcmf_dbg(TRACE, "Enter\n");
3224 if (!check_vif_up(ifp->vif))
3225 return -EIO;
3226
3227 pmkid_len = le32_to_cpu(pmkids->npmkid);
3228 for (i = 0; i < pmkid_len; i++)
3229 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3230 break;
3231 if (i < WL_NUM_PMKIDS_MAX) {
3232 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3233 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3234 if (i == pmkid_len) {
3235 pmkid_len++;
3236 pmkids->npmkid = cpu_to_le32(pmkid_len);
3237 }
3238 } else
3239 err = -EINVAL;
3240
3241 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3242 pmkids->pmkid[pmkid_len].BSSID);
3243 for (i = 0; i < WLAN_PMKID_LEN; i++)
3244 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3245
3246 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3247
3248 brcmf_dbg(TRACE, "Exit\n");
3249 return err;
3250 }
3251
3252 static s32
brcmf_cfg80211_del_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)3253 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3254 struct cfg80211_pmksa *pmksa)
3255 {
3256 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3257 struct brcmf_if *ifp = netdev_priv(ndev);
3258 struct pmkid_list pmkid;
3259 s32 err = 0;
3260 u32 pmkid_len, i;
3261
3262 brcmf_dbg(TRACE, "Enter\n");
3263 if (!check_vif_up(ifp->vif))
3264 return -EIO;
3265
3266 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3267 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3268
3269 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3270 &pmkid.pmkid[0].BSSID);
3271 for (i = 0; i < WLAN_PMKID_LEN; i++)
3272 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
3273
3274 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3275 for (i = 0; i < pmkid_len; i++)
3276 if (!memcmp
3277 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3278 ETH_ALEN))
3279 break;
3280
3281 if ((pmkid_len > 0)
3282 && (i < pmkid_len)) {
3283 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3284 sizeof(struct pmkid));
3285 for (; i < (pmkid_len - 1); i++) {
3286 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3287 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3288 ETH_ALEN);
3289 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3290 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3291 WLAN_PMKID_LEN);
3292 }
3293 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3294 } else
3295 err = -EINVAL;
3296
3297 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3298
3299 brcmf_dbg(TRACE, "Exit\n");
3300 return err;
3301
3302 }
3303
3304 static s32
brcmf_cfg80211_flush_pmksa(struct wiphy * wiphy,struct net_device * ndev)3305 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3306 {
3307 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3308 struct brcmf_if *ifp = netdev_priv(ndev);
3309 s32 err = 0;
3310
3311 brcmf_dbg(TRACE, "Enter\n");
3312 if (!check_vif_up(ifp->vif))
3313 return -EIO;
3314
3315 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3316 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3317
3318 brcmf_dbg(TRACE, "Exit\n");
3319 return err;
3320
3321 }
3322
3323 /*
3324 * PFN result doesn't have all the info which are
3325 * required by the supplicant
3326 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3327 * via wl_inform_single_bss in the required format. Escan does require the
3328 * scan request in the form of cfg80211_scan_request. For timebeing, create
3329 * cfg80211_scan_request one out of the received PNO event.
3330 */
3331 static s32
brcmf_notify_sched_scan_results(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)3332 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3333 const struct brcmf_event_msg *e, void *data)
3334 {
3335 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3336 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3337 struct cfg80211_scan_request *request = NULL;
3338 struct cfg80211_ssid *ssid = NULL;
3339 struct ieee80211_channel *channel = NULL;
3340 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3341 int err = 0;
3342 int channel_req = 0;
3343 int band = 0;
3344 struct brcmf_pno_scanresults_le *pfn_result;
3345 u32 result_count;
3346 u32 status;
3347 u32 datalen;
3348
3349 brcmf_dbg(SCAN, "Enter\n");
3350
3351 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3352 brcmf_dbg(SCAN, "Event data to small. Ignore\n");
3353 return 0;
3354 }
3355
3356 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3357 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3358 return 0;
3359 }
3360
3361 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3362 result_count = le32_to_cpu(pfn_result->count);
3363 status = le32_to_cpu(pfn_result->status);
3364
3365 /*
3366 * PFN event is limited to fit 512 bytes so we may get
3367 * multiple NET_FOUND events. For now place a warning here.
3368 */
3369 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3370 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3371 if (result_count > 0) {
3372 int i;
3373
3374 data += sizeof(struct brcmf_pno_scanresults_le);
3375 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3376 datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3377 if (datalen < result_count * sizeof(*netinfo)) {
3378 brcmf_err("insufficient event data\n");
3379 goto out_err;
3380 }
3381
3382 request = kzalloc(sizeof(*request), GFP_KERNEL);
3383 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3384 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3385 if (!request || !ssid || !channel) {
3386 err = -ENOMEM;
3387 goto out_err;
3388 }
3389
3390 request->wiphy = wiphy;
3391 for (i = 0; i < result_count; i++) {
3392 netinfo = &netinfo_start[i];
3393 if (!netinfo) {
3394 brcmf_err("Invalid netinfo ptr. index: %d\n",
3395 i);
3396 err = -EINVAL;
3397 goto out_err;
3398 }
3399
3400 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3401 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3402 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3403 netinfo->SSID, netinfo->channel);
3404 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3405 ssid[i].ssid_len = netinfo->SSID_len;
3406 request->n_ssids++;
3407
3408 channel_req = netinfo->channel;
3409 if (channel_req <= CH_MAX_2G_CHANNEL)
3410 band = NL80211_BAND_2GHZ;
3411 else
3412 band = NL80211_BAND_5GHZ;
3413 channel[i].center_freq =
3414 ieee80211_channel_to_frequency(channel_req,
3415 band);
3416 channel[i].band = band;
3417 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3418 request->channels[i] = &channel[i];
3419 request->n_channels++;
3420 }
3421
3422 /* assign parsed ssid array */
3423 if (request->n_ssids)
3424 request->ssids = &ssid[0];
3425
3426 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3427 /* Abort any on-going scan */
3428 brcmf_abort_scanning(cfg);
3429 }
3430
3431 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3432 cfg->escan_info.run = brcmf_run_escan;
3433 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3434 if (err) {
3435 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3436 goto out_err;
3437 }
3438 cfg->sched_escan = true;
3439 cfg->scan_request = request;
3440 } else {
3441 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3442 goto out_err;
3443 }
3444
3445 kfree(ssid);
3446 kfree(channel);
3447 kfree(request);
3448 return 0;
3449
3450 out_err:
3451 kfree(ssid);
3452 kfree(channel);
3453 kfree(request);
3454 cfg80211_sched_scan_stopped(wiphy);
3455 return err;
3456 }
3457
brcmf_dev_pno_clean(struct net_device * ndev)3458 static int brcmf_dev_pno_clean(struct net_device *ndev)
3459 {
3460 int ret;
3461
3462 /* Disable pfn */
3463 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3464 if (ret == 0) {
3465 /* clear pfn */
3466 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3467 NULL, 0);
3468 }
3469 if (ret < 0)
3470 brcmf_err("failed code %d\n", ret);
3471
3472 return ret;
3473 }
3474
brcmf_dev_pno_config(struct net_device * ndev)3475 static int brcmf_dev_pno_config(struct net_device *ndev)
3476 {
3477 struct brcmf_pno_param_le pfn_param;
3478
3479 memset(&pfn_param, 0, sizeof(pfn_param));
3480 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3481
3482 /* set extra pno params */
3483 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3484 pfn_param.repeat = BRCMF_PNO_REPEAT;
3485 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3486
3487 /* set up pno scan fr */
3488 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3489
3490 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3491 &pfn_param, sizeof(pfn_param));
3492 }
3493
3494 static int
brcmf_cfg80211_sched_scan_start(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_sched_scan_request * request)3495 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3496 struct net_device *ndev,
3497 struct cfg80211_sched_scan_request *request)
3498 {
3499 struct brcmf_if *ifp = netdev_priv(ndev);
3500 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3501 struct brcmf_pno_net_param_le pfn;
3502 int i;
3503 int ret = 0;
3504
3505 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3506 request->n_match_sets, request->n_ssids);
3507 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3508 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3509 return -EAGAIN;
3510 }
3511 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3512 brcmf_err("Scanning suppressed: status (%lu)\n",
3513 cfg->scan_status);
3514 return -EAGAIN;
3515 }
3516
3517 if (!request->n_ssids || !request->n_match_sets) {
3518 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3519 request->n_ssids);
3520 return -EINVAL;
3521 }
3522
3523 if (request->n_ssids > 0) {
3524 for (i = 0; i < request->n_ssids; i++) {
3525 /* Active scan req for ssids */
3526 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3527 request->ssids[i].ssid);
3528
3529 /*
3530 * match_set ssids is a supert set of n_ssid list,
3531 * so we need not add these set seperately.
3532 */
3533 }
3534 }
3535
3536 if (request->n_match_sets > 0) {
3537 /* clean up everything */
3538 ret = brcmf_dev_pno_clean(ndev);
3539 if (ret < 0) {
3540 brcmf_err("failed error=%d\n", ret);
3541 return ret;
3542 }
3543
3544 /* configure pno */
3545 ret = brcmf_dev_pno_config(ndev);
3546 if (ret < 0) {
3547 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3548 return -EINVAL;
3549 }
3550
3551 /* configure each match set */
3552 for (i = 0; i < request->n_match_sets; i++) {
3553 struct cfg80211_ssid *ssid;
3554 u32 ssid_len;
3555
3556 ssid = &request->match_sets[i].ssid;
3557 ssid_len = ssid->ssid_len;
3558
3559 if (!ssid_len) {
3560 brcmf_err("skip broadcast ssid\n");
3561 continue;
3562 }
3563 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3564 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3565 pfn.wsec = cpu_to_le32(0);
3566 pfn.infra = cpu_to_le32(1);
3567 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3568 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3569 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3570 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3571 sizeof(pfn));
3572 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3573 ret == 0 ? "set" : "failed", ssid->ssid);
3574 }
3575 /* Enable the PNO */
3576 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3577 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3578 return -EINVAL;
3579 }
3580 } else {
3581 return -EINVAL;
3582 }
3583
3584 return 0;
3585 }
3586
brcmf_cfg80211_sched_scan_stop(struct wiphy * wiphy,struct net_device * ndev)3587 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3588 struct net_device *ndev)
3589 {
3590 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3591
3592 brcmf_dbg(SCAN, "enter\n");
3593 brcmf_dev_pno_clean(ndev);
3594 if (cfg->sched_escan)
3595 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3596 return 0;
3597 }
3598
brcmf_configure_opensecurity(struct brcmf_if * ifp)3599 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3600 {
3601 s32 err;
3602
3603 /* set auth */
3604 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3605 if (err < 0) {
3606 brcmf_err("auth error %d\n", err);
3607 return err;
3608 }
3609 /* set wsec */
3610 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3611 if (err < 0) {
3612 brcmf_err("wsec error %d\n", err);
3613 return err;
3614 }
3615 /* set upper-layer auth */
3616 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3617 if (err < 0) {
3618 brcmf_err("wpa_auth error %d\n", err);
3619 return err;
3620 }
3621
3622 return 0;
3623 }
3624
brcmf_valid_wpa_oui(u8 * oui,bool is_rsn_ie)3625 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3626 {
3627 if (is_rsn_ie)
3628 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3629
3630 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3631 }
3632
3633 static s32
brcmf_configure_wpaie(struct brcmf_if * ifp,const struct brcmf_vs_tlv * wpa_ie,bool is_rsn_ie)3634 brcmf_configure_wpaie(struct brcmf_if *ifp,
3635 const struct brcmf_vs_tlv *wpa_ie,
3636 bool is_rsn_ie)
3637 {
3638 u32 auth = 0; /* d11 open authentication */
3639 u16 count;
3640 s32 err = 0;
3641 s32 len = 0;
3642 u32 i;
3643 u32 wsec;
3644 u32 pval = 0;
3645 u32 gval = 0;
3646 u32 wpa_auth = 0;
3647 u32 offset;
3648 u8 *data;
3649 u16 rsn_cap;
3650 u32 wme_bss_disable;
3651
3652 brcmf_dbg(TRACE, "Enter\n");
3653 if (wpa_ie == NULL)
3654 goto exit;
3655
3656 len = wpa_ie->len + TLV_HDR_LEN;
3657 data = (u8 *)wpa_ie;
3658 offset = TLV_HDR_LEN;
3659 if (!is_rsn_ie)
3660 offset += VS_IE_FIXED_HDR_LEN;
3661 else
3662 offset += WPA_IE_VERSION_LEN;
3663
3664 /* check for multicast cipher suite */
3665 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3666 err = -EINVAL;
3667 brcmf_err("no multicast cipher suite\n");
3668 goto exit;
3669 }
3670
3671 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3672 err = -EINVAL;
3673 brcmf_err("ivalid OUI\n");
3674 goto exit;
3675 }
3676 offset += TLV_OUI_LEN;
3677
3678 /* pick up multicast cipher */
3679 switch (data[offset]) {
3680 case WPA_CIPHER_NONE:
3681 gval = 0;
3682 break;
3683 case WPA_CIPHER_WEP_40:
3684 case WPA_CIPHER_WEP_104:
3685 gval = WEP_ENABLED;
3686 break;
3687 case WPA_CIPHER_TKIP:
3688 gval = TKIP_ENABLED;
3689 break;
3690 case WPA_CIPHER_AES_CCM:
3691 gval = AES_ENABLED;
3692 break;
3693 default:
3694 err = -EINVAL;
3695 brcmf_err("Invalid multi cast cipher info\n");
3696 goto exit;
3697 }
3698
3699 offset++;
3700 /* walk thru unicast cipher list and pick up what we recognize */
3701 count = data[offset] + (data[offset + 1] << 8);
3702 offset += WPA_IE_SUITE_COUNT_LEN;
3703 /* Check for unicast suite(s) */
3704 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3705 err = -EINVAL;
3706 brcmf_err("no unicast cipher suite\n");
3707 goto exit;
3708 }
3709 for (i = 0; i < count; i++) {
3710 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3711 err = -EINVAL;
3712 brcmf_err("ivalid OUI\n");
3713 goto exit;
3714 }
3715 offset += TLV_OUI_LEN;
3716 switch (data[offset]) {
3717 case WPA_CIPHER_NONE:
3718 break;
3719 case WPA_CIPHER_WEP_40:
3720 case WPA_CIPHER_WEP_104:
3721 pval |= WEP_ENABLED;
3722 break;
3723 case WPA_CIPHER_TKIP:
3724 pval |= TKIP_ENABLED;
3725 break;
3726 case WPA_CIPHER_AES_CCM:
3727 pval |= AES_ENABLED;
3728 break;
3729 default:
3730 brcmf_err("Ivalid unicast security info\n");
3731 }
3732 offset++;
3733 }
3734 /* walk thru auth management suite list and pick up what we recognize */
3735 count = data[offset] + (data[offset + 1] << 8);
3736 offset += WPA_IE_SUITE_COUNT_LEN;
3737 /* Check for auth key management suite(s) */
3738 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3739 err = -EINVAL;
3740 brcmf_err("no auth key mgmt suite\n");
3741 goto exit;
3742 }
3743 for (i = 0; i < count; i++) {
3744 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3745 err = -EINVAL;
3746 brcmf_err("ivalid OUI\n");
3747 goto exit;
3748 }
3749 offset += TLV_OUI_LEN;
3750 switch (data[offset]) {
3751 case RSN_AKM_NONE:
3752 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3753 wpa_auth |= WPA_AUTH_NONE;
3754 break;
3755 case RSN_AKM_UNSPECIFIED:
3756 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3757 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3758 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3759 break;
3760 case RSN_AKM_PSK:
3761 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3762 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3763 (wpa_auth |= WPA_AUTH_PSK);
3764 break;
3765 default:
3766 brcmf_err("Ivalid key mgmt info\n");
3767 }
3768 offset++;
3769 }
3770
3771 if (is_rsn_ie) {
3772 wme_bss_disable = 1;
3773 if ((offset + RSN_CAP_LEN) <= len) {
3774 rsn_cap = data[offset] + (data[offset + 1] << 8);
3775 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3776 wme_bss_disable = 0;
3777 }
3778 /* set wme_bss_disable to sync RSN Capabilities */
3779 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3780 wme_bss_disable);
3781 if (err < 0) {
3782 brcmf_err("wme_bss_disable error %d\n", err);
3783 goto exit;
3784 }
3785 }
3786 /* FOR WPS , set SES_OW_ENABLED */
3787 wsec = (pval | gval | SES_OW_ENABLED);
3788
3789 /* set auth */
3790 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3791 if (err < 0) {
3792 brcmf_err("auth error %d\n", err);
3793 goto exit;
3794 }
3795 /* set wsec */
3796 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3797 if (err < 0) {
3798 brcmf_err("wsec error %d\n", err);
3799 goto exit;
3800 }
3801 /* set upper-layer auth */
3802 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3803 if (err < 0) {
3804 brcmf_err("wpa_auth error %d\n", err);
3805 goto exit;
3806 }
3807
3808 exit:
3809 return err;
3810 }
3811
3812 static s32
brcmf_parse_vndr_ies(const u8 * vndr_ie_buf,u32 vndr_ie_len,struct parsed_vndr_ies * vndr_ies)3813 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3814 struct parsed_vndr_ies *vndr_ies)
3815 {
3816 struct brcmf_vs_tlv *vndrie;
3817 struct brcmf_tlv *ie;
3818 struct parsed_vndr_ie_info *parsed_info;
3819 s32 remaining_len;
3820
3821 remaining_len = (s32)vndr_ie_len;
3822 memset(vndr_ies, 0, sizeof(*vndr_ies));
3823
3824 ie = (struct brcmf_tlv *)vndr_ie_buf;
3825 while (ie) {
3826 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3827 goto next;
3828 vndrie = (struct brcmf_vs_tlv *)ie;
3829 /* len should be bigger than OUI length + one */
3830 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3831 brcmf_err("invalid vndr ie. length is too small %d\n",
3832 vndrie->len);
3833 goto next;
3834 }
3835 /* if wpa or wme ie, do not add ie */
3836 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3837 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3838 (vndrie->oui_type == WME_OUI_TYPE))) {
3839 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3840 goto next;
3841 }
3842
3843 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3844
3845 /* save vndr ie information */
3846 parsed_info->ie_ptr = (char *)vndrie;
3847 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3848 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3849
3850 vndr_ies->count++;
3851
3852 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3853 parsed_info->vndrie.oui[0],
3854 parsed_info->vndrie.oui[1],
3855 parsed_info->vndrie.oui[2],
3856 parsed_info->vndrie.oui_type);
3857
3858 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3859 break;
3860 next:
3861 remaining_len -= (ie->len + TLV_HDR_LEN);
3862 if (remaining_len <= TLV_HDR_LEN)
3863 ie = NULL;
3864 else
3865 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3866 TLV_HDR_LEN);
3867 }
3868 return 0;
3869 }
3870
3871 static u32
brcmf_vndr_ie(u8 * iebuf,s32 pktflag,u8 * ie_ptr,u32 ie_len,s8 * add_del_cmd)3872 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3873 {
3874
3875 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3876 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3877
3878 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3879
3880 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3881
3882 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3883
3884 return ie_len + VNDR_IE_HDR_SIZE;
3885 }
3886
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif * vif,s32 pktflag,const u8 * vndr_ie_buf,u32 vndr_ie_len)3887 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3888 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3889 {
3890 struct brcmf_if *ifp;
3891 struct vif_saved_ie *saved_ie;
3892 s32 err = 0;
3893 u8 *iovar_ie_buf;
3894 u8 *curr_ie_buf;
3895 u8 *mgmt_ie_buf = NULL;
3896 int mgmt_ie_buf_len;
3897 u32 *mgmt_ie_len;
3898 u32 del_add_ie_buf_len = 0;
3899 u32 total_ie_buf_len = 0;
3900 u32 parsed_ie_buf_len = 0;
3901 struct parsed_vndr_ies old_vndr_ies;
3902 struct parsed_vndr_ies new_vndr_ies;
3903 struct parsed_vndr_ie_info *vndrie_info;
3904 s32 i;
3905 u8 *ptr;
3906 int remained_buf_len;
3907
3908 if (!vif)
3909 return -ENODEV;
3910 ifp = vif->ifp;
3911 saved_ie = &vif->saved_ie;
3912
3913 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3914 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3915 if (!iovar_ie_buf)
3916 return -ENOMEM;
3917 curr_ie_buf = iovar_ie_buf;
3918 switch (pktflag) {
3919 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3920 mgmt_ie_buf = saved_ie->probe_req_ie;
3921 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3922 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3923 break;
3924 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3925 mgmt_ie_buf = saved_ie->probe_res_ie;
3926 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3927 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3928 break;
3929 case BRCMF_VNDR_IE_BEACON_FLAG:
3930 mgmt_ie_buf = saved_ie->beacon_ie;
3931 mgmt_ie_len = &saved_ie->beacon_ie_len;
3932 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3933 break;
3934 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3935 mgmt_ie_buf = saved_ie->assoc_req_ie;
3936 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3937 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3938 break;
3939 default:
3940 err = -EPERM;
3941 brcmf_err("not suitable type\n");
3942 goto exit;
3943 }
3944
3945 if (vndr_ie_len > mgmt_ie_buf_len) {
3946 err = -ENOMEM;
3947 brcmf_err("extra IE size too big\n");
3948 goto exit;
3949 }
3950
3951 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3952 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3953 ptr = curr_ie_buf;
3954 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3955 for (i = 0; i < new_vndr_ies.count; i++) {
3956 vndrie_info = &new_vndr_ies.ie_info[i];
3957 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3958 vndrie_info->ie_len);
3959 parsed_ie_buf_len += vndrie_info->ie_len;
3960 }
3961 }
3962
3963 if (mgmt_ie_buf && *mgmt_ie_len) {
3964 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3965 (memcmp(mgmt_ie_buf, curr_ie_buf,
3966 parsed_ie_buf_len) == 0)) {
3967 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3968 goto exit;
3969 }
3970
3971 /* parse old vndr_ie */
3972 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3973
3974 /* make a command to delete old ie */
3975 for (i = 0; i < old_vndr_ies.count; i++) {
3976 vndrie_info = &old_vndr_ies.ie_info[i];
3977
3978 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3979 vndrie_info->vndrie.id,
3980 vndrie_info->vndrie.len,
3981 vndrie_info->vndrie.oui[0],
3982 vndrie_info->vndrie.oui[1],
3983 vndrie_info->vndrie.oui[2]);
3984
3985 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3986 vndrie_info->ie_ptr,
3987 vndrie_info->ie_len,
3988 "del");
3989 curr_ie_buf += del_add_ie_buf_len;
3990 total_ie_buf_len += del_add_ie_buf_len;
3991 }
3992 }
3993
3994 *mgmt_ie_len = 0;
3995 /* Add if there is any extra IE */
3996 if (mgmt_ie_buf && parsed_ie_buf_len) {
3997 ptr = mgmt_ie_buf;
3998
3999 remained_buf_len = mgmt_ie_buf_len;
4000
4001 /* make a command to add new ie */
4002 for (i = 0; i < new_vndr_ies.count; i++) {
4003 vndrie_info = &new_vndr_ies.ie_info[i];
4004
4005 /* verify remained buf size before copy data */
4006 if (remained_buf_len < (vndrie_info->vndrie.len +
4007 VNDR_IE_VSIE_OFFSET)) {
4008 brcmf_err("no space in mgmt_ie_buf: len left %d",
4009 remained_buf_len);
4010 break;
4011 }
4012 remained_buf_len -= (vndrie_info->ie_len +
4013 VNDR_IE_VSIE_OFFSET);
4014
4015 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
4016 vndrie_info->vndrie.id,
4017 vndrie_info->vndrie.len,
4018 vndrie_info->vndrie.oui[0],
4019 vndrie_info->vndrie.oui[1],
4020 vndrie_info->vndrie.oui[2]);
4021
4022 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4023 vndrie_info->ie_ptr,
4024 vndrie_info->ie_len,
4025 "add");
4026
4027 /* save the parsed IE in wl struct */
4028 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
4029 vndrie_info->ie_len);
4030 *mgmt_ie_len += vndrie_info->ie_len;
4031
4032 curr_ie_buf += del_add_ie_buf_len;
4033 total_ie_buf_len += del_add_ie_buf_len;
4034 }
4035 }
4036 if (total_ie_buf_len) {
4037 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
4038 total_ie_buf_len);
4039 if (err)
4040 brcmf_err("vndr ie set error : %d\n", err);
4041 }
4042
4043 exit:
4044 kfree(iovar_ie_buf);
4045 return err;
4046 }
4047
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif * vif)4048 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
4049 {
4050 s32 pktflags[] = {
4051 BRCMF_VNDR_IE_PRBREQ_FLAG,
4052 BRCMF_VNDR_IE_PRBRSP_FLAG,
4053 BRCMF_VNDR_IE_BEACON_FLAG
4054 };
4055 int i;
4056
4057 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4058 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4059
4060 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4061 return 0;
4062 }
4063
4064 static s32
brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif * vif,struct cfg80211_beacon_data * beacon)4065 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4066 struct cfg80211_beacon_data *beacon)
4067 {
4068 s32 err;
4069
4070 /* Set Beacon IEs to FW */
4071 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4072 beacon->tail, beacon->tail_len);
4073 if (err) {
4074 brcmf_err("Set Beacon IE Failed\n");
4075 return err;
4076 }
4077 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4078
4079 /* Set Probe Response IEs to FW */
4080 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4081 beacon->proberesp_ies,
4082 beacon->proberesp_ies_len);
4083 if (err)
4084 brcmf_err("Set Probe Resp IE Failed\n");
4085 else
4086 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4087
4088 return err;
4089 }
4090
4091 static s32
brcmf_cfg80211_start_ap(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ap_settings * settings)4092 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4093 struct cfg80211_ap_settings *settings)
4094 {
4095 s32 ie_offset;
4096 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4097 struct brcmf_if *ifp = netdev_priv(ndev);
4098 const struct brcmf_tlv *ssid_ie;
4099 const struct brcmf_tlv *country_ie;
4100 struct brcmf_ssid_le ssid_le;
4101 s32 err = -EPERM;
4102 const struct brcmf_tlv *rsn_ie;
4103 const struct brcmf_vs_tlv *wpa_ie;
4104 struct brcmf_join_params join_params;
4105 enum nl80211_iftype dev_role;
4106 struct brcmf_fil_bss_enable_le bss_enable;
4107 u16 chanspec;
4108 bool mbss;
4109 int is_11d;
4110
4111 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4112 settings->chandef.chan->hw_value,
4113 settings->chandef.center_freq1, settings->chandef.width,
4114 settings->beacon_interval, settings->dtim_period);
4115 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4116 settings->ssid, settings->ssid_len, settings->auth_type,
4117 settings->inactivity_timeout);
4118 dev_role = ifp->vif->wdev.iftype;
4119 mbss = ifp->vif->mbss;
4120
4121 /* store current 11d setting */
4122 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4123 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4124 settings->beacon.tail_len,
4125 WLAN_EID_COUNTRY);
4126 is_11d = country_ie ? 1 : 0;
4127
4128 memset(&ssid_le, 0, sizeof(ssid_le));
4129 if (settings->ssid == NULL || settings->ssid_len == 0) {
4130 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4131 ssid_ie = brcmf_parse_tlvs(
4132 (u8 *)&settings->beacon.head[ie_offset],
4133 settings->beacon.head_len - ie_offset,
4134 WLAN_EID_SSID);
4135 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
4136 return -EINVAL;
4137
4138 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4139 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4140 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4141 } else {
4142 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4143 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4144 }
4145
4146 if (!mbss) {
4147 brcmf_set_mpc(ifp, 0);
4148 brcmf_configure_arp_offload(ifp, false);
4149 }
4150
4151 /* find the RSN_IE */
4152 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4153 settings->beacon.tail_len, WLAN_EID_RSN);
4154
4155 /* find the WPA_IE */
4156 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4157 settings->beacon.tail_len);
4158
4159 if ((wpa_ie != NULL || rsn_ie != NULL)) {
4160 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4161 if (wpa_ie != NULL) {
4162 /* WPA IE */
4163 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4164 if (err < 0)
4165 goto exit;
4166 } else {
4167 struct brcmf_vs_tlv *tmp_ie;
4168
4169 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4170
4171 /* RSN IE */
4172 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4173 if (err < 0)
4174 goto exit;
4175 }
4176 } else {
4177 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4178 brcmf_configure_opensecurity(ifp);
4179 }
4180
4181 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4182
4183 if (!mbss) {
4184 chanspec = chandef_to_chanspec(&cfg->d11inf,
4185 &settings->chandef);
4186 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4187 if (err < 0) {
4188 brcmf_err("Set Channel failed: chspec=%d, %d\n",
4189 chanspec, err);
4190 goto exit;
4191 }
4192
4193 if (is_11d != ifp->vif->is_11d) {
4194 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4195 is_11d);
4196 if (err < 0) {
4197 brcmf_err("Regulatory Set Error, %d\n", err);
4198 goto exit;
4199 }
4200 }
4201 if (settings->beacon_interval) {
4202 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4203 settings->beacon_interval);
4204 if (err < 0) {
4205 brcmf_err("Beacon Interval Set Error, %d\n",
4206 err);
4207 goto exit;
4208 }
4209 }
4210 if (settings->dtim_period) {
4211 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4212 settings->dtim_period);
4213 if (err < 0) {
4214 brcmf_err("DTIM Interval Set Error, %d\n", err);
4215 goto exit;
4216 }
4217 }
4218
4219 if (dev_role == NL80211_IFTYPE_AP) {
4220 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4221 if (err < 0) {
4222 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4223 goto exit;
4224 }
4225 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4226 }
4227
4228 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4229 if (err < 0) {
4230 brcmf_err("SET INFRA error %d\n", err);
4231 goto exit;
4232 }
4233 } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4234 /* Multiple-BSS should use same 11d configuration */
4235 err = -EINVAL;
4236 goto exit;
4237 }
4238 if (dev_role == NL80211_IFTYPE_AP) {
4239 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4240 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4241
4242 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4243 if (err < 0) {
4244 brcmf_err("setting AP mode failed %d\n", err);
4245 goto exit;
4246 }
4247 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4248 if (err < 0) {
4249 brcmf_err("BRCMF_C_UP error (%d)\n", err);
4250 goto exit;
4251 }
4252 /* On DOWN the firmware removes the WEP keys, reconfigure
4253 * them if they were set.
4254 */
4255 brcmf_cfg80211_reconfigure_wep(ifp);
4256
4257 memset(&join_params, 0, sizeof(join_params));
4258 /* join parameters starts with ssid */
4259 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4260 /* create softap */
4261 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4262 &join_params, sizeof(join_params));
4263 if (err < 0) {
4264 brcmf_err("SET SSID error (%d)\n", err);
4265 goto exit;
4266 }
4267 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4268 } else {
4269 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4270 sizeof(ssid_le));
4271 if (err < 0) {
4272 brcmf_err("setting ssid failed %d\n", err);
4273 goto exit;
4274 }
4275 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4276 bss_enable.enable = cpu_to_le32(1);
4277 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4278 sizeof(bss_enable));
4279 if (err < 0) {
4280 brcmf_err("bss_enable config failed %d\n", err);
4281 goto exit;
4282 }
4283
4284 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4285 }
4286 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4287 brcmf_net_setcarrier(ifp, true);
4288
4289 exit:
4290 if ((err) && (!mbss)) {
4291 brcmf_set_mpc(ifp, 1);
4292 brcmf_configure_arp_offload(ifp, true);
4293 }
4294 return err;
4295 }
4296
brcmf_cfg80211_stop_ap(struct wiphy * wiphy,struct net_device * ndev)4297 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4298 {
4299 struct brcmf_if *ifp = netdev_priv(ndev);
4300 s32 err;
4301 struct brcmf_fil_bss_enable_le bss_enable;
4302 struct brcmf_join_params join_params;
4303
4304 brcmf_dbg(TRACE, "Enter\n");
4305
4306 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4307 /* Due to most likely deauths outstanding we sleep */
4308 /* first to make sure they get processed by fw. */
4309 msleep(400);
4310
4311 if (ifp->vif->mbss) {
4312 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4313 return err;
4314 }
4315
4316 memset(&join_params, 0, sizeof(join_params));
4317 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4318 &join_params, sizeof(join_params));
4319 if (err < 0)
4320 brcmf_err("SET SSID error (%d)\n", err);
4321 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4322 if (err < 0)
4323 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4324 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4325 if (err < 0)
4326 brcmf_err("setting AP mode failed %d\n", err);
4327 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4328 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4329 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4330 ifp->vif->is_11d);
4331 if (err < 0)
4332 brcmf_err("restoring REGULATORY setting failed %d\n",
4333 err);
4334 /* Bring device back up so it can be used again */
4335 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4336 if (err < 0)
4337 brcmf_err("BRCMF_C_UP error %d\n", err);
4338 } else {
4339 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4340 bss_enable.enable = cpu_to_le32(0);
4341 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4342 sizeof(bss_enable));
4343 if (err < 0)
4344 brcmf_err("bss_enable config failed %d\n", err);
4345 }
4346 brcmf_set_mpc(ifp, 1);
4347 brcmf_configure_arp_offload(ifp, true);
4348 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4349 brcmf_net_setcarrier(ifp, false);
4350
4351 return err;
4352 }
4353
4354 static s32
brcmf_cfg80211_change_beacon(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_beacon_data * info)4355 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4356 struct cfg80211_beacon_data *info)
4357 {
4358 struct brcmf_if *ifp = netdev_priv(ndev);
4359 s32 err;
4360
4361 brcmf_dbg(TRACE, "Enter\n");
4362
4363 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4364
4365 return err;
4366 }
4367
4368 static int
brcmf_cfg80211_del_station(struct wiphy * wiphy,struct net_device * ndev,struct station_del_parameters * params)4369 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4370 struct station_del_parameters *params)
4371 {
4372 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4373 struct brcmf_scb_val_le scbval;
4374 struct brcmf_if *ifp = netdev_priv(ndev);
4375 s32 err;
4376
4377 if (!params->mac)
4378 return -EFAULT;
4379
4380 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4381
4382 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4383 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4384 if (!check_vif_up(ifp->vif))
4385 return -EIO;
4386
4387 memcpy(&scbval.ea, params->mac, ETH_ALEN);
4388 scbval.val = cpu_to_le32(params->reason_code);
4389 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4390 &scbval, sizeof(scbval));
4391 if (err)
4392 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4393
4394 brcmf_dbg(TRACE, "Exit\n");
4395 return err;
4396 }
4397
4398 static int
brcmf_cfg80211_change_station(struct wiphy * wiphy,struct net_device * ndev,const u8 * mac,struct station_parameters * params)4399 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4400 const u8 *mac, struct station_parameters *params)
4401 {
4402 struct brcmf_if *ifp = netdev_priv(ndev);
4403 s32 err;
4404
4405 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4406 params->sta_flags_mask, params->sta_flags_set);
4407
4408 /* Ignore all 00 MAC */
4409 if (is_zero_ether_addr(mac))
4410 return 0;
4411
4412 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4413 return 0;
4414
4415 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4416 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4417 (void *)mac, ETH_ALEN);
4418 else
4419 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4420 (void *)mac, ETH_ALEN);
4421 if (err < 0)
4422 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4423
4424 return err;
4425 }
4426
4427 static void
brcmf_cfg80211_mgmt_frame_register(struct wiphy * wiphy,struct wireless_dev * wdev,u16 frame_type,bool reg)4428 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4429 struct wireless_dev *wdev,
4430 u16 frame_type, bool reg)
4431 {
4432 struct brcmf_cfg80211_vif *vif;
4433 u16 mgmt_type;
4434
4435 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4436
4437 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4438 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4439 if (reg)
4440 vif->mgmt_rx_reg |= BIT(mgmt_type);
4441 else
4442 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4443 }
4444
4445
4446 static int
brcmf_cfg80211_mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)4447 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4448 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4449 {
4450 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4451 struct ieee80211_channel *chan = params->chan;
4452 const u8 *buf = params->buf;
4453 size_t len = params->len;
4454 const struct ieee80211_mgmt *mgmt;
4455 struct brcmf_cfg80211_vif *vif;
4456 s32 err = 0;
4457 s32 ie_offset;
4458 s32 ie_len;
4459 struct brcmf_fil_action_frame_le *action_frame;
4460 struct brcmf_fil_af_params_le *af_params;
4461 bool ack;
4462 s32 chan_nr;
4463 u32 freq;
4464
4465 brcmf_dbg(TRACE, "Enter\n");
4466
4467 *cookie = 0;
4468
4469 mgmt = (const struct ieee80211_mgmt *)buf;
4470
4471 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4472 brcmf_err("Driver only allows MGMT packet type\n");
4473 return -EPERM;
4474 }
4475
4476 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4477
4478 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4479 /* Right now the only reason to get a probe response */
4480 /* is for p2p listen response or for p2p GO from */
4481 /* wpa_supplicant. Unfortunately the probe is send */
4482 /* on primary ndev, while dongle wants it on the p2p */
4483 /* vif. Since this is only reason for a probe */
4484 /* response to be sent, the vif is taken from cfg. */
4485 /* If ever desired to send proberesp for non p2p */
4486 /* response then data should be checked for */
4487 /* "DIRECT-". Note in future supplicant will take */
4488 /* dedicated p2p wdev to do this and then this 'hack'*/
4489 /* is not needed anymore. */
4490 ie_offset = DOT11_MGMT_HDR_LEN +
4491 DOT11_BCN_PRB_FIXED_LEN;
4492 ie_len = len - ie_offset;
4493 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4494 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4495 err = brcmf_vif_set_mgmt_ie(vif,
4496 BRCMF_VNDR_IE_PRBRSP_FLAG,
4497 &buf[ie_offset],
4498 ie_len);
4499 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4500 GFP_KERNEL);
4501 } else if (ieee80211_is_action(mgmt->frame_control)) {
4502 if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
4503 brcmf_err("invalid action frame length\n");
4504 err = -EINVAL;
4505 goto exit;
4506 }
4507 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4508 if (af_params == NULL) {
4509 brcmf_err("unable to allocate frame\n");
4510 err = -ENOMEM;
4511 goto exit;
4512 }
4513 action_frame = &af_params->action_frame;
4514 /* Add the packet Id */
4515 action_frame->packet_id = cpu_to_le32(*cookie);
4516 /* Add BSSID */
4517 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4518 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4519 /* Add the length exepted for 802.11 header */
4520 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4521 /* Add the channel. Use the one specified as parameter if any or
4522 * the current one (got from the firmware) otherwise
4523 */
4524 if (chan)
4525 freq = chan->center_freq;
4526 else
4527 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4528 &freq);
4529 chan_nr = ieee80211_frequency_to_channel(freq);
4530 af_params->channel = cpu_to_le32(chan_nr);
4531
4532 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4533 le16_to_cpu(action_frame->len));
4534
4535 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4536 *cookie, le16_to_cpu(action_frame->len), freq);
4537
4538 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4539 af_params);
4540
4541 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4542 GFP_KERNEL);
4543 kfree(af_params);
4544 } else {
4545 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4546 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4547 }
4548
4549 exit:
4550 return err;
4551 }
4552
4553
4554 static int
brcmf_cfg80211_cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)4555 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4556 struct wireless_dev *wdev,
4557 u64 cookie)
4558 {
4559 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4560 struct brcmf_cfg80211_vif *vif;
4561 int err = 0;
4562
4563 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4564
4565 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4566 if (vif == NULL) {
4567 brcmf_err("No p2p device available for probe response\n");
4568 err = -ENODEV;
4569 goto exit;
4570 }
4571 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4572 exit:
4573 return err;
4574 }
4575
brcmf_cfg80211_crit_proto_start(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_crit_proto_id proto,u16 duration)4576 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4577 struct wireless_dev *wdev,
4578 enum nl80211_crit_proto_id proto,
4579 u16 duration)
4580 {
4581 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4582 struct brcmf_cfg80211_vif *vif;
4583
4584 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4585
4586 /* only DHCP support for now */
4587 if (proto != NL80211_CRIT_PROTO_DHCP)
4588 return -EINVAL;
4589
4590 /* suppress and abort scanning */
4591 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4592 brcmf_abort_scanning(cfg);
4593
4594 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4595 }
4596
brcmf_cfg80211_crit_proto_stop(struct wiphy * wiphy,struct wireless_dev * wdev)4597 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4598 struct wireless_dev *wdev)
4599 {
4600 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4601 struct brcmf_cfg80211_vif *vif;
4602
4603 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4604
4605 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4606 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4607 }
4608
4609 static s32
brcmf_notify_tdls_peer_event(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)4610 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4611 const struct brcmf_event_msg *e, void *data)
4612 {
4613 switch (e->reason) {
4614 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4615 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4616 break;
4617 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4618 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4619 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4620 break;
4621 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4622 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4623 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4624 break;
4625 }
4626
4627 return 0;
4628 }
4629
brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)4630 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4631 {
4632 int ret;
4633
4634 switch (oper) {
4635 case NL80211_TDLS_DISCOVERY_REQ:
4636 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4637 break;
4638 case NL80211_TDLS_SETUP:
4639 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4640 break;
4641 case NL80211_TDLS_TEARDOWN:
4642 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4643 break;
4644 default:
4645 brcmf_err("unsupported operation: %d\n", oper);
4646 ret = -EOPNOTSUPP;
4647 }
4648 return ret;
4649 }
4650
brcmf_cfg80211_tdls_oper(struct wiphy * wiphy,struct net_device * ndev,const u8 * peer,enum nl80211_tdls_operation oper)4651 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4652 struct net_device *ndev, const u8 *peer,
4653 enum nl80211_tdls_operation oper)
4654 {
4655 struct brcmf_if *ifp;
4656 struct brcmf_tdls_iovar_le info;
4657 int ret = 0;
4658
4659 ret = brcmf_convert_nl80211_tdls_oper(oper);
4660 if (ret < 0)
4661 return ret;
4662
4663 ifp = netdev_priv(ndev);
4664 memset(&info, 0, sizeof(info));
4665 info.mode = (u8)ret;
4666 if (peer)
4667 memcpy(info.ea, peer, ETH_ALEN);
4668
4669 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4670 &info, sizeof(info));
4671 if (ret < 0)
4672 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4673
4674 return ret;
4675 }
4676
4677 static struct cfg80211_ops wl_cfg80211_ops = {
4678 .add_virtual_intf = brcmf_cfg80211_add_iface,
4679 .del_virtual_intf = brcmf_cfg80211_del_iface,
4680 .change_virtual_intf = brcmf_cfg80211_change_iface,
4681 .scan = brcmf_cfg80211_scan,
4682 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4683 .join_ibss = brcmf_cfg80211_join_ibss,
4684 .leave_ibss = brcmf_cfg80211_leave_ibss,
4685 .get_station = brcmf_cfg80211_get_station,
4686 .dump_station = brcmf_cfg80211_dump_station,
4687 .set_tx_power = brcmf_cfg80211_set_tx_power,
4688 .get_tx_power = brcmf_cfg80211_get_tx_power,
4689 .add_key = brcmf_cfg80211_add_key,
4690 .del_key = brcmf_cfg80211_del_key,
4691 .get_key = brcmf_cfg80211_get_key,
4692 .set_default_key = brcmf_cfg80211_config_default_key,
4693 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4694 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4695 .connect = brcmf_cfg80211_connect,
4696 .disconnect = brcmf_cfg80211_disconnect,
4697 .suspend = brcmf_cfg80211_suspend,
4698 .resume = brcmf_cfg80211_resume,
4699 .set_pmksa = brcmf_cfg80211_set_pmksa,
4700 .del_pmksa = brcmf_cfg80211_del_pmksa,
4701 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4702 .start_ap = brcmf_cfg80211_start_ap,
4703 .stop_ap = brcmf_cfg80211_stop_ap,
4704 .change_beacon = brcmf_cfg80211_change_beacon,
4705 .del_station = brcmf_cfg80211_del_station,
4706 .change_station = brcmf_cfg80211_change_station,
4707 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4708 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4709 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4710 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4711 .remain_on_channel = brcmf_p2p_remain_on_channel,
4712 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4713 .start_p2p_device = brcmf_p2p_start_device,
4714 .stop_p2p_device = brcmf_p2p_stop_device,
4715 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4716 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4717 .tdls_oper = brcmf_cfg80211_tdls_oper,
4718 };
4719
brcmf_alloc_vif(struct brcmf_cfg80211_info * cfg,enum nl80211_iftype type,bool pm_block)4720 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4721 enum nl80211_iftype type,
4722 bool pm_block)
4723 {
4724 struct brcmf_cfg80211_vif *vif_walk;
4725 struct brcmf_cfg80211_vif *vif;
4726 bool mbss;
4727
4728 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4729 sizeof(*vif));
4730 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4731 if (!vif)
4732 return ERR_PTR(-ENOMEM);
4733
4734 vif->wdev.wiphy = cfg->wiphy;
4735 vif->wdev.iftype = type;
4736
4737 vif->pm_block = pm_block;
4738 vif->roam_off = -1;
4739
4740 brcmf_init_prof(&vif->profile);
4741
4742 if (type == NL80211_IFTYPE_AP) {
4743 mbss = false;
4744 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4745 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4746 mbss = true;
4747 break;
4748 }
4749 }
4750 vif->mbss = mbss;
4751 }
4752
4753 list_add_tail(&vif->list, &cfg->vif_list);
4754 return vif;
4755 }
4756
brcmf_free_vif(struct brcmf_cfg80211_vif * vif)4757 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4758 {
4759 list_del(&vif->list);
4760 kfree(vif);
4761 }
4762
brcmf_cfg80211_free_netdev(struct net_device * ndev)4763 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4764 {
4765 struct brcmf_cfg80211_vif *vif;
4766 struct brcmf_if *ifp;
4767
4768 ifp = netdev_priv(ndev);
4769 vif = ifp->vif;
4770
4771 if (vif)
4772 brcmf_free_vif(vif);
4773 free_netdev(ndev);
4774 }
4775
brcmf_is_linkup(const struct brcmf_event_msg * e)4776 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4777 {
4778 u32 event = e->event_code;
4779 u32 status = e->status;
4780
4781 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4782 brcmf_dbg(CONN, "Processing set ssid\n");
4783 return true;
4784 }
4785
4786 return false;
4787 }
4788
brcmf_is_linkdown(const struct brcmf_event_msg * e)4789 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4790 {
4791 u32 event = e->event_code;
4792 u16 flags = e->flags;
4793
4794 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4795 (event == BRCMF_E_DISASSOC_IND) ||
4796 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4797 brcmf_dbg(CONN, "Processing link down\n");
4798 return true;
4799 }
4800 return false;
4801 }
4802
brcmf_is_nonetwork(struct brcmf_cfg80211_info * cfg,const struct brcmf_event_msg * e)4803 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4804 const struct brcmf_event_msg *e)
4805 {
4806 u32 event = e->event_code;
4807 u32 status = e->status;
4808
4809 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4810 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4811 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4812 return true;
4813 }
4814
4815 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4816 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4817 return true;
4818 }
4819
4820 return false;
4821 }
4822
brcmf_clear_assoc_ies(struct brcmf_cfg80211_info * cfg)4823 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4824 {
4825 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4826
4827 kfree(conn_info->req_ie);
4828 conn_info->req_ie = NULL;
4829 conn_info->req_ie_len = 0;
4830 kfree(conn_info->resp_ie);
4831 conn_info->resp_ie = NULL;
4832 conn_info->resp_ie_len = 0;
4833 }
4834
brcmf_get_assoc_ies(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp)4835 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4836 struct brcmf_if *ifp)
4837 {
4838 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4839 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4840 u32 req_len;
4841 u32 resp_len;
4842 s32 err = 0;
4843
4844 brcmf_clear_assoc_ies(cfg);
4845
4846 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4847 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4848 if (err) {
4849 brcmf_err("could not get assoc info (%d)\n", err);
4850 return err;
4851 }
4852 assoc_info =
4853 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4854 req_len = le32_to_cpu(assoc_info->req_len);
4855 resp_len = le32_to_cpu(assoc_info->resp_len);
4856 if (req_len) {
4857 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4858 cfg->extra_buf,
4859 WL_ASSOC_INFO_MAX);
4860 if (err) {
4861 brcmf_err("could not get assoc req (%d)\n", err);
4862 return err;
4863 }
4864 conn_info->req_ie_len = req_len;
4865 conn_info->req_ie =
4866 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4867 GFP_KERNEL);
4868 if (!conn_info->req_ie)
4869 conn_info->req_ie_len = 0;
4870 } else {
4871 conn_info->req_ie_len = 0;
4872 conn_info->req_ie = NULL;
4873 }
4874 if (resp_len) {
4875 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4876 cfg->extra_buf,
4877 WL_ASSOC_INFO_MAX);
4878 if (err) {
4879 brcmf_err("could not get assoc resp (%d)\n", err);
4880 return err;
4881 }
4882 conn_info->resp_ie_len = resp_len;
4883 conn_info->resp_ie =
4884 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4885 GFP_KERNEL);
4886 if (!conn_info->resp_ie)
4887 conn_info->resp_ie_len = 0;
4888 } else {
4889 conn_info->resp_ie_len = 0;
4890 conn_info->resp_ie = NULL;
4891 }
4892 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4893 conn_info->req_ie_len, conn_info->resp_ie_len);
4894
4895 return err;
4896 }
4897
4898 static s32
brcmf_bss_roaming_done(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e)4899 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4900 struct net_device *ndev,
4901 const struct brcmf_event_msg *e)
4902 {
4903 struct brcmf_if *ifp = netdev_priv(ndev);
4904 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4905 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4906 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4907 struct ieee80211_channel *notify_channel = NULL;
4908 struct ieee80211_supported_band *band;
4909 struct brcmf_bss_info_le *bi;
4910 struct brcmu_chan ch;
4911 u32 freq;
4912 s32 err = 0;
4913 u8 *buf;
4914
4915 brcmf_dbg(TRACE, "Enter\n");
4916
4917 brcmf_get_assoc_ies(cfg, ifp);
4918 memcpy(profile->bssid, e->addr, ETH_ALEN);
4919 brcmf_update_bss_info(cfg, ifp);
4920
4921 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4922 if (buf == NULL) {
4923 err = -ENOMEM;
4924 goto done;
4925 }
4926
4927 /* data sent to dongle has to be little endian */
4928 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4929 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4930 buf, WL_BSS_INFO_MAX);
4931
4932 if (err)
4933 goto done;
4934
4935 bi = (struct brcmf_bss_info_le *)(buf + 4);
4936 ch.chspec = le16_to_cpu(bi->chanspec);
4937 cfg->d11inf.decchspec(&ch);
4938
4939 if (ch.band == BRCMU_CHAN_BAND_2G)
4940 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4941 else
4942 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4943
4944 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4945 notify_channel = ieee80211_get_channel(wiphy, freq);
4946
4947 done:
4948 kfree(buf);
4949 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4950 conn_info->req_ie, conn_info->req_ie_len,
4951 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4952 brcmf_dbg(CONN, "Report roaming result\n");
4953
4954 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4955 brcmf_dbg(TRACE, "Exit\n");
4956 return err;
4957 }
4958
4959 static s32
brcmf_bss_connect_done(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e,bool completed)4960 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4961 struct net_device *ndev, const struct brcmf_event_msg *e,
4962 bool completed)
4963 {
4964 struct brcmf_if *ifp = netdev_priv(ndev);
4965 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4966 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4967
4968 brcmf_dbg(TRACE, "Enter\n");
4969
4970 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4971 &ifp->vif->sme_state)) {
4972 if (completed) {
4973 brcmf_get_assoc_ies(cfg, ifp);
4974 memcpy(profile->bssid, e->addr, ETH_ALEN);
4975 brcmf_update_bss_info(cfg, ifp);
4976 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4977 &ifp->vif->sme_state);
4978 }
4979 cfg80211_connect_result(ndev,
4980 (u8 *)profile->bssid,
4981 conn_info->req_ie,
4982 conn_info->req_ie_len,
4983 conn_info->resp_ie,
4984 conn_info->resp_ie_len,
4985 completed ? WLAN_STATUS_SUCCESS :
4986 WLAN_STATUS_AUTH_TIMEOUT,
4987 GFP_KERNEL);
4988 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4989 completed ? "succeeded" : "failed");
4990 }
4991 brcmf_dbg(TRACE, "Exit\n");
4992 return 0;
4993 }
4994
4995 static s32
brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)4996 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4997 struct net_device *ndev,
4998 const struct brcmf_event_msg *e, void *data)
4999 {
5000 struct brcmf_if *ifp = netdev_priv(ndev);
5001 static int generation;
5002 u32 event = e->event_code;
5003 u32 reason = e->reason;
5004 struct station_info sinfo;
5005
5006 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
5007 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
5008 ndev != cfg_to_ndev(cfg)) {
5009 brcmf_dbg(CONN, "AP mode link down\n");
5010 complete(&cfg->vif_disabled);
5011 if (ifp->vif->mbss)
5012 brcmf_remove_interface(ifp);
5013 return 0;
5014 }
5015
5016 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
5017 (reason == BRCMF_E_STATUS_SUCCESS)) {
5018 memset(&sinfo, 0, sizeof(sinfo));
5019 if (!data) {
5020 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
5021 return -EINVAL;
5022 }
5023 sinfo.assoc_req_ies = data;
5024 sinfo.assoc_req_ies_len = e->datalen;
5025 generation++;
5026 sinfo.generation = generation;
5027 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
5028 } else if ((event == BRCMF_E_DISASSOC_IND) ||
5029 (event == BRCMF_E_DEAUTH_IND) ||
5030 (event == BRCMF_E_DEAUTH)) {
5031 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
5032 }
5033 return 0;
5034 }
5035
5036 static s32
brcmf_notify_connect_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)5037 brcmf_notify_connect_status(struct brcmf_if *ifp,
5038 const struct brcmf_event_msg *e, void *data)
5039 {
5040 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5041 struct net_device *ndev = ifp->ndev;
5042 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5043 struct ieee80211_channel *chan;
5044 s32 err = 0;
5045
5046 if ((e->event_code == BRCMF_E_DEAUTH) ||
5047 (e->event_code == BRCMF_E_DEAUTH_IND) ||
5048 (e->event_code == BRCMF_E_DISASSOC_IND) ||
5049 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
5050 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5051 }
5052
5053 if (brcmf_is_apmode(ifp->vif)) {
5054 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
5055 } else if (brcmf_is_linkup(e)) {
5056 brcmf_dbg(CONN, "Linkup\n");
5057 if (brcmf_is_ibssmode(ifp->vif)) {
5058 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
5059 memcpy(profile->bssid, e->addr, ETH_ALEN);
5060 wl_inform_ibss(cfg, ndev, e->addr);
5061 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
5062 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5063 &ifp->vif->sme_state);
5064 set_bit(BRCMF_VIF_STATUS_CONNECTED,
5065 &ifp->vif->sme_state);
5066 } else
5067 brcmf_bss_connect_done(cfg, ndev, e, true);
5068 brcmf_net_setcarrier(ifp, true);
5069 } else if (brcmf_is_linkdown(e)) {
5070 brcmf_dbg(CONN, "Linkdown\n");
5071 if (!brcmf_is_ibssmode(ifp->vif)) {
5072 brcmf_bss_connect_done(cfg, ndev, e, false);
5073 }
5074 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
5075 brcmf_init_prof(ndev_to_prof(ndev));
5076 if (ndev != cfg_to_ndev(cfg))
5077 complete(&cfg->vif_disabled);
5078 brcmf_net_setcarrier(ifp, false);
5079 } else if (brcmf_is_nonetwork(cfg, e)) {
5080 if (brcmf_is_ibssmode(ifp->vif))
5081 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5082 &ifp->vif->sme_state);
5083 else
5084 brcmf_bss_connect_done(cfg, ndev, e, false);
5085 }
5086
5087 return err;
5088 }
5089
5090 static s32
brcmf_notify_roaming_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)5091 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5092 const struct brcmf_event_msg *e, void *data)
5093 {
5094 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5095 u32 event = e->event_code;
5096 u32 status = e->status;
5097
5098 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5099 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5100 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5101 else
5102 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5103 }
5104
5105 return 0;
5106 }
5107
5108 static s32
brcmf_notify_mic_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)5109 brcmf_notify_mic_status(struct brcmf_if *ifp,
5110 const struct brcmf_event_msg *e, void *data)
5111 {
5112 u16 flags = e->flags;
5113 enum nl80211_key_type key_type;
5114
5115 if (flags & BRCMF_EVENT_MSG_GROUP)
5116 key_type = NL80211_KEYTYPE_GROUP;
5117 else
5118 key_type = NL80211_KEYTYPE_PAIRWISE;
5119
5120 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5121 NULL, GFP_KERNEL);
5122
5123 return 0;
5124 }
5125
brcmf_notify_vif_event(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)5126 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5127 const struct brcmf_event_msg *e, void *data)
5128 {
5129 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5130 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5131 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5132 struct brcmf_cfg80211_vif *vif;
5133
5134 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
5135 ifevent->action, ifevent->flags, ifevent->ifidx,
5136 ifevent->bssidx);
5137
5138 mutex_lock(&event->vif_event_lock);
5139 event->action = ifevent->action;
5140 vif = event->vif;
5141
5142 switch (ifevent->action) {
5143 case BRCMF_E_IF_ADD:
5144 /* waiting process may have timed out */
5145 if (!cfg->vif_event.vif) {
5146 mutex_unlock(&event->vif_event_lock);
5147 return -EBADF;
5148 }
5149
5150 ifp->vif = vif;
5151 vif->ifp = ifp;
5152 if (ifp->ndev) {
5153 vif->wdev.netdev = ifp->ndev;
5154 ifp->ndev->ieee80211_ptr = &vif->wdev;
5155 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5156 }
5157 mutex_unlock(&event->vif_event_lock);
5158 wake_up(&event->vif_wq);
5159 return 0;
5160
5161 case BRCMF_E_IF_DEL:
5162 mutex_unlock(&event->vif_event_lock);
5163 /* event may not be upon user request */
5164 if (brcmf_cfg80211_vif_event_armed(cfg))
5165 wake_up(&event->vif_wq);
5166 return 0;
5167
5168 case BRCMF_E_IF_CHANGE:
5169 mutex_unlock(&event->vif_event_lock);
5170 wake_up(&event->vif_wq);
5171 return 0;
5172
5173 default:
5174 mutex_unlock(&event->vif_event_lock);
5175 break;
5176 }
5177 return -EINVAL;
5178 }
5179
brcmf_init_conf(struct brcmf_cfg80211_conf * conf)5180 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5181 {
5182 conf->frag_threshold = (u32)-1;
5183 conf->rts_threshold = (u32)-1;
5184 conf->retry_short = (u32)-1;
5185 conf->retry_long = (u32)-1;
5186 conf->tx_power = -1;
5187 }
5188
brcmf_register_event_handlers(struct brcmf_cfg80211_info * cfg)5189 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5190 {
5191 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5192 brcmf_notify_connect_status);
5193 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5194 brcmf_notify_connect_status);
5195 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5196 brcmf_notify_connect_status);
5197 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5198 brcmf_notify_connect_status);
5199 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5200 brcmf_notify_connect_status);
5201 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5202 brcmf_notify_connect_status);
5203 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5204 brcmf_notify_roaming_status);
5205 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5206 brcmf_notify_mic_status);
5207 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5208 brcmf_notify_connect_status);
5209 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5210 brcmf_notify_sched_scan_results);
5211 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5212 brcmf_notify_vif_event);
5213 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5214 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5215 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5216 brcmf_p2p_notify_listen_complete);
5217 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5218 brcmf_p2p_notify_action_frame_rx);
5219 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5220 brcmf_p2p_notify_action_tx_complete);
5221 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5222 brcmf_p2p_notify_action_tx_complete);
5223 }
5224
brcmf_deinit_priv_mem(struct brcmf_cfg80211_info * cfg)5225 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5226 {
5227 kfree(cfg->conf);
5228 cfg->conf = NULL;
5229 kfree(cfg->escan_ioctl_buf);
5230 cfg->escan_ioctl_buf = NULL;
5231 kfree(cfg->extra_buf);
5232 cfg->extra_buf = NULL;
5233 kfree(cfg->pmk_list);
5234 cfg->pmk_list = NULL;
5235 }
5236
brcmf_init_priv_mem(struct brcmf_cfg80211_info * cfg)5237 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5238 {
5239 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5240 if (!cfg->conf)
5241 goto init_priv_mem_out;
5242 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5243 if (!cfg->escan_ioctl_buf)
5244 goto init_priv_mem_out;
5245 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5246 if (!cfg->extra_buf)
5247 goto init_priv_mem_out;
5248 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
5249 if (!cfg->pmk_list)
5250 goto init_priv_mem_out;
5251
5252 return 0;
5253
5254 init_priv_mem_out:
5255 brcmf_deinit_priv_mem(cfg);
5256
5257 return -ENOMEM;
5258 }
5259
wl_init_priv(struct brcmf_cfg80211_info * cfg)5260 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5261 {
5262 s32 err = 0;
5263
5264 cfg->scan_request = NULL;
5265 cfg->pwr_save = true;
5266 cfg->active_scan = true; /* we do active scan per default */
5267 cfg->dongle_up = false; /* dongle is not up yet */
5268 err = brcmf_init_priv_mem(cfg);
5269 if (err)
5270 return err;
5271 brcmf_register_event_handlers(cfg);
5272 mutex_init(&cfg->usr_sync);
5273 brcmf_init_escan(cfg);
5274 brcmf_init_conf(cfg->conf);
5275 init_completion(&cfg->vif_disabled);
5276 return err;
5277 }
5278
wl_deinit_priv(struct brcmf_cfg80211_info * cfg)5279 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5280 {
5281 cfg->dongle_up = false; /* dongle down */
5282 brcmf_abort_scanning(cfg);
5283 brcmf_deinit_priv_mem(cfg);
5284 }
5285
init_vif_event(struct brcmf_cfg80211_vif_event * event)5286 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5287 {
5288 init_waitqueue_head(&event->vif_wq);
5289 mutex_init(&event->vif_event_lock);
5290 }
5291
5292 static s32
brcmf_dongle_roam(struct brcmf_if * ifp,u32 bcn_timeout)5293 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5294 {
5295 s32 err = 0;
5296 __le32 roamtrigger[2];
5297 __le32 roam_delta[2];
5298
5299 /*
5300 * Setup timeout if Beacons are lost and roam is
5301 * off to report link down
5302 */
5303 if (brcmf_roamoff) {
5304 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5305 if (err) {
5306 brcmf_err("bcn_timeout error (%d)\n", err);
5307 goto dongle_rom_out;
5308 }
5309 }
5310
5311 /*
5312 * Enable/Disable built-in roaming to allow supplicant
5313 * to take care of roaming
5314 */
5315 brcmf_dbg(INFO, "Internal Roaming = %s\n",
5316 brcmf_roamoff ? "Off" : "On");
5317 err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5318 if (err) {
5319 brcmf_err("roam_off error (%d)\n", err);
5320 goto dongle_rom_out;
5321 }
5322
5323 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5324 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5325 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5326 (void *)roamtrigger, sizeof(roamtrigger));
5327 if (err) {
5328 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5329 goto dongle_rom_out;
5330 }
5331
5332 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5333 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5334 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5335 (void *)roam_delta, sizeof(roam_delta));
5336 if (err) {
5337 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5338 goto dongle_rom_out;
5339 }
5340
5341 dongle_rom_out:
5342 return err;
5343 }
5344
5345 static s32
brcmf_dongle_scantime(struct brcmf_if * ifp,s32 scan_assoc_time,s32 scan_unassoc_time,s32 scan_passive_time)5346 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5347 s32 scan_unassoc_time, s32 scan_passive_time)
5348 {
5349 s32 err = 0;
5350
5351 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5352 scan_assoc_time);
5353 if (err) {
5354 if (err == -EOPNOTSUPP)
5355 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5356 else
5357 brcmf_err("Scan assoc time error (%d)\n", err);
5358 goto dongle_scantime_out;
5359 }
5360 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5361 scan_unassoc_time);
5362 if (err) {
5363 if (err == -EOPNOTSUPP)
5364 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5365 else
5366 brcmf_err("Scan unassoc time error (%d)\n", err);
5367 goto dongle_scantime_out;
5368 }
5369
5370 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5371 scan_passive_time);
5372 if (err) {
5373 if (err == -EOPNOTSUPP)
5374 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5375 else
5376 brcmf_err("Scan passive time error (%d)\n", err);
5377 goto dongle_scantime_out;
5378 }
5379
5380 dongle_scantime_out:
5381 return err;
5382 }
5383
brcmf_update_bw40_channel_flag(struct ieee80211_channel * channel,struct brcmu_chan * ch)5384 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5385 struct brcmu_chan *ch)
5386 {
5387 u32 ht40_flag;
5388
5389 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5390 if (ch->sb == BRCMU_CHAN_SB_U) {
5391 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5392 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5393 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5394 } else {
5395 /* It should be one of
5396 * IEEE80211_CHAN_NO_HT40 or
5397 * IEEE80211_CHAN_NO_HT40PLUS
5398 */
5399 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5400 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5401 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5402 }
5403 }
5404
brcmf_construct_chaninfo(struct brcmf_cfg80211_info * cfg,u32 bw_cap[])5405 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5406 u32 bw_cap[])
5407 {
5408 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5409 struct ieee80211_supported_band *band;
5410 struct ieee80211_channel *channel;
5411 struct wiphy *wiphy;
5412 struct brcmf_chanspec_list *list;
5413 struct brcmu_chan ch;
5414 int err;
5415 u8 *pbuf;
5416 u32 i, j;
5417 u32 total;
5418 u32 chaninfo;
5419 u32 index;
5420
5421 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5422
5423 if (pbuf == NULL)
5424 return -ENOMEM;
5425
5426 list = (struct brcmf_chanspec_list *)pbuf;
5427
5428 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5429 BRCMF_DCMD_MEDLEN);
5430 if (err) {
5431 brcmf_err("get chanspecs error (%d)\n", err);
5432 goto fail_pbuf;
5433 }
5434
5435 wiphy = cfg_to_wiphy(cfg);
5436 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5437 if (band)
5438 for (i = 0; i < band->n_channels; i++)
5439 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5440 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5441 if (band)
5442 for (i = 0; i < band->n_channels; i++)
5443 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5444
5445 total = le32_to_cpu(list->count);
5446 for (i = 0; i < total; i++) {
5447 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5448 cfg->d11inf.decchspec(&ch);
5449
5450 if (ch.band == BRCMU_CHAN_BAND_2G) {
5451 band = wiphy->bands[IEEE80211_BAND_2GHZ];
5452 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5453 band = wiphy->bands[IEEE80211_BAND_5GHZ];
5454 } else {
5455 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5456 continue;
5457 }
5458 if (!band)
5459 continue;
5460 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5461 ch.bw == BRCMU_CHAN_BW_40)
5462 continue;
5463 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5464 ch.bw == BRCMU_CHAN_BW_80)
5465 continue;
5466
5467 channel = band->channels;
5468 index = band->n_channels;
5469 for (j = 0; j < band->n_channels; j++) {
5470 if (channel[j].hw_value == ch.chnum) {
5471 index = j;
5472 break;
5473 }
5474 }
5475 channel[index].center_freq =
5476 ieee80211_channel_to_frequency(ch.chnum, band->band);
5477 channel[index].hw_value = ch.chnum;
5478
5479 /* assuming the chanspecs order is HT20,
5480 * HT40 upper, HT40 lower, and VHT80.
5481 */
5482 if (ch.bw == BRCMU_CHAN_BW_80) {
5483 channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5484 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5485 brcmf_update_bw40_channel_flag(&channel[index], &ch);
5486 } else {
5487 /* enable the channel and disable other bandwidths
5488 * for now as mentioned order assure they are enabled
5489 * for subsequent chanspecs.
5490 */
5491 channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5492 IEEE80211_CHAN_NO_80MHZ;
5493 ch.bw = BRCMU_CHAN_BW_20;
5494 cfg->d11inf.encchspec(&ch);
5495 chaninfo = ch.chspec;
5496 err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5497 &chaninfo);
5498 if (!err) {
5499 if (chaninfo & WL_CHAN_RADAR)
5500 channel[index].flags |=
5501 (IEEE80211_CHAN_RADAR |
5502 IEEE80211_CHAN_NO_IR);
5503 if (chaninfo & WL_CHAN_PASSIVE)
5504 channel[index].flags |=
5505 IEEE80211_CHAN_NO_IR;
5506 }
5507 }
5508 }
5509
5510 fail_pbuf:
5511 kfree(pbuf);
5512 return err;
5513 }
5514
brcmf_enable_bw40_2g(struct brcmf_cfg80211_info * cfg)5515 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5516 {
5517 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5518 struct ieee80211_supported_band *band;
5519 struct brcmf_fil_bwcap_le band_bwcap;
5520 struct brcmf_chanspec_list *list;
5521 u8 *pbuf;
5522 u32 val;
5523 int err;
5524 struct brcmu_chan ch;
5525 u32 num_chan;
5526 int i, j;
5527
5528 /* verify support for bw_cap command */
5529 val = WLC_BAND_5G;
5530 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5531
5532 if (!err) {
5533 /* only set 2G bandwidth using bw_cap command */
5534 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5535 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5536 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5537 sizeof(band_bwcap));
5538 } else {
5539 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5540 val = WLC_N_BW_40ALL;
5541 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5542 }
5543
5544 if (!err) {
5545 /* update channel info in 2G band */
5546 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5547
5548 if (pbuf == NULL)
5549 return -ENOMEM;
5550
5551 ch.band = BRCMU_CHAN_BAND_2G;
5552 ch.bw = BRCMU_CHAN_BW_40;
5553 ch.sb = BRCMU_CHAN_SB_NONE;
5554 ch.chnum = 0;
5555 cfg->d11inf.encchspec(&ch);
5556
5557 /* pass encoded chanspec in query */
5558 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5559
5560 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5561 BRCMF_DCMD_MEDLEN);
5562 if (err) {
5563 brcmf_err("get chanspecs error (%d)\n", err);
5564 kfree(pbuf);
5565 return err;
5566 }
5567
5568 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5569 list = (struct brcmf_chanspec_list *)pbuf;
5570 num_chan = le32_to_cpu(list->count);
5571 for (i = 0; i < num_chan; i++) {
5572 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5573 cfg->d11inf.decchspec(&ch);
5574 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5575 continue;
5576 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5577 continue;
5578 for (j = 0; j < band->n_channels; j++) {
5579 if (band->channels[j].hw_value == ch.chnum)
5580 break;
5581 }
5582 if (WARN_ON(j == band->n_channels))
5583 continue;
5584
5585 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5586 }
5587 kfree(pbuf);
5588 }
5589 return err;
5590 }
5591
brcmf_get_bwcap(struct brcmf_if * ifp,u32 bw_cap[])5592 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5593 {
5594 u32 band, mimo_bwcap;
5595 int err;
5596
5597 band = WLC_BAND_2G;
5598 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5599 if (!err) {
5600 bw_cap[IEEE80211_BAND_2GHZ] = band;
5601 band = WLC_BAND_5G;
5602 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5603 if (!err) {
5604 bw_cap[IEEE80211_BAND_5GHZ] = band;
5605 return;
5606 }
5607 WARN_ON(1);
5608 return;
5609 }
5610 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5611 mimo_bwcap = 0;
5612 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5613 if (err)
5614 /* assume 20MHz if firmware does not give a clue */
5615 mimo_bwcap = WLC_N_BW_20ALL;
5616
5617 switch (mimo_bwcap) {
5618 case WLC_N_BW_40ALL:
5619 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5620 /* fall-thru */
5621 case WLC_N_BW_20IN2G_40IN5G:
5622 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5623 /* fall-thru */
5624 case WLC_N_BW_20ALL:
5625 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5626 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5627 break;
5628 default:
5629 brcmf_err("invalid mimo_bw_cap value\n");
5630 }
5631 }
5632
brcmf_update_ht_cap(struct ieee80211_supported_band * band,u32 bw_cap[2],u32 nchain)5633 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5634 u32 bw_cap[2], u32 nchain)
5635 {
5636 band->ht_cap.ht_supported = true;
5637 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5638 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5639 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5640 }
5641 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5642 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5643 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5644 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5645 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5646 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5647 }
5648
brcmf_get_mcs_map(u32 nchain,enum ieee80211_vht_mcs_support supp)5649 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5650 {
5651 u16 mcs_map;
5652 int i;
5653
5654 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5655 mcs_map = (mcs_map << 2) | supp;
5656
5657 return cpu_to_le16(mcs_map);
5658 }
5659
brcmf_update_vht_cap(struct ieee80211_supported_band * band,u32 bw_cap[2],u32 nchain)5660 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5661 u32 bw_cap[2], u32 nchain)
5662 {
5663 __le16 mcs_map;
5664
5665 /* not allowed in 2.4G band */
5666 if (band->band == IEEE80211_BAND_2GHZ)
5667 return;
5668
5669 band->vht_cap.vht_supported = true;
5670 /* 80MHz is mandatory */
5671 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5672 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5673 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5674 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5675 }
5676 /* all support 256-QAM */
5677 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5678 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5679 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5680 }
5681
brcmf_setup_wiphybands(struct wiphy * wiphy)5682 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5683 {
5684 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5685 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5686 u32 nmode = 0;
5687 u32 vhtmode = 0;
5688 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5689 u32 rxchain;
5690 u32 nchain;
5691 int err;
5692 s32 i;
5693 struct ieee80211_supported_band *band;
5694
5695 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5696 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5697 if (err) {
5698 brcmf_err("nmode error (%d)\n", err);
5699 } else {
5700 brcmf_get_bwcap(ifp, bw_cap);
5701 }
5702 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5703 nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5704 bw_cap[IEEE80211_BAND_5GHZ]);
5705
5706 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5707 if (err) {
5708 brcmf_err("rxchain error (%d)\n", err);
5709 nchain = 1;
5710 } else {
5711 for (nchain = 0; rxchain; nchain++)
5712 rxchain = rxchain & (rxchain - 1);
5713 }
5714 brcmf_dbg(INFO, "nchain=%d\n", nchain);
5715
5716 err = brcmf_construct_chaninfo(cfg, bw_cap);
5717 if (err) {
5718 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5719 return err;
5720 }
5721
5722 wiphy = cfg_to_wiphy(cfg);
5723 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5724 band = wiphy->bands[i];
5725 if (band == NULL)
5726 continue;
5727
5728 if (nmode)
5729 brcmf_update_ht_cap(band, bw_cap, nchain);
5730 if (vhtmode)
5731 brcmf_update_vht_cap(band, bw_cap, nchain);
5732 }
5733
5734 return 0;
5735 }
5736
5737 static const struct ieee80211_txrx_stypes
5738 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5739 [NL80211_IFTYPE_STATION] = {
5740 .tx = 0xffff,
5741 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5742 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5743 },
5744 [NL80211_IFTYPE_P2P_CLIENT] = {
5745 .tx = 0xffff,
5746 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5747 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5748 },
5749 [NL80211_IFTYPE_P2P_GO] = {
5750 .tx = 0xffff,
5751 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5752 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5753 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5754 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5755 BIT(IEEE80211_STYPE_AUTH >> 4) |
5756 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5757 BIT(IEEE80211_STYPE_ACTION >> 4)
5758 },
5759 [NL80211_IFTYPE_P2P_DEVICE] = {
5760 .tx = 0xffff,
5761 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5762 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5763 }
5764 };
5765
5766 /**
5767 * brcmf_setup_ifmodes() - determine interface modes and combinations.
5768 *
5769 * @wiphy: wiphy object.
5770 * @ifp: interface object needed for feat module api.
5771 *
5772 * The interface modes and combinations are determined dynamically here
5773 * based on firmware functionality.
5774 *
5775 * no p2p and no mbss:
5776 *
5777 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5778 *
5779 * no p2p and mbss:
5780 *
5781 * #STA <= 1, #AP <= 1, channels = 1, 2 total
5782 * #AP <= 4, matching BI, channels = 1, 4 total
5783 *
5784 * p2p, no mchan, and mbss:
5785 *
5786 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
5787 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5788 * #AP <= 4, matching BI, channels = 1, 4 total
5789 *
5790 * p2p, mchan, and mbss:
5791 *
5792 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
5793 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
5794 * #AP <= 4, matching BI, channels = 1, 4 total
5795 */
brcmf_setup_ifmodes(struct wiphy * wiphy,struct brcmf_if * ifp)5796 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5797 {
5798 struct ieee80211_iface_combination *combo = NULL;
5799 struct ieee80211_iface_limit *c0_limits = NULL;
5800 struct ieee80211_iface_limit *p2p_limits = NULL;
5801 struct ieee80211_iface_limit *mbss_limits = NULL;
5802 bool mbss, p2p;
5803 int i, c, n_combos;
5804
5805 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
5806 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
5807
5808 n_combos = 1 + !!p2p + !!mbss;
5809 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
5810 if (!combo)
5811 goto err;
5812
5813 c0_limits = kcalloc(p2p ? 3 : 2, sizeof(*c0_limits), GFP_KERNEL);
5814 if (!c0_limits)
5815 goto err;
5816
5817 if (p2p) {
5818 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
5819 if (!p2p_limits)
5820 goto err;
5821 }
5822
5823 if (mbss) {
5824 mbss_limits = kcalloc(1, sizeof(*mbss_limits), GFP_KERNEL);
5825 if (!mbss_limits)
5826 goto err;
5827 }
5828
5829 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5830 BIT(NL80211_IFTYPE_ADHOC) |
5831 BIT(NL80211_IFTYPE_AP);
5832
5833 c = 0;
5834 i = 0;
5835 combo[c].num_different_channels = 1;
5836 c0_limits[i].max = 1;
5837 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5838 if (p2p) {
5839 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5840 combo[c].num_different_channels = 2;
5841 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5842 BIT(NL80211_IFTYPE_P2P_GO) |
5843 BIT(NL80211_IFTYPE_P2P_DEVICE);
5844 c0_limits[i].max = 1;
5845 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5846 c0_limits[i].max = 1;
5847 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5848 BIT(NL80211_IFTYPE_P2P_GO);
5849 } else {
5850 c0_limits[i].max = 1;
5851 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5852 }
5853 combo[c].max_interfaces = i;
5854 combo[c].n_limits = i;
5855 combo[c].limits = c0_limits;
5856
5857 if (p2p) {
5858 c++;
5859 i = 0;
5860 combo[c].num_different_channels = 1;
5861 p2p_limits[i].max = 1;
5862 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5863 p2p_limits[i].max = 1;
5864 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
5865 p2p_limits[i].max = 1;
5866 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
5867 p2p_limits[i].max = 1;
5868 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5869 combo[c].max_interfaces = i;
5870 combo[c].n_limits = i;
5871 combo[c].limits = p2p_limits;
5872 }
5873
5874 if (mbss) {
5875 c++;
5876 combo[c].beacon_int_infra_match = true;
5877 combo[c].num_different_channels = 1;
5878 mbss_limits[0].max = 4;
5879 mbss_limits[0].types = BIT(NL80211_IFTYPE_AP);
5880 combo[c].max_interfaces = 4;
5881 combo[c].n_limits = 1;
5882 combo[c].limits = mbss_limits;
5883 }
5884 wiphy->n_iface_combinations = n_combos;
5885 wiphy->iface_combinations = combo;
5886 return 0;
5887
5888 err:
5889 kfree(c0_limits);
5890 kfree(p2p_limits);
5891 kfree(mbss_limits);
5892 kfree(combo);
5893 return -ENOMEM;
5894 }
5895
brcmf_wiphy_pno_params(struct wiphy * wiphy)5896 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5897 {
5898 /* scheduled scan settings */
5899 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5900 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5901 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5902 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5903 }
5904
5905 #ifdef CONFIG_PM
5906 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5907 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5908 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5909 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5910 .pattern_min_len = 1,
5911 .max_pkt_offset = 1500,
5912 };
5913 #endif
5914
brcmf_wiphy_wowl_params(struct wiphy * wiphy)5915 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5916 {
5917 #ifdef CONFIG_PM
5918 /* wowl settings */
5919 wiphy->wowlan = &brcmf_wowlan_support;
5920 #endif
5921 }
5922
brcmf_setup_wiphy(struct wiphy * wiphy,struct brcmf_if * ifp)5923 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5924 {
5925 struct brcmf_pub *drvr = ifp->drvr;
5926 const struct ieee80211_iface_combination *combo;
5927 struct ieee80211_supported_band *band;
5928 u16 max_interfaces = 0;
5929 __le32 bandlist[3];
5930 u32 n_bands;
5931 int err, i;
5932
5933 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5934 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5935 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5936
5937 err = brcmf_setup_ifmodes(wiphy, ifp);
5938 if (err)
5939 return err;
5940
5941 for (i = 0, combo = wiphy->iface_combinations;
5942 i < wiphy->n_iface_combinations; i++, combo++) {
5943 max_interfaces = max(max_interfaces, combo->max_interfaces);
5944 }
5945
5946 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
5947 i++) {
5948 u8 *addr = drvr->addresses[i].addr;
5949
5950 memcpy(addr, drvr->mac, ETH_ALEN);
5951 if (i) {
5952 addr[0] |= BIT(1);
5953 addr[ETH_ALEN - 1] ^= i;
5954 }
5955 }
5956 wiphy->addresses = drvr->addresses;
5957 wiphy->n_addresses = i;
5958
5959 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5960 wiphy->cipher_suites = __wl_cipher_suites;
5961 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5962 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5963 WIPHY_FLAG_OFFCHAN_TX |
5964 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5965 WIPHY_FLAG_SUPPORTS_TDLS;
5966 if (!brcmf_roamoff)
5967 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5968 wiphy->mgmt_stypes = brcmf_txrx_stypes;
5969 wiphy->max_remain_on_channel_duration = 5000;
5970 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
5971 brcmf_wiphy_pno_params(wiphy);
5972
5973 /* vendor commands/events support */
5974 wiphy->vendor_commands = brcmf_vendor_cmds;
5975 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5976
5977 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
5978 brcmf_wiphy_wowl_params(wiphy);
5979
5980 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
5981 sizeof(bandlist));
5982 if (err) {
5983 brcmf_err("could not obtain band info: err=%d\n", err);
5984 return err;
5985 }
5986 /* first entry in bandlist is number of bands */
5987 n_bands = le32_to_cpu(bandlist[0]);
5988 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
5989 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
5990 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5991 GFP_KERNEL);
5992 if (!band)
5993 return -ENOMEM;
5994
5995 band->channels = kmemdup(&__wl_2ghz_channels,
5996 sizeof(__wl_2ghz_channels),
5997 GFP_KERNEL);
5998 if (!band->channels) {
5999 kfree(band);
6000 return -ENOMEM;
6001 }
6002
6003 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
6004 wiphy->bands[IEEE80211_BAND_2GHZ] = band;
6005 }
6006 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
6007 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
6008 GFP_KERNEL);
6009 if (!band)
6010 return -ENOMEM;
6011
6012 band->channels = kmemdup(&__wl_5ghz_channels,
6013 sizeof(__wl_5ghz_channels),
6014 GFP_KERNEL);
6015 if (!band->channels) {
6016 kfree(band);
6017 return -ENOMEM;
6018 }
6019
6020 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
6021 wiphy->bands[IEEE80211_BAND_5GHZ] = band;
6022 }
6023 }
6024 err = brcmf_setup_wiphybands(wiphy);
6025 return err;
6026 }
6027
brcmf_config_dongle(struct brcmf_cfg80211_info * cfg)6028 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
6029 {
6030 struct net_device *ndev;
6031 struct wireless_dev *wdev;
6032 struct brcmf_if *ifp;
6033 s32 power_mode;
6034 s32 err = 0;
6035
6036 if (cfg->dongle_up)
6037 return err;
6038
6039 ndev = cfg_to_ndev(cfg);
6040 wdev = ndev->ieee80211_ptr;
6041 ifp = netdev_priv(ndev);
6042
6043 /* make sure RF is ready for work */
6044 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
6045
6046 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
6047 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
6048
6049 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
6050 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
6051 if (err)
6052 goto default_conf_out;
6053 brcmf_dbg(INFO, "power save set to %s\n",
6054 (power_mode ? "enabled" : "disabled"));
6055
6056 err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
6057 if (err)
6058 goto default_conf_out;
6059 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
6060 NULL, NULL);
6061 if (err)
6062 goto default_conf_out;
6063
6064 brcmf_configure_arp_offload(ifp, true);
6065
6066 cfg->dongle_up = true;
6067 default_conf_out:
6068
6069 return err;
6070
6071 }
6072
__brcmf_cfg80211_up(struct brcmf_if * ifp)6073 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
6074 {
6075 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6076
6077 return brcmf_config_dongle(ifp->drvr->config);
6078 }
6079
__brcmf_cfg80211_down(struct brcmf_if * ifp)6080 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
6081 {
6082 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6083
6084 /*
6085 * While going down, if associated with AP disassociate
6086 * from AP to save power
6087 */
6088 if (check_vif_up(ifp->vif)) {
6089 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
6090
6091 /* Make sure WPA_Supplicant receives all the event
6092 generated due to DISASSOC call to the fw to keep
6093 the state fw and WPA_Supplicant state consistent
6094 */
6095 brcmf_delay(500);
6096 }
6097
6098 brcmf_abort_scanning(cfg);
6099 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
6100
6101 return 0;
6102 }
6103
brcmf_cfg80211_up(struct net_device * ndev)6104 s32 brcmf_cfg80211_up(struct net_device *ndev)
6105 {
6106 struct brcmf_if *ifp = netdev_priv(ndev);
6107 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6108 s32 err = 0;
6109
6110 mutex_lock(&cfg->usr_sync);
6111 err = __brcmf_cfg80211_up(ifp);
6112 mutex_unlock(&cfg->usr_sync);
6113
6114 return err;
6115 }
6116
brcmf_cfg80211_down(struct net_device * ndev)6117 s32 brcmf_cfg80211_down(struct net_device *ndev)
6118 {
6119 struct brcmf_if *ifp = netdev_priv(ndev);
6120 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6121 s32 err = 0;
6122
6123 mutex_lock(&cfg->usr_sync);
6124 err = __brcmf_cfg80211_down(ifp);
6125 mutex_unlock(&cfg->usr_sync);
6126
6127 return err;
6128 }
6129
brcmf_cfg80211_get_iftype(struct brcmf_if * ifp)6130 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
6131 {
6132 struct wireless_dev *wdev = &ifp->vif->wdev;
6133
6134 return wdev->iftype;
6135 }
6136
brcmf_get_vif_state_any(struct brcmf_cfg80211_info * cfg,unsigned long state)6137 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
6138 unsigned long state)
6139 {
6140 struct brcmf_cfg80211_vif *vif;
6141
6142 list_for_each_entry(vif, &cfg->vif_list, list) {
6143 if (test_bit(state, &vif->sme_state))
6144 return true;
6145 }
6146 return false;
6147 }
6148
vif_event_equals(struct brcmf_cfg80211_vif_event * event,u8 action)6149 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
6150 u8 action)
6151 {
6152 u8 evt_action;
6153
6154 mutex_lock(&event->vif_event_lock);
6155 evt_action = event->action;
6156 mutex_unlock(&event->vif_event_lock);
6157 return evt_action == action;
6158 }
6159
brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info * cfg,struct brcmf_cfg80211_vif * vif)6160 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6161 struct brcmf_cfg80211_vif *vif)
6162 {
6163 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6164
6165 mutex_lock(&event->vif_event_lock);
6166 event->vif = vif;
6167 event->action = 0;
6168 mutex_unlock(&event->vif_event_lock);
6169 }
6170
brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info * cfg)6171 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6172 {
6173 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6174 bool armed;
6175
6176 mutex_lock(&event->vif_event_lock);
6177 armed = event->vif != NULL;
6178 mutex_unlock(&event->vif_event_lock);
6179
6180 return armed;
6181 }
brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info * cfg,u8 action,ulong timeout)6182 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6183 u8 action, ulong timeout)
6184 {
6185 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6186
6187 return wait_event_timeout(event->vif_wq,
6188 vif_event_equals(event, action), timeout);
6189 }
6190
brcmf_cfg80211_reg_notifier(struct wiphy * wiphy,struct regulatory_request * req)6191 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6192 struct regulatory_request *req)
6193 {
6194 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6195 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6196 struct brcmf_fil_country_le ccreq;
6197 int i;
6198
6199 brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6200 req->alpha2[0], req->alpha2[1]);
6201
6202 /* ignore non-ISO3166 country codes */
6203 for (i = 0; i < 2; i++)
6204 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6205 brcmf_err("not a ISO3166 code\n");
6206 return;
6207 }
6208 memset(&ccreq, 0, sizeof(ccreq));
6209 ccreq.rev = cpu_to_le32(-1);
6210 memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6211 if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6212 brcmf_err("firmware rejected country setting\n");
6213 return;
6214 }
6215 brcmf_setup_wiphybands(wiphy);
6216 }
6217
brcmf_free_wiphy(struct wiphy * wiphy)6218 static void brcmf_free_wiphy(struct wiphy *wiphy)
6219 {
6220 int i;
6221
6222 if (!wiphy)
6223 return;
6224
6225 if (wiphy->iface_combinations) {
6226 for (i = 0; i < wiphy->n_iface_combinations; i++)
6227 kfree(wiphy->iface_combinations[i].limits);
6228 }
6229 kfree(wiphy->iface_combinations);
6230 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6231 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6232 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6233 }
6234 if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6235 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6236 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6237 }
6238 wiphy_free(wiphy);
6239 }
6240
brcmf_cfg80211_attach(struct brcmf_pub * drvr,struct device * busdev,bool p2pdev_forced)6241 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6242 struct device *busdev,
6243 bool p2pdev_forced)
6244 {
6245 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
6246 struct brcmf_cfg80211_info *cfg;
6247 struct wiphy *wiphy;
6248 struct brcmf_cfg80211_vif *vif;
6249 struct brcmf_if *ifp;
6250 s32 err = 0;
6251 s32 io_type;
6252 u16 *cap = NULL;
6253
6254 if (!ndev) {
6255 brcmf_err("ndev is invalid\n");
6256 return NULL;
6257 }
6258
6259 ifp = netdev_priv(ndev);
6260 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6261 if (!wiphy) {
6262 brcmf_err("Could not allocate wiphy device\n");
6263 return NULL;
6264 }
6265 memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6266 set_wiphy_dev(wiphy, busdev);
6267
6268 cfg = wiphy_priv(wiphy);
6269 cfg->wiphy = wiphy;
6270 cfg->pub = drvr;
6271 init_vif_event(&cfg->vif_event);
6272 INIT_LIST_HEAD(&cfg->vif_list);
6273
6274 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6275 if (IS_ERR(vif))
6276 goto wiphy_out;
6277
6278 vif->ifp = ifp;
6279 vif->wdev.netdev = ndev;
6280 ndev->ieee80211_ptr = &vif->wdev;
6281 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6282
6283 err = wl_init_priv(cfg);
6284 if (err) {
6285 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6286 brcmf_free_vif(vif);
6287 goto wiphy_out;
6288 }
6289 ifp->vif = vif;
6290
6291 /* determine d11 io type before wiphy setup */
6292 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6293 if (err) {
6294 brcmf_err("Failed to get D11 version (%d)\n", err);
6295 goto priv_out;
6296 }
6297 cfg->d11inf.io_type = (u8)io_type;
6298 brcmu_d11_attach(&cfg->d11inf);
6299
6300 err = brcmf_setup_wiphy(wiphy, ifp);
6301 if (err < 0)
6302 goto priv_out;
6303
6304 brcmf_dbg(INFO, "Registering custom regulatory\n");
6305 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6306 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6307 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6308
6309 /* firmware defaults to 40MHz disabled in 2G band. We signal
6310 * cfg80211 here that we do and have it decide we can enable
6311 * it. But first check if device does support 2G operation.
6312 */
6313 if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6314 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6315 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6316 }
6317 err = wiphy_register(wiphy);
6318 if (err < 0) {
6319 brcmf_err("Could not register wiphy device (%d)\n", err);
6320 goto priv_out;
6321 }
6322
6323 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6324 * setup 40MHz in 2GHz band and enable OBSS scanning.
6325 */
6326 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6327 err = brcmf_enable_bw40_2g(cfg);
6328 if (!err)
6329 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6330 BRCMF_OBSS_COEX_AUTO);
6331 else
6332 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6333 }
6334 /* p2p might require that "if-events" get processed by fweh. So
6335 * activate the already registered event handlers now and activate
6336 * the rest when initialization has completed. drvr->config needs to
6337 * be assigned before activating events.
6338 */
6339 drvr->config = cfg;
6340 err = brcmf_fweh_activate_events(ifp);
6341 if (err) {
6342 brcmf_err("FWEH activation failed (%d)\n", err);
6343 goto wiphy_unreg_out;
6344 }
6345
6346 err = brcmf_p2p_attach(cfg, p2pdev_forced);
6347 if (err) {
6348 brcmf_err("P2P initilisation failed (%d)\n", err);
6349 goto wiphy_unreg_out;
6350 }
6351 err = brcmf_btcoex_attach(cfg);
6352 if (err) {
6353 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6354 brcmf_p2p_detach(&cfg->p2p);
6355 goto wiphy_unreg_out;
6356 }
6357
6358 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6359 if (err) {
6360 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6361 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6362 } else {
6363 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6364 brcmf_notify_tdls_peer_event);
6365 }
6366
6367 /* (re-) activate FWEH event handling */
6368 err = brcmf_fweh_activate_events(ifp);
6369 if (err) {
6370 brcmf_err("FWEH activation failed (%d)\n", err);
6371 goto wiphy_unreg_out;
6372 }
6373
6374 return cfg;
6375
6376 wiphy_unreg_out:
6377 wiphy_unregister(cfg->wiphy);
6378 priv_out:
6379 wl_deinit_priv(cfg);
6380 brcmf_free_vif(vif);
6381 ifp->vif = NULL;
6382 wiphy_out:
6383 brcmf_free_wiphy(wiphy);
6384 return NULL;
6385 }
6386
brcmf_cfg80211_detach(struct brcmf_cfg80211_info * cfg)6387 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6388 {
6389 if (!cfg)
6390 return;
6391
6392 brcmf_btcoex_detach(cfg);
6393 wiphy_unregister(cfg->wiphy);
6394 wl_deinit_priv(cfg);
6395 brcmf_free_wiphy(cfg->wiphy);
6396 }
6397