Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net...
[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_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206 * With respect to these flags, wpa_supplicant doesn't * start p2p
207 * 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 }
1099 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1100 cfg80211_disconnected(vif->wdev.netdev, 0, NULL, 0, GFP_KERNEL);
1101
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 cfg80211_disconnected(ndev, reason_code, NULL, 0, GFP_KERNEL);
1762
1763 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1764 scbval.val = cpu_to_le32(reason_code);
1765 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1766 &scbval, sizeof(scbval));
1767 if (err)
1768 brcmf_err("error (%d)\n", err);
1769
1770 brcmf_dbg(TRACE, "Exit\n");
1771 return err;
1772 }
1773
1774 static s32
1775 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1776 enum nl80211_tx_power_setting type, s32 mbm)
1777 {
1778
1779 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1780 struct net_device *ndev = cfg_to_ndev(cfg);
1781 struct brcmf_if *ifp = netdev_priv(ndev);
1782 u16 txpwrmw;
1783 s32 err = 0;
1784 s32 disable = 0;
1785 s32 dbm = MBM_TO_DBM(mbm);
1786
1787 brcmf_dbg(TRACE, "Enter\n");
1788 if (!check_vif_up(ifp->vif))
1789 return -EIO;
1790
1791 switch (type) {
1792 case NL80211_TX_POWER_AUTOMATIC:
1793 break;
1794 case NL80211_TX_POWER_LIMITED:
1795 case NL80211_TX_POWER_FIXED:
1796 if (dbm < 0) {
1797 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1798 err = -EINVAL;
1799 goto done;
1800 }
1801 break;
1802 }
1803 /* Make sure radio is off or on as far as software is concerned */
1804 disable = WL_RADIO_SW_DISABLE << 16;
1805 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1806 if (err)
1807 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1808
1809 if (dbm > 0xffff)
1810 txpwrmw = 0xffff;
1811 else
1812 txpwrmw = (u16) dbm;
1813 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1814 (s32)brcmf_mw_to_qdbm(txpwrmw));
1815 if (err)
1816 brcmf_err("qtxpower error (%d)\n", err);
1817 cfg->conf->tx_power = dbm;
1818
1819 done:
1820 brcmf_dbg(TRACE, "Exit\n");
1821 return err;
1822 }
1823
1824 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1825 struct wireless_dev *wdev,
1826 s32 *dbm)
1827 {
1828 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1829 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1830 s32 txpwrdbm;
1831 u8 result;
1832 s32 err = 0;
1833
1834 brcmf_dbg(TRACE, "Enter\n");
1835 if (!check_vif_up(ifp->vif))
1836 return -EIO;
1837
1838 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1839 if (err) {
1840 brcmf_err("error (%d)\n", err);
1841 goto done;
1842 }
1843
1844 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1845 *dbm = (s32) brcmf_qdbm_to_mw(result);
1846
1847 done:
1848 brcmf_dbg(TRACE, "Exit\n");
1849 return err;
1850 }
1851
1852 static s32
1853 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1854 u8 key_idx, bool unicast, bool multicast)
1855 {
1856 struct brcmf_if *ifp = netdev_priv(ndev);
1857 u32 index;
1858 u32 wsec;
1859 s32 err = 0;
1860
1861 brcmf_dbg(TRACE, "Enter\n");
1862 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1863 if (!check_vif_up(ifp->vif))
1864 return -EIO;
1865
1866 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1867 if (err) {
1868 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1869 goto done;
1870 }
1871
1872 if (wsec & WEP_ENABLED) {
1873 /* Just select a new current key */
1874 index = key_idx;
1875 err = brcmf_fil_cmd_int_set(ifp,
1876 BRCMF_C_SET_KEY_PRIMARY, index);
1877 if (err)
1878 brcmf_err("error (%d)\n", err);
1879 }
1880 done:
1881 brcmf_dbg(TRACE, "Exit\n");
1882 return err;
1883 }
1884
1885 static s32
1886 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1887 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1888 {
1889 struct brcmf_if *ifp = netdev_priv(ndev);
1890 struct brcmf_wsec_key key;
1891 s32 err = 0;
1892 u8 keybuf[8];
1893
1894 memset(&key, 0, sizeof(key));
1895 key.index = (u32) key_idx;
1896 /* Instead of bcast for ea address for default wep keys,
1897 driver needs it to be Null */
1898 if (!is_multicast_ether_addr(mac_addr))
1899 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1900 key.len = (u32) params->key_len;
1901 /* check for key index change */
1902 if (key.len == 0) {
1903 /* key delete */
1904 err = send_key_to_dongle(ndev, &key);
1905 if (err)
1906 brcmf_err("key delete error (%d)\n", err);
1907 } else {
1908 if (key.len > sizeof(key.data)) {
1909 brcmf_err("Invalid key length (%d)\n", key.len);
1910 return -EINVAL;
1911 }
1912
1913 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1914 memcpy(key.data, params->key, key.len);
1915
1916 if ((ifp->vif->mode != WL_MODE_AP) &&
1917 (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
1918 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
1919 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1920 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1921 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1922 }
1923
1924 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1925 if (params->seq && params->seq_len == 6) {
1926 /* rx iv */
1927 u8 *ivptr;
1928 ivptr = (u8 *) params->seq;
1929 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1930 (ivptr[3] << 8) | ivptr[2];
1931 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1932 key.iv_initialized = true;
1933 }
1934
1935 switch (params->cipher) {
1936 case WLAN_CIPHER_SUITE_WEP40:
1937 key.algo = CRYPTO_ALGO_WEP1;
1938 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1939 break;
1940 case WLAN_CIPHER_SUITE_WEP104:
1941 key.algo = CRYPTO_ALGO_WEP128;
1942 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1943 break;
1944 case WLAN_CIPHER_SUITE_TKIP:
1945 key.algo = CRYPTO_ALGO_TKIP;
1946 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1947 break;
1948 case WLAN_CIPHER_SUITE_AES_CMAC:
1949 key.algo = CRYPTO_ALGO_AES_CCM;
1950 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1951 break;
1952 case WLAN_CIPHER_SUITE_CCMP:
1953 key.algo = CRYPTO_ALGO_AES_CCM;
1954 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1955 break;
1956 default:
1957 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1958 return -EINVAL;
1959 }
1960 err = send_key_to_dongle(ndev, &key);
1961 if (err)
1962 brcmf_err("wsec_key error (%d)\n", err);
1963 }
1964 return err;
1965 }
1966
1967 static s32
1968 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1969 u8 key_idx, bool pairwise, const u8 *mac_addr,
1970 struct key_params *params)
1971 {
1972 struct brcmf_if *ifp = netdev_priv(ndev);
1973 struct brcmf_wsec_key key;
1974 s32 val;
1975 s32 wsec;
1976 s32 err = 0;
1977 u8 keybuf[8];
1978
1979 brcmf_dbg(TRACE, "Enter\n");
1980 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1981 if (!check_vif_up(ifp->vif))
1982 return -EIO;
1983
1984 if (mac_addr) {
1985 brcmf_dbg(TRACE, "Exit");
1986 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1987 }
1988 memset(&key, 0, sizeof(key));
1989
1990 key.len = (u32) params->key_len;
1991 key.index = (u32) key_idx;
1992
1993 if (key.len > sizeof(key.data)) {
1994 brcmf_err("Too long key length (%u)\n", key.len);
1995 err = -EINVAL;
1996 goto done;
1997 }
1998 memcpy(key.data, params->key, key.len);
1999
2000 key.flags = BRCMF_PRIMARY_KEY;
2001 switch (params->cipher) {
2002 case WLAN_CIPHER_SUITE_WEP40:
2003 key.algo = CRYPTO_ALGO_WEP1;
2004 val = WEP_ENABLED;
2005 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2006 break;
2007 case WLAN_CIPHER_SUITE_WEP104:
2008 key.algo = CRYPTO_ALGO_WEP128;
2009 val = WEP_ENABLED;
2010 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2011 break;
2012 case WLAN_CIPHER_SUITE_TKIP:
2013 if (ifp->vif->mode != WL_MODE_AP) {
2014 brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2015 memcpy(keybuf, &key.data[24], sizeof(keybuf));
2016 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2017 memcpy(&key.data[16], keybuf, sizeof(keybuf));
2018 }
2019 key.algo = CRYPTO_ALGO_TKIP;
2020 val = TKIP_ENABLED;
2021 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2022 break;
2023 case WLAN_CIPHER_SUITE_AES_CMAC:
2024 key.algo = CRYPTO_ALGO_AES_CCM;
2025 val = AES_ENABLED;
2026 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2027 break;
2028 case WLAN_CIPHER_SUITE_CCMP:
2029 key.algo = CRYPTO_ALGO_AES_CCM;
2030 val = AES_ENABLED;
2031 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2032 break;
2033 default:
2034 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2035 err = -EINVAL;
2036 goto done;
2037 }
2038
2039 err = send_key_to_dongle(ndev, &key);
2040 if (err)
2041 goto done;
2042
2043 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2044 if (err) {
2045 brcmf_err("get wsec error (%d)\n", err);
2046 goto done;
2047 }
2048 wsec |= val;
2049 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2050 if (err) {
2051 brcmf_err("set wsec error (%d)\n", err);
2052 goto done;
2053 }
2054
2055 done:
2056 brcmf_dbg(TRACE, "Exit\n");
2057 return err;
2058 }
2059
2060 static s32
2061 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2062 u8 key_idx, bool pairwise, const u8 *mac_addr)
2063 {
2064 struct brcmf_if *ifp = netdev_priv(ndev);
2065 struct brcmf_wsec_key key;
2066 s32 err = 0;
2067
2068 brcmf_dbg(TRACE, "Enter\n");
2069 if (!check_vif_up(ifp->vif))
2070 return -EIO;
2071
2072 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
2073 /* we ignore this key index in this case */
2074 brcmf_err("invalid key index (%d)\n", key_idx);
2075 return -EINVAL;
2076 }
2077
2078 memset(&key, 0, sizeof(key));
2079
2080 key.index = (u32) key_idx;
2081 key.flags = BRCMF_PRIMARY_KEY;
2082 key.algo = CRYPTO_ALGO_OFF;
2083
2084 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2085
2086 /* Set the new key/index */
2087 err = send_key_to_dongle(ndev, &key);
2088
2089 brcmf_dbg(TRACE, "Exit\n");
2090 return err;
2091 }
2092
2093 static s32
2094 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2095 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2096 void (*callback) (void *cookie, struct key_params * params))
2097 {
2098 struct key_params params;
2099 struct brcmf_if *ifp = netdev_priv(ndev);
2100 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2101 struct brcmf_cfg80211_security *sec;
2102 s32 wsec;
2103 s32 err = 0;
2104
2105 brcmf_dbg(TRACE, "Enter\n");
2106 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2107 if (!check_vif_up(ifp->vif))
2108 return -EIO;
2109
2110 memset(&params, 0, sizeof(params));
2111
2112 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2113 if (err) {
2114 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2115 /* Ignore this error, may happen during DISASSOC */
2116 err = -EAGAIN;
2117 goto done;
2118 }
2119 if (wsec & WEP_ENABLED) {
2120 sec = &profile->sec;
2121 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2122 params.cipher = WLAN_CIPHER_SUITE_WEP40;
2123 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2124 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2125 params.cipher = WLAN_CIPHER_SUITE_WEP104;
2126 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2127 }
2128 } else if (wsec & TKIP_ENABLED) {
2129 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2130 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2131 } else if (wsec & AES_ENABLED) {
2132 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2133 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2134 } else {
2135 brcmf_err("Invalid algo (0x%x)\n", wsec);
2136 err = -EINVAL;
2137 goto done;
2138 }
2139 callback(cookie, &params);
2140
2141 done:
2142 brcmf_dbg(TRACE, "Exit\n");
2143 return err;
2144 }
2145
2146 static s32
2147 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2148 struct net_device *ndev, u8 key_idx)
2149 {
2150 brcmf_dbg(INFO, "Not supported\n");
2151
2152 return -EOPNOTSUPP;
2153 }
2154
2155 static s32
2156 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2157 u8 *mac, struct station_info *sinfo)
2158 {
2159 struct brcmf_if *ifp = netdev_priv(ndev);
2160 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2161 struct brcmf_scb_val_le scb_val;
2162 int rssi;
2163 s32 rate;
2164 s32 err = 0;
2165 u8 *bssid = profile->bssid;
2166 struct brcmf_sta_info_le sta_info_le;
2167
2168 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2169 if (!check_vif_up(ifp->vif))
2170 return -EIO;
2171
2172 if (ifp->vif->mode == WL_MODE_AP) {
2173 memcpy(&sta_info_le, mac, ETH_ALEN);
2174 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2175 &sta_info_le,
2176 sizeof(sta_info_le));
2177 if (err < 0) {
2178 brcmf_err("GET STA INFO failed, %d\n", err);
2179 goto done;
2180 }
2181 sinfo->filled = STATION_INFO_INACTIVE_TIME;
2182 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2183 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
2184 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
2185 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2186 }
2187 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
2188 sinfo->inactive_time, sinfo->connected_time);
2189 } else if (ifp->vif->mode == WL_MODE_BSS) {
2190 if (memcmp(mac, bssid, ETH_ALEN)) {
2191 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
2192 mac, bssid);
2193 err = -ENOENT;
2194 goto done;
2195 }
2196 /* Report the current tx rate */
2197 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
2198 if (err) {
2199 brcmf_err("Could not get rate (%d)\n", err);
2200 goto done;
2201 } else {
2202 sinfo->filled |= STATION_INFO_TX_BITRATE;
2203 sinfo->txrate.legacy = rate * 5;
2204 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
2205 }
2206
2207 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
2208 &ifp->vif->sme_state)) {
2209 memset(&scb_val, 0, sizeof(scb_val));
2210 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
2211 &scb_val, sizeof(scb_val));
2212 if (err) {
2213 brcmf_err("Could not get rssi (%d)\n", err);
2214 goto done;
2215 } else {
2216 rssi = le32_to_cpu(scb_val.val);
2217 sinfo->filled |= STATION_INFO_SIGNAL;
2218 sinfo->signal = rssi;
2219 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
2220 }
2221 }
2222 } else
2223 err = -EPERM;
2224 done:
2225 brcmf_dbg(TRACE, "Exit\n");
2226 return err;
2227 }
2228
2229 static s32
2230 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2231 bool enabled, s32 timeout)
2232 {
2233 s32 pm;
2234 s32 err = 0;
2235 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2236 struct brcmf_if *ifp = netdev_priv(ndev);
2237
2238 brcmf_dbg(TRACE, "Enter\n");
2239
2240 /*
2241 * Powersave enable/disable request is coming from the
2242 * cfg80211 even before the interface is up. In that
2243 * scenario, driver will be storing the power save
2244 * preference in cfg struct to apply this to
2245 * FW later while initializing the dongle
2246 */
2247 cfg->pwr_save = enabled;
2248 if (!check_vif_up(ifp->vif)) {
2249
2250 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2251 goto done;
2252 }
2253
2254 pm = enabled ? PM_FAST : PM_OFF;
2255 /* Do not enable the power save after assoc if it is a p2p interface */
2256 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2257 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2258 pm = PM_OFF;
2259 }
2260 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2261
2262 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2263 if (err) {
2264 if (err == -ENODEV)
2265 brcmf_err("net_device is not ready yet\n");
2266 else
2267 brcmf_err("error (%d)\n", err);
2268 }
2269 done:
2270 brcmf_dbg(TRACE, "Exit\n");
2271 return err;
2272 }
2273
2274 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2275 struct brcmf_bss_info_le *bi)
2276 {
2277 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2278 struct ieee80211_channel *notify_channel;
2279 struct cfg80211_bss *bss;
2280 struct ieee80211_supported_band *band;
2281 struct brcmu_chan ch;
2282 s32 err = 0;
2283 u16 channel;
2284 u32 freq;
2285 u16 notify_capability;
2286 u16 notify_interval;
2287 u8 *notify_ie;
2288 size_t notify_ielen;
2289 s32 notify_signal;
2290
2291 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2292 brcmf_err("Bss info is larger than buffer. Discarding\n");
2293 return 0;
2294 }
2295
2296 if (!bi->ctl_ch) {
2297 ch.chspec = le16_to_cpu(bi->chanspec);
2298 cfg->d11inf.decchspec(&ch);
2299 bi->ctl_ch = ch.chnum;
2300 }
2301 channel = bi->ctl_ch;
2302
2303 if (channel <= CH_MAX_2G_CHANNEL)
2304 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2305 else
2306 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2307
2308 freq = ieee80211_channel_to_frequency(channel, band->band);
2309 notify_channel = ieee80211_get_channel(wiphy, freq);
2310
2311 notify_capability = le16_to_cpu(bi->capability);
2312 notify_interval = le16_to_cpu(bi->beacon_period);
2313 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2314 notify_ielen = le32_to_cpu(bi->ie_length);
2315 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2316
2317 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2318 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2319 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2320 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2321 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2322
2323 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2324 0, notify_capability, notify_interval, notify_ie,
2325 notify_ielen, notify_signal, GFP_KERNEL);
2326
2327 if (!bss)
2328 return -ENOMEM;
2329
2330 cfg80211_put_bss(wiphy, bss);
2331
2332 return err;
2333 }
2334
2335 static struct brcmf_bss_info_le *
2336 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2337 {
2338 if (bss == NULL)
2339 return list->bss_info_le;
2340 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2341 le32_to_cpu(bss->length));
2342 }
2343
2344 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2345 {
2346 struct brcmf_scan_results *bss_list;
2347 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2348 s32 err = 0;
2349 int i;
2350
2351 bss_list = cfg->bss_list;
2352 if (bss_list->count != 0 &&
2353 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2354 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2355 bss_list->version);
2356 return -EOPNOTSUPP;
2357 }
2358 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2359 for (i = 0; i < bss_list->count; i++) {
2360 bi = next_bss_le(bss_list, bi);
2361 err = brcmf_inform_single_bss(cfg, bi);
2362 if (err)
2363 break;
2364 }
2365 return err;
2366 }
2367
2368 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2369 struct net_device *ndev, const u8 *bssid)
2370 {
2371 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2372 struct ieee80211_channel *notify_channel;
2373 struct brcmf_bss_info_le *bi = NULL;
2374 struct ieee80211_supported_band *band;
2375 struct cfg80211_bss *bss;
2376 struct brcmu_chan ch;
2377 u8 *buf = NULL;
2378 s32 err = 0;
2379 u32 freq;
2380 u16 notify_capability;
2381 u16 notify_interval;
2382 u8 *notify_ie;
2383 size_t notify_ielen;
2384 s32 notify_signal;
2385
2386 brcmf_dbg(TRACE, "Enter\n");
2387
2388 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2389 if (buf == NULL) {
2390 err = -ENOMEM;
2391 goto CleanUp;
2392 }
2393
2394 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2395
2396 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2397 buf, WL_BSS_INFO_MAX);
2398 if (err) {
2399 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2400 goto CleanUp;
2401 }
2402
2403 bi = (struct brcmf_bss_info_le *)(buf + 4);
2404
2405 ch.chspec = le16_to_cpu(bi->chanspec);
2406 cfg->d11inf.decchspec(&ch);
2407
2408 if (ch.band == BRCMU_CHAN_BAND_2G)
2409 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2410 else
2411 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2412
2413 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2414 notify_channel = ieee80211_get_channel(wiphy, freq);
2415
2416 notify_capability = le16_to_cpu(bi->capability);
2417 notify_interval = le16_to_cpu(bi->beacon_period);
2418 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2419 notify_ielen = le32_to_cpu(bi->ie_length);
2420 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2421
2422 brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2423 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2424 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2425 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2426
2427 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2428 0, notify_capability, notify_interval,
2429 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2430
2431 if (!bss) {
2432 err = -ENOMEM;
2433 goto CleanUp;
2434 }
2435
2436 cfg80211_put_bss(wiphy, bss);
2437
2438 CleanUp:
2439
2440 kfree(buf);
2441
2442 brcmf_dbg(TRACE, "Exit\n");
2443
2444 return err;
2445 }
2446
2447 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2448 {
2449 return vif->mode == WL_MODE_IBSS;
2450 }
2451
2452 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2453 struct brcmf_if *ifp)
2454 {
2455 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2456 struct brcmf_bss_info_le *bi;
2457 struct brcmf_ssid *ssid;
2458 struct brcmf_tlv *tim;
2459 u16 beacon_interval;
2460 u8 dtim_period;
2461 size_t ie_len;
2462 u8 *ie;
2463 s32 err = 0;
2464
2465 brcmf_dbg(TRACE, "Enter\n");
2466 if (brcmf_is_ibssmode(ifp->vif))
2467 return err;
2468
2469 ssid = &profile->ssid;
2470
2471 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2472 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2473 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2474 if (err) {
2475 brcmf_err("Could not get bss info %d\n", err);
2476 goto update_bss_info_out;
2477 }
2478
2479 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2480 err = brcmf_inform_single_bss(cfg, bi);
2481 if (err)
2482 goto update_bss_info_out;
2483
2484 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2485 ie_len = le32_to_cpu(bi->ie_length);
2486 beacon_interval = le16_to_cpu(bi->beacon_period);
2487
2488 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2489 if (tim)
2490 dtim_period = tim->data[1];
2491 else {
2492 /*
2493 * active scan was done so we could not get dtim
2494 * information out of probe response.
2495 * so we speficially query dtim information to dongle.
2496 */
2497 u32 var;
2498 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2499 if (err) {
2500 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2501 goto update_bss_info_out;
2502 }
2503 dtim_period = (u8)var;
2504 }
2505
2506 update_bss_info_out:
2507 brcmf_dbg(TRACE, "Exit");
2508 return err;
2509 }
2510
2511 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2512 {
2513 struct escan_info *escan = &cfg->escan_info;
2514
2515 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2516 if (cfg->scan_request) {
2517 escan->escan_state = WL_ESCAN_STATE_IDLE;
2518 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2519 }
2520 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2521 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2522 }
2523
2524 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2525 {
2526 struct brcmf_cfg80211_info *cfg =
2527 container_of(work, struct brcmf_cfg80211_info,
2528 escan_timeout_work);
2529
2530 brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2531 }
2532
2533 static void brcmf_escan_timeout(unsigned long data)
2534 {
2535 struct brcmf_cfg80211_info *cfg =
2536 (struct brcmf_cfg80211_info *)data;
2537
2538 if (cfg->scan_request) {
2539 brcmf_err("timer expired\n");
2540 schedule_work(&cfg->escan_timeout_work);
2541 }
2542 }
2543
2544 static s32
2545 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2546 struct brcmf_bss_info_le *bss,
2547 struct brcmf_bss_info_le *bss_info_le)
2548 {
2549 struct brcmu_chan ch_bss, ch_bss_info_le;
2550
2551 ch_bss.chspec = le16_to_cpu(bss->chanspec);
2552 cfg->d11inf.decchspec(&ch_bss);
2553 ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2554 cfg->d11inf.decchspec(&ch_bss_info_le);
2555
2556 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2557 ch_bss.band == ch_bss_info_le.band &&
2558 bss_info_le->SSID_len == bss->SSID_len &&
2559 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2560 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2561 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2562 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2563 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2564
2565 /* preserve max RSSI if the measurements are
2566 * both on-channel or both off-channel
2567 */
2568 if (bss_info_rssi > bss_rssi)
2569 bss->RSSI = bss_info_le->RSSI;
2570 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2571 (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2572 /* preserve the on-channel rssi measurement
2573 * if the new measurement is off channel
2574 */
2575 bss->RSSI = bss_info_le->RSSI;
2576 bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2577 }
2578 return 1;
2579 }
2580 return 0;
2581 }
2582
2583 static s32
2584 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2585 const struct brcmf_event_msg *e, void *data)
2586 {
2587 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2588 s32 status;
2589 s32 err = 0;
2590 struct brcmf_escan_result_le *escan_result_le;
2591 struct brcmf_bss_info_le *bss_info_le;
2592 struct brcmf_bss_info_le *bss = NULL;
2593 u32 bi_length;
2594 struct brcmf_scan_results *list;
2595 u32 i;
2596 bool aborted;
2597
2598 status = e->status;
2599
2600 if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2601 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2602 return -EPERM;
2603 }
2604
2605 if (status == BRCMF_E_STATUS_PARTIAL) {
2606 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2607 escan_result_le = (struct brcmf_escan_result_le *) data;
2608 if (!escan_result_le) {
2609 brcmf_err("Invalid escan result (NULL pointer)\n");
2610 goto exit;
2611 }
2612 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2613 brcmf_err("Invalid bss_count %d: ignoring\n",
2614 escan_result_le->bss_count);
2615 goto exit;
2616 }
2617 bss_info_le = &escan_result_le->bss_info_le;
2618
2619 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2620 goto exit;
2621
2622 if (!cfg->scan_request) {
2623 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2624 goto exit;
2625 }
2626
2627 bi_length = le32_to_cpu(bss_info_le->length);
2628 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2629 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2630 brcmf_err("Invalid bss_info length %d: ignoring\n",
2631 bi_length);
2632 goto exit;
2633 }
2634
2635 if (!(cfg_to_wiphy(cfg)->interface_modes &
2636 BIT(NL80211_IFTYPE_ADHOC))) {
2637 if (le16_to_cpu(bss_info_le->capability) &
2638 WLAN_CAPABILITY_IBSS) {
2639 brcmf_err("Ignoring IBSS result\n");
2640 goto exit;
2641 }
2642 }
2643
2644 list = (struct brcmf_scan_results *)
2645 cfg->escan_info.escan_buf;
2646 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2647 brcmf_err("Buffer is too small: ignoring\n");
2648 goto exit;
2649 }
2650
2651 for (i = 0; i < list->count; i++) {
2652 bss = bss ? (struct brcmf_bss_info_le *)
2653 ((unsigned char *)bss +
2654 le32_to_cpu(bss->length)) : list->bss_info_le;
2655 if (brcmf_compare_update_same_bss(cfg, bss,
2656 bss_info_le))
2657 goto exit;
2658 }
2659 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2660 bss_info_le, bi_length);
2661 list->version = le32_to_cpu(bss_info_le->version);
2662 list->buflen += bi_length;
2663 list->count++;
2664 } else {
2665 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2666 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2667 goto exit;
2668 if (cfg->scan_request) {
2669 cfg->bss_list = (struct brcmf_scan_results *)
2670 cfg->escan_info.escan_buf;
2671 brcmf_inform_bss(cfg);
2672 aborted = status != BRCMF_E_STATUS_SUCCESS;
2673 brcmf_notify_escan_complete(cfg, ifp, aborted,
2674 false);
2675 } else
2676 brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2677 status);
2678 }
2679 exit:
2680 return err;
2681 }
2682
2683 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2684 {
2685 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2686 brcmf_cfg80211_escan_handler);
2687 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2688 /* Init scan_timeout timer */
2689 init_timer(&cfg->escan_timeout);
2690 cfg->escan_timeout.data = (unsigned long) cfg;
2691 cfg->escan_timeout.function = brcmf_escan_timeout;
2692 INIT_WORK(&cfg->escan_timeout_work,
2693 brcmf_cfg80211_escan_timeout_worker);
2694 }
2695
2696 static __always_inline void brcmf_delay(u32 ms)
2697 {
2698 if (ms < 1000 / HZ) {
2699 cond_resched();
2700 mdelay(ms);
2701 } else {
2702 msleep(ms);
2703 }
2704 }
2705
2706 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2707 {
2708 brcmf_dbg(TRACE, "Enter\n");
2709
2710 return 0;
2711 }
2712
2713 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2714 struct cfg80211_wowlan *wow)
2715 {
2716 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2717 struct net_device *ndev = cfg_to_ndev(cfg);
2718 struct brcmf_cfg80211_vif *vif;
2719
2720 brcmf_dbg(TRACE, "Enter\n");
2721
2722 /*
2723 * if the primary net_device is not READY there is nothing
2724 * we can do but pray resume goes smoothly.
2725 */
2726 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2727 if (!check_vif_up(vif))
2728 goto exit;
2729
2730 list_for_each_entry(vif, &cfg->vif_list, list) {
2731 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2732 continue;
2733 /*
2734 * While going to suspend if associated with AP disassociate
2735 * from AP to save power while system is in suspended state
2736 */
2737 brcmf_link_down(vif);
2738
2739 /* Make sure WPA_Supplicant receives all the event
2740 * generated due to DISASSOC call to the fw to keep
2741 * the state fw and WPA_Supplicant state consistent
2742 */
2743 brcmf_delay(500);
2744 }
2745
2746 /* end any scanning */
2747 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2748 brcmf_abort_scanning(cfg);
2749
2750 /* Turn off watchdog timer */
2751 brcmf_set_mpc(netdev_priv(ndev), 1);
2752
2753 exit:
2754 brcmf_dbg(TRACE, "Exit\n");
2755 /* clear any scanning activity */
2756 cfg->scan_status = 0;
2757 return 0;
2758 }
2759
2760 static __used s32
2761 brcmf_update_pmklist(struct net_device *ndev,
2762 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2763 {
2764 int i, j;
2765 int pmkid_len;
2766
2767 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2768
2769 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2770 for (i = 0; i < pmkid_len; i++) {
2771 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2772 &pmk_list->pmkids.pmkid[i].BSSID);
2773 for (j = 0; j < WLAN_PMKID_LEN; j++)
2774 brcmf_dbg(CONN, "%02x\n",
2775 pmk_list->pmkids.pmkid[i].PMKID[j]);
2776 }
2777
2778 if (!err)
2779 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2780 (char *)pmk_list, sizeof(*pmk_list));
2781
2782 return err;
2783 }
2784
2785 static s32
2786 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2787 struct cfg80211_pmksa *pmksa)
2788 {
2789 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2790 struct brcmf_if *ifp = netdev_priv(ndev);
2791 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2792 s32 err = 0;
2793 int i;
2794 int pmkid_len;
2795
2796 brcmf_dbg(TRACE, "Enter\n");
2797 if (!check_vif_up(ifp->vif))
2798 return -EIO;
2799
2800 pmkid_len = le32_to_cpu(pmkids->npmkid);
2801 for (i = 0; i < pmkid_len; i++)
2802 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2803 break;
2804 if (i < WL_NUM_PMKIDS_MAX) {
2805 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2806 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2807 if (i == pmkid_len) {
2808 pmkid_len++;
2809 pmkids->npmkid = cpu_to_le32(pmkid_len);
2810 }
2811 } else
2812 err = -EINVAL;
2813
2814 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2815 pmkids->pmkid[pmkid_len].BSSID);
2816 for (i = 0; i < WLAN_PMKID_LEN; i++)
2817 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2818
2819 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2820
2821 brcmf_dbg(TRACE, "Exit\n");
2822 return err;
2823 }
2824
2825 static s32
2826 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2827 struct cfg80211_pmksa *pmksa)
2828 {
2829 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2830 struct brcmf_if *ifp = netdev_priv(ndev);
2831 struct pmkid_list pmkid;
2832 s32 err = 0;
2833 int i, pmkid_len;
2834
2835 brcmf_dbg(TRACE, "Enter\n");
2836 if (!check_vif_up(ifp->vif))
2837 return -EIO;
2838
2839 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2840 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2841
2842 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2843 &pmkid.pmkid[0].BSSID);
2844 for (i = 0; i < WLAN_PMKID_LEN; i++)
2845 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2846
2847 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2848 for (i = 0; i < pmkid_len; i++)
2849 if (!memcmp
2850 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2851 ETH_ALEN))
2852 break;
2853
2854 if ((pmkid_len > 0)
2855 && (i < pmkid_len)) {
2856 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2857 sizeof(struct pmkid));
2858 for (; i < (pmkid_len - 1); i++) {
2859 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2860 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2861 ETH_ALEN);
2862 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2863 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2864 WLAN_PMKID_LEN);
2865 }
2866 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2867 } else
2868 err = -EINVAL;
2869
2870 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2871
2872 brcmf_dbg(TRACE, "Exit\n");
2873 return err;
2874
2875 }
2876
2877 static s32
2878 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2879 {
2880 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2881 struct brcmf_if *ifp = netdev_priv(ndev);
2882 s32 err = 0;
2883
2884 brcmf_dbg(TRACE, "Enter\n");
2885 if (!check_vif_up(ifp->vif))
2886 return -EIO;
2887
2888 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2889 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2890
2891 brcmf_dbg(TRACE, "Exit\n");
2892 return err;
2893
2894 }
2895
2896 /*
2897 * PFN result doesn't have all the info which are
2898 * required by the supplicant
2899 * (For e.g IEs) Do a target Escan so that sched scan results are reported
2900 * via wl_inform_single_bss in the required format. Escan does require the
2901 * scan request in the form of cfg80211_scan_request. For timebeing, create
2902 * cfg80211_scan_request one out of the received PNO event.
2903 */
2904 static s32
2905 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2906 const struct brcmf_event_msg *e, void *data)
2907 {
2908 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2909 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2910 struct cfg80211_scan_request *request = NULL;
2911 struct cfg80211_ssid *ssid = NULL;
2912 struct ieee80211_channel *channel = NULL;
2913 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2914 int err = 0;
2915 int channel_req = 0;
2916 int band = 0;
2917 struct brcmf_pno_scanresults_le *pfn_result;
2918 u32 result_count;
2919 u32 status;
2920
2921 brcmf_dbg(SCAN, "Enter\n");
2922
2923 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2924 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2925 return 0;
2926 }
2927
2928 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2929 result_count = le32_to_cpu(pfn_result->count);
2930 status = le32_to_cpu(pfn_result->status);
2931
2932 /*
2933 * PFN event is limited to fit 512 bytes so we may get
2934 * multiple NET_FOUND events. For now place a warning here.
2935 */
2936 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2937 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2938 if (result_count > 0) {
2939 int i;
2940
2941 request = kzalloc(sizeof(*request), GFP_KERNEL);
2942 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2943 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2944 if (!request || !ssid || !channel) {
2945 err = -ENOMEM;
2946 goto out_err;
2947 }
2948
2949 request->wiphy = wiphy;
2950 data += sizeof(struct brcmf_pno_scanresults_le);
2951 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2952
2953 for (i = 0; i < result_count; i++) {
2954 netinfo = &netinfo_start[i];
2955 if (!netinfo) {
2956 brcmf_err("Invalid netinfo ptr. index: %d\n",
2957 i);
2958 err = -EINVAL;
2959 goto out_err;
2960 }
2961
2962 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2963 netinfo->SSID, netinfo->channel);
2964 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2965 ssid[i].ssid_len = netinfo->SSID_len;
2966 request->n_ssids++;
2967
2968 channel_req = netinfo->channel;
2969 if (channel_req <= CH_MAX_2G_CHANNEL)
2970 band = NL80211_BAND_2GHZ;
2971 else
2972 band = NL80211_BAND_5GHZ;
2973 channel[i].center_freq =
2974 ieee80211_channel_to_frequency(channel_req,
2975 band);
2976 channel[i].band = band;
2977 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2978 request->channels[i] = &channel[i];
2979 request->n_channels++;
2980 }
2981
2982 /* assign parsed ssid array */
2983 if (request->n_ssids)
2984 request->ssids = &ssid[0];
2985
2986 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2987 /* Abort any on-going scan */
2988 brcmf_abort_scanning(cfg);
2989 }
2990
2991 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2992 err = brcmf_do_escan(cfg, wiphy, ifp, request);
2993 if (err) {
2994 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2995 goto out_err;
2996 }
2997 cfg->sched_escan = true;
2998 cfg->scan_request = request;
2999 } else {
3000 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3001 goto out_err;
3002 }
3003
3004 kfree(ssid);
3005 kfree(channel);
3006 kfree(request);
3007 return 0;
3008
3009 out_err:
3010 kfree(ssid);
3011 kfree(channel);
3012 kfree(request);
3013 cfg80211_sched_scan_stopped(wiphy);
3014 return err;
3015 }
3016
3017 static int brcmf_dev_pno_clean(struct net_device *ndev)
3018 {
3019 int ret;
3020
3021 /* Disable pfn */
3022 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3023 if (ret == 0) {
3024 /* clear pfn */
3025 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3026 NULL, 0);
3027 }
3028 if (ret < 0)
3029 brcmf_err("failed code %d\n", ret);
3030
3031 return ret;
3032 }
3033
3034 static int brcmf_dev_pno_config(struct net_device *ndev)
3035 {
3036 struct brcmf_pno_param_le pfn_param;
3037
3038 memset(&pfn_param, 0, sizeof(pfn_param));
3039 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3040
3041 /* set extra pno params */
3042 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3043 pfn_param.repeat = BRCMF_PNO_REPEAT;
3044 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3045
3046 /* set up pno scan fr */
3047 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3048
3049 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3050 &pfn_param, sizeof(pfn_param));
3051 }
3052
3053 static int
3054 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3055 struct net_device *ndev,
3056 struct cfg80211_sched_scan_request *request)
3057 {
3058 struct brcmf_if *ifp = netdev_priv(ndev);
3059 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3060 struct brcmf_pno_net_param_le pfn;
3061 int i;
3062 int ret = 0;
3063
3064 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3065 request->n_match_sets, request->n_ssids);
3066 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3067 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3068 return -EAGAIN;
3069 }
3070 if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3071 brcmf_err("Scanning suppressed: status (%lu)\n",
3072 cfg->scan_status);
3073 return -EAGAIN;
3074 }
3075
3076 if (!request->n_ssids || !request->n_match_sets) {
3077 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
3078 request->n_ssids);
3079 return -EINVAL;
3080 }
3081
3082 if (request->n_ssids > 0) {
3083 for (i = 0; i < request->n_ssids; i++) {
3084 /* Active scan req for ssids */
3085 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3086 request->ssids[i].ssid);
3087
3088 /*
3089 * match_set ssids is a supert set of n_ssid list,
3090 * so we need not add these set seperately.
3091 */
3092 }
3093 }
3094
3095 if (request->n_match_sets > 0) {
3096 /* clean up everything */
3097 ret = brcmf_dev_pno_clean(ndev);
3098 if (ret < 0) {
3099 brcmf_err("failed error=%d\n", ret);
3100 return ret;
3101 }
3102
3103 /* configure pno */
3104 ret = brcmf_dev_pno_config(ndev);
3105 if (ret < 0) {
3106 brcmf_err("PNO setup failed!! ret=%d\n", ret);
3107 return -EINVAL;
3108 }
3109
3110 /* configure each match set */
3111 for (i = 0; i < request->n_match_sets; i++) {
3112 struct cfg80211_ssid *ssid;
3113 u32 ssid_len;
3114
3115 ssid = &request->match_sets[i].ssid;
3116 ssid_len = ssid->ssid_len;
3117
3118 if (!ssid_len) {
3119 brcmf_err("skip broadcast ssid\n");
3120 continue;
3121 }
3122 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3123 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3124 pfn.wsec = cpu_to_le32(0);
3125 pfn.infra = cpu_to_le32(1);
3126 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3127 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3128 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3129 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3130 sizeof(pfn));
3131 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3132 ret == 0 ? "set" : "failed", ssid->ssid);
3133 }
3134 /* Enable the PNO */
3135 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3136 brcmf_err("PNO enable failed!! ret=%d\n", ret);
3137 return -EINVAL;
3138 }
3139 } else {
3140 return -EINVAL;
3141 }
3142
3143 return 0;
3144 }
3145
3146 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3147 struct net_device *ndev)
3148 {
3149 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3150
3151 brcmf_dbg(SCAN, "enter\n");
3152 brcmf_dev_pno_clean(ndev);
3153 if (cfg->sched_escan)
3154 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3155 return 0;
3156 }
3157
3158 #ifdef CONFIG_NL80211_TESTMODE
3159 static int brcmf_cfg80211_testmode(struct wiphy *wiphy,
3160 struct wireless_dev *wdev,
3161 void *data, int len)
3162 {
3163 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3164 struct net_device *ndev = cfg_to_ndev(cfg);
3165 struct brcmf_dcmd *dcmd = data;
3166 struct sk_buff *reply;
3167 int ret;
3168
3169 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3170 dcmd->buf, dcmd->len);
3171
3172 if (dcmd->set)
3173 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3174 dcmd->buf, dcmd->len);
3175 else
3176 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3177 dcmd->buf, dcmd->len);
3178 if (ret == 0) {
3179 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3180 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3181 ret = cfg80211_testmode_reply(reply);
3182 }
3183 return ret;
3184 }
3185 #endif
3186
3187 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3188 {
3189 s32 err;
3190
3191 /* set auth */
3192 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3193 if (err < 0) {
3194 brcmf_err("auth error %d\n", err);
3195 return err;
3196 }
3197 /* set wsec */
3198 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3199 if (err < 0) {
3200 brcmf_err("wsec error %d\n", err);
3201 return err;
3202 }
3203 /* set upper-layer auth */
3204 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3205 if (err < 0) {
3206 brcmf_err("wpa_auth error %d\n", err);
3207 return err;
3208 }
3209
3210 return 0;
3211 }
3212
3213 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3214 {
3215 if (is_rsn_ie)
3216 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3217
3218 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3219 }
3220
3221 static s32
3222 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3223 bool is_rsn_ie)
3224 {
3225 struct brcmf_if *ifp = netdev_priv(ndev);
3226 u32 auth = 0; /* d11 open authentication */
3227 u16 count;
3228 s32 err = 0;
3229 s32 len = 0;
3230 u32 i;
3231 u32 wsec;
3232 u32 pval = 0;
3233 u32 gval = 0;
3234 u32 wpa_auth = 0;
3235 u32 offset;
3236 u8 *data;
3237 u16 rsn_cap;
3238 u32 wme_bss_disable;
3239
3240 brcmf_dbg(TRACE, "Enter\n");
3241 if (wpa_ie == NULL)
3242 goto exit;
3243
3244 len = wpa_ie->len + TLV_HDR_LEN;
3245 data = (u8 *)wpa_ie;
3246 offset = TLV_HDR_LEN;
3247 if (!is_rsn_ie)
3248 offset += VS_IE_FIXED_HDR_LEN;
3249 else
3250 offset += WPA_IE_VERSION_LEN;
3251
3252 /* check for multicast cipher suite */
3253 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3254 err = -EINVAL;
3255 brcmf_err("no multicast cipher suite\n");
3256 goto exit;
3257 }
3258
3259 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3260 err = -EINVAL;
3261 brcmf_err("ivalid OUI\n");
3262 goto exit;
3263 }
3264 offset += TLV_OUI_LEN;
3265
3266 /* pick up multicast cipher */
3267 switch (data[offset]) {
3268 case WPA_CIPHER_NONE:
3269 gval = 0;
3270 break;
3271 case WPA_CIPHER_WEP_40:
3272 case WPA_CIPHER_WEP_104:
3273 gval = WEP_ENABLED;
3274 break;
3275 case WPA_CIPHER_TKIP:
3276 gval = TKIP_ENABLED;
3277 break;
3278 case WPA_CIPHER_AES_CCM:
3279 gval = AES_ENABLED;
3280 break;
3281 default:
3282 err = -EINVAL;
3283 brcmf_err("Invalid multi cast cipher info\n");
3284 goto exit;
3285 }
3286
3287 offset++;
3288 /* walk thru unicast cipher list and pick up what we recognize */
3289 count = data[offset] + (data[offset + 1] << 8);
3290 offset += WPA_IE_SUITE_COUNT_LEN;
3291 /* Check for unicast suite(s) */
3292 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3293 err = -EINVAL;
3294 brcmf_err("no unicast cipher suite\n");
3295 goto exit;
3296 }
3297 for (i = 0; i < count; i++) {
3298 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3299 err = -EINVAL;
3300 brcmf_err("ivalid OUI\n");
3301 goto exit;
3302 }
3303 offset += TLV_OUI_LEN;
3304 switch (data[offset]) {
3305 case WPA_CIPHER_NONE:
3306 break;
3307 case WPA_CIPHER_WEP_40:
3308 case WPA_CIPHER_WEP_104:
3309 pval |= WEP_ENABLED;
3310 break;
3311 case WPA_CIPHER_TKIP:
3312 pval |= TKIP_ENABLED;
3313 break;
3314 case WPA_CIPHER_AES_CCM:
3315 pval |= AES_ENABLED;
3316 break;
3317 default:
3318 brcmf_err("Ivalid unicast security info\n");
3319 }
3320 offset++;
3321 }
3322 /* walk thru auth management suite list and pick up what we recognize */
3323 count = data[offset] + (data[offset + 1] << 8);
3324 offset += WPA_IE_SUITE_COUNT_LEN;
3325 /* Check for auth key management suite(s) */
3326 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3327 err = -EINVAL;
3328 brcmf_err("no auth key mgmt suite\n");
3329 goto exit;
3330 }
3331 for (i = 0; i < count; i++) {
3332 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3333 err = -EINVAL;
3334 brcmf_err("ivalid OUI\n");
3335 goto exit;
3336 }
3337 offset += TLV_OUI_LEN;
3338 switch (data[offset]) {
3339 case RSN_AKM_NONE:
3340 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3341 wpa_auth |= WPA_AUTH_NONE;
3342 break;
3343 case RSN_AKM_UNSPECIFIED:
3344 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3345 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3346 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3347 break;
3348 case RSN_AKM_PSK:
3349 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3350 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3351 (wpa_auth |= WPA_AUTH_PSK);
3352 break;
3353 default:
3354 brcmf_err("Ivalid key mgmt info\n");
3355 }
3356 offset++;
3357 }
3358
3359 if (is_rsn_ie) {
3360 wme_bss_disable = 1;
3361 if ((offset + RSN_CAP_LEN) <= len) {
3362 rsn_cap = data[offset] + (data[offset + 1] << 8);
3363 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3364 wme_bss_disable = 0;
3365 }
3366 /* set wme_bss_disable to sync RSN Capabilities */
3367 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3368 wme_bss_disable);
3369 if (err < 0) {
3370 brcmf_err("wme_bss_disable error %d\n", err);
3371 goto exit;
3372 }
3373 }
3374 /* FOR WPS , set SES_OW_ENABLED */
3375 wsec = (pval | gval | SES_OW_ENABLED);
3376
3377 /* set auth */
3378 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3379 if (err < 0) {
3380 brcmf_err("auth error %d\n", err);
3381 goto exit;
3382 }
3383 /* set wsec */
3384 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3385 if (err < 0) {
3386 brcmf_err("wsec error %d\n", err);
3387 goto exit;
3388 }
3389 /* set upper-layer auth */
3390 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3391 if (err < 0) {
3392 brcmf_err("wpa_auth error %d\n", err);
3393 goto exit;
3394 }
3395
3396 exit:
3397 return err;
3398 }
3399
3400 static s32
3401 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3402 struct parsed_vndr_ies *vndr_ies)
3403 {
3404 s32 err = 0;
3405 struct brcmf_vs_tlv *vndrie;
3406 struct brcmf_tlv *ie;
3407 struct parsed_vndr_ie_info *parsed_info;
3408 s32 remaining_len;
3409
3410 remaining_len = (s32)vndr_ie_len;
3411 memset(vndr_ies, 0, sizeof(*vndr_ies));
3412
3413 ie = (struct brcmf_tlv *)vndr_ie_buf;
3414 while (ie) {
3415 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3416 goto next;
3417 vndrie = (struct brcmf_vs_tlv *)ie;
3418 /* len should be bigger than OUI length + one */
3419 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3420 brcmf_err("invalid vndr ie. length is too small %d\n",
3421 vndrie->len);
3422 goto next;
3423 }
3424 /* if wpa or wme ie, do not add ie */
3425 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3426 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3427 (vndrie->oui_type == WME_OUI_TYPE))) {
3428 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3429 goto next;
3430 }
3431
3432 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3433
3434 /* save vndr ie information */
3435 parsed_info->ie_ptr = (char *)vndrie;
3436 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3437 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3438
3439 vndr_ies->count++;
3440
3441 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3442 parsed_info->vndrie.oui[0],
3443 parsed_info->vndrie.oui[1],
3444 parsed_info->vndrie.oui[2],
3445 parsed_info->vndrie.oui_type);
3446
3447 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3448 break;
3449 next:
3450 remaining_len -= (ie->len + TLV_HDR_LEN);
3451 if (remaining_len <= TLV_HDR_LEN)
3452 ie = NULL;
3453 else
3454 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3455 TLV_HDR_LEN);
3456 }
3457 return err;
3458 }
3459
3460 static u32
3461 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3462 {
3463
3464 __le32 iecount_le;
3465 __le32 pktflag_le;
3466
3467 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3468 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3469
3470 iecount_le = cpu_to_le32(1);
3471 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3472
3473 pktflag_le = cpu_to_le32(pktflag);
3474 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3475
3476 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3477
3478 return ie_len + VNDR_IE_HDR_SIZE;
3479 }
3480
3481 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3482 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3483 {
3484 struct brcmf_if *ifp;
3485 struct vif_saved_ie *saved_ie;
3486 s32 err = 0;
3487 u8 *iovar_ie_buf;
3488 u8 *curr_ie_buf;
3489 u8 *mgmt_ie_buf = NULL;
3490 int mgmt_ie_buf_len;
3491 u32 *mgmt_ie_len;
3492 u32 del_add_ie_buf_len = 0;
3493 u32 total_ie_buf_len = 0;
3494 u32 parsed_ie_buf_len = 0;
3495 struct parsed_vndr_ies old_vndr_ies;
3496 struct parsed_vndr_ies new_vndr_ies;
3497 struct parsed_vndr_ie_info *vndrie_info;
3498 s32 i;
3499 u8 *ptr;
3500 int remained_buf_len;
3501
3502 if (!vif)
3503 return -ENODEV;
3504 ifp = vif->ifp;
3505 saved_ie = &vif->saved_ie;
3506
3507 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3508 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3509 if (!iovar_ie_buf)
3510 return -ENOMEM;
3511 curr_ie_buf = iovar_ie_buf;
3512 switch (pktflag) {
3513 case BRCMF_VNDR_IE_PRBREQ_FLAG:
3514 mgmt_ie_buf = saved_ie->probe_req_ie;
3515 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3516 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3517 break;
3518 case BRCMF_VNDR_IE_PRBRSP_FLAG:
3519 mgmt_ie_buf = saved_ie->probe_res_ie;
3520 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3521 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3522 break;
3523 case BRCMF_VNDR_IE_BEACON_FLAG:
3524 mgmt_ie_buf = saved_ie->beacon_ie;
3525 mgmt_ie_len = &saved_ie->beacon_ie_len;
3526 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3527 break;
3528 case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3529 mgmt_ie_buf = saved_ie->assoc_req_ie;
3530 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3531 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3532 break;
3533 default:
3534 err = -EPERM;
3535 brcmf_err("not suitable type\n");
3536 goto exit;
3537 }
3538
3539 if (vndr_ie_len > mgmt_ie_buf_len) {
3540 err = -ENOMEM;
3541 brcmf_err("extra IE size too big\n");
3542 goto exit;
3543 }
3544
3545 /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3546 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3547 ptr = curr_ie_buf;
3548 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3549 for (i = 0; i < new_vndr_ies.count; i++) {
3550 vndrie_info = &new_vndr_ies.ie_info[i];
3551 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3552 vndrie_info->ie_len);
3553 parsed_ie_buf_len += vndrie_info->ie_len;
3554 }
3555 }
3556
3557 if (mgmt_ie_buf && *mgmt_ie_len) {
3558 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3559 (memcmp(mgmt_ie_buf, curr_ie_buf,
3560 parsed_ie_buf_len) == 0)) {
3561 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3562 goto exit;
3563 }
3564
3565 /* parse old vndr_ie */
3566 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3567
3568 /* make a command to delete old ie */
3569 for (i = 0; i < old_vndr_ies.count; i++) {
3570 vndrie_info = &old_vndr_ies.ie_info[i];
3571
3572 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3573 vndrie_info->vndrie.id,
3574 vndrie_info->vndrie.len,
3575 vndrie_info->vndrie.oui[0],
3576 vndrie_info->vndrie.oui[1],
3577 vndrie_info->vndrie.oui[2]);
3578
3579 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3580 vndrie_info->ie_ptr,
3581 vndrie_info->ie_len,
3582 "del");
3583 curr_ie_buf += del_add_ie_buf_len;
3584 total_ie_buf_len += del_add_ie_buf_len;
3585 }
3586 }
3587
3588 *mgmt_ie_len = 0;
3589 /* Add if there is any extra IE */
3590 if (mgmt_ie_buf && parsed_ie_buf_len) {
3591 ptr = mgmt_ie_buf;
3592
3593 remained_buf_len = mgmt_ie_buf_len;
3594
3595 /* make a command to add new ie */
3596 for (i = 0; i < new_vndr_ies.count; i++) {
3597 vndrie_info = &new_vndr_ies.ie_info[i];
3598
3599 /* verify remained buf size before copy data */
3600 if (remained_buf_len < (vndrie_info->vndrie.len +
3601 VNDR_IE_VSIE_OFFSET)) {
3602 brcmf_err("no space in mgmt_ie_buf: len left %d",
3603 remained_buf_len);
3604 break;
3605 }
3606 remained_buf_len -= (vndrie_info->ie_len +
3607 VNDR_IE_VSIE_OFFSET);
3608
3609 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3610 vndrie_info->vndrie.id,
3611 vndrie_info->vndrie.len,
3612 vndrie_info->vndrie.oui[0],
3613 vndrie_info->vndrie.oui[1],
3614 vndrie_info->vndrie.oui[2]);
3615
3616 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3617 vndrie_info->ie_ptr,
3618 vndrie_info->ie_len,
3619 "add");
3620
3621 /* save the parsed IE in wl struct */
3622 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3623 vndrie_info->ie_len);
3624 *mgmt_ie_len += vndrie_info->ie_len;
3625
3626 curr_ie_buf += del_add_ie_buf_len;
3627 total_ie_buf_len += del_add_ie_buf_len;
3628 }
3629 }
3630 if (total_ie_buf_len) {
3631 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3632 total_ie_buf_len);
3633 if (err)
3634 brcmf_err("vndr ie set error : %d\n", err);
3635 }
3636
3637 exit:
3638 kfree(iovar_ie_buf);
3639 return err;
3640 }
3641
3642 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3643 {
3644 s32 pktflags[] = {
3645 BRCMF_VNDR_IE_PRBREQ_FLAG,
3646 BRCMF_VNDR_IE_PRBRSP_FLAG,
3647 BRCMF_VNDR_IE_BEACON_FLAG
3648 };
3649 int i;
3650
3651 for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3652 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3653
3654 memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3655 return 0;
3656 }
3657
3658 static s32
3659 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3660 struct cfg80211_beacon_data *beacon)
3661 {
3662 s32 err;
3663
3664 /* Set Beacon IEs to FW */
3665 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3666 beacon->tail, beacon->tail_len);
3667 if (err) {
3668 brcmf_err("Set Beacon IE Failed\n");
3669 return err;
3670 }
3671 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3672
3673 /* Set Probe Response IEs to FW */
3674 err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3675 beacon->proberesp_ies,
3676 beacon->proberesp_ies_len);
3677 if (err)
3678 brcmf_err("Set Probe Resp IE Failed\n");
3679 else
3680 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3681
3682 return err;
3683 }
3684
3685 static s32
3686 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3687 struct brcmf_if *ifp,
3688 struct ieee80211_channel *channel)
3689 {
3690 u16 chanspec;
3691 s32 err;
3692
3693 brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3694 channel->center_freq);
3695
3696 chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3697 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3698
3699 return err;
3700 }
3701
3702 static s32
3703 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3704 struct cfg80211_ap_settings *settings)
3705 {
3706 s32 ie_offset;
3707 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3708 struct brcmf_if *ifp = netdev_priv(ndev);
3709 struct brcmf_tlv *ssid_ie;
3710 struct brcmf_ssid_le ssid_le;
3711 s32 err = -EPERM;
3712 struct brcmf_tlv *rsn_ie;
3713 struct brcmf_vs_tlv *wpa_ie;
3714 struct brcmf_join_params join_params;
3715 enum nl80211_iftype dev_role;
3716 struct brcmf_fil_bss_enable_le bss_enable;
3717
3718 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3719 cfg80211_get_chandef_type(&settings->chandef),
3720 settings->beacon_interval,
3721 settings->dtim_period);
3722 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3723 settings->ssid, settings->ssid_len, settings->auth_type,
3724 settings->inactivity_timeout);
3725
3726 dev_role = ifp->vif->wdev.iftype;
3727
3728 memset(&ssid_le, 0, sizeof(ssid_le));
3729 if (settings->ssid == NULL || settings->ssid_len == 0) {
3730 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3731 ssid_ie = brcmf_parse_tlvs(
3732 (u8 *)&settings->beacon.head[ie_offset],
3733 settings->beacon.head_len - ie_offset,
3734 WLAN_EID_SSID);
3735 if (!ssid_ie)
3736 return -EINVAL;
3737
3738 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3739 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3740 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3741 } else {
3742 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3743 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3744 }
3745
3746 brcmf_set_mpc(ifp, 0);
3747 brcmf_configure_arp_offload(ifp, false);
3748
3749 /* find the RSN_IE */
3750 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3751 settings->beacon.tail_len, WLAN_EID_RSN);
3752
3753 /* find the WPA_IE */
3754 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3755 settings->beacon.tail_len);
3756
3757 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3758 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3759 if (wpa_ie != NULL) {
3760 /* WPA IE */
3761 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3762 if (err < 0)
3763 goto exit;
3764 } else {
3765 /* RSN IE */
3766 err = brcmf_configure_wpaie(ndev,
3767 (struct brcmf_vs_tlv *)rsn_ie, true);
3768 if (err < 0)
3769 goto exit;
3770 }
3771 } else {
3772 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3773 brcmf_configure_opensecurity(ifp);
3774 }
3775
3776 brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3777
3778 err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
3779 if (err < 0) {
3780 brcmf_err("Set Channel failed, %d\n", err);
3781 goto exit;
3782 }
3783
3784 if (settings->beacon_interval) {
3785 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3786 settings->beacon_interval);
3787 if (err < 0) {
3788 brcmf_err("Beacon Interval Set Error, %d\n", err);
3789 goto exit;
3790 }
3791 }
3792 if (settings->dtim_period) {
3793 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3794 settings->dtim_period);
3795 if (err < 0) {
3796 brcmf_err("DTIM Interval Set Error, %d\n", err);
3797 goto exit;
3798 }
3799 }
3800
3801 if (dev_role == NL80211_IFTYPE_AP) {
3802 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3803 if (err < 0) {
3804 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3805 goto exit;
3806 }
3807 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3808 }
3809
3810 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3811 if (err < 0) {
3812 brcmf_err("SET INFRA error %d\n", err);
3813 goto exit;
3814 }
3815 if (dev_role == NL80211_IFTYPE_AP) {
3816 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3817 if (err < 0) {
3818 brcmf_err("setting AP mode failed %d\n", err);
3819 goto exit;
3820 }
3821 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3822 if (err < 0) {
3823 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3824 goto exit;
3825 }
3826
3827 memset(&join_params, 0, sizeof(join_params));
3828 /* join parameters starts with ssid */
3829 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3830 /* create softap */
3831 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3832 &join_params, sizeof(join_params));
3833 if (err < 0) {
3834 brcmf_err("SET SSID error (%d)\n", err);
3835 goto exit;
3836 }
3837 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3838 } else {
3839 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3840 sizeof(ssid_le));
3841 if (err < 0) {
3842 brcmf_err("setting ssid failed %d\n", err);
3843 goto exit;
3844 }
3845 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3846 bss_enable.enable = cpu_to_le32(1);
3847 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3848 sizeof(bss_enable));
3849 if (err < 0) {
3850 brcmf_err("bss_enable config failed %d\n", err);
3851 goto exit;
3852 }
3853
3854 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3855 }
3856 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3857 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3858
3859 exit:
3860 if (err) {
3861 brcmf_set_mpc(ifp, 1);
3862 brcmf_configure_arp_offload(ifp, true);
3863 }
3864 return err;
3865 }
3866
3867 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3868 {
3869 struct brcmf_if *ifp = netdev_priv(ndev);
3870 s32 err;
3871 struct brcmf_fil_bss_enable_le bss_enable;
3872 struct brcmf_join_params join_params;
3873
3874 brcmf_dbg(TRACE, "Enter\n");
3875
3876 if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3877 /* Due to most likely deauths outstanding we sleep */
3878 /* first to make sure they get processed by fw. */
3879 msleep(400);
3880
3881 memset(&join_params, 0, sizeof(join_params));
3882 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3883 &join_params, sizeof(join_params));
3884 if (err < 0)
3885 brcmf_err("SET SSID error (%d)\n", err);
3886 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3887 if (err < 0)
3888 brcmf_err("BRCMF_C_UP error %d\n", err);
3889 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3890 if (err < 0)
3891 brcmf_err("setting AP mode failed %d\n", err);
3892 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3893 if (err < 0)
3894 brcmf_err("setting INFRA mode failed %d\n", err);
3895 } else {
3896 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3897 bss_enable.enable = cpu_to_le32(0);
3898 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3899 sizeof(bss_enable));
3900 if (err < 0)
3901 brcmf_err("bss_enable config failed %d\n", err);
3902 }
3903 brcmf_set_mpc(ifp, 1);
3904 brcmf_configure_arp_offload(ifp, true);
3905 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3906 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3907
3908 return err;
3909 }
3910
3911 static s32
3912 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3913 struct cfg80211_beacon_data *info)
3914 {
3915 struct brcmf_if *ifp = netdev_priv(ndev);
3916 s32 err;
3917
3918 brcmf_dbg(TRACE, "Enter\n");
3919
3920 err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3921
3922 return err;
3923 }
3924
3925 static int
3926 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3927 u8 *mac)
3928 {
3929 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3930 struct brcmf_scb_val_le scbval;
3931 struct brcmf_if *ifp = netdev_priv(ndev);
3932 s32 err;
3933
3934 if (!mac)
3935 return -EFAULT;
3936
3937 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3938
3939 if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3940 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3941 if (!check_vif_up(ifp->vif))
3942 return -EIO;
3943
3944 memcpy(&scbval.ea, mac, ETH_ALEN);
3945 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3946 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3947 &scbval, sizeof(scbval));
3948 if (err)
3949 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3950
3951 brcmf_dbg(TRACE, "Exit\n");
3952 return err;
3953 }
3954
3955
3956 static void
3957 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3958 struct wireless_dev *wdev,
3959 u16 frame_type, bool reg)
3960 {
3961 struct brcmf_cfg80211_vif *vif;
3962 u16 mgmt_type;
3963
3964 brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3965
3966 mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3967 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3968 if (reg)
3969 vif->mgmt_rx_reg |= BIT(mgmt_type);
3970 else
3971 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3972 }
3973
3974
3975 static int
3976 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3977 struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3978 {
3979 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3980 struct ieee80211_channel *chan = params->chan;
3981 const u8 *buf = params->buf;
3982 size_t len = params->len;
3983 const struct ieee80211_mgmt *mgmt;
3984 struct brcmf_cfg80211_vif *vif;
3985 s32 err = 0;
3986 s32 ie_offset;
3987 s32 ie_len;
3988 struct brcmf_fil_action_frame_le *action_frame;
3989 struct brcmf_fil_af_params_le *af_params;
3990 bool ack;
3991 s32 chan_nr;
3992 u32 freq;
3993
3994 brcmf_dbg(TRACE, "Enter\n");
3995
3996 *cookie = 0;
3997
3998 mgmt = (const struct ieee80211_mgmt *)buf;
3999
4000 if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4001 brcmf_err("Driver only allows MGMT packet type\n");
4002 return -EPERM;
4003 }
4004
4005 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4006
4007 if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4008 /* Right now the only reason to get a probe response */
4009 /* is for p2p listen response or for p2p GO from */
4010 /* wpa_supplicant. Unfortunately the probe is send */
4011 /* on primary ndev, while dongle wants it on the p2p */
4012 /* vif. Since this is only reason for a probe */
4013 /* response to be sent, the vif is taken from cfg. */
4014 /* If ever desired to send proberesp for non p2p */
4015 /* response then data should be checked for */
4016 /* "DIRECT-". Note in future supplicant will take */
4017 /* dedicated p2p wdev to do this and then this 'hack'*/
4018 /* is not needed anymore. */
4019 ie_offset = DOT11_MGMT_HDR_LEN +
4020 DOT11_BCN_PRB_FIXED_LEN;
4021 ie_len = len - ie_offset;
4022 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4023 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4024 err = brcmf_vif_set_mgmt_ie(vif,
4025 BRCMF_VNDR_IE_PRBRSP_FLAG,
4026 &buf[ie_offset],
4027 ie_len);
4028 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4029 GFP_KERNEL);
4030 } else if (ieee80211_is_action(mgmt->frame_control)) {
4031 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4032 if (af_params == NULL) {
4033 brcmf_err("unable to allocate frame\n");
4034 err = -ENOMEM;
4035 goto exit;
4036 }
4037 action_frame = &af_params->action_frame;
4038 /* Add the packet Id */
4039 action_frame->packet_id = cpu_to_le32(*cookie);
4040 /* Add BSSID */
4041 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4042 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4043 /* Add the length exepted for 802.11 header */
4044 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4045 /* Add the channel. Use the one specified as parameter if any or
4046 * the current one (got from the firmware) otherwise
4047 */
4048 if (chan)
4049 freq = chan->center_freq;
4050 else
4051 brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4052 &freq);
4053 chan_nr = ieee80211_frequency_to_channel(freq);
4054 af_params->channel = cpu_to_le32(chan_nr);
4055
4056 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4057 le16_to_cpu(action_frame->len));
4058
4059 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4060 *cookie, le16_to_cpu(action_frame->len), freq);
4061
4062 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4063 af_params);
4064
4065 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4066 GFP_KERNEL);
4067 kfree(af_params);
4068 } else {
4069 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4070 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4071 }
4072
4073 exit:
4074 return err;
4075 }
4076
4077
4078 static int
4079 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4080 struct wireless_dev *wdev,
4081 u64 cookie)
4082 {
4083 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4084 struct brcmf_cfg80211_vif *vif;
4085 int err = 0;
4086
4087 brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4088
4089 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4090 if (vif == NULL) {
4091 brcmf_err("No p2p device available for probe response\n");
4092 err = -ENODEV;
4093 goto exit;
4094 }
4095 brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4096 exit:
4097 return err;
4098 }
4099
4100 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4101 struct wireless_dev *wdev,
4102 enum nl80211_crit_proto_id proto,
4103 u16 duration)
4104 {
4105 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4106 struct brcmf_cfg80211_vif *vif;
4107
4108 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4109
4110 /* only DHCP support for now */
4111 if (proto != NL80211_CRIT_PROTO_DHCP)
4112 return -EINVAL;
4113
4114 /* suppress and abort scanning */
4115 set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4116 brcmf_abort_scanning(cfg);
4117
4118 return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4119 }
4120
4121 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4122 struct wireless_dev *wdev)
4123 {
4124 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4125 struct brcmf_cfg80211_vif *vif;
4126
4127 vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4128
4129 brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4130 clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4131 }
4132
4133 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4134 {
4135 int ret;
4136
4137 switch (oper) {
4138 case NL80211_TDLS_DISCOVERY_REQ:
4139 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4140 break;
4141 case NL80211_TDLS_SETUP:
4142 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4143 break;
4144 case NL80211_TDLS_TEARDOWN:
4145 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4146 break;
4147 default:
4148 brcmf_err("unsupported operation: %d\n", oper);
4149 ret = -EOPNOTSUPP;
4150 }
4151 return ret;
4152 }
4153
4154 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4155 struct net_device *ndev, u8 *peer,
4156 enum nl80211_tdls_operation oper)
4157 {
4158 struct brcmf_if *ifp;
4159 struct brcmf_tdls_iovar_le info;
4160 int ret = 0;
4161
4162 ret = brcmf_convert_nl80211_tdls_oper(oper);
4163 if (ret < 0)
4164 return ret;
4165
4166 ifp = netdev_priv(ndev);
4167 memset(&info, 0, sizeof(info));
4168 info.mode = (u8)ret;
4169 if (peer)
4170 memcpy(info.ea, peer, ETH_ALEN);
4171
4172 ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4173 &info, sizeof(info));
4174 if (ret < 0)
4175 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4176
4177 return ret;
4178 }
4179
4180 static struct cfg80211_ops wl_cfg80211_ops = {
4181 .add_virtual_intf = brcmf_cfg80211_add_iface,
4182 .del_virtual_intf = brcmf_cfg80211_del_iface,
4183 .change_virtual_intf = brcmf_cfg80211_change_iface,
4184 .scan = brcmf_cfg80211_scan,
4185 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4186 .join_ibss = brcmf_cfg80211_join_ibss,
4187 .leave_ibss = brcmf_cfg80211_leave_ibss,
4188 .get_station = brcmf_cfg80211_get_station,
4189 .set_tx_power = brcmf_cfg80211_set_tx_power,
4190 .get_tx_power = brcmf_cfg80211_get_tx_power,
4191 .add_key = brcmf_cfg80211_add_key,
4192 .del_key = brcmf_cfg80211_del_key,
4193 .get_key = brcmf_cfg80211_get_key,
4194 .set_default_key = brcmf_cfg80211_config_default_key,
4195 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4196 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4197 .connect = brcmf_cfg80211_connect,
4198 .disconnect = brcmf_cfg80211_disconnect,
4199 .suspend = brcmf_cfg80211_suspend,
4200 .resume = brcmf_cfg80211_resume,
4201 .set_pmksa = brcmf_cfg80211_set_pmksa,
4202 .del_pmksa = brcmf_cfg80211_del_pmksa,
4203 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4204 .start_ap = brcmf_cfg80211_start_ap,
4205 .stop_ap = brcmf_cfg80211_stop_ap,
4206 .change_beacon = brcmf_cfg80211_change_beacon,
4207 .del_station = brcmf_cfg80211_del_station,
4208 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4209 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4210 .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4211 .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4212 .remain_on_channel = brcmf_p2p_remain_on_channel,
4213 .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4214 .start_p2p_device = brcmf_p2p_start_device,
4215 .stop_p2p_device = brcmf_p2p_stop_device,
4216 .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4217 .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4218 .tdls_oper = brcmf_cfg80211_tdls_oper,
4219 CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4220 };
4221
4222 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4223 {
4224 switch (type) {
4225 case NL80211_IFTYPE_AP_VLAN:
4226 case NL80211_IFTYPE_WDS:
4227 case NL80211_IFTYPE_MONITOR:
4228 case NL80211_IFTYPE_MESH_POINT:
4229 return -ENOTSUPP;
4230 case NL80211_IFTYPE_ADHOC:
4231 return WL_MODE_IBSS;
4232 case NL80211_IFTYPE_STATION:
4233 case NL80211_IFTYPE_P2P_CLIENT:
4234 return WL_MODE_BSS;
4235 case NL80211_IFTYPE_AP:
4236 case NL80211_IFTYPE_P2P_GO:
4237 return WL_MODE_AP;
4238 case NL80211_IFTYPE_P2P_DEVICE:
4239 return WL_MODE_P2P;
4240 case NL80211_IFTYPE_UNSPECIFIED:
4241 default:
4242 break;
4243 }
4244
4245 return -EINVAL;
4246 }
4247
4248 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4249 {
4250 /* scheduled scan settings */
4251 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4252 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4253 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4254 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4255 }
4256
4257 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4258 {
4259 .max = 2,
4260 .types = BIT(NL80211_IFTYPE_STATION) |
4261 BIT(NL80211_IFTYPE_ADHOC) |
4262 BIT(NL80211_IFTYPE_AP)
4263 },
4264 {
4265 .max = 1,
4266 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4267 BIT(NL80211_IFTYPE_P2P_GO)
4268 },
4269 {
4270 .max = 1,
4271 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4272 }
4273 };
4274 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4275 {
4276 .max_interfaces = BRCMF_IFACE_MAX_CNT,
4277 .num_different_channels = 2,
4278 .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4279 .limits = brcmf_iface_limits
4280 }
4281 };
4282
4283 static const struct ieee80211_txrx_stypes
4284 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4285 [NL80211_IFTYPE_STATION] = {
4286 .tx = 0xffff,
4287 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4288 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4289 },
4290 [NL80211_IFTYPE_P2P_CLIENT] = {
4291 .tx = 0xffff,
4292 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4293 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4294 },
4295 [NL80211_IFTYPE_P2P_GO] = {
4296 .tx = 0xffff,
4297 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4298 BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4299 BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4300 BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4301 BIT(IEEE80211_STYPE_AUTH >> 4) |
4302 BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4303 BIT(IEEE80211_STYPE_ACTION >> 4)
4304 },
4305 [NL80211_IFTYPE_P2P_DEVICE] = {
4306 .tx = 0xffff,
4307 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4308 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4309 }
4310 };
4311
4312 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4313 {
4314 struct wiphy *wiphy;
4315 s32 err = 0;
4316
4317 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4318 if (!wiphy) {
4319 brcmf_err("Could not allocate wiphy device\n");
4320 return ERR_PTR(-ENOMEM);
4321 }
4322 set_wiphy_dev(wiphy, phydev);
4323 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4324 wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4325 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4326 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4327 BIT(NL80211_IFTYPE_ADHOC) |
4328 BIT(NL80211_IFTYPE_AP) |
4329 BIT(NL80211_IFTYPE_P2P_CLIENT) |
4330 BIT(NL80211_IFTYPE_P2P_GO) |
4331 BIT(NL80211_IFTYPE_P2P_DEVICE);
4332 wiphy->iface_combinations = brcmf_iface_combos;
4333 wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4334 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4335 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4336 wiphy->cipher_suites = __wl_cipher_suites;
4337 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4338 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4339 WIPHY_FLAG_OFFCHAN_TX |
4340 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4341 WIPHY_FLAG_SUPPORTS_TDLS;
4342 wiphy->mgmt_stypes = brcmf_txrx_stypes;
4343 wiphy->max_remain_on_channel_duration = 5000;
4344 brcmf_wiphy_pno_params(wiphy);
4345 brcmf_dbg(INFO, "Registering custom regulatory\n");
4346 wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4347 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4348 err = wiphy_register(wiphy);
4349 if (err < 0) {
4350 brcmf_err("Could not register wiphy device (%d)\n", err);
4351 wiphy_free(wiphy);
4352 return ERR_PTR(err);
4353 }
4354 return wiphy;
4355 }
4356
4357 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4358 enum nl80211_iftype type,
4359 bool pm_block)
4360 {
4361 struct brcmf_cfg80211_vif *vif;
4362
4363 brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4364 sizeof(*vif));
4365 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4366 if (!vif)
4367 return ERR_PTR(-ENOMEM);
4368
4369 vif->wdev.wiphy = cfg->wiphy;
4370 vif->wdev.iftype = type;
4371
4372 vif->mode = brcmf_nl80211_iftype_to_mode(type);
4373 vif->pm_block = pm_block;
4374 vif->roam_off = -1;
4375
4376 brcmf_init_prof(&vif->profile);
4377
4378 list_add_tail(&vif->list, &cfg->vif_list);
4379 return vif;
4380 }
4381
4382 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4383 {
4384 list_del(&vif->list);
4385 kfree(vif);
4386 }
4387
4388 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4389 {
4390 struct brcmf_cfg80211_vif *vif;
4391 struct brcmf_if *ifp;
4392
4393 ifp = netdev_priv(ndev);
4394 vif = ifp->vif;
4395
4396 brcmf_free_vif(vif);
4397 free_netdev(ndev);
4398 }
4399
4400 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4401 {
4402 u32 event = e->event_code;
4403 u32 status = e->status;
4404
4405 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4406 brcmf_dbg(CONN, "Processing set ssid\n");
4407 return true;
4408 }
4409
4410 return false;
4411 }
4412
4413 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4414 {
4415 u32 event = e->event_code;
4416 u16 flags = e->flags;
4417
4418 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4419 brcmf_dbg(CONN, "Processing link down\n");
4420 return true;
4421 }
4422 return false;
4423 }
4424
4425 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4426 const struct brcmf_event_msg *e)
4427 {
4428 u32 event = e->event_code;
4429 u32 status = e->status;
4430
4431 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4432 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4433 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4434 return true;
4435 }
4436
4437 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4438 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4439 return true;
4440 }
4441
4442 return false;
4443 }
4444
4445 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4446 {
4447 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4448
4449 kfree(conn_info->req_ie);
4450 conn_info->req_ie = NULL;
4451 conn_info->req_ie_len = 0;
4452 kfree(conn_info->resp_ie);
4453 conn_info->resp_ie = NULL;
4454 conn_info->resp_ie_len = 0;
4455 }
4456
4457 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4458 struct brcmf_if *ifp)
4459 {
4460 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4461 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4462 u32 req_len;
4463 u32 resp_len;
4464 s32 err = 0;
4465
4466 brcmf_clear_assoc_ies(cfg);
4467
4468 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4469 cfg->extra_buf, WL_ASSOC_INFO_MAX);
4470 if (err) {
4471 brcmf_err("could not get assoc info (%d)\n", err);
4472 return err;
4473 }
4474 assoc_info =
4475 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4476 req_len = le32_to_cpu(assoc_info->req_len);
4477 resp_len = le32_to_cpu(assoc_info->resp_len);
4478 if (req_len) {
4479 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4480 cfg->extra_buf,
4481 WL_ASSOC_INFO_MAX);
4482 if (err) {
4483 brcmf_err("could not get assoc req (%d)\n", err);
4484 return err;
4485 }
4486 conn_info->req_ie_len = req_len;
4487 conn_info->req_ie =
4488 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4489 GFP_KERNEL);
4490 } else {
4491 conn_info->req_ie_len = 0;
4492 conn_info->req_ie = NULL;
4493 }
4494 if (resp_len) {
4495 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4496 cfg->extra_buf,
4497 WL_ASSOC_INFO_MAX);
4498 if (err) {
4499 brcmf_err("could not get assoc resp (%d)\n", err);
4500 return err;
4501 }
4502 conn_info->resp_ie_len = resp_len;
4503 conn_info->resp_ie =
4504 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4505 GFP_KERNEL);
4506 } else {
4507 conn_info->resp_ie_len = 0;
4508 conn_info->resp_ie = NULL;
4509 }
4510 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4511 conn_info->req_ie_len, conn_info->resp_ie_len);
4512
4513 return err;
4514 }
4515
4516 static s32
4517 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4518 struct net_device *ndev,
4519 const struct brcmf_event_msg *e)
4520 {
4521 struct brcmf_if *ifp = netdev_priv(ndev);
4522 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4523 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4524 struct wiphy *wiphy = cfg_to_wiphy(cfg);
4525 struct ieee80211_channel *notify_channel = NULL;
4526 struct ieee80211_supported_band *band;
4527 struct brcmf_bss_info_le *bi;
4528 struct brcmu_chan ch;
4529 u32 freq;
4530 s32 err = 0;
4531 u8 *buf;
4532
4533 brcmf_dbg(TRACE, "Enter\n");
4534
4535 brcmf_get_assoc_ies(cfg, ifp);
4536 memcpy(profile->bssid, e->addr, ETH_ALEN);
4537 brcmf_update_bss_info(cfg, ifp);
4538
4539 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4540 if (buf == NULL) {
4541 err = -ENOMEM;
4542 goto done;
4543 }
4544
4545 /* data sent to dongle has to be little endian */
4546 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4547 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4548 buf, WL_BSS_INFO_MAX);
4549
4550 if (err)
4551 goto done;
4552
4553 bi = (struct brcmf_bss_info_le *)(buf + 4);
4554 ch.chspec = le16_to_cpu(bi->chanspec);
4555 cfg->d11inf.decchspec(&ch);
4556
4557 if (ch.band == BRCMU_CHAN_BAND_2G)
4558 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4559 else
4560 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4561
4562 freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4563 notify_channel = ieee80211_get_channel(wiphy, freq);
4564
4565 done:
4566 kfree(buf);
4567 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4568 conn_info->req_ie, conn_info->req_ie_len,
4569 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4570 brcmf_dbg(CONN, "Report roaming result\n");
4571
4572 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4573 brcmf_dbg(TRACE, "Exit\n");
4574 return err;
4575 }
4576
4577 static s32
4578 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4579 struct net_device *ndev, const struct brcmf_event_msg *e,
4580 bool completed)
4581 {
4582 struct brcmf_if *ifp = netdev_priv(ndev);
4583 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4584 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4585 s32 err = 0;
4586
4587 brcmf_dbg(TRACE, "Enter\n");
4588
4589 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4590 &ifp->vif->sme_state)) {
4591 if (completed) {
4592 brcmf_get_assoc_ies(cfg, ifp);
4593 memcpy(profile->bssid, e->addr, ETH_ALEN);
4594 brcmf_update_bss_info(cfg, ifp);
4595 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4596 &ifp->vif->sme_state);
4597 }
4598 cfg80211_connect_result(ndev,
4599 (u8 *)profile->bssid,
4600 conn_info->req_ie,
4601 conn_info->req_ie_len,
4602 conn_info->resp_ie,
4603 conn_info->resp_ie_len,
4604 completed ? WLAN_STATUS_SUCCESS :
4605 WLAN_STATUS_AUTH_TIMEOUT,
4606 GFP_KERNEL);
4607 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4608 completed ? "succeeded" : "failed");
4609 }
4610 brcmf_dbg(TRACE, "Exit\n");
4611 return err;
4612 }
4613
4614 static s32
4615 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4616 struct net_device *ndev,
4617 const struct brcmf_event_msg *e, void *data)
4618 {
4619 static int generation;
4620 u32 event = e->event_code;
4621 u32 reason = e->reason;
4622 struct station_info sinfo;
4623
4624 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4625 if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4626 ndev != cfg_to_ndev(cfg)) {
4627 brcmf_dbg(CONN, "AP mode link down\n");
4628 complete(&cfg->vif_disabled);
4629 return 0;
4630 }
4631
4632 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4633 (reason == BRCMF_E_STATUS_SUCCESS)) {
4634 memset(&sinfo, 0, sizeof(sinfo));
4635 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4636 if (!data) {
4637 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4638 return -EINVAL;
4639 }
4640 sinfo.assoc_req_ies = data;
4641 sinfo.assoc_req_ies_len = e->datalen;
4642 generation++;
4643 sinfo.generation = generation;
4644 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4645 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4646 (event == BRCMF_E_DEAUTH_IND) ||
4647 (event == BRCMF_E_DEAUTH)) {
4648 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4649 }
4650 return 0;
4651 }
4652
4653 static s32
4654 brcmf_notify_connect_status(struct brcmf_if *ifp,
4655 const struct brcmf_event_msg *e, void *data)
4656 {
4657 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4658 struct net_device *ndev = ifp->ndev;
4659 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4660 s32 err = 0;
4661
4662 if (ifp->vif->mode == WL_MODE_AP) {
4663 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4664 } else if (brcmf_is_linkup(e)) {
4665 brcmf_dbg(CONN, "Linkup\n");
4666 if (brcmf_is_ibssmode(ifp->vif)) {
4667 memcpy(profile->bssid, e->addr, ETH_ALEN);
4668 wl_inform_ibss(cfg, ndev, e->addr);
4669 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4670 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4671 &ifp->vif->sme_state);
4672 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4673 &ifp->vif->sme_state);
4674 } else
4675 brcmf_bss_connect_done(cfg, ndev, e, true);
4676 } else if (brcmf_is_linkdown(e)) {
4677 brcmf_dbg(CONN, "Linkdown\n");
4678 if (!brcmf_is_ibssmode(ifp->vif)) {
4679 brcmf_bss_connect_done(cfg, ndev, e, false);
4680 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4681 &ifp->vif->sme_state))
4682 cfg80211_disconnected(ndev, 0, NULL, 0,
4683 GFP_KERNEL);
4684 }
4685 brcmf_link_down(ifp->vif);
4686 brcmf_init_prof(ndev_to_prof(ndev));
4687 if (ndev != cfg_to_ndev(cfg))
4688 complete(&cfg->vif_disabled);
4689 } else if (brcmf_is_nonetwork(cfg, e)) {
4690 if (brcmf_is_ibssmode(ifp->vif))
4691 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4692 &ifp->vif->sme_state);
4693 else
4694 brcmf_bss_connect_done(cfg, ndev, e, false);
4695 }
4696
4697 return err;
4698 }
4699
4700 static s32
4701 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4702 const struct brcmf_event_msg *e, void *data)
4703 {
4704 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4705 s32 err = 0;
4706 u32 event = e->event_code;
4707 u32 status = e->status;
4708
4709 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4710 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4711 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4712 else
4713 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4714 }
4715
4716 return err;
4717 }
4718
4719 static s32
4720 brcmf_notify_mic_status(struct brcmf_if *ifp,
4721 const struct brcmf_event_msg *e, void *data)
4722 {
4723 u16 flags = e->flags;
4724 enum nl80211_key_type key_type;
4725
4726 if (flags & BRCMF_EVENT_MSG_GROUP)
4727 key_type = NL80211_KEYTYPE_GROUP;
4728 else
4729 key_type = NL80211_KEYTYPE_PAIRWISE;
4730
4731 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4732 NULL, GFP_KERNEL);
4733
4734 return 0;
4735 }
4736
4737 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4738 const struct brcmf_event_msg *e, void *data)
4739 {
4740 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4741 struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4742 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4743 struct brcmf_cfg80211_vif *vif;
4744
4745 brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4746 ifevent->action, ifevent->flags, ifevent->ifidx,
4747 ifevent->bssidx);
4748
4749 mutex_lock(&event->vif_event_lock);
4750 event->action = ifevent->action;
4751 vif = event->vif;
4752
4753 switch (ifevent->action) {
4754 case BRCMF_E_IF_ADD:
4755 /* waiting process may have timed out */
4756 if (!cfg->vif_event.vif) {
4757 mutex_unlock(&event->vif_event_lock);
4758 return -EBADF;
4759 }
4760
4761 ifp->vif = vif;
4762 vif->ifp = ifp;
4763 if (ifp->ndev) {
4764 vif->wdev.netdev = ifp->ndev;
4765 ifp->ndev->ieee80211_ptr = &vif->wdev;
4766 SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4767 }
4768 mutex_unlock(&event->vif_event_lock);
4769 wake_up(&event->vif_wq);
4770 return 0;
4771
4772 case BRCMF_E_IF_DEL:
4773 mutex_unlock(&event->vif_event_lock);
4774 /* event may not be upon user request */
4775 if (brcmf_cfg80211_vif_event_armed(cfg))
4776 wake_up(&event->vif_wq);
4777 return 0;
4778
4779 case BRCMF_E_IF_CHANGE:
4780 mutex_unlock(&event->vif_event_lock);
4781 wake_up(&event->vif_wq);
4782 return 0;
4783
4784 default:
4785 mutex_unlock(&event->vif_event_lock);
4786 break;
4787 }
4788 return -EINVAL;
4789 }
4790
4791 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4792 {
4793 conf->frag_threshold = (u32)-1;
4794 conf->rts_threshold = (u32)-1;
4795 conf->retry_short = (u32)-1;
4796 conf->retry_long = (u32)-1;
4797 conf->tx_power = -1;
4798 }
4799
4800 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4801 {
4802 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4803 brcmf_notify_connect_status);
4804 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4805 brcmf_notify_connect_status);
4806 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4807 brcmf_notify_connect_status);
4808 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4809 brcmf_notify_connect_status);
4810 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4811 brcmf_notify_connect_status);
4812 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4813 brcmf_notify_connect_status);
4814 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4815 brcmf_notify_roaming_status);
4816 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4817 brcmf_notify_mic_status);
4818 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4819 brcmf_notify_connect_status);
4820 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4821 brcmf_notify_sched_scan_results);
4822 brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4823 brcmf_notify_vif_event);
4824 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4825 brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4826 brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4827 brcmf_p2p_notify_listen_complete);
4828 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4829 brcmf_p2p_notify_action_frame_rx);
4830 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4831 brcmf_p2p_notify_action_tx_complete);
4832 brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4833 brcmf_p2p_notify_action_tx_complete);
4834 }
4835
4836 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4837 {
4838 kfree(cfg->conf);
4839 cfg->conf = NULL;
4840 kfree(cfg->escan_ioctl_buf);
4841 cfg->escan_ioctl_buf = NULL;
4842 kfree(cfg->extra_buf);
4843 cfg->extra_buf = NULL;
4844 kfree(cfg->pmk_list);
4845 cfg->pmk_list = NULL;
4846 }
4847
4848 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4849 {
4850 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4851 if (!cfg->conf)
4852 goto init_priv_mem_out;
4853 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4854 if (!cfg->escan_ioctl_buf)
4855 goto init_priv_mem_out;
4856 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4857 if (!cfg->extra_buf)
4858 goto init_priv_mem_out;
4859 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4860 if (!cfg->pmk_list)
4861 goto init_priv_mem_out;
4862
4863 return 0;
4864
4865 init_priv_mem_out:
4866 brcmf_deinit_priv_mem(cfg);
4867
4868 return -ENOMEM;
4869 }
4870
4871 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4872 {
4873 s32 err = 0;
4874
4875 cfg->scan_request = NULL;
4876 cfg->pwr_save = true;
4877 cfg->roam_on = true; /* roam on & off switch.
4878 we enable roam per default */
4879 cfg->active_scan = true; /* we do active scan for
4880 specific scan per default */
4881 cfg->dongle_up = false; /* dongle is not up yet */
4882 err = brcmf_init_priv_mem(cfg);
4883 if (err)
4884 return err;
4885 brcmf_register_event_handlers(cfg);
4886 mutex_init(&cfg->usr_sync);
4887 brcmf_init_escan(cfg);
4888 brcmf_init_conf(cfg->conf);
4889 init_completion(&cfg->vif_disabled);
4890 return err;
4891 }
4892
4893 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4894 {
4895 cfg->dongle_up = false; /* dongle down */
4896 brcmf_abort_scanning(cfg);
4897 brcmf_deinit_priv_mem(cfg);
4898 }
4899
4900 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4901 {
4902 init_waitqueue_head(&event->vif_wq);
4903 mutex_init(&event->vif_event_lock);
4904 }
4905
4906 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4907 struct device *busdev)
4908 {
4909 struct net_device *ndev = drvr->iflist[0]->ndev;
4910 struct brcmf_cfg80211_info *cfg;
4911 struct wiphy *wiphy;
4912 struct brcmf_cfg80211_vif *vif;
4913 struct brcmf_if *ifp;
4914 s32 err = 0;
4915 s32 io_type;
4916
4917 if (!ndev) {
4918 brcmf_err("ndev is invalid\n");
4919 return NULL;
4920 }
4921
4922 ifp = netdev_priv(ndev);
4923 wiphy = brcmf_setup_wiphy(busdev);
4924 if (IS_ERR(wiphy))
4925 return NULL;
4926
4927 cfg = wiphy_priv(wiphy);
4928 cfg->wiphy = wiphy;
4929 cfg->pub = drvr;
4930 init_vif_event(&cfg->vif_event);
4931 INIT_LIST_HEAD(&cfg->vif_list);
4932
4933 vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4934 if (IS_ERR(vif)) {
4935 wiphy_free(wiphy);
4936 return NULL;
4937 }
4938
4939 vif->ifp = ifp;
4940 vif->wdev.netdev = ndev;
4941 ndev->ieee80211_ptr = &vif->wdev;
4942 SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4943
4944 err = wl_init_priv(cfg);
4945 if (err) {
4946 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4947 goto cfg80211_attach_out;
4948 }
4949 ifp->vif = vif;
4950
4951 err = brcmf_p2p_attach(cfg);
4952 if (err) {
4953 brcmf_err("P2P initilisation failed (%d)\n", err);
4954 goto cfg80211_p2p_attach_out;
4955 }
4956 err = brcmf_btcoex_attach(cfg);
4957 if (err) {
4958 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4959 brcmf_p2p_detach(&cfg->p2p);
4960 goto cfg80211_p2p_attach_out;
4961 }
4962
4963 err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4964 if (err) {
4965 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
4966 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
4967 }
4968
4969 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4970 &io_type);
4971 if (err) {
4972 brcmf_err("Failed to get D11 version (%d)\n", err);
4973 goto cfg80211_p2p_attach_out;
4974 }
4975 cfg->d11inf.io_type = (u8)io_type;
4976 brcmu_d11_attach(&cfg->d11inf);
4977
4978 return cfg;
4979
4980 cfg80211_p2p_attach_out:
4981 wl_deinit_priv(cfg);
4982
4983 cfg80211_attach_out:
4984 brcmf_free_vif(vif);
4985 return NULL;
4986 }
4987
4988 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4989 {
4990 if (!cfg)
4991 return;
4992
4993 WARN_ON(!list_empty(&cfg->vif_list));
4994 wiphy_unregister(cfg->wiphy);
4995 brcmf_btcoex_detach(cfg);
4996 wl_deinit_priv(cfg);
4997 wiphy_free(cfg->wiphy);
4998 }
4999
5000 static s32
5001 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5002 {
5003 s32 err = 0;
5004 __le32 roamtrigger[2];
5005 __le32 roam_delta[2];
5006
5007 /*
5008 * Setup timeout if Beacons are lost and roam is
5009 * off to report link down
5010 */
5011 if (roamvar) {
5012 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5013 if (err) {
5014 brcmf_err("bcn_timeout error (%d)\n", err);
5015 goto dongle_rom_out;
5016 }
5017 }
5018
5019 /*
5020 * Enable/Disable built-in roaming to allow supplicant
5021 * to take care of roaming
5022 */
5023 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
5024 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
5025 if (err) {
5026 brcmf_err("roam_off error (%d)\n", err);
5027 goto dongle_rom_out;
5028 }
5029
5030 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5031 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5032 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5033 (void *)roamtrigger, sizeof(roamtrigger));
5034 if (err) {
5035 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5036 goto dongle_rom_out;
5037 }
5038
5039 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5040 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5041 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5042 (void *)roam_delta, sizeof(roam_delta));
5043 if (err) {
5044 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5045 goto dongle_rom_out;
5046 }
5047
5048 dongle_rom_out:
5049 return err;
5050 }
5051
5052 static s32
5053 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5054 s32 scan_unassoc_time, s32 scan_passive_time)
5055 {
5056 s32 err = 0;
5057
5058 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5059 scan_assoc_time);
5060 if (err) {
5061 if (err == -EOPNOTSUPP)
5062 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5063 else
5064 brcmf_err("Scan assoc time error (%d)\n", err);
5065 goto dongle_scantime_out;
5066 }
5067 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5068 scan_unassoc_time);
5069 if (err) {
5070 if (err == -EOPNOTSUPP)
5071 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5072 else
5073 brcmf_err("Scan unassoc time error (%d)\n", err);
5074 goto dongle_scantime_out;
5075 }
5076
5077 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5078 scan_passive_time);
5079 if (err) {
5080 if (err == -EOPNOTSUPP)
5081 brcmf_dbg(INFO, "Scan passive time is not supported\n");
5082 else
5083 brcmf_err("Scan passive time error (%d)\n", err);
5084 goto dongle_scantime_out;
5085 }
5086
5087 dongle_scantime_out:
5088 return err;
5089 }
5090
5091
5092 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5093 u32 bw_cap[])
5094 {
5095 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5096 struct ieee80211_channel *band_chan_arr;
5097 struct brcmf_chanspec_list *list;
5098 struct brcmu_chan ch;
5099 s32 err;
5100 u8 *pbuf;
5101 u32 i, j;
5102 u32 total;
5103 enum ieee80211_band band;
5104 u32 channel;
5105 u32 *n_cnt;
5106 u32 index;
5107 u32 ht40_flag;
5108 bool update;
5109 u32 array_size;
5110
5111 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5112
5113 if (pbuf == NULL)
5114 return -ENOMEM;
5115
5116 list = (struct brcmf_chanspec_list *)pbuf;
5117
5118 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5119 BRCMF_DCMD_MEDLEN);
5120 if (err) {
5121 brcmf_err("get chanspecs error (%d)\n", err);
5122 goto exit;
5123 }
5124
5125 __wl_band_2ghz.n_channels = 0;
5126 __wl_band_5ghz_a.n_channels = 0;
5127
5128 total = le32_to_cpu(list->count);
5129 for (i = 0; i < total; i++) {
5130 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5131 cfg->d11inf.decchspec(&ch);
5132
5133 if (ch.band == BRCMU_CHAN_BAND_2G) {
5134 band_chan_arr = __wl_2ghz_channels;
5135 array_size = ARRAY_SIZE(__wl_2ghz_channels);
5136 n_cnt = &__wl_band_2ghz.n_channels;
5137 band = IEEE80211_BAND_2GHZ;
5138 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5139 band_chan_arr = __wl_5ghz_a_channels;
5140 array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5141 n_cnt = &__wl_band_5ghz_a.n_channels;
5142 band = IEEE80211_BAND_5GHZ;
5143 } else {
5144 brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5145 continue;
5146 }
5147 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5148 ch.bw == BRCMU_CHAN_BW_40)
5149 continue;
5150 update = false;
5151 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5152 if (band_chan_arr[j].hw_value == ch.chnum) {
5153 update = true;
5154 break;
5155 }
5156 }
5157 if (update)
5158 index = j;
5159 else
5160 index = *n_cnt;
5161 if (index < array_size) {
5162 band_chan_arr[index].center_freq =
5163 ieee80211_channel_to_frequency(ch.chnum, band);
5164 band_chan_arr[index].hw_value = ch.chnum;
5165
5166 brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5167 ch.chnum, band_chan_arr[index].center_freq,
5168 ch.bw, ch.sb);
5169 if (ch.bw == BRCMU_CHAN_BW_40) {
5170 /* assuming the order is HT20, HT40 Upper,
5171 * HT40 lower from chanspecs
5172 */
5173 ht40_flag = band_chan_arr[index].flags &
5174 IEEE80211_CHAN_NO_HT40;
5175 if (ch.sb == BRCMU_CHAN_SB_U) {
5176 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5177 band_chan_arr[index].flags &=
5178 ~IEEE80211_CHAN_NO_HT40;
5179 band_chan_arr[index].flags |=
5180 IEEE80211_CHAN_NO_HT40PLUS;
5181 } else {
5182 /* It should be one of
5183 * IEEE80211_CHAN_NO_HT40 or
5184 * IEEE80211_CHAN_NO_HT40PLUS
5185 */
5186 band_chan_arr[index].flags &=
5187 ~IEEE80211_CHAN_NO_HT40;
5188 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5189 band_chan_arr[index].flags |=
5190 IEEE80211_CHAN_NO_HT40MINUS;
5191 }
5192 } else {
5193 band_chan_arr[index].flags =
5194 IEEE80211_CHAN_NO_HT40;
5195 ch.bw = BRCMU_CHAN_BW_20;
5196 cfg->d11inf.encchspec(&ch);
5197 channel = ch.chspec;
5198 err = brcmf_fil_bsscfg_int_get(ifp,
5199 "per_chan_info",
5200 &channel);
5201 if (!err) {
5202 if (channel & WL_CHAN_RADAR)
5203 band_chan_arr[index].flags |=
5204 (IEEE80211_CHAN_RADAR |
5205 IEEE80211_CHAN_NO_IR);
5206 if (channel & WL_CHAN_PASSIVE)
5207 band_chan_arr[index].flags |=
5208 IEEE80211_CHAN_NO_IR;
5209 }
5210 }
5211 if (!update)
5212 (*n_cnt)++;
5213 }
5214 }
5215 exit:
5216 kfree(pbuf);
5217 return err;
5218 }
5219
5220 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5221 {
5222 u32 band, mimo_bwcap;
5223 int err;
5224
5225 band = WLC_BAND_2G;
5226 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5227 if (!err) {
5228 bw_cap[IEEE80211_BAND_2GHZ] = band;
5229 band = WLC_BAND_5G;
5230 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5231 if (!err) {
5232 bw_cap[IEEE80211_BAND_5GHZ] = band;
5233 return;
5234 }
5235 WARN_ON(1);
5236 return;
5237 }
5238 brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5239 mimo_bwcap = 0;
5240 err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5241 if (err)
5242 /* assume 20MHz if firmware does not give a clue */
5243 mimo_bwcap = WLC_N_BW_20ALL;
5244
5245 switch (mimo_bwcap) {
5246 case WLC_N_BW_40ALL:
5247 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5248 /* fall-thru */
5249 case WLC_N_BW_20IN2G_40IN5G:
5250 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5251 /* fall-thru */
5252 case WLC_N_BW_20ALL:
5253 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5254 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5255 break;
5256 default:
5257 brcmf_err("invalid mimo_bw_cap value\n");
5258 }
5259 }
5260
5261 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5262 {
5263 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5264 struct wiphy *wiphy;
5265 s32 phy_list;
5266 u32 band_list[3];
5267 u32 nmode;
5268 u32 bw_cap[2] = { 0, 0 };
5269 s8 phy;
5270 s32 err;
5271 u32 nband;
5272 s32 i;
5273 struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5274 struct ieee80211_supported_band *band;
5275
5276 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5277 &phy_list, sizeof(phy_list));
5278 if (err) {
5279 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5280 return err;
5281 }
5282
5283 phy = ((char *)&phy_list)[0];
5284 brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5285
5286
5287 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5288 &band_list, sizeof(band_list));
5289 if (err) {
5290 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5291 return err;
5292 }
5293 brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5294 band_list[0], band_list[1], band_list[2]);
5295
5296 err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5297 if (err) {
5298 brcmf_err("nmode error (%d)\n", err);
5299 } else {
5300 brcmf_get_bwcap(ifp, bw_cap);
5301 }
5302 brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5303 bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5304
5305 err = brcmf_construct_reginfo(cfg, bw_cap);
5306 if (err) {
5307 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5308 return err;
5309 }
5310
5311 nband = band_list[0];
5312
5313 for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5314 band = NULL;
5315 if ((band_list[i] == WLC_BAND_5G) &&
5316 (__wl_band_5ghz_a.n_channels > 0))
5317 band = &__wl_band_5ghz_a;
5318 else if ((band_list[i] == WLC_BAND_2G) &&
5319 (__wl_band_2ghz.n_channels > 0))
5320 band = &__wl_band_2ghz;
5321 else
5322 continue;
5323
5324 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5325 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5326 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5327 }
5328 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5329 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5330 band->ht_cap.ht_supported = true;
5331 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5332 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5333 /* An HT shall support all EQM rates for one spatial
5334 * stream
5335 */
5336 band->ht_cap.mcs.rx_mask[0] = 0xff;
5337 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5338 bands[band->band] = band;
5339 }
5340
5341 wiphy = cfg_to_wiphy(cfg);
5342 wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5343 wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5344 wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5345
5346 return err;
5347 }
5348
5349
5350 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5351 {
5352 return brcmf_update_wiphybands(cfg);
5353 }
5354
5355 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5356 {
5357 struct net_device *ndev;
5358 struct wireless_dev *wdev;
5359 struct brcmf_if *ifp;
5360 s32 power_mode;
5361 s32 err = 0;
5362
5363 if (cfg->dongle_up)
5364 return err;
5365
5366 ndev = cfg_to_ndev(cfg);
5367 wdev = ndev->ieee80211_ptr;
5368 ifp = netdev_priv(ndev);
5369
5370 /* make sure RF is ready for work */
5371 brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5372
5373 brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5374 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5375
5376 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5377 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5378 if (err)
5379 goto default_conf_out;
5380 brcmf_dbg(INFO, "power save set to %s\n",
5381 (power_mode ? "enabled" : "disabled"));
5382
5383 err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5384 if (err)
5385 goto default_conf_out;
5386 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5387 NULL, NULL);
5388 if (err)
5389 goto default_conf_out;
5390 err = brcmf_dongle_probecap(cfg);
5391 if (err)
5392 goto default_conf_out;
5393
5394 brcmf_configure_arp_offload(ifp, true);
5395
5396 cfg->dongle_up = true;
5397 default_conf_out:
5398
5399 return err;
5400
5401 }
5402
5403 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5404 {
5405 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5406
5407 return brcmf_config_dongle(ifp->drvr->config);
5408 }
5409
5410 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5411 {
5412 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5413
5414 /*
5415 * While going down, if associated with AP disassociate
5416 * from AP to save power
5417 */
5418 if (check_vif_up(ifp->vif)) {
5419 brcmf_link_down(ifp->vif);
5420
5421 /* Make sure WPA_Supplicant receives all the event
5422 generated due to DISASSOC call to the fw to keep
5423 the state fw and WPA_Supplicant state consistent
5424 */
5425 brcmf_delay(500);
5426 }
5427
5428 brcmf_abort_scanning(cfg);
5429 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5430
5431 return 0;
5432 }
5433
5434 s32 brcmf_cfg80211_up(struct net_device *ndev)
5435 {
5436 struct brcmf_if *ifp = netdev_priv(ndev);
5437 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5438 s32 err = 0;
5439
5440 mutex_lock(&cfg->usr_sync);
5441 err = __brcmf_cfg80211_up(ifp);
5442 mutex_unlock(&cfg->usr_sync);
5443
5444 return err;
5445 }
5446
5447 s32 brcmf_cfg80211_down(struct net_device *ndev)
5448 {
5449 struct brcmf_if *ifp = netdev_priv(ndev);
5450 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5451 s32 err = 0;
5452
5453 mutex_lock(&cfg->usr_sync);
5454 err = __brcmf_cfg80211_down(ifp);
5455 mutex_unlock(&cfg->usr_sync);
5456
5457 return err;
5458 }
5459
5460 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5461 {
5462 struct wireless_dev *wdev = &ifp->vif->wdev;
5463
5464 return wdev->iftype;
5465 }
5466
5467 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5468 {
5469 struct brcmf_cfg80211_vif *vif;
5470 bool result = 0;
5471
5472 list_for_each_entry(vif, &cfg->vif_list, list) {
5473 if (test_bit(state, &vif->sme_state))
5474 result++;
5475 }
5476 return result;
5477 }
5478
5479 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5480 u8 action)
5481 {
5482 u8 evt_action;
5483
5484 mutex_lock(&event->vif_event_lock);
5485 evt_action = event->action;
5486 mutex_unlock(&event->vif_event_lock);
5487 return evt_action == action;
5488 }
5489
5490 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5491 struct brcmf_cfg80211_vif *vif)
5492 {
5493 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5494
5495 mutex_lock(&event->vif_event_lock);
5496 event->vif = vif;
5497 event->action = 0;
5498 mutex_unlock(&event->vif_event_lock);
5499 }
5500
5501 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5502 {
5503 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5504 bool armed;
5505
5506 mutex_lock(&event->vif_event_lock);
5507 armed = event->vif != NULL;
5508 mutex_unlock(&event->vif_event_lock);
5509
5510 return armed;
5511 }
5512 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5513 u8 action, ulong timeout)
5514 {
5515 struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5516
5517 return wait_event_timeout(event->vif_wq,
5518 vif_event_equals(event, action), timeout);
5519 }
5520
This page took 0.292484 seconds and 6 git commands to generate.