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