brcmfmac: add callback for nl80211 testmode command
[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 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/kernel.h>
22 #include <linux/if_arp.h>
23 #include <linux/sched.h>
24 #include <linux/kthread.h>
25 #include <linux/netdevice.h>
26 #include <linux/bitops.h>
27 #include <linux/etherdevice.h>
28 #include <linux/ieee80211.h>
29 #include <linux/uaccess.h>
30 #include <net/cfg80211.h>
31 #include <net/netlink.h>
32
33 #include <brcmu_utils.h>
34 #include <defs.h>
35 #include <brcmu_wifi.h>
36 #include "dhd.h"
37 #include "wl_cfg80211.h"
38
39 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
40 (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
41
42 static const u8 ether_bcast[ETH_ALEN] = {255, 255, 255, 255, 255, 255};
43
44 static u32 brcmf_dbg_level = WL_DBG_ERR;
45
46 static void brcmf_set_drvdata(struct brcmf_cfg80211_dev *dev, void *data)
47 {
48 dev->driver_data = data;
49 }
50
51 static void *brcmf_get_drvdata(struct brcmf_cfg80211_dev *dev)
52 {
53 void *data = NULL;
54
55 if (dev)
56 data = dev->driver_data;
57 return data;
58 }
59
60 static
61 struct brcmf_cfg80211_priv *brcmf_priv_get(struct brcmf_cfg80211_dev *cfg_dev)
62 {
63 struct brcmf_cfg80211_iface *ci = brcmf_get_drvdata(cfg_dev);
64 return ci->cfg_priv;
65 }
66
67 static bool check_sys_up(struct wiphy *wiphy)
68 {
69 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
70 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
71 WL_INFO("device is not ready : status (%d)\n",
72 (int)cfg_priv->status);
73 return false;
74 }
75 return true;
76 }
77
78 #define CHAN2G(_channel, _freq, _flags) { \
79 .band = IEEE80211_BAND_2GHZ, \
80 .center_freq = (_freq), \
81 .hw_value = (_channel), \
82 .flags = (_flags), \
83 .max_antenna_gain = 0, \
84 .max_power = 30, \
85 }
86
87 #define CHAN5G(_channel, _flags) { \
88 .band = IEEE80211_BAND_5GHZ, \
89 .center_freq = 5000 + (5 * (_channel)), \
90 .hw_value = (_channel), \
91 .flags = (_flags), \
92 .max_antenna_gain = 0, \
93 .max_power = 30, \
94 }
95
96 #define RATE_TO_BASE100KBPS(rate) (((rate) * 10) / 2)
97 #define RATETAB_ENT(_rateid, _flags) \
98 { \
99 .bitrate = RATE_TO_BASE100KBPS(_rateid), \
100 .hw_value = (_rateid), \
101 .flags = (_flags), \
102 }
103
104 static struct ieee80211_rate __wl_rates[] = {
105 RATETAB_ENT(BRCM_RATE_1M, 0),
106 RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
107 RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
108 RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
109 RATETAB_ENT(BRCM_RATE_6M, 0),
110 RATETAB_ENT(BRCM_RATE_9M, 0),
111 RATETAB_ENT(BRCM_RATE_12M, 0),
112 RATETAB_ENT(BRCM_RATE_18M, 0),
113 RATETAB_ENT(BRCM_RATE_24M, 0),
114 RATETAB_ENT(BRCM_RATE_36M, 0),
115 RATETAB_ENT(BRCM_RATE_48M, 0),
116 RATETAB_ENT(BRCM_RATE_54M, 0),
117 };
118
119 #define wl_a_rates (__wl_rates + 4)
120 #define wl_a_rates_size 8
121 #define wl_g_rates (__wl_rates + 0)
122 #define wl_g_rates_size 12
123
124 static struct ieee80211_channel __wl_2ghz_channels[] = {
125 CHAN2G(1, 2412, 0),
126 CHAN2G(2, 2417, 0),
127 CHAN2G(3, 2422, 0),
128 CHAN2G(4, 2427, 0),
129 CHAN2G(5, 2432, 0),
130 CHAN2G(6, 2437, 0),
131 CHAN2G(7, 2442, 0),
132 CHAN2G(8, 2447, 0),
133 CHAN2G(9, 2452, 0),
134 CHAN2G(10, 2457, 0),
135 CHAN2G(11, 2462, 0),
136 CHAN2G(12, 2467, 0),
137 CHAN2G(13, 2472, 0),
138 CHAN2G(14, 2484, 0),
139 };
140
141 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
142 CHAN5G(34, 0), CHAN5G(36, 0),
143 CHAN5G(38, 0), CHAN5G(40, 0),
144 CHAN5G(42, 0), CHAN5G(44, 0),
145 CHAN5G(46, 0), CHAN5G(48, 0),
146 CHAN5G(52, 0), CHAN5G(56, 0),
147 CHAN5G(60, 0), CHAN5G(64, 0),
148 CHAN5G(100, 0), CHAN5G(104, 0),
149 CHAN5G(108, 0), CHAN5G(112, 0),
150 CHAN5G(116, 0), CHAN5G(120, 0),
151 CHAN5G(124, 0), CHAN5G(128, 0),
152 CHAN5G(132, 0), CHAN5G(136, 0),
153 CHAN5G(140, 0), CHAN5G(149, 0),
154 CHAN5G(153, 0), CHAN5G(157, 0),
155 CHAN5G(161, 0), CHAN5G(165, 0),
156 CHAN5G(184, 0), CHAN5G(188, 0),
157 CHAN5G(192, 0), CHAN5G(196, 0),
158 CHAN5G(200, 0), CHAN5G(204, 0),
159 CHAN5G(208, 0), CHAN5G(212, 0),
160 CHAN5G(216, 0),
161 };
162
163 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
164 CHAN5G(32, 0), CHAN5G(34, 0),
165 CHAN5G(36, 0), CHAN5G(38, 0),
166 CHAN5G(40, 0), CHAN5G(42, 0),
167 CHAN5G(44, 0), CHAN5G(46, 0),
168 CHAN5G(48, 0), CHAN5G(50, 0),
169 CHAN5G(52, 0), CHAN5G(54, 0),
170 CHAN5G(56, 0), CHAN5G(58, 0),
171 CHAN5G(60, 0), CHAN5G(62, 0),
172 CHAN5G(64, 0), CHAN5G(66, 0),
173 CHAN5G(68, 0), CHAN5G(70, 0),
174 CHAN5G(72, 0), CHAN5G(74, 0),
175 CHAN5G(76, 0), CHAN5G(78, 0),
176 CHAN5G(80, 0), CHAN5G(82, 0),
177 CHAN5G(84, 0), CHAN5G(86, 0),
178 CHAN5G(88, 0), CHAN5G(90, 0),
179 CHAN5G(92, 0), CHAN5G(94, 0),
180 CHAN5G(96, 0), CHAN5G(98, 0),
181 CHAN5G(100, 0), CHAN5G(102, 0),
182 CHAN5G(104, 0), CHAN5G(106, 0),
183 CHAN5G(108, 0), CHAN5G(110, 0),
184 CHAN5G(112, 0), CHAN5G(114, 0),
185 CHAN5G(116, 0), CHAN5G(118, 0),
186 CHAN5G(120, 0), CHAN5G(122, 0),
187 CHAN5G(124, 0), CHAN5G(126, 0),
188 CHAN5G(128, 0), CHAN5G(130, 0),
189 CHAN5G(132, 0), CHAN5G(134, 0),
190 CHAN5G(136, 0), CHAN5G(138, 0),
191 CHAN5G(140, 0), CHAN5G(142, 0),
192 CHAN5G(144, 0), CHAN5G(145, 0),
193 CHAN5G(146, 0), CHAN5G(147, 0),
194 CHAN5G(148, 0), CHAN5G(149, 0),
195 CHAN5G(150, 0), CHAN5G(151, 0),
196 CHAN5G(152, 0), CHAN5G(153, 0),
197 CHAN5G(154, 0), CHAN5G(155, 0),
198 CHAN5G(156, 0), CHAN5G(157, 0),
199 CHAN5G(158, 0), CHAN5G(159, 0),
200 CHAN5G(160, 0), CHAN5G(161, 0),
201 CHAN5G(162, 0), CHAN5G(163, 0),
202 CHAN5G(164, 0), CHAN5G(165, 0),
203 CHAN5G(166, 0), CHAN5G(168, 0),
204 CHAN5G(170, 0), CHAN5G(172, 0),
205 CHAN5G(174, 0), CHAN5G(176, 0),
206 CHAN5G(178, 0), CHAN5G(180, 0),
207 CHAN5G(182, 0), CHAN5G(184, 0),
208 CHAN5G(186, 0), CHAN5G(188, 0),
209 CHAN5G(190, 0), CHAN5G(192, 0),
210 CHAN5G(194, 0), CHAN5G(196, 0),
211 CHAN5G(198, 0), CHAN5G(200, 0),
212 CHAN5G(202, 0), CHAN5G(204, 0),
213 CHAN5G(206, 0), CHAN5G(208, 0),
214 CHAN5G(210, 0), CHAN5G(212, 0),
215 CHAN5G(214, 0), CHAN5G(216, 0),
216 CHAN5G(218, 0), CHAN5G(220, 0),
217 CHAN5G(222, 0), CHAN5G(224, 0),
218 CHAN5G(226, 0), CHAN5G(228, 0),
219 };
220
221 static struct ieee80211_supported_band __wl_band_2ghz = {
222 .band = IEEE80211_BAND_2GHZ,
223 .channels = __wl_2ghz_channels,
224 .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
225 .bitrates = wl_g_rates,
226 .n_bitrates = wl_g_rates_size,
227 };
228
229 static struct ieee80211_supported_band __wl_band_5ghz_a = {
230 .band = IEEE80211_BAND_5GHZ,
231 .channels = __wl_5ghz_a_channels,
232 .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
233 .bitrates = wl_a_rates,
234 .n_bitrates = wl_a_rates_size,
235 };
236
237 static struct ieee80211_supported_band __wl_band_5ghz_n = {
238 .band = IEEE80211_BAND_5GHZ,
239 .channels = __wl_5ghz_n_channels,
240 .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
241 .bitrates = wl_a_rates,
242 .n_bitrates = wl_a_rates_size,
243 };
244
245 static const u32 __wl_cipher_suites[] = {
246 WLAN_CIPHER_SUITE_WEP40,
247 WLAN_CIPHER_SUITE_WEP104,
248 WLAN_CIPHER_SUITE_TKIP,
249 WLAN_CIPHER_SUITE_CCMP,
250 WLAN_CIPHER_SUITE_AES_CMAC,
251 };
252
253 /* tag_ID/length/value_buffer tuple */
254 struct brcmf_tlv {
255 u8 id;
256 u8 len;
257 u8 data[1];
258 };
259
260 /* Quarter dBm units to mW
261 * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
262 * Table is offset so the last entry is largest mW value that fits in
263 * a u16.
264 */
265
266 #define QDBM_OFFSET 153 /* Offset for first entry */
267 #define QDBM_TABLE_LEN 40 /* Table size */
268
269 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
270 * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
271 */
272 #define QDBM_TABLE_LOW_BOUND 6493 /* Low bound */
273
274 /* Largest mW value that will round down to the last table entry,
275 * QDBM_OFFSET + QDBM_TABLE_LEN-1.
276 * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
277 * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
278 */
279 #define QDBM_TABLE_HIGH_BOUND 64938 /* High bound */
280
281 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
282 /* qdBm: +0 +1 +2 +3 +4 +5 +6 +7 */
283 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
284 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
285 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
286 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
287 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
288 };
289
290 static u16 brcmf_qdbm_to_mw(u8 qdbm)
291 {
292 uint factor = 1;
293 int idx = qdbm - QDBM_OFFSET;
294
295 if (idx >= QDBM_TABLE_LEN)
296 /* clamp to max u16 mW value */
297 return 0xFFFF;
298
299 /* scale the qdBm index up to the range of the table 0-40
300 * where an offset of 40 qdBm equals a factor of 10 mW.
301 */
302 while (idx < 0) {
303 idx += 40;
304 factor *= 10;
305 }
306
307 /* return the mW value scaled down to the correct factor of 10,
308 * adding in factor/2 to get proper rounding.
309 */
310 return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
311 }
312
313 static u8 brcmf_mw_to_qdbm(u16 mw)
314 {
315 u8 qdbm;
316 int offset;
317 uint mw_uint = mw;
318 uint boundary;
319
320 /* handle boundary case */
321 if (mw_uint <= 1)
322 return 0;
323
324 offset = QDBM_OFFSET;
325
326 /* move mw into the range of the table */
327 while (mw_uint < QDBM_TABLE_LOW_BOUND) {
328 mw_uint *= 10;
329 offset -= 40;
330 }
331
332 for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
333 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
334 nqdBm_to_mW_map[qdbm]) / 2;
335 if (mw_uint < boundary)
336 break;
337 }
338
339 qdbm += (u8) offset;
340
341 return qdbm;
342 }
343
344 /* function for reading/writing a single u32 from/to the dongle */
345 static int
346 brcmf_exec_dcmd_u32(struct net_device *ndev, u32 cmd, u32 *par)
347 {
348 int err;
349 __le32 par_le = cpu_to_le32(*par);
350
351 err = brcmf_exec_dcmd(ndev, cmd, &par_le, sizeof(__le32));
352 *par = le32_to_cpu(par_le);
353
354 return err;
355 }
356
357 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
358 struct brcmf_wsec_key_le *key_le)
359 {
360 key_le->index = cpu_to_le32(key->index);
361 key_le->len = cpu_to_le32(key->len);
362 key_le->algo = cpu_to_le32(key->algo);
363 key_le->flags = cpu_to_le32(key->flags);
364 key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
365 key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
366 key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
367 memcpy(key_le->data, key->data, sizeof(key->data));
368 memcpy(key_le->ea, key->ea, sizeof(key->ea));
369 }
370
371 static int send_key_to_dongle(struct net_device *ndev,
372 struct brcmf_wsec_key *key)
373 {
374 int err;
375 struct brcmf_wsec_key_le key_le;
376
377 convert_key_from_CPU(key, &key_le);
378 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le, sizeof(key_le));
379 if (err)
380 WL_ERR("WLC_SET_KEY error (%d)\n", err);
381 return err;
382 }
383
384 static s32
385 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
386 enum nl80211_iftype type, u32 *flags,
387 struct vif_params *params)
388 {
389 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
390 struct wireless_dev *wdev;
391 s32 infra = 0;
392 s32 err = 0;
393
394 WL_TRACE("Enter\n");
395 if (!check_sys_up(wiphy))
396 return -EIO;
397
398 switch (type) {
399 case NL80211_IFTYPE_MONITOR:
400 case NL80211_IFTYPE_WDS:
401 WL_ERR("type (%d) : currently we do not support this type\n",
402 type);
403 return -EOPNOTSUPP;
404 case NL80211_IFTYPE_ADHOC:
405 cfg_priv->conf->mode = WL_MODE_IBSS;
406 infra = 0;
407 break;
408 case NL80211_IFTYPE_STATION:
409 cfg_priv->conf->mode = WL_MODE_BSS;
410 infra = 1;
411 break;
412 default:
413 err = -EINVAL;
414 goto done;
415 }
416
417 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
418 if (err) {
419 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
420 err = -EAGAIN;
421 } else {
422 wdev = ndev->ieee80211_ptr;
423 wdev->iftype = type;
424 }
425
426 WL_INFO("IF Type = %s\n",
427 (cfg_priv->conf->mode == WL_MODE_IBSS) ? "Adhoc" : "Infra");
428
429 done:
430 WL_TRACE("Exit\n");
431
432 return err;
433 }
434
435 static s32 brcmf_dev_intvar_set(struct net_device *ndev, s8 *name, s32 val)
436 {
437 s8 buf[BRCMF_DCMD_SMLEN];
438 u32 len;
439 s32 err = 0;
440 __le32 val_le;
441
442 val_le = cpu_to_le32(val);
443 len = brcmf_c_mkiovar(name, (char *)(&val_le), sizeof(val_le), buf,
444 sizeof(buf));
445 BUG_ON(!len);
446
447 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, buf, len);
448 if (err)
449 WL_ERR("error (%d)\n", err);
450
451 return err;
452 }
453
454 static s32
455 brcmf_dev_intvar_get(struct net_device *ndev, s8 *name, s32 *retval)
456 {
457 union {
458 s8 buf[BRCMF_DCMD_SMLEN];
459 __le32 val;
460 } var;
461 u32 len;
462 u32 data_null;
463 s32 err = 0;
464
465 len =
466 brcmf_c_mkiovar(name, (char *)(&data_null), 0, (char *)(&var),
467 sizeof(var.buf));
468 BUG_ON(!len);
469 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, &var, len);
470 if (err)
471 WL_ERR("error (%d)\n", err);
472
473 *retval = le32_to_cpu(var.val);
474
475 return err;
476 }
477
478 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
479 {
480 s32 err = 0;
481 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
482
483 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
484 err = brcmf_dev_intvar_set(ndev, "mpc", mpc);
485 if (err) {
486 WL_ERR("fail to set mpc\n");
487 return;
488 }
489 WL_INFO("MPC : %d\n", mpc);
490 }
491 }
492
493 static void wl_iscan_prep(struct brcmf_scan_params_le *params_le,
494 struct brcmf_ssid *ssid)
495 {
496 memcpy(params_le->bssid, ether_bcast, ETH_ALEN);
497 params_le->bss_type = DOT11_BSSTYPE_ANY;
498 params_le->scan_type = 0;
499 params_le->channel_num = 0;
500 params_le->nprobes = cpu_to_le32(-1);
501 params_le->active_time = cpu_to_le32(-1);
502 params_le->passive_time = cpu_to_le32(-1);
503 params_le->home_time = cpu_to_le32(-1);
504 if (ssid && ssid->SSID_len)
505 memcpy(&params_le->ssid_le, ssid, sizeof(struct brcmf_ssid));
506 }
507
508 static s32
509 brcmf_dev_iovar_setbuf(struct net_device *ndev, s8 * iovar, void *param,
510 s32 paramlen, void *bufptr, s32 buflen)
511 {
512 s32 iolen;
513
514 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
515 BUG_ON(!iolen);
516
517 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, bufptr, iolen);
518 }
519
520 static s32
521 brcmf_dev_iovar_getbuf(struct net_device *ndev, s8 * iovar, void *param,
522 s32 paramlen, void *bufptr, s32 buflen)
523 {
524 s32 iolen;
525
526 iolen = brcmf_c_mkiovar(iovar, param, paramlen, bufptr, buflen);
527 BUG_ON(!iolen);
528
529 return brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, bufptr, buflen);
530 }
531
532 static s32
533 brcmf_run_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan,
534 struct brcmf_ssid *ssid, u16 action)
535 {
536 s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
537 offsetof(struct brcmf_iscan_params_le, params_le);
538 struct brcmf_iscan_params_le *params;
539 s32 err = 0;
540
541 if (ssid && ssid->SSID_len)
542 params_size += sizeof(struct brcmf_ssid);
543 params = kzalloc(params_size, GFP_KERNEL);
544 if (!params)
545 return -ENOMEM;
546 BUG_ON(params_size >= BRCMF_DCMD_SMLEN);
547
548 wl_iscan_prep(&params->params_le, ssid);
549
550 params->version = cpu_to_le32(BRCMF_ISCAN_REQ_VERSION);
551 params->action = cpu_to_le16(action);
552 params->scan_duration = cpu_to_le16(0);
553
554 err = brcmf_dev_iovar_setbuf(iscan->ndev, "iscan", params, params_size,
555 iscan->dcmd_buf, BRCMF_DCMD_SMLEN);
556 if (err) {
557 if (err == -EBUSY)
558 WL_INFO("system busy : iscan canceled\n");
559 else
560 WL_ERR("error (%d)\n", err);
561 }
562
563 kfree(params);
564 return err;
565 }
566
567 static s32 brcmf_do_iscan(struct brcmf_cfg80211_priv *cfg_priv)
568 {
569 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
570 struct net_device *ndev = cfg_to_ndev(cfg_priv);
571 struct brcmf_ssid ssid;
572 __le32 passive_scan;
573 s32 err = 0;
574
575 /* Broadcast scan by default */
576 memset(&ssid, 0, sizeof(ssid));
577
578 iscan->state = WL_ISCAN_STATE_SCANING;
579
580 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
581 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_SET_PASSIVE_SCAN,
582 &passive_scan, sizeof(passive_scan));
583 if (err) {
584 WL_ERR("error (%d)\n", err);
585 return err;
586 }
587 brcmf_set_mpc(ndev, 0);
588 cfg_priv->iscan_kickstart = true;
589 err = brcmf_run_iscan(iscan, &ssid, BRCMF_SCAN_ACTION_START);
590 if (err) {
591 brcmf_set_mpc(ndev, 1);
592 cfg_priv->iscan_kickstart = false;
593 return err;
594 }
595 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
596 iscan->timer_on = 1;
597 return err;
598 }
599
600 static s32
601 __brcmf_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
602 struct cfg80211_scan_request *request,
603 struct cfg80211_ssid *this_ssid)
604 {
605 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
606 struct cfg80211_ssid *ssids;
607 struct brcmf_cfg80211_scan_req *sr = cfg_priv->scan_req_int;
608 __le32 passive_scan;
609 bool iscan_req;
610 bool spec_scan;
611 s32 err = 0;
612 u32 SSID_len;
613
614 if (test_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
615 WL_ERR("Scanning already : status (%lu)\n", cfg_priv->status);
616 return -EAGAIN;
617 }
618 if (test_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status)) {
619 WL_ERR("Scanning being aborted : status (%lu)\n",
620 cfg_priv->status);
621 return -EAGAIN;
622 }
623 if (test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
624 WL_ERR("Connecting : status (%lu)\n",
625 cfg_priv->status);
626 return -EAGAIN;
627 }
628
629 iscan_req = false;
630 spec_scan = false;
631 if (request) {
632 /* scan bss */
633 ssids = request->ssids;
634 if (cfg_priv->iscan_on && (!ssids || !ssids->ssid_len))
635 iscan_req = true;
636 } else {
637 /* scan in ibss */
638 /* we don't do iscan in ibss */
639 ssids = this_ssid;
640 }
641
642 cfg_priv->scan_request = request;
643 set_bit(WL_STATUS_SCANNING, &cfg_priv->status);
644 if (iscan_req) {
645 err = brcmf_do_iscan(cfg_priv);
646 if (!err)
647 return err;
648 else
649 goto scan_out;
650 } else {
651 WL_SCAN("ssid \"%s\", ssid_len (%d)\n",
652 ssids->ssid, ssids->ssid_len);
653 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
654 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
655 sr->ssid_le.SSID_len = cpu_to_le32(0);
656 if (SSID_len) {
657 memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
658 sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
659 spec_scan = true;
660 } else {
661 WL_SCAN("Broadcast scan\n");
662 }
663
664 passive_scan = cfg_priv->active_scan ? 0 : cpu_to_le32(1);
665 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_PASSIVE_SCAN,
666 &passive_scan, sizeof(passive_scan));
667 if (err) {
668 WL_ERR("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
669 goto scan_out;
670 }
671 brcmf_set_mpc(ndev, 0);
672 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN, &sr->ssid_le,
673 sizeof(sr->ssid_le));
674 if (err) {
675 if (err == -EBUSY)
676 WL_INFO("system busy : scan for \"%s\" "
677 "canceled\n", sr->ssid_le.SSID);
678 else
679 WL_ERR("WLC_SCAN error (%d)\n", err);
680
681 brcmf_set_mpc(ndev, 1);
682 goto scan_out;
683 }
684 }
685
686 return 0;
687
688 scan_out:
689 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
690 cfg_priv->scan_request = NULL;
691 return err;
692 }
693
694 static s32
695 brcmf_cfg80211_scan(struct wiphy *wiphy,
696 struct cfg80211_scan_request *request)
697 {
698 struct net_device *ndev = request->wdev->netdev;
699 s32 err = 0;
700
701 WL_TRACE("Enter\n");
702
703 if (!check_sys_up(wiphy))
704 return -EIO;
705
706 err = __brcmf_cfg80211_scan(wiphy, ndev, request, NULL);
707 if (err)
708 WL_ERR("scan error (%d)\n", err);
709
710 WL_TRACE("Exit\n");
711 return err;
712 }
713
714 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
715 {
716 s32 err = 0;
717
718 err = brcmf_dev_intvar_set(ndev, "rtsthresh", rts_threshold);
719 if (err)
720 WL_ERR("Error (%d)\n", err);
721
722 return err;
723 }
724
725 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
726 {
727 s32 err = 0;
728
729 err = brcmf_dev_intvar_set(ndev, "fragthresh", frag_threshold);
730 if (err)
731 WL_ERR("Error (%d)\n", err);
732
733 return err;
734 }
735
736 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
737 {
738 s32 err = 0;
739 u32 cmd = (l ? BRCM_SET_LRL : BRCM_SET_SRL);
740
741 err = brcmf_exec_dcmd_u32(ndev, cmd, &retry);
742 if (err) {
743 WL_ERR("cmd (%d) , error (%d)\n", cmd, err);
744 return err;
745 }
746 return err;
747 }
748
749 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
750 {
751 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
752 struct net_device *ndev = cfg_to_ndev(cfg_priv);
753 s32 err = 0;
754
755 WL_TRACE("Enter\n");
756 if (!check_sys_up(wiphy))
757 return -EIO;
758
759 if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
760 (cfg_priv->conf->rts_threshold != wiphy->rts_threshold)) {
761 cfg_priv->conf->rts_threshold = wiphy->rts_threshold;
762 err = brcmf_set_rts(ndev, cfg_priv->conf->rts_threshold);
763 if (!err)
764 goto done;
765 }
766 if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
767 (cfg_priv->conf->frag_threshold != wiphy->frag_threshold)) {
768 cfg_priv->conf->frag_threshold = wiphy->frag_threshold;
769 err = brcmf_set_frag(ndev, cfg_priv->conf->frag_threshold);
770 if (!err)
771 goto done;
772 }
773 if (changed & WIPHY_PARAM_RETRY_LONG
774 && (cfg_priv->conf->retry_long != wiphy->retry_long)) {
775 cfg_priv->conf->retry_long = wiphy->retry_long;
776 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_long, true);
777 if (!err)
778 goto done;
779 }
780 if (changed & WIPHY_PARAM_RETRY_SHORT
781 && (cfg_priv->conf->retry_short != wiphy->retry_short)) {
782 cfg_priv->conf->retry_short = wiphy->retry_short;
783 err = brcmf_set_retry(ndev, cfg_priv->conf->retry_short, false);
784 if (!err)
785 goto done;
786 }
787
788 done:
789 WL_TRACE("Exit\n");
790 return err;
791 }
792
793 static void *brcmf_read_prof(struct brcmf_cfg80211_priv *cfg_priv, s32 item)
794 {
795 switch (item) {
796 case WL_PROF_SEC:
797 return &cfg_priv->profile->sec;
798 case WL_PROF_BSSID:
799 return &cfg_priv->profile->bssid;
800 case WL_PROF_SSID:
801 return &cfg_priv->profile->ssid;
802 }
803 WL_ERR("invalid item (%d)\n", item);
804 return NULL;
805 }
806
807 static s32
808 brcmf_update_prof(struct brcmf_cfg80211_priv *cfg_priv,
809 const struct brcmf_event_msg *e, void *data, s32 item)
810 {
811 s32 err = 0;
812 struct brcmf_ssid *ssid;
813
814 switch (item) {
815 case WL_PROF_SSID:
816 ssid = (struct brcmf_ssid *) data;
817 memset(cfg_priv->profile->ssid.SSID, 0,
818 sizeof(cfg_priv->profile->ssid.SSID));
819 memcpy(cfg_priv->profile->ssid.SSID,
820 ssid->SSID, ssid->SSID_len);
821 cfg_priv->profile->ssid.SSID_len = ssid->SSID_len;
822 break;
823 case WL_PROF_BSSID:
824 if (data)
825 memcpy(cfg_priv->profile->bssid, data, ETH_ALEN);
826 else
827 memset(cfg_priv->profile->bssid, 0, ETH_ALEN);
828 break;
829 case WL_PROF_SEC:
830 memcpy(&cfg_priv->profile->sec, data,
831 sizeof(cfg_priv->profile->sec));
832 break;
833 case WL_PROF_BEACONINT:
834 cfg_priv->profile->beacon_interval = *(u16 *)data;
835 break;
836 case WL_PROF_DTIMPERIOD:
837 cfg_priv->profile->dtim_period = *(u8 *)data;
838 break;
839 default:
840 WL_ERR("unsupported item (%d)\n", item);
841 err = -EOPNOTSUPP;
842 break;
843 }
844
845 return err;
846 }
847
848 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
849 {
850 memset(prof, 0, sizeof(*prof));
851 }
852
853 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
854 size_t *join_params_size)
855 {
856 u16 chanspec = 0;
857
858 if (ch != 0) {
859 if (ch <= CH_MAX_2G_CHANNEL)
860 chanspec |= WL_CHANSPEC_BAND_2G;
861 else
862 chanspec |= WL_CHANSPEC_BAND_5G;
863
864 chanspec |= WL_CHANSPEC_BW_20;
865 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
866
867 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
868 sizeof(u16);
869
870 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
871 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
872 join_params->params_le.chanspec_num = cpu_to_le32(1);
873
874 WL_CONN("join_params->params.chanspec_list[0]= %#X,"
875 "channel %d, chanspec %#X\n",
876 chanspec, ch, chanspec);
877 }
878 }
879
880 static void brcmf_link_down(struct brcmf_cfg80211_priv *cfg_priv)
881 {
882 struct net_device *ndev = NULL;
883 s32 err = 0;
884
885 WL_TRACE("Enter\n");
886
887 if (cfg_priv->link_up) {
888 ndev = cfg_to_ndev(cfg_priv);
889 WL_INFO("Call WLC_DISASSOC to stop excess roaming\n ");
890 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, NULL, 0);
891 if (err)
892 WL_ERR("WLC_DISASSOC failed (%d)\n", err);
893 cfg_priv->link_up = false;
894 }
895 WL_TRACE("Exit\n");
896 }
897
898 static s32
899 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
900 struct cfg80211_ibss_params *params)
901 {
902 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
903 struct brcmf_join_params join_params;
904 size_t join_params_size = 0;
905 s32 err = 0;
906 s32 wsec = 0;
907 s32 bcnprd;
908 struct brcmf_ssid ssid;
909
910 WL_TRACE("Enter\n");
911 if (!check_sys_up(wiphy))
912 return -EIO;
913
914 if (params->ssid)
915 WL_CONN("SSID: %s\n", params->ssid);
916 else {
917 WL_CONN("SSID: NULL, Not supported\n");
918 return -EOPNOTSUPP;
919 }
920
921 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
922
923 if (params->bssid)
924 WL_CONN("BSSID: %pM\n", params->bssid);
925 else
926 WL_CONN("No BSSID specified\n");
927
928 if (params->channel)
929 WL_CONN("channel: %d\n", params->channel->center_freq);
930 else
931 WL_CONN("no channel specified\n");
932
933 if (params->channel_fixed)
934 WL_CONN("fixed channel required\n");
935 else
936 WL_CONN("no fixed channel required\n");
937
938 if (params->ie && params->ie_len)
939 WL_CONN("ie len: %d\n", params->ie_len);
940 else
941 WL_CONN("no ie specified\n");
942
943 if (params->beacon_interval)
944 WL_CONN("beacon interval: %d\n", params->beacon_interval);
945 else
946 WL_CONN("no beacon interval specified\n");
947
948 if (params->basic_rates)
949 WL_CONN("basic rates: %08X\n", params->basic_rates);
950 else
951 WL_CONN("no basic rates specified\n");
952
953 if (params->privacy)
954 WL_CONN("privacy required\n");
955 else
956 WL_CONN("no privacy required\n");
957
958 /* Configure Privacy for starter */
959 if (params->privacy)
960 wsec |= WEP_ENABLED;
961
962 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
963 if (err) {
964 WL_ERR("wsec failed (%d)\n", err);
965 goto done;
966 }
967
968 /* Configure Beacon Interval for starter */
969 if (params->beacon_interval)
970 bcnprd = params->beacon_interval;
971 else
972 bcnprd = 100;
973
974 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_BCNPRD, &bcnprd);
975 if (err) {
976 WL_ERR("WLC_SET_BCNPRD failed (%d)\n", err);
977 goto done;
978 }
979
980 /* Configure required join parameter */
981 memset(&join_params, 0, sizeof(struct brcmf_join_params));
982
983 /* SSID */
984 ssid.SSID_len = min_t(u32, params->ssid_len, 32);
985 memcpy(ssid.SSID, params->ssid, ssid.SSID_len);
986 memcpy(join_params.ssid_le.SSID, params->ssid, ssid.SSID_len);
987 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
988 join_params_size = sizeof(join_params.ssid_le);
989 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
990
991 /* BSSID */
992 if (params->bssid) {
993 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
994 join_params_size = sizeof(join_params.ssid_le) +
995 BRCMF_ASSOC_PARAMS_FIXED_SIZE;
996 } else {
997 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
998 }
999
1000 brcmf_update_prof(cfg_priv, NULL,
1001 &join_params.params_le.bssid, WL_PROF_BSSID);
1002
1003 /* Channel */
1004 if (params->channel) {
1005 u32 target_channel;
1006
1007 cfg_priv->channel =
1008 ieee80211_frequency_to_channel(
1009 params->channel->center_freq);
1010 if (params->channel_fixed) {
1011 /* adding chanspec */
1012 brcmf_ch_to_chanspec(cfg_priv->channel,
1013 &join_params, &join_params_size);
1014 }
1015
1016 /* set channel for starter */
1017 target_channel = cfg_priv->channel;
1018 err = brcmf_exec_dcmd_u32(ndev, BRCM_SET_CHANNEL,
1019 &target_channel);
1020 if (err) {
1021 WL_ERR("WLC_SET_CHANNEL failed (%d)\n", err);
1022 goto done;
1023 }
1024 } else
1025 cfg_priv->channel = 0;
1026
1027 cfg_priv->ibss_starter = false;
1028
1029
1030 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1031 &join_params, join_params_size);
1032 if (err) {
1033 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1034 goto done;
1035 }
1036
1037 done:
1038 if (err)
1039 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1040 WL_TRACE("Exit\n");
1041 return err;
1042 }
1043
1044 static s32
1045 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1046 {
1047 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1048 s32 err = 0;
1049
1050 WL_TRACE("Enter\n");
1051 if (!check_sys_up(wiphy))
1052 return -EIO;
1053
1054 brcmf_link_down(cfg_priv);
1055
1056 WL_TRACE("Exit\n");
1057
1058 return err;
1059 }
1060
1061 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1062 struct cfg80211_connect_params *sme)
1063 {
1064 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1065 struct brcmf_cfg80211_security *sec;
1066 s32 val = 0;
1067 s32 err = 0;
1068
1069 if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1070 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1071 else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1072 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1073 else
1074 val = WPA_AUTH_DISABLED;
1075 WL_CONN("setting wpa_auth to 0x%0x\n", val);
1076 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1077 if (err) {
1078 WL_ERR("set wpa_auth failed (%d)\n", err);
1079 return err;
1080 }
1081 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1082 sec->wpa_versions = sme->crypto.wpa_versions;
1083 return err;
1084 }
1085
1086 static s32 brcmf_set_auth_type(struct net_device *ndev,
1087 struct cfg80211_connect_params *sme)
1088 {
1089 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1090 struct brcmf_cfg80211_security *sec;
1091 s32 val = 0;
1092 s32 err = 0;
1093
1094 switch (sme->auth_type) {
1095 case NL80211_AUTHTYPE_OPEN_SYSTEM:
1096 val = 0;
1097 WL_CONN("open system\n");
1098 break;
1099 case NL80211_AUTHTYPE_SHARED_KEY:
1100 val = 1;
1101 WL_CONN("shared key\n");
1102 break;
1103 case NL80211_AUTHTYPE_AUTOMATIC:
1104 val = 2;
1105 WL_CONN("automatic\n");
1106 break;
1107 case NL80211_AUTHTYPE_NETWORK_EAP:
1108 WL_CONN("network eap\n");
1109 default:
1110 val = 2;
1111 WL_ERR("invalid auth type (%d)\n", sme->auth_type);
1112 break;
1113 }
1114
1115 err = brcmf_dev_intvar_set(ndev, "auth", val);
1116 if (err) {
1117 WL_ERR("set auth failed (%d)\n", err);
1118 return err;
1119 }
1120 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1121 sec->auth_type = sme->auth_type;
1122 return err;
1123 }
1124
1125 static s32
1126 brcmf_set_set_cipher(struct net_device *ndev,
1127 struct cfg80211_connect_params *sme)
1128 {
1129 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1130 struct brcmf_cfg80211_security *sec;
1131 s32 pval = 0;
1132 s32 gval = 0;
1133 s32 err = 0;
1134
1135 if (sme->crypto.n_ciphers_pairwise) {
1136 switch (sme->crypto.ciphers_pairwise[0]) {
1137 case WLAN_CIPHER_SUITE_WEP40:
1138 case WLAN_CIPHER_SUITE_WEP104:
1139 pval = WEP_ENABLED;
1140 break;
1141 case WLAN_CIPHER_SUITE_TKIP:
1142 pval = TKIP_ENABLED;
1143 break;
1144 case WLAN_CIPHER_SUITE_CCMP:
1145 pval = AES_ENABLED;
1146 break;
1147 case WLAN_CIPHER_SUITE_AES_CMAC:
1148 pval = AES_ENABLED;
1149 break;
1150 default:
1151 WL_ERR("invalid cipher pairwise (%d)\n",
1152 sme->crypto.ciphers_pairwise[0]);
1153 return -EINVAL;
1154 }
1155 }
1156 if (sme->crypto.cipher_group) {
1157 switch (sme->crypto.cipher_group) {
1158 case WLAN_CIPHER_SUITE_WEP40:
1159 case WLAN_CIPHER_SUITE_WEP104:
1160 gval = WEP_ENABLED;
1161 break;
1162 case WLAN_CIPHER_SUITE_TKIP:
1163 gval = TKIP_ENABLED;
1164 break;
1165 case WLAN_CIPHER_SUITE_CCMP:
1166 gval = AES_ENABLED;
1167 break;
1168 case WLAN_CIPHER_SUITE_AES_CMAC:
1169 gval = AES_ENABLED;
1170 break;
1171 default:
1172 WL_ERR("invalid cipher group (%d)\n",
1173 sme->crypto.cipher_group);
1174 return -EINVAL;
1175 }
1176 }
1177
1178 WL_CONN("pval (%d) gval (%d)\n", pval, gval);
1179 err = brcmf_dev_intvar_set(ndev, "wsec", pval | gval);
1180 if (err) {
1181 WL_ERR("error (%d)\n", err);
1182 return err;
1183 }
1184
1185 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1186 sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1187 sec->cipher_group = sme->crypto.cipher_group;
1188
1189 return err;
1190 }
1191
1192 static s32
1193 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1194 {
1195 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1196 struct brcmf_cfg80211_security *sec;
1197 s32 val = 0;
1198 s32 err = 0;
1199
1200 if (sme->crypto.n_akm_suites) {
1201 err = brcmf_dev_intvar_get(ndev, "wpa_auth", &val);
1202 if (err) {
1203 WL_ERR("could not get wpa_auth (%d)\n", err);
1204 return err;
1205 }
1206 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1207 switch (sme->crypto.akm_suites[0]) {
1208 case WLAN_AKM_SUITE_8021X:
1209 val = WPA_AUTH_UNSPECIFIED;
1210 break;
1211 case WLAN_AKM_SUITE_PSK:
1212 val = WPA_AUTH_PSK;
1213 break;
1214 default:
1215 WL_ERR("invalid cipher group (%d)\n",
1216 sme->crypto.cipher_group);
1217 return -EINVAL;
1218 }
1219 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1220 switch (sme->crypto.akm_suites[0]) {
1221 case WLAN_AKM_SUITE_8021X:
1222 val = WPA2_AUTH_UNSPECIFIED;
1223 break;
1224 case WLAN_AKM_SUITE_PSK:
1225 val = WPA2_AUTH_PSK;
1226 break;
1227 default:
1228 WL_ERR("invalid cipher group (%d)\n",
1229 sme->crypto.cipher_group);
1230 return -EINVAL;
1231 }
1232 }
1233
1234 WL_CONN("setting wpa_auth to %d\n", val);
1235 err = brcmf_dev_intvar_set(ndev, "wpa_auth", val);
1236 if (err) {
1237 WL_ERR("could not set wpa_auth (%d)\n", err);
1238 return err;
1239 }
1240 }
1241 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1242 sec->wpa_auth = sme->crypto.akm_suites[0];
1243
1244 return err;
1245 }
1246
1247 static s32
1248 brcmf_set_wep_sharedkey(struct net_device *ndev,
1249 struct cfg80211_connect_params *sme)
1250 {
1251 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
1252 struct brcmf_cfg80211_security *sec;
1253 struct brcmf_wsec_key key;
1254 s32 val;
1255 s32 err = 0;
1256
1257 WL_CONN("key len (%d)\n", sme->key_len);
1258
1259 if (sme->key_len == 0)
1260 return 0;
1261
1262 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1263 WL_CONN("wpa_versions 0x%x cipher_pairwise 0x%x\n",
1264 sec->wpa_versions, sec->cipher_pairwise);
1265
1266 if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1267 return 0;
1268
1269 if (sec->cipher_pairwise &
1270 (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)) {
1271 memset(&key, 0, sizeof(key));
1272 key.len = (u32) sme->key_len;
1273 key.index = (u32) sme->key_idx;
1274 if (key.len > sizeof(key.data)) {
1275 WL_ERR("Too long key length (%u)\n", key.len);
1276 return -EINVAL;
1277 }
1278 memcpy(key.data, sme->key, key.len);
1279 key.flags = BRCMF_PRIMARY_KEY;
1280 switch (sec->cipher_pairwise) {
1281 case WLAN_CIPHER_SUITE_WEP40:
1282 key.algo = CRYPTO_ALGO_WEP1;
1283 break;
1284 case WLAN_CIPHER_SUITE_WEP104:
1285 key.algo = CRYPTO_ALGO_WEP128;
1286 break;
1287 default:
1288 WL_ERR("Invalid algorithm (%d)\n",
1289 sme->crypto.ciphers_pairwise[0]);
1290 return -EINVAL;
1291 }
1292 /* Set the new key/index */
1293 WL_CONN("key length (%d) key index (%d) algo (%d)\n",
1294 key.len, key.index, key.algo);
1295 WL_CONN("key \"%s\"\n", key.data);
1296 err = send_key_to_dongle(ndev, &key);
1297 if (err)
1298 return err;
1299
1300 if (sec->auth_type == NL80211_AUTHTYPE_OPEN_SYSTEM) {
1301 WL_CONN("set auth_type to shared key\n");
1302 val = 1; /* shared key */
1303 err = brcmf_dev_intvar_set(ndev, "auth", val);
1304 if (err) {
1305 WL_ERR("set auth failed (%d)\n", err);
1306 return err;
1307 }
1308 }
1309 }
1310 return err;
1311 }
1312
1313 static s32
1314 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1315 struct cfg80211_connect_params *sme)
1316 {
1317 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1318 struct ieee80211_channel *chan = sme->channel;
1319 struct brcmf_join_params join_params;
1320 size_t join_params_size;
1321 struct brcmf_ssid ssid;
1322
1323 s32 err = 0;
1324
1325 WL_TRACE("Enter\n");
1326 if (!check_sys_up(wiphy))
1327 return -EIO;
1328
1329 if (!sme->ssid) {
1330 WL_ERR("Invalid ssid\n");
1331 return -EOPNOTSUPP;
1332 }
1333
1334 set_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1335
1336 if (chan) {
1337 cfg_priv->channel =
1338 ieee80211_frequency_to_channel(chan->center_freq);
1339 WL_CONN("channel (%d), center_req (%d)\n",
1340 cfg_priv->channel, chan->center_freq);
1341 } else
1342 cfg_priv->channel = 0;
1343
1344 WL_INFO("ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1345
1346 err = brcmf_set_wpa_version(ndev, sme);
1347 if (err) {
1348 WL_ERR("wl_set_wpa_version failed (%d)\n", err);
1349 goto done;
1350 }
1351
1352 err = brcmf_set_auth_type(ndev, sme);
1353 if (err) {
1354 WL_ERR("wl_set_auth_type failed (%d)\n", err);
1355 goto done;
1356 }
1357
1358 err = brcmf_set_set_cipher(ndev, sme);
1359 if (err) {
1360 WL_ERR("wl_set_set_cipher failed (%d)\n", err);
1361 goto done;
1362 }
1363
1364 err = brcmf_set_key_mgmt(ndev, sme);
1365 if (err) {
1366 WL_ERR("wl_set_key_mgmt failed (%d)\n", err);
1367 goto done;
1368 }
1369
1370 err = brcmf_set_wep_sharedkey(ndev, sme);
1371 if (err) {
1372 WL_ERR("brcmf_set_wep_sharedkey failed (%d)\n", err);
1373 goto done;
1374 }
1375
1376 memset(&join_params, 0, sizeof(join_params));
1377 join_params_size = sizeof(join_params.ssid_le);
1378
1379 ssid.SSID_len = min_t(u32, sizeof(ssid.SSID), (u32)sme->ssid_len);
1380 memcpy(&join_params.ssid_le.SSID, sme->ssid, ssid.SSID_len);
1381 memcpy(&ssid.SSID, sme->ssid, ssid.SSID_len);
1382 join_params.ssid_le.SSID_len = cpu_to_le32(ssid.SSID_len);
1383 brcmf_update_prof(cfg_priv, NULL, &ssid, WL_PROF_SSID);
1384
1385 memcpy(join_params.params_le.bssid, ether_bcast, ETH_ALEN);
1386
1387 if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1388 WL_CONN("ssid \"%s\", len (%d)\n",
1389 ssid.SSID, ssid.SSID_len);
1390
1391 brcmf_ch_to_chanspec(cfg_priv->channel,
1392 &join_params, &join_params_size);
1393 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SSID,
1394 &join_params, join_params_size);
1395 if (err)
1396 WL_ERR("WLC_SET_SSID failed (%d)\n", err);
1397
1398 done:
1399 if (err)
1400 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
1401 WL_TRACE("Exit\n");
1402 return err;
1403 }
1404
1405 static s32
1406 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1407 u16 reason_code)
1408 {
1409 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1410 struct brcmf_scb_val_le scbval;
1411 s32 err = 0;
1412
1413 WL_TRACE("Enter. Reason code = %d\n", reason_code);
1414 if (!check_sys_up(wiphy))
1415 return -EIO;
1416
1417 clear_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
1418
1419 memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1420 scbval.val = cpu_to_le32(reason_code);
1421 err = brcmf_exec_dcmd(ndev, BRCMF_C_DISASSOC, &scbval,
1422 sizeof(struct brcmf_scb_val_le));
1423 if (err)
1424 WL_ERR("error (%d)\n", err);
1425
1426 cfg_priv->link_up = false;
1427
1428 WL_TRACE("Exit\n");
1429 return err;
1430 }
1431
1432 static s32
1433 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1434 enum nl80211_tx_power_setting type, s32 mbm)
1435 {
1436
1437 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1438 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1439 u16 txpwrmw;
1440 s32 err = 0;
1441 s32 disable = 0;
1442 s32 dbm = MBM_TO_DBM(mbm);
1443
1444 WL_TRACE("Enter\n");
1445 if (!check_sys_up(wiphy))
1446 return -EIO;
1447
1448 switch (type) {
1449 case NL80211_TX_POWER_AUTOMATIC:
1450 break;
1451 case NL80211_TX_POWER_LIMITED:
1452 case NL80211_TX_POWER_FIXED:
1453 if (dbm < 0) {
1454 WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1455 err = -EINVAL;
1456 goto done;
1457 }
1458 break;
1459 }
1460 /* Make sure radio is off or on as far as software is concerned */
1461 disable = WL_RADIO_SW_DISABLE << 16;
1462 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1463 if (err)
1464 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1465
1466 if (dbm > 0xffff)
1467 txpwrmw = 0xffff;
1468 else
1469 txpwrmw = (u16) dbm;
1470 err = brcmf_dev_intvar_set(ndev, "qtxpower",
1471 (s32) (brcmf_mw_to_qdbm(txpwrmw)));
1472 if (err)
1473 WL_ERR("qtxpower error (%d)\n", err);
1474 cfg_priv->conf->tx_power = dbm;
1475
1476 done:
1477 WL_TRACE("Exit\n");
1478 return err;
1479 }
1480
1481 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1482 {
1483 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1484 struct net_device *ndev = cfg_to_ndev(cfg_priv);
1485 s32 txpwrdbm;
1486 u8 result;
1487 s32 err = 0;
1488
1489 WL_TRACE("Enter\n");
1490 if (!check_sys_up(wiphy))
1491 return -EIO;
1492
1493 err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1494 if (err) {
1495 WL_ERR("error (%d)\n", err);
1496 goto done;
1497 }
1498
1499 result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1500 *dbm = (s32) brcmf_qdbm_to_mw(result);
1501
1502 done:
1503 WL_TRACE("Exit\n");
1504 return err;
1505 }
1506
1507 static s32
1508 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1509 u8 key_idx, bool unicast, bool multicast)
1510 {
1511 u32 index;
1512 u32 wsec;
1513 s32 err = 0;
1514
1515 WL_TRACE("Enter\n");
1516 WL_CONN("key index (%d)\n", key_idx);
1517 if (!check_sys_up(wiphy))
1518 return -EIO;
1519
1520 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1521 if (err) {
1522 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1523 goto done;
1524 }
1525
1526 if (wsec & WEP_ENABLED) {
1527 /* Just select a new current key */
1528 index = key_idx;
1529 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_KEY_PRIMARY,
1530 &index);
1531 if (err)
1532 WL_ERR("error (%d)\n", err);
1533 }
1534 done:
1535 WL_TRACE("Exit\n");
1536 return err;
1537 }
1538
1539 static s32
1540 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1541 u8 key_idx, const u8 *mac_addr, struct key_params *params)
1542 {
1543 struct brcmf_wsec_key key;
1544 struct brcmf_wsec_key_le key_le;
1545 s32 err = 0;
1546
1547 memset(&key, 0, sizeof(key));
1548 key.index = (u32) key_idx;
1549 /* Instead of bcast for ea address for default wep keys,
1550 driver needs it to be Null */
1551 if (!is_multicast_ether_addr(mac_addr))
1552 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1553 key.len = (u32) params->key_len;
1554 /* check for key index change */
1555 if (key.len == 0) {
1556 /* key delete */
1557 err = send_key_to_dongle(ndev, &key);
1558 if (err)
1559 return err;
1560 } else {
1561 if (key.len > sizeof(key.data)) {
1562 WL_ERR("Invalid key length (%d)\n", key.len);
1563 return -EINVAL;
1564 }
1565
1566 WL_CONN("Setting the key index %d\n", key.index);
1567 memcpy(key.data, params->key, key.len);
1568
1569 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1570 u8 keybuf[8];
1571 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1572 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1573 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1574 }
1575
1576 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1577 if (params->seq && params->seq_len == 6) {
1578 /* rx iv */
1579 u8 *ivptr;
1580 ivptr = (u8 *) params->seq;
1581 key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1582 (ivptr[3] << 8) | ivptr[2];
1583 key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1584 key.iv_initialized = true;
1585 }
1586
1587 switch (params->cipher) {
1588 case WLAN_CIPHER_SUITE_WEP40:
1589 key.algo = CRYPTO_ALGO_WEP1;
1590 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1591 break;
1592 case WLAN_CIPHER_SUITE_WEP104:
1593 key.algo = CRYPTO_ALGO_WEP128;
1594 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1595 break;
1596 case WLAN_CIPHER_SUITE_TKIP:
1597 key.algo = CRYPTO_ALGO_TKIP;
1598 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1599 break;
1600 case WLAN_CIPHER_SUITE_AES_CMAC:
1601 key.algo = CRYPTO_ALGO_AES_CCM;
1602 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1603 break;
1604 case WLAN_CIPHER_SUITE_CCMP:
1605 key.algo = CRYPTO_ALGO_AES_CCM;
1606 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1607 break;
1608 default:
1609 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1610 return -EINVAL;
1611 }
1612 convert_key_from_CPU(&key, &key_le);
1613
1614 brcmf_netdev_wait_pend8021x(ndev);
1615 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_KEY, &key_le,
1616 sizeof(key_le));
1617 if (err) {
1618 WL_ERR("WLC_SET_KEY error (%d)\n", err);
1619 return err;
1620 }
1621 }
1622 return err;
1623 }
1624
1625 static s32
1626 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1627 u8 key_idx, bool pairwise, const u8 *mac_addr,
1628 struct key_params *params)
1629 {
1630 struct brcmf_wsec_key key;
1631 s32 val;
1632 s32 wsec;
1633 s32 err = 0;
1634 u8 keybuf[8];
1635
1636 WL_TRACE("Enter\n");
1637 WL_CONN("key index (%d)\n", key_idx);
1638 if (!check_sys_up(wiphy))
1639 return -EIO;
1640
1641 if (mac_addr) {
1642 WL_TRACE("Exit");
1643 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1644 }
1645 memset(&key, 0, sizeof(key));
1646
1647 key.len = (u32) params->key_len;
1648 key.index = (u32) key_idx;
1649
1650 if (key.len > sizeof(key.data)) {
1651 WL_ERR("Too long key length (%u)\n", key.len);
1652 err = -EINVAL;
1653 goto done;
1654 }
1655 memcpy(key.data, params->key, key.len);
1656
1657 key.flags = BRCMF_PRIMARY_KEY;
1658 switch (params->cipher) {
1659 case WLAN_CIPHER_SUITE_WEP40:
1660 key.algo = CRYPTO_ALGO_WEP1;
1661 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1662 break;
1663 case WLAN_CIPHER_SUITE_WEP104:
1664 key.algo = CRYPTO_ALGO_WEP128;
1665 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1666 break;
1667 case WLAN_CIPHER_SUITE_TKIP:
1668 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1669 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1670 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1671 key.algo = CRYPTO_ALGO_TKIP;
1672 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1673 break;
1674 case WLAN_CIPHER_SUITE_AES_CMAC:
1675 key.algo = CRYPTO_ALGO_AES_CCM;
1676 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1677 break;
1678 case WLAN_CIPHER_SUITE_CCMP:
1679 key.algo = CRYPTO_ALGO_AES_CCM;
1680 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1681 break;
1682 default:
1683 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1684 err = -EINVAL;
1685 goto done;
1686 }
1687
1688 err = send_key_to_dongle(ndev, &key); /* Set the new key/index */
1689 if (err)
1690 goto done;
1691
1692 val = WEP_ENABLED;
1693 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1694 if (err) {
1695 WL_ERR("get wsec error (%d)\n", err);
1696 goto done;
1697 }
1698 wsec &= ~(WEP_ENABLED);
1699 wsec |= val;
1700 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1701 if (err) {
1702 WL_ERR("set wsec error (%d)\n", err);
1703 goto done;
1704 }
1705
1706 val = 1; /* assume shared key. otherwise 0 */
1707 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1708 if (err)
1709 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1710 done:
1711 WL_TRACE("Exit\n");
1712 return err;
1713 }
1714
1715 static s32
1716 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1717 u8 key_idx, bool pairwise, const u8 *mac_addr)
1718 {
1719 struct brcmf_wsec_key key;
1720 s32 err = 0;
1721 s32 val;
1722 s32 wsec;
1723
1724 WL_TRACE("Enter\n");
1725 if (!check_sys_up(wiphy))
1726 return -EIO;
1727
1728 memset(&key, 0, sizeof(key));
1729
1730 key.index = (u32) key_idx;
1731 key.flags = BRCMF_PRIMARY_KEY;
1732 key.algo = CRYPTO_ALGO_OFF;
1733
1734 WL_CONN("key index (%d)\n", key_idx);
1735
1736 /* Set the new key/index */
1737 err = send_key_to_dongle(ndev, &key);
1738 if (err) {
1739 if (err == -EINVAL) {
1740 if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1741 /* we ignore this key index in this case */
1742 WL_ERR("invalid key index (%d)\n", key_idx);
1743 }
1744 /* Ignore this error, may happen during DISASSOC */
1745 err = -EAGAIN;
1746 goto done;
1747 }
1748
1749 val = 0;
1750 err = brcmf_dev_intvar_get(ndev, "wsec", &wsec);
1751 if (err) {
1752 WL_ERR("get wsec error (%d)\n", err);
1753 /* Ignore this error, may happen during DISASSOC */
1754 err = -EAGAIN;
1755 goto done;
1756 }
1757 wsec &= ~(WEP_ENABLED);
1758 wsec |= val;
1759 err = brcmf_dev_intvar_set(ndev, "wsec", wsec);
1760 if (err) {
1761 WL_ERR("set wsec error (%d)\n", err);
1762 /* Ignore this error, may happen during DISASSOC */
1763 err = -EAGAIN;
1764 goto done;
1765 }
1766
1767 val = 0; /* assume open key. otherwise 1 */
1768 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_AUTH, &val);
1769 if (err) {
1770 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1771 /* Ignore this error, may happen during DISASSOC */
1772 err = -EAGAIN;
1773 }
1774 done:
1775 WL_TRACE("Exit\n");
1776 return err;
1777 }
1778
1779 static s32
1780 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1781 u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1782 void (*callback) (void *cookie, struct key_params * params))
1783 {
1784 struct key_params params;
1785 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1786 struct brcmf_cfg80211_security *sec;
1787 s32 wsec;
1788 s32 err = 0;
1789
1790 WL_TRACE("Enter\n");
1791 WL_CONN("key index (%d)\n", key_idx);
1792 if (!check_sys_up(wiphy))
1793 return -EIO;
1794
1795 memset(&params, 0, sizeof(params));
1796
1797 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_WSEC, &wsec);
1798 if (err) {
1799 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1800 /* Ignore this error, may happen during DISASSOC */
1801 err = -EAGAIN;
1802 goto done;
1803 }
1804 switch (wsec) {
1805 case WEP_ENABLED:
1806 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1807 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1808 params.cipher = WLAN_CIPHER_SUITE_WEP40;
1809 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1810 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1811 params.cipher = WLAN_CIPHER_SUITE_WEP104;
1812 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1813 }
1814 break;
1815 case TKIP_ENABLED:
1816 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1817 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1818 break;
1819 case AES_ENABLED:
1820 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1821 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1822 break;
1823 default:
1824 WL_ERR("Invalid algo (0x%x)\n", wsec);
1825 err = -EINVAL;
1826 goto done;
1827 }
1828 callback(cookie, &params);
1829
1830 done:
1831 WL_TRACE("Exit\n");
1832 return err;
1833 }
1834
1835 static s32
1836 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1837 struct net_device *ndev, u8 key_idx)
1838 {
1839 WL_INFO("Not supported\n");
1840
1841 return -EOPNOTSUPP;
1842 }
1843
1844 static s32
1845 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1846 u8 *mac, struct station_info *sinfo)
1847 {
1848 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1849 struct brcmf_scb_val_le scb_val;
1850 int rssi;
1851 s32 rate;
1852 s32 err = 0;
1853 u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1854
1855 WL_TRACE("Enter\n");
1856 if (!check_sys_up(wiphy))
1857 return -EIO;
1858
1859 if (memcmp(mac, bssid, ETH_ALEN)) {
1860 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1861 "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1862 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1863 bssid[0], bssid[1], bssid[2], bssid[3],
1864 bssid[4], bssid[5]);
1865 err = -ENOENT;
1866 goto done;
1867 }
1868
1869 /* Report the current tx rate */
1870 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_GET_RATE, &rate);
1871 if (err) {
1872 WL_ERR("Could not get rate (%d)\n", err);
1873 } else {
1874 sinfo->filled |= STATION_INFO_TX_BITRATE;
1875 sinfo->txrate.legacy = rate * 5;
1876 WL_CONN("Rate %d Mbps\n", rate / 2);
1877 }
1878
1879 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1880 scb_val.val = cpu_to_le32(0);
1881 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_RSSI, &scb_val,
1882 sizeof(struct brcmf_scb_val_le));
1883 if (err)
1884 WL_ERR("Could not get rssi (%d)\n", err);
1885
1886 rssi = le32_to_cpu(scb_val.val);
1887 sinfo->filled |= STATION_INFO_SIGNAL;
1888 sinfo->signal = rssi;
1889 WL_CONN("RSSI %d dBm\n", rssi);
1890 }
1891
1892 done:
1893 WL_TRACE("Exit\n");
1894 return err;
1895 }
1896
1897 static s32
1898 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1899 bool enabled, s32 timeout)
1900 {
1901 s32 pm;
1902 s32 err = 0;
1903 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1904
1905 WL_TRACE("Enter\n");
1906
1907 /*
1908 * Powersave enable/disable request is coming from the
1909 * cfg80211 even before the interface is up. In that
1910 * scenario, driver will be storing the power save
1911 * preference in cfg_priv struct to apply this to
1912 * FW later while initializing the dongle
1913 */
1914 cfg_priv->pwr_save = enabled;
1915 if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1916
1917 WL_INFO("Device is not ready,"
1918 "storing the value in cfg_priv struct\n");
1919 goto done;
1920 }
1921
1922 pm = enabled ? PM_FAST : PM_OFF;
1923 WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1924
1925 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &pm);
1926 if (err) {
1927 if (err == -ENODEV)
1928 WL_ERR("net_device is not ready yet\n");
1929 else
1930 WL_ERR("error (%d)\n", err);
1931 }
1932 done:
1933 WL_TRACE("Exit\n");
1934 return err;
1935 }
1936
1937 static s32
1938 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
1939 const u8 *addr,
1940 const struct cfg80211_bitrate_mask *mask)
1941 {
1942 struct brcm_rateset_le rateset_le;
1943 s32 rate;
1944 s32 val;
1945 s32 err_bg;
1946 s32 err_a;
1947 u32 legacy;
1948 s32 err = 0;
1949
1950 WL_TRACE("Enter\n");
1951 if (!check_sys_up(wiphy))
1952 return -EIO;
1953
1954 /* addr param is always NULL. ignore it */
1955 /* Get current rateset */
1956 err = brcmf_exec_dcmd(ndev, BRCM_GET_CURR_RATESET, &rateset_le,
1957 sizeof(rateset_le));
1958 if (err) {
1959 WL_ERR("could not get current rateset (%d)\n", err);
1960 goto done;
1961 }
1962
1963 legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1964 if (!legacy)
1965 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1966 0xFFFF);
1967
1968 val = wl_g_rates[legacy - 1].bitrate * 100000;
1969
1970 if (val < le32_to_cpu(rateset_le.count))
1971 /* Select rate by rateset index */
1972 rate = rateset_le.rates[val] & 0x7f;
1973 else
1974 /* Specified rate in bps */
1975 rate = val / 500000;
1976
1977 WL_CONN("rate %d mbps\n", rate / 2);
1978
1979 /*
1980 *
1981 * Set rate override,
1982 * Since the is a/b/g-blind, both a/bg_rate are enforced.
1983 */
1984 err_bg = brcmf_dev_intvar_set(ndev, "bg_rate", rate);
1985 err_a = brcmf_dev_intvar_set(ndev, "a_rate", rate);
1986 if (err_bg && err_a) {
1987 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1988 err = err_bg | err_a;
1989 }
1990
1991 done:
1992 WL_TRACE("Exit\n");
1993 return err;
1994 }
1995
1996 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1997 struct brcmf_bss_info_le *bi)
1998 {
1999 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2000 struct ieee80211_channel *notify_channel;
2001 struct cfg80211_bss *bss;
2002 struct ieee80211_supported_band *band;
2003 s32 err = 0;
2004 u16 channel;
2005 u32 freq;
2006 u16 notify_capability;
2007 u16 notify_interval;
2008 u8 *notify_ie;
2009 size_t notify_ielen;
2010 s32 notify_signal;
2011
2012 if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2013 WL_ERR("Bss info is larger than buffer. Discarding\n");
2014 return 0;
2015 }
2016
2017 channel = bi->ctl_ch ? bi->ctl_ch :
2018 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2019
2020 if (channel <= CH_MAX_2G_CHANNEL)
2021 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2022 else
2023 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2024
2025 freq = ieee80211_channel_to_frequency(channel, band->band);
2026 notify_channel = ieee80211_get_channel(wiphy, freq);
2027
2028 notify_capability = le16_to_cpu(bi->capability);
2029 notify_interval = le16_to_cpu(bi->beacon_period);
2030 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2031 notify_ielen = le32_to_cpu(bi->ie_length);
2032 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2033
2034 WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
2035 bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
2036 bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
2037 WL_CONN("Channel: %d(%d)\n", channel, freq);
2038 WL_CONN("Capability: %X\n", notify_capability);
2039 WL_CONN("Beacon interval: %d\n", notify_interval);
2040 WL_CONN("Signal: %d\n", notify_signal);
2041
2042 bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2043 0, notify_capability, notify_interval, notify_ie,
2044 notify_ielen, notify_signal, GFP_KERNEL);
2045
2046 if (!bss)
2047 return -ENOMEM;
2048
2049 cfg80211_put_bss(bss);
2050
2051 return err;
2052 }
2053
2054 static struct brcmf_bss_info_le *
2055 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2056 {
2057 if (bss == NULL)
2058 return list->bss_info_le;
2059 return (struct brcmf_bss_info_le *)((unsigned long)bss +
2060 le32_to_cpu(bss->length));
2061 }
2062
2063 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
2064 {
2065 struct brcmf_scan_results *bss_list;
2066 struct brcmf_bss_info_le *bi = NULL; /* must be initialized */
2067 s32 err = 0;
2068 int i;
2069
2070 bss_list = cfg_priv->bss_list;
2071 if (bss_list->version != BRCMF_BSS_INFO_VERSION) {
2072 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
2073 bss_list->version);
2074 return -EOPNOTSUPP;
2075 }
2076 WL_SCAN("scanned AP count (%d)\n", bss_list->count);
2077 for (i = 0; i < bss_list->count && i < WL_AP_MAX; i++) {
2078 bi = next_bss_le(bss_list, bi);
2079 err = brcmf_inform_single_bss(cfg_priv, bi);
2080 if (err)
2081 break;
2082 }
2083 return err;
2084 }
2085
2086 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2087 struct net_device *ndev, const u8 *bssid)
2088 {
2089 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2090 struct ieee80211_channel *notify_channel;
2091 struct brcmf_bss_info_le *bi = NULL;
2092 struct ieee80211_supported_band *band;
2093 struct cfg80211_bss *bss;
2094 u8 *buf = NULL;
2095 s32 err = 0;
2096 u16 channel;
2097 u32 freq;
2098 u16 notify_capability;
2099 u16 notify_interval;
2100 u8 *notify_ie;
2101 size_t notify_ielen;
2102 s32 notify_signal;
2103
2104 WL_TRACE("Enter\n");
2105
2106 buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2107 if (buf == NULL) {
2108 err = -ENOMEM;
2109 goto CleanUp;
2110 }
2111
2112 *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2113
2114 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2115 if (err) {
2116 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2117 goto CleanUp;
2118 }
2119
2120 bi = (struct brcmf_bss_info_le *)(buf + 4);
2121
2122 channel = bi->ctl_ch ? bi->ctl_ch :
2123 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2124
2125 if (channel <= CH_MAX_2G_CHANNEL)
2126 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2127 else
2128 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2129
2130 freq = ieee80211_channel_to_frequency(channel, band->band);
2131 notify_channel = ieee80211_get_channel(wiphy, freq);
2132
2133 notify_capability = le16_to_cpu(bi->capability);
2134 notify_interval = le16_to_cpu(bi->beacon_period);
2135 notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2136 notify_ielen = le32_to_cpu(bi->ie_length);
2137 notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2138
2139 WL_CONN("channel: %d(%d)\n", channel, freq);
2140 WL_CONN("capability: %X\n", notify_capability);
2141 WL_CONN("beacon interval: %d\n", notify_interval);
2142 WL_CONN("signal: %d\n", notify_signal);
2143
2144 bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2145 0, notify_capability, notify_interval,
2146 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2147
2148 if (!bss) {
2149 err = -ENOMEM;
2150 goto CleanUp;
2151 }
2152
2153 cfg80211_put_bss(bss);
2154
2155 CleanUp:
2156
2157 kfree(buf);
2158
2159 WL_TRACE("Exit\n");
2160
2161 return err;
2162 }
2163
2164 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2165 {
2166 return cfg_priv->conf->mode == WL_MODE_IBSS;
2167 }
2168
2169 /*
2170 * Traverse a string of 1-byte tag/1-byte length/variable-length value
2171 * triples, returning a pointer to the substring whose first element
2172 * matches tag
2173 */
2174 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2175 {
2176 struct brcmf_tlv *elt;
2177 int totlen;
2178
2179 elt = (struct brcmf_tlv *) buf;
2180 totlen = buflen;
2181
2182 /* find tagged parameter */
2183 while (totlen >= 2) {
2184 int len = elt->len;
2185
2186 /* validate remaining totlen */
2187 if ((elt->id == key) && (totlen >= (len + 2)))
2188 return elt;
2189
2190 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + 2));
2191 totlen -= (len + 2);
2192 }
2193
2194 return NULL;
2195 }
2196
2197 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2198 {
2199 struct brcmf_bss_info_le *bi;
2200 struct brcmf_ssid *ssid;
2201 struct brcmf_tlv *tim;
2202 u16 beacon_interval;
2203 u8 dtim_period;
2204 size_t ie_len;
2205 u8 *ie;
2206 s32 err = 0;
2207
2208 WL_TRACE("Enter\n");
2209 if (brcmf_is_ibssmode(cfg_priv))
2210 return err;
2211
2212 ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2213
2214 *(__le32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2215 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2216 cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2217 if (err) {
2218 WL_ERR("Could not get bss info %d\n", err);
2219 goto update_bss_info_out;
2220 }
2221
2222 bi = (struct brcmf_bss_info_le *)(cfg_priv->extra_buf + 4);
2223 err = brcmf_inform_single_bss(cfg_priv, bi);
2224 if (err)
2225 goto update_bss_info_out;
2226
2227 ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2228 ie_len = le32_to_cpu(bi->ie_length);
2229 beacon_interval = le16_to_cpu(bi->beacon_period);
2230
2231 tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2232 if (tim)
2233 dtim_period = tim->data[1];
2234 else {
2235 /*
2236 * active scan was done so we could not get dtim
2237 * information out of probe response.
2238 * so we speficially query dtim information to dongle.
2239 */
2240 u32 var;
2241 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2242 "dtim_assoc", &var);
2243 if (err) {
2244 WL_ERR("wl dtim_assoc failed (%d)\n", err);
2245 goto update_bss_info_out;
2246 }
2247 dtim_period = (u8)var;
2248 }
2249
2250 brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2251 brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2252
2253 update_bss_info_out:
2254 WL_TRACE("Exit");
2255 return err;
2256 }
2257
2258 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2259 {
2260 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2261 struct brcmf_ssid ssid;
2262
2263 if (cfg_priv->iscan_on) {
2264 iscan->state = WL_ISCAN_STATE_IDLE;
2265
2266 if (iscan->timer_on) {
2267 del_timer_sync(&iscan->timer);
2268 iscan->timer_on = 0;
2269 }
2270
2271 cancel_work_sync(&iscan->work);
2272
2273 /* Abort iscan running in FW */
2274 memset(&ssid, 0, sizeof(ssid));
2275 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2276 }
2277 }
2278
2279 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2280 bool aborted)
2281 {
2282 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2283 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2284
2285 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
2286 WL_ERR("Scan complete while device not scanning\n");
2287 return;
2288 }
2289 if (cfg_priv->scan_request) {
2290 WL_SCAN("ISCAN Completed scan: %s\n",
2291 aborted ? "Aborted" : "Done");
2292 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2293 brcmf_set_mpc(ndev, 1);
2294 cfg_priv->scan_request = NULL;
2295 }
2296 cfg_priv->iscan_kickstart = false;
2297 }
2298
2299 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2300 {
2301 if (iscan->state != WL_ISCAN_STATE_IDLE) {
2302 WL_SCAN("wake up iscan\n");
2303 schedule_work(&iscan->work);
2304 return 0;
2305 }
2306
2307 return -EIO;
2308 }
2309
2310 static s32
2311 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2312 struct brcmf_scan_results **bss_list)
2313 {
2314 struct brcmf_iscan_results list;
2315 struct brcmf_scan_results *results;
2316 struct brcmf_scan_results_le *results_le;
2317 struct brcmf_iscan_results *list_buf;
2318 s32 err = 0;
2319
2320 memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2321 list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2322 results = &list_buf->results;
2323 results_le = &list_buf->results_le;
2324 results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2325 results->version = 0;
2326 results->count = 0;
2327
2328 memset(&list, 0, sizeof(list));
2329 list.results_le.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2330 err = brcmf_dev_iovar_getbuf(iscan->ndev, "iscanresults", &list,
2331 BRCMF_ISCAN_RESULTS_FIXED_SIZE,
2332 iscan->scan_buf, WL_ISCAN_BUF_MAX);
2333 if (err) {
2334 WL_ERR("error (%d)\n", err);
2335 return err;
2336 }
2337 results->buflen = le32_to_cpu(results_le->buflen);
2338 results->version = le32_to_cpu(results_le->version);
2339 results->count = le32_to_cpu(results_le->count);
2340 WL_SCAN("results->count = %d\n", results_le->count);
2341 WL_SCAN("results->buflen = %d\n", results_le->buflen);
2342 *status = le32_to_cpu(list_buf->status_le);
2343 WL_SCAN("status = %d\n", *status);
2344 *bss_list = results;
2345
2346 return err;
2347 }
2348
2349 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2350 {
2351 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2352 s32 err = 0;
2353
2354 iscan->state = WL_ISCAN_STATE_IDLE;
2355 brcmf_inform_bss(cfg_priv);
2356 brcmf_notify_iscan_complete(iscan, false);
2357
2358 return err;
2359 }
2360
2361 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2362 {
2363 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2364 s32 err = 0;
2365
2366 /* Reschedule the timer */
2367 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2368 iscan->timer_on = 1;
2369
2370 return err;
2371 }
2372
2373 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2374 {
2375 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2376 s32 err = 0;
2377
2378 brcmf_inform_bss(cfg_priv);
2379 brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2380 /* Reschedule the timer */
2381 mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2382 iscan->timer_on = 1;
2383
2384 return err;
2385 }
2386
2387 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2388 {
2389 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2390 s32 err = 0;
2391
2392 iscan->state = WL_ISCAN_STATE_IDLE;
2393 brcmf_notify_iscan_complete(iscan, true);
2394
2395 return err;
2396 }
2397
2398 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2399 {
2400 struct brcmf_cfg80211_iscan_ctrl *iscan =
2401 container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2402 work);
2403 struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2404 struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2405 u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2406
2407 if (iscan->timer_on) {
2408 del_timer_sync(&iscan->timer);
2409 iscan->timer_on = 0;
2410 }
2411
2412 if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2413 status = BRCMF_SCAN_RESULTS_ABORTED;
2414 WL_ERR("Abort iscan\n");
2415 }
2416
2417 el->handler[status](cfg_priv);
2418 }
2419
2420 static void brcmf_iscan_timer(unsigned long data)
2421 {
2422 struct brcmf_cfg80211_iscan_ctrl *iscan =
2423 (struct brcmf_cfg80211_iscan_ctrl *)data;
2424
2425 if (iscan) {
2426 iscan->timer_on = 0;
2427 WL_SCAN("timer expired\n");
2428 brcmf_wakeup_iscan(iscan);
2429 }
2430 }
2431
2432 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2433 {
2434 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2435
2436 if (cfg_priv->iscan_on) {
2437 iscan->state = WL_ISCAN_STATE_IDLE;
2438 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2439 }
2440
2441 return 0;
2442 }
2443
2444 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2445 {
2446 memset(el, 0, sizeof(*el));
2447 el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2448 el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2449 el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2450 el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2451 el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2452 }
2453
2454 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2455 {
2456 struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2457 int err = 0;
2458
2459 if (cfg_priv->iscan_on) {
2460 iscan->ndev = cfg_to_ndev(cfg_priv);
2461 brcmf_init_iscan_eloop(&iscan->el);
2462 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2463 init_timer(&iscan->timer);
2464 iscan->timer.data = (unsigned long) iscan;
2465 iscan->timer.function = brcmf_iscan_timer;
2466 err = brcmf_invoke_iscan(cfg_priv);
2467 if (!err)
2468 iscan->data = cfg_priv;
2469 }
2470
2471 return err;
2472 }
2473
2474 static __always_inline void brcmf_delay(u32 ms)
2475 {
2476 if (ms < 1000 / HZ) {
2477 cond_resched();
2478 mdelay(ms);
2479 } else {
2480 msleep(ms);
2481 }
2482 }
2483
2484 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2485 {
2486 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2487
2488 /*
2489 * Check for WL_STATUS_READY before any function call which
2490 * could result is bus access. Don't block the resume for
2491 * any driver error conditions
2492 */
2493 WL_TRACE("Enter\n");
2494
2495 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2496 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2497
2498 WL_TRACE("Exit\n");
2499 return 0;
2500 }
2501
2502 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2503 struct cfg80211_wowlan *wow)
2504 {
2505 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2506 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2507
2508 WL_TRACE("Enter\n");
2509
2510 /*
2511 * Check for WL_STATUS_READY before any function call which
2512 * could result is bus access. Don't block the suspend for
2513 * any driver error conditions
2514 */
2515
2516 /*
2517 * While going to suspend if associated with AP disassociate
2518 * from AP to save power while system is in suspended state
2519 */
2520 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2521 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2522 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2523 WL_INFO("Disassociating from AP"
2524 " while entering suspend state\n");
2525 brcmf_link_down(cfg_priv);
2526
2527 /*
2528 * Make sure WPA_Supplicant receives all the event
2529 * generated due to DISASSOC call to the fw to keep
2530 * the state fw and WPA_Supplicant state consistent
2531 */
2532 brcmf_delay(500);
2533 }
2534
2535 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2536 if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2537 brcmf_term_iscan(cfg_priv);
2538
2539 if (cfg_priv->scan_request) {
2540 /* Indidate scan abort to cfg80211 layer */
2541 WL_INFO("Terminating scan in progress\n");
2542 cfg80211_scan_done(cfg_priv->scan_request, true);
2543 cfg_priv->scan_request = NULL;
2544 }
2545 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2546 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2547
2548 /* Turn off watchdog timer */
2549 if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2550 WL_INFO("Enable MPC\n");
2551 brcmf_set_mpc(ndev, 1);
2552 }
2553
2554 WL_TRACE("Exit\n");
2555
2556 return 0;
2557 }
2558
2559 static __used s32
2560 brcmf_dev_bufvar_set(struct net_device *ndev, s8 *name, s8 *buf, s32 len)
2561 {
2562 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2563 u32 buflen;
2564
2565 buflen = brcmf_c_mkiovar(name, buf, len, cfg_priv->dcmd_buf,
2566 WL_DCMD_LEN_MAX);
2567 BUG_ON(!buflen);
2568
2569 return brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, cfg_priv->dcmd_buf,
2570 buflen);
2571 }
2572
2573 static s32
2574 brcmf_dev_bufvar_get(struct net_device *ndev, s8 *name, s8 *buf,
2575 s32 buf_len)
2576 {
2577 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
2578 u32 len;
2579 s32 err = 0;
2580
2581 len = brcmf_c_mkiovar(name, NULL, 0, cfg_priv->dcmd_buf,
2582 WL_DCMD_LEN_MAX);
2583 BUG_ON(!len);
2584 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, cfg_priv->dcmd_buf,
2585 WL_DCMD_LEN_MAX);
2586 if (err) {
2587 WL_ERR("error (%d)\n", err);
2588 return err;
2589 }
2590 memcpy(buf, cfg_priv->dcmd_buf, buf_len);
2591
2592 return err;
2593 }
2594
2595 static __used s32
2596 brcmf_update_pmklist(struct net_device *ndev,
2597 struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2598 {
2599 int i, j;
2600 int pmkid_len;
2601
2602 pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2603
2604 WL_CONN("No of elements %d\n", pmkid_len);
2605 for (i = 0; i < pmkid_len; i++) {
2606 WL_CONN("PMKID[%d]: %pM =\n", i,
2607 &pmk_list->pmkids.pmkid[i].BSSID);
2608 for (j = 0; j < WLAN_PMKID_LEN; j++)
2609 WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2610 }
2611
2612 if (!err)
2613 brcmf_dev_bufvar_set(ndev, "pmkid_info", (char *)pmk_list,
2614 sizeof(*pmk_list));
2615
2616 return err;
2617 }
2618
2619 static s32
2620 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2621 struct cfg80211_pmksa *pmksa)
2622 {
2623 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2624 struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2625 s32 err = 0;
2626 int i;
2627 int pmkid_len;
2628
2629 WL_TRACE("Enter\n");
2630 if (!check_sys_up(wiphy))
2631 return -EIO;
2632
2633 pmkid_len = le32_to_cpu(pmkids->npmkid);
2634 for (i = 0; i < pmkid_len; i++)
2635 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2636 break;
2637 if (i < WL_NUM_PMKIDS_MAX) {
2638 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2639 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2640 if (i == pmkid_len) {
2641 pmkid_len++;
2642 pmkids->npmkid = cpu_to_le32(pmkid_len);
2643 }
2644 } else
2645 err = -EINVAL;
2646
2647 WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2648 pmkids->pmkid[pmkid_len].BSSID);
2649 for (i = 0; i < WLAN_PMKID_LEN; i++)
2650 WL_CONN("%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2651
2652 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2653
2654 WL_TRACE("Exit\n");
2655 return err;
2656 }
2657
2658 static s32
2659 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2660 struct cfg80211_pmksa *pmksa)
2661 {
2662 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2663 struct pmkid_list pmkid;
2664 s32 err = 0;
2665 int i, pmkid_len;
2666
2667 WL_TRACE("Enter\n");
2668 if (!check_sys_up(wiphy))
2669 return -EIO;
2670
2671 memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2672 memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2673
2674 WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2675 &pmkid.pmkid[0].BSSID);
2676 for (i = 0; i < WLAN_PMKID_LEN; i++)
2677 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2678
2679 pmkid_len = le32_to_cpu(cfg_priv->pmk_list->pmkids.npmkid);
2680 for (i = 0; i < pmkid_len; i++)
2681 if (!memcmp
2682 (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2683 ETH_ALEN))
2684 break;
2685
2686 if ((pmkid_len > 0)
2687 && (i < pmkid_len)) {
2688 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2689 sizeof(struct pmkid));
2690 for (; i < (pmkid_len - 1); i++) {
2691 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2692 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2693 ETH_ALEN);
2694 memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2695 &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2696 WLAN_PMKID_LEN);
2697 }
2698 cfg_priv->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2699 } else
2700 err = -EINVAL;
2701
2702 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2703
2704 WL_TRACE("Exit\n");
2705 return err;
2706
2707 }
2708
2709 static s32
2710 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2711 {
2712 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2713 s32 err = 0;
2714
2715 WL_TRACE("Enter\n");
2716 if (!check_sys_up(wiphy))
2717 return -EIO;
2718
2719 memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2720 err = brcmf_update_pmklist(ndev, cfg_priv->pmk_list, err);
2721
2722 WL_TRACE("Exit\n");
2723 return err;
2724
2725 }
2726
2727 #ifdef CONFIG_NL80211_TESTMODE
2728 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
2729 {
2730 struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2731 struct net_device *ndev = cfg_priv->wdev->netdev;
2732 struct brcmf_dcmd *dcmd = data;
2733 struct sk_buff *reply;
2734 int ret;
2735
2736 ret = brcmf_netlink_dcmd(ndev, dcmd);
2737 if (ret == 0) {
2738 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
2739 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
2740 ret = cfg80211_testmode_reply(reply);
2741 }
2742 return ret;
2743 }
2744 #endif
2745
2746 static struct cfg80211_ops wl_cfg80211_ops = {
2747 .change_virtual_intf = brcmf_cfg80211_change_iface,
2748 .scan = brcmf_cfg80211_scan,
2749 .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2750 .join_ibss = brcmf_cfg80211_join_ibss,
2751 .leave_ibss = brcmf_cfg80211_leave_ibss,
2752 .get_station = brcmf_cfg80211_get_station,
2753 .set_tx_power = brcmf_cfg80211_set_tx_power,
2754 .get_tx_power = brcmf_cfg80211_get_tx_power,
2755 .add_key = brcmf_cfg80211_add_key,
2756 .del_key = brcmf_cfg80211_del_key,
2757 .get_key = brcmf_cfg80211_get_key,
2758 .set_default_key = brcmf_cfg80211_config_default_key,
2759 .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2760 .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2761 .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2762 .connect = brcmf_cfg80211_connect,
2763 .disconnect = brcmf_cfg80211_disconnect,
2764 .suspend = brcmf_cfg80211_suspend,
2765 .resume = brcmf_cfg80211_resume,
2766 .set_pmksa = brcmf_cfg80211_set_pmksa,
2767 .del_pmksa = brcmf_cfg80211_del_pmksa,
2768 .flush_pmksa = brcmf_cfg80211_flush_pmksa,
2769 #ifdef CONFIG_NL80211_TESTMODE
2770 .testmode_cmd = brcmf_cfg80211_testmode
2771 #endif
2772 };
2773
2774 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2775 {
2776 s32 err = 0;
2777
2778 switch (mode) {
2779 case WL_MODE_BSS:
2780 return NL80211_IFTYPE_STATION;
2781 case WL_MODE_IBSS:
2782 return NL80211_IFTYPE_ADHOC;
2783 default:
2784 return NL80211_IFTYPE_UNSPECIFIED;
2785 }
2786
2787 return err;
2788 }
2789
2790 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2791 struct device *ndev)
2792 {
2793 struct wireless_dev *wdev;
2794 s32 err = 0;
2795
2796 wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2797 if (!wdev)
2798 return ERR_PTR(-ENOMEM);
2799
2800 wdev->wiphy =
2801 wiphy_new(&wl_cfg80211_ops,
2802 sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2803 if (!wdev->wiphy) {
2804 WL_ERR("Could not allocate wiphy device\n");
2805 err = -ENOMEM;
2806 goto wiphy_new_out;
2807 }
2808 set_wiphy_dev(wdev->wiphy, ndev);
2809 wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2810 wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2811 wdev->wiphy->interface_modes =
2812 BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2813 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2814 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a; /* Set
2815 * it as 11a by default.
2816 * This will be updated with
2817 * 11n phy tables in
2818 * "ifconfig up"
2819 * if phy has 11n capability
2820 */
2821 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2822 wdev->wiphy->cipher_suites = __wl_cipher_suites;
2823 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2824 wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT; /* enable power
2825 * save mode
2826 * by default
2827 */
2828 err = wiphy_register(wdev->wiphy);
2829 if (err < 0) {
2830 WL_ERR("Could not register wiphy device (%d)\n", err);
2831 goto wiphy_register_out;
2832 }
2833 return wdev;
2834
2835 wiphy_register_out:
2836 wiphy_free(wdev->wiphy);
2837
2838 wiphy_new_out:
2839 kfree(wdev);
2840
2841 return ERR_PTR(err);
2842 }
2843
2844 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2845 {
2846 struct wireless_dev *wdev = cfg_priv->wdev;
2847
2848 if (!wdev) {
2849 WL_ERR("wdev is invalid\n");
2850 return;
2851 }
2852 wiphy_unregister(wdev->wiphy);
2853 wiphy_free(wdev->wiphy);
2854 kfree(wdev);
2855 cfg_priv->wdev = NULL;
2856 }
2857
2858 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2859 const struct brcmf_event_msg *e)
2860 {
2861 u32 event = be32_to_cpu(e->event_type);
2862 u32 status = be32_to_cpu(e->status);
2863
2864 if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2865 WL_CONN("Processing set ssid\n");
2866 cfg_priv->link_up = true;
2867 return true;
2868 }
2869
2870 return false;
2871 }
2872
2873 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2874 const struct brcmf_event_msg *e)
2875 {
2876 u32 event = be32_to_cpu(e->event_type);
2877 u16 flags = be16_to_cpu(e->flags);
2878
2879 if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2880 WL_CONN("Processing link down\n");
2881 return true;
2882 }
2883 return false;
2884 }
2885
2886 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2887 const struct brcmf_event_msg *e)
2888 {
2889 u32 event = be32_to_cpu(e->event_type);
2890 u32 status = be32_to_cpu(e->status);
2891
2892 if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2893 WL_CONN("Processing Link %s & no network found\n",
2894 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2895 "up" : "down");
2896 return true;
2897 }
2898
2899 if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2900 WL_CONN("Processing connecting & no network found\n");
2901 return true;
2902 }
2903
2904 return false;
2905 }
2906
2907 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2908 {
2909 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2910
2911 kfree(conn_info->req_ie);
2912 conn_info->req_ie = NULL;
2913 conn_info->req_ie_len = 0;
2914 kfree(conn_info->resp_ie);
2915 conn_info->resp_ie = NULL;
2916 conn_info->resp_ie_len = 0;
2917 }
2918
2919 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2920 {
2921 struct net_device *ndev = cfg_to_ndev(cfg_priv);
2922 struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
2923 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2924 u32 req_len;
2925 u32 resp_len;
2926 s32 err = 0;
2927
2928 brcmf_clear_assoc_ies(cfg_priv);
2929
2930 err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2931 WL_ASSOC_INFO_MAX);
2932 if (err) {
2933 WL_ERR("could not get assoc info (%d)\n", err);
2934 return err;
2935 }
2936 assoc_info =
2937 (struct brcmf_cfg80211_assoc_ielen_le *)cfg_priv->extra_buf;
2938 req_len = le32_to_cpu(assoc_info->req_len);
2939 resp_len = le32_to_cpu(assoc_info->resp_len);
2940 if (req_len) {
2941 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2942 cfg_priv->extra_buf,
2943 WL_ASSOC_INFO_MAX);
2944 if (err) {
2945 WL_ERR("could not get assoc req (%d)\n", err);
2946 return err;
2947 }
2948 conn_info->req_ie_len = req_len;
2949 conn_info->req_ie =
2950 kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2951 GFP_KERNEL);
2952 } else {
2953 conn_info->req_ie_len = 0;
2954 conn_info->req_ie = NULL;
2955 }
2956 if (resp_len) {
2957 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2958 cfg_priv->extra_buf,
2959 WL_ASSOC_INFO_MAX);
2960 if (err) {
2961 WL_ERR("could not get assoc resp (%d)\n", err);
2962 return err;
2963 }
2964 conn_info->resp_ie_len = resp_len;
2965 conn_info->resp_ie =
2966 kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2967 GFP_KERNEL);
2968 } else {
2969 conn_info->resp_ie_len = 0;
2970 conn_info->resp_ie = NULL;
2971 }
2972 WL_CONN("req len (%d) resp len (%d)\n",
2973 conn_info->req_ie_len, conn_info->resp_ie_len);
2974
2975 return err;
2976 }
2977
2978 static s32
2979 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2980 struct net_device *ndev,
2981 const struct brcmf_event_msg *e)
2982 {
2983 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2984 struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2985 struct brcmf_channel_info_le channel_le;
2986 struct ieee80211_channel *notify_channel;
2987 struct ieee80211_supported_band *band;
2988 u32 freq;
2989 s32 err = 0;
2990 u32 target_channel;
2991
2992 WL_TRACE("Enter\n");
2993
2994 brcmf_get_assoc_ies(cfg_priv);
2995 brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2996 brcmf_update_bss_info(cfg_priv);
2997
2998 brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2999 sizeof(channel_le));
3000
3001 target_channel = le32_to_cpu(channel_le.target_channel);
3002 WL_CONN("Roamed to channel %d\n", target_channel);
3003
3004 if (target_channel <= CH_MAX_2G_CHANNEL)
3005 band = wiphy->bands[IEEE80211_BAND_2GHZ];
3006 else
3007 band = wiphy->bands[IEEE80211_BAND_5GHZ];
3008
3009 freq = ieee80211_channel_to_frequency(target_channel, band->band);
3010 notify_channel = ieee80211_get_channel(wiphy, freq);
3011
3012 cfg80211_roamed(ndev, notify_channel,
3013 (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
3014 conn_info->req_ie, conn_info->req_ie_len,
3015 conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
3016 WL_CONN("Report roaming result\n");
3017
3018 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3019 WL_TRACE("Exit\n");
3020 return err;
3021 }
3022
3023 static s32
3024 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
3025 struct net_device *ndev, const struct brcmf_event_msg *e,
3026 bool completed)
3027 {
3028 struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
3029 s32 err = 0;
3030
3031 WL_TRACE("Enter\n");
3032
3033 if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
3034 if (completed) {
3035 brcmf_get_assoc_ies(cfg_priv);
3036 brcmf_update_prof(cfg_priv, NULL, &e->addr,
3037 WL_PROF_BSSID);
3038 brcmf_update_bss_info(cfg_priv);
3039 }
3040 cfg80211_connect_result(ndev,
3041 (u8 *)brcmf_read_prof(cfg_priv,
3042 WL_PROF_BSSID),
3043 conn_info->req_ie,
3044 conn_info->req_ie_len,
3045 conn_info->resp_ie,
3046 conn_info->resp_ie_len,
3047 completed ? WLAN_STATUS_SUCCESS :
3048 WLAN_STATUS_AUTH_TIMEOUT,
3049 GFP_KERNEL);
3050 if (completed)
3051 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3052 WL_CONN("Report connect result - connection %s\n",
3053 completed ? "succeeded" : "failed");
3054 }
3055 WL_TRACE("Exit\n");
3056 return err;
3057 }
3058
3059 static s32
3060 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
3061 struct net_device *ndev,
3062 const struct brcmf_event_msg *e, void *data)
3063 {
3064 s32 err = 0;
3065
3066 if (brcmf_is_linkup(cfg_priv, e)) {
3067 WL_CONN("Linkup\n");
3068 if (brcmf_is_ibssmode(cfg_priv)) {
3069 brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
3070 WL_PROF_BSSID);
3071 wl_inform_ibss(cfg_priv, ndev, e->addr);
3072 cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
3073 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3074 set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
3075 } else
3076 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3077 } else if (brcmf_is_linkdown(cfg_priv, e)) {
3078 WL_CONN("Linkdown\n");
3079 if (brcmf_is_ibssmode(cfg_priv)) {
3080 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3081 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3082 &cfg_priv->status))
3083 brcmf_link_down(cfg_priv);
3084 } else {
3085 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3086 if (test_and_clear_bit(WL_STATUS_CONNECTED,
3087 &cfg_priv->status)) {
3088 cfg80211_disconnected(ndev, 0, NULL, 0,
3089 GFP_KERNEL);
3090 brcmf_link_down(cfg_priv);
3091 }
3092 }
3093 brcmf_init_prof(cfg_priv->profile);
3094 } else if (brcmf_is_nonetwork(cfg_priv, e)) {
3095 if (brcmf_is_ibssmode(cfg_priv))
3096 clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
3097 else
3098 brcmf_bss_connect_done(cfg_priv, ndev, e, false);
3099 }
3100
3101 return err;
3102 }
3103
3104 static s32
3105 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
3106 struct net_device *ndev,
3107 const struct brcmf_event_msg *e, void *data)
3108 {
3109 s32 err = 0;
3110 u32 event = be32_to_cpu(e->event_type);
3111 u32 status = be32_to_cpu(e->status);
3112
3113 if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
3114 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
3115 brcmf_bss_roaming_done(cfg_priv, ndev, e);
3116 else
3117 brcmf_bss_connect_done(cfg_priv, ndev, e, true);
3118 }
3119
3120 return err;
3121 }
3122
3123 static s32
3124 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
3125 struct net_device *ndev,
3126 const struct brcmf_event_msg *e, void *data)
3127 {
3128 u16 flags = be16_to_cpu(e->flags);
3129 enum nl80211_key_type key_type;
3130
3131 if (flags & BRCMF_EVENT_MSG_GROUP)
3132 key_type = NL80211_KEYTYPE_GROUP;
3133 else
3134 key_type = NL80211_KEYTYPE_PAIRWISE;
3135
3136 cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3137 NULL, GFP_KERNEL);
3138
3139 return 0;
3140 }
3141
3142 static s32
3143 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3144 struct net_device *ndev,
3145 const struct brcmf_event_msg *e, void *data)
3146 {
3147 struct brcmf_channel_info_le channel_inform_le;
3148 struct brcmf_scan_results_le *bss_list_le;
3149 u32 len = WL_SCAN_BUF_MAX;
3150 s32 err = 0;
3151 bool scan_abort = false;
3152 u32 scan_channel;
3153
3154 WL_TRACE("Enter\n");
3155
3156 if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3157 WL_TRACE("Exit\n");
3158 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3159 }
3160
3161 if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3162 WL_ERR("Scan complete while device not scanning\n");
3163 scan_abort = true;
3164 err = -EINVAL;
3165 goto scan_done_out;
3166 }
3167
3168 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3169 sizeof(channel_inform_le));
3170 if (err) {
3171 WL_ERR("scan busy (%d)\n", err);
3172 scan_abort = true;
3173 goto scan_done_out;
3174 }
3175 scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3176 if (scan_channel)
3177 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3178 cfg_priv->bss_list = cfg_priv->scan_results;
3179 bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3180
3181 memset(cfg_priv->scan_results, 0, len);
3182 bss_list_le->buflen = cpu_to_le32(len);
3183 err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3184 cfg_priv->scan_results, len);
3185 if (err) {
3186 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3187 err = -EINVAL;
3188 scan_abort = true;
3189 goto scan_done_out;
3190 }
3191 cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3192 cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3193 cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3194
3195 err = brcmf_inform_bss(cfg_priv);
3196 if (err) {
3197 scan_abort = true;
3198 goto scan_done_out;
3199 }
3200
3201 scan_done_out:
3202 if (cfg_priv->scan_request) {
3203 WL_SCAN("calling cfg80211_scan_done\n");
3204 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3205 brcmf_set_mpc(ndev, 1);
3206 cfg_priv->scan_request = NULL;
3207 }
3208
3209 WL_TRACE("Exit\n");
3210
3211 return err;
3212 }
3213
3214 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3215 {
3216 conf->mode = (u32)-1;
3217 conf->frag_threshold = (u32)-1;
3218 conf->rts_threshold = (u32)-1;
3219 conf->retry_short = (u32)-1;
3220 conf->retry_long = (u32)-1;
3221 conf->tx_power = -1;
3222 }
3223
3224 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3225 {
3226 memset(el, 0, sizeof(*el));
3227 el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3228 el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3229 el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3230 el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3231 el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3232 }
3233
3234 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3235 {
3236 kfree(cfg_priv->scan_results);
3237 cfg_priv->scan_results = NULL;
3238 kfree(cfg_priv->bss_info);
3239 cfg_priv->bss_info = NULL;
3240 kfree(cfg_priv->conf);
3241 cfg_priv->conf = NULL;
3242 kfree(cfg_priv->profile);
3243 cfg_priv->profile = NULL;
3244 kfree(cfg_priv->scan_req_int);
3245 cfg_priv->scan_req_int = NULL;
3246 kfree(cfg_priv->dcmd_buf);
3247 cfg_priv->dcmd_buf = NULL;
3248 kfree(cfg_priv->extra_buf);
3249 cfg_priv->extra_buf = NULL;
3250 kfree(cfg_priv->iscan);
3251 cfg_priv->iscan = NULL;
3252 kfree(cfg_priv->pmk_list);
3253 cfg_priv->pmk_list = NULL;
3254 }
3255
3256 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3257 {
3258 cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3259 if (!cfg_priv->scan_results)
3260 goto init_priv_mem_out;
3261 cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3262 if (!cfg_priv->conf)
3263 goto init_priv_mem_out;
3264 cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3265 if (!cfg_priv->profile)
3266 goto init_priv_mem_out;
3267 cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3268 if (!cfg_priv->bss_info)
3269 goto init_priv_mem_out;
3270 cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3271 GFP_KERNEL);
3272 if (!cfg_priv->scan_req_int)
3273 goto init_priv_mem_out;
3274 cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3275 if (!cfg_priv->dcmd_buf)
3276 goto init_priv_mem_out;
3277 cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3278 if (!cfg_priv->extra_buf)
3279 goto init_priv_mem_out;
3280 cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3281 if (!cfg_priv->iscan)
3282 goto init_priv_mem_out;
3283 cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3284 if (!cfg_priv->pmk_list)
3285 goto init_priv_mem_out;
3286
3287 return 0;
3288
3289 init_priv_mem_out:
3290 brcmf_deinit_priv_mem(cfg_priv);
3291
3292 return -ENOMEM;
3293 }
3294
3295 /*
3296 * retrieve first queued event from head
3297 */
3298
3299 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3300 struct brcmf_cfg80211_priv *cfg_priv)
3301 {
3302 struct brcmf_cfg80211_event_q *e = NULL;
3303
3304 spin_lock_irq(&cfg_priv->evt_q_lock);
3305 if (!list_empty(&cfg_priv->evt_q_list)) {
3306 e = list_first_entry(&cfg_priv->evt_q_list,
3307 struct brcmf_cfg80211_event_q, evt_q_list);
3308 list_del(&e->evt_q_list);
3309 }
3310 spin_unlock_irq(&cfg_priv->evt_q_lock);
3311
3312 return e;
3313 }
3314
3315 /*
3316 * push event to tail of the queue
3317 *
3318 * remark: this function may not sleep as it is called in atomic context.
3319 */
3320
3321 static s32
3322 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3323 const struct brcmf_event_msg *msg)
3324 {
3325 struct brcmf_cfg80211_event_q *e;
3326 s32 err = 0;
3327 ulong flags;
3328
3329 e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_ATOMIC);
3330 if (!e)
3331 return -ENOMEM;
3332
3333 e->etype = event;
3334 memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3335
3336 spin_lock_irqsave(&cfg_priv->evt_q_lock, flags);
3337 list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3338 spin_unlock_irqrestore(&cfg_priv->evt_q_lock, flags);
3339
3340 return err;
3341 }
3342
3343 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3344 {
3345 kfree(e);
3346 }
3347
3348 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3349 {
3350 struct brcmf_cfg80211_priv *cfg_priv =
3351 container_of(work, struct brcmf_cfg80211_priv,
3352 event_work);
3353 struct brcmf_cfg80211_event_q *e;
3354
3355 e = brcmf_deq_event(cfg_priv);
3356 if (unlikely(!e)) {
3357 WL_ERR("event queue empty...\n");
3358 return;
3359 }
3360
3361 do {
3362 WL_INFO("event type (%d)\n", e->etype);
3363 if (cfg_priv->el.handler[e->etype])
3364 cfg_priv->el.handler[e->etype](cfg_priv,
3365 cfg_to_ndev(cfg_priv),
3366 &e->emsg, e->edata);
3367 else
3368 WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3369 brcmf_put_event(e);
3370 } while ((e = brcmf_deq_event(cfg_priv)));
3371
3372 }
3373
3374 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3375 {
3376 spin_lock_init(&cfg_priv->evt_q_lock);
3377 INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3378 }
3379
3380 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3381 {
3382 struct brcmf_cfg80211_event_q *e;
3383
3384 spin_lock_irq(&cfg_priv->evt_q_lock);
3385 while (!list_empty(&cfg_priv->evt_q_list)) {
3386 e = list_first_entry(&cfg_priv->evt_q_list,
3387 struct brcmf_cfg80211_event_q, evt_q_list);
3388 list_del(&e->evt_q_list);
3389 kfree(e);
3390 }
3391 spin_unlock_irq(&cfg_priv->evt_q_lock);
3392 }
3393
3394 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3395 {
3396 s32 err = 0;
3397
3398 cfg_priv->scan_request = NULL;
3399 cfg_priv->pwr_save = true;
3400 cfg_priv->iscan_on = true; /* iscan on & off switch.
3401 we enable iscan per default */
3402 cfg_priv->roam_on = true; /* roam on & off switch.
3403 we enable roam per default */
3404
3405 cfg_priv->iscan_kickstart = false;
3406 cfg_priv->active_scan = true; /* we do active scan for
3407 specific scan per default */
3408 cfg_priv->dongle_up = false; /* dongle is not up yet */
3409 brcmf_init_eq(cfg_priv);
3410 err = brcmf_init_priv_mem(cfg_priv);
3411 if (err)
3412 return err;
3413 INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3414 brcmf_init_eloop_handler(&cfg_priv->el);
3415 mutex_init(&cfg_priv->usr_sync);
3416 err = brcmf_init_iscan(cfg_priv);
3417 if (err)
3418 return err;
3419 brcmf_init_conf(cfg_priv->conf);
3420 brcmf_init_prof(cfg_priv->profile);
3421 brcmf_link_down(cfg_priv);
3422
3423 return err;
3424 }
3425
3426 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3427 {
3428 cancel_work_sync(&cfg_priv->event_work);
3429 cfg_priv->dongle_up = false; /* dongle down */
3430 brcmf_flush_eq(cfg_priv);
3431 brcmf_link_down(cfg_priv);
3432 brcmf_term_iscan(cfg_priv);
3433 brcmf_deinit_priv_mem(cfg_priv);
3434 }
3435
3436 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3437 struct device *busdev,
3438 void *data)
3439 {
3440 struct wireless_dev *wdev;
3441 struct brcmf_cfg80211_priv *cfg_priv;
3442 struct brcmf_cfg80211_iface *ci;
3443 struct brcmf_cfg80211_dev *cfg_dev;
3444 s32 err = 0;
3445
3446 if (!ndev) {
3447 WL_ERR("ndev is invalid\n");
3448 return NULL;
3449 }
3450 cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3451 if (!cfg_dev)
3452 return NULL;
3453
3454 wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3455 if (IS_ERR(wdev)) {
3456 kfree(cfg_dev);
3457 return NULL;
3458 }
3459
3460 wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3461 cfg_priv = wdev_to_cfg(wdev);
3462 cfg_priv->wdev = wdev;
3463 cfg_priv->pub = data;
3464 ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3465 ci->cfg_priv = cfg_priv;
3466 ndev->ieee80211_ptr = wdev;
3467 SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3468 wdev->netdev = ndev;
3469 err = wl_init_priv(cfg_priv);
3470 if (err) {
3471 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3472 goto cfg80211_attach_out;
3473 }
3474 brcmf_set_drvdata(cfg_dev, ci);
3475
3476 return cfg_dev;
3477
3478 cfg80211_attach_out:
3479 brcmf_free_wdev(cfg_priv);
3480 kfree(cfg_dev);
3481 return NULL;
3482 }
3483
3484 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3485 {
3486 struct brcmf_cfg80211_priv *cfg_priv;
3487
3488 cfg_priv = brcmf_priv_get(cfg_dev);
3489
3490 wl_deinit_priv(cfg_priv);
3491 brcmf_free_wdev(cfg_priv);
3492 brcmf_set_drvdata(cfg_dev, NULL);
3493 kfree(cfg_dev);
3494 }
3495
3496 void
3497 brcmf_cfg80211_event(struct net_device *ndev,
3498 const struct brcmf_event_msg *e, void *data)
3499 {
3500 u32 event_type = be32_to_cpu(e->event_type);
3501 struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3502
3503 if (!brcmf_enq_event(cfg_priv, event_type, e))
3504 schedule_work(&cfg_priv->event_work);
3505 }
3506
3507 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3508 {
3509 s32 infra = 0;
3510 s32 err = 0;
3511
3512 switch (iftype) {
3513 case NL80211_IFTYPE_MONITOR:
3514 case NL80211_IFTYPE_WDS:
3515 WL_ERR("type (%d) : currently we do not support this mode\n",
3516 iftype);
3517 err = -EINVAL;
3518 return err;
3519 case NL80211_IFTYPE_ADHOC:
3520 infra = 0;
3521 break;
3522 case NL80211_IFTYPE_STATION:
3523 infra = 1;
3524 break;
3525 default:
3526 err = -EINVAL;
3527 WL_ERR("invalid type (%d)\n", iftype);
3528 return err;
3529 }
3530 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3531 if (err) {
3532 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3533 return err;
3534 }
3535
3536 return 0;
3537 }
3538
3539 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3540 {
3541 /* Room for "event_msgs" + '\0' + bitvec */
3542 s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3543 s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3544 s32 err = 0;
3545
3546 WL_TRACE("Enter\n");
3547
3548 /* Setup event_msgs */
3549 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3550 iovbuf, sizeof(iovbuf));
3551 err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3552 if (err) {
3553 WL_ERR("Get event_msgs error (%d)\n", err);
3554 goto dongle_eventmsg_out;
3555 }
3556 memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3557
3558 setbit(eventmask, BRCMF_E_SET_SSID);
3559 setbit(eventmask, BRCMF_E_ROAM);
3560 setbit(eventmask, BRCMF_E_PRUNE);
3561 setbit(eventmask, BRCMF_E_AUTH);
3562 setbit(eventmask, BRCMF_E_REASSOC);
3563 setbit(eventmask, BRCMF_E_REASSOC_IND);
3564 setbit(eventmask, BRCMF_E_DEAUTH_IND);
3565 setbit(eventmask, BRCMF_E_DISASSOC_IND);
3566 setbit(eventmask, BRCMF_E_DISASSOC);
3567 setbit(eventmask, BRCMF_E_JOIN);
3568 setbit(eventmask, BRCMF_E_ASSOC_IND);
3569 setbit(eventmask, BRCMF_E_PSK_SUP);
3570 setbit(eventmask, BRCMF_E_LINK);
3571 setbit(eventmask, BRCMF_E_NDIS_LINK);
3572 setbit(eventmask, BRCMF_E_MIC_ERROR);
3573 setbit(eventmask, BRCMF_E_PMKID_CACHE);
3574 setbit(eventmask, BRCMF_E_TXFAIL);
3575 setbit(eventmask, BRCMF_E_JOIN_START);
3576 setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3577
3578 brcmf_c_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN,
3579 iovbuf, sizeof(iovbuf));
3580 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3581 if (err) {
3582 WL_ERR("Set event_msgs error (%d)\n", err);
3583 goto dongle_eventmsg_out;
3584 }
3585
3586 dongle_eventmsg_out:
3587 WL_TRACE("Exit\n");
3588 return err;
3589 }
3590
3591 static s32
3592 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3593 {
3594 s8 iovbuf[32];
3595 s32 err = 0;
3596 __le32 roamtrigger[2];
3597 __le32 roam_delta[2];
3598 __le32 bcn_to_le;
3599 __le32 roamvar_le;
3600
3601 /*
3602 * Setup timeout if Beacons are lost and roam is
3603 * off to report link down
3604 */
3605 if (roamvar) {
3606 bcn_to_le = cpu_to_le32(bcn_timeout);
3607 brcmf_c_mkiovar("bcn_timeout", (char *)&bcn_to_le,
3608 sizeof(bcn_to_le), iovbuf, sizeof(iovbuf));
3609 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3610 iovbuf, sizeof(iovbuf));
3611 if (err) {
3612 WL_ERR("bcn_timeout error (%d)\n", err);
3613 goto dongle_rom_out;
3614 }
3615 }
3616
3617 /*
3618 * Enable/Disable built-in roaming to allow supplicant
3619 * to take care of roaming
3620 */
3621 WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3622 roamvar_le = cpu_to_le32(roamvar);
3623 brcmf_c_mkiovar("roam_off", (char *)&roamvar_le,
3624 sizeof(roamvar_le), iovbuf, sizeof(iovbuf));
3625 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3626 if (err) {
3627 WL_ERR("roam_off error (%d)\n", err);
3628 goto dongle_rom_out;
3629 }
3630
3631 roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
3632 roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
3633 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3634 (void *)roamtrigger, sizeof(roamtrigger));
3635 if (err) {
3636 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3637 goto dongle_rom_out;
3638 }
3639
3640 roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
3641 roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
3642 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3643 (void *)roam_delta, sizeof(roam_delta));
3644 if (err) {
3645 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3646 goto dongle_rom_out;
3647 }
3648
3649 dongle_rom_out:
3650 return err;
3651 }
3652
3653 static s32
3654 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3655 s32 scan_unassoc_time, s32 scan_passive_time)
3656 {
3657 s32 err = 0;
3658 __le32 scan_assoc_tm_le = cpu_to_le32(scan_assoc_time);
3659 __le32 scan_unassoc_tm_le = cpu_to_le32(scan_unassoc_time);
3660 __le32 scan_passive_tm_le = cpu_to_le32(scan_passive_time);
3661
3662 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3663 &scan_assoc_tm_le, sizeof(scan_assoc_tm_le));
3664 if (err) {
3665 if (err == -EOPNOTSUPP)
3666 WL_INFO("Scan assoc time is not supported\n");
3667 else
3668 WL_ERR("Scan assoc time error (%d)\n", err);
3669 goto dongle_scantime_out;
3670 }
3671 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3672 &scan_unassoc_tm_le, sizeof(scan_unassoc_tm_le));
3673 if (err) {
3674 if (err == -EOPNOTSUPP)
3675 WL_INFO("Scan unassoc time is not supported\n");
3676 else
3677 WL_ERR("Scan unassoc time error (%d)\n", err);
3678 goto dongle_scantime_out;
3679 }
3680
3681 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3682 &scan_passive_tm_le, sizeof(scan_passive_tm_le));
3683 if (err) {
3684 if (err == -EOPNOTSUPP)
3685 WL_INFO("Scan passive time is not supported\n");
3686 else
3687 WL_ERR("Scan passive time error (%d)\n", err);
3688 goto dongle_scantime_out;
3689 }
3690
3691 dongle_scantime_out:
3692 return err;
3693 }
3694
3695 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3696 {
3697 struct wiphy *wiphy;
3698 s32 phy_list;
3699 s8 phy;
3700 s32 err = 0;
3701
3702 err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3703 &phy_list, sizeof(phy_list));
3704 if (err) {
3705 WL_ERR("error (%d)\n", err);
3706 return err;
3707 }
3708
3709 phy = ((char *)&phy_list)[1];
3710 WL_INFO("%c phy\n", phy);
3711 if (phy == 'n' || phy == 'a') {
3712 wiphy = cfg_to_wiphy(cfg_priv);
3713 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3714 }
3715
3716 return err;
3717 }
3718
3719 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3720 {
3721 return wl_update_wiphybands(cfg_priv);
3722 }
3723
3724 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3725 {
3726 struct net_device *ndev;
3727 struct wireless_dev *wdev;
3728 s32 power_mode;
3729 s32 err = 0;
3730
3731 if (cfg_priv->dongle_up)
3732 return err;
3733
3734 ndev = cfg_to_ndev(cfg_priv);
3735 wdev = ndev->ieee80211_ptr;
3736
3737 brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3738 WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3739
3740 err = brcmf_dongle_eventmsg(ndev);
3741 if (err)
3742 goto default_conf_out;
3743
3744 power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3745 err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3746 if (err)
3747 goto default_conf_out;
3748 WL_INFO("power save set to %s\n",
3749 (power_mode ? "enabled" : "disabled"));
3750
3751 err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3752 WL_BEACON_TIMEOUT);
3753 if (err)
3754 goto default_conf_out;
3755 err = brcmf_dongle_mode(ndev, wdev->iftype);
3756 if (err && err != -EINPROGRESS)
3757 goto default_conf_out;
3758 err = brcmf_dongle_probecap(cfg_priv);
3759 if (err)
3760 goto default_conf_out;
3761
3762 /* -EINPROGRESS: Call commit handler */
3763
3764 default_conf_out:
3765
3766 cfg_priv->dongle_up = true;
3767
3768 return err;
3769
3770 }
3771
3772 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3773 {
3774 char buf[10+IFNAMSIZ];
3775 struct dentry *fd;
3776 s32 err = 0;
3777
3778 sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3779 cfg_priv->debugfsdir = debugfs_create_dir(buf,
3780 cfg_to_wiphy(cfg_priv)->debugfsdir);
3781
3782 fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3783 (u16 *)&cfg_priv->profile->beacon_interval);
3784 if (!fd) {
3785 err = -ENOMEM;
3786 goto err_out;
3787 }
3788
3789 fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3790 (u8 *)&cfg_priv->profile->dtim_period);
3791 if (!fd) {
3792 err = -ENOMEM;
3793 goto err_out;
3794 }
3795
3796 err_out:
3797 return err;
3798 }
3799
3800 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3801 {
3802 debugfs_remove_recursive(cfg_priv->debugfsdir);
3803 cfg_priv->debugfsdir = NULL;
3804 }
3805
3806 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3807 {
3808 s32 err = 0;
3809
3810 set_bit(WL_STATUS_READY, &cfg_priv->status);
3811
3812 brcmf_debugfs_add_netdev_params(cfg_priv);
3813
3814 err = brcmf_config_dongle(cfg_priv);
3815 if (err)
3816 return err;
3817
3818 brcmf_invoke_iscan(cfg_priv);
3819
3820 return err;
3821 }
3822
3823 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3824 {
3825 /*
3826 * While going down, if associated with AP disassociate
3827 * from AP to save power
3828 */
3829 if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3830 test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3831 test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3832 WL_INFO("Disassociating from AP");
3833 brcmf_link_down(cfg_priv);
3834
3835 /* Make sure WPA_Supplicant receives all the event
3836 generated due to DISASSOC call to the fw to keep
3837 the state fw and WPA_Supplicant state consistent
3838 */
3839 brcmf_delay(500);
3840 }
3841
3842 set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3843 brcmf_term_iscan(cfg_priv);
3844 if (cfg_priv->scan_request) {
3845 cfg80211_scan_done(cfg_priv->scan_request, true);
3846 /* May need to perform this to cover rmmod */
3847 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3848 cfg_priv->scan_request = NULL;
3849 }
3850 clear_bit(WL_STATUS_READY, &cfg_priv->status);
3851 clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3852 clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3853
3854 brcmf_debugfs_remove_netdev(cfg_priv);
3855
3856 return 0;
3857 }
3858
3859 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3860 {
3861 struct brcmf_cfg80211_priv *cfg_priv;
3862 s32 err = 0;
3863
3864 cfg_priv = brcmf_priv_get(cfg_dev);
3865 mutex_lock(&cfg_priv->usr_sync);
3866 err = __brcmf_cfg80211_up(cfg_priv);
3867 mutex_unlock(&cfg_priv->usr_sync);
3868
3869 return err;
3870 }
3871
3872 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3873 {
3874 struct brcmf_cfg80211_priv *cfg_priv;
3875 s32 err = 0;
3876
3877 cfg_priv = brcmf_priv_get(cfg_dev);
3878 mutex_lock(&cfg_priv->usr_sync);
3879 err = __brcmf_cfg80211_down(cfg_priv);
3880 mutex_unlock(&cfg_priv->usr_sync);
3881
3882 return err;
3883 }
3884
3885 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3886 u8 t, u8 l, u8 *v)
3887 {
3888 struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3889 s32 err = 0;
3890
3891 if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3892 WL_ERR("ei crosses buffer boundary\n");
3893 return -ENOSPC;
3894 }
3895 ie->buf[ie->offset] = t;
3896 ie->buf[ie->offset + 1] = l;
3897 memcpy(&ie->buf[ie->offset + 2], v, l);
3898 ie->offset += l + 2;
3899
3900 return err;
3901 }
This page took 0.212299 seconds and 5 git commands to generate.