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