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