1 // SPDX-License-Identifier: ISC
2 /*
3 * Copyright (c) 2010 Broadcom Corporation
4 */
5
6 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
7
8 #include <linux/kernel.h>
9 #include <linux/etherdevice.h>
10 #include <linux/module.h>
11 #include <linux/vmalloc.h>
12 #include <net/cfg80211.h>
13 #include <net/netlink.h>
14 #include <uapi/linux/if_arp.h>
15
16 #include <brcmu_utils.h>
17 #include <defs.h>
18 #include <brcmu_wifi.h>
19 #include <brcm_hw_ids.h>
20 #include "core.h"
21 #include "debug.h"
22 #include "tracepoint.h"
23 #include "fwil_types.h"
24 #include "p2p.h"
25 #include "btcoex.h"
26 #include "pno.h"
27 #include "fwsignal.h"
28 #include "cfg80211.h"
29 #include "feature.h"
30 #include "fwil.h"
31 #include "proto.h"
32 #include "vendor.h"
33 #include "bus.h"
34 #include "common.h"
35 #include "fwvid.h"
36
37 #define BRCMF_SCAN_IE_LEN_MAX 2048
38
39 #define WPA_OUI "\x00\x50\xF2" /* WPA OUI */
40 #define WPA_OUI_TYPE 1
41 #define RSN_OUI "\x00\x0F\xAC" /* RSN OUI */
42 #define WME_OUI_TYPE 2
43 #define WPS_OUI_TYPE 4
44
45 #define VS_IE_FIXED_HDR_LEN 6
46 #define WPA_IE_VERSION_LEN 2
47 #define WPA_IE_MIN_OUI_LEN 4
48 #define WPA_IE_SUITE_COUNT_LEN 2
49
50 #define WPA_CIPHER_NONE 0 /* None */
51 #define WPA_CIPHER_WEP_40 1 /* WEP (40-bit) */
52 #define WPA_CIPHER_TKIP 2 /* TKIP: default for WPA */
53 #define WPA_CIPHER_AES_CCM 4 /* AES (CCM) */
54 #define WPA_CIPHER_WEP_104 5 /* WEP (104-bit) */
55
56 #define RSN_AKM_NONE 0 /* None (IBSS) */
57 #define RSN_AKM_UNSPECIFIED 1 /* Over 802.1x */
58 #define RSN_AKM_PSK 2 /* Pre-shared Key */
59 #define RSN_AKM_SHA256_1X 5 /* SHA256, 802.1X */
60 #define RSN_AKM_SHA256_PSK 6 /* SHA256, Pre-shared Key */
61 #define RSN_AKM_SAE 8 /* SAE */
62 #define RSN_CAP_LEN 2 /* Length of RSN capabilities */
63 #define RSN_CAP_PTK_REPLAY_CNTR_MASK (BIT(2) | BIT(3))
64 #define RSN_CAP_MFPR_MASK BIT(6)
65 #define RSN_CAP_MFPC_MASK BIT(7)
66 #define RSN_PMKID_COUNT_LEN 2
67
68 #define VNDR_IE_CMD_LEN 4 /* length of the set command
69 * string :"add", "del" (+ NUL)
70 */
71 #define VNDR_IE_COUNT_OFFSET 4
72 #define VNDR_IE_PKTFLAG_OFFSET 8
73 #define VNDR_IE_VSIE_OFFSET 12
74 #define VNDR_IE_HDR_SIZE 12
75 #define VNDR_IE_PARSE_LIMIT 5
76
77 #define DOT11_BCN_PRB_FIXED_LEN 12 /* beacon/probe fixed length */
78
79 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS 320
80 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS 400
81 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS 20
82
83 #define BRCMF_SCAN_CHANNEL_TIME 40
84 #define BRCMF_SCAN_UNASSOC_TIME 40
85 #define BRCMF_SCAN_PASSIVE_TIME 120
86
87 #define BRCMF_ND_INFO_TIMEOUT msecs_to_jiffies(2000)
88
89 #define BRCMF_PS_MAX_TIMEOUT_MS 2000
90
91 /* Dump obss definitions */
92 #define ACS_MSRMNT_DELAY 80
93 #define CHAN_NOISE_DUMMY (-80)
94 #define OBSS_TOKEN_IDX 15
95 #define IBSS_TOKEN_IDX 15
96 #define TX_TOKEN_IDX 14
97 #define CTG_TOKEN_IDX 13
98 #define PKT_TOKEN_IDX 15
99 #define IDLE_TOKEN_IDX 12
100
101 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
102 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
103
104 #define BRCMF_MAX_CHANSPEC_LIST \
105 (BRCMF_DCMD_MEDLEN / sizeof(__le32) - 1)
106
107 struct brcmf_dump_survey {
108 u32 obss;
109 u32 ibss;
110 u32 no_ctg;
111 u32 no_pckt;
112 u32 tx;
113 u32 idle;
114 };
115
116 struct cca_stats_n_flags {
117 u32 msrmnt_time; /* Time for Measurement (msec) */
118 u32 msrmnt_done; /* flag set when measurement complete */
119 char buf[1];
120 };
121
122 struct cca_msrmnt_query {
123 u32 msrmnt_query;
124 u32 time_req;
125 };
126
check_vif_up(struct brcmf_cfg80211_vif * vif)127 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
128 {
129 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
130 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
131 vif->sme_state);
132 return false;
133 }
134 return true;
135 }
136
137 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
138 #define RATETAB_ENT(_rateid, _flags) \
139 { \
140 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
141 .hw_value = (_rateid), \
142 .flags = (_flags), \
143 }
144
145 static struct ieee80211_rate __wl_rates[] = {
146 RATETAB_ENT(BRCM_RATE_1M, 0),
147 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
148 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
149 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
150 RATETAB_ENT(BRCM_RATE_6M, 0),
151 RATETAB_ENT(BRCM_RATE_9M, 0),
152 RATETAB_ENT(BRCM_RATE_12M, 0),
153 RATETAB_ENT(BRCM_RATE_18M, 0),
154 RATETAB_ENT(BRCM_RATE_24M, 0),
155 RATETAB_ENT(BRCM_RATE_36M, 0),
156 RATETAB_ENT(BRCM_RATE_48M, 0),
157 RATETAB_ENT(BRCM_RATE_54M, 0),
158 };
159
160 #define wl_g_rates (__wl_rates + 0)
161 #define wl_g_rates_size ARRAY_SIZE(__wl_rates)
162 #define wl_a_rates (__wl_rates + 4)
163 #define wl_a_rates_size (wl_g_rates_size - 4)
164
165 #define CHAN2G(_channel, _freq) { \
166 .band = NL80211_BAND_2GHZ, \
167 .center_freq = (_freq), \
168 .hw_value = (_channel), \
169 .max_antenna_gain = 0, \
170 .max_power = 30, \
171 }
172
173 #define CHAN5G(_channel) { \
174 .band = NL80211_BAND_5GHZ, \
175 .center_freq = 5000 + (5 * (_channel)), \
176 .hw_value = (_channel), \
177 .max_antenna_gain = 0, \
178 .max_power = 30, \
179 }
180
181 static struct ieee80211_channel __wl_2ghz_channels[] = {
182 CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
183 CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
184 CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
185 CHAN2G(13, 2472), CHAN2G(14, 2484)
186 };
187
188 static struct ieee80211_channel __wl_5ghz_channels[] = {
189 CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
190 CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
191 CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
192 CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
193 CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
194 CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
195 };
196
197 /* Band templates duplicated per wiphy. The channel info
198 * above is added to the band during setup.
199 */
200 static const struct ieee80211_supported_band __wl_band_2ghz = {
201 .band = NL80211_BAND_2GHZ,
202 .bitrates = wl_g_rates,
203 .n_bitrates = wl_g_rates_size,
204 };
205
206 static const struct ieee80211_supported_band __wl_band_5ghz = {
207 .band = NL80211_BAND_5GHZ,
208 .bitrates = wl_a_rates,
209 .n_bitrates = wl_a_rates_size,
210 };
211
212 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
213 * By default world regulatory domain defined in reg.c puts the flags
214 * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
215 * With respect to these flags, wpa_supplicant doesn't * start p2p
216 * operations on 5GHz channels. All the changes in world regulatory
217 * domain are to be done here.
218 */
219 static const struct ieee80211_regdomain brcmf_regdom = {
220 .n_reg_rules = 4,
221 .alpha2 = "99",
222 .reg_rules = {
223 /* IEEE 802.11b/g, channels 1..11 */
224 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
225 /* If any */
226 /* IEEE 802.11 channel 14 - Only JP enables
227 * this and for 802.11b only
228 */
229 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
230 /* IEEE 802.11a, channel 36..64 */
231 REG_RULE(5150-10, 5350+10, 160, 6, 20, 0),
232 /* IEEE 802.11a, channel 100..165 */
233 REG_RULE(5470-10, 5850+10, 160, 6, 20, 0), }
234 };
235
236 /* Note: brcmf_cipher_suites is an array of int defining which cipher suites
237 * are supported. A pointer to this array and the number of entries is passed
238 * on to upper layers. AES_CMAC defines whether or not the driver supports MFP.
239 * So the cipher suite AES_CMAC has to be the last one in the array, and when
240 * device does not support MFP then the number of suites will be decreased by 1
241 */
242 static const u32 brcmf_cipher_suites[] = {
243 WLAN_CIPHER_SUITE_WEP40,
244 WLAN_CIPHER_SUITE_WEP104,
245 WLAN_CIPHER_SUITE_TKIP,
246 WLAN_CIPHER_SUITE_CCMP,
247 /* Keep as last entry: */
248 WLAN_CIPHER_SUITE_AES_CMAC
249 };
250
251 /* Vendor specific ie. id = 221, oui and type defines exact ie */
252 struct brcmf_vs_tlv {
253 u8 id;
254 u8 len;
255 u8 oui[3];
256 u8 oui_type;
257 };
258
259 struct parsed_vndr_ie_info {
260 u8 *ie_ptr;
261 u32 ie_len; /* total length including id & length field */
262 struct brcmf_vs_tlv vndrie;
263 };
264
265 struct parsed_vndr_ies {
266 u32 count;
267 struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
268 };
269
270 #define WL_INTERFACE_CREATE_VER_1 1
271 #define WL_INTERFACE_CREATE_VER_2 2
272 #define WL_INTERFACE_CREATE_VER_3 3
273 #define WL_INTERFACE_CREATE_VER_MAX WL_INTERFACE_CREATE_VER_3
274
275 #define WL_INTERFACE_MAC_DONT_USE 0x0
276 #define WL_INTERFACE_MAC_USE 0x2
277
278 #define WL_INTERFACE_CREATE_STA 0x0
279 #define WL_INTERFACE_CREATE_AP 0x1
280
281 struct wl_interface_create_v1 {
282 u16 ver; /* structure version */
283 u32 flags; /* flags for operation */
284 u8 mac_addr[ETH_ALEN]; /* MAC address */
285 u32 wlc_index; /* optional for wlc index */
286 };
287
288 struct wl_interface_create_v2 {
289 u16 ver; /* structure version */
290 u8 pad1[2];
291 u32 flags; /* flags for operation */
292 u8 mac_addr[ETH_ALEN]; /* MAC address */
293 u8 iftype; /* type of interface created */
294 u8 pad2;
295 u32 wlc_index; /* optional for wlc index */
296 };
297
298 struct wl_interface_create_v3 {
299 u16 ver; /* structure version */
300 u16 len; /* length of structure + data */
301 u16 fixed_len; /* length of structure */
302 u8 iftype; /* type of interface created */
303 u8 wlc_index; /* optional for wlc index */
304 u32 flags; /* flags for operation */
305 u8 mac_addr[ETH_ALEN]; /* MAC address */
306 u8 bssid[ETH_ALEN]; /* optional for BSSID */
307 u8 if_index; /* interface index request */
308 u8 pad[3];
309 u8 data[]; /* Optional for specific data */
310 };
311
nl80211_band_to_fwil(enum nl80211_band band)312 static u8 nl80211_band_to_fwil(enum nl80211_band band)
313 {
314 switch (band) {
315 case NL80211_BAND_2GHZ:
316 return WLC_BAND_2G;
317 case NL80211_BAND_5GHZ:
318 return WLC_BAND_5G;
319 default:
320 WARN_ON(1);
321 break;
322 }
323 return 0;
324 }
325
chandef_to_chanspec(struct brcmu_d11inf * d11inf,struct cfg80211_chan_def * ch)326 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
327 struct cfg80211_chan_def *ch)
328 {
329 struct brcmu_chan ch_inf;
330 s32 primary_offset;
331
332 brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
333 ch->chan->center_freq, ch->center_freq1, ch->width);
334 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
335 primary_offset = ch->chan->center_freq - ch->center_freq1;
336 switch (ch->width) {
337 case NL80211_CHAN_WIDTH_20:
338 case NL80211_CHAN_WIDTH_20_NOHT:
339 ch_inf.bw = BRCMU_CHAN_BW_20;
340 WARN_ON(primary_offset != 0);
341 break;
342 case NL80211_CHAN_WIDTH_40:
343 ch_inf.bw = BRCMU_CHAN_BW_40;
344 if (primary_offset > 0)
345 ch_inf.sb = BRCMU_CHAN_SB_U;
346 else
347 ch_inf.sb = BRCMU_CHAN_SB_L;
348 break;
349 case NL80211_CHAN_WIDTH_80:
350 ch_inf.bw = BRCMU_CHAN_BW_80;
351 if (primary_offset == -30)
352 ch_inf.sb = BRCMU_CHAN_SB_LL;
353 else if (primary_offset == -10)
354 ch_inf.sb = BRCMU_CHAN_SB_LU;
355 else if (primary_offset == 10)
356 ch_inf.sb = BRCMU_CHAN_SB_UL;
357 else
358 ch_inf.sb = BRCMU_CHAN_SB_UU;
359 break;
360 case NL80211_CHAN_WIDTH_160:
361 ch_inf.bw = BRCMU_CHAN_BW_160;
362 if (primary_offset == -70)
363 ch_inf.sb = BRCMU_CHAN_SB_LLL;
364 else if (primary_offset == -50)
365 ch_inf.sb = BRCMU_CHAN_SB_LLU;
366 else if (primary_offset == -30)
367 ch_inf.sb = BRCMU_CHAN_SB_LUL;
368 else if (primary_offset == -10)
369 ch_inf.sb = BRCMU_CHAN_SB_LUU;
370 else if (primary_offset == 10)
371 ch_inf.sb = BRCMU_CHAN_SB_ULL;
372 else if (primary_offset == 30)
373 ch_inf.sb = BRCMU_CHAN_SB_ULU;
374 else if (primary_offset == 50)
375 ch_inf.sb = BRCMU_CHAN_SB_UUL;
376 else
377 ch_inf.sb = BRCMU_CHAN_SB_UUU;
378 break;
379 case NL80211_CHAN_WIDTH_80P80:
380 case NL80211_CHAN_WIDTH_5:
381 case NL80211_CHAN_WIDTH_10:
382 default:
383 WARN_ON_ONCE(1);
384 }
385 switch (ch->chan->band) {
386 case NL80211_BAND_2GHZ:
387 ch_inf.band = BRCMU_CHAN_BAND_2G;
388 break;
389 case NL80211_BAND_5GHZ:
390 ch_inf.band = BRCMU_CHAN_BAND_5G;
391 break;
392 case NL80211_BAND_60GHZ:
393 default:
394 WARN_ON_ONCE(1);
395 }
396 d11inf->encchspec(&ch_inf);
397
398 brcmf_dbg(TRACE, "chanspec: 0x%x\n", ch_inf.chspec);
399 return ch_inf.chspec;
400 }
401
channel_to_chanspec(struct brcmu_d11inf * d11inf,struct ieee80211_channel * ch)402 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
403 struct ieee80211_channel *ch)
404 {
405 struct brcmu_chan ch_inf;
406
407 ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
408 ch_inf.bw = BRCMU_CHAN_BW_20;
409 d11inf->encchspec(&ch_inf);
410
411 return ch_inf.chspec;
412 }
413
414 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
415 * triples, returning a pointer to the substring whose first element
416 * matches tag
417 */
418 static const struct brcmf_tlv *
brcmf_parse_tlvs(const void * buf,int buflen,uint key)419 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
420 {
421 const struct brcmf_tlv *elt = buf;
422 int totlen = buflen;
423
424 /* find tagged parameter */
425 while (totlen >= TLV_HDR_LEN) {
426 int len = elt->len;
427
428 /* validate remaining totlen */
429 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
430 return elt;
431
432 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
433 totlen -= (len + TLV_HDR_LEN);
434 }
435
436 return NULL;
437 }
438
439 /* Is any of the tlvs the expected entry? If
440 * not update the tlvs buffer pointer/length.
441 */
442 static bool
brcmf_tlv_has_ie(const u8 * ie,const u8 ** tlvs,u32 * tlvs_len,const u8 * oui,u32 oui_len,u8 type)443 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
444 const u8 *oui, u32 oui_len, u8 type)
445 {
446 /* If the contents match the OUI and the type */
447 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
448 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
449 type == ie[TLV_BODY_OFF + oui_len]) {
450 return true;
451 }
452
453 if (tlvs == NULL)
454 return false;
455 /* point to the next ie */
456 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
457 /* calculate the length of the rest of the buffer */
458 *tlvs_len -= (int)(ie - *tlvs);
459 /* update the pointer to the start of the buffer */
460 *tlvs = ie;
461
462 return false;
463 }
464
465 static struct brcmf_vs_tlv *
brcmf_find_wpaie(const u8 * parse,u32 len)466 brcmf_find_wpaie(const u8 *parse, u32 len)
467 {
468 const struct brcmf_tlv *ie;
469
470 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
471 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
472 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
473 return (struct brcmf_vs_tlv *)ie;
474 }
475 return NULL;
476 }
477
478 static struct brcmf_vs_tlv *
brcmf_find_wpsie(const u8 * parse,u32 len)479 brcmf_find_wpsie(const u8 *parse, u32 len)
480 {
481 const struct brcmf_tlv *ie;
482
483 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
484 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
485 WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
486 return (struct brcmf_vs_tlv *)ie;
487 }
488 return NULL;
489 }
490
brcmf_vif_change_validate(struct brcmf_cfg80211_info * cfg,struct brcmf_cfg80211_vif * vif,enum nl80211_iftype new_type)491 static int brcmf_vif_change_validate(struct brcmf_cfg80211_info *cfg,
492 struct brcmf_cfg80211_vif *vif,
493 enum nl80211_iftype new_type)
494 {
495 struct brcmf_cfg80211_vif *pos;
496 bool check_combos = false;
497 int ret = 0;
498 struct iface_combination_params params = {
499 .num_different_channels = 1,
500 };
501
502 list_for_each_entry(pos, &cfg->vif_list, list)
503 if (pos == vif) {
504 params.iftype_num[new_type]++;
505 } else {
506 /* concurrent interfaces so need check combinations */
507 check_combos = true;
508 params.iftype_num[pos->wdev.iftype]++;
509 }
510
511 if (check_combos)
512 ret = cfg80211_check_combinations(cfg->wiphy, ¶ms);
513
514 return ret;
515 }
516
brcmf_vif_add_validate(struct brcmf_cfg80211_info * cfg,enum nl80211_iftype new_type)517 static int brcmf_vif_add_validate(struct brcmf_cfg80211_info *cfg,
518 enum nl80211_iftype new_type)
519 {
520 struct brcmf_cfg80211_vif *pos;
521 struct iface_combination_params params = {
522 .num_different_channels = 1,
523 };
524
525 list_for_each_entry(pos, &cfg->vif_list, list)
526 params.iftype_num[pos->wdev.iftype]++;
527
528 params.iftype_num[new_type]++;
529 return cfg80211_check_combinations(cfg->wiphy, ¶ms);
530 }
531
convert_key_from_CPU(struct brcmf_wsec_key * key,struct brcmf_wsec_key_le * key_le)532 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
533 struct brcmf_wsec_key_le *key_le)
534 {
535 key_le->index = cpu_to_le32(key->index);
536 key_le->len = cpu_to_le32(key->len);
537 key_le->algo = cpu_to_le32(key->algo);
538 key_le->flags = cpu_to_le32(key->flags);
539 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
540 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
541 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
542 memcpy(key_le->data, key->data, sizeof(key->data));
543 memcpy(key_le->ea, key->ea, sizeof(key->ea));
544 }
545
546 static int
send_key_to_dongle(struct brcmf_if * ifp,struct brcmf_wsec_key * key)547 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
548 {
549 struct brcmf_pub *drvr = ifp->drvr;
550 int err;
551 struct brcmf_wsec_key_le key_le;
552
553 convert_key_from_CPU(key, &key_le);
554
555 brcmf_netdev_wait_pend8021x(ifp);
556
557 err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
558 sizeof(key_le));
559
560 if (err)
561 bphy_err(drvr, "wsec_key error (%d)\n", err);
562 return err;
563 }
564
565 static void
brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev * wdev)566 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
567 {
568 struct brcmf_cfg80211_vif *vif;
569 struct brcmf_if *ifp;
570
571 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
572 ifp = vif->ifp;
573
574 if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
575 (wdev->iftype == NL80211_IFTYPE_AP) ||
576 (wdev->iftype == NL80211_IFTYPE_P2P_GO))
577 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
578 ADDR_DIRECT);
579 else
580 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
581 ADDR_INDIRECT);
582 }
583
brcmf_get_first_free_bsscfgidx(struct brcmf_pub * drvr)584 static int brcmf_get_first_free_bsscfgidx(struct brcmf_pub *drvr)
585 {
586 int bsscfgidx;
587
588 for (bsscfgidx = 0; bsscfgidx < BRCMF_MAX_IFS; bsscfgidx++) {
589 /* bsscfgidx 1 is reserved for legacy P2P */
590 if (bsscfgidx == 1)
591 continue;
592 if (!drvr->iflist[bsscfgidx])
593 return bsscfgidx;
594 }
595
596 return -ENOMEM;
597 }
598
brcmf_set_vif_sta_macaddr(struct brcmf_if * ifp,u8 * mac_addr)599 static void brcmf_set_vif_sta_macaddr(struct brcmf_if *ifp, u8 *mac_addr)
600 {
601 u8 mac_idx = ifp->drvr->sta_mac_idx;
602
603 /* set difference MAC address with locally administered bit */
604 memcpy(mac_addr, ifp->mac_addr, ETH_ALEN);
605 mac_addr[0] |= 0x02;
606 mac_addr[3] ^= mac_idx ? 0xC0 : 0xA0;
607 mac_idx++;
608 mac_idx = mac_idx % 2;
609 ifp->drvr->sta_mac_idx = mac_idx;
610 }
611
brcmf_cfg80211_request_sta_if(struct brcmf_if * ifp,u8 * macaddr)612 static int brcmf_cfg80211_request_sta_if(struct brcmf_if *ifp, u8 *macaddr)
613 {
614 struct wl_interface_create_v1 iface_v1;
615 struct wl_interface_create_v2 iface_v2;
616 struct wl_interface_create_v3 iface_v3;
617 u32 iface_create_ver;
618 int err;
619
620 /* interface_create version 1 */
621 memset(&iface_v1, 0, sizeof(iface_v1));
622 iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
623 iface_v1.flags = WL_INTERFACE_CREATE_STA |
624 WL_INTERFACE_MAC_USE;
625 if (!is_zero_ether_addr(macaddr))
626 memcpy(iface_v1.mac_addr, macaddr, ETH_ALEN);
627 else
628 brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
629
630 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
631 &iface_v1,
632 sizeof(iface_v1));
633 if (err) {
634 brcmf_info("failed to create interface(v1), err=%d\n",
635 err);
636 } else {
637 brcmf_dbg(INFO, "interface created(v1)\n");
638 return 0;
639 }
640
641 /* interface_create version 2 */
642 memset(&iface_v2, 0, sizeof(iface_v2));
643 iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
644 iface_v2.flags = WL_INTERFACE_MAC_USE;
645 iface_v2.iftype = WL_INTERFACE_CREATE_STA;
646 if (!is_zero_ether_addr(macaddr))
647 memcpy(iface_v2.mac_addr, macaddr, ETH_ALEN);
648 else
649 brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
650
651 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
652 &iface_v2,
653 sizeof(iface_v2));
654 if (err) {
655 brcmf_info("failed to create interface(v2), err=%d\n",
656 err);
657 } else {
658 brcmf_dbg(INFO, "interface created(v2)\n");
659 return 0;
660 }
661
662 /* interface_create version 3+ */
663 /* get supported version from firmware side */
664 iface_create_ver = 0;
665 err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
666 &iface_create_ver);
667 if (err) {
668 brcmf_err("fail to get supported version, err=%d\n", err);
669 return -EOPNOTSUPP;
670 }
671
672 switch (iface_create_ver) {
673 case WL_INTERFACE_CREATE_VER_3:
674 memset(&iface_v3, 0, sizeof(iface_v3));
675 iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
676 iface_v3.flags = WL_INTERFACE_MAC_USE;
677 iface_v3.iftype = WL_INTERFACE_CREATE_STA;
678 if (!is_zero_ether_addr(macaddr))
679 memcpy(iface_v3.mac_addr, macaddr, ETH_ALEN);
680 else
681 brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
682
683 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
684 &iface_v3,
685 sizeof(iface_v3));
686
687 if (!err)
688 brcmf_dbg(INFO, "interface created(v3)\n");
689 break;
690 default:
691 brcmf_err("not support interface create(v%d)\n",
692 iface_create_ver);
693 err = -EOPNOTSUPP;
694 break;
695 }
696
697 if (err) {
698 brcmf_info("station interface creation failed (%d)\n",
699 err);
700 return -EIO;
701 }
702
703 return 0;
704 }
705
brcmf_cfg80211_request_ap_if(struct brcmf_if * ifp)706 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
707 {
708 struct wl_interface_create_v1 iface_v1;
709 struct wl_interface_create_v2 iface_v2;
710 struct wl_interface_create_v3 iface_v3;
711 u32 iface_create_ver;
712 struct brcmf_pub *drvr = ifp->drvr;
713 struct brcmf_mbss_ssid_le mbss_ssid_le;
714 int bsscfgidx;
715 int err;
716
717 /* interface_create version 1 */
718 memset(&iface_v1, 0, sizeof(iface_v1));
719 iface_v1.ver = WL_INTERFACE_CREATE_VER_1;
720 iface_v1.flags = WL_INTERFACE_CREATE_AP |
721 WL_INTERFACE_MAC_USE;
722
723 brcmf_set_vif_sta_macaddr(ifp, iface_v1.mac_addr);
724
725 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
726 &iface_v1,
727 sizeof(iface_v1));
728 if (err) {
729 brcmf_info("failed to create interface(v1), err=%d\n",
730 err);
731 } else {
732 brcmf_dbg(INFO, "interface created(v1)\n");
733 return 0;
734 }
735
736 /* interface_create version 2 */
737 memset(&iface_v2, 0, sizeof(iface_v2));
738 iface_v2.ver = WL_INTERFACE_CREATE_VER_2;
739 iface_v2.flags = WL_INTERFACE_MAC_USE;
740 iface_v2.iftype = WL_INTERFACE_CREATE_AP;
741
742 brcmf_set_vif_sta_macaddr(ifp, iface_v2.mac_addr);
743
744 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
745 &iface_v2,
746 sizeof(iface_v2));
747 if (err) {
748 brcmf_info("failed to create interface(v2), err=%d\n",
749 err);
750 } else {
751 brcmf_dbg(INFO, "interface created(v2)\n");
752 return 0;
753 }
754
755 /* interface_create version 3+ */
756 /* get supported version from firmware side */
757 iface_create_ver = 0;
758 err = brcmf_fil_bsscfg_int_query(ifp, "interface_create",
759 &iface_create_ver);
760 if (err) {
761 brcmf_err("fail to get supported version, err=%d\n", err);
762 return -EOPNOTSUPP;
763 }
764
765 switch (iface_create_ver) {
766 case WL_INTERFACE_CREATE_VER_3:
767 memset(&iface_v3, 0, sizeof(iface_v3));
768 iface_v3.ver = WL_INTERFACE_CREATE_VER_3;
769 iface_v3.flags = WL_INTERFACE_MAC_USE;
770 iface_v3.iftype = WL_INTERFACE_CREATE_AP;
771 brcmf_set_vif_sta_macaddr(ifp, iface_v3.mac_addr);
772
773 err = brcmf_fil_iovar_data_get(ifp, "interface_create",
774 &iface_v3,
775 sizeof(iface_v3));
776
777 if (!err)
778 brcmf_dbg(INFO, "interface created(v3)\n");
779 break;
780 default:
781 brcmf_err("not support interface create(v%d)\n",
782 iface_create_ver);
783 err = -EOPNOTSUPP;
784 break;
785 }
786
787 if (err) {
788 brcmf_info("Does not support interface_create (%d)\n",
789 err);
790 memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
791 bsscfgidx = brcmf_get_first_free_bsscfgidx(ifp->drvr);
792 if (bsscfgidx < 0)
793 return bsscfgidx;
794
795 mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
796 mbss_ssid_le.SSID_len = cpu_to_le32(5);
797 sprintf(mbss_ssid_le.SSID, "ssid%d", bsscfgidx);
798
799 err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
800 sizeof(mbss_ssid_le));
801
802 if (err < 0)
803 bphy_err(drvr, "setting ssid failed %d\n", err);
804 }
805
806 return err;
807 }
808
809 /**
810 * brcmf_apsta_add_vif() - create a new AP or STA virtual interface
811 *
812 * @wiphy: wiphy device of new interface.
813 * @name: name of the new interface.
814 * @params: contains mac address for AP or STA device.
815 * @type: interface type.
816 *
817 * Return: pointer to new vif on success, ERR_PTR(-errno) if not
818 */
819 static
brcmf_apsta_add_vif(struct wiphy * wiphy,const char * name,struct vif_params * params,enum nl80211_iftype type)820 struct wireless_dev *brcmf_apsta_add_vif(struct wiphy *wiphy, const char *name,
821 struct vif_params *params,
822 enum nl80211_iftype type)
823 {
824 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
825 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
826 struct brcmf_pub *drvr = cfg->pub;
827 struct brcmf_cfg80211_vif *vif;
828 int err;
829
830 if (type != NL80211_IFTYPE_STATION && type != NL80211_IFTYPE_AP)
831 return ERR_PTR(-EINVAL);
832
833 if (brcmf_cfg80211_vif_event_armed(cfg))
834 return ERR_PTR(-EBUSY);
835
836 brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
837
838 vif = brcmf_alloc_vif(cfg, type);
839 if (IS_ERR(vif))
840 return (struct wireless_dev *)vif;
841
842 brcmf_cfg80211_arm_vif_event(cfg, vif);
843
844 if (type == NL80211_IFTYPE_STATION)
845 err = brcmf_cfg80211_request_sta_if(ifp, params->macaddr);
846 else
847 err = brcmf_cfg80211_request_ap_if(ifp);
848 if (err) {
849 brcmf_cfg80211_arm_vif_event(cfg, NULL);
850 goto fail;
851 }
852
853 /* wait for firmware event */
854 err = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_ADD,
855 BRCMF_VIF_EVENT_TIMEOUT);
856 brcmf_cfg80211_arm_vif_event(cfg, NULL);
857 if (!err) {
858 bphy_err(drvr, "timeout occurred\n");
859 err = -EIO;
860 goto fail;
861 }
862
863 /* interface created in firmware */
864 ifp = vif->ifp;
865 if (!ifp) {
866 bphy_err(drvr, "no if pointer provided\n");
867 err = -ENOENT;
868 goto fail;
869 }
870
871 strscpy(ifp->ndev->name, name, sizeof(ifp->ndev->name));
872 err = brcmf_net_attach(ifp, true);
873 if (err) {
874 bphy_err(drvr, "Registering netdevice failed\n");
875 free_netdev(ifp->ndev);
876 goto fail;
877 }
878
879 return &ifp->vif->wdev;
880
881 fail:
882 brcmf_free_vif(vif);
883 return ERR_PTR(err);
884 }
885
brcmf_is_apmode(struct brcmf_cfg80211_vif * vif)886 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
887 {
888 enum nl80211_iftype iftype;
889
890 iftype = vif->wdev.iftype;
891 return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
892 }
893
brcmf_is_ibssmode(struct brcmf_cfg80211_vif * vif)894 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
895 {
896 return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
897 }
898
899 /**
900 * brcmf_mon_add_vif() - create monitor mode virtual interface
901 *
902 * @wiphy: wiphy device of new interface.
903 * @name: name of the new interface.
904 *
905 * Return: pointer to new vif on success, ERR_PTR(-errno) if not
906 */
brcmf_mon_add_vif(struct wiphy * wiphy,const char * name)907 static struct wireless_dev *brcmf_mon_add_vif(struct wiphy *wiphy,
908 const char *name)
909 {
910 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
911 struct brcmf_cfg80211_vif *vif;
912 struct net_device *ndev;
913 struct brcmf_if *ifp;
914 int err;
915
916 if (cfg->pub->mon_if) {
917 err = -EEXIST;
918 goto err_out;
919 }
920
921 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_MONITOR);
922 if (IS_ERR(vif)) {
923 err = PTR_ERR(vif);
924 goto err_out;
925 }
926
927 ndev = alloc_netdev(sizeof(*ifp), name, NET_NAME_UNKNOWN, ether_setup);
928 if (!ndev) {
929 err = -ENOMEM;
930 goto err_free_vif;
931 }
932 ndev->type = ARPHRD_IEEE80211_RADIOTAP;
933 ndev->ieee80211_ptr = &vif->wdev;
934 ndev->needs_free_netdev = true;
935 ndev->priv_destructor = brcmf_cfg80211_free_netdev;
936 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
937
938 ifp = netdev_priv(ndev);
939 ifp->vif = vif;
940 ifp->ndev = ndev;
941 ifp->drvr = cfg->pub;
942
943 vif->ifp = ifp;
944 vif->wdev.netdev = ndev;
945
946 err = brcmf_net_mon_attach(ifp);
947 if (err) {
948 brcmf_err("Failed to attach %s device\n", ndev->name);
949 free_netdev(ndev);
950 goto err_free_vif;
951 }
952
953 cfg->pub->mon_if = ifp;
954
955 return &vif->wdev;
956
957 err_free_vif:
958 brcmf_free_vif(vif);
959 err_out:
960 return ERR_PTR(err);
961 }
962
brcmf_mon_del_vif(struct wiphy * wiphy,struct wireless_dev * wdev)963 static int brcmf_mon_del_vif(struct wiphy *wiphy, struct wireless_dev *wdev)
964 {
965 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
966 struct net_device *ndev = wdev->netdev;
967
968 ndev->netdev_ops->ndo_stop(ndev);
969
970 brcmf_net_detach(ndev, true);
971
972 cfg->pub->mon_if = NULL;
973
974 return 0;
975 }
976
brcmf_cfg80211_add_iface(struct wiphy * wiphy,const char * name,unsigned char name_assign_type,enum nl80211_iftype type,struct vif_params * params)977 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
978 const char *name,
979 unsigned char name_assign_type,
980 enum nl80211_iftype type,
981 struct vif_params *params)
982 {
983 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
984 struct brcmf_pub *drvr = cfg->pub;
985 struct wireless_dev *wdev;
986 int err;
987
988 brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
989 err = brcmf_vif_add_validate(wiphy_to_cfg(wiphy), type);
990 if (err) {
991 bphy_err(drvr, "iface validation failed: err=%d\n", err);
992 return ERR_PTR(err);
993 }
994 switch (type) {
995 case NL80211_IFTYPE_ADHOC:
996 case NL80211_IFTYPE_AP_VLAN:
997 case NL80211_IFTYPE_WDS:
998 case NL80211_IFTYPE_MESH_POINT:
999 return ERR_PTR(-EOPNOTSUPP);
1000 case NL80211_IFTYPE_MONITOR:
1001 return brcmf_mon_add_vif(wiphy, name);
1002 case NL80211_IFTYPE_STATION:
1003 case NL80211_IFTYPE_AP:
1004 wdev = brcmf_apsta_add_vif(wiphy, name, params, type);
1005 break;
1006 case NL80211_IFTYPE_P2P_CLIENT:
1007 case NL80211_IFTYPE_P2P_GO:
1008 case NL80211_IFTYPE_P2P_DEVICE:
1009 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, params);
1010 break;
1011 case NL80211_IFTYPE_UNSPECIFIED:
1012 default:
1013 return ERR_PTR(-EINVAL);
1014 }
1015
1016 if (IS_ERR(wdev))
1017 bphy_err(drvr, "add iface %s type %d failed: err=%d\n", name,
1018 type, (int)PTR_ERR(wdev));
1019 else
1020 brcmf_cfg80211_update_proto_addr_mode(wdev);
1021
1022 return wdev;
1023 }
1024
brcmf_scan_config_mpc(struct brcmf_if * ifp,int mpc)1025 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
1026 {
1027 if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
1028 brcmf_set_mpc(ifp, mpc);
1029 }
1030
brcmf_set_mpc(struct brcmf_if * ifp,int mpc)1031 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
1032 {
1033 struct brcmf_pub *drvr = ifp->drvr;
1034 s32 err = 0;
1035
1036 if (check_vif_up(ifp->vif)) {
1037 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
1038 if (err) {
1039 bphy_err(drvr, "fail to set mpc\n");
1040 return;
1041 }
1042 brcmf_dbg(INFO, "MPC : %d\n", mpc);
1043 }
1044 }
1045
brcmf_is_apmode_operating(struct wiphy * wiphy)1046 bool brcmf_is_apmode_operating(struct wiphy *wiphy)
1047 {
1048 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1049 struct brcmf_cfg80211_vif *vif;
1050 bool ret = false;
1051
1052 list_for_each_entry(vif, &cfg->vif_list, list) {
1053 if (brcmf_is_apmode(vif) &&
1054 test_bit(BRCMF_VIF_STATUS_AP_CREATED, &vif->sme_state))
1055 ret = true;
1056 }
1057
1058 return ret;
1059 }
1060
brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le * params_v2_le,struct brcmf_scan_params_le * params_le)1061 static void brcmf_scan_params_v2_to_v1(struct brcmf_scan_params_v2_le *params_v2_le,
1062 struct brcmf_scan_params_le *params_le)
1063 {
1064 size_t params_size;
1065 u32 ch;
1066 int n_channels, n_ssids;
1067
1068 memcpy(¶ms_le->ssid_le, ¶ms_v2_le->ssid_le,
1069 sizeof(params_le->ssid_le));
1070 memcpy(¶ms_le->bssid, ¶ms_v2_le->bssid,
1071 sizeof(params_le->bssid));
1072
1073 params_le->bss_type = params_v2_le->bss_type;
1074 params_le->scan_type = le32_to_cpu(params_v2_le->scan_type);
1075 params_le->nprobes = params_v2_le->nprobes;
1076 params_le->active_time = params_v2_le->active_time;
1077 params_le->passive_time = params_v2_le->passive_time;
1078 params_le->home_time = params_v2_le->home_time;
1079 params_le->channel_num = params_v2_le->channel_num;
1080
1081 ch = le32_to_cpu(params_v2_le->channel_num);
1082 n_channels = ch & BRCMF_SCAN_PARAMS_COUNT_MASK;
1083 n_ssids = ch >> BRCMF_SCAN_PARAMS_NSSID_SHIFT;
1084
1085 params_size = sizeof(u16) * n_channels;
1086 if (n_ssids > 0) {
1087 params_size = roundup(params_size, sizeof(u32));
1088 params_size += sizeof(struct brcmf_ssid_le) * n_ssids;
1089 }
1090
1091 memcpy(¶ms_le->channel_list[0],
1092 ¶ms_v2_le->channel_list[0], params_size);
1093 }
1094
brcmf_escan_prep(struct brcmf_cfg80211_info * cfg,struct brcmf_scan_params_v2_le * params_le,struct cfg80211_scan_request * request)1095 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
1096 struct brcmf_scan_params_v2_le *params_le,
1097 struct cfg80211_scan_request *request)
1098 {
1099 u32 n_ssids;
1100 u32 n_channels;
1101 s32 i;
1102 s32 offset;
1103 u16 chanspec;
1104 char *ptr;
1105 int length;
1106 struct brcmf_ssid_le ssid_le;
1107
1108 eth_broadcast_addr(params_le->bssid);
1109
1110 length = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1111
1112 params_le->version = cpu_to_le16(BRCMF_SCAN_PARAMS_VERSION_V2);
1113 params_le->bss_type = DOT11_BSSTYPE_ANY;
1114 params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_ACTIVE);
1115 params_le->channel_num = 0;
1116 params_le->nprobes = cpu_to_le32(-1);
1117 params_le->active_time = cpu_to_le32(-1);
1118 params_le->passive_time = cpu_to_le32(-1);
1119 params_le->home_time = cpu_to_le32(-1);
1120 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
1121
1122 /* Scan abort */
1123 if (!request) {
1124 length += sizeof(u16);
1125 params_le->channel_num = cpu_to_le32(1);
1126 params_le->channel_list[0] = cpu_to_le16(-1);
1127 params_le->length = cpu_to_le16(length);
1128 return;
1129 }
1130
1131 n_ssids = request->n_ssids;
1132 n_channels = request->n_channels;
1133
1134 /* Copy channel array if applicable */
1135 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
1136 n_channels);
1137 if (n_channels > 0) {
1138 length += roundup(sizeof(u16) * n_channels, sizeof(u32));
1139 for (i = 0; i < n_channels; i++) {
1140 chanspec = channel_to_chanspec(&cfg->d11inf,
1141 request->channels[i]);
1142 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
1143 request->channels[i]->hw_value, chanspec);
1144 params_le->channel_list[i] = cpu_to_le16(chanspec);
1145 }
1146 } else {
1147 brcmf_dbg(SCAN, "Scanning all channels\n");
1148 }
1149
1150 /* Copy ssid array if applicable */
1151 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
1152 if (n_ssids > 0) {
1153 offset = offsetof(struct brcmf_scan_params_v2_le, channel_list) +
1154 n_channels * sizeof(u16);
1155 offset = roundup(offset, sizeof(u32));
1156 length += sizeof(ssid_le) * n_ssids;
1157 ptr = (char *)params_le + offset;
1158 for (i = 0; i < n_ssids; i++) {
1159 memset(&ssid_le, 0, sizeof(ssid_le));
1160 ssid_le.SSID_len =
1161 cpu_to_le32(request->ssids[i].ssid_len);
1162 memcpy(ssid_le.SSID, request->ssids[i].ssid,
1163 request->ssids[i].ssid_len);
1164 if (!ssid_le.SSID_len)
1165 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
1166 else
1167 brcmf_dbg(SCAN, "%d: scan for %.32s size=%d\n",
1168 i, ssid_le.SSID, ssid_le.SSID_len);
1169 memcpy(ptr, &ssid_le, sizeof(ssid_le));
1170 ptr += sizeof(ssid_le);
1171 }
1172 } else {
1173 brcmf_dbg(SCAN, "Performing passive scan\n");
1174 params_le->scan_type = cpu_to_le32(BRCMF_SCANTYPE_PASSIVE);
1175 }
1176 params_le->length = cpu_to_le16(length);
1177 /* Adding mask to channel numbers */
1178 params_le->channel_num =
1179 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
1180 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
1181 }
1182
brcmf_notify_escan_complete(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,bool aborted,bool fw_abort)1183 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
1184 struct brcmf_if *ifp, bool aborted,
1185 bool fw_abort)
1186 {
1187 struct brcmf_pub *drvr = cfg->pub;
1188 struct brcmf_scan_params_v2_le params_v2_le;
1189 struct cfg80211_scan_request *scan_request;
1190 u64 reqid;
1191 u32 bucket;
1192 s32 err = 0;
1193
1194 brcmf_dbg(SCAN, "Enter\n");
1195
1196 /* clear scan request, because the FW abort can cause a second call */
1197 /* to this functon and might cause a double cfg80211_scan_done */
1198 scan_request = cfg->scan_request;
1199 cfg->scan_request = NULL;
1200
1201 timer_delete_sync(&cfg->escan_timeout);
1202
1203 if (fw_abort) {
1204 /* Do a scan abort to stop the driver's scan engine */
1205 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
1206
1207 brcmf_escan_prep(cfg, ¶ms_v2_le, NULL);
1208
1209 /* E-Scan (or anyother type) can be aborted by SCAN */
1210 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1211 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1212 ¶ms_v2_le,
1213 sizeof(params_v2_le));
1214 } else {
1215 struct brcmf_scan_params_le params_le;
1216
1217 brcmf_scan_params_v2_to_v1(¶ms_v2_le, ¶ms_le);
1218 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1219 ¶ms_le,
1220 sizeof(params_le));
1221 }
1222
1223 if (err)
1224 bphy_err(drvr, "Scan abort failed\n");
1225 }
1226
1227 brcmf_scan_config_mpc(ifp, 1);
1228
1229 /*
1230 * e-scan can be initiated internally
1231 * which takes precedence.
1232 */
1233 if (cfg->int_escan_map) {
1234 brcmf_dbg(SCAN, "scheduled scan completed (%x)\n",
1235 cfg->int_escan_map);
1236 while (cfg->int_escan_map) {
1237 bucket = __ffs(cfg->int_escan_map);
1238 cfg->int_escan_map &= ~BIT(bucket);
1239 reqid = brcmf_pno_find_reqid_by_bucket(cfg->pno,
1240 bucket);
1241 if (!aborted) {
1242 brcmf_dbg(SCAN, "report results: reqid=%llu\n",
1243 reqid);
1244 cfg80211_sched_scan_results(cfg_to_wiphy(cfg),
1245 reqid);
1246 }
1247 }
1248 } else if (scan_request) {
1249 struct cfg80211_scan_info info = {
1250 .aborted = aborted,
1251 };
1252
1253 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
1254 aborted ? "Aborted" : "Done");
1255 cfg80211_scan_done(scan_request, &info);
1256 }
1257 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
1258 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
1259
1260 return err;
1261 }
1262
brcmf_cfg80211_del_apsta_iface(struct wiphy * wiphy,struct wireless_dev * wdev)1263 static int brcmf_cfg80211_del_apsta_iface(struct wiphy *wiphy,
1264 struct wireless_dev *wdev)
1265 {
1266 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1267 struct net_device *ndev = wdev->netdev;
1268 struct brcmf_if *ifp = netdev_priv(ndev);
1269 struct brcmf_pub *drvr = cfg->pub;
1270 int ret;
1271 int err;
1272
1273 brcmf_cfg80211_arm_vif_event(cfg, ifp->vif);
1274
1275 err = brcmf_fil_bsscfg_data_set(ifp, "interface_remove", NULL, 0);
1276 if (err) {
1277 bphy_err(drvr, "interface_remove failed %d\n", err);
1278 goto err_unarm;
1279 }
1280
1281 /* wait for firmware event */
1282 ret = brcmf_cfg80211_wait_vif_event(cfg, BRCMF_E_IF_DEL,
1283 BRCMF_VIF_EVENT_TIMEOUT);
1284 if (!ret) {
1285 bphy_err(drvr, "timeout occurred\n");
1286 err = -EIO;
1287 goto err_unarm;
1288 }
1289
1290 brcmf_remove_interface(ifp, true);
1291
1292 err_unarm:
1293 brcmf_cfg80211_arm_vif_event(cfg, NULL);
1294 return err;
1295 }
1296
1297 static
brcmf_cfg80211_del_iface(struct wiphy * wiphy,struct wireless_dev * wdev)1298 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
1299 {
1300 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1301 struct net_device *ndev = wdev->netdev;
1302
1303 if (ndev && ndev == cfg_to_ndev(cfg))
1304 return -ENOTSUPP;
1305
1306 /* vif event pending in firmware */
1307 if (brcmf_cfg80211_vif_event_armed(cfg))
1308 return -EBUSY;
1309
1310 if (ndev) {
1311 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
1312 cfg->escan_info.ifp == netdev_priv(ndev))
1313 brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
1314 true, true);
1315
1316 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
1317 }
1318
1319 switch (wdev->iftype) {
1320 case NL80211_IFTYPE_ADHOC:
1321 case NL80211_IFTYPE_AP_VLAN:
1322 case NL80211_IFTYPE_WDS:
1323 case NL80211_IFTYPE_MESH_POINT:
1324 return -EOPNOTSUPP;
1325 case NL80211_IFTYPE_MONITOR:
1326 return brcmf_mon_del_vif(wiphy, wdev);
1327 case NL80211_IFTYPE_STATION:
1328 case NL80211_IFTYPE_AP:
1329 return brcmf_cfg80211_del_apsta_iface(wiphy, wdev);
1330 case NL80211_IFTYPE_P2P_CLIENT:
1331 case NL80211_IFTYPE_P2P_GO:
1332 case NL80211_IFTYPE_P2P_DEVICE:
1333 return brcmf_p2p_del_vif(wiphy, wdev);
1334 case NL80211_IFTYPE_UNSPECIFIED:
1335 default:
1336 return -EINVAL;
1337 }
1338 return -EOPNOTSUPP;
1339 }
1340
1341 static s32
brcmf_cfg80211_change_iface(struct wiphy * wiphy,struct net_device * ndev,enum nl80211_iftype type,struct vif_params * params)1342 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1343 enum nl80211_iftype type,
1344 struct vif_params *params)
1345 {
1346 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1347 struct brcmf_if *ifp = netdev_priv(ndev);
1348 struct brcmf_cfg80211_vif *vif = ifp->vif;
1349 struct brcmf_pub *drvr = cfg->pub;
1350 s32 infra = 0;
1351 s32 ap = 0;
1352 s32 err = 0;
1353
1354 brcmf_dbg(TRACE, "Enter, bsscfgidx=%d, type=%d\n", ifp->bsscfgidx,
1355 type);
1356
1357 /* WAR: There are a number of p2p interface related problems which
1358 * need to be handled initially (before doing the validate).
1359 * wpa_supplicant tends to do iface changes on p2p device/client/go
1360 * which are not always possible/allowed. However we need to return
1361 * OK otherwise the wpa_supplicant wont start. The situation differs
1362 * on configuration and setup (p2pon=1 module param). The first check
1363 * is to see if the request is a change to station for p2p iface.
1364 */
1365 if ((type == NL80211_IFTYPE_STATION) &&
1366 ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
1367 (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) ||
1368 (vif->wdev.iftype == NL80211_IFTYPE_P2P_DEVICE))) {
1369 brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
1370 /* Now depending on whether module param p2pon=1 was used the
1371 * response needs to be either 0 or EOPNOTSUPP. The reason is
1372 * that if p2pon=1 is used, but a newer supplicant is used then
1373 * we should return an error, as this combination wont work.
1374 * In other situations 0 is returned and supplicant will start
1375 * normally. It will give a trace in cfg80211, but it is the
1376 * only way to get it working. Unfortunately this will result
1377 * in situation where we wont support new supplicant in
1378 * combination with module param p2pon=1, but that is the way
1379 * it is. If the user tries this then unloading of driver might
1380 * fail/lock.
1381 */
1382 if (cfg->p2p.p2pdev_dynamically)
1383 return -EOPNOTSUPP;
1384 else
1385 return 0;
1386 }
1387 err = brcmf_vif_change_validate(wiphy_to_cfg(wiphy), vif, type);
1388 if (err) {
1389 bphy_err(drvr, "iface validation failed: err=%d\n", err);
1390 return err;
1391 }
1392 switch (type) {
1393 case NL80211_IFTYPE_MONITOR:
1394 case NL80211_IFTYPE_WDS:
1395 bphy_err(drvr, "type (%d) : currently we do not support this type\n",
1396 type);
1397 return -EOPNOTSUPP;
1398 case NL80211_IFTYPE_ADHOC:
1399 infra = 0;
1400 break;
1401 case NL80211_IFTYPE_STATION:
1402 infra = 1;
1403 break;
1404 case NL80211_IFTYPE_AP:
1405 case NL80211_IFTYPE_P2P_GO:
1406 ap = 1;
1407 break;
1408 default:
1409 err = -EINVAL;
1410 goto done;
1411 }
1412
1413 if (ap) {
1414 if (type == NL80211_IFTYPE_P2P_GO) {
1415 brcmf_dbg(INFO, "IF Type = P2P GO\n");
1416 err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
1417 }
1418 if (!err) {
1419 brcmf_dbg(INFO, "IF Type = AP\n");
1420 }
1421 } else {
1422 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
1423 if (err) {
1424 bphy_err(drvr, "WLC_SET_INFRA error (%d)\n", err);
1425 err = -EAGAIN;
1426 goto done;
1427 }
1428 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
1429 "Adhoc" : "Infra");
1430 }
1431 ndev->ieee80211_ptr->iftype = type;
1432
1433 brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
1434
1435 done:
1436 brcmf_dbg(TRACE, "Exit\n");
1437
1438 return err;
1439 }
1440
1441 static s32
brcmf_run_escan(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,struct cfg80211_scan_request * request)1442 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
1443 struct cfg80211_scan_request *request)
1444 {
1445 struct brcmf_pub *drvr = cfg->pub;
1446 s32 params_size = BRCMF_SCAN_PARAMS_V2_FIXED_SIZE +
1447 offsetof(struct brcmf_escan_params_le, params_v2_le);
1448 struct brcmf_escan_params_le *params;
1449 s32 err = 0;
1450
1451 brcmf_dbg(SCAN, "E-SCAN START\n");
1452
1453 if (request != NULL) {
1454 /* Allocate space for populating ssids in struct */
1455 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
1456
1457 /* Allocate space for populating ssids in struct */
1458 params_size += sizeof(struct brcmf_ssid_le) * request->n_ssids;
1459 }
1460
1461 params = kzalloc(params_size, GFP_KERNEL);
1462 if (!params) {
1463 err = -ENOMEM;
1464 goto exit;
1465 }
1466 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
1467 brcmf_escan_prep(cfg, ¶ms->params_v2_le, request);
1468
1469 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION_V2);
1470
1471 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_V2)) {
1472 struct brcmf_escan_params_le *params_v1;
1473
1474 params_size -= BRCMF_SCAN_PARAMS_V2_FIXED_SIZE;
1475 params_size += BRCMF_SCAN_PARAMS_FIXED_SIZE;
1476 params_v1 = kzalloc(params_size, GFP_KERNEL);
1477 if (!params_v1) {
1478 err = -ENOMEM;
1479 goto exit_params;
1480 }
1481 params_v1->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
1482 brcmf_scan_params_v2_to_v1(¶ms->params_v2_le, ¶ms_v1->params_le);
1483 kfree(params);
1484 params = params_v1;
1485 }
1486
1487 params->action = cpu_to_le16(WL_ESCAN_ACTION_START);
1488 params->sync_id = cpu_to_le16(0x1234);
1489
1490 err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1491 if (err) {
1492 if (err == -EBUSY)
1493 brcmf_dbg(INFO, "system busy : escan canceled\n");
1494 else
1495 bphy_err(drvr, "error (%d)\n", err);
1496 }
1497
1498 exit_params:
1499 kfree(params);
1500 exit:
1501 return err;
1502 }
1503
1504 static s32
brcmf_do_escan(struct brcmf_if * ifp,struct cfg80211_scan_request * request)1505 brcmf_do_escan(struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1506 {
1507 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
1508 s32 err;
1509 struct brcmf_scan_results *results;
1510 struct escan_info *escan = &cfg->escan_info;
1511
1512 brcmf_dbg(SCAN, "Enter\n");
1513 escan->ifp = ifp;
1514 escan->wiphy = cfg->wiphy;
1515 escan->escan_state = WL_ESCAN_STATE_SCANNING;
1516
1517 brcmf_scan_config_mpc(ifp, 0);
1518 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1519 results->version = 0;
1520 results->count = 0;
1521 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1522
1523 err = escan->run(cfg, ifp, request);
1524 if (err)
1525 brcmf_scan_config_mpc(ifp, 1);
1526 return err;
1527 }
1528
1529 static s32
brcmf_cfg80211_scan(struct wiphy * wiphy,struct cfg80211_scan_request * request)1530 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1531 {
1532 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1533 struct brcmf_pub *drvr = cfg->pub;
1534 struct brcmf_cfg80211_vif *vif;
1535 s32 err = 0;
1536
1537 brcmf_dbg(TRACE, "Enter\n");
1538 vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1539 if (!check_vif_up(vif))
1540 return -EIO;
1541
1542 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1543 bphy_err(drvr, "Scanning already: status (%lu)\n",
1544 cfg->scan_status);
1545 return -EAGAIN;
1546 }
1547 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1548 bphy_err(drvr, "Scanning being aborted: status (%lu)\n",
1549 cfg->scan_status);
1550 return -EAGAIN;
1551 }
1552 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1553 bphy_err(drvr, "Scanning suppressed: status (%lu)\n",
1554 cfg->scan_status);
1555 return -EAGAIN;
1556 }
1557 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state)) {
1558 bphy_err(drvr, "Connecting: status (%lu)\n", vif->sme_state);
1559 return -EAGAIN;
1560 }
1561
1562 brcmf_dbg(SCAN, "START ESCAN\n");
1563
1564 cfg->scan_request = request;
1565 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1566
1567 cfg->escan_info.run = brcmf_run_escan;
1568 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1569 if (err)
1570 goto scan_out;
1571
1572 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG,
1573 request->ie, request->ie_len);
1574 if (err)
1575 goto scan_out;
1576
1577 /* If scan req comes for p2p0, send it over primary I/F */
1578 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1579 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1580
1581 err = brcmf_do_escan(vif->ifp, request);
1582 if (err)
1583 goto scan_out;
1584
1585 /* Arm scan timeout timer */
1586 mod_timer(&cfg->escan_timeout,
1587 jiffies + msecs_to_jiffies(BRCMF_ESCAN_TIMER_INTERVAL_MS));
1588
1589 return 0;
1590
1591 scan_out:
1592 bphy_err(drvr, "scan error (%d)\n", err);
1593 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1594 cfg->scan_request = NULL;
1595 return err;
1596 }
1597
brcmf_set_rts(struct net_device * ndev,u32 rts_threshold)1598 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1599 {
1600 struct brcmf_if *ifp = netdev_priv(ndev);
1601 struct brcmf_pub *drvr = ifp->drvr;
1602 s32 err = 0;
1603
1604 err = brcmf_fil_iovar_int_set(ifp, "rtsthresh", rts_threshold);
1605 if (err)
1606 bphy_err(drvr, "Error (%d)\n", err);
1607
1608 return err;
1609 }
1610
brcmf_set_frag(struct net_device * ndev,u32 frag_threshold)1611 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1612 {
1613 struct brcmf_if *ifp = netdev_priv(ndev);
1614 struct brcmf_pub *drvr = ifp->drvr;
1615 s32 err = 0;
1616
1617 err = brcmf_fil_iovar_int_set(ifp, "fragthresh",
1618 frag_threshold);
1619 if (err)
1620 bphy_err(drvr, "Error (%d)\n", err);
1621
1622 return err;
1623 }
1624
brcmf_set_retry(struct net_device * ndev,u32 retry,bool l)1625 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1626 {
1627 struct brcmf_if *ifp = netdev_priv(ndev);
1628 struct brcmf_pub *drvr = ifp->drvr;
1629 s32 err = 0;
1630 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1631
1632 err = brcmf_fil_cmd_int_set(ifp, cmd, retry);
1633 if (err) {
1634 bphy_err(drvr, "cmd (%d) , error (%d)\n", cmd, err);
1635 return err;
1636 }
1637 return err;
1638 }
1639
brcmf_cfg80211_set_wiphy_params(struct wiphy * wiphy,int radio_idx,u32 changed)1640 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, int radio_idx,
1641 u32 changed)
1642 {
1643 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1644 struct net_device *ndev = cfg_to_ndev(cfg);
1645 struct brcmf_if *ifp = netdev_priv(ndev);
1646 s32 err = 0;
1647
1648 brcmf_dbg(TRACE, "Enter\n");
1649 if (!check_vif_up(ifp->vif))
1650 return -EIO;
1651
1652 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1653 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1654 cfg->conf->rts_threshold = wiphy->rts_threshold;
1655 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1656 if (!err)
1657 goto done;
1658 }
1659 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1660 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1661 cfg->conf->frag_threshold = wiphy->frag_threshold;
1662 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1663 if (!err)
1664 goto done;
1665 }
1666 if (changed & WIPHY_PARAM_RETRY_LONG
1667 && (cfg->conf->retry_long != wiphy->retry_long)) {
1668 cfg->conf->retry_long = wiphy->retry_long;
1669 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1670 if (!err)
1671 goto done;
1672 }
1673 if (changed & WIPHY_PARAM_RETRY_SHORT
1674 && (cfg->conf->retry_short != wiphy->retry_short)) {
1675 cfg->conf->retry_short = wiphy->retry_short;
1676 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1677 if (!err)
1678 goto done;
1679 }
1680
1681 done:
1682 brcmf_dbg(TRACE, "Exit\n");
1683 return err;
1684 }
1685
brcmf_init_prof(struct brcmf_cfg80211_profile * prof)1686 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1687 {
1688 memset(prof, 0, sizeof(*prof));
1689 }
1690
brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg * e)1691 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1692 {
1693 u16 reason;
1694
1695 switch (e->event_code) {
1696 case BRCMF_E_DEAUTH:
1697 case BRCMF_E_DEAUTH_IND:
1698 case BRCMF_E_DISASSOC_IND:
1699 reason = e->reason;
1700 break;
1701 case BRCMF_E_LINK:
1702 default:
1703 reason = 0;
1704 break;
1705 }
1706 return reason;
1707 }
1708
brcmf_set_wsec(struct brcmf_if * ifp,const u8 * key,u16 key_len,u16 flags)1709 int brcmf_set_wsec(struct brcmf_if *ifp, const u8 *key, u16 key_len, u16 flags)
1710 {
1711 struct brcmf_pub *drvr = ifp->drvr;
1712 struct brcmf_wsec_pmk_le pmk;
1713 int err;
1714
1715 if (key_len > sizeof(pmk.key)) {
1716 bphy_err(drvr, "key must be less than %zu bytes\n",
1717 sizeof(pmk.key));
1718 return -EINVAL;
1719 }
1720
1721 memset(&pmk, 0, sizeof(pmk));
1722
1723 /* pass key material directly */
1724 pmk.key_len = cpu_to_le16(key_len);
1725 pmk.flags = cpu_to_le16(flags);
1726 memcpy(pmk.key, key, key_len);
1727
1728 /* store key material in firmware */
1729 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_WSEC_PMK,
1730 &pmk, sizeof(pmk));
1731 if (err < 0)
1732 bphy_err(drvr, "failed to change PSK in firmware (len=%u)\n",
1733 key_len);
1734
1735 return err;
1736 }
1737 BRCMF_EXPORT_SYMBOL_GPL(brcmf_set_wsec);
1738
brcmf_set_pmk(struct brcmf_if * ifp,const u8 * pmk_data,u16 pmk_len)1739 static int brcmf_set_pmk(struct brcmf_if *ifp, const u8 *pmk_data, u16 pmk_len)
1740 {
1741 return brcmf_set_wsec(ifp, pmk_data, pmk_len, 0);
1742 }
1743
brcmf_link_down(struct brcmf_cfg80211_vif * vif,u16 reason,bool locally_generated)1744 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason,
1745 bool locally_generated)
1746 {
1747 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1748 struct brcmf_pub *drvr = cfg->pub;
1749 bool bus_up = drvr->bus_if->state == BRCMF_BUS_UP;
1750 s32 err = 0;
1751
1752 brcmf_dbg(TRACE, "Enter\n");
1753
1754 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1755 if (bus_up) {
1756 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n");
1757 err = brcmf_fil_cmd_data_set(vif->ifp,
1758 BRCMF_C_DISASSOC, NULL, 0);
1759 if (err)
1760 bphy_err(drvr, "WLC_DISASSOC failed (%d)\n",
1761 err);
1762 }
1763
1764 if ((vif->wdev.iftype == NL80211_IFTYPE_STATION) ||
1765 (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT))
1766 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1767 locally_generated, GFP_KERNEL);
1768 }
1769 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1770 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
1771 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
1772 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1773 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1774 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
1775 if (bus_up)
1776 brcmf_set_pmk(vif->ifp, NULL, 0);
1777 vif->profile.use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
1778 }
1779 brcmf_dbg(TRACE, "Exit\n");
1780 }
1781
1782 static s32
brcmf_cfg80211_join_ibss(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ibss_params * params)1783 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1784 struct cfg80211_ibss_params *params)
1785 {
1786 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1787 struct brcmf_if *ifp = netdev_priv(ndev);
1788 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1789 struct brcmf_pub *drvr = cfg->pub;
1790 struct brcmf_join_params join_params;
1791 size_t join_params_size = 0;
1792 s32 err = 0;
1793 s32 wsec = 0;
1794 s32 bcnprd;
1795 u16 chanspec;
1796 u32 ssid_len;
1797
1798 brcmf_dbg(TRACE, "Enter\n");
1799 if (!check_vif_up(ifp->vif))
1800 return -EIO;
1801
1802 if (params->ssid)
1803 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1804 else {
1805 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1806 return -EOPNOTSUPP;
1807 }
1808
1809 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1810
1811 if (params->bssid)
1812 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1813 else
1814 brcmf_dbg(CONN, "No BSSID specified\n");
1815
1816 if (params->chandef.chan)
1817 brcmf_dbg(CONN, "channel: %d\n",
1818 params->chandef.chan->center_freq);
1819 else
1820 brcmf_dbg(CONN, "no channel specified\n");
1821
1822 if (params->channel_fixed)
1823 brcmf_dbg(CONN, "fixed channel required\n");
1824 else
1825 brcmf_dbg(CONN, "no fixed channel required\n");
1826
1827 if (params->ie && params->ie_len)
1828 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1829 else
1830 brcmf_dbg(CONN, "no ie specified\n");
1831
1832 if (params->beacon_interval)
1833 brcmf_dbg(CONN, "beacon interval: %d\n",
1834 params->beacon_interval);
1835 else
1836 brcmf_dbg(CONN, "no beacon interval specified\n");
1837
1838 if (params->basic_rates)
1839 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1840 else
1841 brcmf_dbg(CONN, "no basic rates specified\n");
1842
1843 if (params->privacy)
1844 brcmf_dbg(CONN, "privacy required\n");
1845 else
1846 brcmf_dbg(CONN, "no privacy required\n");
1847
1848 /* Configure Privacy for starter */
1849 if (params->privacy)
1850 wsec |= WEP_ENABLED;
1851
1852 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1853 if (err) {
1854 bphy_err(drvr, "wsec failed (%d)\n", err);
1855 goto done;
1856 }
1857
1858 /* Configure Beacon Interval for starter */
1859 if (params->beacon_interval)
1860 bcnprd = params->beacon_interval;
1861 else
1862 bcnprd = 100;
1863
1864 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1865 if (err) {
1866 bphy_err(drvr, "WLC_SET_BCNPRD failed (%d)\n", err);
1867 goto done;
1868 }
1869
1870 /* Configure required join parameter */
1871 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1872
1873 /* SSID */
1874 ssid_len = min_t(u32, params->ssid_len, IEEE80211_MAX_SSID_LEN);
1875 memcpy(join_params.ssid_le.SSID, params->ssid, ssid_len);
1876 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
1877 join_params_size = sizeof(join_params.ssid_le);
1878
1879 /* BSSID */
1880 if (params->bssid) {
1881 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1882 join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1883 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1884 } else {
1885 eth_broadcast_addr(join_params.params_le.bssid);
1886 eth_zero_addr(profile->bssid);
1887 }
1888
1889 /* Channel */
1890 if (params->chandef.chan) {
1891 u32 target_channel;
1892
1893 cfg->channel =
1894 ieee80211_frequency_to_channel(
1895 params->chandef.chan->center_freq);
1896 if (params->channel_fixed) {
1897 /* adding chanspec */
1898 chanspec = chandef_to_chanspec(&cfg->d11inf,
1899 ¶ms->chandef);
1900 join_params.params_le.chanspec_list[0] =
1901 cpu_to_le16(chanspec);
1902 join_params.params_le.chanspec_num = cpu_to_le32(1);
1903 join_params_size += sizeof(join_params.params_le);
1904 }
1905
1906 /* set channel for starter */
1907 target_channel = cfg->channel;
1908 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1909 target_channel);
1910 if (err) {
1911 bphy_err(drvr, "WLC_SET_CHANNEL failed (%d)\n", err);
1912 goto done;
1913 }
1914 } else
1915 cfg->channel = 0;
1916
1917 cfg->ibss_starter = false;
1918
1919
1920 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1921 &join_params, join_params_size);
1922 if (err) {
1923 bphy_err(drvr, "WLC_SET_SSID failed (%d)\n", err);
1924 goto done;
1925 }
1926
1927 done:
1928 if (err)
1929 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1930 brcmf_dbg(TRACE, "Exit\n");
1931 return err;
1932 }
1933
1934 static s32
brcmf_cfg80211_leave_ibss(struct wiphy * wiphy,struct net_device * ndev)1935 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1936 {
1937 struct brcmf_if *ifp = netdev_priv(ndev);
1938
1939 brcmf_dbg(TRACE, "Enter\n");
1940 if (!check_vif_up(ifp->vif)) {
1941 /* When driver is being unloaded, it can end up here. If an
1942 * error is returned then later on a debug trace in the wireless
1943 * core module will be printed. To avoid this 0 is returned.
1944 */
1945 return 0;
1946 }
1947
1948 brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING, true);
1949 brcmf_net_setcarrier(ifp, false);
1950
1951 brcmf_dbg(TRACE, "Exit\n");
1952
1953 return 0;
1954 }
1955
brcmf_set_wpa_version(struct net_device * ndev,struct cfg80211_connect_params * sme)1956 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1957 struct cfg80211_connect_params *sme)
1958 {
1959 struct brcmf_if *ifp = netdev_priv(ndev);
1960 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1961 struct brcmf_pub *drvr = ifp->drvr;
1962 struct brcmf_cfg80211_security *sec;
1963 s32 val;
1964 s32 err;
1965
1966 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1) {
1967 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1968 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2) {
1969 if (drvr->bus_if->fwvid == BRCMF_FWVENDOR_CYW &&
1970 sme->crypto.akm_suites[0] == WLAN_AKM_SUITE_SAE)
1971 val = WPA3_AUTH_SAE_PSK;
1972 else
1973 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1974 } else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_3) {
1975 val = WPA3_AUTH_SAE_PSK;
1976 } else {
1977 val = WPA_AUTH_DISABLED;
1978 }
1979 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1980 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", val);
1981 if (err) {
1982 bphy_err(drvr, "set wpa_auth failed (%d)\n", err);
1983 return err;
1984 }
1985 sec = &profile->sec;
1986 sec->wpa_versions = sme->crypto.wpa_versions;
1987 return err;
1988 }
1989
brcmf_set_auth_type(struct net_device * ndev,struct cfg80211_connect_params * sme)1990 static s32 brcmf_set_auth_type(struct net_device *ndev,
1991 struct cfg80211_connect_params *sme)
1992 {
1993 struct brcmf_if *ifp = netdev_priv(ndev);
1994 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1995 struct brcmf_pub *drvr = ifp->drvr;
1996 struct brcmf_cfg80211_security *sec;
1997 s32 val = 0;
1998 s32 err = 0;
1999
2000 switch (sme->auth_type) {
2001 case NL80211_AUTHTYPE_OPEN_SYSTEM:
2002 val = 0;
2003 brcmf_dbg(CONN, "open system\n");
2004 break;
2005 case NL80211_AUTHTYPE_SHARED_KEY:
2006 val = 1;
2007 brcmf_dbg(CONN, "shared key\n");
2008 break;
2009 case NL80211_AUTHTYPE_SAE:
2010 val = 3;
2011 brcmf_dbg(CONN, "SAE authentication\n");
2012 break;
2013 default:
2014 val = 2;
2015 brcmf_dbg(CONN, "automatic, auth type (%d)\n", sme->auth_type);
2016 break;
2017 }
2018
2019 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
2020 if (err) {
2021 bphy_err(drvr, "set auth failed (%d)\n", err);
2022 return err;
2023 }
2024 sec = &profile->sec;
2025 sec->auth_type = sme->auth_type;
2026 return err;
2027 }
2028
2029 static s32
brcmf_set_wsec_mode(struct net_device * ndev,struct cfg80211_connect_params * sme)2030 brcmf_set_wsec_mode(struct net_device *ndev,
2031 struct cfg80211_connect_params *sme)
2032 {
2033 struct brcmf_if *ifp = netdev_priv(ndev);
2034 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2035 struct brcmf_pub *drvr = ifp->drvr;
2036 struct brcmf_cfg80211_security *sec;
2037 s32 pval = 0;
2038 s32 gval = 0;
2039 s32 wsec;
2040 s32 err = 0;
2041
2042 if (sme->crypto.n_ciphers_pairwise) {
2043 switch (sme->crypto.ciphers_pairwise[0]) {
2044 case WLAN_CIPHER_SUITE_WEP40:
2045 case WLAN_CIPHER_SUITE_WEP104:
2046 pval = WEP_ENABLED;
2047 break;
2048 case WLAN_CIPHER_SUITE_TKIP:
2049 pval = TKIP_ENABLED;
2050 break;
2051 case WLAN_CIPHER_SUITE_CCMP:
2052 pval = AES_ENABLED;
2053 break;
2054 case WLAN_CIPHER_SUITE_AES_CMAC:
2055 pval = AES_ENABLED;
2056 break;
2057 default:
2058 bphy_err(drvr, "invalid cipher pairwise (%d)\n",
2059 sme->crypto.ciphers_pairwise[0]);
2060 return -EINVAL;
2061 }
2062 }
2063 if (sme->crypto.cipher_group) {
2064 switch (sme->crypto.cipher_group) {
2065 case WLAN_CIPHER_SUITE_WEP40:
2066 case WLAN_CIPHER_SUITE_WEP104:
2067 gval = WEP_ENABLED;
2068 break;
2069 case WLAN_CIPHER_SUITE_TKIP:
2070 gval = TKIP_ENABLED;
2071 break;
2072 case WLAN_CIPHER_SUITE_CCMP:
2073 gval = AES_ENABLED;
2074 break;
2075 case WLAN_CIPHER_SUITE_AES_CMAC:
2076 gval = AES_ENABLED;
2077 break;
2078 default:
2079 bphy_err(drvr, "invalid cipher group (%d)\n",
2080 sme->crypto.cipher_group);
2081 return -EINVAL;
2082 }
2083 }
2084
2085 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
2086 /* In case of privacy, but no security and WPS then simulate */
2087 /* setting AES. WPS-2.0 allows no security */
2088 if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
2089 sme->privacy)
2090 pval = AES_ENABLED;
2091
2092 wsec = pval | gval;
2093 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2094 if (err) {
2095 bphy_err(drvr, "error (%d)\n", err);
2096 return err;
2097 }
2098
2099 sec = &profile->sec;
2100 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
2101 sec->cipher_group = sme->crypto.cipher_group;
2102
2103 return err;
2104 }
2105
2106 static s32
brcmf_set_key_mgmt(struct net_device * ndev,struct cfg80211_connect_params * sme)2107 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
2108 {
2109 struct brcmf_if *ifp = netdev_priv(ndev);
2110 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2111 struct brcmf_pub *drvr = ifp->drvr;
2112 s32 val;
2113 s32 err;
2114 const struct brcmf_tlv *rsn_ie;
2115 const u8 *ie;
2116 u32 ie_len;
2117 u32 offset;
2118 u16 rsn_cap;
2119 u32 mfp;
2120 u16 count;
2121
2122 profile->use_fwsup = BRCMF_PROFILE_FWSUP_NONE;
2123 profile->is_ft = false;
2124
2125 if (!sme->crypto.n_akm_suites)
2126 return 0;
2127
2128 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
2129 "wpa_auth", &val);
2130 if (err) {
2131 bphy_err(drvr, "could not get wpa_auth (%d)\n", err);
2132 return err;
2133 }
2134 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
2135 switch (sme->crypto.akm_suites[0]) {
2136 case WLAN_AKM_SUITE_8021X:
2137 val = WPA_AUTH_UNSPECIFIED;
2138 if (sme->want_1x)
2139 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2140 break;
2141 case WLAN_AKM_SUITE_PSK:
2142 val = WPA_AUTH_PSK;
2143 break;
2144 default:
2145 bphy_err(drvr, "invalid akm suite (%d)\n",
2146 sme->crypto.akm_suites[0]);
2147 return -EINVAL;
2148 }
2149 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
2150 switch (sme->crypto.akm_suites[0]) {
2151 case WLAN_AKM_SUITE_8021X:
2152 val = WPA2_AUTH_UNSPECIFIED;
2153 if (sme->want_1x)
2154 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2155 break;
2156 case WLAN_AKM_SUITE_8021X_SHA256:
2157 val = WPA2_AUTH_1X_SHA256;
2158 if (sme->want_1x)
2159 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2160 break;
2161 case WLAN_AKM_SUITE_PSK_SHA256:
2162 val = WPA2_AUTH_PSK_SHA256;
2163 break;
2164 case WLAN_AKM_SUITE_PSK:
2165 val = WPA2_AUTH_PSK;
2166 break;
2167 case WLAN_AKM_SUITE_FT_8021X:
2168 val = WPA2_AUTH_UNSPECIFIED | WPA2_AUTH_FT;
2169 profile->is_ft = true;
2170 if (sme->want_1x)
2171 profile->use_fwsup = BRCMF_PROFILE_FWSUP_1X;
2172 break;
2173 case WLAN_AKM_SUITE_FT_PSK:
2174 val = WPA2_AUTH_PSK | WPA2_AUTH_FT;
2175 profile->is_ft = true;
2176 break;
2177 default:
2178 bphy_err(drvr, "invalid akm suite (%d)\n",
2179 sme->crypto.akm_suites[0]);
2180 return -EINVAL;
2181 }
2182 } else if (val & WPA3_AUTH_SAE_PSK) {
2183 switch (sme->crypto.akm_suites[0]) {
2184 case WLAN_AKM_SUITE_SAE:
2185 val = WPA3_AUTH_SAE_PSK;
2186 break;
2187 case WLAN_AKM_SUITE_FT_OVER_SAE:
2188 val = WPA3_AUTH_SAE_PSK | WPA2_AUTH_FT;
2189 profile->is_ft = true;
2190 break;
2191 default:
2192 bphy_err(drvr, "invalid akm suite (%d)\n",
2193 sme->crypto.akm_suites[0]);
2194 return -EINVAL;
2195 }
2196 if (sme->crypto.sae_pwd) {
2197 profile->use_fwsup = BRCMF_PROFILE_FWSUP_SAE;
2198 }
2199 }
2200
2201 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X)
2202 brcmf_dbg(INFO, "using 1X offload\n");
2203 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE)
2204 brcmf_dbg(INFO, "using SAE offload\n");
2205
2206 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2207 goto skip_mfp_config;
2208 /* The MFP mode (1 or 2) needs to be determined, parse IEs. The
2209 * IE will not be verified, just a quick search for MFP config
2210 */
2211 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie, sme->ie_len,
2212 WLAN_EID_RSN);
2213 if (!rsn_ie)
2214 goto skip_mfp_config;
2215 ie = (const u8 *)rsn_ie;
2216 ie_len = rsn_ie->len + TLV_HDR_LEN;
2217 /* Skip unicast suite */
2218 offset = TLV_HDR_LEN + WPA_IE_VERSION_LEN + WPA_IE_MIN_OUI_LEN;
2219 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
2220 goto skip_mfp_config;
2221 /* Skip multicast suite */
2222 count = ie[offset] + (ie[offset + 1] << 8);
2223 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
2224 if (offset + WPA_IE_SUITE_COUNT_LEN >= ie_len)
2225 goto skip_mfp_config;
2226 /* Skip auth key management suite(s) */
2227 count = ie[offset] + (ie[offset + 1] << 8);
2228 offset += WPA_IE_SUITE_COUNT_LEN + (count * WPA_IE_MIN_OUI_LEN);
2229 if (offset + WPA_IE_SUITE_COUNT_LEN > ie_len)
2230 goto skip_mfp_config;
2231 /* Ready to read capabilities */
2232 mfp = BRCMF_MFP_NONE;
2233 rsn_cap = ie[offset] + (ie[offset + 1] << 8);
2234 if (rsn_cap & RSN_CAP_MFPR_MASK)
2235 mfp = BRCMF_MFP_REQUIRED;
2236 else if (rsn_cap & RSN_CAP_MFPC_MASK)
2237 mfp = BRCMF_MFP_CAPABLE;
2238 brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "mfp", mfp);
2239
2240 skip_mfp_config:
2241 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
2242 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
2243 if (err) {
2244 bphy_err(drvr, "could not set wpa_auth (%d)\n", err);
2245 return err;
2246 }
2247
2248 return err;
2249 }
2250
2251 static s32
brcmf_set_sharedkey(struct net_device * ndev,struct cfg80211_connect_params * sme)2252 brcmf_set_sharedkey(struct net_device *ndev,
2253 struct cfg80211_connect_params *sme)
2254 {
2255 struct brcmf_if *ifp = netdev_priv(ndev);
2256 struct brcmf_pub *drvr = ifp->drvr;
2257 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2258 struct brcmf_cfg80211_security *sec;
2259 struct brcmf_wsec_key key;
2260 s32 val;
2261 s32 err = 0;
2262
2263 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
2264
2265 if (sme->key_len == 0)
2266 return 0;
2267
2268 sec = &profile->sec;
2269 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
2270 sec->wpa_versions, sec->cipher_pairwise);
2271
2272 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2 |
2273 NL80211_WPA_VERSION_3))
2274 return 0;
2275
2276 if (!(sec->cipher_pairwise &
2277 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
2278 return 0;
2279
2280 memset(&key, 0, sizeof(key));
2281 key.len = (u32) sme->key_len;
2282 key.index = (u32) sme->key_idx;
2283 if (key.len > sizeof(key.data)) {
2284 bphy_err(drvr, "Too long key length (%u)\n", key.len);
2285 return -EINVAL;
2286 }
2287 memcpy(key.data, sme->key, key.len);
2288 key.flags = BRCMF_PRIMARY_KEY;
2289 switch (sec->cipher_pairwise) {
2290 case WLAN_CIPHER_SUITE_WEP40:
2291 key.algo = CRYPTO_ALGO_WEP1;
2292 break;
2293 case WLAN_CIPHER_SUITE_WEP104:
2294 key.algo = CRYPTO_ALGO_WEP128;
2295 break;
2296 default:
2297 bphy_err(drvr, "Invalid algorithm (%d)\n",
2298 sme->crypto.ciphers_pairwise[0]);
2299 return -EINVAL;
2300 }
2301 /* Set the new key/index */
2302 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
2303 key.len, key.index, key.algo);
2304 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
2305 err = send_key_to_dongle(ifp, &key);
2306 if (err)
2307 return err;
2308
2309 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
2310 brcmf_dbg(CONN, "set auth_type to shared key\n");
2311 val = WL_AUTH_SHARED_KEY; /* shared key */
2312 err = brcmf_fil_bsscfg_int_set(ifp, "auth", val);
2313 if (err)
2314 bphy_err(drvr, "set auth failed (%d)\n", err);
2315 }
2316 return err;
2317 }
2318
2319 static
brcmf_war_auth_type(struct brcmf_if * ifp,enum nl80211_auth_type type)2320 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
2321 enum nl80211_auth_type type)
2322 {
2323 if (type == NL80211_AUTHTYPE_AUTOMATIC &&
2324 brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
2325 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
2326 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
2327 }
2328 return type;
2329 }
2330
brcmf_set_join_pref(struct brcmf_if * ifp,struct cfg80211_bss_selection * bss_select)2331 static void brcmf_set_join_pref(struct brcmf_if *ifp,
2332 struct cfg80211_bss_selection *bss_select)
2333 {
2334 struct brcmf_pub *drvr = ifp->drvr;
2335 struct brcmf_join_pref_params join_pref_params[2];
2336 enum nl80211_band band;
2337 int err, i = 0;
2338
2339 join_pref_params[i].len = 2;
2340 join_pref_params[i].rssi_gain = 0;
2341
2342 if (bss_select->behaviour != NL80211_BSS_SELECT_ATTR_BAND_PREF)
2343 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_ASSOC_PREFER, WLC_BAND_AUTO);
2344
2345 switch (bss_select->behaviour) {
2346 case __NL80211_BSS_SELECT_ATTR_INVALID:
2347 brcmf_c_set_joinpref_default(ifp);
2348 return;
2349 case NL80211_BSS_SELECT_ATTR_BAND_PREF:
2350 join_pref_params[i].type = BRCMF_JOIN_PREF_BAND;
2351 band = bss_select->param.band_pref;
2352 join_pref_params[i].band = nl80211_band_to_fwil(band);
2353 i++;
2354 break;
2355 case NL80211_BSS_SELECT_ATTR_RSSI_ADJUST:
2356 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI_DELTA;
2357 band = bss_select->param.adjust.band;
2358 join_pref_params[i].band = nl80211_band_to_fwil(band);
2359 join_pref_params[i].rssi_gain = bss_select->param.adjust.delta;
2360 i++;
2361 break;
2362 case NL80211_BSS_SELECT_ATTR_RSSI:
2363 default:
2364 break;
2365 }
2366 join_pref_params[i].type = BRCMF_JOIN_PREF_RSSI;
2367 join_pref_params[i].len = 2;
2368 join_pref_params[i].rssi_gain = 0;
2369 join_pref_params[i].band = 0;
2370 err = brcmf_fil_iovar_data_set(ifp, "join_pref", join_pref_params,
2371 sizeof(join_pref_params));
2372 if (err)
2373 bphy_err(drvr, "Set join_pref error (%d)\n", err);
2374 }
2375
2376 static s32
brcmf_cfg80211_connect(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * sme)2377 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
2378 struct cfg80211_connect_params *sme)
2379 {
2380 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2381 struct brcmf_if *ifp = netdev_priv(ndev);
2382 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2383 struct ieee80211_channel *chan = sme->channel;
2384 struct brcmf_pub *drvr = ifp->drvr;
2385 struct brcmf_join_params join_params;
2386 size_t join_params_size;
2387 const struct brcmf_tlv *rsn_ie;
2388 const struct brcmf_vs_tlv *wpa_ie;
2389 const void *ie;
2390 u32 ie_len;
2391 struct brcmf_ext_join_params_le *ext_join_params;
2392 u16 chanspec;
2393 s32 err = 0;
2394 u32 ssid_len;
2395
2396 brcmf_dbg(TRACE, "Enter\n");
2397 if (!check_vif_up(ifp->vif))
2398 return -EIO;
2399
2400 if (!sme->ssid) {
2401 bphy_err(drvr, "Invalid ssid\n");
2402 return -EOPNOTSUPP;
2403 }
2404
2405 if (sme->channel_hint)
2406 chan = sme->channel_hint;
2407
2408 if (sme->bssid_hint)
2409 sme->bssid = sme->bssid_hint;
2410
2411 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
2412 /* A normal (non P2P) connection request setup. */
2413 ie = NULL;
2414 ie_len = 0;
2415 /* find the WPA_IE */
2416 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
2417 if (wpa_ie) {
2418 ie = wpa_ie;
2419 ie_len = wpa_ie->len + TLV_HDR_LEN;
2420 } else {
2421 /* find the RSN_IE */
2422 rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
2423 sme->ie_len,
2424 WLAN_EID_RSN);
2425 if (rsn_ie) {
2426 ie = rsn_ie;
2427 ie_len = rsn_ie->len + TLV_HDR_LEN;
2428 }
2429 }
2430 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
2431 }
2432
2433 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
2434 sme->ie, sme->ie_len);
2435 if (err)
2436 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
2437 else
2438 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
2439
2440 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2441
2442 if (chan) {
2443 cfg->channel =
2444 ieee80211_frequency_to_channel(chan->center_freq);
2445 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
2446 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
2447 cfg->channel, chan->center_freq, chanspec);
2448 } else {
2449 cfg->channel = 0;
2450 chanspec = 0;
2451 }
2452
2453 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
2454
2455 err = brcmf_set_wpa_version(ndev, sme);
2456 if (err) {
2457 bphy_err(drvr, "wl_set_wpa_version failed (%d)\n", err);
2458 goto done;
2459 }
2460
2461 sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
2462 err = brcmf_set_auth_type(ndev, sme);
2463 if (err) {
2464 bphy_err(drvr, "wl_set_auth_type failed (%d)\n", err);
2465 goto done;
2466 }
2467
2468 err = brcmf_set_wsec_mode(ndev, sme);
2469 if (err) {
2470 bphy_err(drvr, "wl_set_set_cipher failed (%d)\n", err);
2471 goto done;
2472 }
2473
2474 err = brcmf_set_key_mgmt(ndev, sme);
2475 if (err) {
2476 bphy_err(drvr, "wl_set_key_mgmt failed (%d)\n", err);
2477 goto done;
2478 }
2479
2480 err = brcmf_set_sharedkey(ndev, sme);
2481 if (err) {
2482 bphy_err(drvr, "brcmf_set_sharedkey failed (%d)\n", err);
2483 goto done;
2484 }
2485
2486 if (sme->crypto.psk &&
2487 profile->use_fwsup != BRCMF_PROFILE_FWSUP_SAE) {
2488 if (WARN_ON(profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE)) {
2489 err = -EINVAL;
2490 goto done;
2491 }
2492 brcmf_dbg(INFO, "using PSK offload\n");
2493 profile->use_fwsup = BRCMF_PROFILE_FWSUP_PSK;
2494 }
2495
2496 if (profile->use_fwsup != BRCMF_PROFILE_FWSUP_NONE) {
2497 /* enable firmware supplicant for this interface */
2498 err = brcmf_fil_iovar_int_set(ifp, "sup_wpa", 1);
2499 if (err < 0) {
2500 bphy_err(drvr, "failed to enable fw supplicant\n");
2501 goto done;
2502 }
2503 }
2504
2505 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_PSK)
2506 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2507 BRCMF_WSEC_MAX_PSK_LEN);
2508 else if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_SAE) {
2509 /* clean up user-space RSNE */
2510 err = brcmf_fil_iovar_data_set(ifp, "wpaie", NULL, 0);
2511 if (err) {
2512 bphy_err(drvr, "failed to clean up user-space RSNE\n");
2513 goto done;
2514 }
2515 err = brcmf_fwvid_set_sae_password(ifp, &sme->crypto);
2516 if (!err && sme->crypto.psk)
2517 err = brcmf_set_pmk(ifp, sme->crypto.psk,
2518 BRCMF_WSEC_MAX_PSK_LEN);
2519 }
2520 if (err)
2521 goto done;
2522
2523 /* Join with specific BSSID and cached SSID
2524 * If SSID is zero join based on BSSID only
2525 */
2526 join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
2527 offsetof(struct brcmf_assoc_params_le, chanspec_list);
2528 if (cfg->channel)
2529 join_params_size += sizeof(u16);
2530 ext_join_params = kzalloc(sizeof(*ext_join_params), GFP_KERNEL);
2531 if (ext_join_params == NULL) {
2532 err = -ENOMEM;
2533 goto done;
2534 }
2535 ssid_len = min_t(u32, sme->ssid_len, IEEE80211_MAX_SSID_LEN);
2536 ext_join_params->ssid_le.SSID_len = cpu_to_le32(ssid_len);
2537 memcpy(&ext_join_params->ssid_le.SSID, sme->ssid, ssid_len);
2538 if (ssid_len < IEEE80211_MAX_SSID_LEN)
2539 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n",
2540 ext_join_params->ssid_le.SSID, ssid_len);
2541
2542 /* Set up join scan parameters */
2543 ext_join_params->scan_le.scan_type = -1;
2544 ext_join_params->scan_le.home_time = cpu_to_le32(-1);
2545
2546 if (sme->bssid)
2547 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
2548 else
2549 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
2550
2551 if (cfg->channel) {
2552 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
2553
2554 ext_join_params->assoc_le.chanspec_list[0] =
2555 cpu_to_le16(chanspec);
2556 /* Increase dwell time to receive probe response or detect
2557 * beacon from target AP at a noisy air only during connect
2558 * command.
2559 */
2560 ext_join_params->scan_le.active_time =
2561 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
2562 ext_join_params->scan_le.passive_time =
2563 cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
2564 /* To sync with presence period of VSDB GO send probe request
2565 * more frequently. Probe request will be stopped when it gets
2566 * probe response from target AP/GO.
2567 */
2568 ext_join_params->scan_le.nprobes =
2569 cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
2570 BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
2571 } else {
2572 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
2573 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
2574 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
2575 }
2576
2577 brcmf_set_join_pref(ifp, &sme->bss_select);
2578
2579 err = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
2580 join_params_size);
2581 kfree(ext_join_params);
2582 if (!err)
2583 /* This is it. join command worked, we are done */
2584 goto done;
2585
2586 /* join command failed, fallback to set ssid */
2587 memset(&join_params, 0, sizeof(join_params));
2588 join_params_size = sizeof(join_params.ssid_le);
2589
2590 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid_len);
2591 join_params.ssid_le.SSID_len = cpu_to_le32(ssid_len);
2592
2593 if (sme->bssid)
2594 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
2595 else
2596 eth_broadcast_addr(join_params.params_le.bssid);
2597
2598 if (cfg->channel) {
2599 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
2600 join_params.params_le.chanspec_num = cpu_to_le32(1);
2601 join_params_size += sizeof(join_params.params_le);
2602 }
2603 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
2604 &join_params, join_params_size);
2605 if (err)
2606 bphy_err(drvr, "BRCMF_C_SET_SSID failed (%d)\n", err);
2607
2608 done:
2609 if (err)
2610 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2611 brcmf_dbg(TRACE, "Exit\n");
2612 return err;
2613 }
2614
2615 static s32
brcmf_cfg80211_disconnect(struct wiphy * wiphy,struct net_device * ndev,u16 reason_code)2616 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
2617 u16 reason_code)
2618 {
2619 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2620 struct brcmf_if *ifp = netdev_priv(ndev);
2621 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2622 struct brcmf_pub *drvr = cfg->pub;
2623 struct brcmf_scb_val_le scbval;
2624 s32 err = 0;
2625
2626 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
2627 if (!check_vif_up(ifp->vif))
2628 return -EIO;
2629
2630 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
2631 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
2632 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &ifp->vif->sme_state);
2633 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &ifp->vif->sme_state);
2634 cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
2635
2636 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
2637 scbval.val = cpu_to_le32(reason_code);
2638 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
2639 &scbval, sizeof(scbval));
2640 if (err)
2641 bphy_err(drvr, "error (%d)\n", err);
2642
2643 brcmf_dbg(TRACE, "Exit\n");
2644 return err;
2645 }
2646
2647 static s32
brcmf_cfg80211_set_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,int radio_idx,enum nl80211_tx_power_setting type,s32 mbm)2648 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2649 int radio_idx, enum nl80211_tx_power_setting type,
2650 s32 mbm)
2651 {
2652 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2653 struct net_device *ndev = cfg_to_ndev(cfg);
2654 struct brcmf_if *ifp = netdev_priv(ndev);
2655 struct brcmf_pub *drvr = cfg->pub;
2656 s32 err;
2657 s32 disable;
2658 u32 qdbm = 127;
2659
2660 brcmf_dbg(TRACE, "Enter %d %d\n", type, mbm);
2661 if (!check_vif_up(ifp->vif))
2662 return -EIO;
2663
2664 switch (type) {
2665 case NL80211_TX_POWER_AUTOMATIC:
2666 break;
2667 case NL80211_TX_POWER_LIMITED:
2668 case NL80211_TX_POWER_FIXED:
2669 if (mbm < 0) {
2670 bphy_err(drvr, "TX_POWER_FIXED - dbm is negative\n");
2671 err = -EINVAL;
2672 goto done;
2673 }
2674 qdbm = MBM_TO_DBM(4 * mbm);
2675 if (qdbm > 127)
2676 qdbm = 127;
2677 qdbm |= WL_TXPWR_OVERRIDE;
2678 break;
2679 default:
2680 bphy_err(drvr, "Unsupported type %d\n", type);
2681 err = -EINVAL;
2682 goto done;
2683 }
2684 /* Make sure radio is off or on as far as software is concerned */
2685 disable = WL_RADIO_SW_DISABLE << 16;
2686 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2687 if (err)
2688 bphy_err(drvr, "WLC_SET_RADIO error (%d)\n", err);
2689
2690 err = brcmf_fil_iovar_int_set(ifp, "qtxpower", qdbm);
2691 if (err)
2692 bphy_err(drvr, "qtxpower error (%d)\n", err);
2693
2694 done:
2695 brcmf_dbg(TRACE, "Exit %d (qdbm)\n", qdbm & ~WL_TXPWR_OVERRIDE);
2696 return err;
2697 }
2698
2699 static s32
brcmf_cfg80211_get_tx_power(struct wiphy * wiphy,struct wireless_dev * wdev,int radio_idx,unsigned int link_id,s32 * dbm)2700 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
2701 int radio_idx, unsigned int link_id, s32 *dbm)
2702 {
2703 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2704 struct brcmf_cfg80211_vif *vif = wdev_to_vif(wdev);
2705 struct brcmf_pub *drvr = cfg->pub;
2706 s32 qdbm;
2707 s32 err;
2708
2709 brcmf_dbg(TRACE, "Enter\n");
2710 if (!check_vif_up(vif))
2711 return -EIO;
2712
2713 err = brcmf_fil_iovar_int_get(vif->ifp, "qtxpower", &qdbm);
2714 if (err) {
2715 bphy_err(drvr, "error (%d)\n", err);
2716 goto done;
2717 }
2718 *dbm = (qdbm & ~WL_TXPWR_OVERRIDE) / 4;
2719
2720 done:
2721 brcmf_dbg(TRACE, "Exit (0x%x %d)\n", qdbm, *dbm);
2722 return err;
2723 }
2724
2725 static s32
brcmf_cfg80211_config_default_key(struct wiphy * wiphy,struct net_device * ndev,int link_id,u8 key_idx,bool unicast,bool multicast)2726 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2727 int link_id, u8 key_idx, bool unicast,
2728 bool multicast)
2729 {
2730 struct brcmf_if *ifp = netdev_priv(ndev);
2731 struct brcmf_pub *drvr = ifp->drvr;
2732 u32 index;
2733 u32 wsec;
2734 s32 err = 0;
2735
2736 brcmf_dbg(TRACE, "Enter\n");
2737 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2738 if (!check_vif_up(ifp->vif))
2739 return -EIO;
2740
2741 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2742 if (err) {
2743 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2744 goto done;
2745 }
2746
2747 if (wsec & WEP_ENABLED) {
2748 /* Just select a new current key */
2749 index = key_idx;
2750 err = brcmf_fil_cmd_int_set(ifp,
2751 BRCMF_C_SET_KEY_PRIMARY, index);
2752 if (err)
2753 bphy_err(drvr, "error (%d)\n", err);
2754 }
2755 done:
2756 brcmf_dbg(TRACE, "Exit\n");
2757 return err;
2758 }
2759
2760 static s32
brcmf_cfg80211_del_key(struct wiphy * wiphy,struct net_device * ndev,int link_id,u8 key_idx,bool pairwise,const u8 * mac_addr)2761 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2762 int link_id, u8 key_idx, bool pairwise,
2763 const u8 *mac_addr)
2764 {
2765 struct brcmf_if *ifp = netdev_priv(ndev);
2766 struct brcmf_wsec_key *key;
2767 s32 err;
2768
2769 brcmf_dbg(TRACE, "Enter\n");
2770 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2771
2772 if (!check_vif_up(ifp->vif))
2773 return -EIO;
2774
2775 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2776 /* we ignore this key index in this case */
2777 return -EINVAL;
2778 }
2779
2780 key = &ifp->vif->profile.key[key_idx];
2781
2782 if (key->algo == CRYPTO_ALGO_OFF) {
2783 brcmf_dbg(CONN, "Ignore clearing of (never configured) key\n");
2784 return -EINVAL;
2785 }
2786
2787 memset(key, 0, sizeof(*key));
2788 key->index = (u32)key_idx;
2789 key->flags = BRCMF_PRIMARY_KEY;
2790
2791 /* Clear the key/index */
2792 err = send_key_to_dongle(ifp, key);
2793
2794 brcmf_dbg(TRACE, "Exit\n");
2795 return err;
2796 }
2797
2798 static s32
brcmf_cfg80211_add_key(struct wiphy * wiphy,struct net_device * ndev,int link_id,u8 key_idx,bool pairwise,const u8 * mac_addr,struct key_params * params)2799 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2800 int link_id, u8 key_idx, bool pairwise,
2801 const u8 *mac_addr, struct key_params *params)
2802 {
2803 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2804 struct brcmf_if *ifp = netdev_priv(ndev);
2805 struct brcmf_pub *drvr = cfg->pub;
2806 struct brcmf_wsec_key *key;
2807 s32 val;
2808 s32 wsec;
2809 s32 err;
2810 u8 keybuf[8];
2811 bool ext_key;
2812
2813 brcmf_dbg(TRACE, "Enter\n");
2814 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2815 if (!check_vif_up(ifp->vif))
2816 return -EIO;
2817
2818 if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2819 /* we ignore this key index in this case */
2820 bphy_err(drvr, "invalid key index (%d)\n", key_idx);
2821 return -EINVAL;
2822 }
2823
2824 if (params->key_len == 0)
2825 return brcmf_cfg80211_del_key(wiphy, ndev, -1, key_idx,
2826 pairwise, mac_addr);
2827
2828 if (params->key_len > sizeof(key->data)) {
2829 bphy_err(drvr, "Too long key length (%u)\n", params->key_len);
2830 return -EINVAL;
2831 }
2832
2833 ext_key = false;
2834 if (mac_addr && (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2835 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2836 brcmf_dbg(TRACE, "Ext key, mac %pM", mac_addr);
2837 ext_key = true;
2838 }
2839
2840 key = &ifp->vif->profile.key[key_idx];
2841 memset(key, 0, sizeof(*key));
2842 if ((ext_key) && (!is_multicast_ether_addr(mac_addr)))
2843 memcpy((char *)&key->ea, (void *)mac_addr, ETH_ALEN);
2844 key->len = params->key_len;
2845 key->index = key_idx;
2846 memcpy(key->data, params->key, key->len);
2847 if (!ext_key)
2848 key->flags = BRCMF_PRIMARY_KEY;
2849
2850 if (params->seq && params->seq_len == 6) {
2851 /* rx iv */
2852 u8 *ivptr;
2853
2854 ivptr = (u8 *)params->seq;
2855 key->rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2856 (ivptr[3] << 8) | ivptr[2];
2857 key->rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2858 key->iv_initialized = true;
2859 }
2860
2861 switch (params->cipher) {
2862 case WLAN_CIPHER_SUITE_WEP40:
2863 key->algo = CRYPTO_ALGO_WEP1;
2864 val = WEP_ENABLED;
2865 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2866 break;
2867 case WLAN_CIPHER_SUITE_WEP104:
2868 key->algo = CRYPTO_ALGO_WEP128;
2869 val = WEP_ENABLED;
2870 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2871 break;
2872 case WLAN_CIPHER_SUITE_TKIP:
2873 if (!brcmf_is_apmode(ifp->vif)) {
2874 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2875 memcpy(keybuf, &key->data[24], sizeof(keybuf));
2876 memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2877 memcpy(&key->data[16], keybuf, sizeof(keybuf));
2878 }
2879 key->algo = CRYPTO_ALGO_TKIP;
2880 val = TKIP_ENABLED;
2881 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2882 break;
2883 case WLAN_CIPHER_SUITE_AES_CMAC:
2884 key->algo = CRYPTO_ALGO_AES_CCM;
2885 val = AES_ENABLED;
2886 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2887 break;
2888 case WLAN_CIPHER_SUITE_CCMP:
2889 key->algo = CRYPTO_ALGO_AES_CCM;
2890 val = AES_ENABLED;
2891 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2892 break;
2893 default:
2894 bphy_err(drvr, "Invalid cipher (0x%x)\n", params->cipher);
2895 err = -EINVAL;
2896 goto done;
2897 }
2898
2899 err = send_key_to_dongle(ifp, key);
2900 if (ext_key || err)
2901 goto done;
2902
2903 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2904 if (err) {
2905 bphy_err(drvr, "get wsec error (%d)\n", err);
2906 goto done;
2907 }
2908 wsec |= val;
2909 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2910 if (err) {
2911 bphy_err(drvr, "set wsec error (%d)\n", err);
2912 goto done;
2913 }
2914
2915 done:
2916 brcmf_dbg(TRACE, "Exit\n");
2917 return err;
2918 }
2919
2920 static s32
brcmf_cfg80211_get_key(struct wiphy * wiphy,struct net_device * ndev,int link_id,u8 key_idx,bool pairwise,const u8 * mac_addr,void * cookie,void (* callback)(void * cookie,struct key_params * params))2921 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2922 int link_id, u8 key_idx, bool pairwise,
2923 const u8 *mac_addr, void *cookie,
2924 void (*callback)(void *cookie,
2925 struct key_params *params))
2926 {
2927 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2928 struct key_params params;
2929 struct brcmf_if *ifp = netdev_priv(ndev);
2930 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2931 struct brcmf_pub *drvr = cfg->pub;
2932 struct brcmf_cfg80211_security *sec;
2933 s32 wsec;
2934 s32 err = 0;
2935
2936 brcmf_dbg(TRACE, "Enter\n");
2937 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2938 if (!check_vif_up(ifp->vif))
2939 return -EIO;
2940
2941 memset(¶ms, 0, sizeof(params));
2942
2943 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2944 if (err) {
2945 bphy_err(drvr, "WLC_GET_WSEC error (%d)\n", err);
2946 /* Ignore this error, may happen during DISASSOC */
2947 err = -EAGAIN;
2948 goto done;
2949 }
2950 if (wsec & WEP_ENABLED) {
2951 sec = &profile->sec;
2952 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2953 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2954 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2955 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2956 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2957 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2958 }
2959 } else if (wsec & TKIP_ENABLED) {
2960 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2961 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2962 } else if (wsec & AES_ENABLED) {
2963 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2964 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2965 } else {
2966 bphy_err(drvr, "Invalid algo (0x%x)\n", wsec);
2967 err = -EINVAL;
2968 goto done;
2969 }
2970 callback(cookie, ¶ms);
2971
2972 done:
2973 brcmf_dbg(TRACE, "Exit\n");
2974 return err;
2975 }
2976
2977 static s32
brcmf_cfg80211_config_default_mgmt_key(struct wiphy * wiphy,struct net_device * ndev,int link_id,u8 key_idx)2978 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2979 struct net_device *ndev, int link_id,
2980 u8 key_idx)
2981 {
2982 struct brcmf_if *ifp = netdev_priv(ndev);
2983
2984 brcmf_dbg(TRACE, "Enter key_idx %d\n", key_idx);
2985
2986 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
2987 return 0;
2988
2989 brcmf_dbg(INFO, "Not supported\n");
2990
2991 return -EOPNOTSUPP;
2992 }
2993
2994 static void
brcmf_cfg80211_reconfigure_wep(struct brcmf_if * ifp)2995 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2996 {
2997 struct brcmf_pub *drvr = ifp->drvr;
2998 s32 err;
2999 u8 key_idx;
3000 struct brcmf_wsec_key *key;
3001 s32 wsec;
3002
3003 for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
3004 key = &ifp->vif->profile.key[key_idx];
3005 if ((key->algo == CRYPTO_ALGO_WEP1) ||
3006 (key->algo == CRYPTO_ALGO_WEP128))
3007 break;
3008 }
3009 if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
3010 return;
3011
3012 err = send_key_to_dongle(ifp, key);
3013 if (err) {
3014 bphy_err(drvr, "Setting WEP key failed (%d)\n", err);
3015 return;
3016 }
3017 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
3018 if (err) {
3019 bphy_err(drvr, "get wsec error (%d)\n", err);
3020 return;
3021 }
3022 wsec |= WEP_ENABLED;
3023 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3024 if (err)
3025 bphy_err(drvr, "set wsec error (%d)\n", err);
3026 }
3027
brcmf_convert_sta_flags(u32 fw_sta_flags,struct station_info * si)3028 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
3029 {
3030 struct nl80211_sta_flag_update *sfu;
3031
3032 brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
3033 si->filled |= BIT_ULL(NL80211_STA_INFO_STA_FLAGS);
3034 sfu = &si->sta_flags;
3035 sfu->mask = BIT(NL80211_STA_FLAG_WME) |
3036 BIT(NL80211_STA_FLAG_AUTHENTICATED) |
3037 BIT(NL80211_STA_FLAG_ASSOCIATED) |
3038 BIT(NL80211_STA_FLAG_AUTHORIZED);
3039 if (fw_sta_flags & BRCMF_STA_WME)
3040 sfu->set |= BIT(NL80211_STA_FLAG_WME);
3041 if (fw_sta_flags & BRCMF_STA_AUTHE)
3042 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
3043 if (fw_sta_flags & BRCMF_STA_ASSOC)
3044 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
3045 if (fw_sta_flags & BRCMF_STA_AUTHO)
3046 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
3047 }
3048
brcmf_fill_bss_param(struct brcmf_if * ifp,struct station_info * si)3049 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
3050 {
3051 struct brcmf_pub *drvr = ifp->drvr;
3052 struct {
3053 __le32 len;
3054 struct brcmf_bss_info_le bss_le;
3055 } *buf;
3056 u16 capability;
3057 int err;
3058
3059 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3060 if (!buf)
3061 return;
3062
3063 buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
3064 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
3065 WL_BSS_INFO_MAX);
3066 if (err) {
3067 bphy_err(drvr, "Failed to get bss info (%d)\n", err);
3068 goto out_kfree;
3069 }
3070 si->filled |= BIT_ULL(NL80211_STA_INFO_BSS_PARAM);
3071 si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
3072 si->bss_param.dtim_period = buf->bss_le.dtim_period;
3073 capability = le16_to_cpu(buf->bss_le.capability);
3074 if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
3075 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
3076 if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
3077 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
3078 if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
3079 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
3080
3081 out_kfree:
3082 kfree(buf);
3083 }
3084
3085 static s32
brcmf_cfg80211_get_station_ibss(struct brcmf_if * ifp,struct station_info * sinfo)3086 brcmf_cfg80211_get_station_ibss(struct brcmf_if *ifp,
3087 struct station_info *sinfo)
3088 {
3089 struct brcmf_pub *drvr = ifp->drvr;
3090 struct brcmf_scb_val_le scbval;
3091 struct brcmf_pktcnt_le pktcnt;
3092 s32 err;
3093 u32 rate;
3094 u32 rssi;
3095
3096 /* Get the current tx rate */
3097 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
3098 if (err < 0) {
3099 bphy_err(drvr, "BRCMF_C_GET_RATE error (%d)\n", err);
3100 return err;
3101 }
3102 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
3103 sinfo->txrate.legacy = rate * 5;
3104
3105 memset(&scbval, 0, sizeof(scbval));
3106 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI, &scbval,
3107 sizeof(scbval));
3108 if (err) {
3109 bphy_err(drvr, "BRCMF_C_GET_RSSI error (%d)\n", err);
3110 return err;
3111 }
3112 rssi = le32_to_cpu(scbval.val);
3113 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3114 sinfo->signal = rssi;
3115
3116 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_GET_PKTCNTS, &pktcnt,
3117 sizeof(pktcnt));
3118 if (err) {
3119 bphy_err(drvr, "BRCMF_C_GET_GET_PKTCNTS error (%d)\n", err);
3120 return err;
3121 }
3122 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS) |
3123 BIT_ULL(NL80211_STA_INFO_RX_DROP_MISC) |
3124 BIT_ULL(NL80211_STA_INFO_TX_PACKETS) |
3125 BIT_ULL(NL80211_STA_INFO_TX_FAILED);
3126 sinfo->rx_packets = le32_to_cpu(pktcnt.rx_good_pkt);
3127 sinfo->rx_dropped_misc = le32_to_cpu(pktcnt.rx_bad_pkt);
3128 sinfo->tx_packets = le32_to_cpu(pktcnt.tx_good_pkt);
3129 sinfo->tx_failed = le32_to_cpu(pktcnt.tx_bad_pkt);
3130
3131 return 0;
3132 }
3133
3134 static s32
brcmf_cfg80211_get_station(struct wiphy * wiphy,struct net_device * ndev,const u8 * mac,struct station_info * sinfo)3135 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
3136 const u8 *mac, struct station_info *sinfo)
3137 {
3138 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3139 struct brcmf_if *ifp = netdev_priv(ndev);
3140 struct brcmf_pub *drvr = cfg->pub;
3141 struct brcmf_scb_val_le scb_val;
3142 s32 err = 0;
3143 struct brcmf_sta_info_le sta_info_le;
3144 u32 sta_flags;
3145 u32 is_tdls_peer;
3146 s32 total_rssi_avg = 0;
3147 s32 total_rssi = 0;
3148 s32 count_rssi = 0;
3149 int rssi;
3150 u32 i;
3151
3152 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
3153 if (!check_vif_up(ifp->vif))
3154 return -EIO;
3155
3156 if (brcmf_is_ibssmode(ifp->vif))
3157 return brcmf_cfg80211_get_station_ibss(ifp, sinfo);
3158
3159 memset(&sta_info_le, 0, sizeof(sta_info_le));
3160 memcpy(&sta_info_le, mac, ETH_ALEN);
3161 err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
3162 &sta_info_le,
3163 sizeof(sta_info_le));
3164 is_tdls_peer = !err;
3165 if (err) {
3166 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
3167 &sta_info_le,
3168 sizeof(sta_info_le));
3169 if (err < 0) {
3170 bphy_err(drvr, "GET STA INFO failed, %d\n", err);
3171 goto done;
3172 }
3173 }
3174 brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
3175 sinfo->filled = BIT_ULL(NL80211_STA_INFO_INACTIVE_TIME);
3176 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
3177 sta_flags = le32_to_cpu(sta_info_le.flags);
3178 brcmf_convert_sta_flags(sta_flags, sinfo);
3179 sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
3180 if (is_tdls_peer)
3181 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
3182 else
3183 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
3184 if (sta_flags & BRCMF_STA_ASSOC) {
3185 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CONNECTED_TIME);
3186 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
3187 brcmf_fill_bss_param(ifp, sinfo);
3188 }
3189 if (sta_flags & BRCMF_STA_SCBSTATS) {
3190 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_FAILED);
3191 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
3192 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_PACKETS);
3193 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
3194 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
3195 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_PACKETS);
3196 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
3197 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
3198 if (sinfo->tx_packets) {
3199 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BITRATE);
3200 sinfo->txrate.legacy =
3201 le32_to_cpu(sta_info_le.tx_rate) / 100;
3202 }
3203 if (sinfo->rx_packets) {
3204 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BITRATE);
3205 sinfo->rxrate.legacy =
3206 le32_to_cpu(sta_info_le.rx_rate) / 100;
3207 }
3208 if (le16_to_cpu(sta_info_le.ver) >= 4) {
3209 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_TX_BYTES);
3210 sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
3211 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_RX_BYTES);
3212 sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
3213 }
3214 for (i = 0; i < BRCMF_ANT_MAX; i++) {
3215 if (sta_info_le.rssi[i] == 0 ||
3216 sta_info_le.rx_lastpkt_rssi[i] == 0)
3217 continue;
3218 sinfo->chains |= BIT(count_rssi);
3219 sinfo->chain_signal[count_rssi] =
3220 sta_info_le.rx_lastpkt_rssi[i];
3221 sinfo->chain_signal_avg[count_rssi] =
3222 sta_info_le.rssi[i];
3223 total_rssi += sta_info_le.rx_lastpkt_rssi[i];
3224 total_rssi_avg += sta_info_le.rssi[i];
3225 count_rssi++;
3226 }
3227 if (count_rssi) {
3228 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3229 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL_AVG);
3230 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL);
3231 sinfo->filled |=
3232 BIT_ULL(NL80211_STA_INFO_CHAIN_SIGNAL_AVG);
3233 sinfo->signal = total_rssi / count_rssi;
3234 sinfo->signal_avg = total_rssi_avg / count_rssi;
3235 } else if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
3236 &ifp->vif->sme_state)) {
3237 memset(&scb_val, 0, sizeof(scb_val));
3238 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
3239 &scb_val, sizeof(scb_val));
3240 if (err) {
3241 bphy_err(drvr, "Could not get rssi (%d)\n",
3242 err);
3243 goto done;
3244 } else {
3245 rssi = le32_to_cpu(scb_val.val);
3246 sinfo->filled |= BIT_ULL(NL80211_STA_INFO_SIGNAL);
3247 sinfo->signal = rssi;
3248 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
3249 }
3250 }
3251 }
3252 done:
3253 brcmf_dbg(TRACE, "Exit\n");
3254 return err;
3255 }
3256
3257 static int
brcmf_cfg80211_dump_station(struct wiphy * wiphy,struct net_device * ndev,int idx,u8 * mac,struct station_info * sinfo)3258 brcmf_cfg80211_dump_station(struct wiphy *wiphy, struct net_device *ndev,
3259 int idx, u8 *mac, struct station_info *sinfo)
3260 {
3261 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3262 struct brcmf_if *ifp = netdev_priv(ndev);
3263 struct brcmf_pub *drvr = cfg->pub;
3264 s32 err;
3265
3266 brcmf_dbg(TRACE, "Enter, idx %d\n", idx);
3267
3268 if (idx == 0) {
3269 cfg->assoclist.count = cpu_to_le32(BRCMF_MAX_ASSOCLIST);
3270 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_ASSOCLIST,
3271 &cfg->assoclist,
3272 sizeof(cfg->assoclist));
3273 if (err) {
3274 /* GET_ASSOCLIST unsupported by firmware of older chips */
3275 if (err == -EBADE)
3276 bphy_info_once(drvr, "BRCMF_C_GET_ASSOCLIST unsupported\n");
3277 else
3278 bphy_err(drvr, "BRCMF_C_GET_ASSOCLIST failed, err=%d\n",
3279 err);
3280
3281 cfg->assoclist.count = 0;
3282 return -EOPNOTSUPP;
3283 }
3284 }
3285 if (idx < le32_to_cpu(cfg->assoclist.count)) {
3286 memcpy(mac, cfg->assoclist.mac[idx], ETH_ALEN);
3287 return brcmf_cfg80211_get_station(wiphy, ndev, mac, sinfo);
3288 }
3289 return -ENOENT;
3290 }
3291
3292 static s32
brcmf_cfg80211_set_power_mgmt(struct wiphy * wiphy,struct net_device * ndev,bool enabled,s32 timeout)3293 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
3294 bool enabled, s32 timeout)
3295 {
3296 s32 pm;
3297 s32 err = 0;
3298 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3299 struct brcmf_if *ifp = netdev_priv(ndev);
3300 struct brcmf_pub *drvr = cfg->pub;
3301
3302 brcmf_dbg(TRACE, "Enter\n");
3303
3304 /*
3305 * Powersave enable/disable request is coming from the
3306 * cfg80211 even before the interface is up. In that
3307 * scenario, driver will be storing the power save
3308 * preference in cfg struct to apply this to
3309 * FW later while initializing the dongle
3310 */
3311 cfg->pwr_save = enabled;
3312 if (!check_vif_up(ifp->vif)) {
3313
3314 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
3315 goto done;
3316 }
3317
3318 pm = enabled ? PM_FAST : PM_OFF;
3319 /* Do not enable the power save after assoc if it is a p2p interface */
3320 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
3321 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
3322 pm = PM_OFF;
3323 }
3324 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
3325
3326 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
3327 if (err) {
3328 if (err == -ENODEV)
3329 bphy_err(drvr, "net_device is not ready yet\n");
3330 else
3331 bphy_err(drvr, "error (%d)\n", err);
3332 }
3333
3334 err = brcmf_fil_iovar_int_set(ifp, "pm2_sleep_ret",
3335 min_t(u32, timeout, BRCMF_PS_MAX_TIMEOUT_MS));
3336 if (err)
3337 bphy_err(drvr, "Unable to set pm timeout, (%d)\n", err);
3338
3339 done:
3340 brcmf_dbg(TRACE, "Exit\n");
3341 return err;
3342 }
3343
brcmf_inform_single_bss(struct brcmf_cfg80211_info * cfg,struct brcmf_bss_info_le * bi)3344 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
3345 struct brcmf_bss_info_le *bi)
3346 {
3347 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3348 struct brcmf_pub *drvr = cfg->pub;
3349 struct cfg80211_bss *bss;
3350 enum nl80211_band band;
3351 struct brcmu_chan ch;
3352 u16 channel;
3353 u32 freq;
3354 u16 notify_capability;
3355 u16 notify_interval;
3356 u8 *notify_ie;
3357 size_t notify_ielen;
3358 struct cfg80211_inform_bss bss_data = {};
3359
3360 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
3361 bphy_err(drvr, "Bss info is larger than buffer. Discarding\n");
3362 return -EINVAL;
3363 }
3364
3365 if (!bi->ctl_ch) {
3366 ch.chspec = le16_to_cpu(bi->chanspec);
3367 cfg->d11inf.decchspec(&ch);
3368 bi->ctl_ch = ch.control_ch_num;
3369 }
3370 channel = bi->ctl_ch;
3371
3372 if (channel <= CH_MAX_2G_CHANNEL)
3373 band = NL80211_BAND_2GHZ;
3374 else
3375 band = NL80211_BAND_5GHZ;
3376
3377 freq = ieee80211_channel_to_frequency(channel, band);
3378 bss_data.chan = ieee80211_get_channel(wiphy, freq);
3379 bss_data.boottime_ns = ktime_to_ns(ktime_get_boottime());
3380
3381 notify_capability = le16_to_cpu(bi->capability);
3382 notify_interval = le16_to_cpu(bi->beacon_period);
3383 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3384 notify_ielen = le32_to_cpu(bi->ie_length);
3385 bss_data.signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3386
3387 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
3388 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
3389 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
3390 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
3391 brcmf_dbg(CONN, "Signal: %d\n", bss_data.signal);
3392
3393 bss = cfg80211_inform_bss_data(wiphy, &bss_data,
3394 CFG80211_BSS_FTYPE_UNKNOWN,
3395 (const u8 *)bi->BSSID,
3396 0, notify_capability,
3397 notify_interval, notify_ie,
3398 notify_ielen, GFP_KERNEL);
3399
3400 if (!bss)
3401 return -ENOMEM;
3402
3403 cfg80211_put_bss(wiphy, bss);
3404
3405 return 0;
3406 }
3407
3408 static struct brcmf_bss_info_le *
next_bss_le(struct brcmf_scan_results * list,struct brcmf_bss_info_le * bss)3409 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
3410 {
3411 if (bss == NULL)
3412 return list->bss_info_le;
3413 return (struct brcmf_bss_info_le *)((unsigned long)bss +
3414 le32_to_cpu(bss->length));
3415 }
3416
brcmf_inform_bss(struct brcmf_cfg80211_info * cfg)3417 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
3418 {
3419 struct brcmf_pub *drvr = cfg->pub;
3420 struct brcmf_scan_results *bss_list;
3421 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
3422 s32 err = 0;
3423 int i;
3424
3425 bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
3426 if (bss_list->count != 0 &&
3427 bss_list->version != BRCMF_BSS_INFO_VERSION) {
3428 bphy_err(drvr, "Version %d != WL_BSS_INFO_VERSION\n",
3429 bss_list->version);
3430 return -EOPNOTSUPP;
3431 }
3432 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
3433 for (i = 0; i < bss_list->count; i++) {
3434 bi = next_bss_le(bss_list, bi);
3435 err = brcmf_inform_single_bss(cfg, bi);
3436 if (err)
3437 break;
3438 }
3439 return err;
3440 }
3441
brcmf_inform_ibss(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const u8 * bssid)3442 static s32 brcmf_inform_ibss(struct brcmf_cfg80211_info *cfg,
3443 struct net_device *ndev, const u8 *bssid)
3444 {
3445 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3446 struct brcmf_pub *drvr = cfg->pub;
3447 struct ieee80211_channel *notify_channel;
3448 struct brcmf_bss_info_le *bi = NULL;
3449 struct ieee80211_supported_band *band;
3450 struct cfg80211_bss *bss;
3451 struct brcmu_chan ch;
3452 u8 *buf = NULL;
3453 s32 err = 0;
3454 u32 freq;
3455 u16 notify_capability;
3456 u16 notify_interval;
3457 u8 *notify_ie;
3458 size_t notify_ielen;
3459 s32 notify_signal;
3460
3461 brcmf_dbg(TRACE, "Enter\n");
3462
3463 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3464 if (buf == NULL) {
3465 err = -ENOMEM;
3466 goto CleanUp;
3467 }
3468
3469 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3470
3471 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
3472 buf, WL_BSS_INFO_MAX);
3473 if (err) {
3474 bphy_err(drvr, "WLC_GET_BSS_INFO failed: %d\n", err);
3475 goto CleanUp;
3476 }
3477
3478 bi = (struct brcmf_bss_info_le *)(buf + 4);
3479
3480 ch.chspec = le16_to_cpu(bi->chanspec);
3481 cfg->d11inf.decchspec(&ch);
3482
3483 if (ch.band == BRCMU_CHAN_BAND_2G)
3484 band = wiphy->bands[NL80211_BAND_2GHZ];
3485 else
3486 band = wiphy->bands[NL80211_BAND_5GHZ];
3487
3488 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
3489 cfg->channel = freq;
3490 notify_channel = ieee80211_get_channel(wiphy, freq);
3491
3492 notify_capability = le16_to_cpu(bi->capability);
3493 notify_interval = le16_to_cpu(bi->beacon_period);
3494 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
3495 notify_ielen = le32_to_cpu(bi->ie_length);
3496 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
3497
3498 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.control_ch_num, freq);
3499 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
3500 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
3501 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
3502
3503 bss = cfg80211_inform_bss(wiphy, notify_channel,
3504 CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
3505 notify_capability, notify_interval,
3506 notify_ie, notify_ielen, notify_signal,
3507 GFP_KERNEL);
3508
3509 if (!bss) {
3510 err = -ENOMEM;
3511 goto CleanUp;
3512 }
3513
3514 cfg80211_put_bss(wiphy, bss);
3515
3516 CleanUp:
3517
3518 kfree(buf);
3519
3520 brcmf_dbg(TRACE, "Exit\n");
3521
3522 return err;
3523 }
3524
brcmf_update_bss_info(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp)3525 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
3526 struct brcmf_if *ifp)
3527 {
3528 struct brcmf_pub *drvr = cfg->pub;
3529 struct brcmf_bss_info_le *bi = NULL;
3530 s32 err = 0;
3531
3532 brcmf_dbg(TRACE, "Enter\n");
3533 if (brcmf_is_ibssmode(ifp->vif))
3534 return err;
3535
3536 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
3537 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3538 cfg->extra_buf, WL_EXTRA_BUF_MAX);
3539 if (err) {
3540 bphy_err(drvr, "Could not get bss info %d\n", err);
3541 goto update_bss_info_out;
3542 }
3543 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
3544 err = brcmf_inform_single_bss(cfg, bi);
3545
3546 update_bss_info_out:
3547 brcmf_dbg(TRACE, "Exit");
3548 return err;
3549 }
3550
brcmf_abort_scanning(struct brcmf_cfg80211_info * cfg)3551 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
3552 {
3553 struct escan_info *escan = &cfg->escan_info;
3554
3555 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3556 if (cfg->int_escan_map || cfg->scan_request) {
3557 escan->escan_state = WL_ESCAN_STATE_IDLE;
3558 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
3559 }
3560 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3561 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
3562 }
3563
brcmf_cfg80211_escan_timeout_worker(struct work_struct * work)3564 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
3565 {
3566 struct brcmf_cfg80211_info *cfg =
3567 container_of(work, struct brcmf_cfg80211_info,
3568 escan_timeout_work);
3569
3570 brcmf_inform_bss(cfg);
3571 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
3572 }
3573
brcmf_escan_timeout(struct timer_list * t)3574 static void brcmf_escan_timeout(struct timer_list *t)
3575 {
3576 struct brcmf_cfg80211_info *cfg =
3577 timer_container_of(cfg, t, escan_timeout);
3578 struct brcmf_pub *drvr = cfg->pub;
3579
3580 if (cfg->int_escan_map || cfg->scan_request) {
3581 bphy_err(drvr, "timer expired\n");
3582 schedule_work(&cfg->escan_timeout_work);
3583 }
3584 }
3585
3586 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)3587 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
3588 struct brcmf_bss_info_le *bss,
3589 struct brcmf_bss_info_le *bss_info_le)
3590 {
3591 struct brcmu_chan ch_bss, ch_bss_info_le;
3592
3593 ch_bss.chspec = le16_to_cpu(bss->chanspec);
3594 cfg->d11inf.decchspec(&ch_bss);
3595 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
3596 cfg->d11inf.decchspec(&ch_bss_info_le);
3597
3598 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
3599 ch_bss.band == ch_bss_info_le.band &&
3600 bss_info_le->SSID_len == bss->SSID_len &&
3601 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
3602 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
3603 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
3604 s16 bss_rssi = le16_to_cpu(bss->RSSI);
3605 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
3606
3607 /* preserve max RSSI if the measurements are
3608 * both on-channel or both off-channel
3609 */
3610 if (bss_info_rssi > bss_rssi)
3611 bss->RSSI = bss_info_le->RSSI;
3612 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
3613 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
3614 /* preserve the on-channel rssi measurement
3615 * if the new measurement is off channel
3616 */
3617 bss->RSSI = bss_info_le->RSSI;
3618 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
3619 }
3620 return 1;
3621 }
3622 return 0;
3623 }
3624
3625 static s32
brcmf_cfg80211_escan_handler(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)3626 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
3627 const struct brcmf_event_msg *e, void *data)
3628 {
3629 struct brcmf_pub *drvr = ifp->drvr;
3630 struct brcmf_cfg80211_info *cfg = drvr->config;
3631 s32 status;
3632 struct brcmf_escan_result_le *escan_result_le;
3633 u32 escan_buflen;
3634 struct brcmf_bss_info_le *bss_info_le;
3635 struct brcmf_bss_info_le *bss = NULL;
3636 u32 bi_length;
3637 struct brcmf_scan_results *list;
3638 u32 i;
3639 bool aborted;
3640
3641 status = e->status;
3642
3643 if (status == BRCMF_E_STATUS_ABORT)
3644 goto exit;
3645
3646 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3647 bphy_err(drvr, "scan not ready, bsscfgidx=%d\n",
3648 ifp->bsscfgidx);
3649 return -EPERM;
3650 }
3651
3652 if (status == BRCMF_E_STATUS_PARTIAL) {
3653 brcmf_dbg(SCAN, "ESCAN Partial result\n");
3654 if (e->datalen < sizeof(*escan_result_le)) {
3655 bphy_err(drvr, "invalid event data length\n");
3656 goto exit;
3657 }
3658 escan_result_le = (struct brcmf_escan_result_le *) data;
3659 if (!escan_result_le) {
3660 bphy_err(drvr, "Invalid escan result (NULL pointer)\n");
3661 goto exit;
3662 }
3663 escan_buflen = le32_to_cpu(escan_result_le->buflen);
3664 if (escan_buflen > BRCMF_ESCAN_BUF_SIZE ||
3665 escan_buflen > e->datalen ||
3666 escan_buflen < sizeof(*escan_result_le)) {
3667 bphy_err(drvr, "Invalid escan buffer length: %d\n",
3668 escan_buflen);
3669 goto exit;
3670 }
3671 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
3672 bphy_err(drvr, "Invalid bss_count %d: ignoring\n",
3673 escan_result_le->bss_count);
3674 goto exit;
3675 }
3676 bss_info_le = &escan_result_le->bss_info_le;
3677
3678 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
3679 goto exit;
3680
3681 if (!cfg->int_escan_map && !cfg->scan_request) {
3682 brcmf_dbg(SCAN, "result without cfg80211 request\n");
3683 goto exit;
3684 }
3685
3686 bi_length = le32_to_cpu(bss_info_le->length);
3687 if (bi_length != escan_buflen - WL_ESCAN_RESULTS_FIXED_SIZE) {
3688 bphy_err(drvr, "Ignoring invalid bss_info length: %d\n",
3689 bi_length);
3690 goto exit;
3691 }
3692
3693 if (!(cfg_to_wiphy(cfg)->interface_modes &
3694 BIT(NL80211_IFTYPE_ADHOC))) {
3695 if (le16_to_cpu(bss_info_le->capability) &
3696 WLAN_CAPABILITY_IBSS) {
3697 bphy_err(drvr, "Ignoring IBSS result\n");
3698 goto exit;
3699 }
3700 }
3701
3702 list = (struct brcmf_scan_results *)
3703 cfg->escan_info.escan_buf;
3704 if (bi_length > BRCMF_ESCAN_BUF_SIZE - list->buflen) {
3705 bphy_err(drvr, "Buffer is too small: ignoring\n");
3706 goto exit;
3707 }
3708
3709 for (i = 0; i < list->count; i++) {
3710 bss = bss ? (struct brcmf_bss_info_le *)
3711 ((unsigned char *)bss +
3712 le32_to_cpu(bss->length)) : list->bss_info_le;
3713 if (brcmf_compare_update_same_bss(cfg, bss,
3714 bss_info_le))
3715 goto exit;
3716 }
3717 memcpy(&cfg->escan_info.escan_buf[list->buflen], bss_info_le,
3718 bi_length);
3719 list->version = le32_to_cpu(bss_info_le->version);
3720 list->buflen += bi_length;
3721 list->count++;
3722 } else {
3723 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3724 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
3725 goto exit;
3726 if (cfg->int_escan_map || cfg->scan_request) {
3727 brcmf_inform_bss(cfg);
3728 aborted = status != BRCMF_E_STATUS_SUCCESS;
3729 brcmf_notify_escan_complete(cfg, ifp, aborted, false);
3730 } else
3731 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
3732 status);
3733 }
3734 exit:
3735 return 0;
3736 }
3737
brcmf_init_escan(struct brcmf_cfg80211_info * cfg)3738 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
3739 {
3740 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
3741 brcmf_cfg80211_escan_handler);
3742 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
3743 /* Init scan_timeout timer */
3744 timer_setup(&cfg->escan_timeout, brcmf_escan_timeout, 0);
3745 INIT_WORK(&cfg->escan_timeout_work,
3746 brcmf_cfg80211_escan_timeout_worker);
3747 }
3748
3749 static struct cfg80211_scan_request *
brcmf_alloc_internal_escan_request(struct wiphy * wiphy,u32 n_netinfo)3750 brcmf_alloc_internal_escan_request(struct wiphy *wiphy, u32 n_netinfo) {
3751 struct cfg80211_scan_request *req;
3752 size_t req_size;
3753
3754 req_size = sizeof(*req) +
3755 n_netinfo * sizeof(req->channels[0]) +
3756 n_netinfo * sizeof(*req->ssids);
3757
3758 req = kzalloc(req_size, GFP_KERNEL);
3759 if (req) {
3760 req->wiphy = wiphy;
3761 req->ssids = (void *)(&req->channels[0]) +
3762 n_netinfo * sizeof(req->channels[0]);
3763 }
3764 return req;
3765 }
3766
brcmf_internal_escan_add_info(struct cfg80211_scan_request * req,u8 * ssid,u8 ssid_len,u8 channel)3767 static int brcmf_internal_escan_add_info(struct cfg80211_scan_request *req,
3768 u8 *ssid, u8 ssid_len, u8 channel)
3769 {
3770 struct ieee80211_channel *chan;
3771 enum nl80211_band band;
3772 int freq, i;
3773
3774 if (channel <= CH_MAX_2G_CHANNEL)
3775 band = NL80211_BAND_2GHZ;
3776 else
3777 band = NL80211_BAND_5GHZ;
3778
3779 freq = ieee80211_channel_to_frequency(channel, band);
3780 if (!freq)
3781 return -EINVAL;
3782
3783 chan = ieee80211_get_channel(req->wiphy, freq);
3784 if (!chan)
3785 return -EINVAL;
3786
3787 for (i = 0; i < req->n_channels; i++) {
3788 if (req->channels[i] == chan)
3789 break;
3790 }
3791 if (i == req->n_channels) {
3792 req->n_channels++;
3793 req->channels[i] = chan;
3794 }
3795
3796 for (i = 0; i < req->n_ssids; i++) {
3797 if (req->ssids[i].ssid_len == ssid_len &&
3798 !memcmp(req->ssids[i].ssid, ssid, ssid_len))
3799 break;
3800 }
3801 if (i == req->n_ssids) {
3802 memcpy(req->ssids[req->n_ssids].ssid, ssid, ssid_len);
3803 req->ssids[req->n_ssids++].ssid_len = ssid_len;
3804 }
3805 return 0;
3806 }
3807
brcmf_start_internal_escan(struct brcmf_if * ifp,u32 fwmap,struct cfg80211_scan_request * request)3808 static int brcmf_start_internal_escan(struct brcmf_if *ifp, u32 fwmap,
3809 struct cfg80211_scan_request *request)
3810 {
3811 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3812 int err;
3813
3814 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3815 if (cfg->int_escan_map)
3816 brcmf_dbg(SCAN, "aborting internal scan: map=%u\n",
3817 cfg->int_escan_map);
3818 /* Abort any on-going scan */
3819 brcmf_abort_scanning(cfg);
3820 }
3821
3822 brcmf_dbg(SCAN, "start internal scan: map=%u\n", fwmap);
3823 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3824 cfg->escan_info.run = brcmf_run_escan;
3825 err = brcmf_do_escan(ifp, request);
3826 if (err) {
3827 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3828 return err;
3829 }
3830 cfg->int_escan_map = fwmap;
3831 return 0;
3832 }
3833
3834 static struct brcmf_pno_net_info_le *
brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le * pfn_v1)3835 brcmf_get_netinfo_array(struct brcmf_pno_scanresults_le *pfn_v1)
3836 {
3837 struct brcmf_pno_scanresults_v2_le *pfn_v2;
3838 struct brcmf_pno_net_info_le *netinfo;
3839
3840 switch (pfn_v1->version) {
3841 default:
3842 WARN_ON(1);
3843 fallthrough;
3844 case cpu_to_le32(1):
3845 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v1 + 1);
3846 break;
3847 case cpu_to_le32(2):
3848 pfn_v2 = (struct brcmf_pno_scanresults_v2_le *)pfn_v1;
3849 netinfo = (struct brcmf_pno_net_info_le *)(pfn_v2 + 1);
3850 break;
3851 }
3852
3853 return netinfo;
3854 }
3855
3856 /* PFN result doesn't have all the info which are required by the supplicant
3857 * (For e.g IEs) Do a target Escan so that sched scan results are reported
3858 * via wl_inform_single_bss in the required format. Escan does require the
3859 * scan request in the form of cfg80211_scan_request. For timebeing, create
3860 * cfg80211_scan_request one out of the received PNO event.
3861 */
3862 static s32
brcmf_notify_sched_scan_results(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)3863 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3864 const struct brcmf_event_msg *e, void *data)
3865 {
3866 struct brcmf_pub *drvr = ifp->drvr;
3867 struct brcmf_cfg80211_info *cfg = drvr->config;
3868 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3869 struct cfg80211_scan_request *request = NULL;
3870 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3871 int i, err = 0;
3872 struct brcmf_pno_scanresults_le *pfn_result;
3873 u32 bucket_map;
3874 u32 result_count;
3875 u32 status;
3876 u32 datalen;
3877
3878 brcmf_dbg(SCAN, "Enter\n");
3879
3880 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
3881 brcmf_dbg(SCAN, "Event data too small. Ignore\n");
3882 return 0;
3883 }
3884
3885 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3886 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3887 return 0;
3888 }
3889
3890 pfn_result = (struct brcmf_pno_scanresults_le *)data;
3891 result_count = le32_to_cpu(pfn_result->count);
3892 status = le32_to_cpu(pfn_result->status);
3893
3894 /* PFN event is limited to fit 512 bytes so we may get
3895 * multiple NET_FOUND events. For now place a warning here.
3896 */
3897 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3898 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3899 if (!result_count) {
3900 bphy_err(drvr, "FALSE PNO Event. (pfn_count == 0)\n");
3901 goto out_err;
3902 }
3903
3904 netinfo_start = brcmf_get_netinfo_array(pfn_result);
3905 datalen = e->datalen - ((void *)netinfo_start - (void *)pfn_result);
3906 if (datalen < result_count * sizeof(*netinfo)) {
3907 bphy_err(drvr, "insufficient event data\n");
3908 goto out_err;
3909 }
3910
3911 request = brcmf_alloc_internal_escan_request(wiphy,
3912 result_count);
3913 if (!request) {
3914 err = -ENOMEM;
3915 goto out_err;
3916 }
3917
3918 bucket_map = 0;
3919 for (i = 0; i < result_count; i++) {
3920 netinfo = &netinfo_start[i];
3921
3922 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
3923 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
3924 brcmf_dbg(SCAN, "SSID:%.32s Channel:%d\n",
3925 netinfo->SSID, netinfo->channel);
3926 bucket_map |= brcmf_pno_get_bucket_map(cfg->pno, netinfo);
3927 err = brcmf_internal_escan_add_info(request,
3928 netinfo->SSID,
3929 netinfo->SSID_len,
3930 netinfo->channel);
3931 if (err)
3932 goto out_err;
3933 }
3934
3935 if (!bucket_map)
3936 goto free_req;
3937
3938 err = brcmf_start_internal_escan(ifp, bucket_map, request);
3939 if (!err)
3940 goto free_req;
3941
3942 out_err:
3943 cfg80211_sched_scan_stopped(wiphy, 0);
3944 free_req:
3945 kfree(request);
3946 return err;
3947 }
3948
3949 static int
brcmf_cfg80211_sched_scan_start(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_sched_scan_request * req)3950 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3951 struct net_device *ndev,
3952 struct cfg80211_sched_scan_request *req)
3953 {
3954 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3955 struct brcmf_if *ifp = netdev_priv(ndev);
3956 struct brcmf_pub *drvr = cfg->pub;
3957
3958 brcmf_dbg(SCAN, "Enter: n_match_sets=%d n_ssids=%d\n",
3959 req->n_match_sets, req->n_ssids);
3960
3961 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3962 bphy_err(drvr, "Scanning suppressed: status=%lu\n",
3963 cfg->scan_status);
3964 return -EAGAIN;
3965 }
3966
3967 if (req->n_match_sets <= 0) {
3968 brcmf_dbg(SCAN, "invalid number of matchsets specified: %d\n",
3969 req->n_match_sets);
3970 return -EINVAL;
3971 }
3972
3973 return brcmf_pno_start_sched_scan(ifp, req);
3974 }
3975
brcmf_cfg80211_sched_scan_stop(struct wiphy * wiphy,struct net_device * ndev,u64 reqid)3976 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3977 struct net_device *ndev, u64 reqid)
3978 {
3979 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3980 struct brcmf_if *ifp = netdev_priv(ndev);
3981
3982 brcmf_dbg(SCAN, "enter\n");
3983 brcmf_pno_stop_sched_scan(ifp, reqid);
3984 if (cfg->int_escan_map)
3985 brcmf_notify_escan_complete(cfg, ifp, true, true);
3986 return 0;
3987 }
3988
brcmf_delay(u32 ms)3989 static __always_inline void brcmf_delay(u32 ms)
3990 {
3991 if (ms < 1000 / HZ) {
3992 cond_resched();
3993 mdelay(ms);
3994 } else {
3995 msleep(ms);
3996 }
3997 }
3998
brcmf_config_wowl_pattern(struct brcmf_if * ifp,u8 cmd[4],u8 * pattern,u32 patternsize,u8 * mask,u32 packet_offset)3999 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
4000 u8 *pattern, u32 patternsize, u8 *mask,
4001 u32 packet_offset)
4002 {
4003 struct brcmf_fil_wowl_pattern_le *filter;
4004 u32 masksize;
4005 u32 patternoffset;
4006 u8 *buf;
4007 u32 bufsize;
4008 s32 ret;
4009
4010 masksize = (patternsize + 7) / 8;
4011 patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
4012
4013 bufsize = sizeof(*filter) + patternsize + masksize;
4014 buf = kzalloc(bufsize, GFP_KERNEL);
4015 if (!buf)
4016 return -ENOMEM;
4017 filter = (struct brcmf_fil_wowl_pattern_le *)buf;
4018
4019 memcpy(filter->cmd, cmd, 4);
4020 filter->masksize = cpu_to_le32(masksize);
4021 filter->offset = cpu_to_le32(packet_offset);
4022 filter->patternoffset = cpu_to_le32(patternoffset);
4023 filter->patternsize = cpu_to_le32(patternsize);
4024 filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
4025
4026 if ((mask) && (masksize))
4027 memcpy(buf + sizeof(*filter), mask, masksize);
4028 if ((pattern) && (patternsize))
4029 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
4030
4031 ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
4032
4033 kfree(buf);
4034 return ret;
4035 }
4036
4037 static s32
brcmf_wowl_nd_results(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)4038 brcmf_wowl_nd_results(struct brcmf_if *ifp, const struct brcmf_event_msg *e,
4039 void *data)
4040 {
4041 struct brcmf_pub *drvr = ifp->drvr;
4042 struct brcmf_cfg80211_info *cfg = drvr->config;
4043 struct brcmf_pno_scanresults_le *pfn_result;
4044 struct brcmf_pno_net_info_le *netinfo;
4045
4046 brcmf_dbg(SCAN, "Enter\n");
4047
4048 if (e->datalen < (sizeof(*pfn_result) + sizeof(*netinfo))) {
4049 brcmf_dbg(SCAN, "Event data too small. Ignore\n");
4050 return 0;
4051 }
4052
4053 pfn_result = (struct brcmf_pno_scanresults_le *)data;
4054
4055 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
4056 brcmf_dbg(SCAN, "PFN NET LOST event. Ignore\n");
4057 return 0;
4058 }
4059
4060 if (le32_to_cpu(pfn_result->count) < 1) {
4061 bphy_err(drvr, "Invalid result count, expected 1 (%d)\n",
4062 le32_to_cpu(pfn_result->count));
4063 return -EINVAL;
4064 }
4065
4066 netinfo = brcmf_get_netinfo_array(pfn_result);
4067 if (netinfo->SSID_len > IEEE80211_MAX_SSID_LEN)
4068 netinfo->SSID_len = IEEE80211_MAX_SSID_LEN;
4069 memcpy(cfg->wowl.nd->ssid.ssid, netinfo->SSID, netinfo->SSID_len);
4070 cfg->wowl.nd->ssid.ssid_len = netinfo->SSID_len;
4071 cfg->wowl.nd->n_channels = 1;
4072 cfg->wowl.nd->channels[0] =
4073 ieee80211_channel_to_frequency(netinfo->channel,
4074 netinfo->channel <= CH_MAX_2G_CHANNEL ?
4075 NL80211_BAND_2GHZ : NL80211_BAND_5GHZ);
4076 cfg->wowl.nd_info->n_matches = 1;
4077 cfg->wowl.nd_info->matches[0] = cfg->wowl.nd;
4078
4079 /* Inform (the resume task) that the net detect information was recvd */
4080 cfg->wowl.nd_data_completed = true;
4081 wake_up(&cfg->wowl.nd_data_wait);
4082
4083 return 0;
4084 }
4085
4086 #ifdef CONFIG_PM
4087
brcmf_report_wowl_wakeind(struct wiphy * wiphy,struct brcmf_if * ifp)4088 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
4089 {
4090 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4091 struct brcmf_pub *drvr = cfg->pub;
4092 struct brcmf_wowl_wakeind_le wake_ind_le;
4093 struct cfg80211_wowlan_wakeup wakeup_data;
4094 struct cfg80211_wowlan_wakeup *wakeup;
4095 u32 wakeind;
4096 s32 err;
4097 long time_left;
4098
4099 err = brcmf_fil_iovar_data_get(ifp, "wowl_wakeind", &wake_ind_le,
4100 sizeof(wake_ind_le));
4101 if (err) {
4102 bphy_err(drvr, "Get wowl_wakeind failed, err = %d\n", err);
4103 return;
4104 }
4105
4106 wakeind = le32_to_cpu(wake_ind_le.ucode_wakeind);
4107 if (wakeind & (BRCMF_WOWL_MAGIC | BRCMF_WOWL_DIS | BRCMF_WOWL_BCN |
4108 BRCMF_WOWL_RETR | BRCMF_WOWL_NET |
4109 BRCMF_WOWL_PFN_FOUND)) {
4110 wakeup = &wakeup_data;
4111 memset(&wakeup_data, 0, sizeof(wakeup_data));
4112 wakeup_data.pattern_idx = -1;
4113
4114 if (wakeind & BRCMF_WOWL_MAGIC) {
4115 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_MAGIC\n");
4116 wakeup_data.magic_pkt = true;
4117 }
4118 if (wakeind & BRCMF_WOWL_DIS) {
4119 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_DIS\n");
4120 wakeup_data.disconnect = true;
4121 }
4122 if (wakeind & BRCMF_WOWL_BCN) {
4123 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_BCN\n");
4124 wakeup_data.disconnect = true;
4125 }
4126 if (wakeind & BRCMF_WOWL_RETR) {
4127 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_RETR\n");
4128 wakeup_data.disconnect = true;
4129 }
4130 if (wakeind & BRCMF_WOWL_NET) {
4131 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_NET\n");
4132 /* For now always map to pattern 0, no API to get
4133 * correct information available at the moment.
4134 */
4135 wakeup_data.pattern_idx = 0;
4136 }
4137 if (wakeind & BRCMF_WOWL_PFN_FOUND) {
4138 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_PFN_FOUND\n");
4139 time_left = wait_event_timeout(cfg->wowl.nd_data_wait,
4140 cfg->wowl.nd_data_completed,
4141 BRCMF_ND_INFO_TIMEOUT);
4142 if (!time_left)
4143 bphy_err(drvr, "No result for wowl net detect\n");
4144 else
4145 wakeup_data.net_detect = cfg->wowl.nd_info;
4146 }
4147 if (wakeind & BRCMF_WOWL_GTK_FAILURE) {
4148 brcmf_dbg(INFO, "WOWL Wake indicator: BRCMF_WOWL_GTK_FAILURE\n");
4149 wakeup_data.gtk_rekey_failure = true;
4150 }
4151 } else {
4152 wakeup = NULL;
4153 }
4154 cfg80211_report_wowlan_wakeup(&ifp->vif->wdev, wakeup, GFP_KERNEL);
4155 }
4156
4157 #else
4158
brcmf_report_wowl_wakeind(struct wiphy * wiphy,struct brcmf_if * ifp)4159 static void brcmf_report_wowl_wakeind(struct wiphy *wiphy, struct brcmf_if *ifp)
4160 {
4161 }
4162
4163 #endif /* CONFIG_PM */
4164
brcmf_cfg80211_resume(struct wiphy * wiphy)4165 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
4166 {
4167 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4168 struct net_device *ndev = cfg_to_ndev(cfg);
4169 struct brcmf_if *ifp = netdev_priv(ndev);
4170
4171 brcmf_dbg(TRACE, "Enter\n");
4172
4173 if (cfg->wowl.active) {
4174 brcmf_report_wowl_wakeind(wiphy, ifp);
4175 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
4176 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
4177 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
4178 brcmf_configure_arp_nd_offload(ifp, true);
4179 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
4180 cfg->wowl.pre_pmmode);
4181 cfg->wowl.active = false;
4182 if (cfg->wowl.nd_enabled) {
4183 brcmf_cfg80211_sched_scan_stop(cfg->wiphy, ifp->ndev, 0);
4184 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
4185 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4186 brcmf_notify_sched_scan_results);
4187 cfg->wowl.nd_enabled = false;
4188 }
4189 }
4190 return 0;
4191 }
4192
brcmf_configure_wowl(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp,struct cfg80211_wowlan * wowl)4193 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
4194 struct brcmf_if *ifp,
4195 struct cfg80211_wowlan *wowl)
4196 {
4197 u32 wowl_config;
4198 struct brcmf_wowl_wakeind_le wowl_wakeind;
4199 u32 i;
4200
4201 brcmf_dbg(TRACE, "Suspend, wowl config.\n");
4202
4203 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ARP_ND))
4204 brcmf_configure_arp_nd_offload(ifp, false);
4205 brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->wowl.pre_pmmode);
4206 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
4207
4208 wowl_config = 0;
4209 if (wowl->disconnect)
4210 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
4211 if (wowl->magic_pkt)
4212 wowl_config |= BRCMF_WOWL_MAGIC;
4213 if ((wowl->patterns) && (wowl->n_patterns)) {
4214 wowl_config |= BRCMF_WOWL_NET;
4215 for (i = 0; i < wowl->n_patterns; i++) {
4216 brcmf_config_wowl_pattern(ifp, "add",
4217 (u8 *)wowl->patterns[i].pattern,
4218 wowl->patterns[i].pattern_len,
4219 (u8 *)wowl->patterns[i].mask,
4220 wowl->patterns[i].pkt_offset);
4221 }
4222 }
4223 if (wowl->nd_config) {
4224 brcmf_cfg80211_sched_scan_start(cfg->wiphy, ifp->ndev,
4225 wowl->nd_config);
4226 wowl_config |= BRCMF_WOWL_PFN_FOUND;
4227
4228 cfg->wowl.nd_data_completed = false;
4229 cfg->wowl.nd_enabled = true;
4230 /* Now reroute the event for PFN to the wowl function. */
4231 brcmf_fweh_unregister(cfg->pub, BRCMF_E_PFN_NET_FOUND);
4232 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4233 brcmf_wowl_nd_results);
4234 }
4235 if (wowl->gtk_rekey_failure)
4236 wowl_config |= BRCMF_WOWL_GTK_FAILURE;
4237 if (!test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4238 wowl_config |= BRCMF_WOWL_UNASSOC;
4239
4240 memcpy(&wowl_wakeind, "clear", 6);
4241 brcmf_fil_iovar_data_set(ifp, "wowl_wakeind", &wowl_wakeind,
4242 sizeof(wowl_wakeind));
4243 brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
4244 brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
4245 brcmf_bus_wowl_config(cfg->pub->bus_if, true);
4246 cfg->wowl.active = true;
4247 }
4248
brcmf_keepalive_start(struct brcmf_if * ifp,unsigned int interval)4249 static int brcmf_keepalive_start(struct brcmf_if *ifp, unsigned int interval)
4250 {
4251 struct brcmf_mkeep_alive_pkt_le kalive = {0};
4252 int ret = 0;
4253
4254 /* Configure Null function/data keepalive */
4255 kalive.version = cpu_to_le16(1);
4256 kalive.period_msec = cpu_to_le32(interval * MSEC_PER_SEC);
4257 kalive.len_bytes = cpu_to_le16(0);
4258 kalive.keep_alive_id = 0;
4259
4260 ret = brcmf_fil_iovar_data_set(ifp, "mkeep_alive", &kalive, sizeof(kalive));
4261 if (ret)
4262 brcmf_err("keep-alive packet config failed, ret=%d\n", ret);
4263
4264 return ret;
4265 }
4266
brcmf_cfg80211_suspend(struct wiphy * wiphy,struct cfg80211_wowlan * wowl)4267 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
4268 struct cfg80211_wowlan *wowl)
4269 {
4270 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4271 struct net_device *ndev = cfg_to_ndev(cfg);
4272 struct brcmf_if *ifp = netdev_priv(ndev);
4273 struct brcmf_cfg80211_vif *vif;
4274
4275 brcmf_dbg(TRACE, "Enter\n");
4276
4277 /* if the primary net_device is not READY there is nothing
4278 * we can do but pray resume goes smoothly.
4279 */
4280 if (!check_vif_up(ifp->vif))
4281 goto exit;
4282
4283 /* Stop scheduled scan */
4284 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
4285 brcmf_cfg80211_sched_scan_stop(wiphy, ndev, 0);
4286
4287 /* end any scanning */
4288 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
4289 brcmf_abort_scanning(cfg);
4290
4291 if (wowl == NULL) {
4292 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
4293 list_for_each_entry(vif, &cfg->vif_list, list) {
4294 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
4295 continue;
4296 /* While going to suspend if associated with AP
4297 * disassociate from AP to save power while system is
4298 * in suspended state
4299 */
4300 brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED, true);
4301 /* Make sure WPA_Supplicant receives all the event
4302 * generated due to DISASSOC call to the fw to keep
4303 * the state fw and WPA_Supplicant state consistent
4304 */
4305 brcmf_delay(500);
4306 }
4307 /* Configure MPC */
4308 brcmf_set_mpc(ifp, 1);
4309
4310 } else {
4311 /* Configure WOWL parameters */
4312 brcmf_configure_wowl(cfg, ifp, wowl);
4313
4314 /* Prevent disassociation due to inactivity with keep-alive */
4315 brcmf_keepalive_start(ifp, 30);
4316 }
4317
4318 exit:
4319 brcmf_dbg(TRACE, "Exit\n");
4320 /* clear any scanning activity */
4321 cfg->scan_status = 0;
4322 return 0;
4323 }
4324
4325 static s32
brcmf_pmksa_v3_op(struct brcmf_if * ifp,struct cfg80211_pmksa * pmksa,bool alive)4326 brcmf_pmksa_v3_op(struct brcmf_if *ifp, struct cfg80211_pmksa *pmksa,
4327 bool alive)
4328 {
4329 struct brcmf_pmk_op_v3_le *pmk_op;
4330 int length = offsetof(struct brcmf_pmk_op_v3_le, pmk);
4331 int ret;
4332
4333 pmk_op = kzalloc(sizeof(*pmk_op), GFP_KERNEL);
4334 if (!pmk_op)
4335 return -ENOMEM;
4336
4337 pmk_op->version = cpu_to_le16(BRCMF_PMKSA_VER_3);
4338
4339 if (!pmksa) {
4340 /* Flush operation, operate on entire list */
4341 pmk_op->count = cpu_to_le16(0);
4342 } else {
4343 /* Single PMK operation */
4344 pmk_op->count = cpu_to_le16(1);
4345 length += sizeof(struct brcmf_pmksa_v3);
4346 if (pmksa->bssid)
4347 memcpy(pmk_op->pmk[0].bssid, pmksa->bssid, ETH_ALEN);
4348 if (pmksa->pmkid) {
4349 memcpy(pmk_op->pmk[0].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4350 pmk_op->pmk[0].pmkid_len = WLAN_PMKID_LEN;
4351 }
4352 if (pmksa->ssid && pmksa->ssid_len) {
4353 memcpy(pmk_op->pmk[0].ssid.SSID, pmksa->ssid, pmksa->ssid_len);
4354 pmk_op->pmk[0].ssid.SSID_len = pmksa->ssid_len;
4355 }
4356 pmk_op->pmk[0].time_left = cpu_to_le32(alive ? BRCMF_PMKSA_NO_EXPIRY : 0);
4357 }
4358
4359 pmk_op->length = cpu_to_le16(length);
4360
4361 ret = brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_op, sizeof(*pmk_op));
4362 kfree(pmk_op);
4363 return ret;
4364 }
4365
4366 static __used s32
brcmf_update_pmklist(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp)4367 brcmf_update_pmklist(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp)
4368 {
4369 struct brcmf_pmk_list_le *pmk_list;
4370 int i;
4371 u32 npmk;
4372
4373 pmk_list = &cfg->pmk_list;
4374 npmk = le32_to_cpu(pmk_list->npmk);
4375
4376 brcmf_dbg(CONN, "No of elements %d\n", npmk);
4377 for (i = 0; i < npmk; i++)
4378 brcmf_dbg(CONN, "PMK[%d]: %pM\n", i, &pmk_list->pmk[i].bssid);
4379
4380 return brcmf_fil_iovar_data_set(ifp, "pmkid_info", pmk_list,
4381 sizeof(*pmk_list));
4382 }
4383
4384 static s32
brcmf_cfg80211_set_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)4385 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4386 struct cfg80211_pmksa *pmksa)
4387 {
4388 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4389 struct brcmf_if *ifp = netdev_priv(ndev);
4390 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4391 struct brcmf_pub *drvr = cfg->pub;
4392 s32 err;
4393 u32 npmk, i;
4394
4395 brcmf_dbg(TRACE, "Enter\n");
4396 if (!check_vif_up(ifp->vif))
4397 return -EIO;
4398
4399 brcmf_dbg(CONN, "set_pmksa - PMK bssid: %pM =\n", pmksa->bssid);
4400 brcmf_dbg(CONN, "%*ph\n", WLAN_PMKID_LEN, pmksa->pmkid);
4401
4402 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4403 return brcmf_pmksa_v3_op(ifp, pmksa, true);
4404
4405 /* TODO: implement PMKID_V2 */
4406
4407 npmk = le32_to_cpu(cfg->pmk_list.npmk);
4408 for (i = 0; i < npmk; i++)
4409 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4410 break;
4411 if (i < BRCMF_MAXPMKID) {
4412 memcpy(pmk[i].bssid, pmksa->bssid, ETH_ALEN);
4413 memcpy(pmk[i].pmkid, pmksa->pmkid, WLAN_PMKID_LEN);
4414 if (i == npmk) {
4415 npmk++;
4416 cfg->pmk_list.npmk = cpu_to_le32(npmk);
4417 }
4418 } else {
4419 bphy_err(drvr, "Too many PMKSA entries cached %d\n", npmk);
4420 return -EINVAL;
4421 }
4422
4423 err = brcmf_update_pmklist(cfg, ifp);
4424
4425 brcmf_dbg(TRACE, "Exit\n");
4426 return err;
4427 }
4428
4429 static s32
brcmf_cfg80211_del_pmksa(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_pmksa * pmksa)4430 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
4431 struct cfg80211_pmksa *pmksa)
4432 {
4433 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4434 struct brcmf_if *ifp = netdev_priv(ndev);
4435 struct brcmf_pmksa *pmk = &cfg->pmk_list.pmk[0];
4436 struct brcmf_pub *drvr = cfg->pub;
4437 s32 err;
4438 u32 npmk, i;
4439
4440 brcmf_dbg(TRACE, "Enter\n");
4441 if (!check_vif_up(ifp->vif))
4442 return -EIO;
4443
4444 brcmf_dbg(CONN, "del_pmksa - PMK bssid = %pM\n", pmksa->bssid);
4445
4446 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4447 return brcmf_pmksa_v3_op(ifp, pmksa, false);
4448
4449 /* TODO: implement PMKID_V2 */
4450
4451 npmk = le32_to_cpu(cfg->pmk_list.npmk);
4452 for (i = 0; i < npmk; i++)
4453 if (!memcmp(pmksa->bssid, pmk[i].bssid, ETH_ALEN))
4454 break;
4455
4456 if ((npmk > 0) && (i < npmk)) {
4457 for (; i < (npmk - 1); i++) {
4458 memcpy(&pmk[i].bssid, &pmk[i + 1].bssid, ETH_ALEN);
4459 memcpy(&pmk[i].pmkid, &pmk[i + 1].pmkid,
4460 WLAN_PMKID_LEN);
4461 }
4462 memset(&pmk[i], 0, sizeof(*pmk));
4463 cfg->pmk_list.npmk = cpu_to_le32(npmk - 1);
4464 } else {
4465 bphy_err(drvr, "Cache entry not found\n");
4466 return -EINVAL;
4467 }
4468
4469 err = brcmf_update_pmklist(cfg, ifp);
4470
4471 brcmf_dbg(TRACE, "Exit\n");
4472 return err;
4473
4474 }
4475
4476 static s32
brcmf_cfg80211_flush_pmksa(struct wiphy * wiphy,struct net_device * ndev)4477 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
4478 {
4479 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4480 struct brcmf_if *ifp = netdev_priv(ndev);
4481 s32 err;
4482
4483 brcmf_dbg(TRACE, "Enter\n");
4484 if (!check_vif_up(ifp->vif))
4485 return -EIO;
4486
4487 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PMKID_V3))
4488 return brcmf_pmksa_v3_op(ifp, NULL, false);
4489
4490 /* TODO: implement PMKID_V2 */
4491
4492 memset(&cfg->pmk_list, 0, sizeof(cfg->pmk_list));
4493 err = brcmf_update_pmklist(cfg, ifp);
4494
4495 brcmf_dbg(TRACE, "Exit\n");
4496 return err;
4497
4498 }
4499
brcmf_configure_opensecurity(struct brcmf_if * ifp)4500 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
4501 {
4502 struct brcmf_pub *drvr = ifp->drvr;
4503 s32 err;
4504 s32 wpa_val;
4505
4506 /* set auth */
4507 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
4508 if (err < 0) {
4509 bphy_err(drvr, "auth error %d\n", err);
4510 return err;
4511 }
4512 /* set wsec */
4513 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
4514 if (err < 0) {
4515 bphy_err(drvr, "wsec error %d\n", err);
4516 return err;
4517 }
4518 /* set upper-layer auth */
4519 if (brcmf_is_ibssmode(ifp->vif))
4520 wpa_val = WPA_AUTH_NONE;
4521 else
4522 wpa_val = WPA_AUTH_DISABLED;
4523 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_val);
4524 if (err < 0) {
4525 bphy_err(drvr, "wpa_auth error %d\n", err);
4526 return err;
4527 }
4528
4529 return 0;
4530 }
4531
brcmf_valid_wpa_oui(u8 * oui,bool is_rsn_ie)4532 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
4533 {
4534 if (is_rsn_ie)
4535 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
4536
4537 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
4538 }
4539
4540 static s32
brcmf_configure_wpaie(struct brcmf_if * ifp,const struct brcmf_vs_tlv * wpa_ie,bool is_rsn_ie)4541 brcmf_configure_wpaie(struct brcmf_if *ifp,
4542 const struct brcmf_vs_tlv *wpa_ie,
4543 bool is_rsn_ie)
4544 {
4545 struct brcmf_pub *drvr = ifp->drvr;
4546 u32 auth = 0; /* d11 open authentication */
4547 u16 count;
4548 s32 err = 0;
4549 s32 len;
4550 u32 i;
4551 u32 wsec;
4552 u32 pval = 0;
4553 u32 gval = 0;
4554 u32 wpa_auth = 0;
4555 u32 offset;
4556 u8 *data;
4557 u16 rsn_cap;
4558 u32 wme_bss_disable;
4559 u32 mfp;
4560
4561 brcmf_dbg(TRACE, "Enter\n");
4562 if (wpa_ie == NULL)
4563 goto exit;
4564
4565 len = wpa_ie->len + TLV_HDR_LEN;
4566 data = (u8 *)wpa_ie;
4567 offset = TLV_HDR_LEN;
4568 if (!is_rsn_ie)
4569 offset += VS_IE_FIXED_HDR_LEN;
4570 else
4571 offset += WPA_IE_VERSION_LEN;
4572
4573 /* check for multicast cipher suite */
4574 if (offset + WPA_IE_MIN_OUI_LEN > len) {
4575 err = -EINVAL;
4576 bphy_err(drvr, "no multicast cipher suite\n");
4577 goto exit;
4578 }
4579
4580 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4581 err = -EINVAL;
4582 bphy_err(drvr, "invalid OUI\n");
4583 goto exit;
4584 }
4585 offset += TLV_OUI_LEN;
4586
4587 /* pick up multicast cipher */
4588 switch (data[offset]) {
4589 case WPA_CIPHER_NONE:
4590 gval = 0;
4591 break;
4592 case WPA_CIPHER_WEP_40:
4593 case WPA_CIPHER_WEP_104:
4594 gval = WEP_ENABLED;
4595 break;
4596 case WPA_CIPHER_TKIP:
4597 gval = TKIP_ENABLED;
4598 break;
4599 case WPA_CIPHER_AES_CCM:
4600 gval = AES_ENABLED;
4601 break;
4602 default:
4603 err = -EINVAL;
4604 bphy_err(drvr, "Invalid multi cast cipher info\n");
4605 goto exit;
4606 }
4607
4608 offset++;
4609 /* walk thru unicast cipher list and pick up what we recognize */
4610 count = data[offset] + (data[offset + 1] << 8);
4611 offset += WPA_IE_SUITE_COUNT_LEN;
4612 /* Check for unicast suite(s) */
4613 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4614 err = -EINVAL;
4615 bphy_err(drvr, "no unicast cipher suite\n");
4616 goto exit;
4617 }
4618 for (i = 0; i < count; i++) {
4619 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4620 err = -EINVAL;
4621 bphy_err(drvr, "invalid OUI\n");
4622 goto exit;
4623 }
4624 offset += TLV_OUI_LEN;
4625 switch (data[offset]) {
4626 case WPA_CIPHER_NONE:
4627 break;
4628 case WPA_CIPHER_WEP_40:
4629 case WPA_CIPHER_WEP_104:
4630 pval |= WEP_ENABLED;
4631 break;
4632 case WPA_CIPHER_TKIP:
4633 pval |= TKIP_ENABLED;
4634 break;
4635 case WPA_CIPHER_AES_CCM:
4636 pval |= AES_ENABLED;
4637 break;
4638 default:
4639 bphy_err(drvr, "Invalid unicast security info\n");
4640 }
4641 offset++;
4642 }
4643 /* walk thru auth management suite list and pick up what we recognize */
4644 count = data[offset] + (data[offset + 1] << 8);
4645 offset += WPA_IE_SUITE_COUNT_LEN;
4646 /* Check for auth key management suite(s) */
4647 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
4648 err = -EINVAL;
4649 bphy_err(drvr, "no auth key mgmt suite\n");
4650 goto exit;
4651 }
4652 for (i = 0; i < count; i++) {
4653 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
4654 err = -EINVAL;
4655 bphy_err(drvr, "invalid OUI\n");
4656 goto exit;
4657 }
4658 offset += TLV_OUI_LEN;
4659 switch (data[offset]) {
4660 case RSN_AKM_NONE:
4661 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
4662 wpa_auth |= WPA_AUTH_NONE;
4663 break;
4664 case RSN_AKM_UNSPECIFIED:
4665 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
4666 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
4667 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
4668 break;
4669 case RSN_AKM_PSK:
4670 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
4671 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
4672 (wpa_auth |= WPA_AUTH_PSK);
4673 break;
4674 case RSN_AKM_SHA256_PSK:
4675 brcmf_dbg(TRACE, "RSN_AKM_MFP_PSK\n");
4676 wpa_auth |= WPA2_AUTH_PSK_SHA256;
4677 break;
4678 case RSN_AKM_SHA256_1X:
4679 brcmf_dbg(TRACE, "RSN_AKM_MFP_1X\n");
4680 wpa_auth |= WPA2_AUTH_1X_SHA256;
4681 break;
4682 case RSN_AKM_SAE:
4683 brcmf_dbg(TRACE, "RSN_AKM_SAE\n");
4684 wpa_auth |= WPA3_AUTH_SAE_PSK;
4685 break;
4686 default:
4687 bphy_err(drvr, "Invalid key mgmt info\n");
4688 }
4689 offset++;
4690 }
4691
4692 mfp = BRCMF_MFP_NONE;
4693 if (is_rsn_ie) {
4694 wme_bss_disable = 1;
4695 if ((offset + RSN_CAP_LEN) <= len) {
4696 rsn_cap = data[offset] + (data[offset + 1] << 8);
4697 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
4698 wme_bss_disable = 0;
4699 if (rsn_cap & RSN_CAP_MFPR_MASK) {
4700 brcmf_dbg(TRACE, "MFP Required\n");
4701 mfp = BRCMF_MFP_REQUIRED;
4702 /* Firmware only supports mfp required in
4703 * combination with WPA2_AUTH_PSK_SHA256,
4704 * WPA2_AUTH_1X_SHA256, or WPA3_AUTH_SAE_PSK.
4705 */
4706 if (!(wpa_auth & (WPA2_AUTH_PSK_SHA256 |
4707 WPA2_AUTH_1X_SHA256 |
4708 WPA3_AUTH_SAE_PSK))) {
4709 err = -EINVAL;
4710 goto exit;
4711 }
4712 /* Firmware has requirement that WPA2_AUTH_PSK/
4713 * WPA2_AUTH_UNSPECIFIED be set, if SHA256 OUI
4714 * is to be included in the rsn ie.
4715 */
4716 if (wpa_auth & WPA2_AUTH_PSK_SHA256)
4717 wpa_auth |= WPA2_AUTH_PSK;
4718 else if (wpa_auth & WPA2_AUTH_1X_SHA256)
4719 wpa_auth |= WPA2_AUTH_UNSPECIFIED;
4720 } else if (rsn_cap & RSN_CAP_MFPC_MASK) {
4721 brcmf_dbg(TRACE, "MFP Capable\n");
4722 mfp = BRCMF_MFP_CAPABLE;
4723 }
4724 }
4725 offset += RSN_CAP_LEN;
4726 /* set wme_bss_disable to sync RSN Capabilities */
4727 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
4728 wme_bss_disable);
4729 if (err < 0) {
4730 bphy_err(drvr, "wme_bss_disable error %d\n", err);
4731 goto exit;
4732 }
4733
4734 /* Skip PMKID cnt as it is know to be 0 for AP. */
4735 offset += RSN_PMKID_COUNT_LEN;
4736
4737 /* See if there is BIP wpa suite left for MFP */
4738 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP) &&
4739 ((offset + WPA_IE_MIN_OUI_LEN) <= len)) {
4740 err = brcmf_fil_bsscfg_data_set(ifp, "bip",
4741 &data[offset],
4742 WPA_IE_MIN_OUI_LEN);
4743 if (err < 0) {
4744 bphy_err(drvr, "bip error %d\n", err);
4745 goto exit;
4746 }
4747 }
4748 }
4749 /* FOR WPS , set SES_OW_ENABLED */
4750 wsec = (pval | gval | SES_OW_ENABLED);
4751
4752 /* set auth */
4753 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
4754 if (err < 0) {
4755 bphy_err(drvr, "auth error %d\n", err);
4756 goto exit;
4757 }
4758 /* set wsec */
4759 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
4760 if (err < 0) {
4761 bphy_err(drvr, "wsec error %d\n", err);
4762 goto exit;
4763 }
4764 /* Configure MFP, this needs to go after wsec otherwise the wsec command
4765 * will overwrite the values set by MFP
4766 */
4767 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP)) {
4768 err = brcmf_fil_bsscfg_int_set(ifp, "mfp", mfp);
4769 if (err < 0) {
4770 bphy_err(drvr, "mfp error %d\n", err);
4771 goto exit;
4772 }
4773 }
4774 /* set upper-layer auth */
4775 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
4776 if (err < 0) {
4777 bphy_err(drvr, "wpa_auth error %d\n", err);
4778 goto exit;
4779 }
4780
4781 exit:
4782 return err;
4783 }
4784
4785 static s32
brcmf_parse_vndr_ies(const u8 * vndr_ie_buf,u32 vndr_ie_len,struct parsed_vndr_ies * vndr_ies)4786 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
4787 struct parsed_vndr_ies *vndr_ies)
4788 {
4789 struct brcmf_vs_tlv *vndrie;
4790 struct brcmf_tlv *ie;
4791 struct parsed_vndr_ie_info *parsed_info;
4792 s32 remaining_len;
4793
4794 remaining_len = (s32)vndr_ie_len;
4795 memset(vndr_ies, 0, sizeof(*vndr_ies));
4796
4797 ie = (struct brcmf_tlv *)vndr_ie_buf;
4798 while (ie) {
4799 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
4800 goto next;
4801 vndrie = (struct brcmf_vs_tlv *)ie;
4802 /* len should be bigger than OUI length + one */
4803 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
4804 brcmf_err("invalid vndr ie. length is too small %d\n",
4805 vndrie->len);
4806 goto next;
4807 }
4808 /* if wpa or wme ie, do not add ie */
4809 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
4810 ((vndrie->oui_type == WPA_OUI_TYPE) ||
4811 (vndrie->oui_type == WME_OUI_TYPE))) {
4812 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
4813 goto next;
4814 }
4815
4816 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
4817
4818 /* save vndr ie information */
4819 parsed_info->ie_ptr = (char *)vndrie;
4820 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
4821 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
4822
4823 vndr_ies->count++;
4824
4825 brcmf_dbg(TRACE, "** OUI %3ph, type 0x%02x\n",
4826 parsed_info->vndrie.oui,
4827 parsed_info->vndrie.oui_type);
4828
4829 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
4830 break;
4831 next:
4832 remaining_len -= (ie->len + TLV_HDR_LEN);
4833 if (remaining_len <= TLV_HDR_LEN)
4834 ie = NULL;
4835 else
4836 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
4837 TLV_HDR_LEN);
4838 }
4839 return 0;
4840 }
4841
4842 static u32
brcmf_vndr_ie(u8 * iebuf,s32 pktflag,u8 * ie_ptr,u32 ie_len,s8 * add_del_cmd)4843 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
4844 {
4845 strscpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN);
4846
4847 put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
4848
4849 put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
4850
4851 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
4852
4853 return ie_len + VNDR_IE_HDR_SIZE;
4854 }
4855
brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif * vif,s32 pktflag,const u8 * vndr_ie_buf,u32 vndr_ie_len)4856 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
4857 const u8 *vndr_ie_buf, u32 vndr_ie_len)
4858 {
4859 struct brcmf_pub *drvr;
4860 struct brcmf_if *ifp;
4861 struct vif_saved_ie *saved_ie;
4862 s32 err = 0;
4863 u8 *iovar_ie_buf;
4864 u8 *curr_ie_buf;
4865 u8 *mgmt_ie_buf = NULL;
4866 int mgmt_ie_buf_len;
4867 u32 *mgmt_ie_len;
4868 u32 del_add_ie_buf_len = 0;
4869 u32 total_ie_buf_len = 0;
4870 u32 parsed_ie_buf_len = 0;
4871 struct parsed_vndr_ies old_vndr_ies;
4872 struct parsed_vndr_ies new_vndr_ies;
4873 struct parsed_vndr_ie_info *vndrie_info;
4874 s32 i;
4875 u8 *ptr;
4876 int remained_buf_len;
4877
4878 if (!vif)
4879 return -ENODEV;
4880 ifp = vif->ifp;
4881 drvr = ifp->drvr;
4882 saved_ie = &vif->saved_ie;
4883
4884 brcmf_dbg(TRACE, "bsscfgidx %d, pktflag : 0x%02X\n", ifp->bsscfgidx,
4885 pktflag);
4886 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4887 if (!iovar_ie_buf)
4888 return -ENOMEM;
4889 curr_ie_buf = iovar_ie_buf;
4890 switch (pktflag) {
4891 case BRCMF_VNDR_IE_PRBREQ_FLAG:
4892 mgmt_ie_buf = saved_ie->probe_req_ie;
4893 mgmt_ie_len = &saved_ie->probe_req_ie_len;
4894 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
4895 break;
4896 case BRCMF_VNDR_IE_PRBRSP_FLAG:
4897 mgmt_ie_buf = saved_ie->probe_res_ie;
4898 mgmt_ie_len = &saved_ie->probe_res_ie_len;
4899 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
4900 break;
4901 case BRCMF_VNDR_IE_BEACON_FLAG:
4902 mgmt_ie_buf = saved_ie->beacon_ie;
4903 mgmt_ie_len = &saved_ie->beacon_ie_len;
4904 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
4905 break;
4906 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
4907 mgmt_ie_buf = saved_ie->assoc_req_ie;
4908 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
4909 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
4910 break;
4911 case BRCMF_VNDR_IE_ASSOCRSP_FLAG:
4912 mgmt_ie_buf = saved_ie->assoc_res_ie;
4913 mgmt_ie_len = &saved_ie->assoc_res_ie_len;
4914 mgmt_ie_buf_len = sizeof(saved_ie->assoc_res_ie);
4915 break;
4916 default:
4917 err = -EPERM;
4918 bphy_err(drvr, "not suitable type\n");
4919 goto exit;
4920 }
4921
4922 if (vndr_ie_len > mgmt_ie_buf_len) {
4923 err = -ENOMEM;
4924 bphy_err(drvr, "extra IE size too big\n");
4925 goto exit;
4926 }
4927
4928 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
4929 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
4930 ptr = curr_ie_buf;
4931 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
4932 for (i = 0; i < new_vndr_ies.count; i++) {
4933 vndrie_info = &new_vndr_ies.ie_info[i];
4934 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
4935 vndrie_info->ie_len);
4936 parsed_ie_buf_len += vndrie_info->ie_len;
4937 }
4938 }
4939
4940 if (mgmt_ie_buf && *mgmt_ie_len) {
4941 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
4942 (memcmp(mgmt_ie_buf, curr_ie_buf,
4943 parsed_ie_buf_len) == 0)) {
4944 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
4945 goto exit;
4946 }
4947
4948 /* parse old vndr_ie */
4949 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
4950
4951 /* make a command to delete old ie */
4952 for (i = 0; i < old_vndr_ies.count; i++) {
4953 vndrie_info = &old_vndr_ies.ie_info[i];
4954
4955 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%3ph\n",
4956 vndrie_info->vndrie.id,
4957 vndrie_info->vndrie.len,
4958 vndrie_info->vndrie.oui);
4959
4960 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4961 vndrie_info->ie_ptr,
4962 vndrie_info->ie_len,
4963 "del");
4964 curr_ie_buf += del_add_ie_buf_len;
4965 total_ie_buf_len += del_add_ie_buf_len;
4966 }
4967 }
4968
4969 *mgmt_ie_len = 0;
4970 /* Add if there is any extra IE */
4971 if (mgmt_ie_buf && parsed_ie_buf_len) {
4972 ptr = mgmt_ie_buf;
4973
4974 remained_buf_len = mgmt_ie_buf_len;
4975
4976 /* make a command to add new ie */
4977 for (i = 0; i < new_vndr_ies.count; i++) {
4978 vndrie_info = &new_vndr_ies.ie_info[i];
4979
4980 /* verify remained buf size before copy data */
4981 if (remained_buf_len < (vndrie_info->vndrie.len +
4982 VNDR_IE_VSIE_OFFSET)) {
4983 bphy_err(drvr, "no space in mgmt_ie_buf: len left %d",
4984 remained_buf_len);
4985 break;
4986 }
4987 remained_buf_len -= (vndrie_info->ie_len +
4988 VNDR_IE_VSIE_OFFSET);
4989
4990 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%3ph\n",
4991 vndrie_info->vndrie.id,
4992 vndrie_info->vndrie.len,
4993 vndrie_info->vndrie.oui);
4994
4995 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
4996 vndrie_info->ie_ptr,
4997 vndrie_info->ie_len,
4998 "add");
4999
5000 /* save the parsed IE in wl struct */
5001 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
5002 vndrie_info->ie_len);
5003 *mgmt_ie_len += vndrie_info->ie_len;
5004
5005 curr_ie_buf += del_add_ie_buf_len;
5006 total_ie_buf_len += del_add_ie_buf_len;
5007 }
5008 }
5009 if (total_ie_buf_len) {
5010 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
5011 total_ie_buf_len);
5012 if (err)
5013 bphy_err(drvr, "vndr ie set error : %d\n", err);
5014 }
5015
5016 exit:
5017 kfree(iovar_ie_buf);
5018 return err;
5019 }
5020
brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif * vif)5021 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
5022 {
5023 static const s32 pktflags[] = {
5024 BRCMF_VNDR_IE_PRBRSP_FLAG,
5025 BRCMF_VNDR_IE_BEACON_FLAG
5026 };
5027 int i;
5028
5029 if (vif->wdev.iftype == NL80211_IFTYPE_AP)
5030 brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG, NULL, 0);
5031 else
5032 brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBREQ_FLAG, NULL, 0);
5033
5034 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
5035 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
5036
5037 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
5038 return 0;
5039 }
5040
5041 static s32
brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif * vif,struct cfg80211_beacon_data * beacon)5042 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
5043 struct cfg80211_beacon_data *beacon)
5044 {
5045 struct brcmf_pub *drvr = vif->ifp->drvr;
5046 s32 err;
5047
5048 /* Set Beacon IEs to FW */
5049 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
5050 beacon->tail, beacon->tail_len);
5051 if (err) {
5052 bphy_err(drvr, "Set Beacon IE Failed\n");
5053 return err;
5054 }
5055 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
5056
5057 /* Set Probe Response IEs to FW */
5058 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
5059 beacon->proberesp_ies,
5060 beacon->proberesp_ies_len);
5061 if (err)
5062 bphy_err(drvr, "Set Probe Resp IE Failed\n");
5063 else
5064 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
5065
5066 /* Set Assoc Response IEs to FW */
5067 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_ASSOCRSP_FLAG,
5068 beacon->assocresp_ies,
5069 beacon->assocresp_ies_len);
5070 if (err)
5071 brcmf_err("Set Assoc Resp IE Failed\n");
5072 else
5073 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc Resp\n");
5074
5075 return err;
5076 }
5077
5078 static s32
brcmf_parse_configure_security(struct brcmf_if * ifp,struct cfg80211_ap_settings * settings,enum nl80211_iftype dev_role)5079 brcmf_parse_configure_security(struct brcmf_if *ifp,
5080 struct cfg80211_ap_settings *settings,
5081 enum nl80211_iftype dev_role)
5082 {
5083 const struct brcmf_tlv *rsn_ie;
5084 const struct brcmf_vs_tlv *wpa_ie;
5085 s32 err = 0;
5086
5087 /* find the RSN_IE */
5088 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
5089 settings->beacon.tail_len, WLAN_EID_RSN);
5090
5091 /* find the WPA_IE */
5092 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
5093 settings->beacon.tail_len);
5094
5095 if (wpa_ie || rsn_ie) {
5096 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
5097 if (wpa_ie) {
5098 /* WPA IE */
5099 err = brcmf_configure_wpaie(ifp, wpa_ie, false);
5100 if (err < 0)
5101 return err;
5102 } else {
5103 struct brcmf_vs_tlv *tmp_ie;
5104
5105 tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
5106
5107 /* RSN IE */
5108 err = brcmf_configure_wpaie(ifp, tmp_ie, true);
5109 if (err < 0)
5110 return err;
5111 }
5112 } else {
5113 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
5114 brcmf_configure_opensecurity(ifp);
5115 }
5116
5117 return err;
5118 }
5119
5120 static s32
brcmf_cfg80211_start_ap(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ap_settings * settings)5121 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
5122 struct cfg80211_ap_settings *settings)
5123 {
5124 s32 ie_offset;
5125 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5126 struct brcmf_if *ifp = netdev_priv(ndev);
5127 struct brcmf_pub *drvr = cfg->pub;
5128 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5129 struct cfg80211_crypto_settings *crypto = &settings->crypto;
5130 const struct brcmf_tlv *ssid_ie;
5131 const struct brcmf_tlv *country_ie;
5132 struct brcmf_ssid_le ssid_le;
5133 s32 err = -EPERM;
5134 struct brcmf_join_params join_params;
5135 enum nl80211_iftype dev_role;
5136 struct brcmf_fil_bss_enable_le bss_enable;
5137 u16 chanspec = chandef_to_chanspec(&cfg->d11inf, &settings->chandef);
5138 bool mbss;
5139 int is_11d;
5140 bool supports_11d;
5141 bool closednet;
5142
5143 brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
5144 settings->chandef.chan->hw_value,
5145 settings->chandef.center_freq1, settings->chandef.width,
5146 settings->beacon_interval, settings->dtim_period);
5147 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
5148 settings->ssid, settings->ssid_len, settings->auth_type,
5149 settings->inactivity_timeout);
5150 dev_role = ifp->vif->wdev.iftype;
5151 mbss = ifp->vif->mbss;
5152
5153 /* store current 11d setting */
5154 if (brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY,
5155 &ifp->vif->is_11d)) {
5156 is_11d = supports_11d = false;
5157 } else {
5158 country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
5159 settings->beacon.tail_len,
5160 WLAN_EID_COUNTRY);
5161 is_11d = country_ie ? 1 : 0;
5162 supports_11d = true;
5163 }
5164
5165 memset(&ssid_le, 0, sizeof(ssid_le));
5166 if (settings->ssid == NULL || settings->ssid_len == 0) {
5167 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
5168 ssid_ie = brcmf_parse_tlvs(
5169 (u8 *)&settings->beacon.head[ie_offset],
5170 settings->beacon.head_len - ie_offset,
5171 WLAN_EID_SSID);
5172 if (!ssid_ie || ssid_ie->len > IEEE80211_MAX_SSID_LEN)
5173 return -EINVAL;
5174
5175 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
5176 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
5177 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
5178 } else {
5179 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
5180 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
5181 }
5182
5183 if (!mbss) {
5184 brcmf_set_mpc(ifp, 0);
5185 brcmf_configure_arp_nd_offload(ifp, false);
5186 }
5187
5188 /* Parameters shared by all radio interfaces */
5189 if (!mbss) {
5190 if ((supports_11d) && (is_11d != ifp->vif->is_11d)) {
5191 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
5192 is_11d);
5193 if (err < 0) {
5194 bphy_err(drvr, "Regulatory Set Error, %d\n",
5195 err);
5196 goto exit;
5197 }
5198 }
5199 if (settings->beacon_interval) {
5200 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
5201 settings->beacon_interval);
5202 if (err < 0) {
5203 bphy_err(drvr, "Beacon Interval Set Error, %d\n",
5204 err);
5205 goto exit;
5206 }
5207 }
5208 if (settings->dtim_period) {
5209 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
5210 settings->dtim_period);
5211 if (err < 0) {
5212 bphy_err(drvr, "DTIM Interval Set Error, %d\n",
5213 err);
5214 goto exit;
5215 }
5216 }
5217
5218 if ((dev_role == NL80211_IFTYPE_AP) &&
5219 ((ifp->ifidx == 0) ||
5220 (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB) &&
5221 !brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN)))) {
5222 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5223 if (err < 0) {
5224 bphy_err(drvr, "BRCMF_C_DOWN error %d\n",
5225 err);
5226 goto exit;
5227 }
5228 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
5229 }
5230
5231 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
5232 if (err < 0) {
5233 bphy_err(drvr, "SET INFRA error %d\n", err);
5234 goto exit;
5235 }
5236 } else if (WARN_ON(supports_11d && (is_11d != ifp->vif->is_11d))) {
5237 /* Multiple-BSS should use same 11d configuration */
5238 err = -EINVAL;
5239 goto exit;
5240 }
5241
5242 /* Interface specific setup */
5243 if (dev_role == NL80211_IFTYPE_AP) {
5244 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
5245 brcmf_fil_iovar_int_set(ifp, "mbss", 1);
5246
5247 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
5248 if (err < 0) {
5249 bphy_err(drvr, "setting AP mode failed %d\n",
5250 err);
5251 goto exit;
5252 }
5253 if (!mbss) {
5254 /* Firmware 10.x requires setting channel after enabling
5255 * AP and before bringing interface up.
5256 */
5257 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
5258 if (err < 0) {
5259 bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
5260 chanspec, err);
5261 goto exit;
5262 }
5263 }
5264 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
5265 if (err < 0) {
5266 bphy_err(drvr, "BRCMF_C_UP error (%d)\n", err);
5267 goto exit;
5268 }
5269
5270 if (crypto->psk) {
5271 brcmf_dbg(INFO, "using PSK offload\n");
5272 profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_PSK);
5273 err = brcmf_set_pmk(ifp, crypto->psk,
5274 BRCMF_WSEC_MAX_PSK_LEN);
5275 if (err < 0)
5276 goto exit;
5277 }
5278 if (crypto->sae_pwd) {
5279 brcmf_dbg(INFO, "using SAE offload\n");
5280 profile->use_fwauth |= BIT(BRCMF_PROFILE_FWAUTH_SAE);
5281 err = brcmf_fwvid_set_sae_password(ifp, crypto);
5282 if (err < 0)
5283 goto exit;
5284 }
5285 if (profile->use_fwauth == 0)
5286 profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
5287
5288 err = brcmf_parse_configure_security(ifp, settings,
5289 NL80211_IFTYPE_AP);
5290 if (err < 0) {
5291 bphy_err(drvr, "brcmf_parse_configure_security error\n");
5292 goto exit;
5293 }
5294
5295 /* On DOWN the firmware removes the WEP keys, reconfigure
5296 * them if they were set.
5297 */
5298 brcmf_cfg80211_reconfigure_wep(ifp);
5299
5300 memset(&join_params, 0, sizeof(join_params));
5301 /* join parameters starts with ssid */
5302 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
5303 /* create softap */
5304 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
5305 &join_params, sizeof(join_params));
5306 if (err < 0) {
5307 bphy_err(drvr, "SET SSID error (%d)\n", err);
5308 goto exit;
5309 }
5310
5311 closednet =
5312 (settings->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE);
5313 err = brcmf_fil_iovar_int_set(ifp, "closednet", closednet);
5314 if (err) {
5315 bphy_err(drvr, "%s closednet error (%d)\n",
5316 (closednet ? "enabled" : "disabled"),
5317 err);
5318 goto exit;
5319 }
5320
5321 brcmf_dbg(TRACE, "AP mode configuration complete\n");
5322 } else if (dev_role == NL80211_IFTYPE_P2P_GO) {
5323 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
5324 if (err < 0) {
5325 bphy_err(drvr, "Set Channel failed: chspec=%d, %d\n",
5326 chanspec, err);
5327 goto exit;
5328 }
5329
5330 err = brcmf_parse_configure_security(ifp, settings,
5331 NL80211_IFTYPE_P2P_GO);
5332 if (err < 0) {
5333 brcmf_err("brcmf_parse_configure_security error\n");
5334 goto exit;
5335 }
5336
5337 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
5338 sizeof(ssid_le));
5339 if (err < 0) {
5340 bphy_err(drvr, "setting ssid failed %d\n", err);
5341 goto exit;
5342 }
5343 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
5344 bss_enable.enable = cpu_to_le32(1);
5345 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
5346 sizeof(bss_enable));
5347 if (err < 0) {
5348 bphy_err(drvr, "bss_enable config failed %d\n", err);
5349 goto exit;
5350 }
5351
5352 brcmf_dbg(TRACE, "GO mode configuration complete\n");
5353 } else {
5354 WARN_ON(1);
5355 }
5356
5357 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
5358 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
5359 brcmf_net_setcarrier(ifp, true);
5360
5361 exit:
5362 if ((err) && (!mbss)) {
5363 brcmf_set_mpc(ifp, 1);
5364 brcmf_configure_arp_nd_offload(ifp, true);
5365 }
5366 return err;
5367 }
5368
brcmf_cfg80211_stop_ap(struct wiphy * wiphy,struct net_device * ndev,unsigned int link_id)5369 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev,
5370 unsigned int link_id)
5371 {
5372 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5373 struct brcmf_if *ifp = netdev_priv(ndev);
5374 struct brcmf_pub *drvr = cfg->pub;
5375 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
5376 s32 err;
5377 struct brcmf_fil_bss_enable_le bss_enable;
5378 struct brcmf_join_params join_params;
5379
5380 brcmf_dbg(TRACE, "Enter\n");
5381
5382 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
5383 /* Due to most likely deauths outstanding we sleep */
5384 /* first to make sure they get processed by fw. */
5385 msleep(400);
5386
5387 if (profile->use_fwauth != BIT(BRCMF_PROFILE_FWAUTH_NONE)) {
5388 struct cfg80211_crypto_settings crypto = {};
5389
5390 if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_PSK))
5391 brcmf_set_pmk(ifp, NULL, 0);
5392 if (profile->use_fwauth & BIT(BRCMF_PROFILE_FWAUTH_SAE))
5393 brcmf_fwvid_set_sae_password(ifp, &crypto);
5394 profile->use_fwauth = BIT(BRCMF_PROFILE_FWAUTH_NONE);
5395 }
5396
5397 if (ifp->vif->mbss) {
5398 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5399 return err;
5400 }
5401
5402 /* First BSS doesn't get a full reset */
5403 if (ifp->bsscfgidx == 0)
5404 brcmf_fil_iovar_int_set(ifp, "closednet", 0);
5405
5406 memset(&join_params, 0, sizeof(join_params));
5407 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
5408 &join_params, sizeof(join_params));
5409 if (err < 0)
5410 bphy_err(drvr, "SET SSID error (%d)\n", err);
5411 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
5412 if (err < 0)
5413 bphy_err(drvr, "BRCMF_C_DOWN error %d\n", err);
5414 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
5415 if (err < 0)
5416 bphy_err(drvr, "setting AP mode failed %d\n", err);
5417 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
5418 brcmf_fil_iovar_int_set(ifp, "mbss", 0);
5419 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
5420 ifp->vif->is_11d);
5421 /* Bring device back up so it can be used again */
5422 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
5423 if (err < 0)
5424 bphy_err(drvr, "BRCMF_C_UP error %d\n", err);
5425
5426 brcmf_vif_clear_mgmt_ies(ifp->vif);
5427 } else {
5428 bss_enable.bsscfgidx = cpu_to_le32(ifp->bsscfgidx);
5429 bss_enable.enable = cpu_to_le32(0);
5430 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
5431 sizeof(bss_enable));
5432 if (err < 0)
5433 bphy_err(drvr, "bss_enable config failed %d\n", err);
5434 }
5435 brcmf_set_mpc(ifp, 1);
5436 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
5437 brcmf_configure_arp_nd_offload(ifp, true);
5438 brcmf_net_setcarrier(ifp, false);
5439
5440 return err;
5441 }
5442
5443 static s32
brcmf_cfg80211_change_beacon(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_ap_update * info)5444 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
5445 struct cfg80211_ap_update *info)
5446 {
5447 struct brcmf_if *ifp = netdev_priv(ndev);
5448
5449 brcmf_dbg(TRACE, "Enter\n");
5450
5451 return brcmf_config_ap_mgmt_ie(ifp->vif, &info->beacon);
5452 }
5453
5454 static int
brcmf_cfg80211_del_station(struct wiphy * wiphy,struct net_device * ndev,struct station_del_parameters * params)5455 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
5456 struct station_del_parameters *params)
5457 {
5458 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5459 struct brcmf_pub *drvr = cfg->pub;
5460 struct brcmf_scb_val_le scbval;
5461 struct brcmf_if *ifp = netdev_priv(ndev);
5462 s32 err;
5463
5464 if (!params->mac)
5465 return -EFAULT;
5466
5467 brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
5468
5469 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
5470 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
5471 if (!check_vif_up(ifp->vif))
5472 return -EIO;
5473
5474 memcpy(&scbval.ea, params->mac, ETH_ALEN);
5475 scbval.val = cpu_to_le32(params->reason_code);
5476 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
5477 &scbval, sizeof(scbval));
5478 if (err)
5479 bphy_err(drvr, "SCB_DEAUTHENTICATE_FOR_REASON failed %d\n",
5480 err);
5481
5482 brcmf_dbg(TRACE, "Exit\n");
5483 return err;
5484 }
5485
5486 static int
brcmf_cfg80211_change_station(struct wiphy * wiphy,struct net_device * ndev,const u8 * mac,struct station_parameters * params)5487 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
5488 const u8 *mac, struct station_parameters *params)
5489 {
5490 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5491 struct brcmf_pub *drvr = cfg->pub;
5492 struct brcmf_if *ifp = netdev_priv(ndev);
5493 s32 err;
5494
5495 brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
5496 params->sta_flags_mask, params->sta_flags_set);
5497
5498 /* Ignore all 00 MAC */
5499 if (is_zero_ether_addr(mac))
5500 return 0;
5501
5502 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
5503 return 0;
5504
5505 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
5506 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
5507 (void *)mac, ETH_ALEN);
5508 else
5509 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
5510 (void *)mac, ETH_ALEN);
5511 if (err < 0)
5512 bphy_err(drvr, "Setting SCB (de-)authorize failed, %d\n", err);
5513
5514 return err;
5515 }
5516
5517 static void
brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy * wiphy,struct wireless_dev * wdev,struct mgmt_frame_regs * upd)5518 brcmf_cfg80211_update_mgmt_frame_registrations(struct wiphy *wiphy,
5519 struct wireless_dev *wdev,
5520 struct mgmt_frame_regs *upd)
5521 {
5522 struct brcmf_cfg80211_vif *vif;
5523
5524 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5525
5526 vif->mgmt_rx_reg = upd->interface_stypes;
5527 }
5528
5529
5530 int
brcmf_cfg80211_mgmt_tx(struct wiphy * wiphy,struct wireless_dev * wdev,struct cfg80211_mgmt_tx_params * params,u64 * cookie)5531 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
5532 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
5533 {
5534 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5535 struct ieee80211_channel *chan = params->chan;
5536 struct brcmf_pub *drvr = cfg->pub;
5537 const u8 *buf = params->buf;
5538 size_t len = params->len;
5539 const struct ieee80211_mgmt *mgmt;
5540 struct brcmf_cfg80211_vif *vif;
5541 s32 err = 0;
5542 s32 ie_offset;
5543 s32 ie_len;
5544 struct brcmf_fil_action_frame_le *action_frame;
5545 struct brcmf_fil_af_params_le *af_params;
5546 bool ack;
5547 __le32 hw_ch;
5548
5549 brcmf_dbg(TRACE, "Enter\n");
5550
5551 *cookie = 0;
5552
5553 mgmt = (const struct ieee80211_mgmt *)buf;
5554
5555 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
5556 bphy_err(drvr, "Driver only allows MGMT packet type\n");
5557 return -EPERM;
5558 }
5559
5560 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5561
5562 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
5563 /* Right now the only reason to get a probe response */
5564 /* is for p2p listen response or for p2p GO from */
5565 /* wpa_supplicant. Unfortunately the probe is send */
5566 /* on primary ndev, while dongle wants it on the p2p */
5567 /* vif. Since this is only reason for a probe */
5568 /* response to be sent, the vif is taken from cfg. */
5569 /* If ever desired to send proberesp for non p2p */
5570 /* response then data should be checked for */
5571 /* "DIRECT-". Note in future supplicant will take */
5572 /* dedicated p2p wdev to do this and then this 'hack'*/
5573 /* is not needed anymore. */
5574 ie_offset = DOT11_MGMT_HDR_LEN +
5575 DOT11_BCN_PRB_FIXED_LEN;
5576 ie_len = len - ie_offset;
5577 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
5578 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5579 err = brcmf_vif_set_mgmt_ie(vif,
5580 BRCMF_VNDR_IE_PRBRSP_FLAG,
5581 &buf[ie_offset],
5582 ie_len);
5583 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
5584 GFP_KERNEL);
5585 } else if (ieee80211_is_action(mgmt->frame_control)) {
5586 if (len > BRCMF_FIL_ACTION_FRAME_SIZE + DOT11_MGMT_HDR_LEN) {
5587 bphy_err(drvr, "invalid action frame length\n");
5588 err = -EINVAL;
5589 goto exit;
5590 }
5591 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
5592 if (af_params == NULL) {
5593 bphy_err(drvr, "unable to allocate frame\n");
5594 err = -ENOMEM;
5595 goto exit;
5596 }
5597 action_frame = &af_params->action_frame;
5598 /* Add the packet Id */
5599 action_frame->packet_id = cpu_to_le32(*cookie);
5600 /* Add BSSID */
5601 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
5602 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
5603 /* Add the length exepted for 802.11 header */
5604 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
5605 /* Add the channel. Use the one specified as parameter if any or
5606 * the current one (got from the firmware) otherwise
5607 */
5608 if (chan) {
5609 hw_ch = cpu_to_le32(chan->hw_value);
5610 } else {
5611 err = brcmf_fil_cmd_data_get(vif->ifp,
5612 BRCMF_C_GET_CHANNEL,
5613 &hw_ch, sizeof(hw_ch));
5614 if (err) {
5615 bphy_err(drvr,
5616 "unable to get current hw channel\n");
5617 goto free;
5618 }
5619 }
5620 af_params->channel = hw_ch;
5621
5622 af_params->dwell_time = cpu_to_le32(params->wait);
5623 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
5624 le16_to_cpu(action_frame->len));
5625
5626 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, channel=%d\n",
5627 *cookie, le16_to_cpu(action_frame->len),
5628 le32_to_cpu(af_params->channel));
5629
5630 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
5631 af_params);
5632
5633 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
5634 GFP_KERNEL);
5635 free:
5636 kfree(af_params);
5637 } else {
5638 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
5639 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len);
5640 }
5641
5642 exit:
5643 return err;
5644 }
5645 BRCMF_EXPORT_SYMBOL_GPL(brcmf_cfg80211_mgmt_tx);
5646
brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy * wiphy,struct net_device * ndev,s32 rssi_low,s32 rssi_high)5647 static int brcmf_cfg80211_set_cqm_rssi_range_config(struct wiphy *wiphy,
5648 struct net_device *ndev,
5649 s32 rssi_low, s32 rssi_high)
5650 {
5651 struct brcmf_cfg80211_vif *vif;
5652 struct brcmf_if *ifp;
5653 int err = 0;
5654
5655 brcmf_dbg(TRACE, "low=%d high=%d", rssi_low, rssi_high);
5656
5657 ifp = netdev_priv(ndev);
5658 vif = ifp->vif;
5659
5660 if (rssi_low != vif->cqm_rssi_low || rssi_high != vif->cqm_rssi_high) {
5661 /* The firmware will send an event when the RSSI is less than or
5662 * equal to a configured level and the previous RSSI event was
5663 * less than or equal to a different level. Set a third level
5664 * so that we also detect the transition from rssi <= rssi_high
5665 * to rssi > rssi_high.
5666 */
5667 struct brcmf_rssi_event_le config = {
5668 .rate_limit_msec = cpu_to_le32(0),
5669 .rssi_level_num = 3,
5670 .rssi_levels = {
5671 clamp_val(rssi_low, S8_MIN, S8_MAX - 2),
5672 clamp_val(rssi_high, S8_MIN + 1, S8_MAX - 1),
5673 S8_MAX,
5674 },
5675 };
5676
5677 err = brcmf_fil_iovar_data_set(ifp, "rssi_event", &config,
5678 sizeof(config));
5679 if (err) {
5680 err = -EINVAL;
5681 } else {
5682 vif->cqm_rssi_low = rssi_low;
5683 vif->cqm_rssi_high = rssi_high;
5684 }
5685 }
5686
5687 return err;
5688 }
5689
5690 static int
brcmf_cfg80211_cancel_remain_on_channel(struct wiphy * wiphy,struct wireless_dev * wdev,u64 cookie)5691 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
5692 struct wireless_dev *wdev,
5693 u64 cookie)
5694 {
5695 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5696 struct brcmf_pub *drvr = cfg->pub;
5697 struct brcmf_cfg80211_vif *vif;
5698 int err = 0;
5699
5700 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
5701
5702 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
5703 if (vif == NULL) {
5704 bphy_err(drvr, "No p2p device available for probe response\n");
5705 err = -ENODEV;
5706 goto exit;
5707 }
5708 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
5709 exit:
5710 return err;
5711 }
5712
brcmf_cfg80211_get_channel(struct wiphy * wiphy,struct wireless_dev * wdev,unsigned int link_id,struct cfg80211_chan_def * chandef)5713 static int brcmf_cfg80211_get_channel(struct wiphy *wiphy,
5714 struct wireless_dev *wdev,
5715 unsigned int link_id,
5716 struct cfg80211_chan_def *chandef)
5717 {
5718 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5719 struct net_device *ndev = wdev->netdev;
5720 struct brcmf_pub *drvr = cfg->pub;
5721 struct brcmu_chan ch;
5722 enum nl80211_band band = 0;
5723 enum nl80211_chan_width width = 0;
5724 u32 chanspec;
5725 int freq, err;
5726
5727 if (!ndev || drvr->bus_if->state != BRCMF_BUS_UP)
5728 return -ENODEV;
5729
5730 err = brcmf_fil_iovar_int_get(netdev_priv(ndev), "chanspec", &chanspec);
5731 if (err) {
5732 bphy_err(drvr, "chanspec failed (%d)\n", err);
5733 return err;
5734 }
5735
5736 ch.chspec = chanspec;
5737 cfg->d11inf.decchspec(&ch);
5738
5739 switch (ch.band) {
5740 case BRCMU_CHAN_BAND_2G:
5741 band = NL80211_BAND_2GHZ;
5742 break;
5743 case BRCMU_CHAN_BAND_5G:
5744 band = NL80211_BAND_5GHZ;
5745 break;
5746 }
5747
5748 switch (ch.bw) {
5749 case BRCMU_CHAN_BW_80:
5750 width = NL80211_CHAN_WIDTH_80;
5751 break;
5752 case BRCMU_CHAN_BW_40:
5753 width = NL80211_CHAN_WIDTH_40;
5754 break;
5755 case BRCMU_CHAN_BW_20:
5756 width = NL80211_CHAN_WIDTH_20;
5757 break;
5758 case BRCMU_CHAN_BW_80P80:
5759 width = NL80211_CHAN_WIDTH_80P80;
5760 break;
5761 case BRCMU_CHAN_BW_160:
5762 width = NL80211_CHAN_WIDTH_160;
5763 break;
5764 }
5765
5766 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band);
5767 chandef->chan = ieee80211_get_channel(wiphy, freq);
5768 chandef->width = width;
5769 chandef->center_freq1 = ieee80211_channel_to_frequency(ch.chnum, band);
5770 chandef->center_freq2 = 0;
5771
5772 return 0;
5773 }
5774
brcmf_cfg80211_crit_proto_start(struct wiphy * wiphy,struct wireless_dev * wdev,enum nl80211_crit_proto_id proto,u16 duration)5775 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
5776 struct wireless_dev *wdev,
5777 enum nl80211_crit_proto_id proto,
5778 u16 duration)
5779 {
5780 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5781 struct brcmf_cfg80211_vif *vif;
5782
5783 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5784
5785 /* only DHCP support for now */
5786 if (proto != NL80211_CRIT_PROTO_DHCP)
5787 return -EINVAL;
5788
5789 /* suppress and abort scanning */
5790 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5791 brcmf_abort_scanning(cfg);
5792
5793 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
5794 }
5795
brcmf_cfg80211_crit_proto_stop(struct wiphy * wiphy,struct wireless_dev * wdev)5796 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
5797 struct wireless_dev *wdev)
5798 {
5799 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5800 struct brcmf_cfg80211_vif *vif;
5801
5802 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
5803
5804 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
5805 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
5806 }
5807
5808 static s32
brcmf_notify_tdls_peer_event(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)5809 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
5810 const struct brcmf_event_msg *e, void *data)
5811 {
5812 switch (e->reason) {
5813 case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
5814 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
5815 break;
5816 case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
5817 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
5818 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5819 break;
5820 case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
5821 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
5822 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
5823 break;
5824 }
5825
5826 return 0;
5827 }
5828
brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)5829 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
5830 {
5831 int ret;
5832
5833 switch (oper) {
5834 case NL80211_TDLS_DISCOVERY_REQ:
5835 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
5836 break;
5837 case NL80211_TDLS_SETUP:
5838 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
5839 break;
5840 case NL80211_TDLS_TEARDOWN:
5841 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
5842 break;
5843 default:
5844 brcmf_err("unsupported operation: %d\n", oper);
5845 ret = -EOPNOTSUPP;
5846 }
5847 return ret;
5848 }
5849
brcmf_cfg80211_tdls_oper(struct wiphy * wiphy,struct net_device * ndev,const u8 * peer,enum nl80211_tdls_operation oper)5850 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
5851 struct net_device *ndev, const u8 *peer,
5852 enum nl80211_tdls_operation oper)
5853 {
5854 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5855 struct brcmf_pub *drvr = cfg->pub;
5856 struct brcmf_if *ifp;
5857 struct brcmf_tdls_iovar_le info;
5858 int ret = 0;
5859
5860 ret = brcmf_convert_nl80211_tdls_oper(oper);
5861 if (ret < 0)
5862 return ret;
5863
5864 ifp = netdev_priv(ndev);
5865 memset(&info, 0, sizeof(info));
5866 info.mode = (u8)ret;
5867 if (peer)
5868 memcpy(info.ea, peer, ETH_ALEN);
5869
5870 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
5871 &info, sizeof(info));
5872 if (ret < 0)
5873 bphy_err(drvr, "tdls_endpoint iovar failed: ret=%d\n", ret);
5874
5875 return ret;
5876 }
5877
5878 static int
brcmf_cfg80211_update_conn_params(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_connect_params * sme,u32 changed)5879 brcmf_cfg80211_update_conn_params(struct wiphy *wiphy,
5880 struct net_device *ndev,
5881 struct cfg80211_connect_params *sme,
5882 u32 changed)
5883 {
5884 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5885 struct brcmf_pub *drvr = cfg->pub;
5886 struct brcmf_if *ifp;
5887 int err;
5888
5889 if (!(changed & UPDATE_ASSOC_IES))
5890 return 0;
5891
5892 ifp = netdev_priv(ndev);
5893 err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
5894 sme->ie, sme->ie_len);
5895 if (err)
5896 bphy_err(drvr, "Set Assoc REQ IE Failed\n");
5897 else
5898 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
5899
5900 return err;
5901 }
5902
5903 #ifdef CONFIG_PM
5904 static int
brcmf_cfg80211_set_rekey_data(struct wiphy * wiphy,struct net_device * ndev,struct cfg80211_gtk_rekey_data * gtk)5905 brcmf_cfg80211_set_rekey_data(struct wiphy *wiphy, struct net_device *ndev,
5906 struct cfg80211_gtk_rekey_data *gtk)
5907 {
5908 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
5909 struct brcmf_pub *drvr = cfg->pub;
5910 struct brcmf_if *ifp = netdev_priv(ndev);
5911 struct brcmf_gtk_keyinfo_le gtk_le;
5912 int ret;
5913
5914 brcmf_dbg(TRACE, "Enter, bssidx=%d\n", ifp->bsscfgidx);
5915
5916 memcpy(gtk_le.kck, gtk->kck, sizeof(gtk_le.kck));
5917 memcpy(gtk_le.kek, gtk->kek, sizeof(gtk_le.kek));
5918 memcpy(gtk_le.replay_counter, gtk->replay_ctr,
5919 sizeof(gtk_le.replay_counter));
5920
5921 ret = brcmf_fil_iovar_data_set(ifp, "gtk_key_info", >k_le,
5922 sizeof(gtk_le));
5923 if (ret < 0)
5924 bphy_err(drvr, "gtk_key_info iovar failed: ret=%d\n", ret);
5925
5926 return ret;
5927 }
5928 #endif
5929
brcmf_cfg80211_set_pmk(struct wiphy * wiphy,struct net_device * dev,const struct cfg80211_pmk_conf * conf)5930 static int brcmf_cfg80211_set_pmk(struct wiphy *wiphy, struct net_device *dev,
5931 const struct cfg80211_pmk_conf *conf)
5932 {
5933 struct brcmf_if *ifp;
5934
5935 brcmf_dbg(TRACE, "enter\n");
5936
5937 /* expect using firmware supplicant for 1X */
5938 ifp = netdev_priv(dev);
5939 if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5940 return -EINVAL;
5941
5942 if (conf->pmk_len > BRCMF_WSEC_MAX_PSK_LEN)
5943 return -ERANGE;
5944
5945 return brcmf_set_pmk(ifp, conf->pmk, conf->pmk_len);
5946 }
5947
brcmf_cfg80211_del_pmk(struct wiphy * wiphy,struct net_device * dev,const u8 * aa)5948 static int brcmf_cfg80211_del_pmk(struct wiphy *wiphy, struct net_device *dev,
5949 const u8 *aa)
5950 {
5951 struct brcmf_if *ifp;
5952
5953 brcmf_dbg(TRACE, "enter\n");
5954 ifp = netdev_priv(dev);
5955 if (WARN_ON(ifp->vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_1X))
5956 return -EINVAL;
5957
5958 return brcmf_set_pmk(ifp, NULL, 0);
5959 }
5960
5961 static struct cfg80211_ops brcmf_cfg80211_ops = {
5962 .add_virtual_intf = brcmf_cfg80211_add_iface,
5963 .del_virtual_intf = brcmf_cfg80211_del_iface,
5964 .change_virtual_intf = brcmf_cfg80211_change_iface,
5965 .scan = brcmf_cfg80211_scan,
5966 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
5967 .join_ibss = brcmf_cfg80211_join_ibss,
5968 .leave_ibss = brcmf_cfg80211_leave_ibss,
5969 .get_station = brcmf_cfg80211_get_station,
5970 .dump_station = brcmf_cfg80211_dump_station,
5971 .set_tx_power = brcmf_cfg80211_set_tx_power,
5972 .get_tx_power = brcmf_cfg80211_get_tx_power,
5973 .add_key = brcmf_cfg80211_add_key,
5974 .del_key = brcmf_cfg80211_del_key,
5975 .get_key = brcmf_cfg80211_get_key,
5976 .set_default_key = brcmf_cfg80211_config_default_key,
5977 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
5978 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
5979 .connect = brcmf_cfg80211_connect,
5980 .disconnect = brcmf_cfg80211_disconnect,
5981 .suspend = brcmf_cfg80211_suspend,
5982 .resume = brcmf_cfg80211_resume,
5983 .set_pmksa = brcmf_cfg80211_set_pmksa,
5984 .del_pmksa = brcmf_cfg80211_del_pmksa,
5985 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
5986 .start_ap = brcmf_cfg80211_start_ap,
5987 .stop_ap = brcmf_cfg80211_stop_ap,
5988 .change_beacon = brcmf_cfg80211_change_beacon,
5989 .del_station = brcmf_cfg80211_del_station,
5990 .change_station = brcmf_cfg80211_change_station,
5991 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
5992 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
5993 .update_mgmt_frame_registrations =
5994 brcmf_cfg80211_update_mgmt_frame_registrations,
5995 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
5996 .set_cqm_rssi_range_config = brcmf_cfg80211_set_cqm_rssi_range_config,
5997 .remain_on_channel = brcmf_p2p_remain_on_channel,
5998 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
5999 .get_channel = brcmf_cfg80211_get_channel,
6000 .start_p2p_device = brcmf_p2p_start_device,
6001 .stop_p2p_device = brcmf_p2p_stop_device,
6002 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
6003 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
6004 .tdls_oper = brcmf_cfg80211_tdls_oper,
6005 .update_connect_params = brcmf_cfg80211_update_conn_params,
6006 .set_pmk = brcmf_cfg80211_set_pmk,
6007 .del_pmk = brcmf_cfg80211_del_pmk,
6008 };
6009
brcmf_cfg80211_get_ops(struct brcmf_mp_device * settings)6010 struct cfg80211_ops *brcmf_cfg80211_get_ops(struct brcmf_mp_device *settings)
6011 {
6012 struct cfg80211_ops *ops;
6013
6014 ops = kmemdup(&brcmf_cfg80211_ops, sizeof(brcmf_cfg80211_ops),
6015 GFP_KERNEL);
6016
6017 if (ops && settings->roamoff)
6018 ops->update_connect_params = NULL;
6019
6020 return ops;
6021 }
6022
brcmf_alloc_vif(struct brcmf_cfg80211_info * cfg,enum nl80211_iftype type)6023 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
6024 enum nl80211_iftype type)
6025 {
6026 struct brcmf_cfg80211_vif *vif_walk;
6027 struct brcmf_cfg80211_vif *vif;
6028 bool mbss;
6029 struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
6030
6031 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
6032 sizeof(*vif));
6033 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
6034 if (!vif)
6035 return ERR_PTR(-ENOMEM);
6036
6037 vif->wdev.wiphy = cfg->wiphy;
6038 vif->wdev.iftype = type;
6039 init_completion(&vif->mgmt_tx);
6040
6041 brcmf_init_prof(&vif->profile);
6042
6043 if (type == NL80211_IFTYPE_AP &&
6044 brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
6045 mbss = false;
6046 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
6047 if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
6048 mbss = true;
6049 break;
6050 }
6051 }
6052 vif->mbss = mbss;
6053 }
6054
6055 list_add_tail(&vif->list, &cfg->vif_list);
6056 return vif;
6057 }
6058
brcmf_free_vif(struct brcmf_cfg80211_vif * vif)6059 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
6060 {
6061 list_del(&vif->list);
6062 kfree(vif);
6063 }
6064
brcmf_cfg80211_free_netdev(struct net_device * ndev)6065 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
6066 {
6067 struct brcmf_cfg80211_vif *vif;
6068 struct brcmf_if *ifp;
6069
6070 ifp = netdev_priv(ndev);
6071 vif = ifp->vif;
6072
6073 if (vif)
6074 brcmf_free_vif(vif);
6075 }
6076
brcmf_is_linkup(struct brcmf_cfg80211_vif * vif,const struct brcmf_event_msg * e)6077 static bool brcmf_is_linkup(struct brcmf_cfg80211_vif *vif,
6078 const struct brcmf_event_msg *e)
6079 {
6080 u32 event = e->event_code;
6081 u32 status = e->status;
6082
6083 if ((vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_PSK ||
6084 vif->profile.use_fwsup == BRCMF_PROFILE_FWSUP_SAE) &&
6085 event == BRCMF_E_PSK_SUP &&
6086 status == BRCMF_E_STATUS_FWSUP_COMPLETED)
6087 set_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6088 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
6089 brcmf_dbg(CONN, "Processing set ssid\n");
6090 memcpy(vif->profile.bssid, e->addr, ETH_ALEN);
6091 if (vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_PSK &&
6092 vif->profile.use_fwsup != BRCMF_PROFILE_FWSUP_SAE)
6093 return true;
6094
6095 set_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6096 }
6097
6098 if (test_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state) &&
6099 test_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state)) {
6100 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6101 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6102 return true;
6103 }
6104 return false;
6105 }
6106
brcmf_is_linkdown(struct brcmf_cfg80211_vif * vif,const struct brcmf_event_msg * e)6107 static bool brcmf_is_linkdown(struct brcmf_cfg80211_vif *vif,
6108 const struct brcmf_event_msg *e)
6109 {
6110 u32 event = e->event_code;
6111 u16 flags = e->flags;
6112
6113 if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
6114 (event == BRCMF_E_DISASSOC_IND) ||
6115 ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
6116 brcmf_dbg(CONN, "Processing link down\n");
6117 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS, &vif->sme_state);
6118 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS, &vif->sme_state);
6119 return true;
6120 }
6121 return false;
6122 }
6123
brcmf_is_nonetwork(struct brcmf_cfg80211_info * cfg,const struct brcmf_event_msg * e)6124 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
6125 const struct brcmf_event_msg *e)
6126 {
6127 u32 event = e->event_code;
6128 u32 status = e->status;
6129
6130 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
6131 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
6132 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
6133 return true;
6134 }
6135
6136 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
6137 brcmf_dbg(CONN, "Processing connecting & no network found\n");
6138 return true;
6139 }
6140
6141 if (event == BRCMF_E_PSK_SUP &&
6142 status != BRCMF_E_STATUS_FWSUP_COMPLETED) {
6143 brcmf_dbg(CONN, "Processing failed supplicant state: %u\n",
6144 status);
6145 return true;
6146 }
6147
6148 return false;
6149 }
6150
brcmf_clear_assoc_ies(struct brcmf_cfg80211_info * cfg)6151 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
6152 {
6153 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6154
6155 kfree(conn_info->req_ie);
6156 conn_info->req_ie = NULL;
6157 conn_info->req_ie_len = 0;
6158 kfree(conn_info->resp_ie);
6159 conn_info->resp_ie = NULL;
6160 conn_info->resp_ie_len = 0;
6161 }
6162
brcmf_map_prio_to_prec(void * config,u8 prio)6163 u8 brcmf_map_prio_to_prec(void *config, u8 prio)
6164 {
6165 struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
6166
6167 if (!cfg)
6168 return (prio == PRIO_8021D_NONE || prio == PRIO_8021D_BE) ?
6169 (prio ^ 2) : prio;
6170
6171 /* For those AC(s) with ACM flag set to 1, convert its 4-level priority
6172 * to an 8-level precedence which is the same as BE's
6173 */
6174 if (prio > PRIO_8021D_EE &&
6175 cfg->ac_priority[prio] == cfg->ac_priority[PRIO_8021D_BE])
6176 return cfg->ac_priority[prio] * 2;
6177
6178 /* Conversion of 4-level priority to 8-level precedence */
6179 if (prio == PRIO_8021D_BE || prio == PRIO_8021D_BK ||
6180 prio == PRIO_8021D_CL || prio == PRIO_8021D_VO)
6181 return cfg->ac_priority[prio] * 2;
6182 else
6183 return cfg->ac_priority[prio] * 2 + 1;
6184 }
6185
brcmf_map_prio_to_aci(void * config,u8 prio)6186 u8 brcmf_map_prio_to_aci(void *config, u8 prio)
6187 {
6188 /* Prio here refers to the 802.1d priority in range of 0 to 7.
6189 * ACI here refers to the WLAN AC Index in range of 0 to 3.
6190 * This function will return ACI corresponding to input prio.
6191 */
6192 struct brcmf_cfg80211_info *cfg = (struct brcmf_cfg80211_info *)config;
6193
6194 if (cfg)
6195 return cfg->ac_priority[prio];
6196
6197 return prio;
6198 }
6199
brcmf_init_wmm_prio(u8 * priority)6200 static void brcmf_init_wmm_prio(u8 *priority)
6201 {
6202 /* Initialize AC priority array to default
6203 * 802.1d priority as per following table:
6204 * 802.1d prio 0,3 maps to BE
6205 * 802.1d prio 1,2 maps to BK
6206 * 802.1d prio 4,5 maps to VI
6207 * 802.1d prio 6,7 maps to VO
6208 */
6209 priority[0] = BRCMF_FWS_FIFO_AC_BE;
6210 priority[3] = BRCMF_FWS_FIFO_AC_BE;
6211 priority[1] = BRCMF_FWS_FIFO_AC_BK;
6212 priority[2] = BRCMF_FWS_FIFO_AC_BK;
6213 priority[4] = BRCMF_FWS_FIFO_AC_VI;
6214 priority[5] = BRCMF_FWS_FIFO_AC_VI;
6215 priority[6] = BRCMF_FWS_FIFO_AC_VO;
6216 priority[7] = BRCMF_FWS_FIFO_AC_VO;
6217 }
6218
brcmf_wifi_prioritize_acparams(const struct brcmf_cfg80211_edcf_acparam * acp,u8 * priority)6219 static void brcmf_wifi_prioritize_acparams(const
6220 struct brcmf_cfg80211_edcf_acparam *acp, u8 *priority)
6221 {
6222 u8 aci;
6223 u8 aifsn;
6224 u8 ecwmin;
6225 u8 ecwmax;
6226 u8 acm;
6227 u8 ranking_basis[EDCF_AC_COUNT];
6228 u8 aci_prio[EDCF_AC_COUNT]; /* AC_BE, AC_BK, AC_VI, AC_VO */
6229 u8 index;
6230
6231 for (aci = 0; aci < EDCF_AC_COUNT; aci++, acp++) {
6232 aifsn = acp->ACI & EDCF_AIFSN_MASK;
6233 acm = (acp->ACI & EDCF_ACM_MASK) ? 1 : 0;
6234 ecwmin = acp->ECW & EDCF_ECWMIN_MASK;
6235 ecwmax = (acp->ECW & EDCF_ECWMAX_MASK) >> EDCF_ECWMAX_SHIFT;
6236 brcmf_dbg(CONN, "ACI %d aifsn %d acm %d ecwmin %d ecwmax %d\n",
6237 aci, aifsn, acm, ecwmin, ecwmax);
6238 /* Default AC_VO will be the lowest ranking value */
6239 ranking_basis[aci] = aifsn + ecwmin + ecwmax;
6240 /* Initialise priority starting at 0 (AC_BE) */
6241 aci_prio[aci] = 0;
6242
6243 /* If ACM is set, STA can't use this AC as per 802.11.
6244 * Change the ranking to BE
6245 */
6246 if (aci != AC_BE && aci != AC_BK && acm == 1)
6247 ranking_basis[aci] = ranking_basis[AC_BE];
6248 }
6249
6250 /* Ranking method which works for AC priority
6251 * swapping when values for cwmin, cwmax and aifsn are varied
6252 * Compare each aci_prio against each other aci_prio
6253 */
6254 for (aci = 0; aci < EDCF_AC_COUNT; aci++) {
6255 for (index = 0; index < EDCF_AC_COUNT; index++) {
6256 if (index != aci) {
6257 /* Smaller ranking value has higher priority,
6258 * so increment priority for each ACI which has
6259 * a higher ranking value
6260 */
6261 if (ranking_basis[aci] < ranking_basis[index])
6262 aci_prio[aci]++;
6263 }
6264 }
6265 }
6266
6267 /* By now, aci_prio[] will be in range of 0 to 3.
6268 * Use ACI prio to get the new priority value for
6269 * each 802.1d traffic type, in this range.
6270 */
6271 if (!(aci_prio[AC_BE] == aci_prio[AC_BK] &&
6272 aci_prio[AC_BK] == aci_prio[AC_VI] &&
6273 aci_prio[AC_VI] == aci_prio[AC_VO])) {
6274 /* 802.1d 0,3 maps to BE */
6275 priority[0] = aci_prio[AC_BE];
6276 priority[3] = aci_prio[AC_BE];
6277
6278 /* 802.1d 1,2 maps to BK */
6279 priority[1] = aci_prio[AC_BK];
6280 priority[2] = aci_prio[AC_BK];
6281
6282 /* 802.1d 4,5 maps to VO */
6283 priority[4] = aci_prio[AC_VI];
6284 priority[5] = aci_prio[AC_VI];
6285
6286 /* 802.1d 6,7 maps to VO */
6287 priority[6] = aci_prio[AC_VO];
6288 priority[7] = aci_prio[AC_VO];
6289 } else {
6290 /* Initialize to default priority */
6291 brcmf_init_wmm_prio(priority);
6292 }
6293
6294 brcmf_dbg(CONN, "Adj prio BE 0->%d, BK 1->%d, BK 2->%d, BE 3->%d\n",
6295 priority[0], priority[1], priority[2], priority[3]);
6296
6297 brcmf_dbg(CONN, "Adj prio VI 4->%d, VI 5->%d, VO 6->%d, VO 7->%d\n",
6298 priority[4], priority[5], priority[6], priority[7]);
6299 }
6300
brcmf_get_assoc_ies(struct brcmf_cfg80211_info * cfg,struct brcmf_if * ifp)6301 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
6302 struct brcmf_if *ifp)
6303 {
6304 struct brcmf_pub *drvr = cfg->pub;
6305 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
6306 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6307 struct brcmf_cfg80211_edcf_acparam edcf_acparam_info[EDCF_AC_COUNT];
6308 u32 req_len;
6309 u32 resp_len;
6310 s32 err = 0;
6311
6312 brcmf_clear_assoc_ies(cfg);
6313
6314 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
6315 cfg->extra_buf, WL_ASSOC_INFO_MAX);
6316 if (err) {
6317 bphy_err(drvr, "could not get assoc info (%d)\n", err);
6318 return err;
6319 }
6320 assoc_info =
6321 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
6322 req_len = le32_to_cpu(assoc_info->req_len);
6323 resp_len = le32_to_cpu(assoc_info->resp_len);
6324 if (req_len > WL_EXTRA_BUF_MAX || resp_len > WL_EXTRA_BUF_MAX) {
6325 bphy_err(drvr, "invalid lengths in assoc info: req %u resp %u\n",
6326 req_len, resp_len);
6327 return -EINVAL;
6328 }
6329 if (req_len) {
6330 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
6331 cfg->extra_buf,
6332 WL_ASSOC_INFO_MAX);
6333 if (err) {
6334 bphy_err(drvr, "could not get assoc req (%d)\n", err);
6335 return err;
6336 }
6337 conn_info->req_ie_len = req_len;
6338 conn_info->req_ie =
6339 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
6340 GFP_KERNEL);
6341 if (!conn_info->req_ie)
6342 conn_info->req_ie_len = 0;
6343 } else {
6344 conn_info->req_ie_len = 0;
6345 conn_info->req_ie = NULL;
6346 }
6347 if (resp_len) {
6348 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
6349 cfg->extra_buf,
6350 WL_ASSOC_INFO_MAX);
6351 if (err) {
6352 bphy_err(drvr, "could not get assoc resp (%d)\n", err);
6353 return err;
6354 }
6355 conn_info->resp_ie_len = resp_len;
6356 conn_info->resp_ie =
6357 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
6358 GFP_KERNEL);
6359 if (!conn_info->resp_ie)
6360 conn_info->resp_ie_len = 0;
6361
6362 err = brcmf_fil_iovar_data_get(ifp, "wme_ac_sta",
6363 edcf_acparam_info,
6364 sizeof(edcf_acparam_info));
6365 if (err) {
6366 brcmf_err("could not get wme_ac_sta (%d)\n", err);
6367 return err;
6368 }
6369
6370 brcmf_wifi_prioritize_acparams(edcf_acparam_info,
6371 cfg->ac_priority);
6372 } else {
6373 conn_info->resp_ie_len = 0;
6374 conn_info->resp_ie = NULL;
6375 }
6376 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
6377 conn_info->req_ie_len, conn_info->resp_ie_len);
6378
6379 return err;
6380 }
6381
6382 static s32
brcmf_bss_roaming_done(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e)6383 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
6384 struct net_device *ndev,
6385 const struct brcmf_event_msg *e)
6386 {
6387 struct brcmf_if *ifp = netdev_priv(ndev);
6388 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6389 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6390 struct wiphy *wiphy = cfg_to_wiphy(cfg);
6391 struct ieee80211_channel *notify_channel = NULL;
6392 struct ieee80211_supported_band *band;
6393 struct brcmf_bss_info_le *bi;
6394 struct brcmu_chan ch;
6395 struct cfg80211_roam_info roam_info = {};
6396 u32 freq;
6397 s32 err = 0;
6398 u8 *buf;
6399
6400 brcmf_dbg(TRACE, "Enter\n");
6401
6402 brcmf_get_assoc_ies(cfg, ifp);
6403 memcpy(profile->bssid, e->addr, ETH_ALEN);
6404 brcmf_update_bss_info(cfg, ifp);
6405
6406 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
6407 if (buf == NULL) {
6408 err = -ENOMEM;
6409 goto done;
6410 }
6411
6412 /* data sent to dongle has to be little endian */
6413 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
6414 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
6415 buf, WL_BSS_INFO_MAX);
6416
6417 if (err)
6418 goto done;
6419
6420 bi = (struct brcmf_bss_info_le *)(buf + 4);
6421 ch.chspec = le16_to_cpu(bi->chanspec);
6422 cfg->d11inf.decchspec(&ch);
6423
6424 if (ch.band == BRCMU_CHAN_BAND_2G)
6425 band = wiphy->bands[NL80211_BAND_2GHZ];
6426 else
6427 band = wiphy->bands[NL80211_BAND_5GHZ];
6428
6429 freq = ieee80211_channel_to_frequency(ch.control_ch_num, band->band);
6430 notify_channel = ieee80211_get_channel(wiphy, freq);
6431
6432 done:
6433 kfree(buf);
6434
6435 roam_info.links[0].channel = notify_channel;
6436 roam_info.links[0].bssid = profile->bssid;
6437 roam_info.req_ie = conn_info->req_ie;
6438 roam_info.req_ie_len = conn_info->req_ie_len;
6439 roam_info.resp_ie = conn_info->resp_ie;
6440 roam_info.resp_ie_len = conn_info->resp_ie_len;
6441
6442 cfg80211_roamed(ndev, &roam_info, GFP_KERNEL);
6443 brcmf_dbg(CONN, "Report roaming result\n");
6444
6445 if (profile->use_fwsup == BRCMF_PROFILE_FWSUP_1X && profile->is_ft) {
6446 cfg80211_port_authorized(ndev, profile->bssid, NULL, 0, GFP_KERNEL);
6447 brcmf_dbg(CONN, "Report port authorized\n");
6448 }
6449
6450 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
6451 brcmf_dbg(TRACE, "Exit\n");
6452 return err;
6453 }
6454
6455 static s32
brcmf_bss_connect_done(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e,bool completed)6456 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
6457 struct net_device *ndev, const struct brcmf_event_msg *e,
6458 bool completed)
6459 {
6460 struct brcmf_if *ifp = netdev_priv(ndev);
6461 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6462 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
6463 struct cfg80211_connect_resp_params conn_params;
6464
6465 brcmf_dbg(TRACE, "Enter\n");
6466
6467 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6468 &ifp->vif->sme_state)) {
6469 memset(&conn_params, 0, sizeof(conn_params));
6470 if (completed) {
6471 brcmf_get_assoc_ies(cfg, ifp);
6472 brcmf_update_bss_info(cfg, ifp);
6473 set_bit(BRCMF_VIF_STATUS_CONNECTED,
6474 &ifp->vif->sme_state);
6475 conn_params.status = WLAN_STATUS_SUCCESS;
6476 } else {
6477 clear_bit(BRCMF_VIF_STATUS_EAP_SUCCESS,
6478 &ifp->vif->sme_state);
6479 clear_bit(BRCMF_VIF_STATUS_ASSOC_SUCCESS,
6480 &ifp->vif->sme_state);
6481 conn_params.status = WLAN_STATUS_AUTH_TIMEOUT;
6482 }
6483 conn_params.links[0].bssid = profile->bssid;
6484 conn_params.req_ie = conn_info->req_ie;
6485 conn_params.req_ie_len = conn_info->req_ie_len;
6486 conn_params.resp_ie = conn_info->resp_ie;
6487 conn_params.resp_ie_len = conn_info->resp_ie_len;
6488 cfg80211_connect_done(ndev, &conn_params, GFP_KERNEL);
6489 brcmf_dbg(CONN, "Report connect result - connection %s\n",
6490 completed ? "succeeded" : "failed");
6491 }
6492 brcmf_dbg(TRACE, "Exit\n");
6493 return 0;
6494 }
6495
6496 static s32
brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info * cfg,struct net_device * ndev,const struct brcmf_event_msg * e,void * data)6497 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
6498 struct net_device *ndev,
6499 const struct brcmf_event_msg *e, void *data)
6500 {
6501 struct brcmf_pub *drvr = cfg->pub;
6502 static int generation;
6503 u32 event = e->event_code;
6504 u32 reason = e->reason;
6505 struct station_info *sinfo;
6506
6507 brcmf_dbg(CONN, "event %s (%u), reason %d\n",
6508 brcmf_fweh_event_name(event), event, reason);
6509 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
6510 ndev != cfg_to_ndev(cfg)) {
6511 brcmf_dbg(CONN, "AP mode link down\n");
6512 complete(&cfg->vif_disabled);
6513 return 0;
6514 }
6515
6516 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
6517 (reason == BRCMF_E_STATUS_SUCCESS)) {
6518 if (!data) {
6519 bphy_err(drvr, "No IEs present in ASSOC/REASSOC_IND\n");
6520 return -EINVAL;
6521 }
6522
6523 sinfo = kzalloc(sizeof(*sinfo), GFP_KERNEL);
6524 if (!sinfo)
6525 return -ENOMEM;
6526
6527 sinfo->assoc_req_ies = data;
6528 sinfo->assoc_req_ies_len = e->datalen;
6529 generation++;
6530 sinfo->generation = generation;
6531 cfg80211_new_sta(ndev, e->addr, sinfo, GFP_KERNEL);
6532
6533 kfree(sinfo);
6534 } else if ((event == BRCMF_E_DISASSOC_IND) ||
6535 (event == BRCMF_E_DEAUTH_IND) ||
6536 (event == BRCMF_E_DEAUTH)) {
6537 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
6538 }
6539 return 0;
6540 }
6541
6542 static s32
brcmf_notify_connect_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)6543 brcmf_notify_connect_status(struct brcmf_if *ifp,
6544 const struct brcmf_event_msg *e, void *data)
6545 {
6546 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6547 struct net_device *ndev = ifp->ndev;
6548 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
6549 struct ieee80211_channel *chan;
6550 s32 err = 0;
6551
6552 if ((e->event_code == BRCMF_E_DEAUTH) ||
6553 (e->event_code == BRCMF_E_DEAUTH_IND) ||
6554 (e->event_code == BRCMF_E_DISASSOC_IND) ||
6555 ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
6556 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
6557 }
6558
6559 if (brcmf_is_apmode(ifp->vif)) {
6560 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
6561 } else if (brcmf_is_linkup(ifp->vif, e)) {
6562 brcmf_dbg(CONN, "Linkup\n");
6563 if (brcmf_is_ibssmode(ifp->vif)) {
6564 brcmf_inform_ibss(cfg, ndev, e->addr);
6565 chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
6566 memcpy(profile->bssid, e->addr, ETH_ALEN);
6567 cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
6568 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6569 &ifp->vif->sme_state);
6570 set_bit(BRCMF_VIF_STATUS_CONNECTED,
6571 &ifp->vif->sme_state);
6572 } else
6573 brcmf_bss_connect_done(cfg, ndev, e, true);
6574 brcmf_net_setcarrier(ifp, true);
6575 } else if (brcmf_is_linkdown(ifp->vif, e)) {
6576 brcmf_dbg(CONN, "Linkdown\n");
6577 if (!brcmf_is_ibssmode(ifp->vif) &&
6578 (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6579 &ifp->vif->sme_state) ||
6580 test_bit(BRCMF_VIF_STATUS_CONNECTING,
6581 &ifp->vif->sme_state))) {
6582 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6583 &ifp->vif->sme_state) &&
6584 memcmp(profile->bssid, e->addr, ETH_ALEN))
6585 return err;
6586
6587 brcmf_bss_connect_done(cfg, ndev, e, false);
6588 brcmf_link_down(ifp->vif,
6589 brcmf_map_fw_linkdown_reason(e),
6590 e->event_code &
6591 (BRCMF_E_DEAUTH_IND |
6592 BRCMF_E_DISASSOC_IND)
6593 ? false : true);
6594 brcmf_init_prof(ndev_to_prof(ndev));
6595 if (ndev != cfg_to_ndev(cfg))
6596 complete(&cfg->vif_disabled);
6597 brcmf_net_setcarrier(ifp, false);
6598 }
6599 } else if (brcmf_is_nonetwork(cfg, e)) {
6600 if (brcmf_is_ibssmode(ifp->vif))
6601 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
6602 &ifp->vif->sme_state);
6603 else
6604 brcmf_bss_connect_done(cfg, ndev, e, false);
6605 }
6606
6607 return err;
6608 }
6609
6610 static s32
brcmf_notify_roaming_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)6611 brcmf_notify_roaming_status(struct brcmf_if *ifp,
6612 const struct brcmf_event_msg *e, void *data)
6613 {
6614 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6615 u32 event = e->event_code;
6616 u32 status = e->status;
6617
6618 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
6619 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
6620 &ifp->vif->sme_state)) {
6621 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
6622 } else {
6623 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
6624 brcmf_net_setcarrier(ifp, true);
6625 }
6626 }
6627
6628 return 0;
6629 }
6630
6631 static s32
brcmf_notify_mic_status(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)6632 brcmf_notify_mic_status(struct brcmf_if *ifp,
6633 const struct brcmf_event_msg *e, void *data)
6634 {
6635 u16 flags = e->flags;
6636 enum nl80211_key_type key_type;
6637
6638 if (flags & BRCMF_EVENT_MSG_GROUP)
6639 key_type = NL80211_KEYTYPE_GROUP;
6640 else
6641 key_type = NL80211_KEYTYPE_PAIRWISE;
6642
6643 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
6644 NULL, GFP_KERNEL);
6645
6646 return 0;
6647 }
6648
brcmf_notify_rssi(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)6649 static s32 brcmf_notify_rssi(struct brcmf_if *ifp,
6650 const struct brcmf_event_msg *e, void *data)
6651 {
6652 struct brcmf_cfg80211_vif *vif = ifp->vif;
6653 struct brcmf_rssi_be *info = data;
6654 s32 rssi, snr = 0, noise = 0;
6655 s32 low, high, last;
6656
6657 if (e->datalen >= sizeof(*info)) {
6658 rssi = be32_to_cpu(info->rssi);
6659 snr = be32_to_cpu(info->snr);
6660 noise = be32_to_cpu(info->noise);
6661 } else if (e->datalen >= sizeof(rssi)) {
6662 rssi = be32_to_cpu(*(__be32 *)data);
6663 } else {
6664 brcmf_err("insufficient RSSI event data\n");
6665 return 0;
6666 }
6667
6668 low = vif->cqm_rssi_low;
6669 high = vif->cqm_rssi_high;
6670 last = vif->cqm_rssi_last;
6671
6672 brcmf_dbg(TRACE, "rssi=%d snr=%d noise=%d low=%d high=%d last=%d\n",
6673 rssi, snr, noise, low, high, last);
6674
6675 vif->cqm_rssi_last = rssi;
6676
6677 if (rssi <= low || rssi == 0) {
6678 brcmf_dbg(INFO, "LOW rssi=%d\n", rssi);
6679 cfg80211_cqm_rssi_notify(ifp->ndev,
6680 NL80211_CQM_RSSI_THRESHOLD_EVENT_LOW,
6681 rssi, GFP_KERNEL);
6682 } else if (rssi > high) {
6683 brcmf_dbg(INFO, "HIGH rssi=%d\n", rssi);
6684 cfg80211_cqm_rssi_notify(ifp->ndev,
6685 NL80211_CQM_RSSI_THRESHOLD_EVENT_HIGH,
6686 rssi, GFP_KERNEL);
6687 }
6688
6689 return 0;
6690 }
6691
brcmf_notify_vif_event(struct brcmf_if * ifp,const struct brcmf_event_msg * e,void * data)6692 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
6693 const struct brcmf_event_msg *e, void *data)
6694 {
6695 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
6696 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
6697 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6698 struct brcmf_cfg80211_vif *vif;
6699
6700 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfgidx %u\n",
6701 ifevent->action, ifevent->flags, ifevent->ifidx,
6702 ifevent->bsscfgidx);
6703
6704 spin_lock(&event->vif_event_lock);
6705 event->action = ifevent->action;
6706 vif = event->vif;
6707
6708 switch (ifevent->action) {
6709 case BRCMF_E_IF_ADD:
6710 /* waiting process may have timed out */
6711 if (!cfg->vif_event.vif) {
6712 spin_unlock(&event->vif_event_lock);
6713 return -EBADF;
6714 }
6715
6716 ifp->vif = vif;
6717 vif->ifp = ifp;
6718 if (ifp->ndev) {
6719 vif->wdev.netdev = ifp->ndev;
6720 ifp->ndev->ieee80211_ptr = &vif->wdev;
6721 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
6722 }
6723 spin_unlock(&event->vif_event_lock);
6724 wake_up(&event->vif_wq);
6725 return 0;
6726
6727 case BRCMF_E_IF_DEL:
6728 spin_unlock(&event->vif_event_lock);
6729 /* event may not be upon user request */
6730 if (brcmf_cfg80211_vif_event_armed(cfg))
6731 wake_up(&event->vif_wq);
6732 return 0;
6733
6734 case BRCMF_E_IF_CHANGE:
6735 spin_unlock(&event->vif_event_lock);
6736 wake_up(&event->vif_wq);
6737 return 0;
6738
6739 default:
6740 spin_unlock(&event->vif_event_lock);
6741 break;
6742 }
6743 return -EINVAL;
6744 }
6745
brcmf_init_conf(struct brcmf_cfg80211_conf * conf)6746 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
6747 {
6748 conf->frag_threshold = (u32)-1;
6749 conf->rts_threshold = (u32)-1;
6750 conf->retry_short = (u32)-1;
6751 conf->retry_long = (u32)-1;
6752 }
6753
brcmf_register_event_handlers(struct brcmf_cfg80211_info * cfg)6754 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
6755 {
6756 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
6757 brcmf_notify_connect_status);
6758 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
6759 brcmf_notify_connect_status);
6760 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
6761 brcmf_notify_connect_status);
6762 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
6763 brcmf_notify_connect_status);
6764 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
6765 brcmf_notify_connect_status);
6766 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
6767 brcmf_notify_connect_status);
6768 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
6769 brcmf_notify_roaming_status);
6770 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
6771 brcmf_notify_mic_status);
6772 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
6773 brcmf_notify_connect_status);
6774 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
6775 brcmf_notify_sched_scan_results);
6776 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
6777 brcmf_notify_vif_event);
6778 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
6779 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
6780 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
6781 brcmf_p2p_notify_listen_complete);
6782 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
6783 brcmf_p2p_notify_action_frame_rx);
6784 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
6785 brcmf_p2p_notify_action_tx_complete);
6786 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
6787 brcmf_p2p_notify_action_tx_complete);
6788 brcmf_fweh_register(cfg->pub, BRCMF_E_PSK_SUP,
6789 brcmf_notify_connect_status);
6790 brcmf_fweh_register(cfg->pub, BRCMF_E_RSSI, brcmf_notify_rssi);
6791
6792 brcmf_fwvid_register_event_handlers(cfg->pub);
6793 }
6794
brcmf_deinit_priv_mem(struct brcmf_cfg80211_info * cfg)6795 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
6796 {
6797 kfree(cfg->conf);
6798 cfg->conf = NULL;
6799 kfree(cfg->extra_buf);
6800 cfg->extra_buf = NULL;
6801 kfree(cfg->wowl.nd);
6802 cfg->wowl.nd = NULL;
6803 kfree(cfg->wowl.nd_info);
6804 cfg->wowl.nd_info = NULL;
6805 kfree(cfg->escan_info.escan_buf);
6806 cfg->escan_info.escan_buf = NULL;
6807 }
6808
brcmf_init_priv_mem(struct brcmf_cfg80211_info * cfg)6809 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
6810 {
6811 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
6812 if (!cfg->conf)
6813 goto init_priv_mem_out;
6814 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
6815 if (!cfg->extra_buf)
6816 goto init_priv_mem_out;
6817 cfg->wowl.nd = kzalloc(sizeof(*cfg->wowl.nd) + sizeof(u32), GFP_KERNEL);
6818 if (!cfg->wowl.nd)
6819 goto init_priv_mem_out;
6820 cfg->wowl.nd_info = kzalloc(sizeof(*cfg->wowl.nd_info) +
6821 sizeof(struct cfg80211_wowlan_nd_match *),
6822 GFP_KERNEL);
6823 if (!cfg->wowl.nd_info)
6824 goto init_priv_mem_out;
6825 cfg->escan_info.escan_buf = kzalloc(BRCMF_ESCAN_BUF_SIZE, GFP_KERNEL);
6826 if (!cfg->escan_info.escan_buf)
6827 goto init_priv_mem_out;
6828
6829 return 0;
6830
6831 init_priv_mem_out:
6832 brcmf_deinit_priv_mem(cfg);
6833
6834 return -ENOMEM;
6835 }
6836
wl_init_priv(struct brcmf_cfg80211_info * cfg)6837 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
6838 {
6839 s32 err = 0;
6840
6841 cfg->scan_request = NULL;
6842 cfg->pwr_save = true;
6843 cfg->dongle_up = false; /* dongle is not up yet */
6844 err = brcmf_init_priv_mem(cfg);
6845 if (err)
6846 return err;
6847 brcmf_register_event_handlers(cfg);
6848 mutex_init(&cfg->usr_sync);
6849 brcmf_init_escan(cfg);
6850 brcmf_init_conf(cfg->conf);
6851 brcmf_init_wmm_prio(cfg->ac_priority);
6852 init_completion(&cfg->vif_disabled);
6853 return err;
6854 }
6855
wl_deinit_priv(struct brcmf_cfg80211_info * cfg)6856 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
6857 {
6858 cfg->dongle_up = false; /* dongle down */
6859 brcmf_abort_scanning(cfg);
6860 brcmf_deinit_priv_mem(cfg);
6861 brcmf_clear_assoc_ies(cfg);
6862 }
6863
init_vif_event(struct brcmf_cfg80211_vif_event * event)6864 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
6865 {
6866 init_waitqueue_head(&event->vif_wq);
6867 spin_lock_init(&event->vif_event_lock);
6868 }
6869
brcmf_dongle_roam(struct brcmf_if * ifp)6870 static s32 brcmf_dongle_roam(struct brcmf_if *ifp)
6871 {
6872 struct brcmf_pub *drvr = ifp->drvr;
6873 s32 err;
6874 u32 bcn_timeout;
6875 __le32 roamtrigger[2];
6876 __le32 roam_delta[2];
6877
6878 /* Configure beacon timeout value based upon roaming setting */
6879 if (ifp->drvr->settings->roamoff)
6880 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_OFF;
6881 else
6882 bcn_timeout = BRCMF_DEFAULT_BCN_TIMEOUT_ROAM_ON;
6883 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
6884 if (err) {
6885 bphy_err(drvr, "bcn_timeout error (%d)\n", err);
6886 goto roam_setup_done;
6887 }
6888
6889 /* Enable/Disable built-in roaming to allow supplicant to take care of
6890 * roaming.
6891 */
6892 brcmf_dbg(INFO, "Internal Roaming = %s\n",
6893 ifp->drvr->settings->roamoff ? "Off" : "On");
6894 err = brcmf_fil_iovar_int_set(ifp, "roam_off",
6895 ifp->drvr->settings->roamoff);
6896 if (err) {
6897 bphy_err(drvr, "roam_off error (%d)\n", err);
6898 goto roam_setup_done;
6899 }
6900
6901 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
6902 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
6903 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
6904 (void *)roamtrigger, sizeof(roamtrigger));
6905 if (err)
6906 bphy_err(drvr, "WLC_SET_ROAM_TRIGGER error (%d)\n", err);
6907
6908 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
6909 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
6910 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
6911 (void *)roam_delta, sizeof(roam_delta));
6912 if (err)
6913 bphy_err(drvr, "WLC_SET_ROAM_DELTA error (%d)\n", err);
6914
6915 return 0;
6916
6917 roam_setup_done:
6918 return err;
6919 }
6920
6921 static s32
brcmf_dongle_scantime(struct brcmf_if * ifp)6922 brcmf_dongle_scantime(struct brcmf_if *ifp)
6923 {
6924 struct brcmf_pub *drvr = ifp->drvr;
6925 s32 err = 0;
6926
6927 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
6928 BRCMF_SCAN_CHANNEL_TIME);
6929 if (err) {
6930 bphy_err(drvr, "Scan assoc time error (%d)\n", err);
6931 goto dongle_scantime_out;
6932 }
6933 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
6934 BRCMF_SCAN_UNASSOC_TIME);
6935 if (err) {
6936 bphy_err(drvr, "Scan unassoc time error (%d)\n", err);
6937 goto dongle_scantime_out;
6938 }
6939
6940 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
6941 BRCMF_SCAN_PASSIVE_TIME);
6942 if (err) {
6943 bphy_err(drvr, "Scan passive time error (%d)\n", err);
6944 goto dongle_scantime_out;
6945 }
6946
6947 dongle_scantime_out:
6948 return err;
6949 }
6950
brcmf_update_bw40_channel_flag(struct ieee80211_channel * channel,struct brcmu_chan * ch)6951 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
6952 struct brcmu_chan *ch)
6953 {
6954 u32 ht40_flag;
6955
6956 ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
6957 if (ch->sb == BRCMU_CHAN_SB_U) {
6958 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6959 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6960 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
6961 } else {
6962 /* It should be one of
6963 * IEEE80211_CHAN_NO_HT40 or
6964 * IEEE80211_CHAN_NO_HT40PLUS
6965 */
6966 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
6967 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
6968 channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
6969 }
6970 }
6971
brcmf_construct_chaninfo(struct brcmf_cfg80211_info * cfg,u32 bw_cap[])6972 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
6973 u32 bw_cap[])
6974 {
6975 struct wiphy *wiphy = cfg_to_wiphy(cfg);
6976 struct brcmf_pub *drvr = cfg->pub;
6977 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
6978 struct ieee80211_supported_band *band;
6979 struct ieee80211_channel *channel;
6980 struct brcmf_chanspec_list *list;
6981 struct brcmu_chan ch;
6982 int err;
6983 u8 *pbuf;
6984 u32 i, j;
6985 u32 total;
6986 u32 chaninfo;
6987
6988 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
6989
6990 if (pbuf == NULL)
6991 return -ENOMEM;
6992
6993 list = (struct brcmf_chanspec_list *)pbuf;
6994
6995 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
6996 BRCMF_DCMD_MEDLEN);
6997 if (err) {
6998 bphy_err(drvr, "get chanspecs error (%d)\n", err);
6999 goto fail_pbuf;
7000 }
7001
7002 band = wiphy->bands[NL80211_BAND_2GHZ];
7003 if (band)
7004 for (i = 0; i < band->n_channels; i++)
7005 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
7006 band = wiphy->bands[NL80211_BAND_5GHZ];
7007 if (band)
7008 for (i = 0; i < band->n_channels; i++)
7009 band->channels[i].flags = IEEE80211_CHAN_DISABLED;
7010
7011 total = le32_to_cpu(list->count);
7012 if (total > BRCMF_MAX_CHANSPEC_LIST) {
7013 bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
7014 total);
7015 err = -EINVAL;
7016 goto fail_pbuf;
7017 }
7018
7019 for (i = 0; i < total; i++) {
7020 ch.chspec = (u16)le32_to_cpu(list->element[i]);
7021 cfg->d11inf.decchspec(&ch);
7022
7023 if (ch.band == BRCMU_CHAN_BAND_2G) {
7024 band = wiphy->bands[NL80211_BAND_2GHZ];
7025 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
7026 band = wiphy->bands[NL80211_BAND_5GHZ];
7027 } else {
7028 bphy_err(drvr, "Invalid channel Spec. 0x%x.\n",
7029 ch.chspec);
7030 continue;
7031 }
7032 if (!band)
7033 continue;
7034 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
7035 ch.bw == BRCMU_CHAN_BW_40)
7036 continue;
7037 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
7038 ch.bw == BRCMU_CHAN_BW_80)
7039 continue;
7040
7041 channel = NULL;
7042 for (j = 0; j < band->n_channels; j++) {
7043 if (band->channels[j].hw_value == ch.control_ch_num) {
7044 channel = &band->channels[j];
7045 break;
7046 }
7047 }
7048 if (!channel) {
7049 /* It seems firmware supports some channel we never
7050 * considered. Something new in IEEE standard?
7051 */
7052 bphy_err(drvr, "Ignoring unexpected firmware channel %d\n",
7053 ch.control_ch_num);
7054 continue;
7055 }
7056
7057 if (channel->orig_flags & IEEE80211_CHAN_DISABLED)
7058 continue;
7059
7060 /* assuming the chanspecs order is HT20,
7061 * HT40 upper, HT40 lower, and VHT80.
7062 */
7063 switch (ch.bw) {
7064 case BRCMU_CHAN_BW_160:
7065 channel->flags &= ~IEEE80211_CHAN_NO_160MHZ;
7066 break;
7067 case BRCMU_CHAN_BW_80:
7068 channel->flags &= ~IEEE80211_CHAN_NO_80MHZ;
7069 break;
7070 case BRCMU_CHAN_BW_40:
7071 brcmf_update_bw40_channel_flag(channel, &ch);
7072 break;
7073 default:
7074 wiphy_warn(wiphy, "Firmware reported unsupported bandwidth %d\n",
7075 ch.bw);
7076 fallthrough;
7077 case BRCMU_CHAN_BW_20:
7078 /* enable the channel and disable other bandwidths
7079 * for now as mentioned order assure they are enabled
7080 * for subsequent chanspecs.
7081 */
7082 channel->flags = IEEE80211_CHAN_NO_HT40 |
7083 IEEE80211_CHAN_NO_80MHZ |
7084 IEEE80211_CHAN_NO_160MHZ;
7085 ch.bw = BRCMU_CHAN_BW_20;
7086 cfg->d11inf.encchspec(&ch);
7087 chaninfo = ch.chspec;
7088 err = brcmf_fil_bsscfg_int_query(ifp, "per_chan_info",
7089 &chaninfo);
7090 if (!err) {
7091 if (chaninfo & WL_CHAN_RADAR)
7092 channel->flags |=
7093 (IEEE80211_CHAN_RADAR |
7094 IEEE80211_CHAN_NO_IR);
7095 if (chaninfo & WL_CHAN_PASSIVE)
7096 channel->flags |=
7097 IEEE80211_CHAN_NO_IR;
7098 }
7099 }
7100 }
7101
7102 fail_pbuf:
7103 kfree(pbuf);
7104 return err;
7105 }
7106
brcmf_enable_bw40_2g(struct brcmf_cfg80211_info * cfg)7107 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
7108 {
7109 struct brcmf_pub *drvr = cfg->pub;
7110 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
7111 struct ieee80211_supported_band *band;
7112 struct brcmf_fil_bwcap_le band_bwcap;
7113 struct brcmf_chanspec_list *list;
7114 u8 *pbuf;
7115 u32 val;
7116 int err;
7117 struct brcmu_chan ch;
7118 u32 num_chan;
7119 int i, j;
7120
7121 /* verify support for bw_cap command */
7122 val = WLC_BAND_5G;
7123 err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &val);
7124
7125 if (!err) {
7126 /* only set 2G bandwidth using bw_cap command */
7127 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
7128 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
7129 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
7130 sizeof(band_bwcap));
7131 } else {
7132 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
7133 val = WLC_N_BW_40ALL;
7134 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
7135 }
7136
7137 if (!err) {
7138 /* update channel info in 2G band */
7139 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
7140
7141 if (pbuf == NULL)
7142 return -ENOMEM;
7143
7144 ch.band = BRCMU_CHAN_BAND_2G;
7145 ch.bw = BRCMU_CHAN_BW_40;
7146 ch.sb = BRCMU_CHAN_SB_NONE;
7147 ch.chnum = 0;
7148 cfg->d11inf.encchspec(&ch);
7149
7150 /* pass encoded chanspec in query */
7151 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
7152
7153 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
7154 BRCMF_DCMD_MEDLEN);
7155 if (err) {
7156 bphy_err(drvr, "get chanspecs error (%d)\n", err);
7157 kfree(pbuf);
7158 return err;
7159 }
7160
7161 band = cfg_to_wiphy(cfg)->bands[NL80211_BAND_2GHZ];
7162 list = (struct brcmf_chanspec_list *)pbuf;
7163 num_chan = le32_to_cpu(list->count);
7164 if (num_chan > BRCMF_MAX_CHANSPEC_LIST) {
7165 bphy_err(drvr, "Invalid count of channel Spec. (%u)\n",
7166 num_chan);
7167 kfree(pbuf);
7168 return -EINVAL;
7169 }
7170
7171 for (i = 0; i < num_chan; i++) {
7172 ch.chspec = (u16)le32_to_cpu(list->element[i]);
7173 cfg->d11inf.decchspec(&ch);
7174 if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
7175 continue;
7176 if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
7177 continue;
7178 for (j = 0; j < band->n_channels; j++) {
7179 if (band->channels[j].hw_value == ch.control_ch_num)
7180 break;
7181 }
7182 if (WARN_ON(j == band->n_channels))
7183 continue;
7184
7185 brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
7186 }
7187 kfree(pbuf);
7188 }
7189 return err;
7190 }
7191
brcmf_get_bwcap(struct brcmf_if * ifp,u32 bw_cap[])7192 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
7193 {
7194 struct brcmf_pub *drvr = ifp->drvr;
7195 u32 band, mimo_bwcap;
7196 int err;
7197
7198 band = WLC_BAND_2G;
7199 err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
7200 if (!err) {
7201 bw_cap[NL80211_BAND_2GHZ] = band;
7202 band = WLC_BAND_5G;
7203 err = brcmf_fil_iovar_int_query(ifp, "bw_cap", &band);
7204 if (!err) {
7205 bw_cap[NL80211_BAND_5GHZ] = band;
7206 return;
7207 }
7208 WARN_ON(1);
7209 return;
7210 }
7211 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
7212 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
7213 if (err)
7214 /* assume 20MHz if firmware does not give a clue */
7215 mimo_bwcap = WLC_N_BW_20ALL;
7216
7217 switch (mimo_bwcap) {
7218 case WLC_N_BW_40ALL:
7219 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
7220 fallthrough;
7221 case WLC_N_BW_20IN2G_40IN5G:
7222 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
7223 fallthrough;
7224 case WLC_N_BW_20ALL:
7225 bw_cap[NL80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
7226 bw_cap[NL80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
7227 break;
7228 default:
7229 bphy_err(drvr, "invalid mimo_bw_cap value\n");
7230 }
7231 }
7232
brcmf_update_ht_cap(struct ieee80211_supported_band * band,u32 bw_cap[2],u32 nchain)7233 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
7234 u32 bw_cap[2], u32 nchain)
7235 {
7236 band->ht_cap.ht_supported = true;
7237 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
7238 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
7239 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
7240 }
7241 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
7242 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
7243 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
7244 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
7245 memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
7246 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
7247 }
7248
brcmf_get_mcs_map(u32 nchain,enum ieee80211_vht_mcs_support supp)7249 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
7250 {
7251 u16 mcs_map;
7252 int i;
7253
7254 for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
7255 mcs_map = (mcs_map << 2) | supp;
7256
7257 return cpu_to_le16(mcs_map);
7258 }
7259
brcmf_update_vht_cap(struct ieee80211_supported_band * band,u32 bw_cap[2],u32 nchain,u32 txstreams,u32 txbf_bfe_cap,u32 txbf_bfr_cap)7260 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
7261 u32 bw_cap[2], u32 nchain, u32 txstreams,
7262 u32 txbf_bfe_cap, u32 txbf_bfr_cap)
7263 {
7264 __le16 mcs_map;
7265
7266 /* not allowed in 2.4G band */
7267 if (band->band == NL80211_BAND_2GHZ)
7268 return;
7269
7270 band->vht_cap.vht_supported = true;
7271 /* 80MHz is mandatory */
7272 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
7273 if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
7274 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
7275 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
7276 }
7277 /* all support 256-QAM */
7278 mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
7279 band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
7280 band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
7281
7282 /* Beamforming support information */
7283 if (txbf_bfe_cap & BRCMF_TXBF_SU_BFE_CAP)
7284 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMEE_CAPABLE;
7285 if (txbf_bfe_cap & BRCMF_TXBF_MU_BFE_CAP)
7286 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMEE_CAPABLE;
7287 if (txbf_bfr_cap & BRCMF_TXBF_SU_BFR_CAP)
7288 band->vht_cap.cap |= IEEE80211_VHT_CAP_SU_BEAMFORMER_CAPABLE;
7289 if (txbf_bfr_cap & BRCMF_TXBF_MU_BFR_CAP)
7290 band->vht_cap.cap |= IEEE80211_VHT_CAP_MU_BEAMFORMER_CAPABLE;
7291
7292 if ((txbf_bfe_cap || txbf_bfr_cap) && (txstreams > 1)) {
7293 band->vht_cap.cap |=
7294 (2 << IEEE80211_VHT_CAP_BEAMFORMEE_STS_SHIFT);
7295 band->vht_cap.cap |= ((txstreams - 1) <<
7296 IEEE80211_VHT_CAP_SOUNDING_DIMENSIONS_SHIFT);
7297 band->vht_cap.cap |=
7298 IEEE80211_VHT_CAP_VHT_LINK_ADAPTATION_VHT_MRQ_MFB;
7299 }
7300 }
7301
brcmf_setup_wiphybands(struct brcmf_cfg80211_info * cfg)7302 static int brcmf_setup_wiphybands(struct brcmf_cfg80211_info *cfg)
7303 {
7304 struct brcmf_pub *drvr = cfg->pub;
7305 struct brcmf_if *ifp = brcmf_get_ifp(drvr, 0);
7306 struct wiphy *wiphy = cfg_to_wiphy(cfg);
7307 u32 nmode;
7308 u32 vhtmode = 0;
7309 u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
7310 u32 rxchain;
7311 u32 nchain;
7312 int err;
7313 s32 i;
7314 struct ieee80211_supported_band *band;
7315 u32 txstreams = 0;
7316 u32 txbf_bfe_cap = 0;
7317 u32 txbf_bfr_cap = 0;
7318
7319 (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
7320 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
7321 if (err) {
7322 bphy_err(drvr, "nmode error (%d)\n", err);
7323 } else {
7324 brcmf_get_bwcap(ifp, bw_cap);
7325 }
7326 brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
7327 nmode, vhtmode, bw_cap[NL80211_BAND_2GHZ],
7328 bw_cap[NL80211_BAND_5GHZ]);
7329
7330 err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
7331 if (err) {
7332 /* rxchain unsupported by firmware of older chips */
7333 if (err == -EBADE)
7334 bphy_info_once(drvr, "rxchain unsupported\n");
7335 else
7336 bphy_err(drvr, "rxchain error (%d)\n", err);
7337
7338 nchain = 1;
7339 } else {
7340 for (nchain = 0; rxchain; nchain++)
7341 rxchain = rxchain & (rxchain - 1);
7342 }
7343 brcmf_dbg(INFO, "nchain=%d\n", nchain);
7344
7345 err = brcmf_construct_chaninfo(cfg, bw_cap);
7346 if (err) {
7347 bphy_err(drvr, "brcmf_construct_chaninfo failed (%d)\n", err);
7348 return err;
7349 }
7350
7351 if (vhtmode) {
7352 (void)brcmf_fil_iovar_int_get(ifp, "txstreams", &txstreams);
7353 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfe_cap",
7354 &txbf_bfe_cap);
7355 (void)brcmf_fil_iovar_int_get(ifp, "txbf_bfr_cap",
7356 &txbf_bfr_cap);
7357 }
7358
7359 for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
7360 band = wiphy->bands[i];
7361 if (band == NULL)
7362 continue;
7363
7364 if (nmode)
7365 brcmf_update_ht_cap(band, bw_cap, nchain);
7366 if (vhtmode)
7367 brcmf_update_vht_cap(band, bw_cap, nchain, txstreams,
7368 txbf_bfe_cap, txbf_bfr_cap);
7369 }
7370
7371 return 0;
7372 }
7373
7374 static const struct ieee80211_txrx_stypes
7375 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
7376 [NL80211_IFTYPE_STATION] = {
7377 .tx = 0xffff,
7378 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7379 BIT(IEEE80211_STYPE_AUTH >> 4) |
7380 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7381 },
7382 [NL80211_IFTYPE_P2P_CLIENT] = {
7383 .tx = 0xffff,
7384 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7385 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7386 },
7387 [NL80211_IFTYPE_P2P_GO] = {
7388 .tx = 0xffff,
7389 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
7390 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
7391 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
7392 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
7393 BIT(IEEE80211_STYPE_AUTH >> 4) |
7394 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
7395 BIT(IEEE80211_STYPE_ACTION >> 4)
7396 },
7397 [NL80211_IFTYPE_P2P_DEVICE] = {
7398 .tx = 0xffff,
7399 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
7400 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
7401 },
7402 [NL80211_IFTYPE_AP] = {
7403 .tx = 0xffff,
7404 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
7405 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
7406 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
7407 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
7408 BIT(IEEE80211_STYPE_AUTH >> 4) |
7409 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
7410 BIT(IEEE80211_STYPE_ACTION >> 4)
7411 }
7412 };
7413
7414 /**
7415 * brcmf_setup_ifmodes() - determine interface modes and combinations.
7416 *
7417 * @wiphy: wiphy object.
7418 * @ifp: interface object needed for feat module api.
7419 *
7420 * The interface modes and combinations are determined dynamically here
7421 * based on firmware functionality.
7422 *
7423 * no p2p and no mbss:
7424 *
7425 * #STA <= 1, #AP <= 1, channels = 1, 2 total
7426 *
7427 * no p2p and mbss:
7428 *
7429 * #STA <= 1, #AP <= 1, channels = 1, 2 total
7430 * #AP <= 4, matching BI, channels = 1, 4 total
7431 *
7432 * no p2p and rsdb:
7433 * #STA <= 1, #AP <= 2, channels = 2, 4 total
7434 *
7435 * p2p, no mchan, and mbss:
7436 *
7437 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 1, 3 total
7438 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
7439 * #AP <= 4, matching BI, channels = 1, 4 total
7440 *
7441 * p2p, mchan, and mbss:
7442 *
7443 * #STA <= 2, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 1, channels = 2, 3 total
7444 * #STA <= 1, #P2P-DEV <= 1, #AP <= 1, #P2P-CL <= 1, channels = 1, 4 total
7445 * #AP <= 4, matching BI, channels = 1, 4 total
7446 *
7447 * p2p, rsdb, and no mbss:
7448 * #STA <= 1, #P2P-DEV <= 1, #{P2P-CL, P2P-GO} <= 2, AP <= 2,
7449 * channels = 2, 4 total
7450 *
7451 * Return: 0 on success, negative errno on failure
7452 */
brcmf_setup_ifmodes(struct wiphy * wiphy,struct brcmf_if * ifp)7453 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
7454 {
7455 struct ieee80211_iface_combination *combo = NULL;
7456 struct ieee80211_iface_limit *c0_limits = NULL;
7457 struct ieee80211_iface_limit *p2p_limits = NULL;
7458 struct ieee80211_iface_limit *mbss_limits = NULL;
7459 bool mon_flag, mbss, p2p, rsdb, mchan;
7460 int i, c, n_combos, n_limits;
7461
7462 mon_flag = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MONITOR_FLAG);
7463 mbss = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS);
7464 p2p = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P);
7465 rsdb = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_RSDB);
7466 mchan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN);
7467
7468 n_combos = 1 + !!(p2p && !rsdb) + !!mbss;
7469 combo = kcalloc(n_combos, sizeof(*combo), GFP_KERNEL);
7470 if (!combo)
7471 goto err;
7472
7473 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
7474 BIT(NL80211_IFTYPE_ADHOC) |
7475 BIT(NL80211_IFTYPE_AP);
7476 if (mon_flag)
7477 wiphy->interface_modes |= BIT(NL80211_IFTYPE_MONITOR);
7478 if (p2p)
7479 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
7480 BIT(NL80211_IFTYPE_P2P_GO) |
7481 BIT(NL80211_IFTYPE_P2P_DEVICE);
7482
7483 c = 0;
7484 i = 0;
7485 n_limits = 1 + mon_flag + (p2p ? 2 : 0) + (rsdb || !p2p);
7486 c0_limits = kcalloc(n_limits, sizeof(*c0_limits), GFP_KERNEL);
7487 if (!c0_limits)
7488 goto err;
7489
7490 combo[c].num_different_channels = 1 + (rsdb || (p2p && mchan));
7491 c0_limits[i].max = 1 + (p2p && mchan);
7492 c0_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7493 if (mon_flag) {
7494 c0_limits[i].max = 1;
7495 c0_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7496 }
7497 if (p2p) {
7498 c0_limits[i].max = 1;
7499 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7500 c0_limits[i].max = 1 + rsdb;
7501 c0_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
7502 BIT(NL80211_IFTYPE_P2P_GO);
7503 }
7504 if (p2p && rsdb) {
7505 c0_limits[i].max = 2;
7506 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7507 combo[c].max_interfaces = 4;
7508 } else if (p2p) {
7509 combo[c].max_interfaces = i;
7510 } else if (rsdb) {
7511 c0_limits[i].max = 2;
7512 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7513 combo[c].max_interfaces = 3;
7514 } else {
7515 c0_limits[i].max = 1;
7516 c0_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7517 combo[c].max_interfaces = i;
7518 }
7519 combo[c].n_limits = i;
7520 combo[c].limits = c0_limits;
7521
7522 if (p2p && !rsdb) {
7523 c++;
7524 i = 0;
7525 p2p_limits = kcalloc(4, sizeof(*p2p_limits), GFP_KERNEL);
7526 if (!p2p_limits)
7527 goto err;
7528 p2p_limits[i].max = 1;
7529 p2p_limits[i++].types = BIT(NL80211_IFTYPE_STATION);
7530 p2p_limits[i].max = 1;
7531 p2p_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7532 p2p_limits[i].max = 1;
7533 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT);
7534 p2p_limits[i].max = 1;
7535 p2p_limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
7536 combo[c].num_different_channels = 1;
7537 combo[c].max_interfaces = i;
7538 combo[c].n_limits = i;
7539 combo[c].limits = p2p_limits;
7540 }
7541
7542 if (mbss) {
7543 c++;
7544 i = 0;
7545 n_limits = 1 + mon_flag;
7546 mbss_limits = kcalloc(n_limits, sizeof(*mbss_limits),
7547 GFP_KERNEL);
7548 if (!mbss_limits)
7549 goto err;
7550 mbss_limits[i].max = 4;
7551 mbss_limits[i++].types = BIT(NL80211_IFTYPE_AP);
7552 if (mon_flag) {
7553 mbss_limits[i].max = 1;
7554 mbss_limits[i++].types = BIT(NL80211_IFTYPE_MONITOR);
7555 }
7556 combo[c].beacon_int_infra_match = true;
7557 combo[c].num_different_channels = 1;
7558 combo[c].max_interfaces = 4 + mon_flag;
7559 combo[c].n_limits = i;
7560 combo[c].limits = mbss_limits;
7561 }
7562
7563 wiphy->n_iface_combinations = n_combos;
7564 wiphy->iface_combinations = combo;
7565 return 0;
7566
7567 err:
7568 kfree(c0_limits);
7569 kfree(p2p_limits);
7570 kfree(mbss_limits);
7571 kfree(combo);
7572 return -ENOMEM;
7573 }
7574
7575 #ifdef CONFIG_PM
7576 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
7577 .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
7578 .n_patterns = BRCMF_WOWL_MAXPATTERNS,
7579 .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
7580 .pattern_min_len = 1,
7581 .max_pkt_offset = 1500,
7582 };
7583 #endif
7584
brcmf_wiphy_wowl_params(struct wiphy * wiphy,struct brcmf_if * ifp)7585 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy, struct brcmf_if *ifp)
7586 {
7587 #ifdef CONFIG_PM
7588 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
7589 struct brcmf_pub *drvr = cfg->pub;
7590 struct wiphy_wowlan_support *wowl;
7591
7592 wowl = kmemdup(&brcmf_wowlan_support, sizeof(brcmf_wowlan_support),
7593 GFP_KERNEL);
7594 if (!wowl) {
7595 bphy_err(drvr, "only support basic wowlan features\n");
7596 wiphy->wowlan = &brcmf_wowlan_support;
7597 return;
7598 }
7599
7600 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7601 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_ND)) {
7602 wowl->flags |= WIPHY_WOWLAN_NET_DETECT;
7603 wowl->max_nd_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
7604 init_waitqueue_head(&cfg->wowl.nd_data_wait);
7605 }
7606 }
7607 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK)) {
7608 wowl->flags |= WIPHY_WOWLAN_SUPPORTS_GTK_REKEY;
7609 wowl->flags |= WIPHY_WOWLAN_GTK_REKEY_FAILURE;
7610 }
7611
7612 wiphy->wowlan = wowl;
7613 #endif
7614 }
7615
brcmf_setup_wiphy(struct wiphy * wiphy,struct brcmf_if * ifp)7616 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
7617 {
7618 struct brcmf_pub *drvr = ifp->drvr;
7619 const struct ieee80211_iface_combination *combo;
7620 struct ieee80211_supported_band *band;
7621 u16 max_interfaces = 0;
7622 bool gscan;
7623 __le32 bandlist[3];
7624 u32 n_bands;
7625 int err, i;
7626
7627 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
7628 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
7629 wiphy->max_num_pmkids = BRCMF_MAXPMKID;
7630
7631 err = brcmf_setup_ifmodes(wiphy, ifp);
7632 if (err)
7633 return err;
7634
7635 for (i = 0, combo = wiphy->iface_combinations;
7636 i < wiphy->n_iface_combinations; i++, combo++) {
7637 max_interfaces = max(max_interfaces, combo->max_interfaces);
7638 }
7639
7640 for (i = 0; i < max_interfaces && i < ARRAY_SIZE(drvr->addresses);
7641 i++) {
7642 u8 *addr = drvr->addresses[i].addr;
7643
7644 memcpy(addr, drvr->mac, ETH_ALEN);
7645 if (i) {
7646 addr[0] |= BIT(1);
7647 addr[ETH_ALEN - 1] ^= i;
7648 }
7649 }
7650 wiphy->addresses = drvr->addresses;
7651 wiphy->n_addresses = i;
7652
7653 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
7654 wiphy->cipher_suites = brcmf_cipher_suites;
7655 wiphy->n_cipher_suites = ARRAY_SIZE(brcmf_cipher_suites);
7656 if (!brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MFP))
7657 wiphy->n_cipher_suites--;
7658 wiphy->bss_select_support = BIT(NL80211_BSS_SELECT_ATTR_RSSI) |
7659 BIT(NL80211_BSS_SELECT_ATTR_BAND_PREF) |
7660 BIT(NL80211_BSS_SELECT_ATTR_RSSI_ADJUST);
7661
7662 wiphy->flags |= WIPHY_FLAG_NETNS_OK |
7663 WIPHY_FLAG_PS_ON_BY_DEFAULT |
7664 WIPHY_FLAG_HAVE_AP_SME |
7665 WIPHY_FLAG_OFFCHAN_TX |
7666 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
7667 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS))
7668 wiphy->flags |= WIPHY_FLAG_SUPPORTS_TDLS;
7669 if (!ifp->drvr->settings->roamoff)
7670 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
7671 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWSUP)) {
7672 wiphy_ext_feature_set(wiphy,
7673 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_PSK);
7674 wiphy_ext_feature_set(wiphy,
7675 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_STA_1X);
7676 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7677 wiphy_ext_feature_set(wiphy,
7678 NL80211_EXT_FEATURE_SAE_OFFLOAD);
7679 }
7680 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_FWAUTH)) {
7681 wiphy_ext_feature_set(wiphy,
7682 NL80211_EXT_FEATURE_4WAY_HANDSHAKE_AP_PSK);
7683 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE))
7684 wiphy_ext_feature_set(wiphy,
7685 NL80211_EXT_FEATURE_SAE_OFFLOAD_AP);
7686 }
7687 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SAE_EXT))
7688 wiphy->features |= NL80211_FEATURE_SAE;
7689 wiphy->mgmt_stypes = brcmf_txrx_stypes;
7690 wiphy->max_remain_on_channel_duration = 5000;
7691 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO)) {
7692 gscan = brcmf_feat_is_enabled(ifp, BRCMF_FEAT_GSCAN);
7693 brcmf_pno_wiphy_params(wiphy, gscan);
7694 }
7695 /* vendor commands/events support */
7696 wiphy->vendor_commands = brcmf_vendor_cmds;
7697 wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
7698
7699 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
7700 brcmf_wiphy_wowl_params(wiphy, ifp);
7701 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
7702 sizeof(bandlist));
7703 if (err) {
7704 bphy_err(drvr, "could not obtain band info: err=%d\n", err);
7705 return err;
7706 }
7707 /* first entry in bandlist is number of bands */
7708 n_bands = le32_to_cpu(bandlist[0]);
7709 for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
7710 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
7711 band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
7712 GFP_KERNEL);
7713 if (!band)
7714 return -ENOMEM;
7715
7716 band->channels = kmemdup(&__wl_2ghz_channels,
7717 sizeof(__wl_2ghz_channels),
7718 GFP_KERNEL);
7719 if (!band->channels) {
7720 kfree(band);
7721 return -ENOMEM;
7722 }
7723
7724 band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
7725 wiphy->bands[NL80211_BAND_2GHZ] = band;
7726 }
7727 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
7728 band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
7729 GFP_KERNEL);
7730 if (!band)
7731 return -ENOMEM;
7732
7733 band->channels = kmemdup(&__wl_5ghz_channels,
7734 sizeof(__wl_5ghz_channels),
7735 GFP_KERNEL);
7736 if (!band->channels) {
7737 kfree(band);
7738 return -ENOMEM;
7739 }
7740
7741 band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
7742 wiphy->bands[NL80211_BAND_5GHZ] = band;
7743 }
7744 }
7745
7746 if (wiphy->bands[NL80211_BAND_5GHZ] &&
7747 brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DOT11H))
7748 wiphy_ext_feature_set(wiphy,
7749 NL80211_EXT_FEATURE_DFS_OFFLOAD);
7750
7751 wiphy_ext_feature_set(wiphy, NL80211_EXT_FEATURE_CQM_RSSI_LIST);
7752
7753 wiphy_read_of_freq_limits(wiphy);
7754
7755 return 0;
7756 }
7757
brcmf_config_dongle(struct brcmf_cfg80211_info * cfg)7758 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
7759 {
7760 struct brcmf_pub *drvr = cfg->pub;
7761 struct net_device *ndev;
7762 struct wireless_dev *wdev;
7763 struct brcmf_if *ifp;
7764 s32 power_mode;
7765 s32 err = 0;
7766
7767 if (cfg->dongle_up)
7768 return err;
7769
7770 ndev = cfg_to_ndev(cfg);
7771 wdev = ndev->ieee80211_ptr;
7772 ifp = netdev_priv(ndev);
7773
7774 /* make sure RF is ready for work */
7775 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
7776
7777 brcmf_dongle_scantime(ifp);
7778
7779 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
7780 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
7781 if (err)
7782 goto default_conf_out;
7783 brcmf_dbg(INFO, "power save set to %s\n",
7784 (power_mode ? "enabled" : "disabled"));
7785
7786 err = brcmf_dongle_roam(ifp);
7787 if (err)
7788 goto default_conf_out;
7789 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
7790 NULL);
7791 if (err)
7792 goto default_conf_out;
7793
7794 brcmf_configure_arp_nd_offload(ifp, true);
7795
7796 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_FAKEFRAG, 1);
7797 if (err) {
7798 bphy_err(drvr, "failed to set frameburst mode\n");
7799 goto default_conf_out;
7800 }
7801
7802 cfg->dongle_up = true;
7803 default_conf_out:
7804
7805 return err;
7806
7807 }
7808
__brcmf_cfg80211_up(struct brcmf_if * ifp)7809 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
7810 {
7811 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7812
7813 return brcmf_config_dongle(ifp->drvr->config);
7814 }
7815
__brcmf_cfg80211_down(struct brcmf_if * ifp)7816 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
7817 {
7818 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7819
7820 /*
7821 * While going down, if associated with AP disassociate
7822 * from AP to save power
7823 */
7824 if (check_vif_up(ifp->vif)) {
7825 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED, true);
7826
7827 /* Make sure WPA_Supplicant receives all the event
7828 generated due to DISASSOC call to the fw to keep
7829 the state fw and WPA_Supplicant state consistent
7830 */
7831 brcmf_delay(500);
7832 }
7833
7834 brcmf_abort_scanning(cfg);
7835 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
7836
7837 return 0;
7838 }
7839
brcmf_cfg80211_up(struct net_device * ndev)7840 s32 brcmf_cfg80211_up(struct net_device *ndev)
7841 {
7842 struct brcmf_if *ifp = netdev_priv(ndev);
7843 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7844 s32 err = 0;
7845
7846 mutex_lock(&cfg->usr_sync);
7847 err = __brcmf_cfg80211_up(ifp);
7848 mutex_unlock(&cfg->usr_sync);
7849
7850 return err;
7851 }
7852
brcmf_cfg80211_down(struct net_device * ndev)7853 s32 brcmf_cfg80211_down(struct net_device *ndev)
7854 {
7855 struct brcmf_if *ifp = netdev_priv(ndev);
7856 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
7857 s32 err = 0;
7858
7859 mutex_lock(&cfg->usr_sync);
7860 err = __brcmf_cfg80211_down(ifp);
7861 mutex_unlock(&cfg->usr_sync);
7862
7863 return err;
7864 }
7865
brcmf_get_vif_state_any(struct brcmf_cfg80211_info * cfg,unsigned long state)7866 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
7867 unsigned long state)
7868 {
7869 struct brcmf_cfg80211_vif *vif;
7870
7871 list_for_each_entry(vif, &cfg->vif_list, list) {
7872 if (test_bit(state, &vif->sme_state))
7873 return true;
7874 }
7875 return false;
7876 }
7877
vif_event_equals(struct brcmf_cfg80211_vif_event * event,u8 action)7878 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
7879 u8 action)
7880 {
7881 u8 evt_action;
7882
7883 spin_lock(&event->vif_event_lock);
7884 evt_action = event->action;
7885 spin_unlock(&event->vif_event_lock);
7886 return evt_action == action;
7887 }
7888
brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info * cfg,struct brcmf_cfg80211_vif * vif)7889 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
7890 struct brcmf_cfg80211_vif *vif)
7891 {
7892 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7893
7894 spin_lock(&event->vif_event_lock);
7895 event->vif = vif;
7896 event->action = 0;
7897 spin_unlock(&event->vif_event_lock);
7898 }
7899
brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info * cfg)7900 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
7901 {
7902 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7903 bool armed;
7904
7905 spin_lock(&event->vif_event_lock);
7906 armed = event->vif != NULL;
7907 spin_unlock(&event->vif_event_lock);
7908
7909 return armed;
7910 }
7911
brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info * cfg,u8 action,ulong timeout)7912 int brcmf_cfg80211_wait_vif_event(struct brcmf_cfg80211_info *cfg,
7913 u8 action, ulong timeout)
7914 {
7915 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
7916
7917 return wait_event_timeout(event->vif_wq,
7918 vif_event_equals(event, action), timeout);
7919 }
7920
brmcf_use_iso3166_ccode_fallback(struct brcmf_pub * drvr)7921 static bool brmcf_use_iso3166_ccode_fallback(struct brcmf_pub *drvr)
7922 {
7923 if (drvr->settings->trivial_ccode_map)
7924 return true;
7925
7926 switch (drvr->bus_if->chip) {
7927 case BRCM_CC_43430_CHIP_ID:
7928 case BRCM_CC_4345_CHIP_ID:
7929 case BRCM_CC_4356_CHIP_ID:
7930 case BRCM_CC_43602_CHIP_ID:
7931 return true;
7932 default:
7933 return false;
7934 }
7935 }
7936
brcmf_translate_country_code(struct brcmf_pub * drvr,char alpha2[2],struct brcmf_fil_country_le * ccreq)7937 static s32 brcmf_translate_country_code(struct brcmf_pub *drvr, char alpha2[2],
7938 struct brcmf_fil_country_le *ccreq)
7939 {
7940 struct brcmfmac_pd_cc *country_codes;
7941 struct brcmfmac_pd_cc_entry *cc;
7942 s32 found_index;
7943 int i;
7944
7945 if ((alpha2[0] == ccreq->country_abbrev[0]) &&
7946 (alpha2[1] == ccreq->country_abbrev[1])) {
7947 brcmf_dbg(TRACE, "Country code already set\n");
7948 return -EAGAIN;
7949 }
7950
7951 country_codes = drvr->settings->country_codes;
7952 if (!country_codes) {
7953 if (brmcf_use_iso3166_ccode_fallback(drvr)) {
7954 brcmf_dbg(TRACE, "No country codes configured for device, using ISO3166 code and 0 rev\n");
7955 memset(ccreq, 0, sizeof(*ccreq));
7956 ccreq->country_abbrev[0] = alpha2[0];
7957 ccreq->country_abbrev[1] = alpha2[1];
7958 ccreq->ccode[0] = alpha2[0];
7959 ccreq->ccode[1] = alpha2[1];
7960 return 0;
7961 }
7962
7963 brcmf_dbg(TRACE, "No country codes configured for device\n");
7964 return -EINVAL;
7965 }
7966
7967 found_index = -1;
7968 for (i = 0; i < country_codes->table_size; i++) {
7969 cc = &country_codes->table[i];
7970 if ((cc->iso3166[0] == '\0') && (found_index == -1))
7971 found_index = i;
7972 if ((cc->iso3166[0] == alpha2[0]) &&
7973 (cc->iso3166[1] == alpha2[1])) {
7974 found_index = i;
7975 break;
7976 }
7977 }
7978 if (found_index == -1) {
7979 brcmf_dbg(TRACE, "No country code match found\n");
7980 return -EINVAL;
7981 }
7982 memset(ccreq, 0, sizeof(*ccreq));
7983 ccreq->rev = cpu_to_le32(country_codes->table[found_index].rev);
7984 memcpy(ccreq->ccode, country_codes->table[found_index].cc,
7985 BRCMF_COUNTRY_BUF_SZ);
7986 ccreq->country_abbrev[0] = alpha2[0];
7987 ccreq->country_abbrev[1] = alpha2[1];
7988 ccreq->country_abbrev[2] = 0;
7989
7990 return 0;
7991 }
7992
7993 static int
brcmf_parse_dump_obss(char * buf,struct brcmf_dump_survey * survey)7994 brcmf_parse_dump_obss(char *buf, struct brcmf_dump_survey *survey)
7995 {
7996 int i;
7997 char *token;
7998 char delim[] = "\n ";
7999 unsigned long val;
8000 int err = 0;
8001
8002 token = strsep(&buf, delim);
8003 while (token) {
8004 if (!strcmp(token, "OBSS")) {
8005 for (i = 0; i < OBSS_TOKEN_IDX; i++)
8006 token = strsep(&buf, delim);
8007 err = kstrtoul(token, 10, &val);
8008 if (err)
8009 break;
8010 survey->obss = val;
8011 }
8012
8013 if (!strcmp(token, "IBSS")) {
8014 for (i = 0; i < IBSS_TOKEN_IDX; i++)
8015 token = strsep(&buf, delim);
8016 err = kstrtoul(token, 10, &val);
8017 if (err)
8018 break;
8019 survey->ibss = val;
8020 }
8021
8022 if (!strcmp(token, "TXDur")) {
8023 for (i = 0; i < TX_TOKEN_IDX; i++)
8024 token = strsep(&buf, delim);
8025 err = kstrtoul(token, 10, &val);
8026 if (err)
8027 break;
8028 survey->tx = val;
8029 }
8030
8031 if (!strcmp(token, "Category")) {
8032 for (i = 0; i < CTG_TOKEN_IDX; i++)
8033 token = strsep(&buf, delim);
8034 err = kstrtoul(token, 10, &val);
8035 if (err)
8036 break;
8037 survey->no_ctg = val;
8038 }
8039
8040 if (!strcmp(token, "Packet")) {
8041 for (i = 0; i < PKT_TOKEN_IDX; i++)
8042 token = strsep(&buf, delim);
8043 err = kstrtoul(token, 10, &val);
8044 if (err)
8045 break;
8046 survey->no_pckt = val;
8047 }
8048
8049 if (!strcmp(token, "Opp(time):")) {
8050 for (i = 0; i < IDLE_TOKEN_IDX; i++)
8051 token = strsep(&buf, delim);
8052 err = kstrtoul(token, 10, &val);
8053 if (err)
8054 break;
8055 survey->idle = val;
8056 }
8057
8058 token = strsep(&buf, delim);
8059 }
8060
8061 return err;
8062 }
8063
8064 static int
brcmf_dump_obss(struct brcmf_if * ifp,struct cca_msrmnt_query req,struct brcmf_dump_survey * survey)8065 brcmf_dump_obss(struct brcmf_if *ifp, struct cca_msrmnt_query req,
8066 struct brcmf_dump_survey *survey)
8067 {
8068 struct cca_stats_n_flags *results;
8069 char *buf;
8070 int err;
8071
8072 buf = kzalloc(sizeof(char) * BRCMF_DCMD_MEDLEN, GFP_KERNEL);
8073 if (!buf)
8074 return -ENOMEM;
8075
8076 memcpy(buf, &req, sizeof(struct cca_msrmnt_query));
8077 err = brcmf_fil_iovar_data_get(ifp, "dump_obss",
8078 buf, BRCMF_DCMD_MEDLEN);
8079 if (err) {
8080 brcmf_err("dump_obss error (%d)\n", err);
8081 err = -EINVAL;
8082 goto exit;
8083 }
8084 results = (struct cca_stats_n_flags *)(buf);
8085
8086 if (req.msrmnt_query)
8087 brcmf_parse_dump_obss(results->buf, survey);
8088
8089 exit:
8090 kfree(buf);
8091 return err;
8092 }
8093
8094 static s32
brcmf_set_channel(struct brcmf_cfg80211_info * cfg,struct ieee80211_channel * chan)8095 brcmf_set_channel(struct brcmf_cfg80211_info *cfg, struct ieee80211_channel *chan)
8096 {
8097 u16 chspec = 0;
8098 int err = 0;
8099 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
8100
8101 if (chan->flags & IEEE80211_CHAN_DISABLED)
8102 return -EINVAL;
8103
8104 /* set_channel */
8105 chspec = channel_to_chanspec(&cfg->d11inf, chan);
8106 if (chspec != INVCHANSPEC) {
8107 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chspec);
8108 if (err) {
8109 brcmf_err("set chanspec 0x%04x fail, reason %d\n", chspec, err);
8110 err = -EINVAL;
8111 }
8112 } else {
8113 brcmf_err("failed to convert host chanspec to fw chanspec\n");
8114 err = -EINVAL;
8115 }
8116
8117 return err;
8118 }
8119
8120 static int
brcmf_cfg80211_dump_survey(struct wiphy * wiphy,struct net_device * ndev,int idx,struct survey_info * info)8121 brcmf_cfg80211_dump_survey(struct wiphy *wiphy, struct net_device *ndev,
8122 int idx, struct survey_info *info)
8123 {
8124 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
8125 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
8126 struct brcmf_dump_survey survey = {};
8127 struct ieee80211_supported_band *band;
8128 enum nl80211_band band_id;
8129 struct cca_msrmnt_query req;
8130 u32 noise;
8131 int err;
8132
8133 brcmf_dbg(TRACE, "Enter: channel idx=%d\n", idx);
8134
8135 /* Do not run survey when VIF in CONNECTING / CONNECTED states */
8136 if ((test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) ||
8137 (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))) {
8138 return -EBUSY;
8139 }
8140
8141 for (band_id = 0; band_id < NUM_NL80211_BANDS; band_id++) {
8142 band = wiphy->bands[band_id];
8143 if (!band)
8144 continue;
8145 if (idx >= band->n_channels) {
8146 idx -= band->n_channels;
8147 continue;
8148 }
8149
8150 info->channel = &band->channels[idx];
8151 break;
8152 }
8153 if (band_id == NUM_NL80211_BANDS)
8154 return -ENOENT;
8155
8156 /* Setting current channel to the requested channel */
8157 info->filled = 0;
8158 if (brcmf_set_channel(cfg, info->channel))
8159 return 0;
8160
8161 /* Disable mpc */
8162 brcmf_set_mpc(ifp, 0);
8163
8164 /* Set interface up, explicitly. */
8165 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
8166 if (err) {
8167 brcmf_err("set interface up failed, err = %d\n", err);
8168 goto exit;
8169 }
8170
8171 /* Get noise value */
8172 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PHY_NOISE, &noise);
8173 if (err) {
8174 brcmf_err("Get Phy Noise failed, use dummy value\n");
8175 noise = CHAN_NOISE_DUMMY;
8176 }
8177
8178 /* Start Measurement for obss stats on current channel */
8179 req.msrmnt_query = 0;
8180 req.time_req = ACS_MSRMNT_DELAY;
8181 err = brcmf_dump_obss(ifp, req, &survey);
8182 if (err)
8183 goto exit;
8184
8185 /* Add 10 ms for IOVAR completion */
8186 msleep(ACS_MSRMNT_DELAY + 10);
8187
8188 /* Issue IOVAR to collect measurement results */
8189 req.msrmnt_query = 1;
8190 err = brcmf_dump_obss(ifp, req, &survey);
8191 if (err)
8192 goto exit;
8193
8194 info->noise = noise;
8195 info->time = ACS_MSRMNT_DELAY;
8196 info->time_busy = ACS_MSRMNT_DELAY - survey.idle;
8197 info->time_rx = survey.obss + survey.ibss + survey.no_ctg +
8198 survey.no_pckt;
8199 info->time_tx = survey.tx;
8200 info->filled = SURVEY_INFO_NOISE_DBM | SURVEY_INFO_TIME |
8201 SURVEY_INFO_TIME_BUSY | SURVEY_INFO_TIME_RX |
8202 SURVEY_INFO_TIME_TX;
8203
8204 brcmf_dbg(INFO, "OBSS dump: channel %d: survey duration %d\n",
8205 ieee80211_frequency_to_channel(info->channel->center_freq),
8206 ACS_MSRMNT_DELAY);
8207 brcmf_dbg(INFO, "noise(%d) busy(%llu) rx(%llu) tx(%llu)\n",
8208 info->noise, info->time_busy, info->time_rx, info->time_tx);
8209
8210 exit:
8211 if (!brcmf_is_apmode(ifp->vif))
8212 brcmf_set_mpc(ifp, 1);
8213 return err;
8214 }
8215
brcmf_cfg80211_reg_notifier(struct wiphy * wiphy,struct regulatory_request * req)8216 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
8217 struct regulatory_request *req)
8218 {
8219 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
8220 struct brcmf_if *ifp = brcmf_get_ifp(cfg->pub, 0);
8221 struct brcmf_pub *drvr = cfg->pub;
8222 struct brcmf_fil_country_le ccreq;
8223 s32 err;
8224 int i;
8225
8226 /* The country code gets set to "00" by default at boot, ignore */
8227 if (req->alpha2[0] == '0' && req->alpha2[1] == '0')
8228 return;
8229
8230 /* ignore non-ISO3166 country codes */
8231 for (i = 0; i < 2; i++)
8232 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
8233 bphy_err(drvr, "not an ISO3166 code (0x%02x 0x%02x)\n",
8234 req->alpha2[0], req->alpha2[1]);
8235 return;
8236 }
8237
8238 brcmf_dbg(TRACE, "Enter: initiator=%d, alpha=%c%c\n", req->initiator,
8239 req->alpha2[0], req->alpha2[1]);
8240
8241 err = brcmf_fil_iovar_data_get(ifp, "country", &ccreq, sizeof(ccreq));
8242 if (err) {
8243 bphy_err(drvr, "Country code iovar returned err = %d\n", err);
8244 return;
8245 }
8246
8247 err = brcmf_translate_country_code(ifp->drvr, req->alpha2, &ccreq);
8248 if (err)
8249 return;
8250
8251 err = brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq));
8252 if (err) {
8253 bphy_err(drvr, "Firmware rejected country setting\n");
8254 return;
8255 }
8256 brcmf_setup_wiphybands(cfg);
8257 }
8258
brcmf_free_wiphy(struct wiphy * wiphy)8259 static void brcmf_free_wiphy(struct wiphy *wiphy)
8260 {
8261 int i;
8262
8263 if (!wiphy)
8264 return;
8265
8266 if (wiphy->iface_combinations) {
8267 for (i = 0; i < wiphy->n_iface_combinations; i++)
8268 kfree(wiphy->iface_combinations[i].limits);
8269 }
8270 kfree(wiphy->iface_combinations);
8271 if (wiphy->bands[NL80211_BAND_2GHZ]) {
8272 kfree(wiphy->bands[NL80211_BAND_2GHZ]->channels);
8273 kfree(wiphy->bands[NL80211_BAND_2GHZ]);
8274 }
8275 if (wiphy->bands[NL80211_BAND_5GHZ]) {
8276 kfree(wiphy->bands[NL80211_BAND_5GHZ]->channels);
8277 kfree(wiphy->bands[NL80211_BAND_5GHZ]);
8278 }
8279 #if IS_ENABLED(CONFIG_PM)
8280 if (wiphy->wowlan != &brcmf_wowlan_support)
8281 kfree(wiphy->wowlan);
8282 #endif
8283 }
8284
brcmf_cfg80211_attach(struct brcmf_pub * drvr,struct cfg80211_ops * ops,bool p2pdev_forced)8285 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
8286 struct cfg80211_ops *ops,
8287 bool p2pdev_forced)
8288 {
8289 struct wiphy *wiphy = drvr->wiphy;
8290 struct net_device *ndev = brcmf_get_ifp(drvr, 0)->ndev;
8291 struct brcmf_cfg80211_info *cfg;
8292 struct brcmf_cfg80211_vif *vif;
8293 struct brcmf_if *ifp;
8294 s32 err = 0;
8295 s32 io_type;
8296 u16 *cap = NULL;
8297
8298 if (!ndev) {
8299 bphy_err(drvr, "ndev is invalid\n");
8300 return NULL;
8301 }
8302
8303 cfg = kzalloc(sizeof(*cfg), GFP_KERNEL);
8304 if (!cfg) {
8305 bphy_err(drvr, "Could not allocate wiphy device\n");
8306 return NULL;
8307 }
8308
8309 cfg->wiphy = wiphy;
8310 cfg->pub = drvr;
8311 init_vif_event(&cfg->vif_event);
8312 INIT_LIST_HEAD(&cfg->vif_list);
8313
8314 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION);
8315 if (IS_ERR(vif))
8316 goto wiphy_out;
8317
8318 ifp = netdev_priv(ndev);
8319 vif->ifp = ifp;
8320 vif->wdev.netdev = ndev;
8321 ndev->ieee80211_ptr = &vif->wdev;
8322 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
8323
8324 err = wl_init_priv(cfg);
8325 if (err) {
8326 bphy_err(drvr, "Failed to init iwm_priv (%d)\n", err);
8327 brcmf_free_vif(vif);
8328 goto wiphy_out;
8329 }
8330 ifp->vif = vif;
8331
8332 /* determine d11 io type before wiphy setup */
8333 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
8334 if (err) {
8335 bphy_err(drvr, "Failed to get D11 version (%d)\n", err);
8336 goto priv_out;
8337 }
8338 cfg->d11inf.io_type = (u8)io_type;
8339 brcmu_d11_attach(&cfg->d11inf);
8340
8341 /* regulatory notifier below needs access to cfg so
8342 * assign it now.
8343 */
8344 drvr->config = cfg;
8345
8346 err = brcmf_setup_wiphy(wiphy, ifp);
8347 if (err < 0)
8348 goto priv_out;
8349
8350 brcmf_dbg(INFO, "Registering custom regulatory\n");
8351 wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
8352 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
8353 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
8354
8355 /* firmware defaults to 40MHz disabled in 2G band. We signal
8356 * cfg80211 here that we do and have it decide we can enable
8357 * it. But first check if device does support 2G operation.
8358 */
8359 if (wiphy->bands[NL80211_BAND_2GHZ]) {
8360 cap = &wiphy->bands[NL80211_BAND_2GHZ]->ht_cap.cap;
8361 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8362 }
8363 #ifdef CONFIG_PM
8364 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL_GTK))
8365 ops->set_rekey_data = brcmf_cfg80211_set_rekey_data;
8366 #endif
8367 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_DUMP_OBSS))
8368 ops->dump_survey = brcmf_cfg80211_dump_survey;
8369
8370 err = wiphy_register(wiphy);
8371 if (err < 0) {
8372 bphy_err(drvr, "Could not register wiphy device (%d)\n", err);
8373 goto priv_out;
8374 }
8375
8376 err = brcmf_setup_wiphybands(cfg);
8377 if (err) {
8378 bphy_err(drvr, "Setting wiphy bands failed (%d)\n", err);
8379 goto wiphy_unreg_out;
8380 }
8381
8382 /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
8383 * setup 40MHz in 2GHz band and enable OBSS scanning.
8384 */
8385 if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
8386 err = brcmf_enable_bw40_2g(cfg);
8387 if (!err)
8388 err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
8389 BRCMF_OBSS_COEX_AUTO);
8390 else
8391 *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
8392 }
8393
8394 err = brcmf_fweh_activate_events(ifp);
8395 if (err) {
8396 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
8397 goto wiphy_unreg_out;
8398 }
8399
8400 err = brcmf_p2p_attach(cfg, p2pdev_forced);
8401 if (err) {
8402 bphy_err(drvr, "P2P initialisation failed (%d)\n", err);
8403 goto wiphy_unreg_out;
8404 }
8405 err = brcmf_btcoex_attach(cfg);
8406 if (err) {
8407 bphy_err(drvr, "BT-coex initialisation failed (%d)\n", err);
8408 brcmf_p2p_detach(&cfg->p2p);
8409 goto wiphy_unreg_out;
8410 }
8411 err = brcmf_pno_attach(cfg);
8412 if (err) {
8413 bphy_err(drvr, "PNO initialisation failed (%d)\n", err);
8414 brcmf_btcoex_detach(cfg);
8415 brcmf_p2p_detach(&cfg->p2p);
8416 goto wiphy_unreg_out;
8417 }
8418
8419 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_TDLS)) {
8420 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
8421 if (err) {
8422 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
8423 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
8424 } else {
8425 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
8426 brcmf_notify_tdls_peer_event);
8427 }
8428 }
8429
8430 /* (re-) activate FWEH event handling */
8431 err = brcmf_fweh_activate_events(ifp);
8432 if (err) {
8433 bphy_err(drvr, "FWEH activation failed (%d)\n", err);
8434 goto detach;
8435 }
8436
8437 /* Fill in some of the advertised nl80211 supported features */
8438 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_SCAN_RANDOM_MAC)) {
8439 wiphy->features |= NL80211_FEATURE_SCHED_SCAN_RANDOM_MAC_ADDR;
8440 #ifdef CONFIG_PM
8441 if (wiphy->wowlan &&
8442 wiphy->wowlan->flags & WIPHY_WOWLAN_NET_DETECT)
8443 wiphy->features |= NL80211_FEATURE_ND_RANDOM_MAC_ADDR;
8444 #endif
8445 }
8446
8447 return cfg;
8448
8449 detach:
8450 brcmf_pno_detach(cfg);
8451 brcmf_btcoex_detach(cfg);
8452 brcmf_p2p_detach(&cfg->p2p);
8453 wiphy_unreg_out:
8454 wiphy_unregister(cfg->wiphy);
8455 priv_out:
8456 wl_deinit_priv(cfg);
8457 brcmf_free_vif(vif);
8458 ifp->vif = NULL;
8459 wiphy_out:
8460 brcmf_free_wiphy(wiphy);
8461 kfree(cfg);
8462 return NULL;
8463 }
8464
brcmf_cfg80211_detach(struct brcmf_cfg80211_info * cfg)8465 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
8466 {
8467 if (!cfg)
8468 return;
8469
8470 brcmf_pno_detach(cfg);
8471 brcmf_btcoex_detach(cfg);
8472 wiphy_unregister(cfg->wiphy);
8473 wl_deinit_priv(cfg);
8474 cancel_work_sync(&cfg->escan_timeout_work);
8475 brcmf_free_wiphy(cfg->wiphy);
8476 kfree(cfg);
8477 }
8478