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