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