1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21#include <linux/kernel.h>
22#include <linux/etherdevice.h>
23#include <net/cfg80211.h>
24#include <net/netlink.h>
25
26#include <brcmu_utils.h>
27#include <defs.h>
28#include <brcmu_wifi.h>
29#include "dhd.h"
30#include "dhd_dbg.h"
31#include "wl_cfg80211.h"
32#include "fwil.h"
33
34#define BRCMF_SCAN_IE_LEN_MAX 2048
35#define BRCMF_PNO_VERSION 2
36#define BRCMF_PNO_TIME 30
37#define BRCMF_PNO_REPEAT 4
38#define BRCMF_PNO_FREQ_EXPO_MAX 3
39#define BRCMF_PNO_MAX_PFN_COUNT 16
40#define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT 6
41#define BRCMF_PNO_HIDDEN_BIT 2
42#define BRCMF_PNO_WPA_AUTH_ANY 0xFFFFFFFF
43#define BRCMF_PNO_SCAN_COMPLETE 1
44#define BRCMF_PNO_SCAN_INCOMPLETE 0
45
46#define BRCMF_IFACE_MAX_CNT 2
47
48#define TLV_LEN_OFF 1
49#define TLV_HDR_LEN 2
50#define TLV_BODY_OFF 2
51#define TLV_OUI_LEN 3
52#define WPA_OUI "\x00\x50\xF2"
53#define WPA_OUI_TYPE 1
54#define RSN_OUI "\x00\x0F\xAC"
55#define WME_OUI_TYPE 2
56
57#define VS_IE_FIXED_HDR_LEN 6
58#define WPA_IE_VERSION_LEN 2
59#define WPA_IE_MIN_OUI_LEN 4
60#define WPA_IE_SUITE_COUNT_LEN 2
61
62#define WPA_CIPHER_NONE 0
63#define WPA_CIPHER_WEP_40 1
64#define WPA_CIPHER_TKIP 2
65#define WPA_CIPHER_AES_CCM 4
66#define WPA_CIPHER_WEP_104 5
67
68#define RSN_AKM_NONE 0
69#define RSN_AKM_UNSPECIFIED 1
70#define RSN_AKM_PSK 2
71#define RSN_CAP_LEN 2
72#define RSN_CAP_PTK_REPLAY_CNTR_MASK 0x000C
73
74#define VNDR_IE_CMD_LEN 4
75
76
77#define VNDR_IE_COUNT_OFFSET 4
78#define VNDR_IE_PKTFLAG_OFFSET 8
79#define VNDR_IE_VSIE_OFFSET 12
80#define VNDR_IE_HDR_SIZE 12
81#define VNDR_IE_BEACON_FLAG 0x1
82#define VNDR_IE_PRBRSP_FLAG 0x2
83#define MAX_VNDR_IE_NUMBER 5
84
85#define DOT11_MGMT_HDR_LEN 24
86#define DOT11_BCN_PRB_FIXED_LEN 12
87
88#define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
89 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
90
91static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
92{
93 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
94 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
95 vif->sme_state);
96 return false;
97 }
98 return true;
99}
100
101#define CHAN2G(_channel, _freq, _flags) { \
102 .band = IEEE80211_BAND_2GHZ, \
103 .center_freq = (_freq), \
104 .hw_value = (_channel), \
105 .flags = (_flags), \
106 .max_antenna_gain = 0, \
107 .max_power = 30, \
108}
109
110#define CHAN5G(_channel, _flags) { \
111 .band = IEEE80211_BAND_5GHZ, \
112 .center_freq = 5000 + (5 * (_channel)), \
113 .hw_value = (_channel), \
114 .flags = (_flags), \
115 .max_antenna_gain = 0, \
116 .max_power = 30, \
117}
118
119#define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
120#define RATETAB_ENT(_rateid, _flags) \
121 { \
122 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
123 .hw_value = (_rateid), \
124 .flags = (_flags), \
125 }
126
127static struct ieee80211_rate __wl_rates[] = {
128 RATETAB_ENT(BRCM_RATE_1M, 0),
129 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
130 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
131 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
132 RATETAB_ENT(BRCM_RATE_6M, 0),
133 RATETAB_ENT(BRCM_RATE_9M, 0),
134 RATETAB_ENT(BRCM_RATE_12M, 0),
135 RATETAB_ENT(BRCM_RATE_18M, 0),
136 RATETAB_ENT(BRCM_RATE_24M, 0),
137 RATETAB_ENT(BRCM_RATE_36M, 0),
138 RATETAB_ENT(BRCM_RATE_48M, 0),
139 RATETAB_ENT(BRCM_RATE_54M, 0),
140};
141
142#define wl_a_rates (__wl_rates + 4)
143#define wl_a_rates_size 8
144#define wl_g_rates (__wl_rates + 0)
145#define wl_g_rates_size 12
146
147static struct ieee80211_channel __wl_2ghz_channels[] = {
148 CHAN2G(1, 2412, 0),
149 CHAN2G(2, 2417, 0),
150 CHAN2G(3, 2422, 0),
151 CHAN2G(4, 2427, 0),
152 CHAN2G(5, 2432, 0),
153 CHAN2G(6, 2437, 0),
154 CHAN2G(7, 2442, 0),
155 CHAN2G(8, 2447, 0),
156 CHAN2G(9, 2452, 0),
157 CHAN2G(10, 2457, 0),
158 CHAN2G(11, 2462, 0),
159 CHAN2G(12, 2467, 0),
160 CHAN2G(13, 2472, 0),
161 CHAN2G(14, 2484, 0),
162};
163
164static struct ieee80211_channel __wl_5ghz_a_channels[] = {
165 CHAN5G(34, 0), CHAN5G(36, 0),
166 CHAN5G(38, 0), CHAN5G(40, 0),
167 CHAN5G(42, 0), CHAN5G(44, 0),
168 CHAN5G(46, 0), CHAN5G(48, 0),
169 CHAN5G(52, 0), CHAN5G(56, 0),
170 CHAN5G(60, 0), CHAN5G(64, 0),
171 CHAN5G(100, 0), CHAN5G(104, 0),
172 CHAN5G(108, 0), CHAN5G(112, 0),
173 CHAN5G(116, 0), CHAN5G(120, 0),
174 CHAN5G(124, 0), CHAN5G(128, 0),
175 CHAN5G(132, 0), CHAN5G(136, 0),
176 CHAN5G(140, 0), CHAN5G(149, 0),
177 CHAN5G(153, 0), CHAN5G(157, 0),
178 CHAN5G(161, 0), CHAN5G(165, 0),
179 CHAN5G(184, 0), CHAN5G(188, 0),
180 CHAN5G(192, 0), CHAN5G(196, 0),
181 CHAN5G(200, 0), CHAN5G(204, 0),
182 CHAN5G(208, 0), CHAN5G(212, 0),
183 CHAN5G(216, 0),
184};
185
186static struct ieee80211_channel __wl_5ghz_n_channels[] = {
187 CHAN5G(32, 0), CHAN5G(34, 0),
188 CHAN5G(36, 0), CHAN5G(38, 0),
189 CHAN5G(40, 0), CHAN5G(42, 0),
190 CHAN5G(44, 0), CHAN5G(46, 0),
191 CHAN5G(48, 0), CHAN5G(50, 0),
192 CHAN5G(52, 0), CHAN5G(54, 0),
193 CHAN5G(56, 0), CHAN5G(58, 0),
194 CHAN5G(60, 0), CHAN5G(62, 0),
195 CHAN5G(64, 0), CHAN5G(66, 0),
196 CHAN5G(68, 0), CHAN5G(70, 0),
197 CHAN5G(72, 0), CHAN5G(74, 0),
198 CHAN5G(76, 0), CHAN5G(78, 0),
199 CHAN5G(80, 0), CHAN5G(82, 0),
200 CHAN5G(84, 0), CHAN5G(86, 0),
201 CHAN5G(88, 0), CHAN5G(90, 0),
202 CHAN5G(92, 0), CHAN5G(94, 0),
203 CHAN5G(96, 0), CHAN5G(98, 0),
204 CHAN5G(100, 0), CHAN5G(102, 0),
205 CHAN5G(104, 0), CHAN5G(106, 0),
206 CHAN5G(108, 0), CHAN5G(110, 0),
207 CHAN5G(112, 0), CHAN5G(114, 0),
208 CHAN5G(116, 0), CHAN5G(118, 0),
209 CHAN5G(120, 0), CHAN5G(122, 0),
210 CHAN5G(124, 0), CHAN5G(126, 0),
211 CHAN5G(128, 0), CHAN5G(130, 0),
212 CHAN5G(132, 0), CHAN5G(134, 0),
213 CHAN5G(136, 0), CHAN5G(138, 0),
214 CHAN5G(140, 0), CHAN5G(142, 0),
215 CHAN5G(144, 0), CHAN5G(145, 0),
216 CHAN5G(146, 0), CHAN5G(147, 0),
217 CHAN5G(148, 0), CHAN5G(149, 0),
218 CHAN5G(150, 0), CHAN5G(151, 0),
219 CHAN5G(152, 0), CHAN5G(153, 0),
220 CHAN5G(154, 0), CHAN5G(155, 0),
221 CHAN5G(156, 0), CHAN5G(157, 0),
222 CHAN5G(158, 0), CHAN5G(159, 0),
223 CHAN5G(160, 0), CHAN5G(161, 0),
224 CHAN5G(162, 0), CHAN5G(163, 0),
225 CHAN5G(164, 0), CHAN5G(165, 0),
226 CHAN5G(166, 0), CHAN5G(168, 0),
227 CHAN5G(170, 0), CHAN5G(172, 0),
228 CHAN5G(174, 0), CHAN5G(176, 0),
229 CHAN5G(178, 0), CHAN5G(180, 0),
230 CHAN5G(182, 0), CHAN5G(184, 0),
231 CHAN5G(186, 0), CHAN5G(188, 0),
232 CHAN5G(190, 0), CHAN5G(192, 0),
233 CHAN5G(194, 0), CHAN5G(196, 0),
234 CHAN5G(198, 0), CHAN5G(200, 0),
235 CHAN5G(202, 0), CHAN5G(204, 0),
236 CHAN5G(206, 0), CHAN5G(208, 0),
237 CHAN5G(210, 0), CHAN5G(212, 0),
238 CHAN5G(214, 0), CHAN5G(216, 0),
239 CHAN5G(218, 0), CHAN5G(220, 0),
240 CHAN5G(222, 0), CHAN5G(224, 0),
241 CHAN5G(226, 0), CHAN5G(228, 0),
242};
243
244static struct ieee80211_supported_band __wl_band_2ghz = {
245 .band = IEEE80211_BAND_2GHZ,
246 .channels = __wl_2ghz_channels,
247 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
248 .bitrates = wl_g_rates,
249 .n_bitrates = wl_g_rates_size,
250};
251
252static struct ieee80211_supported_band __wl_band_5ghz_a = {
253 .band = IEEE80211_BAND_5GHZ,
254 .channels = __wl_5ghz_a_channels,
255 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
256 .bitrates = wl_a_rates,
257 .n_bitrates = wl_a_rates_size,
258};
259
260static struct ieee80211_supported_band __wl_band_5ghz_n = {
261 .band = IEEE80211_BAND_5GHZ,
262 .channels = __wl_5ghz_n_channels,
263 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
264 .bitrates = wl_a_rates,
265 .n_bitrates = wl_a_rates_size,
266};
267
268static const u32 __wl_cipher_suites[] = {
269 WLAN_CIPHER_SUITE_WEP40,
270 WLAN_CIPHER_SUITE_WEP104,
271 WLAN_CIPHER_SUITE_TKIP,
272 WLAN_CIPHER_SUITE_CCMP,
273 WLAN_CIPHER_SUITE_AES_CMAC,
274};
275
276
277struct brcmf_tlv {
278 u8 id;
279 u8 len;
280 u8 data[1];
281};
282
283
284struct brcmf_vs_tlv {
285 u8 id;
286 u8 len;
287 u8 oui[3];
288 u8 oui_type;
289};
290
291struct parsed_vndr_ie_info {
292 u8 *ie_ptr;
293 u32 ie_len;
294 struct brcmf_vs_tlv vndrie;
295};
296
297struct parsed_vndr_ies {
298 u32 count;
299 struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
300};
301
302
303
304
305
306
307
308#define QDBM_OFFSET 153
309#define QDBM_TABLE_LEN 40
310
311
312
313
314#define QDBM_TABLE_LOW_BOUND 6493
315
316
317
318
319
320
321#define QDBM_TABLE_HIGH_BOUND 64938
322
323static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
324
325 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
326 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
327 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
328 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
329 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
330};
331
332static u16 brcmf_qdbm_to_mw(u8 qdbm)
333{
334 uint factor = 1;
335 int idx = qdbm - QDBM_OFFSET;
336
337 if (idx >= QDBM_TABLE_LEN)
338
339 return 0xFFFF;
340
341
342
343
344 while (idx < 0) {
345 idx += 40;
346 factor *= 10;
347 }
348
349
350
351
352 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
353}
354
355static u8 brcmf_mw_to_qdbm(u16 mw)
356{
357 u8 qdbm;
358 int offset;
359 uint mw_uint = mw;
360 uint boundary;
361
362
363 if (mw_uint <= 1)
364 return 0;
365
366 offset = QDBM_OFFSET;
367
368
369 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
370 mw_uint *= 10;
371 offset -= 40;
372 }
373
374 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
375 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
376 nqdBm_to_mW_map[qdbm]) / 2;
377 if (mw_uint < boundary)
378 break;
379 }
380
381 qdbm += (u8) offset;
382
383 return qdbm;
384}
385
386static u16 channel_to_chanspec(struct ieee80211_channel *ch)
387{
388 u16 chanspec;
389
390 chanspec = ieee80211_frequency_to_channel(ch->center_freq);
391 chanspec &= WL_CHANSPEC_CHAN_MASK;
392
393 if (ch->band == IEEE80211_BAND_2GHZ)
394 chanspec |= WL_CHANSPEC_BAND_2G;
395 else
396 chanspec |= WL_CHANSPEC_BAND_5G;
397
398 if (ch->flags & IEEE80211_CHAN_NO_HT40) {
399 chanspec |= WL_CHANSPEC_BW_20;
400 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
401 } else {
402 chanspec |= WL_CHANSPEC_BW_40;
403 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
404 chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
405 else
406 chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
407 }
408 return chanspec;
409}
410
411static void convert_key_from_CPU(struct brcmf_wsec_key *key,
412 struct brcmf_wsec_key_le *key_le)
413{
414 key_le->index = cpu_to_le32(key->index);
415 key_le->len = cpu_to_le32(key->len);
416 key_le->algo = cpu_to_le32(key->algo);
417 key_le->flags = cpu_to_le32(key->flags);
418 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
419 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
420 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
421 memcpy(key_le->data, key->data, sizeof(key->data));
422 memcpy(key_le->ea, key->ea, sizeof(key->ea));
423}
424
425static int
426send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
427{
428 int err;
429 struct brcmf_wsec_key_le key_le;
430
431 convert_key_from_CPU(key, &key_le);
432
433 brcmf_netdev_wait_pend8021x(ndev);
434
435 err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
436 sizeof(key_le));
437
438 if (err)
439 brcmf_err("wsec_key error (%d)\n", err);
440 return err;
441}
442
443static s32
444brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
445 enum nl80211_iftype type, u32 *flags,
446 struct vif_params *params)
447{
448 struct brcmf_if *ifp = netdev_priv(ndev);
449 struct brcmf_cfg80211_vif *vif = ifp->vif;
450 s32 infra = 0;
451 s32 ap = 0;
452 s32 err = 0;
453
454 brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
455
456 switch (type) {
457 case NL80211_IFTYPE_MONITOR:
458 case NL80211_IFTYPE_WDS:
459 brcmf_err("type (%d) : currently we do not support this type\n",
460 type);
461 return -EOPNOTSUPP;
462 case NL80211_IFTYPE_ADHOC:
463 vif->mode = WL_MODE_IBSS;
464 infra = 0;
465 break;
466 case NL80211_IFTYPE_STATION:
467 vif->mode = WL_MODE_BSS;
468 infra = 1;
469 break;
470 case NL80211_IFTYPE_AP:
471 vif->mode = WL_MODE_AP;
472 ap = 1;
473 break;
474 default:
475 err = -EINVAL;
476 goto done;
477 }
478
479 if (ap) {
480 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
481 brcmf_dbg(INFO, "IF Type = AP\n");
482 } else {
483 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
484 if (err) {
485 brcmf_err("WLC_SET_INFRA error (%d)\n", err);
486 err = -EAGAIN;
487 goto done;
488 }
489 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
490 "Adhoc" : "Infra");
491 }
492 ndev->ieee80211_ptr->iftype = type;
493
494done:
495 brcmf_dbg(TRACE, "Exit\n");
496
497 return err;
498}
499
500static void brcmf_set_mpc(struct net_device *ndev, int mpc)
501{
502 struct brcmf_if *ifp = netdev_priv(ndev);
503 s32 err = 0;
504
505 if (check_vif_up(ifp->vif)) {
506 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
507 if (err) {
508 brcmf_err("fail to set mpc\n");
509 return;
510 }
511 brcmf_dbg(INFO, "MPC : %d\n", mpc);
512 }
513}
514
515static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
516 struct cfg80211_scan_request *request)
517{
518 u32 n_ssids;
519 u32 n_channels;
520 s32 i;
521 s32 offset;
522 u16 chanspec;
523 char *ptr;
524 struct brcmf_ssid_le ssid_le;
525
526 memset(params_le->bssid, 0xFF, ETH_ALEN);
527 params_le->bss_type = DOT11_BSSTYPE_ANY;
528 params_le->scan_type = 0;
529 params_le->channel_num = 0;
530 params_le->nprobes = cpu_to_le32(-1);
531 params_le->active_time = cpu_to_le32(-1);
532 params_le->passive_time = cpu_to_le32(-1);
533 params_le->home_time = cpu_to_le32(-1);
534 memset(¶ms_le->ssid_le, 0, sizeof(params_le->ssid_le));
535
536
537 if (!request)
538 return;
539
540 n_ssids = request->n_ssids;
541 n_channels = request->n_channels;
542
543 brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
544 n_channels);
545 if (n_channels > 0) {
546 for (i = 0; i < n_channels; i++) {
547 chanspec = channel_to_chanspec(request->channels[i]);
548 brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
549 request->channels[i]->hw_value, chanspec);
550 params_le->channel_list[i] = cpu_to_le16(chanspec);
551 }
552 } else {
553 brcmf_dbg(SCAN, "Scanning all channels\n");
554 }
555
556 brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
557 if (n_ssids > 0) {
558 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
559 n_channels * sizeof(u16);
560 offset = roundup(offset, sizeof(u32));
561 ptr = (char *)params_le + offset;
562 for (i = 0; i < n_ssids; i++) {
563 memset(&ssid_le, 0, sizeof(ssid_le));
564 ssid_le.SSID_len =
565 cpu_to_le32(request->ssids[i].ssid_len);
566 memcpy(ssid_le.SSID, request->ssids[i].ssid,
567 request->ssids[i].ssid_len);
568 if (!ssid_le.SSID_len)
569 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
570 else
571 brcmf_dbg(SCAN, "%d: scan for %s size =%d\n",
572 i, ssid_le.SSID, ssid_le.SSID_len);
573 memcpy(ptr, &ssid_le, sizeof(ssid_le));
574 ptr += sizeof(ssid_le);
575 }
576 } else {
577 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
578 if ((request->ssids) && request->ssids->ssid_len) {
579 brcmf_dbg(SCAN, "SSID %s len=%d\n",
580 params_le->ssid_le.SSID,
581 request->ssids->ssid_len);
582 params_le->ssid_le.SSID_len =
583 cpu_to_le32(request->ssids->ssid_len);
584 memcpy(¶ms_le->ssid_le.SSID, request->ssids->ssid,
585 request->ssids->ssid_len);
586 }
587 }
588
589 params_le->channel_num =
590 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
591 (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
592}
593
594static s32
595brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
596 struct net_device *ndev,
597 bool aborted, bool fw_abort)
598{
599 struct brcmf_scan_params_le params_le;
600 struct cfg80211_scan_request *scan_request;
601 s32 err = 0;
602
603 brcmf_dbg(SCAN, "Enter\n");
604
605
606
607 scan_request = cfg->scan_request;
608 cfg->scan_request = NULL;
609
610 if (timer_pending(&cfg->escan_timeout))
611 del_timer_sync(&cfg->escan_timeout);
612
613 if (fw_abort) {
614
615 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
616 memset(¶ms_le, 0, sizeof(params_le));
617 memset(params_le.bssid, 0xFF, ETH_ALEN);
618 params_le.bss_type = DOT11_BSSTYPE_ANY;
619 params_le.scan_type = 0;
620 params_le.channel_num = cpu_to_le32(1);
621 params_le.nprobes = cpu_to_le32(1);
622 params_le.active_time = cpu_to_le32(-1);
623 params_le.passive_time = cpu_to_le32(-1);
624 params_le.home_time = cpu_to_le32(-1);
625
626 params_le.channel_list[0] = cpu_to_le16(-1);
627
628 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
629 ¶ms_le, sizeof(params_le));
630 if (err)
631 brcmf_err("Scan abort failed\n");
632 }
633
634
635
636
637 if (cfg->sched_escan) {
638 brcmf_dbg(SCAN, "scheduled scan completed\n");
639 cfg->sched_escan = false;
640 if (!aborted)
641 cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
642 brcmf_set_mpc(ndev, 1);
643 } else if (scan_request) {
644 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
645 aborted ? "Aborted" : "Done");
646 cfg80211_scan_done(scan_request, aborted);
647 brcmf_set_mpc(ndev, 1);
648 }
649 if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
650 brcmf_err("Scan complete while device not scanning\n");
651 return -EPERM;
652 }
653
654 return err;
655}
656
657static s32
658brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
659 struct cfg80211_scan_request *request, u16 action)
660{
661 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
662 offsetof(struct brcmf_escan_params_le, params_le);
663 struct brcmf_escan_params_le *params;
664 s32 err = 0;
665
666 brcmf_dbg(SCAN, "E-SCAN START\n");
667
668 if (request != NULL) {
669
670 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
671
672
673 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
674 }
675
676 params = kzalloc(params_size, GFP_KERNEL);
677 if (!params) {
678 err = -ENOMEM;
679 goto exit;
680 }
681 BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
682 brcmf_escan_prep(¶ms->params_le, request);
683 params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
684 params->action = cpu_to_le16(action);
685 params->sync_id = cpu_to_le16(0x1234);
686
687 err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
688 params, params_size);
689 if (err) {
690 if (err == -EBUSY)
691 brcmf_dbg(INFO, "system busy : escan canceled\n");
692 else
693 brcmf_err("error (%d)\n", err);
694 }
695
696 kfree(params);
697exit:
698 return err;
699}
700
701static s32
702brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
703 struct net_device *ndev, struct cfg80211_scan_request *request)
704{
705 s32 err;
706 u32 passive_scan;
707 struct brcmf_scan_results *results;
708
709 brcmf_dbg(SCAN, "Enter\n");
710 cfg->escan_info.ndev = ndev;
711 cfg->escan_info.wiphy = wiphy;
712 cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
713 passive_scan = cfg->active_scan ? 0 : 1;
714 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
715 passive_scan);
716 if (err) {
717 brcmf_err("error (%d)\n", err);
718 return err;
719 }
720 brcmf_set_mpc(ndev, 0);
721 results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
722 results->version = 0;
723 results->count = 0;
724 results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
725
726 err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
727 if (err)
728 brcmf_set_mpc(ndev, 1);
729 return err;
730}
731
732static s32
733brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
734 struct cfg80211_scan_request *request,
735 struct cfg80211_ssid *this_ssid)
736{
737 struct brcmf_if *ifp = netdev_priv(ndev);
738 struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
739 struct cfg80211_ssid *ssids;
740 struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
741 u32 passive_scan;
742 bool escan_req;
743 bool spec_scan;
744 s32 err;
745 u32 SSID_len;
746
747 brcmf_dbg(SCAN, "START ESCAN\n");
748
749 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
750 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
751 return -EAGAIN;
752 }
753 if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
754 brcmf_err("Scanning being aborted: status (%lu)\n",
755 cfg->scan_status);
756 return -EAGAIN;
757 }
758 if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
759 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
760 return -EAGAIN;
761 }
762
763
764 mod_timer(&cfg->escan_timeout, jiffies +
765 WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
766
767 escan_req = false;
768 if (request) {
769
770 ssids = request->ssids;
771 escan_req = true;
772 } else {
773
774
775 ssids = this_ssid;
776 }
777
778 cfg->scan_request = request;
779 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
780 if (escan_req) {
781 err = brcmf_do_escan(cfg, wiphy, ndev, request);
782 if (err)
783 goto scan_out;
784 } else {
785 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
786 ssids->ssid, ssids->ssid_len);
787 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
788 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
789 sr->ssid_le.SSID_len = cpu_to_le32(0);
790 spec_scan = false;
791 if (SSID_len) {
792 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
793 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
794 spec_scan = true;
795 } else
796 brcmf_dbg(SCAN, "Broadcast scan\n");
797
798 passive_scan = cfg->active_scan ? 0 : 1;
799 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
800 passive_scan);
801 if (err) {
802 brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
803 goto scan_out;
804 }
805 brcmf_set_mpc(ndev, 0);
806 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
807 &sr->ssid_le, sizeof(sr->ssid_le));
808 if (err) {
809 if (err == -EBUSY)
810 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
811 sr->ssid_le.SSID);
812 else
813 brcmf_err("WLC_SCAN error (%d)\n", err);
814
815 brcmf_set_mpc(ndev, 1);
816 goto scan_out;
817 }
818 }
819
820 return 0;
821
822scan_out:
823 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
824 if (timer_pending(&cfg->escan_timeout))
825 del_timer_sync(&cfg->escan_timeout);
826 cfg->scan_request = NULL;
827 return err;
828}
829
830static s32
831brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
832{
833 struct net_device *ndev = request->wdev->netdev;
834 s32 err = 0;
835
836 brcmf_dbg(TRACE, "Enter\n");
837
838 if (!check_vif_up(container_of(request->wdev,
839 struct brcmf_cfg80211_vif, wdev)))
840 return -EIO;
841
842 err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
843
844 if (err)
845 brcmf_err("scan error (%d)\n", err);
846
847 brcmf_dbg(TRACE, "Exit\n");
848 return err;
849}
850
851static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
852{
853 s32 err = 0;
854
855 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
856 rts_threshold);
857 if (err)
858 brcmf_err("Error (%d)\n", err);
859
860 return err;
861}
862
863static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
864{
865 s32 err = 0;
866
867 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
868 frag_threshold);
869 if (err)
870 brcmf_err("Error (%d)\n", err);
871
872 return err;
873}
874
875static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
876{
877 s32 err = 0;
878 u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
879
880 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
881 if (err) {
882 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
883 return err;
884 }
885 return err;
886}
887
888static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
889{
890 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
891 struct net_device *ndev = cfg_to_ndev(cfg);
892 struct brcmf_if *ifp = netdev_priv(ndev);
893 s32 err = 0;
894
895 brcmf_dbg(TRACE, "Enter\n");
896 if (!check_vif_up(ifp->vif))
897 return -EIO;
898
899 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
900 (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
901 cfg->conf->rts_threshold = wiphy->rts_threshold;
902 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
903 if (!err)
904 goto done;
905 }
906 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
907 (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
908 cfg->conf->frag_threshold = wiphy->frag_threshold;
909 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
910 if (!err)
911 goto done;
912 }
913 if (changed & WIPHY_PARAM_RETRY_LONG
914 && (cfg->conf->retry_long != wiphy->retry_long)) {
915 cfg->conf->retry_long = wiphy->retry_long;
916 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
917 if (!err)
918 goto done;
919 }
920 if (changed & WIPHY_PARAM_RETRY_SHORT
921 && (cfg->conf->retry_short != wiphy->retry_short)) {
922 cfg->conf->retry_short = wiphy->retry_short;
923 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
924 if (!err)
925 goto done;
926 }
927
928done:
929 brcmf_dbg(TRACE, "Exit\n");
930 return err;
931}
932
933static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
934{
935 memset(prof, 0, sizeof(*prof));
936}
937
938static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
939 size_t *join_params_size)
940{
941 u16 chanspec = 0;
942
943 if (ch != 0) {
944 if (ch <= CH_MAX_2G_CHANNEL)
945 chanspec |= WL_CHANSPEC_BAND_2G;
946 else
947 chanspec |= WL_CHANSPEC_BAND_5G;
948
949 chanspec |= WL_CHANSPEC_BW_20;
950 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
951
952 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
953 sizeof(u16);
954
955 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
956 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
957 join_params->params_le.chanspec_num = cpu_to_le32(1);
958
959 brcmf_dbg(CONN, "channel %d, chanspec %#X\n", ch, chanspec);
960 }
961}
962
963static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
964{
965 s32 err = 0;
966
967 brcmf_dbg(TRACE, "Enter\n");
968
969 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
970 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
971 err = brcmf_fil_cmd_data_set(vif->ifp,
972 BRCMF_C_DISASSOC, NULL, 0);
973 if (err)
974 brcmf_err("WLC_DISASSOC failed (%d)\n", err);
975 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
976 }
977 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
978 brcmf_dbg(TRACE, "Exit\n");
979}
980
981static s32
982brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
983 struct cfg80211_ibss_params *params)
984{
985 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
986 struct brcmf_if *ifp = netdev_priv(ndev);
987 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
988 struct brcmf_join_params join_params;
989 size_t join_params_size = 0;
990 s32 err = 0;
991 s32 wsec = 0;
992 s32 bcnprd;
993
994 brcmf_dbg(TRACE, "Enter\n");
995 if (!check_vif_up(ifp->vif))
996 return -EIO;
997
998 if (params->ssid)
999 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1000 else {
1001 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1002 return -EOPNOTSUPP;
1003 }
1004
1005 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1006
1007 if (params->bssid)
1008 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1009 else
1010 brcmf_dbg(CONN, "No BSSID specified\n");
1011
1012 if (params->chandef.chan)
1013 brcmf_dbg(CONN, "channel: %d\n",
1014 params->chandef.chan->center_freq);
1015 else
1016 brcmf_dbg(CONN, "no channel specified\n");
1017
1018 if (params->channel_fixed)
1019 brcmf_dbg(CONN, "fixed channel required\n");
1020 else
1021 brcmf_dbg(CONN, "no fixed channel required\n");
1022
1023 if (params->ie && params->ie_len)
1024 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1025 else
1026 brcmf_dbg(CONN, "no ie specified\n");
1027
1028 if (params->beacon_interval)
1029 brcmf_dbg(CONN, "beacon interval: %d\n",
1030 params->beacon_interval);
1031 else
1032 brcmf_dbg(CONN, "no beacon interval specified\n");
1033
1034 if (params->basic_rates)
1035 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1036 else
1037 brcmf_dbg(CONN, "no basic rates specified\n");
1038
1039 if (params->privacy)
1040 brcmf_dbg(CONN, "privacy required\n");
1041 else
1042 brcmf_dbg(CONN, "no privacy required\n");
1043
1044
1045 if (params->privacy)
1046 wsec |= WEP_ENABLED;
1047
1048 err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1049 if (err) {
1050 brcmf_err("wsec failed (%d)\n", err);
1051 goto done;
1052 }
1053
1054
1055 if (params->beacon_interval)
1056 bcnprd = params->beacon_interval;
1057 else
1058 bcnprd = 100;
1059
1060 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1061 if (err) {
1062 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1063 goto done;
1064 }
1065
1066
1067 memset(&join_params, 0, sizeof(struct brcmf_join_params));
1068
1069
1070 profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1071 memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1072 memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1073 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1074 join_params_size = sizeof(join_params.ssid_le);
1075
1076
1077 if (params->bssid) {
1078 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1079 join_params_size = sizeof(join_params.ssid_le) +
1080 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1081 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1082 } else {
1083 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1084 memset(profile->bssid, 0, ETH_ALEN);
1085 }
1086
1087
1088 if (params->chandef.chan) {
1089 u32 target_channel;
1090
1091 cfg->channel =
1092 ieee80211_frequency_to_channel(
1093 params->chandef.chan->center_freq);
1094 if (params->channel_fixed) {
1095
1096 brcmf_ch_to_chanspec(cfg->channel,
1097 &join_params, &join_params_size);
1098 }
1099
1100
1101 target_channel = cfg->channel;
1102 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1103 target_channel);
1104 if (err) {
1105 brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1106 goto done;
1107 }
1108 } else
1109 cfg->channel = 0;
1110
1111 cfg->ibss_starter = false;
1112
1113
1114 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1115 &join_params, join_params_size);
1116 if (err) {
1117 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1118 goto done;
1119 }
1120
1121done:
1122 if (err)
1123 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1124 brcmf_dbg(TRACE, "Exit\n");
1125 return err;
1126}
1127
1128static s32
1129brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1130{
1131 struct brcmf_if *ifp = netdev_priv(ndev);
1132 s32 err = 0;
1133
1134 brcmf_dbg(TRACE, "Enter\n");
1135 if (!check_vif_up(ifp->vif))
1136 return -EIO;
1137
1138 brcmf_link_down(ifp->vif);
1139
1140 brcmf_dbg(TRACE, "Exit\n");
1141
1142 return err;
1143}
1144
1145static s32 brcmf_set_wpa_version(struct net_device *ndev,
1146 struct cfg80211_connect_params *sme)
1147{
1148 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1149 struct brcmf_cfg80211_security *sec;
1150 s32 val = 0;
1151 s32 err = 0;
1152
1153 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1154 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1155 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1156 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1157 else
1158 val = WPA_AUTH_DISABLED;
1159 brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1160 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1161 if (err) {
1162 brcmf_err("set wpa_auth failed (%d)\n", err);
1163 return err;
1164 }
1165 sec = &profile->sec;
1166 sec->wpa_versions = sme->crypto.wpa_versions;
1167 return err;
1168}
1169
1170static s32 brcmf_set_auth_type(struct net_device *ndev,
1171 struct cfg80211_connect_params *sme)
1172{
1173 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1174 struct brcmf_cfg80211_security *sec;
1175 s32 val = 0;
1176 s32 err = 0;
1177
1178 switch (sme->auth_type) {
1179 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1180 val = 0;
1181 brcmf_dbg(CONN, "open system\n");
1182 break;
1183 case NL80211_AUTHTYPE_SHARED_KEY:
1184 val = 1;
1185 brcmf_dbg(CONN, "shared key\n");
1186 break;
1187 case NL80211_AUTHTYPE_AUTOMATIC:
1188 val = 2;
1189 brcmf_dbg(CONN, "automatic\n");
1190 break;
1191 case NL80211_AUTHTYPE_NETWORK_EAP:
1192 brcmf_dbg(CONN, "network eap\n");
1193 default:
1194 val = 2;
1195 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1196 break;
1197 }
1198
1199 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1200 if (err) {
1201 brcmf_err("set auth failed (%d)\n", err);
1202 return err;
1203 }
1204 sec = &profile->sec;
1205 sec->auth_type = sme->auth_type;
1206 return err;
1207}
1208
1209static s32
1210brcmf_set_set_cipher(struct net_device *ndev,
1211 struct cfg80211_connect_params *sme)
1212{
1213 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1214 struct brcmf_cfg80211_security *sec;
1215 s32 pval = 0;
1216 s32 gval = 0;
1217 s32 err = 0;
1218
1219 if (sme->crypto.n_ciphers_pairwise) {
1220 switch (sme->crypto.ciphers_pairwise[0]) {
1221 case WLAN_CIPHER_SUITE_WEP40:
1222 case WLAN_CIPHER_SUITE_WEP104:
1223 pval = WEP_ENABLED;
1224 break;
1225 case WLAN_CIPHER_SUITE_TKIP:
1226 pval = TKIP_ENABLED;
1227 break;
1228 case WLAN_CIPHER_SUITE_CCMP:
1229 pval = AES_ENABLED;
1230 break;
1231 case WLAN_CIPHER_SUITE_AES_CMAC:
1232 pval = AES_ENABLED;
1233 break;
1234 default:
1235 brcmf_err("invalid cipher pairwise (%d)\n",
1236 sme->crypto.ciphers_pairwise[0]);
1237 return -EINVAL;
1238 }
1239 }
1240 if (sme->crypto.cipher_group) {
1241 switch (sme->crypto.cipher_group) {
1242 case WLAN_CIPHER_SUITE_WEP40:
1243 case WLAN_CIPHER_SUITE_WEP104:
1244 gval = WEP_ENABLED;
1245 break;
1246 case WLAN_CIPHER_SUITE_TKIP:
1247 gval = TKIP_ENABLED;
1248 break;
1249 case WLAN_CIPHER_SUITE_CCMP:
1250 gval = AES_ENABLED;
1251 break;
1252 case WLAN_CIPHER_SUITE_AES_CMAC:
1253 gval = AES_ENABLED;
1254 break;
1255 default:
1256 brcmf_err("invalid cipher group (%d)\n",
1257 sme->crypto.cipher_group);
1258 return -EINVAL;
1259 }
1260 }
1261
1262 brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1263 err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1264 if (err) {
1265 brcmf_err("error (%d)\n", err);
1266 return err;
1267 }
1268
1269 sec = &profile->sec;
1270 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1271 sec->cipher_group = sme->crypto.cipher_group;
1272
1273 return err;
1274}
1275
1276static s32
1277brcmf_set_key_mgmt(struct net_device *ndev, 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.n_akm_suites) {
1285 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1286 "wpa_auth", &val);
1287 if (err) {
1288 brcmf_err("could not get wpa_auth (%d)\n", err);
1289 return err;
1290 }
1291 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1292 switch (sme->crypto.akm_suites[0]) {
1293 case WLAN_AKM_SUITE_8021X:
1294 val = WPA_AUTH_UNSPECIFIED;
1295 break;
1296 case WLAN_AKM_SUITE_PSK:
1297 val = WPA_AUTH_PSK;
1298 break;
1299 default:
1300 brcmf_err("invalid cipher group (%d)\n",
1301 sme->crypto.cipher_group);
1302 return -EINVAL;
1303 }
1304 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1305 switch (sme->crypto.akm_suites[0]) {
1306 case WLAN_AKM_SUITE_8021X:
1307 val = WPA2_AUTH_UNSPECIFIED;
1308 break;
1309 case WLAN_AKM_SUITE_PSK:
1310 val = WPA2_AUTH_PSK;
1311 break;
1312 default:
1313 brcmf_err("invalid cipher group (%d)\n",
1314 sme->crypto.cipher_group);
1315 return -EINVAL;
1316 }
1317 }
1318
1319 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1320 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1321 "wpa_auth", val);
1322 if (err) {
1323 brcmf_err("could not set wpa_auth (%d)\n", err);
1324 return err;
1325 }
1326 }
1327 sec = &profile->sec;
1328 sec->wpa_auth = sme->crypto.akm_suites[0];
1329
1330 return err;
1331}
1332
1333static s32
1334brcmf_set_sharedkey(struct net_device *ndev,
1335 struct cfg80211_connect_params *sme)
1336{
1337 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1338 struct brcmf_cfg80211_security *sec;
1339 struct brcmf_wsec_key key;
1340 s32 val;
1341 s32 err = 0;
1342
1343 brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1344
1345 if (sme->key_len == 0)
1346 return 0;
1347
1348 sec = &profile->sec;
1349 brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1350 sec->wpa_versions, sec->cipher_pairwise);
1351
1352 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1353 return 0;
1354
1355 if (!(sec->cipher_pairwise &
1356 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1357 return 0;
1358
1359 memset(&key, 0, sizeof(key));
1360 key.len = (u32) sme->key_len;
1361 key.index = (u32) sme->key_idx;
1362 if (key.len > sizeof(key.data)) {
1363 brcmf_err("Too long key length (%u)\n", key.len);
1364 return -EINVAL;
1365 }
1366 memcpy(key.data, sme->key, key.len);
1367 key.flags = BRCMF_PRIMARY_KEY;
1368 switch (sec->cipher_pairwise) {
1369 case WLAN_CIPHER_SUITE_WEP40:
1370 key.algo = CRYPTO_ALGO_WEP1;
1371 break;
1372 case WLAN_CIPHER_SUITE_WEP104:
1373 key.algo = CRYPTO_ALGO_WEP128;
1374 break;
1375 default:
1376 brcmf_err("Invalid algorithm (%d)\n",
1377 sme->crypto.ciphers_pairwise[0]);
1378 return -EINVAL;
1379 }
1380
1381 brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1382 key.len, key.index, key.algo);
1383 brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1384 err = send_key_to_dongle(ndev, &key);
1385 if (err)
1386 return err;
1387
1388 if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1389 brcmf_dbg(CONN, "set auth_type to shared key\n");
1390 val = WL_AUTH_SHARED_KEY;
1391 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1392 if (err)
1393 brcmf_err("set auth failed (%d)\n", err);
1394 }
1395 return err;
1396}
1397
1398static s32
1399brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1400 struct cfg80211_connect_params *sme)
1401{
1402 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1403 struct brcmf_if *ifp = netdev_priv(ndev);
1404 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1405 struct ieee80211_channel *chan = sme->channel;
1406 struct brcmf_join_params join_params;
1407 size_t join_params_size;
1408 struct brcmf_ssid ssid;
1409
1410 s32 err = 0;
1411
1412 brcmf_dbg(TRACE, "Enter\n");
1413 if (!check_vif_up(ifp->vif))
1414 return -EIO;
1415
1416 if (!sme->ssid) {
1417 brcmf_err("Invalid ssid\n");
1418 return -EOPNOTSUPP;
1419 }
1420
1421 set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1422
1423 if (chan) {
1424 cfg->channel =
1425 ieee80211_frequency_to_channel(chan->center_freq);
1426 brcmf_dbg(CONN, "channel (%d), center_req (%d)\n",
1427 cfg->channel, chan->center_freq);
1428 } else
1429 cfg->channel = 0;
1430
1431 brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1432
1433 err = brcmf_set_wpa_version(ndev, sme);
1434 if (err) {
1435 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1436 goto done;
1437 }
1438
1439 err = brcmf_set_auth_type(ndev, sme);
1440 if (err) {
1441 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1442 goto done;
1443 }
1444
1445 err = brcmf_set_set_cipher(ndev, sme);
1446 if (err) {
1447 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1448 goto done;
1449 }
1450
1451 err = brcmf_set_key_mgmt(ndev, sme);
1452 if (err) {
1453 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1454 goto done;
1455 }
1456
1457 err = brcmf_set_sharedkey(ndev, sme);
1458 if (err) {
1459 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1460 goto done;
1461 }
1462
1463 memset(&join_params, 0, sizeof(join_params));
1464 join_params_size = sizeof(join_params.ssid_le);
1465
1466 profile->ssid.SSID_len = min_t(u32,
1467 sizeof(ssid.SSID), (u32)sme->ssid_len);
1468 memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1469 memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1470 join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1471
1472 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1473
1474 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1475 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n",
1476 ssid.SSID, ssid.SSID_len);
1477
1478 brcmf_ch_to_chanspec(cfg->channel,
1479 &join_params, &join_params_size);
1480 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1481 &join_params, join_params_size);
1482 if (err)
1483 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1484
1485done:
1486 if (err)
1487 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1488 brcmf_dbg(TRACE, "Exit\n");
1489 return err;
1490}
1491
1492static s32
1493brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1494 u16 reason_code)
1495{
1496 struct brcmf_if *ifp = netdev_priv(ndev);
1497 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1498 struct brcmf_scb_val_le scbval;
1499 s32 err = 0;
1500
1501 brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1502 if (!check_vif_up(ifp->vif))
1503 return -EIO;
1504
1505 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1506
1507 memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1508 scbval.val = cpu_to_le32(reason_code);
1509 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1510 &scbval, sizeof(scbval));
1511 if (err)
1512 brcmf_err("error (%d)\n", err);
1513
1514 brcmf_dbg(TRACE, "Exit\n");
1515 return err;
1516}
1517
1518static s32
1519brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1520 enum nl80211_tx_power_setting type, s32 mbm)
1521{
1522
1523 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1524 struct net_device *ndev = cfg_to_ndev(cfg);
1525 struct brcmf_if *ifp = netdev_priv(ndev);
1526 u16 txpwrmw;
1527 s32 err = 0;
1528 s32 disable = 0;
1529 s32 dbm = MBM_TO_DBM(mbm);
1530
1531 brcmf_dbg(TRACE, "Enter\n");
1532 if (!check_vif_up(ifp->vif))
1533 return -EIO;
1534
1535 switch (type) {
1536 case NL80211_TX_POWER_AUTOMATIC:
1537 break;
1538 case NL80211_TX_POWER_LIMITED:
1539 case NL80211_TX_POWER_FIXED:
1540 if (dbm < 0) {
1541 brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1542 err = -EINVAL;
1543 goto done;
1544 }
1545 break;
1546 }
1547
1548 disable = WL_RADIO_SW_DISABLE << 16;
1549 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1550 if (err)
1551 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1552
1553 if (dbm > 0xffff)
1554 txpwrmw = 0xffff;
1555 else
1556 txpwrmw = (u16) dbm;
1557 err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1558 (s32)brcmf_mw_to_qdbm(txpwrmw));
1559 if (err)
1560 brcmf_err("qtxpower error (%d)\n", err);
1561 cfg->conf->tx_power = dbm;
1562
1563done:
1564 brcmf_dbg(TRACE, "Exit\n");
1565 return err;
1566}
1567
1568static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1569 struct wireless_dev *wdev,
1570 s32 *dbm)
1571{
1572 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1573 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1574 s32 txpwrdbm;
1575 u8 result;
1576 s32 err = 0;
1577
1578 brcmf_dbg(TRACE, "Enter\n");
1579 if (!check_vif_up(ifp->vif))
1580 return -EIO;
1581
1582 err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1583 if (err) {
1584 brcmf_err("error (%d)\n", err);
1585 goto done;
1586 }
1587
1588 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1589 *dbm = (s32) brcmf_qdbm_to_mw(result);
1590
1591done:
1592 brcmf_dbg(TRACE, "Exit\n");
1593 return err;
1594}
1595
1596static s32
1597brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1598 u8 key_idx, bool unicast, bool multicast)
1599{
1600 struct brcmf_if *ifp = netdev_priv(ndev);
1601 u32 index;
1602 u32 wsec;
1603 s32 err = 0;
1604
1605 brcmf_dbg(TRACE, "Enter\n");
1606 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1607 if (!check_vif_up(ifp->vif))
1608 return -EIO;
1609
1610 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1611 if (err) {
1612 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1613 goto done;
1614 }
1615
1616 if (wsec & WEP_ENABLED) {
1617
1618 index = key_idx;
1619 err = brcmf_fil_cmd_int_set(ifp,
1620 BRCMF_C_SET_KEY_PRIMARY, index);
1621 if (err)
1622 brcmf_err("error (%d)\n", err);
1623 }
1624done:
1625 brcmf_dbg(TRACE, "Exit\n");
1626 return err;
1627}
1628
1629static s32
1630brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1631 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1632{
1633 struct brcmf_wsec_key key;
1634 s32 err = 0;
1635
1636 memset(&key, 0, sizeof(key));
1637 key.index = (u32) key_idx;
1638
1639
1640 if (!is_multicast_ether_addr(mac_addr))
1641 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1642 key.len = (u32) params->key_len;
1643
1644 if (key.len == 0) {
1645
1646 err = send_key_to_dongle(ndev, &key);
1647 if (err)
1648 brcmf_err("key delete error (%d)\n", err);
1649 } else {
1650 if (key.len > sizeof(key.data)) {
1651 brcmf_err("Invalid key length (%d)\n", key.len);
1652 return -EINVAL;
1653 }
1654
1655 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1656 memcpy(key.data, params->key, key.len);
1657
1658 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1659 u8 keybuf[8];
1660 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1661 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1662 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1663 }
1664
1665
1666 if (params->seq && params->seq_len == 6) {
1667
1668 u8 *ivptr;
1669 ivptr = (u8 *) params->seq;
1670 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1671 (ivptr[3] << 8) | ivptr[2];
1672 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1673 key.iv_initialized = true;
1674 }
1675
1676 switch (params->cipher) {
1677 case WLAN_CIPHER_SUITE_WEP40:
1678 key.algo = CRYPTO_ALGO_WEP1;
1679 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1680 break;
1681 case WLAN_CIPHER_SUITE_WEP104:
1682 key.algo = CRYPTO_ALGO_WEP128;
1683 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1684 break;
1685 case WLAN_CIPHER_SUITE_TKIP:
1686 key.algo = CRYPTO_ALGO_TKIP;
1687 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1688 break;
1689 case WLAN_CIPHER_SUITE_AES_CMAC:
1690 key.algo = CRYPTO_ALGO_AES_CCM;
1691 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1692 break;
1693 case WLAN_CIPHER_SUITE_CCMP:
1694 key.algo = CRYPTO_ALGO_AES_CCM;
1695 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1696 break;
1697 default:
1698 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1699 return -EINVAL;
1700 }
1701 err = send_key_to_dongle(ndev, &key);
1702 if (err)
1703 brcmf_err("wsec_key error (%d)\n", err);
1704 }
1705 return err;
1706}
1707
1708static s32
1709brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1710 u8 key_idx, bool pairwise, const u8 *mac_addr,
1711 struct key_params *params)
1712{
1713 struct brcmf_if *ifp = netdev_priv(ndev);
1714 struct brcmf_wsec_key key;
1715 s32 val;
1716 s32 wsec;
1717 s32 err = 0;
1718 u8 keybuf[8];
1719
1720 brcmf_dbg(TRACE, "Enter\n");
1721 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1722 if (!check_vif_up(ifp->vif))
1723 return -EIO;
1724
1725 if (mac_addr) {
1726 brcmf_dbg(TRACE, "Exit");
1727 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1728 }
1729 memset(&key, 0, sizeof(key));
1730
1731 key.len = (u32) params->key_len;
1732 key.index = (u32) key_idx;
1733
1734 if (key.len > sizeof(key.data)) {
1735 brcmf_err("Too long key length (%u)\n", key.len);
1736 err = -EINVAL;
1737 goto done;
1738 }
1739 memcpy(key.data, params->key, key.len);
1740
1741 key.flags = BRCMF_PRIMARY_KEY;
1742 switch (params->cipher) {
1743 case WLAN_CIPHER_SUITE_WEP40:
1744 key.algo = CRYPTO_ALGO_WEP1;
1745 val = WEP_ENABLED;
1746 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1747 break;
1748 case WLAN_CIPHER_SUITE_WEP104:
1749 key.algo = CRYPTO_ALGO_WEP128;
1750 val = WEP_ENABLED;
1751 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1752 break;
1753 case WLAN_CIPHER_SUITE_TKIP:
1754 if (ifp->vif->mode != WL_MODE_AP) {
1755 brcmf_dbg(CONN, "Swapping key\n");
1756 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1757 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1758 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1759 }
1760 key.algo = CRYPTO_ALGO_TKIP;
1761 val = TKIP_ENABLED;
1762 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1763 break;
1764 case WLAN_CIPHER_SUITE_AES_CMAC:
1765 key.algo = CRYPTO_ALGO_AES_CCM;
1766 val = AES_ENABLED;
1767 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1768 break;
1769 case WLAN_CIPHER_SUITE_CCMP:
1770 key.algo = CRYPTO_ALGO_AES_CCM;
1771 val = AES_ENABLED;
1772 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1773 break;
1774 default:
1775 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1776 err = -EINVAL;
1777 goto done;
1778 }
1779
1780 err = send_key_to_dongle(ndev, &key);
1781 if (err)
1782 goto done;
1783
1784 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1785 if (err) {
1786 brcmf_err("get wsec error (%d)\n", err);
1787 goto done;
1788 }
1789 wsec |= val;
1790 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1791 if (err) {
1792 brcmf_err("set wsec error (%d)\n", err);
1793 goto done;
1794 }
1795
1796done:
1797 brcmf_dbg(TRACE, "Exit\n");
1798 return err;
1799}
1800
1801static s32
1802brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1803 u8 key_idx, bool pairwise, const u8 *mac_addr)
1804{
1805 struct brcmf_if *ifp = netdev_priv(ndev);
1806 struct brcmf_wsec_key key;
1807 s32 err = 0;
1808
1809 brcmf_dbg(TRACE, "Enter\n");
1810 if (!check_vif_up(ifp->vif))
1811 return -EIO;
1812
1813 if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1814
1815 brcmf_err("invalid key index (%d)\n", key_idx);
1816 return -EINVAL;
1817 }
1818
1819 memset(&key, 0, sizeof(key));
1820
1821 key.index = (u32) key_idx;
1822 key.flags = BRCMF_PRIMARY_KEY;
1823 key.algo = CRYPTO_ALGO_OFF;
1824
1825 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1826
1827
1828 err = send_key_to_dongle(ndev, &key);
1829
1830 brcmf_dbg(TRACE, "Exit\n");
1831 return err;
1832}
1833
1834static s32
1835brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1836 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1837 void (*callback) (void *cookie, struct key_params * params))
1838{
1839 struct key_params params;
1840 struct brcmf_if *ifp = netdev_priv(ndev);
1841 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1842 struct brcmf_cfg80211_security *sec;
1843 s32 wsec;
1844 s32 err = 0;
1845
1846 brcmf_dbg(TRACE, "Enter\n");
1847 brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1848 if (!check_vif_up(ifp->vif))
1849 return -EIO;
1850
1851 memset(¶ms, 0, sizeof(params));
1852
1853 err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1854 if (err) {
1855 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1856
1857 err = -EAGAIN;
1858 goto done;
1859 }
1860 switch (wsec & ~SES_OW_ENABLED) {
1861 case WEP_ENABLED:
1862 sec = &profile->sec;
1863 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1864 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1865 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1866 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1867 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1868 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1869 }
1870 break;
1871 case TKIP_ENABLED:
1872 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1873 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1874 break;
1875 case AES_ENABLED:
1876 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1877 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1878 break;
1879 default:
1880 brcmf_err("Invalid algo (0x%x)\n", wsec);
1881 err = -EINVAL;
1882 goto done;
1883 }
1884 callback(cookie, ¶ms);
1885
1886done:
1887 brcmf_dbg(TRACE, "Exit\n");
1888 return err;
1889}
1890
1891static s32
1892brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1893 struct net_device *ndev, u8 key_idx)
1894{
1895 brcmf_dbg(INFO, "Not supported\n");
1896
1897 return -EOPNOTSUPP;
1898}
1899
1900static s32
1901brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1902 u8 *mac, struct station_info *sinfo)
1903{
1904 struct brcmf_if *ifp = netdev_priv(ndev);
1905 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1906 struct brcmf_scb_val_le scb_val;
1907 int rssi;
1908 s32 rate;
1909 s32 err = 0;
1910 u8 *bssid = profile->bssid;
1911 struct brcmf_sta_info_le sta_info_le;
1912
1913 brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
1914 if (!check_vif_up(ifp->vif))
1915 return -EIO;
1916
1917 if (ifp->vif->mode == WL_MODE_AP) {
1918 memcpy(&sta_info_le, mac, ETH_ALEN);
1919 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1920 &sta_info_le,
1921 sizeof(sta_info_le));
1922 if (err < 0) {
1923 brcmf_err("GET STA INFO failed, %d\n", err);
1924 goto done;
1925 }
1926 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1927 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1928 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1929 sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1930 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1931 }
1932 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
1933 sinfo->inactive_time, sinfo->connected_time);
1934 } else if (ifp->vif->mode == WL_MODE_BSS) {
1935 if (memcmp(mac, bssid, ETH_ALEN)) {
1936 brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1937 mac, bssid);
1938 err = -ENOENT;
1939 goto done;
1940 }
1941
1942 err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1943 if (err) {
1944 brcmf_err("Could not get rate (%d)\n", err);
1945 goto done;
1946 } else {
1947 sinfo->filled |= STATION_INFO_TX_BITRATE;
1948 sinfo->txrate.legacy = rate * 5;
1949 brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
1950 }
1951
1952 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1953 &ifp->vif->sme_state)) {
1954 memset(&scb_val, 0, sizeof(scb_val));
1955 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1956 &scb_val, sizeof(scb_val));
1957 if (err) {
1958 brcmf_err("Could not get rssi (%d)\n", err);
1959 goto done;
1960 } else {
1961 rssi = le32_to_cpu(scb_val.val);
1962 sinfo->filled |= STATION_INFO_SIGNAL;
1963 sinfo->signal = rssi;
1964 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
1965 }
1966 }
1967 } else
1968 err = -EPERM;
1969done:
1970 brcmf_dbg(TRACE, "Exit\n");
1971 return err;
1972}
1973
1974static s32
1975brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1976 bool enabled, s32 timeout)
1977{
1978 s32 pm;
1979 s32 err = 0;
1980 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1981 struct brcmf_if *ifp = netdev_priv(ndev);
1982
1983 brcmf_dbg(TRACE, "Enter\n");
1984
1985
1986
1987
1988
1989
1990
1991
1992 cfg->pwr_save = enabled;
1993 if (!check_vif_up(ifp->vif)) {
1994
1995 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
1996 goto done;
1997 }
1998
1999 pm = enabled ? PM_FAST : PM_OFF;
2000 brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2001
2002 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2003 if (err) {
2004 if (err == -ENODEV)
2005 brcmf_err("net_device is not ready yet\n");
2006 else
2007 brcmf_err("error (%d)\n", err);
2008 }
2009done:
2010 brcmf_dbg(TRACE, "Exit\n");
2011 return err;
2012}
2013
2014static s32
2015brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2016 const u8 *addr,
2017 const struct cfg80211_bitrate_mask *mask)
2018{
2019 struct brcmf_if *ifp = netdev_priv(ndev);
2020 struct brcm_rateset_le rateset_le;
2021 s32 rate;
2022 s32 val;
2023 s32 err_bg;
2024 s32 err_a;
2025 u32 legacy;
2026 s32 err = 0;
2027
2028 brcmf_dbg(TRACE, "Enter\n");
2029 if (!check_vif_up(ifp->vif))
2030 return -EIO;
2031
2032
2033
2034 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2035 &rateset_le, sizeof(rateset_le));
2036 if (err) {
2037 brcmf_err("could not get current rateset (%d)\n", err);
2038 goto done;
2039 }
2040
2041 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2042 if (!legacy)
2043 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2044 0xFFFF);
2045
2046 val = wl_g_rates[legacy - 1].bitrate * 100000;
2047
2048 if (val < le32_to_cpu(rateset_le.count))
2049
2050 rate = rateset_le.rates[val] & 0x7f;
2051 else
2052
2053 rate = val / 500000;
2054
2055 brcmf_dbg(CONN, "rate %d mbps\n", rate / 2);
2056
2057
2058
2059
2060
2061
2062 err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2063 err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2064 if (err_bg && err_a) {
2065 brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg,
2066 err_a);
2067 err = err_bg | err_a;
2068 }
2069
2070done:
2071 brcmf_dbg(TRACE, "Exit\n");
2072 return err;
2073}
2074
2075static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2076 struct brcmf_bss_info_le *bi)
2077{
2078 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2079 struct ieee80211_channel *notify_channel;
2080 struct cfg80211_bss *bss;
2081 struct ieee80211_supported_band *band;
2082 s32 err = 0;
2083 u16 channel;
2084 u32 freq;
2085 u16 notify_capability;
2086 u16 notify_interval;
2087 u8 *notify_ie;
2088 size_t notify_ielen;
2089 s32 notify_signal;
2090
2091 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2092 brcmf_err("Bss info is larger than buffer. Discarding\n");
2093 return 0;
2094 }
2095
2096 channel = bi->ctl_ch ? bi->ctl_ch :
2097 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2098
2099 if (channel <= CH_MAX_2G_CHANNEL)
2100 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2101 else
2102 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2103
2104 freq = ieee80211_channel_to_frequency(channel, band->band);
2105 notify_channel = ieee80211_get_channel(wiphy, freq);
2106
2107 notify_capability = le16_to_cpu(bi->capability);
2108 notify_interval = le16_to_cpu(bi->beacon_period);
2109 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2110 notify_ielen = le32_to_cpu(bi->ie_length);
2111 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2112
2113 brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2114 brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2115 brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2116 brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2117 brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2118
2119 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2120 0, notify_capability, notify_interval, notify_ie,
2121 notify_ielen, notify_signal, GFP_KERNEL);
2122
2123 if (!bss)
2124 return -ENOMEM;
2125
2126 cfg80211_put_bss(bss);
2127
2128 return err;
2129}
2130
2131static struct brcmf_bss_info_le *
2132next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2133{
2134 if (bss == NULL)
2135 return list->bss_info_le;
2136 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2137 le32_to_cpu(bss->length));
2138}
2139
2140static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2141{
2142 struct brcmf_scan_results *bss_list;
2143 struct brcmf_bss_info_le *bi = NULL;
2144 s32 err = 0;
2145 int i;
2146
2147 bss_list = cfg->bss_list;
2148 if (bss_list->count != 0 &&
2149 bss_list->version != BRCMF_BSS_INFO_VERSION) {
2150 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2151 bss_list->version);
2152 return -EOPNOTSUPP;
2153 }
2154 brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2155 for (i = 0; i < bss_list->count; i++) {
2156 bi = next_bss_le(bss_list, bi);
2157 err = brcmf_inform_single_bss(cfg, bi);
2158 if (err)
2159 break;
2160 }
2161 return err;
2162}
2163
2164static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2165 struct net_device *ndev, const u8 *bssid)
2166{
2167 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2168 struct ieee80211_channel *notify_channel;
2169 struct brcmf_bss_info_le *bi = NULL;
2170 struct ieee80211_supported_band *band;
2171 struct cfg80211_bss *bss;
2172 u8 *buf = NULL;
2173 s32 err = 0;
2174 u16 channel;
2175 u32 freq;
2176 u16 notify_capability;
2177 u16 notify_interval;
2178 u8 *notify_ie;
2179 size_t notify_ielen;
2180 s32 notify_signal;
2181
2182 brcmf_dbg(TRACE, "Enter\n");
2183
2184 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2185 if (buf == NULL) {
2186 err = -ENOMEM;
2187 goto CleanUp;
2188 }
2189
2190 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2191
2192 err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2193 buf, WL_BSS_INFO_MAX);
2194 if (err) {
2195 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2196 goto CleanUp;
2197 }
2198
2199 bi = (struct brcmf_bss_info_le *)(buf + 4);
2200
2201 channel = bi->ctl_ch ? bi->ctl_ch :
2202 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2203
2204 if (channel <= CH_MAX_2G_CHANNEL)
2205 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2206 else
2207 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2208
2209 freq = ieee80211_channel_to_frequency(channel, band->band);
2210 notify_channel = ieee80211_get_channel(wiphy, freq);
2211
2212 notify_capability = le16_to_cpu(bi->capability);
2213 notify_interval = le16_to_cpu(bi->beacon_period);
2214 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2215 notify_ielen = le32_to_cpu(bi->ie_length);
2216 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2217
2218 brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2219 brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2220 brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2221 brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2222
2223 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2224 0, notify_capability, notify_interval,
2225 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2226
2227 if (!bss) {
2228 err = -ENOMEM;
2229 goto CleanUp;
2230 }
2231
2232 cfg80211_put_bss(bss);
2233
2234CleanUp:
2235
2236 kfree(buf);
2237
2238 brcmf_dbg(TRACE, "Exit\n");
2239
2240 return err;
2241}
2242
2243static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2244{
2245 return vif->mode == WL_MODE_IBSS;
2246}
2247
2248
2249
2250
2251
2252
2253static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2254{
2255 struct brcmf_tlv *elt;
2256 int totlen;
2257
2258 elt = (struct brcmf_tlv *) buf;
2259 totlen = buflen;
2260
2261
2262 while (totlen >= TLV_HDR_LEN) {
2263 int len = elt->len;
2264
2265
2266 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2267 return elt;
2268
2269 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2270 totlen -= (len + TLV_HDR_LEN);
2271 }
2272
2273 return NULL;
2274}
2275
2276
2277
2278
2279static bool
2280brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2281 u8 *oui, u32 oui_len, u8 type)
2282{
2283
2284 if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2285 !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2286 type == ie[TLV_BODY_OFF + oui_len]) {
2287 return true;
2288 }
2289
2290 if (tlvs == NULL)
2291 return false;
2292
2293 ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2294
2295 *tlvs_len -= (int)(ie - *tlvs);
2296
2297 *tlvs = ie;
2298
2299 return false;
2300}
2301
2302static struct brcmf_vs_tlv *
2303brcmf_find_wpaie(u8 *parse, u32 len)
2304{
2305 struct brcmf_tlv *ie;
2306
2307 while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2308 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2309 WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2310 return (struct brcmf_vs_tlv *)ie;
2311 }
2312 return NULL;
2313}
2314
2315static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2316{
2317 struct net_device *ndev = cfg_to_ndev(cfg);
2318 struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2319 struct brcmf_if *ifp = netdev_priv(ndev);
2320 struct brcmf_bss_info_le *bi;
2321 struct brcmf_ssid *ssid;
2322 struct brcmf_tlv *tim;
2323 u16 beacon_interval;
2324 u8 dtim_period;
2325 size_t ie_len;
2326 u8 *ie;
2327 s32 err = 0;
2328
2329 brcmf_dbg(TRACE, "Enter\n");
2330 if (brcmf_is_ibssmode(ifp->vif))
2331 return err;
2332
2333 ssid = &profile->ssid;
2334
2335 *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2336 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2337 cfg->extra_buf, WL_EXTRA_BUF_MAX);
2338 if (err) {
2339 brcmf_err("Could not get bss info %d\n", err);
2340 goto update_bss_info_out;
2341 }
2342
2343 bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2344 err = brcmf_inform_single_bss(cfg, bi);
2345 if (err)
2346 goto update_bss_info_out;
2347
2348 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2349 ie_len = le32_to_cpu(bi->ie_length);
2350 beacon_interval = le16_to_cpu(bi->beacon_period);
2351
2352 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2353 if (tim)
2354 dtim_period = tim->data[1];
2355 else {
2356
2357
2358
2359
2360
2361 u32 var;
2362 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2363 if (err) {
2364 brcmf_err("wl dtim_assoc failed (%d)\n", err);
2365 goto update_bss_info_out;
2366 }
2367 dtim_period = (u8)var;
2368 }
2369
2370update_bss_info_out:
2371 brcmf_dbg(TRACE, "Exit");
2372 return err;
2373}
2374
2375static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2376{
2377 struct escan_info *escan = &cfg->escan_info;
2378
2379 set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2380 if (cfg->scan_request) {
2381 escan->escan_state = WL_ESCAN_STATE_IDLE;
2382 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2383 }
2384 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2385 clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2386}
2387
2388static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2389{
2390 struct brcmf_cfg80211_info *cfg =
2391 container_of(work, struct brcmf_cfg80211_info,
2392 escan_timeout_work);
2393
2394 brcmf_notify_escan_complete(cfg,
2395 cfg->escan_info.ndev, true, true);
2396}
2397
2398static void brcmf_escan_timeout(unsigned long data)
2399{
2400 struct brcmf_cfg80211_info *cfg =
2401 (struct brcmf_cfg80211_info *)data;
2402
2403 if (cfg->scan_request) {
2404 brcmf_err("timer expired\n");
2405 schedule_work(&cfg->escan_timeout_work);
2406 }
2407}
2408
2409static s32
2410brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2411 struct brcmf_bss_info_le *bss_info_le)
2412{
2413 if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2414 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2415 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2416 bss_info_le->SSID_len == bss->SSID_len &&
2417 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2418 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2419 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2420 s16 bss_rssi = le16_to_cpu(bss->RSSI);
2421 s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2422
2423
2424
2425
2426 if (bss_info_rssi > bss_rssi)
2427 bss->RSSI = bss_info_le->RSSI;
2428 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2429 (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2430
2431
2432
2433 bss->RSSI = bss_info_le->RSSI;
2434 bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2435 }
2436 return 1;
2437 }
2438 return 0;
2439}
2440
2441static s32
2442brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2443 const struct brcmf_event_msg *e, void *data)
2444{
2445 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2446 struct net_device *ndev = ifp->ndev;
2447 s32 status;
2448 s32 err = 0;
2449 struct brcmf_escan_result_le *escan_result_le;
2450 struct brcmf_bss_info_le *bss_info_le;
2451 struct brcmf_bss_info_le *bss = NULL;
2452 u32 bi_length;
2453 struct brcmf_scan_results *list;
2454 u32 i;
2455 bool aborted;
2456
2457 status = e->status;
2458
2459 if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2460 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2461 !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2462 return -EPERM;
2463 }
2464
2465 if (status == BRCMF_E_STATUS_PARTIAL) {
2466 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2467 escan_result_le = (struct brcmf_escan_result_le *) data;
2468 if (!escan_result_le) {
2469 brcmf_err("Invalid escan result (NULL pointer)\n");
2470 goto exit;
2471 }
2472 if (!cfg->scan_request) {
2473 brcmf_dbg(SCAN, "result without cfg80211 request\n");
2474 goto exit;
2475 }
2476
2477 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2478 brcmf_err("Invalid bss_count %d: ignoring\n",
2479 escan_result_le->bss_count);
2480 goto exit;
2481 }
2482 bss_info_le = &escan_result_le->bss_info_le;
2483
2484 bi_length = le32_to_cpu(bss_info_le->length);
2485 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2486 WL_ESCAN_RESULTS_FIXED_SIZE)) {
2487 brcmf_err("Invalid bss_info length %d: ignoring\n",
2488 bi_length);
2489 goto exit;
2490 }
2491
2492 if (!(cfg_to_wiphy(cfg)->interface_modes &
2493 BIT(NL80211_IFTYPE_ADHOC))) {
2494 if (le16_to_cpu(bss_info_le->capability) &
2495 WLAN_CAPABILITY_IBSS) {
2496 brcmf_err("Ignoring IBSS result\n");
2497 goto exit;
2498 }
2499 }
2500
2501 list = (struct brcmf_scan_results *)
2502 cfg->escan_info.escan_buf;
2503 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2504 brcmf_err("Buffer is too small: ignoring\n");
2505 goto exit;
2506 }
2507
2508 for (i = 0; i < list->count; i++) {
2509 bss = bss ? (struct brcmf_bss_info_le *)
2510 ((unsigned char *)bss +
2511 le32_to_cpu(bss->length)) : list->bss_info_le;
2512 if (brcmf_compare_update_same_bss(bss, bss_info_le))
2513 goto exit;
2514 }
2515 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2516 bss_info_le, bi_length);
2517 list->version = le32_to_cpu(bss_info_le->version);
2518 list->buflen += bi_length;
2519 list->count++;
2520 } else {
2521 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2522 if (cfg->scan_request) {
2523 cfg->bss_list = (struct brcmf_scan_results *)
2524 cfg->escan_info.escan_buf;
2525 brcmf_inform_bss(cfg);
2526 aborted = status != BRCMF_E_STATUS_SUCCESS;
2527 brcmf_notify_escan_complete(cfg, ndev, aborted,
2528 false);
2529 } else
2530 brcmf_err("Unexpected scan result 0x%x\n", status);
2531 }
2532exit:
2533 return err;
2534}
2535
2536static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2537{
2538 brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2539 brcmf_cfg80211_escan_handler);
2540 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2541
2542 init_timer(&cfg->escan_timeout);
2543 cfg->escan_timeout.data = (unsigned long) cfg;
2544 cfg->escan_timeout.function = brcmf_escan_timeout;
2545 INIT_WORK(&cfg->escan_timeout_work,
2546 brcmf_cfg80211_escan_timeout_worker);
2547}
2548
2549static __always_inline void brcmf_delay(u32 ms)
2550{
2551 if (ms < 1000 / HZ) {
2552 cond_resched();
2553 mdelay(ms);
2554 } else {
2555 msleep(ms);
2556 }
2557}
2558
2559static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2560{
2561 brcmf_dbg(TRACE, "Enter\n");
2562
2563 return 0;
2564}
2565
2566static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2567 struct cfg80211_wowlan *wow)
2568{
2569 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2570 struct net_device *ndev = cfg_to_ndev(cfg);
2571 struct brcmf_cfg80211_vif *vif;
2572
2573 brcmf_dbg(TRACE, "Enter\n");
2574
2575
2576
2577
2578
2579 vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2580 if (!check_vif_up(vif))
2581 goto exit;
2582
2583 list_for_each_entry(vif, &cfg->vif_list, list) {
2584 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2585 continue;
2586
2587
2588
2589
2590 brcmf_link_down(vif);
2591
2592
2593
2594
2595
2596 brcmf_delay(500);
2597 }
2598
2599
2600 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2601 brcmf_abort_scanning(cfg);
2602
2603
2604 brcmf_set_mpc(ndev, 1);
2605
2606exit:
2607 brcmf_dbg(TRACE, "Exit\n");
2608
2609 cfg->scan_status = 0;
2610 return 0;
2611}
2612
2613static __used s32
2614brcmf_update_pmklist(struct net_device *ndev,
2615 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2616{
2617 int i, j;
2618 int pmkid_len;
2619
2620 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2621
2622 brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2623 for (i = 0; i < pmkid_len; i++) {
2624 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2625 &pmk_list->pmkids.pmkid[i].BSSID);
2626 for (j = 0; j < WLAN_PMKID_LEN; j++)
2627 brcmf_dbg(CONN, "%02x\n",
2628 pmk_list->pmkids.pmkid[i].PMKID[j]);
2629 }
2630
2631 if (!err)
2632 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2633 (char *)pmk_list, sizeof(*pmk_list));
2634
2635 return err;
2636}
2637
2638static s32
2639brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2640 struct cfg80211_pmksa *pmksa)
2641{
2642 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2643 struct brcmf_if *ifp = netdev_priv(ndev);
2644 struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2645 s32 err = 0;
2646 int i;
2647 int pmkid_len;
2648
2649 brcmf_dbg(TRACE, "Enter\n");
2650 if (!check_vif_up(ifp->vif))
2651 return -EIO;
2652
2653 pmkid_len = le32_to_cpu(pmkids->npmkid);
2654 for (i = 0; i < pmkid_len; i++)
2655 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2656 break;
2657 if (i < WL_NUM_PMKIDS_MAX) {
2658 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2659 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2660 if (i == pmkid_len) {
2661 pmkid_len++;
2662 pmkids->npmkid = cpu_to_le32(pmkid_len);
2663 }
2664 } else
2665 err = -EINVAL;
2666
2667 brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2668 pmkids->pmkid[pmkid_len].BSSID);
2669 for (i = 0; i < WLAN_PMKID_LEN; i++)
2670 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2671
2672 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2673
2674 brcmf_dbg(TRACE, "Exit\n");
2675 return err;
2676}
2677
2678static s32
2679brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2680 struct cfg80211_pmksa *pmksa)
2681{
2682 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2683 struct brcmf_if *ifp = netdev_priv(ndev);
2684 struct pmkid_list pmkid;
2685 s32 err = 0;
2686 int i, pmkid_len;
2687
2688 brcmf_dbg(TRACE, "Enter\n");
2689 if (!check_vif_up(ifp->vif))
2690 return -EIO;
2691
2692 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2693 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2694
2695 brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2696 &pmkid.pmkid[0].BSSID);
2697 for (i = 0; i < WLAN_PMKID_LEN; i++)
2698 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2699
2700 pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2701 for (i = 0; i < pmkid_len; i++)
2702 if (!memcmp
2703 (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2704 ETH_ALEN))
2705 break;
2706
2707 if ((pmkid_len > 0)
2708 && (i < pmkid_len)) {
2709 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2710 sizeof(struct pmkid));
2711 for (; i < (pmkid_len - 1); i++) {
2712 memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2713 &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2714 ETH_ALEN);
2715 memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2716 &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2717 WLAN_PMKID_LEN);
2718 }
2719 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2720 } else
2721 err = -EINVAL;
2722
2723 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2724
2725 brcmf_dbg(TRACE, "Exit\n");
2726 return err;
2727
2728}
2729
2730static s32
2731brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2732{
2733 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2734 struct brcmf_if *ifp = netdev_priv(ndev);
2735 s32 err = 0;
2736
2737 brcmf_dbg(TRACE, "Enter\n");
2738 if (!check_vif_up(ifp->vif))
2739 return -EIO;
2740
2741 memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2742 err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2743
2744 brcmf_dbg(TRACE, "Exit\n");
2745 return err;
2746
2747}
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757static s32
2758brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2759 const struct brcmf_event_msg *e, void *data)
2760{
2761 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2762 struct net_device *ndev = ifp->ndev;
2763 struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2764 struct cfg80211_scan_request *request = NULL;
2765 struct cfg80211_ssid *ssid = NULL;
2766 struct ieee80211_channel *channel = NULL;
2767 struct wiphy *wiphy = cfg_to_wiphy(cfg);
2768 int err = 0;
2769 int channel_req = 0;
2770 int band = 0;
2771 struct brcmf_pno_scanresults_le *pfn_result;
2772 u32 result_count;
2773 u32 status;
2774
2775 brcmf_dbg(SCAN, "Enter\n");
2776
2777 if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2778 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2779 return 0;
2780 }
2781
2782 pfn_result = (struct brcmf_pno_scanresults_le *)data;
2783 result_count = le32_to_cpu(pfn_result->count);
2784 status = le32_to_cpu(pfn_result->status);
2785
2786
2787
2788
2789
2790 WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2791 brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2792 if (result_count > 0) {
2793 int i;
2794
2795 request = kzalloc(sizeof(*request), GFP_KERNEL);
2796 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2797 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2798 if (!request || !ssid || !channel) {
2799 err = -ENOMEM;
2800 goto out_err;
2801 }
2802
2803 request->wiphy = wiphy;
2804 data += sizeof(struct brcmf_pno_scanresults_le);
2805 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2806
2807 for (i = 0; i < result_count; i++) {
2808 netinfo = &netinfo_start[i];
2809 if (!netinfo) {
2810 brcmf_err("Invalid netinfo ptr. index: %d\n",
2811 i);
2812 err = -EINVAL;
2813 goto out_err;
2814 }
2815
2816 brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2817 netinfo->SSID, netinfo->channel);
2818 memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2819 ssid[i].ssid_len = netinfo->SSID_len;
2820 request->n_ssids++;
2821
2822 channel_req = netinfo->channel;
2823 if (channel_req <= CH_MAX_2G_CHANNEL)
2824 band = NL80211_BAND_2GHZ;
2825 else
2826 band = NL80211_BAND_5GHZ;
2827 channel[i].center_freq =
2828 ieee80211_channel_to_frequency(channel_req,
2829 band);
2830 channel[i].band = band;
2831 channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2832 request->channels[i] = &channel[i];
2833 request->n_channels++;
2834 }
2835
2836
2837 if (request->n_ssids)
2838 request->ssids = &ssid[0];
2839
2840 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2841
2842 brcmf_abort_scanning(cfg);
2843 }
2844
2845 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2846 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2847 if (err) {
2848 clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2849 goto out_err;
2850 }
2851 cfg->sched_escan = true;
2852 cfg->scan_request = request;
2853 } else {
2854 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2855 goto out_err;
2856 }
2857
2858 kfree(ssid);
2859 kfree(channel);
2860 kfree(request);
2861 return 0;
2862
2863out_err:
2864 kfree(ssid);
2865 kfree(channel);
2866 kfree(request);
2867 cfg80211_sched_scan_stopped(wiphy);
2868 return err;
2869}
2870
2871static int brcmf_dev_pno_clean(struct net_device *ndev)
2872{
2873 int ret;
2874
2875
2876 ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2877 if (ret == 0) {
2878
2879 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2880 NULL, 0);
2881 }
2882 if (ret < 0)
2883 brcmf_err("failed code %d\n", ret);
2884
2885 return ret;
2886}
2887
2888static int brcmf_dev_pno_config(struct net_device *ndev)
2889{
2890 struct brcmf_pno_param_le pfn_param;
2891
2892 memset(&pfn_param, 0, sizeof(pfn_param));
2893 pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2894
2895
2896 pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2897 pfn_param.repeat = BRCMF_PNO_REPEAT;
2898 pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2899
2900
2901 pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2902
2903 return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2904 &pfn_param, sizeof(pfn_param));
2905}
2906
2907static int
2908brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2909 struct net_device *ndev,
2910 struct cfg80211_sched_scan_request *request)
2911{
2912 struct brcmf_if *ifp = netdev_priv(ndev);
2913 struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2914 struct brcmf_pno_net_param_le pfn;
2915 int i;
2916 int ret = 0;
2917
2918 brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
2919 request->n_match_sets, request->n_ssids);
2920 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2921 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
2922 return -EAGAIN;
2923 }
2924
2925 if (!request || !request->n_ssids || !request->n_match_sets) {
2926 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2927 request ? request->n_ssids : 0);
2928 return -EINVAL;
2929 }
2930
2931 if (request->n_ssids > 0) {
2932 for (i = 0; i < request->n_ssids; i++) {
2933
2934 brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
2935 request->ssids[i].ssid);
2936
2937
2938
2939
2940
2941 }
2942 }
2943
2944 if (request->n_match_sets > 0) {
2945
2946 ret = brcmf_dev_pno_clean(ndev);
2947 if (ret < 0) {
2948 brcmf_err("failed error=%d\n", ret);
2949 return ret;
2950 }
2951
2952
2953 ret = brcmf_dev_pno_config(ndev);
2954 if (ret < 0) {
2955 brcmf_err("PNO setup failed!! ret=%d\n", ret);
2956 return -EINVAL;
2957 }
2958
2959
2960 for (i = 0; i < request->n_match_sets; i++) {
2961 struct cfg80211_ssid *ssid;
2962 u32 ssid_len;
2963
2964 ssid = &request->match_sets[i].ssid;
2965 ssid_len = ssid->ssid_len;
2966
2967 if (!ssid_len) {
2968 brcmf_err("skip broadcast ssid\n");
2969 continue;
2970 }
2971 pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2972 pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2973 pfn.wsec = cpu_to_le32(0);
2974 pfn.infra = cpu_to_le32(1);
2975 pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2976 pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2977 memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2978 ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2979 sizeof(pfn));
2980 brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
2981 ret == 0 ? "set" : "failed", ssid->ssid);
2982 }
2983
2984 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2985 brcmf_err("PNO enable failed!! ret=%d\n", ret);
2986 return -EINVAL;
2987 }
2988 } else {
2989 return -EINVAL;
2990 }
2991
2992 return 0;
2993}
2994
2995static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2996 struct net_device *ndev)
2997{
2998 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2999
3000 brcmf_dbg(SCAN, "enter\n");
3001 brcmf_dev_pno_clean(ndev);
3002 if (cfg->sched_escan)
3003 brcmf_notify_escan_complete(cfg, ndev, true, true);
3004 return 0;
3005}
3006
3007#ifdef CONFIG_NL80211_TESTMODE
3008static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3009{
3010 struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3011 struct net_device *ndev = cfg_to_ndev(cfg);
3012 struct brcmf_dcmd *dcmd = data;
3013 struct sk_buff *reply;
3014 int ret;
3015
3016 brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3017 dcmd->buf, dcmd->len);
3018
3019 if (dcmd->set)
3020 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3021 dcmd->buf, dcmd->len);
3022 else
3023 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3024 dcmd->buf, dcmd->len);
3025 if (ret == 0) {
3026 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3027 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3028 ret = cfg80211_testmode_reply(reply);
3029 }
3030 return ret;
3031}
3032#endif
3033
3034static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3035{
3036 struct brcmf_if *ifp = netdev_priv(ndev);
3037 s32 err;
3038
3039
3040 err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3041 if (err < 0) {
3042 brcmf_err("auth error %d\n", err);
3043 return err;
3044 }
3045
3046 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3047 if (err < 0) {
3048 brcmf_err("wsec error %d\n", err);
3049 return err;
3050 }
3051
3052 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3053 if (err < 0) {
3054 brcmf_err("wpa_auth error %d\n", err);
3055 return err;
3056 }
3057
3058 return 0;
3059}
3060
3061static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3062{
3063 if (is_rsn_ie)
3064 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3065
3066 return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3067}
3068
3069static s32
3070brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3071 bool is_rsn_ie)
3072{
3073 struct brcmf_if *ifp = netdev_priv(ndev);
3074 u32 auth = 0;
3075 u16 count;
3076 s32 err = 0;
3077 s32 len = 0;
3078 u32 i;
3079 u32 wsec;
3080 u32 pval = 0;
3081 u32 gval = 0;
3082 u32 wpa_auth = 0;
3083 u32 offset;
3084 u8 *data;
3085 u16 rsn_cap;
3086 u32 wme_bss_disable;
3087
3088 brcmf_dbg(TRACE, "Enter\n");
3089 if (wpa_ie == NULL)
3090 goto exit;
3091
3092 len = wpa_ie->len + TLV_HDR_LEN;
3093 data = (u8 *)wpa_ie;
3094 offset = TLV_HDR_LEN;
3095 if (!is_rsn_ie)
3096 offset += VS_IE_FIXED_HDR_LEN;
3097 else
3098 offset += WPA_IE_VERSION_LEN;
3099
3100
3101 if (offset + WPA_IE_MIN_OUI_LEN > len) {
3102 err = -EINVAL;
3103 brcmf_err("no multicast cipher suite\n");
3104 goto exit;
3105 }
3106
3107 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3108 err = -EINVAL;
3109 brcmf_err("ivalid OUI\n");
3110 goto exit;
3111 }
3112 offset += TLV_OUI_LEN;
3113
3114
3115 switch (data[offset]) {
3116 case WPA_CIPHER_NONE:
3117 gval = 0;
3118 break;
3119 case WPA_CIPHER_WEP_40:
3120 case WPA_CIPHER_WEP_104:
3121 gval = WEP_ENABLED;
3122 break;
3123 case WPA_CIPHER_TKIP:
3124 gval = TKIP_ENABLED;
3125 break;
3126 case WPA_CIPHER_AES_CCM:
3127 gval = AES_ENABLED;
3128 break;
3129 default:
3130 err = -EINVAL;
3131 brcmf_err("Invalid multi cast cipher info\n");
3132 goto exit;
3133 }
3134
3135 offset++;
3136
3137 count = data[offset] + (data[offset + 1] << 8);
3138 offset += WPA_IE_SUITE_COUNT_LEN;
3139
3140 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3141 err = -EINVAL;
3142 brcmf_err("no unicast cipher suite\n");
3143 goto exit;
3144 }
3145 for (i = 0; i < count; i++) {
3146 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3147 err = -EINVAL;
3148 brcmf_err("ivalid OUI\n");
3149 goto exit;
3150 }
3151 offset += TLV_OUI_LEN;
3152 switch (data[offset]) {
3153 case WPA_CIPHER_NONE:
3154 break;
3155 case WPA_CIPHER_WEP_40:
3156 case WPA_CIPHER_WEP_104:
3157 pval |= WEP_ENABLED;
3158 break;
3159 case WPA_CIPHER_TKIP:
3160 pval |= TKIP_ENABLED;
3161 break;
3162 case WPA_CIPHER_AES_CCM:
3163 pval |= AES_ENABLED;
3164 break;
3165 default:
3166 brcmf_err("Ivalid unicast security info\n");
3167 }
3168 offset++;
3169 }
3170
3171 count = data[offset] + (data[offset + 1] << 8);
3172 offset += WPA_IE_SUITE_COUNT_LEN;
3173
3174 if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3175 err = -EINVAL;
3176 brcmf_err("no auth key mgmt suite\n");
3177 goto exit;
3178 }
3179 for (i = 0; i < count; i++) {
3180 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3181 err = -EINVAL;
3182 brcmf_err("ivalid OUI\n");
3183 goto exit;
3184 }
3185 offset += TLV_OUI_LEN;
3186 switch (data[offset]) {
3187 case RSN_AKM_NONE:
3188 brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3189 wpa_auth |= WPA_AUTH_NONE;
3190 break;
3191 case RSN_AKM_UNSPECIFIED:
3192 brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3193 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3194 (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3195 break;
3196 case RSN_AKM_PSK:
3197 brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3198 is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3199 (wpa_auth |= WPA_AUTH_PSK);
3200 break;
3201 default:
3202 brcmf_err("Ivalid key mgmt info\n");
3203 }
3204 offset++;
3205 }
3206
3207 if (is_rsn_ie) {
3208 wme_bss_disable = 1;
3209 if ((offset + RSN_CAP_LEN) <= len) {
3210 rsn_cap = data[offset] + (data[offset + 1] << 8);
3211 if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3212 wme_bss_disable = 0;
3213 }
3214
3215 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3216 wme_bss_disable);
3217 if (err < 0) {
3218 brcmf_err("wme_bss_disable error %d\n", err);
3219 goto exit;
3220 }
3221 }
3222
3223 wsec = (pval | gval | SES_OW_ENABLED);
3224
3225
3226 err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3227 if (err < 0) {
3228 brcmf_err("auth error %d\n", err);
3229 goto exit;
3230 }
3231
3232 err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3233 if (err < 0) {
3234 brcmf_err("wsec error %d\n", err);
3235 goto exit;
3236 }
3237
3238 err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3239 if (err < 0) {
3240 brcmf_err("wpa_auth error %d\n", err);
3241 goto exit;
3242 }
3243
3244exit:
3245 return err;
3246}
3247
3248static s32
3249brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3250 struct parsed_vndr_ies *vndr_ies)
3251{
3252 s32 err = 0;
3253 struct brcmf_vs_tlv *vndrie;
3254 struct brcmf_tlv *ie;
3255 struct parsed_vndr_ie_info *parsed_info;
3256 s32 remaining_len;
3257
3258 remaining_len = (s32)vndr_ie_len;
3259 memset(vndr_ies, 0, sizeof(*vndr_ies));
3260
3261 ie = (struct brcmf_tlv *)vndr_ie_buf;
3262 while (ie) {
3263 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3264 goto next;
3265 vndrie = (struct brcmf_vs_tlv *)ie;
3266
3267 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3268 brcmf_err("invalid vndr ie. length is too small %d\n",
3269 vndrie->len);
3270 goto next;
3271 }
3272
3273 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3274 ((vndrie->oui_type == WPA_OUI_TYPE) ||
3275 (vndrie->oui_type == WME_OUI_TYPE))) {
3276 brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3277 goto next;
3278 }
3279
3280 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3281
3282
3283 parsed_info->ie_ptr = (char *)vndrie;
3284 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3285 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3286
3287 vndr_ies->count++;
3288
3289 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3290 parsed_info->vndrie.oui[0],
3291 parsed_info->vndrie.oui[1],
3292 parsed_info->vndrie.oui[2],
3293 parsed_info->vndrie.oui_type);
3294
3295 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3296 break;
3297next:
3298 remaining_len -= (ie->len + TLV_HDR_LEN);
3299 if (remaining_len <= TLV_HDR_LEN)
3300 ie = NULL;
3301 else
3302 ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3303 TLV_HDR_LEN);
3304 }
3305 return err;
3306}
3307
3308static u32
3309brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3310{
3311
3312 __le32 iecount_le;
3313 __le32 pktflag_le;
3314
3315 strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3316 iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3317
3318 iecount_le = cpu_to_le32(1);
3319 memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3320
3321 pktflag_le = cpu_to_le32(pktflag);
3322 memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3323
3324 memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3325
3326 return ie_len + VNDR_IE_HDR_SIZE;
3327}
3328
3329static
3330s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3331 const u8 *vndr_ie_buf, u32 vndr_ie_len)
3332{
3333 struct brcmf_if *ifp;
3334 struct vif_saved_ie *saved_ie;
3335 s32 err = 0;
3336 u8 *iovar_ie_buf;
3337 u8 *curr_ie_buf;
3338 u8 *mgmt_ie_buf = NULL;
3339 int mgmt_ie_buf_len;
3340 u32 *mgmt_ie_len;
3341 u32 del_add_ie_buf_len = 0;
3342 u32 total_ie_buf_len = 0;
3343 u32 parsed_ie_buf_len = 0;
3344 struct parsed_vndr_ies old_vndr_ies;
3345 struct parsed_vndr_ies new_vndr_ies;
3346 struct parsed_vndr_ie_info *vndrie_info;
3347 s32 i;
3348 u8 *ptr;
3349 int remained_buf_len;
3350
3351 if (!vif)
3352 return -ENODEV;
3353 ifp = vif->ifp;
3354 saved_ie = &vif->saved_ie;
3355
3356 brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3357 iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3358 if (!iovar_ie_buf)
3359 return -ENOMEM;
3360 curr_ie_buf = iovar_ie_buf;
3361 if (ifp->vif->mode == WL_MODE_AP) {
3362 switch (pktflag) {
3363 case VNDR_IE_PRBRSP_FLAG:
3364 mgmt_ie_buf = saved_ie->probe_res_ie;
3365 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3366 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3367 break;
3368 case VNDR_IE_BEACON_FLAG:
3369 mgmt_ie_buf = saved_ie->beacon_ie;
3370 mgmt_ie_len = &saved_ie->beacon_ie_len;
3371 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3372 break;
3373 default:
3374 err = -EPERM;
3375 brcmf_err("not suitable type\n");
3376 goto exit;
3377 }
3378 } else {
3379 err = -EPERM;
3380 brcmf_err("not suitable type\n");
3381 goto exit;
3382 }
3383
3384 if (vndr_ie_len > mgmt_ie_buf_len) {
3385 err = -ENOMEM;
3386 brcmf_err("extra IE size too big\n");
3387 goto exit;
3388 }
3389
3390
3391 if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3392 ptr = curr_ie_buf;
3393 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3394 for (i = 0; i < new_vndr_ies.count; i++) {
3395 vndrie_info = &new_vndr_ies.ie_info[i];
3396 memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3397 vndrie_info->ie_len);
3398 parsed_ie_buf_len += vndrie_info->ie_len;
3399 }
3400 }
3401
3402 if (mgmt_ie_buf && *mgmt_ie_len) {
3403 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3404 (memcmp(mgmt_ie_buf, curr_ie_buf,
3405 parsed_ie_buf_len) == 0)) {
3406 brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3407 goto exit;
3408 }
3409
3410
3411 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3412
3413
3414 for (i = 0; i < old_vndr_ies.count; i++) {
3415 vndrie_info = &old_vndr_ies.ie_info[i];
3416
3417 brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3418 vndrie_info->vndrie.id,
3419 vndrie_info->vndrie.len,
3420 vndrie_info->vndrie.oui[0],
3421 vndrie_info->vndrie.oui[1],
3422 vndrie_info->vndrie.oui[2]);
3423
3424 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3425 vndrie_info->ie_ptr,
3426 vndrie_info->ie_len,
3427 "del");
3428 curr_ie_buf += del_add_ie_buf_len;
3429 total_ie_buf_len += del_add_ie_buf_len;
3430 }
3431 }
3432
3433 *mgmt_ie_len = 0;
3434
3435 if (mgmt_ie_buf && parsed_ie_buf_len) {
3436 ptr = mgmt_ie_buf;
3437
3438 remained_buf_len = mgmt_ie_buf_len;
3439
3440
3441 for (i = 0; i < new_vndr_ies.count; i++) {
3442 vndrie_info = &new_vndr_ies.ie_info[i];
3443
3444
3445 if (remained_buf_len < (vndrie_info->vndrie.len +
3446 VNDR_IE_VSIE_OFFSET)) {
3447 brcmf_err("no space in mgmt_ie_buf: len left %d",
3448 remained_buf_len);
3449 break;
3450 }
3451 remained_buf_len -= (vndrie_info->ie_len +
3452 VNDR_IE_VSIE_OFFSET);
3453
3454 brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3455 vndrie_info->vndrie.id,
3456 vndrie_info->vndrie.len,
3457 vndrie_info->vndrie.oui[0],
3458 vndrie_info->vndrie.oui[1],
3459 vndrie_info->vndrie.oui[2]);
3460
3461 del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3462 vndrie_info->ie_ptr,
3463 vndrie_info->ie_len,
3464 "add");
3465
3466
3467 memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3468 vndrie_info->ie_len);
3469 *mgmt_ie_len += vndrie_info->ie_len;
3470
3471 curr_ie_buf += del_add_ie_buf_len;
3472 total_ie_buf_len += del_add_ie_buf_len;
3473 }
3474 }
3475 if (total_ie_buf_len) {
3476 err = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3477 total_ie_buf_len);
3478 if (err)
3479 brcmf_err("vndr ie set error : %d\n", err);
3480 }
3481
3482exit:
3483 kfree(iovar_ie_buf);
3484 return err;
3485}
3486
3487static s32
3488brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3489 struct cfg80211_ap_settings *settings)
3490{
3491 s32 ie_offset;
3492 struct brcmf_if *ifp = netdev_priv(ndev);
3493 struct brcmf_tlv *ssid_ie;
3494 struct brcmf_ssid_le ssid_le;
3495 s32 err = -EPERM;
3496 struct brcmf_tlv *rsn_ie;
3497 struct brcmf_vs_tlv *wpa_ie;
3498 struct brcmf_join_params join_params;
3499 s32 bssidx = 0;
3500
3501 brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3502 cfg80211_get_chandef_type(&settings->chandef),
3503 settings->beacon_interval,
3504 settings->dtim_period);
3505 brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3506 settings->ssid, settings->ssid_len, settings->auth_type,
3507 settings->inactivity_timeout);
3508
3509 if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3510 brcmf_err("Not in AP creation mode\n");
3511 return -EPERM;
3512 }
3513
3514 memset(&ssid_le, 0, sizeof(ssid_le));
3515 if (settings->ssid == NULL || settings->ssid_len == 0) {
3516 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3517 ssid_ie = brcmf_parse_tlvs(
3518 (u8 *)&settings->beacon.head[ie_offset],
3519 settings->beacon.head_len - ie_offset,
3520 WLAN_EID_SSID);
3521 if (!ssid_ie)
3522 return -EINVAL;
3523
3524 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3525 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3526 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3527 } else {
3528 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3529 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3530 }
3531
3532 brcmf_set_mpc(ndev, 0);
3533 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3534 if (err < 0) {
3535 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3536 goto exit;
3537 }
3538 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3539 if (err < 0) {
3540 brcmf_err("SET INFRA error %d\n", err);
3541 goto exit;
3542 }
3543 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3544 if (err < 0) {
3545 brcmf_err("setting AP mode failed %d\n", err);
3546 goto exit;
3547 }
3548
3549
3550 rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3551 settings->beacon.tail_len, WLAN_EID_RSN);
3552
3553
3554 wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3555 settings->beacon.tail_len);
3556
3557 if ((wpa_ie != NULL || rsn_ie != NULL)) {
3558 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3559 if (wpa_ie != NULL) {
3560
3561 err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3562 if (err < 0)
3563 goto exit;
3564 } else {
3565
3566 err = brcmf_configure_wpaie(ndev,
3567 (struct brcmf_vs_tlv *)rsn_ie, true);
3568 if (err < 0)
3569 goto exit;
3570 }
3571 } else {
3572 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3573 brcmf_configure_opensecurity(ndev, bssidx);
3574 }
3575
3576 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3577 VNDR_IE_BEACON_FLAG,
3578 settings->beacon.tail,
3579 settings->beacon.tail_len);
3580 if (err)
3581 brcmf_err("Set Beacon IE Failed\n");
3582 else
3583 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3584
3585
3586 err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3587 VNDR_IE_PRBRSP_FLAG,
3588 settings->beacon.proberesp_ies,
3589 settings->beacon.proberesp_ies_len);
3590 if (err)
3591 brcmf_err("Set Probe Resp IE Failed\n");
3592 else
3593 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3594
3595 if (settings->beacon_interval) {
3596 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3597 settings->beacon_interval);
3598 if (err < 0) {
3599 brcmf_err("Beacon Interval Set Error, %d\n", err);
3600 goto exit;
3601 }
3602 }
3603 if (settings->dtim_period) {
3604 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3605 settings->dtim_period);
3606 if (err < 0) {
3607 brcmf_err("DTIM Interval Set Error, %d\n", err);
3608 goto exit;
3609 }
3610 }
3611 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3612 if (err < 0) {
3613 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3614 goto exit;
3615 }
3616
3617 memset(&join_params, 0, sizeof(join_params));
3618
3619 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3620
3621 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3622 &join_params, sizeof(join_params));
3623 if (err < 0) {
3624 brcmf_err("SET SSID error (%d)\n", err);
3625 goto exit;
3626 }
3627 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3628 set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3629
3630exit:
3631 if (err)
3632 brcmf_set_mpc(ndev, 1);
3633 return err;
3634}
3635
3636static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3637{
3638 struct brcmf_if *ifp = netdev_priv(ndev);
3639 s32 err = -EPERM;
3640
3641 brcmf_dbg(TRACE, "Enter\n");
3642
3643 if (ifp->vif->mode == WL_MODE_AP) {
3644
3645
3646 msleep(400);
3647 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3648 if (err < 0) {
3649 brcmf_err("setting AP mode failed %d\n", err);
3650 goto exit;
3651 }
3652 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3653 if (err < 0) {
3654 brcmf_err("BRCMF_C_UP error %d\n", err);
3655 goto exit;
3656 }
3657 brcmf_set_mpc(ndev, 1);
3658 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3659 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3660 }
3661exit:
3662 return err;
3663}
3664
3665static int
3666brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3667 u8 *mac)
3668{
3669 struct brcmf_scb_val_le scbval;
3670 struct brcmf_if *ifp = netdev_priv(ndev);
3671 s32 err;
3672
3673 if (!mac)
3674 return -EFAULT;
3675
3676 brcmf_dbg(TRACE, "Enter %pM\n", mac);
3677
3678 if (!check_vif_up(ifp->vif))
3679 return -EIO;
3680
3681 memcpy(&scbval.ea, mac, ETH_ALEN);
3682 scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3683 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3684 &scbval, sizeof(scbval));
3685 if (err)
3686 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3687
3688 brcmf_dbg(TRACE, "Exit\n");
3689 return err;
3690}
3691
3692static struct cfg80211_ops wl_cfg80211_ops = {
3693 .change_virtual_intf = brcmf_cfg80211_change_iface,
3694 .scan = brcmf_cfg80211_scan,
3695 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3696 .join_ibss = brcmf_cfg80211_join_ibss,
3697 .leave_ibss = brcmf_cfg80211_leave_ibss,
3698 .get_station = brcmf_cfg80211_get_station,
3699 .set_tx_power = brcmf_cfg80211_set_tx_power,
3700 .get_tx_power = brcmf_cfg80211_get_tx_power,
3701 .add_key = brcmf_cfg80211_add_key,
3702 .del_key = brcmf_cfg80211_del_key,
3703 .get_key = brcmf_cfg80211_get_key,
3704 .set_default_key = brcmf_cfg80211_config_default_key,
3705 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3706 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3707 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3708 .connect = brcmf_cfg80211_connect,
3709 .disconnect = brcmf_cfg80211_disconnect,
3710 .suspend = brcmf_cfg80211_suspend,
3711 .resume = brcmf_cfg80211_resume,
3712 .set_pmksa = brcmf_cfg80211_set_pmksa,
3713 .del_pmksa = brcmf_cfg80211_del_pmksa,
3714 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3715 .start_ap = brcmf_cfg80211_start_ap,
3716 .stop_ap = brcmf_cfg80211_stop_ap,
3717 .del_station = brcmf_cfg80211_del_station,
3718 .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3719 .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3720#ifdef CONFIG_NL80211_TESTMODE
3721 .testmode_cmd = brcmf_cfg80211_testmode
3722#endif
3723};
3724
3725static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3726{
3727 s32 err = 0;
3728
3729 switch (mode) {
3730 case WL_MODE_BSS:
3731 return NL80211_IFTYPE_STATION;
3732 case WL_MODE_IBSS:
3733 return NL80211_IFTYPE_ADHOC;
3734 default:
3735 return NL80211_IFTYPE_UNSPECIFIED;
3736 }
3737
3738 return err;
3739}
3740
3741static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3742{
3743
3744 wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3745 wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3746 wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3747 wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3748}
3749
3750static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3751{
3752 struct wiphy *wiphy;
3753 s32 err = 0;
3754
3755 wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3756 if (!wiphy) {
3757 brcmf_err("Could not allocate wiphy device\n");
3758 return ERR_PTR(-ENOMEM);
3759 }
3760 set_wiphy_dev(wiphy, phydev);
3761 wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3762 wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3763 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3764 BIT(NL80211_IFTYPE_ADHOC) |
3765 BIT(NL80211_IFTYPE_AP);
3766 wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3767 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;
3768
3769
3770
3771
3772
3773
3774 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3775 wiphy->cipher_suites = __wl_cipher_suites;
3776 wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3777 wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;
3778
3779
3780
3781 brcmf_wiphy_pno_params(wiphy);
3782 err = wiphy_register(wiphy);
3783 if (err < 0) {
3784 brcmf_err("Could not register wiphy device (%d)\n", err);
3785 wiphy_free(wiphy);
3786 return ERR_PTR(err);
3787 }
3788 return wiphy;
3789}
3790
3791static
3792struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3793 struct net_device *netdev,
3794 s32 mode, bool pm_block)
3795{
3796 struct brcmf_cfg80211_vif *vif;
3797
3798 if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3799 return ERR_PTR(-ENOSPC);
3800
3801 vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3802 if (!vif)
3803 return ERR_PTR(-ENOMEM);
3804
3805 vif->wdev.wiphy = cfg->wiphy;
3806 vif->wdev.netdev = netdev;
3807 vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3808
3809 if (netdev) {
3810 vif->ifp = netdev_priv(netdev);
3811 netdev->ieee80211_ptr = &vif->wdev;
3812 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3813 }
3814
3815 vif->mode = mode;
3816 vif->pm_block = pm_block;
3817 vif->roam_off = -1;
3818
3819 brcmf_init_prof(&vif->profile);
3820
3821 list_add_tail(&vif->list, &cfg->vif_list);
3822 cfg->vif_cnt++;
3823 return vif;
3824}
3825
3826static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3827{
3828 struct brcmf_cfg80211_info *cfg;
3829 struct wiphy *wiphy;
3830
3831 wiphy = vif->wdev.wiphy;
3832 cfg = wiphy_priv(wiphy);
3833 list_del(&vif->list);
3834 cfg->vif_cnt--;
3835
3836 kfree(vif);
3837 if (!cfg->vif_cnt) {
3838 wiphy_unregister(wiphy);
3839 wiphy_free(wiphy);
3840 }
3841}
3842
3843static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3844{
3845 u32 event = e->event_code;
3846 u32 status = e->status;
3847
3848 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3849 brcmf_dbg(CONN, "Processing set ssid\n");
3850 return true;
3851 }
3852
3853 return false;
3854}
3855
3856static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3857{
3858 u32 event = e->event_code;
3859 u16 flags = e->flags;
3860
3861 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3862 brcmf_dbg(CONN, "Processing link down\n");
3863 return true;
3864 }
3865 return false;
3866}
3867
3868static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3869 const struct brcmf_event_msg *e)
3870{
3871 u32 event = e->event_code;
3872 u32 status = e->status;
3873
3874 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3875 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
3876 e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3877 return true;
3878 }
3879
3880 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3881 brcmf_dbg(CONN, "Processing connecting & no network found\n");
3882 return true;
3883 }
3884
3885 return false;
3886}
3887
3888static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3889{
3890 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3891
3892 kfree(conn_info->req_ie);
3893 conn_info->req_ie = NULL;
3894 conn_info->req_ie_len = 0;
3895 kfree(conn_info->resp_ie);
3896 conn_info->resp_ie = NULL;
3897 conn_info->resp_ie_len = 0;
3898}
3899
3900static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3901{
3902 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3903 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3904 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3905 u32 req_len;
3906 u32 resp_len;
3907 s32 err = 0;
3908
3909 brcmf_clear_assoc_ies(cfg);
3910
3911 err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3912 cfg->extra_buf, WL_ASSOC_INFO_MAX);
3913 if (err) {
3914 brcmf_err("could not get assoc info (%d)\n", err);
3915 return err;
3916 }
3917 assoc_info =
3918 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3919 req_len = le32_to_cpu(assoc_info->req_len);
3920 resp_len = le32_to_cpu(assoc_info->resp_len);
3921 if (req_len) {
3922 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3923 cfg->extra_buf,
3924 WL_ASSOC_INFO_MAX);
3925 if (err) {
3926 brcmf_err("could not get assoc req (%d)\n", err);
3927 return err;
3928 }
3929 conn_info->req_ie_len = req_len;
3930 conn_info->req_ie =
3931 kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3932 GFP_KERNEL);
3933 } else {
3934 conn_info->req_ie_len = 0;
3935 conn_info->req_ie = NULL;
3936 }
3937 if (resp_len) {
3938 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3939 cfg->extra_buf,
3940 WL_ASSOC_INFO_MAX);
3941 if (err) {
3942 brcmf_err("could not get assoc resp (%d)\n", err);
3943 return err;
3944 }
3945 conn_info->resp_ie_len = resp_len;
3946 conn_info->resp_ie =
3947 kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3948 GFP_KERNEL);
3949 } else {
3950 conn_info->resp_ie_len = 0;
3951 conn_info->resp_ie = NULL;
3952 }
3953 brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
3954 conn_info->req_ie_len, conn_info->resp_ie_len);
3955
3956 return err;
3957}
3958
3959static s32
3960brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3961 struct net_device *ndev,
3962 const struct brcmf_event_msg *e)
3963{
3964 struct brcmf_if *ifp = netdev_priv(ndev);
3965 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3966 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3967 struct wiphy *wiphy = cfg_to_wiphy(cfg);
3968 struct ieee80211_channel *notify_channel = NULL;
3969 struct ieee80211_supported_band *band;
3970 struct brcmf_bss_info_le *bi;
3971 u32 freq;
3972 s32 err = 0;
3973 u32 target_channel;
3974 u8 *buf;
3975
3976 brcmf_dbg(TRACE, "Enter\n");
3977
3978 brcmf_get_assoc_ies(cfg);
3979 memcpy(profile->bssid, e->addr, ETH_ALEN);
3980 brcmf_update_bss_info(cfg);
3981
3982 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3983 if (buf == NULL) {
3984 err = -ENOMEM;
3985 goto done;
3986 }
3987
3988
3989 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3990 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3991 buf, WL_BSS_INFO_MAX);
3992
3993 if (err)
3994 goto done;
3995
3996 bi = (struct brcmf_bss_info_le *)(buf + 4);
3997 target_channel = bi->ctl_ch ? bi->ctl_ch :
3998 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
3999
4000 if (target_channel <= CH_MAX_2G_CHANNEL)
4001 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4002 else
4003 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4004
4005 freq = ieee80211_channel_to_frequency(target_channel, band->band);
4006 notify_channel = ieee80211_get_channel(wiphy, freq);
4007
4008done:
4009 kfree(buf);
4010 cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4011 conn_info->req_ie, conn_info->req_ie_len,
4012 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4013 brcmf_dbg(CONN, "Report roaming result\n");
4014
4015 set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4016 brcmf_dbg(TRACE, "Exit\n");
4017 return err;
4018}
4019
4020static s32
4021brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4022 struct net_device *ndev, const struct brcmf_event_msg *e,
4023 bool completed)
4024{
4025 struct brcmf_if *ifp = netdev_priv(ndev);
4026 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4027 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4028 s32 err = 0;
4029
4030 brcmf_dbg(TRACE, "Enter\n");
4031
4032 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4033 &ifp->vif->sme_state)) {
4034 if (completed) {
4035 brcmf_get_assoc_ies(cfg);
4036 memcpy(profile->bssid, e->addr, ETH_ALEN);
4037 brcmf_update_bss_info(cfg);
4038 }
4039 cfg80211_connect_result(ndev,
4040 (u8 *)profile->bssid,
4041 conn_info->req_ie,
4042 conn_info->req_ie_len,
4043 conn_info->resp_ie,
4044 conn_info->resp_ie_len,
4045 completed ? WLAN_STATUS_SUCCESS :
4046 WLAN_STATUS_AUTH_TIMEOUT,
4047 GFP_KERNEL);
4048 if (completed)
4049 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4050 &ifp->vif->sme_state);
4051 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4052 completed ? "succeeded" : "failed");
4053 }
4054 brcmf_dbg(TRACE, "Exit\n");
4055 return err;
4056}
4057
4058static s32
4059brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4060 struct net_device *ndev,
4061 const struct brcmf_event_msg *e, void *data)
4062{
4063 s32 err = 0;
4064 u32 event = e->event_code;
4065 u32 reason = e->reason;
4066 u32 len = e->datalen;
4067 static int generation;
4068
4069 struct station_info sinfo;
4070
4071 brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4072 memset(&sinfo, 0, sizeof(sinfo));
4073
4074 sinfo.filled = 0;
4075 if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4076 reason == BRCMF_E_STATUS_SUCCESS) {
4077 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4078 if (!data) {
4079 brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4080 return -EINVAL;
4081 }
4082 sinfo.assoc_req_ies = data;
4083 sinfo.assoc_req_ies_len = len;
4084 generation++;
4085 sinfo.generation = generation;
4086 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4087 } else if ((event == BRCMF_E_DISASSOC_IND) ||
4088 (event == BRCMF_E_DEAUTH_IND) ||
4089 (event == BRCMF_E_DEAUTH)) {
4090 generation++;
4091 sinfo.generation = generation;
4092 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4093 }
4094 return err;
4095}
4096
4097static s32
4098brcmf_notify_connect_status(struct brcmf_if *ifp,
4099 const struct brcmf_event_msg *e, void *data)
4100{
4101 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4102 struct net_device *ndev = ifp->ndev;
4103 struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4104 s32 err = 0;
4105
4106 if (ifp->vif->mode == WL_MODE_AP) {
4107 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4108 } else if (brcmf_is_linkup(e)) {
4109 brcmf_dbg(CONN, "Linkup\n");
4110 if (brcmf_is_ibssmode(ifp->vif)) {
4111 memcpy(profile->bssid, e->addr, ETH_ALEN);
4112 wl_inform_ibss(cfg, ndev, e->addr);
4113 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4114 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4115 &ifp->vif->sme_state);
4116 set_bit(BRCMF_VIF_STATUS_CONNECTED,
4117 &ifp->vif->sme_state);
4118 } else
4119 brcmf_bss_connect_done(cfg, ndev, e, true);
4120 } else if (brcmf_is_linkdown(e)) {
4121 brcmf_dbg(CONN, "Linkdown\n");
4122 if (!brcmf_is_ibssmode(ifp->vif)) {
4123 brcmf_bss_connect_done(cfg, ndev, e, false);
4124 if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4125 &ifp->vif->sme_state))
4126 cfg80211_disconnected(ndev, 0, NULL, 0,
4127 GFP_KERNEL);
4128 }
4129 brcmf_link_down(ifp->vif);
4130 brcmf_init_prof(ndev_to_prof(ndev));
4131 } else if (brcmf_is_nonetwork(cfg, e)) {
4132 if (brcmf_is_ibssmode(ifp->vif))
4133 clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4134 &ifp->vif->sme_state);
4135 else
4136 brcmf_bss_connect_done(cfg, ndev, e, false);
4137 }
4138
4139 return err;
4140}
4141
4142static s32
4143brcmf_notify_roaming_status(struct brcmf_if *ifp,
4144 const struct brcmf_event_msg *e, void *data)
4145{
4146 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4147 s32 err = 0;
4148 u32 event = e->event_code;
4149 u32 status = e->status;
4150
4151 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4152 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4153 brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4154 else
4155 brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4156 }
4157
4158 return err;
4159}
4160
4161static s32
4162brcmf_notify_mic_status(struct brcmf_if *ifp,
4163 const struct brcmf_event_msg *e, void *data)
4164{
4165 u16 flags = e->flags;
4166 enum nl80211_key_type key_type;
4167
4168 if (flags & BRCMF_EVENT_MSG_GROUP)
4169 key_type = NL80211_KEYTYPE_GROUP;
4170 else
4171 key_type = NL80211_KEYTYPE_PAIRWISE;
4172
4173 cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4174 NULL, GFP_KERNEL);
4175
4176 return 0;
4177}
4178
4179static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4180{
4181 conf->frag_threshold = (u32)-1;
4182 conf->rts_threshold = (u32)-1;
4183 conf->retry_short = (u32)-1;
4184 conf->retry_long = (u32)-1;
4185 conf->tx_power = -1;
4186}
4187
4188static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4189{
4190 brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4191 brcmf_notify_connect_status);
4192 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4193 brcmf_notify_connect_status);
4194 brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4195 brcmf_notify_connect_status);
4196 brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4197 brcmf_notify_connect_status);
4198 brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4199 brcmf_notify_connect_status);
4200 brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4201 brcmf_notify_connect_status);
4202 brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4203 brcmf_notify_roaming_status);
4204 brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4205 brcmf_notify_mic_status);
4206 brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4207 brcmf_notify_connect_status);
4208 brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4209 brcmf_notify_sched_scan_results);
4210}
4211
4212static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4213{
4214 kfree(cfg->conf);
4215 cfg->conf = NULL;
4216 kfree(cfg->escan_ioctl_buf);
4217 cfg->escan_ioctl_buf = NULL;
4218 kfree(cfg->extra_buf);
4219 cfg->extra_buf = NULL;
4220 kfree(cfg->pmk_list);
4221 cfg->pmk_list = NULL;
4222}
4223
4224static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4225{
4226 cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4227 if (!cfg->conf)
4228 goto init_priv_mem_out;
4229 cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4230 if (!cfg->escan_ioctl_buf)
4231 goto init_priv_mem_out;
4232 cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4233 if (!cfg->extra_buf)
4234 goto init_priv_mem_out;
4235 cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4236 if (!cfg->pmk_list)
4237 goto init_priv_mem_out;
4238
4239 return 0;
4240
4241init_priv_mem_out:
4242 brcmf_deinit_priv_mem(cfg);
4243
4244 return -ENOMEM;
4245}
4246
4247static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4248{
4249 s32 err = 0;
4250
4251 cfg->scan_request = NULL;
4252 cfg->pwr_save = true;
4253 cfg->roam_on = true;
4254
4255 cfg->active_scan = true;
4256
4257 cfg->dongle_up = false;
4258 err = brcmf_init_priv_mem(cfg);
4259 if (err)
4260 return err;
4261 brcmf_register_event_handlers(cfg);
4262 mutex_init(&cfg->usr_sync);
4263 brcmf_init_escan(cfg);
4264 brcmf_init_conf(cfg->conf);
4265
4266 return err;
4267}
4268
4269static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4270{
4271 cfg->dongle_up = false;
4272 brcmf_abort_scanning(cfg);
4273 brcmf_deinit_priv_mem(cfg);
4274}
4275
4276struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4277 struct device *busdev)
4278{
4279 struct net_device *ndev = drvr->iflist[0]->ndev;
4280 struct brcmf_cfg80211_info *cfg;
4281 struct wiphy *wiphy;
4282 struct brcmf_cfg80211_vif *vif;
4283 struct brcmf_if *ifp;
4284 s32 err = 0;
4285
4286 if (!ndev) {
4287 brcmf_err("ndev is invalid\n");
4288 return NULL;
4289 }
4290
4291 ifp = netdev_priv(ndev);
4292 wiphy = brcmf_setup_wiphy(busdev);
4293 if (IS_ERR(wiphy))
4294 return NULL;
4295
4296 cfg = wiphy_priv(wiphy);
4297 cfg->wiphy = wiphy;
4298 cfg->pub = drvr;
4299 INIT_LIST_HEAD(&cfg->vif_list);
4300
4301 vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4302 if (IS_ERR(vif)) {
4303 wiphy_free(wiphy);
4304 return NULL;
4305 }
4306
4307 err = wl_init_priv(cfg);
4308 if (err) {
4309 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4310 goto cfg80211_attach_out;
4311 }
4312
4313 ifp->vif = vif;
4314 return cfg;
4315
4316cfg80211_attach_out:
4317 brcmf_free_vif(vif);
4318 return NULL;
4319}
4320
4321void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4322{
4323 struct brcmf_cfg80211_vif *vif;
4324 struct brcmf_cfg80211_vif *tmp;
4325
4326 wl_deinit_priv(cfg);
4327 list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4328 brcmf_free_vif(vif);
4329 }
4330}
4331
4332static s32
4333brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4334{
4335 struct brcmf_if *ifp = netdev_priv(ndev);
4336 s32 err = 0;
4337 __le32 roamtrigger[2];
4338 __le32 roam_delta[2];
4339
4340
4341
4342
4343
4344 if (roamvar) {
4345 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4346 if (err) {
4347 brcmf_err("bcn_timeout error (%d)\n", err);
4348 goto dongle_rom_out;
4349 }
4350 }
4351
4352
4353
4354
4355
4356 brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4357 err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4358 if (err) {
4359 brcmf_err("roam_off error (%d)\n", err);
4360 goto dongle_rom_out;
4361 }
4362
4363 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4364 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4365 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4366 (void *)roamtrigger, sizeof(roamtrigger));
4367 if (err) {
4368 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4369 goto dongle_rom_out;
4370 }
4371
4372 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4373 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4374 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4375 (void *)roam_delta, sizeof(roam_delta));
4376 if (err) {
4377 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4378 goto dongle_rom_out;
4379 }
4380
4381dongle_rom_out:
4382 return err;
4383}
4384
4385static s32
4386brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4387 s32 scan_unassoc_time, s32 scan_passive_time)
4388{
4389 struct brcmf_if *ifp = netdev_priv(ndev);
4390 s32 err = 0;
4391
4392 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4393 scan_assoc_time);
4394 if (err) {
4395 if (err == -EOPNOTSUPP)
4396 brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4397 else
4398 brcmf_err("Scan assoc time error (%d)\n", err);
4399 goto dongle_scantime_out;
4400 }
4401 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4402 scan_unassoc_time);
4403 if (err) {
4404 if (err == -EOPNOTSUPP)
4405 brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4406 else
4407 brcmf_err("Scan unassoc time error (%d)\n", err);
4408 goto dongle_scantime_out;
4409 }
4410
4411 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4412 scan_passive_time);
4413 if (err) {
4414 if (err == -EOPNOTSUPP)
4415 brcmf_dbg(INFO, "Scan passive time is not supported\n");
4416 else
4417 brcmf_err("Scan passive time error (%d)\n", err);
4418 goto dongle_scantime_out;
4419 }
4420
4421dongle_scantime_out:
4422 return err;
4423}
4424
4425static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4426{
4427 struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4428 struct wiphy *wiphy;
4429 s32 phy_list;
4430 s8 phy;
4431 s32 err = 0;
4432
4433 err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4434 &phy_list, sizeof(phy_list));
4435 if (err) {
4436 brcmf_err("error (%d)\n", err);
4437 return err;
4438 }
4439
4440 phy = ((char *)&phy_list)[0];
4441 brcmf_dbg(INFO, "%c phy\n", phy);
4442 if (phy == 'n' || phy == 'a') {
4443 wiphy = cfg_to_wiphy(cfg);
4444 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4445 }
4446
4447 return err;
4448}
4449
4450static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4451{
4452 return wl_update_wiphybands(cfg);
4453}
4454
4455static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4456{
4457 struct net_device *ndev;
4458 struct wireless_dev *wdev;
4459 s32 power_mode;
4460 s32 err = 0;
4461
4462 if (cfg->dongle_up)
4463 return err;
4464
4465 ndev = cfg_to_ndev(cfg);
4466 wdev = ndev->ieee80211_ptr;
4467
4468 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4469 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4470
4471 power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4472 err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4473 power_mode);
4474 if (err)
4475 goto default_conf_out;
4476 brcmf_dbg(INFO, "power save set to %s\n",
4477 (power_mode ? "enabled" : "disabled"));
4478
4479 err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4480 WL_BEACON_TIMEOUT);
4481 if (err)
4482 goto default_conf_out;
4483 err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4484 NULL, NULL);
4485 if (err && err != -EINPROGRESS)
4486 goto default_conf_out;
4487 err = brcmf_dongle_probecap(cfg);
4488 if (err)
4489 goto default_conf_out;
4490
4491
4492
4493default_conf_out:
4494
4495 cfg->dongle_up = true;
4496
4497 return err;
4498
4499}
4500
4501static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4502{
4503 set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4504 if (ifp->idx)
4505 return 0;
4506
4507 return brcmf_config_dongle(ifp->drvr->config);
4508}
4509
4510static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4511{
4512 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4513
4514
4515
4516
4517
4518 if (check_vif_up(ifp->vif)) {
4519 brcmf_link_down(ifp->vif);
4520
4521
4522
4523
4524
4525 brcmf_delay(500);
4526 }
4527
4528 brcmf_abort_scanning(cfg);
4529 clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4530
4531 return 0;
4532}
4533
4534s32 brcmf_cfg80211_up(struct net_device *ndev)
4535{
4536 struct brcmf_if *ifp = netdev_priv(ndev);
4537 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4538 s32 err = 0;
4539
4540 mutex_lock(&cfg->usr_sync);
4541 err = __brcmf_cfg80211_up(ifp);
4542 mutex_unlock(&cfg->usr_sync);
4543
4544 return err;
4545}
4546
4547s32 brcmf_cfg80211_down(struct net_device *ndev)
4548{
4549 struct brcmf_if *ifp = netdev_priv(ndev);
4550 struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4551 s32 err = 0;
4552
4553 mutex_lock(&cfg->usr_sync);
4554 err = __brcmf_cfg80211_down(ifp);
4555 mutex_unlock(&cfg->usr_sync);
4556
4557 return err;
4558}
4559
4560