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