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