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