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