]> git.karo-electronics.de Git - mv-sheeva.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
9e69cd725d59ba53b1772d8fc90b3de94f28e16a
[mv-sheeva.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 *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 = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2785         req_len = assoc_info->req_len;
2786         resp_len = assoc_info->resp_len;
2787         if (req_len) {
2788                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2789                                            cfg_priv->extra_buf,
2790                                            WL_ASSOC_INFO_MAX);
2791                 if (err) {
2792                         WL_ERR("could not get assoc req (%d)\n", err);
2793                         return err;
2794                 }
2795                 conn_info->req_ie_len = req_len;
2796                 conn_info->req_ie =
2797                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2798                             GFP_KERNEL);
2799         } else {
2800                 conn_info->req_ie_len = 0;
2801                 conn_info->req_ie = NULL;
2802         }
2803         if (resp_len) {
2804                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2805                                            cfg_priv->extra_buf,
2806                                            WL_ASSOC_INFO_MAX);
2807                 if (err) {
2808                         WL_ERR("could not get assoc resp (%d)\n", err);
2809                         return err;
2810                 }
2811                 conn_info->resp_ie_len = resp_len;
2812                 conn_info->resp_ie =
2813                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2814                             GFP_KERNEL);
2815         } else {
2816                 conn_info->resp_ie_len = 0;
2817                 conn_info->resp_ie = NULL;
2818         }
2819         WL_CONN("req len (%d) resp len (%d)\n",
2820                conn_info->req_ie_len, conn_info->resp_ie_len);
2821
2822         return err;
2823 }
2824
2825 static s32
2826 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2827                        struct net_device *ndev,
2828                        const struct brcmf_event_msg *e)
2829 {
2830         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2831         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2832         struct brcmf_channel_info_le channel_le;
2833         struct ieee80211_channel *notify_channel;
2834         struct ieee80211_supported_band *band;
2835         u32 freq;
2836         s32 err = 0;
2837         u32 target_channel;
2838
2839         WL_TRACE("Enter\n");
2840
2841         brcmf_get_assoc_ies(cfg_priv);
2842         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2843         brcmf_update_bss_info(cfg_priv);
2844
2845         brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_le,
2846                         sizeof(channel_le));
2847
2848         target_channel = le32_to_cpu(channel_le.target_channel);
2849         WL_CONN("Roamed to channel %d\n", target_channel);
2850
2851         if (target_channel <= CH_MAX_2G_CHANNEL)
2852                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2853         else
2854                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2855
2856         freq = ieee80211_channel_to_frequency(target_channel, band->band);
2857         notify_channel = ieee80211_get_channel(wiphy, freq);
2858
2859         cfg80211_roamed(ndev, notify_channel,
2860                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2861                         conn_info->req_ie, conn_info->req_ie_len,
2862                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2863         WL_CONN("Report roaming result\n");
2864
2865         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2866         WL_TRACE("Exit\n");
2867         return err;
2868 }
2869
2870 static s32
2871 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2872                        struct net_device *ndev, const struct brcmf_event_msg *e,
2873                        bool completed)
2874 {
2875         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2876         s32 err = 0;
2877
2878         WL_TRACE("Enter\n");
2879
2880         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2881                 if (completed) {
2882                         brcmf_get_assoc_ies(cfg_priv);
2883                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
2884                                           WL_PROF_BSSID);
2885                         brcmf_update_bss_info(cfg_priv);
2886                 }
2887                 cfg80211_connect_result(ndev,
2888                                         (u8 *)brcmf_read_prof(cfg_priv,
2889                                                               WL_PROF_BSSID),
2890                                         conn_info->req_ie,
2891                                         conn_info->req_ie_len,
2892                                         conn_info->resp_ie,
2893                                         conn_info->resp_ie_len,
2894                                         completed ? WLAN_STATUS_SUCCESS :
2895                                                     WLAN_STATUS_AUTH_TIMEOUT,
2896                                         GFP_KERNEL);
2897                 if (completed)
2898                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2899                 WL_CONN("Report connect result - connection %s\n",
2900                                 completed ? "succeeded" : "failed");
2901         }
2902         WL_TRACE("Exit\n");
2903         return err;
2904 }
2905
2906 static s32
2907 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2908                             struct net_device *ndev,
2909                             const struct brcmf_event_msg *e, void *data)
2910 {
2911         s32 err = 0;
2912
2913         if (brcmf_is_linkup(cfg_priv, e)) {
2914                 WL_CONN("Linkup\n");
2915                 if (brcmf_is_ibssmode(cfg_priv)) {
2916                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2917                                 WL_PROF_BSSID);
2918                         wl_inform_ibss(cfg_priv, ndev, e->addr);
2919                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2920                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2921                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2922                 } else
2923                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2924         } else if (brcmf_is_linkdown(cfg_priv, e)) {
2925                 WL_CONN("Linkdown\n");
2926                 if (brcmf_is_ibssmode(cfg_priv)) {
2927                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2928                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2929                                 &cfg_priv->status))
2930                                 brcmf_link_down(cfg_priv);
2931                 } else {
2932                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2933                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2934                                 &cfg_priv->status)) {
2935                                 cfg80211_disconnected(ndev, 0, NULL, 0,
2936                                         GFP_KERNEL);
2937                                 brcmf_link_down(cfg_priv);
2938                         }
2939                 }
2940                 brcmf_init_prof(cfg_priv->profile);
2941         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2942                 if (brcmf_is_ibssmode(cfg_priv))
2943                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2944                 else
2945                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2946         }
2947
2948         return err;
2949 }
2950
2951 static s32
2952 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2953                             struct net_device *ndev,
2954                             const struct brcmf_event_msg *e, void *data)
2955 {
2956         s32 err = 0;
2957         u32 event = be32_to_cpu(e->event_type);
2958         u32 status = be32_to_cpu(e->status);
2959
2960         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2961                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2962                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
2963                 else
2964                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2965         }
2966
2967         return err;
2968 }
2969
2970 static s32
2971 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2972                         struct net_device *ndev,
2973                         const struct brcmf_event_msg *e, void *data)
2974 {
2975         u16 flags = be16_to_cpu(e->flags);
2976         enum nl80211_key_type key_type;
2977
2978         if (flags & BRCMF_EVENT_MSG_GROUP)
2979                 key_type = NL80211_KEYTYPE_GROUP;
2980         else
2981                 key_type = NL80211_KEYTYPE_PAIRWISE;
2982
2983         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
2984                                      NULL, GFP_KERNEL);
2985
2986         return 0;
2987 }
2988
2989 static s32
2990 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
2991                          struct net_device *ndev,
2992                          const struct brcmf_event_msg *e, void *data)
2993 {
2994         struct brcmf_channel_info_le channel_inform_le;
2995         struct brcmf_scan_results_le *bss_list_le;
2996         u32 len = WL_SCAN_BUF_MAX;
2997         s32 err = 0;
2998         bool scan_abort = false;
2999         u32 scan_channel;
3000
3001         WL_TRACE("Enter\n");
3002
3003         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3004                 WL_TRACE("Exit\n");
3005                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3006         }
3007
3008         if (!test_and_clear_bit(WL_STATUS_SCANNING, &cfg_priv->status)) {
3009                 WL_ERR("Scan complete while device not scanning\n");
3010                 scan_abort = true;
3011                 err = -EINVAL;
3012                 goto scan_done_out;
3013         }
3014
3015         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_CHANNEL, &channel_inform_le,
3016                               sizeof(channel_inform_le));
3017         if (err) {
3018                 WL_ERR("scan busy (%d)\n", err);
3019                 scan_abort = true;
3020                 goto scan_done_out;
3021         }
3022         scan_channel = le32_to_cpu(channel_inform_le.scan_channel);
3023         if (scan_channel)
3024                 WL_CONN("channel_inform.scan_channel (%d)\n", scan_channel);
3025         cfg_priv->bss_list = cfg_priv->scan_results;
3026         bss_list_le = (struct brcmf_scan_results_le *) cfg_priv->bss_list;
3027
3028         memset(cfg_priv->scan_results, 0, len);
3029         bss_list_le->buflen = cpu_to_le32(len);
3030         err = brcmf_exec_dcmd(ndev, BRCMF_C_SCAN_RESULTS,
3031                               cfg_priv->scan_results, len);
3032         if (err) {
3033                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3034                 err = -EINVAL;
3035                 scan_abort = true;
3036                 goto scan_done_out;
3037         }
3038         cfg_priv->scan_results->buflen = le32_to_cpu(bss_list_le->buflen);
3039         cfg_priv->scan_results->version = le32_to_cpu(bss_list_le->version);
3040         cfg_priv->scan_results->count = le32_to_cpu(bss_list_le->count);
3041
3042         err = brcmf_inform_bss(cfg_priv);
3043         if (err) {
3044                 scan_abort = true;
3045                 goto scan_done_out;
3046         }
3047
3048 scan_done_out:
3049         if (cfg_priv->scan_request) {
3050                 WL_SCAN("calling cfg80211_scan_done\n");
3051                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3052                 brcmf_set_mpc(ndev, 1);
3053                 cfg_priv->scan_request = NULL;
3054         }
3055
3056         WL_TRACE("Exit\n");
3057
3058         return err;
3059 }
3060
3061 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3062 {
3063         conf->mode = (u32)-1;
3064         conf->frag_threshold = (u32)-1;
3065         conf->rts_threshold = (u32)-1;
3066         conf->retry_short = (u32)-1;
3067         conf->retry_long = (u32)-1;
3068         conf->tx_power = -1;
3069 }
3070
3071 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3072 {
3073         memset(el, 0, sizeof(*el));
3074         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3075         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3076         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3077         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3078         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3079 }
3080
3081 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3082 {
3083         kfree(cfg_priv->scan_results);
3084         cfg_priv->scan_results = NULL;
3085         kfree(cfg_priv->bss_info);
3086         cfg_priv->bss_info = NULL;
3087         kfree(cfg_priv->conf);
3088         cfg_priv->conf = NULL;
3089         kfree(cfg_priv->profile);
3090         cfg_priv->profile = NULL;
3091         kfree(cfg_priv->scan_req_int);
3092         cfg_priv->scan_req_int = NULL;
3093         kfree(cfg_priv->dcmd_buf);
3094         cfg_priv->dcmd_buf = NULL;
3095         kfree(cfg_priv->extra_buf);
3096         cfg_priv->extra_buf = NULL;
3097         kfree(cfg_priv->iscan);
3098         cfg_priv->iscan = NULL;
3099         kfree(cfg_priv->pmk_list);
3100         cfg_priv->pmk_list = NULL;
3101 }
3102
3103 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3104 {
3105         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3106         if (!cfg_priv->scan_results)
3107                 goto init_priv_mem_out;
3108         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3109         if (!cfg_priv->conf)
3110                 goto init_priv_mem_out;
3111         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3112         if (!cfg_priv->profile)
3113                 goto init_priv_mem_out;
3114         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3115         if (!cfg_priv->bss_info)
3116                 goto init_priv_mem_out;
3117         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3118                                          GFP_KERNEL);
3119         if (!cfg_priv->scan_req_int)
3120                 goto init_priv_mem_out;
3121         cfg_priv->dcmd_buf = kzalloc(WL_DCMD_LEN_MAX, GFP_KERNEL);
3122         if (!cfg_priv->dcmd_buf)
3123                 goto init_priv_mem_out;
3124         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3125         if (!cfg_priv->extra_buf)
3126                 goto init_priv_mem_out;
3127         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3128         if (!cfg_priv->iscan)
3129                 goto init_priv_mem_out;
3130         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3131         if (!cfg_priv->pmk_list)
3132                 goto init_priv_mem_out;
3133
3134         return 0;
3135
3136 init_priv_mem_out:
3137         brcmf_deinit_priv_mem(cfg_priv);
3138
3139         return -ENOMEM;
3140 }
3141
3142 /*
3143 * retrieve first queued event from head
3144 */
3145
3146 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3147         struct brcmf_cfg80211_priv *cfg_priv)
3148 {
3149         struct brcmf_cfg80211_event_q *e = NULL;
3150
3151         spin_lock_irq(&cfg_priv->evt_q_lock);
3152         if (!list_empty(&cfg_priv->evt_q_list)) {
3153                 e = list_first_entry(&cfg_priv->evt_q_list,
3154                                      struct brcmf_cfg80211_event_q, evt_q_list);
3155                 list_del(&e->evt_q_list);
3156         }
3157         spin_unlock_irq(&cfg_priv->evt_q_lock);
3158
3159         return e;
3160 }
3161
3162 /*
3163 ** push event to tail of the queue
3164 */
3165
3166 static s32
3167 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3168                 const struct brcmf_event_msg *msg)
3169 {
3170         struct brcmf_cfg80211_event_q *e;
3171         s32 err = 0;
3172
3173         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3174         if (!e)
3175                 return -ENOMEM;
3176
3177         e->etype = event;
3178         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3179
3180         spin_lock_irq(&cfg_priv->evt_q_lock);
3181         list_add_tail(&e->evt_q_list, &cfg_priv->evt_q_list);
3182         spin_unlock_irq(&cfg_priv->evt_q_lock);
3183
3184         return err;
3185 }
3186
3187 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3188 {
3189         kfree(e);
3190 }
3191
3192 static void brcmf_cfg80211_event_handler(struct work_struct *work)
3193 {
3194         struct brcmf_cfg80211_priv *cfg_priv =
3195                         container_of(work, struct brcmf_cfg80211_priv,
3196                                      event_work);
3197         struct brcmf_cfg80211_event_q *e;
3198
3199         e = brcmf_deq_event(cfg_priv);
3200         if (unlikely(!e)) {
3201                 WL_ERR("event queue empty...\n");
3202                 return;
3203         }
3204
3205         do {
3206                 WL_INFO("event type (%d)\n", e->etype);
3207                 if (cfg_priv->el.handler[e->etype])
3208                         cfg_priv->el.handler[e->etype](cfg_priv,
3209                                                        cfg_to_ndev(cfg_priv),
3210                                                        &e->emsg, e->edata);
3211                 else
3212                         WL_INFO("Unknown Event (%d): ignoring\n", e->etype);
3213                 brcmf_put_event(e);
3214         } while ((e = brcmf_deq_event(cfg_priv)));
3215
3216 }
3217
3218 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3219 {
3220         spin_lock_init(&cfg_priv->evt_q_lock);
3221         INIT_LIST_HEAD(&cfg_priv->evt_q_list);
3222 }
3223
3224 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3225 {
3226         struct brcmf_cfg80211_event_q *e;
3227
3228         spin_lock_irq(&cfg_priv->evt_q_lock);
3229         while (!list_empty(&cfg_priv->evt_q_list)) {
3230                 e = list_first_entry(&cfg_priv->evt_q_list,
3231                                      struct brcmf_cfg80211_event_q, evt_q_list);
3232                 list_del(&e->evt_q_list);
3233                 kfree(e);
3234         }
3235         spin_unlock_irq(&cfg_priv->evt_q_lock);
3236 }
3237
3238 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3239 {
3240         s32 err = 0;
3241
3242         cfg_priv->scan_request = NULL;
3243         cfg_priv->pwr_save = true;
3244         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3245                                  we enable iscan per default */
3246         cfg_priv->roam_on = true;       /* roam on & off switch.
3247                                  we enable roam per default */
3248
3249         cfg_priv->iscan_kickstart = false;
3250         cfg_priv->active_scan = true;   /* we do active scan for
3251                                  specific scan per default */
3252         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3253         brcmf_init_eq(cfg_priv);
3254         err = brcmf_init_priv_mem(cfg_priv);
3255         if (err)
3256                 return err;
3257         INIT_WORK(&cfg_priv->event_work, brcmf_cfg80211_event_handler);
3258         brcmf_init_eloop_handler(&cfg_priv->el);
3259         mutex_init(&cfg_priv->usr_sync);
3260         err = brcmf_init_iscan(cfg_priv);
3261         if (err)
3262                 return err;
3263         brcmf_init_conf(cfg_priv->conf);
3264         brcmf_init_prof(cfg_priv->profile);
3265         brcmf_link_down(cfg_priv);
3266
3267         return err;
3268 }
3269
3270 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3271 {
3272         cancel_work_sync(&cfg_priv->event_work);
3273         cfg_priv->dongle_up = false;    /* dongle down */
3274         brcmf_flush_eq(cfg_priv);
3275         brcmf_link_down(cfg_priv);
3276         brcmf_term_iscan(cfg_priv);
3277         brcmf_deinit_priv_mem(cfg_priv);
3278 }
3279
3280 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3281                                                  struct device *busdev,
3282                                                  void *data)
3283 {
3284         struct wireless_dev *wdev;
3285         struct brcmf_cfg80211_priv *cfg_priv;
3286         struct brcmf_cfg80211_iface *ci;
3287         struct brcmf_cfg80211_dev *cfg_dev;
3288         s32 err = 0;
3289
3290         if (!ndev) {
3291                 WL_ERR("ndev is invalid\n");
3292                 return NULL;
3293         }
3294         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3295         if (!cfg_dev)
3296                 return NULL;
3297
3298         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3299         if (IS_ERR(wdev)) {
3300                 kfree(cfg_dev);
3301                 return NULL;
3302         }
3303
3304         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3305         cfg_priv = wdev_to_cfg(wdev);
3306         cfg_priv->wdev = wdev;
3307         cfg_priv->pub = data;
3308         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3309         ci->cfg_priv = cfg_priv;
3310         ndev->ieee80211_ptr = wdev;
3311         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3312         wdev->netdev = ndev;
3313         err = wl_init_priv(cfg_priv);
3314         if (err) {
3315                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3316                 goto cfg80211_attach_out;
3317         }
3318         brcmf_set_drvdata(cfg_dev, ci);
3319
3320         return cfg_dev;
3321
3322 cfg80211_attach_out:
3323         brcmf_free_wdev(cfg_priv);
3324         kfree(cfg_dev);
3325         return NULL;
3326 }
3327
3328 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3329 {
3330         struct brcmf_cfg80211_priv *cfg_priv;
3331
3332         cfg_priv = brcmf_priv_get(cfg_dev);
3333
3334         wl_deinit_priv(cfg_priv);
3335         brcmf_free_wdev(cfg_priv);
3336         brcmf_set_drvdata(cfg_dev, NULL);
3337         kfree(cfg_dev);
3338 }
3339
3340 void
3341 brcmf_cfg80211_event(struct net_device *ndev,
3342                   const struct brcmf_event_msg *e, void *data)
3343 {
3344         u32 event_type = be32_to_cpu(e->event_type);
3345         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3346
3347         if (!brcmf_enq_event(cfg_priv, event_type, e))
3348                 schedule_work(&cfg_priv->event_work);
3349 }
3350
3351 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3352 {
3353         s32 infra = 0;
3354         s32 err = 0;
3355
3356         switch (iftype) {
3357         case NL80211_IFTYPE_MONITOR:
3358         case NL80211_IFTYPE_WDS:
3359                 WL_ERR("type (%d) : currently we do not support this mode\n",
3360                        iftype);
3361                 err = -EINVAL;
3362                 return err;
3363         case NL80211_IFTYPE_ADHOC:
3364                 infra = 0;
3365                 break;
3366         case NL80211_IFTYPE_STATION:
3367                 infra = 1;
3368                 break;
3369         default:
3370                 err = -EINVAL;
3371                 WL_ERR("invalid type (%d)\n", iftype);
3372                 return err;
3373         }
3374         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3375         if (err) {
3376                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3377                 return err;
3378         }
3379
3380         return 0;
3381 }
3382
3383 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3384 {
3385         /* Room for "event_msgs" + '\0' + bitvec */
3386         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3387         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3388         s32 err = 0;
3389
3390         WL_TRACE("Enter\n");
3391
3392         /* Setup event_msgs */
3393         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3394                     sizeof(iovbuf));
3395         err = brcmf_exec_dcmd(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3396         if (err) {
3397                 WL_ERR("Get event_msgs error (%d)\n", err);
3398                 goto dongle_eventmsg_out;
3399         }
3400         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3401
3402         setbit(eventmask, BRCMF_E_SET_SSID);
3403         setbit(eventmask, BRCMF_E_ROAM);
3404         setbit(eventmask, BRCMF_E_PRUNE);
3405         setbit(eventmask, BRCMF_E_AUTH);
3406         setbit(eventmask, BRCMF_E_REASSOC);
3407         setbit(eventmask, BRCMF_E_REASSOC_IND);
3408         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3409         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3410         setbit(eventmask, BRCMF_E_DISASSOC);
3411         setbit(eventmask, BRCMF_E_JOIN);
3412         setbit(eventmask, BRCMF_E_ASSOC_IND);
3413         setbit(eventmask, BRCMF_E_PSK_SUP);
3414         setbit(eventmask, BRCMF_E_LINK);
3415         setbit(eventmask, BRCMF_E_NDIS_LINK);
3416         setbit(eventmask, BRCMF_E_MIC_ERROR);
3417         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3418         setbit(eventmask, BRCMF_E_TXFAIL);
3419         setbit(eventmask, BRCMF_E_JOIN_START);
3420         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3421
3422         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3423                     sizeof(iovbuf));
3424         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3425         if (err) {
3426                 WL_ERR("Set event_msgs error (%d)\n", err);
3427                 goto dongle_eventmsg_out;
3428         }
3429
3430 dongle_eventmsg_out:
3431         WL_TRACE("Exit\n");
3432         return err;
3433 }
3434
3435 static s32
3436 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3437 {
3438         s8 iovbuf[32];
3439         s32 roamtrigger[2];
3440         s32 roam_delta[2];
3441         s32 err = 0;
3442
3443         /*
3444          * Setup timeout if Beacons are lost and roam is
3445          * off to report link down
3446          */
3447         if (roamvar) {
3448                 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3449                         sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3450                 err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR,
3451                                    iovbuf, sizeof(iovbuf));
3452                 if (err) {
3453                         WL_ERR("bcn_timeout error (%d)\n", err);
3454                         goto dongle_rom_out;
3455                 }
3456         }
3457
3458         /*
3459          * Enable/Disable built-in roaming to allow supplicant
3460          * to take care of roaming
3461          */
3462         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3463         brcmu_mkiovar("roam_off", (char *)&roamvar,
3464                                 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3465         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3466         if (err) {
3467                 WL_ERR("roam_off error (%d)\n", err);
3468                 goto dongle_rom_out;
3469         }
3470
3471         roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3472         roamtrigger[1] = BRCM_BAND_ALL;
3473         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3474                         (void *)roamtrigger, sizeof(roamtrigger));
3475         if (err) {
3476                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3477                 goto dongle_rom_out;
3478         }
3479
3480         roam_delta[0] = WL_ROAM_DELTA;
3481         roam_delta[1] = BRCM_BAND_ALL;
3482         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_ROAM_DELTA,
3483                                 (void *)roam_delta, sizeof(roam_delta));
3484         if (err) {
3485                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3486                 goto dongle_rom_out;
3487         }
3488
3489 dongle_rom_out:
3490         return err;
3491 }
3492
3493 static s32
3494 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3495                 s32 scan_unassoc_time, s32 scan_passive_time)
3496 {
3497         s32 err = 0;
3498
3499         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3500                            &scan_assoc_time, sizeof(scan_assoc_time));
3501         if (err) {
3502                 if (err == -EOPNOTSUPP)
3503                         WL_INFO("Scan assoc time is not supported\n");
3504                 else
3505                         WL_ERR("Scan assoc time error (%d)\n", err);
3506                 goto dongle_scantime_out;
3507         }
3508         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3509                            &scan_unassoc_time, sizeof(scan_unassoc_time));
3510         if (err) {
3511                 if (err == -EOPNOTSUPP)
3512                         WL_INFO("Scan unassoc time is not supported\n");
3513                 else
3514                         WL_ERR("Scan unassoc time error (%d)\n", err);
3515                 goto dongle_scantime_out;
3516         }
3517
3518         err = brcmf_exec_dcmd(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3519                            &scan_passive_time, sizeof(scan_passive_time));
3520         if (err) {
3521                 if (err == -EOPNOTSUPP)
3522                         WL_INFO("Scan passive time is not supported\n");
3523                 else
3524                         WL_ERR("Scan passive time error (%d)\n", err);
3525                 goto dongle_scantime_out;
3526         }
3527
3528 dongle_scantime_out:
3529         return err;
3530 }
3531
3532 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3533 {
3534         struct wiphy *wiphy;
3535         s32 phy_list;
3536         s8 phy;
3537         s32 err = 0;
3538
3539         err = brcmf_exec_dcmd(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3540                               &phy_list, sizeof(phy_list));
3541         if (err) {
3542                 WL_ERR("error (%d)\n", err);
3543                 return err;
3544         }
3545
3546         phy = ((char *)&phy_list)[1];
3547         WL_INFO("%c phy\n", phy);
3548         if (phy == 'n' || phy == 'a') {
3549                 wiphy = cfg_to_wiphy(cfg_priv);
3550                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3551         }
3552
3553         return err;
3554 }
3555
3556 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3557 {
3558         return wl_update_wiphybands(cfg_priv);
3559 }
3560
3561 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv)
3562 {
3563         struct net_device *ndev;
3564         struct wireless_dev *wdev;
3565         s32 power_mode;
3566         s32 err = 0;
3567
3568         if (cfg_priv->dongle_up)
3569                 return err;
3570
3571         ndev = cfg_to_ndev(cfg_priv);
3572         wdev = ndev->ieee80211_ptr;
3573
3574         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3575                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3576
3577         err = brcmf_dongle_eventmsg(ndev);
3578         if (err)
3579                 goto default_conf_out;
3580
3581         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3582         err = brcmf_exec_dcmd_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3583         if (err)
3584                 goto default_conf_out;
3585         WL_INFO("power save set to %s\n",
3586                 (power_mode ? "enabled" : "disabled"));
3587
3588         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3589                                 WL_BEACON_TIMEOUT);
3590         if (err)
3591                 goto default_conf_out;
3592         err = brcmf_dongle_mode(ndev, wdev->iftype);
3593         if (err && err != -EINPROGRESS)
3594                 goto default_conf_out;
3595         err = brcmf_dongle_probecap(cfg_priv);
3596         if (err)
3597                 goto default_conf_out;
3598
3599         /* -EINPROGRESS: Call commit handler */
3600
3601 default_conf_out:
3602
3603         cfg_priv->dongle_up = true;
3604
3605         return err;
3606
3607 }
3608
3609 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3610 {
3611         char buf[10+IFNAMSIZ];
3612         struct dentry *fd;
3613         s32 err = 0;
3614
3615         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3616         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3617                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3618
3619         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3620                 (u16 *)&cfg_priv->profile->beacon_interval);
3621         if (!fd) {
3622                 err = -ENOMEM;
3623                 goto err_out;
3624         }
3625
3626         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3627                 (u8 *)&cfg_priv->profile->dtim_period);
3628         if (!fd) {
3629                 err = -ENOMEM;
3630                 goto err_out;
3631         }
3632
3633 err_out:
3634         return err;
3635 }
3636
3637 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3638 {
3639         debugfs_remove_recursive(cfg_priv->debugfsdir);
3640         cfg_priv->debugfsdir = NULL;
3641 }
3642
3643 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3644 {
3645         s32 err = 0;
3646
3647         set_bit(WL_STATUS_READY, &cfg_priv->status);
3648
3649         brcmf_debugfs_add_netdev_params(cfg_priv);
3650
3651         err = brcmf_config_dongle(cfg_priv);
3652         if (err)
3653                 return err;
3654
3655         brcmf_invoke_iscan(cfg_priv);
3656
3657         return err;
3658 }
3659
3660 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3661 {
3662         /*
3663          * While going down, if associated with AP disassociate
3664          * from AP to save power
3665          */
3666         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3667              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3668              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3669                 WL_INFO("Disassociating from AP");
3670                 brcmf_link_down(cfg_priv);
3671
3672                 /* Make sure WPA_Supplicant receives all the event
3673                    generated due to DISASSOC call to the fw to keep
3674                    the state fw and WPA_Supplicant state consistent
3675                  */
3676                 brcmf_delay(500);
3677         }
3678
3679         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3680         brcmf_term_iscan(cfg_priv);
3681         if (cfg_priv->scan_request) {
3682                 cfg80211_scan_done(cfg_priv->scan_request, true);
3683                 /* May need to perform this to cover rmmod */
3684                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3685                 cfg_priv->scan_request = NULL;
3686         }
3687         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3688         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3689         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3690
3691         brcmf_debugfs_remove_netdev(cfg_priv);
3692
3693         return 0;
3694 }
3695
3696 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3697 {
3698         struct brcmf_cfg80211_priv *cfg_priv;
3699         s32 err = 0;
3700
3701         cfg_priv = brcmf_priv_get(cfg_dev);
3702         mutex_lock(&cfg_priv->usr_sync);
3703         err = __brcmf_cfg80211_up(cfg_priv);
3704         mutex_unlock(&cfg_priv->usr_sync);
3705
3706         return err;
3707 }
3708
3709 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3710 {
3711         struct brcmf_cfg80211_priv *cfg_priv;
3712         s32 err = 0;
3713
3714         cfg_priv = brcmf_priv_get(cfg_dev);
3715         mutex_lock(&cfg_priv->usr_sync);
3716         err = __brcmf_cfg80211_down(cfg_priv);
3717         mutex_unlock(&cfg_priv->usr_sync);
3718
3719         return err;
3720 }
3721
3722 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3723                                u8 t, u8 l, u8 *v)
3724 {
3725         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3726         s32 err = 0;
3727
3728         if (ie->offset + l + 2 > WL_TLV_INFO_MAX) {
3729                 WL_ERR("ei crosses buffer boundary\n");
3730                 return -ENOSPC;
3731         }
3732         ie->buf[ie->offset] = t;
3733         ie->buf[ie->offset + 1] = l;
3734         memcpy(&ie->buf[ie->offset + 2], v, l);
3735         ie->offset += l + 2;
3736
3737         return err;
3738 }