staging: brcm80211: fixed sparse endianness warnings on fullmac assoc pars
[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 (unlikely(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 (unlikely(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                 s32 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 (unlikely(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 (unlikely(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 (unlikely(!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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (likely(!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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 = cpu_to_le32(params->beacon_interval);
894         else
895                 bcnprd = cpu_to_le32(100);
896
897         err = brcmf_dev_ioctl(dev, BRCM_SET_BCNPRD, &bcnprd, sizeof(bcnprd));
898         if (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(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 (unlikely(!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 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         scbval.val = reason_code;
1340         memcpy(&scbval.ea, brcmf_read_prof(cfg_priv, WL_PROF_BSSID), ETH_ALEN);
1341         scbval.val = cpu_to_le32(scbval.val);
1342         err = brcmf_dev_ioctl(dev, BRCMF_C_DISASSOC, &scbval,
1343                         sizeof(struct brcmf_scb_val));
1344         if (unlikely(err))
1345                 WL_ERR("error (%d)\n", err);
1346
1347         cfg_priv->link_up = false;
1348
1349         WL_TRACE("Exit\n");
1350         return err;
1351 }
1352
1353 static s32
1354 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy,
1355                          enum nl80211_tx_power_setting type, s32 dbm)
1356 {
1357
1358         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1359         struct net_device *ndev = cfg_to_ndev(cfg_priv);
1360         u16 txpwrmw;
1361         s32 err = 0;
1362         s32 disable = 0;
1363
1364         WL_TRACE("Enter\n");
1365         if (!check_sys_up(wiphy))
1366                 return -EIO;
1367
1368         switch (type) {
1369         case NL80211_TX_POWER_AUTOMATIC:
1370                 break;
1371         case NL80211_TX_POWER_LIMITED:
1372                 if (dbm < 0) {
1373                         WL_ERR("TX_POWER_LIMITED - dbm is negative\n");
1374                         err = -EINVAL;
1375                         goto done;
1376                 }
1377                 break;
1378         case NL80211_TX_POWER_FIXED:
1379                 if (dbm < 0) {
1380                         WL_ERR("TX_POWER_FIXED - dbm is negative\n");
1381                         err = -EINVAL;
1382                         goto done;
1383                 }
1384                 break;
1385         }
1386         /* Make sure radio is off or on as far as software is concerned */
1387         disable = WL_RADIO_SW_DISABLE << 16;
1388         err = brcmf_dev_ioctl_u32(ndev, BRCMF_C_SET_RADIO, &disable);
1389         if (unlikely(err))
1390                 WL_ERR("WLC_SET_RADIO error (%d)\n", err);
1391
1392         if (dbm > 0xffff)
1393                 txpwrmw = 0xffff;
1394         else
1395                 txpwrmw = (u16) dbm;
1396         err = brcmf_dev_intvar_set(ndev, "qtxpower",
1397                         (s32) (brcmu_mw_to_qdbm(txpwrmw)));
1398         if (unlikely(err))
1399                 WL_ERR("qtxpower error (%d)\n", err);
1400         cfg_priv->conf->tx_power = dbm;
1401
1402 done:
1403         WL_TRACE("Exit\n");
1404         return err;
1405 }
1406
1407 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy, s32 *dbm)
1408 {
1409         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1410         struct net_device *ndev = cfg_to_ndev(cfg_priv);
1411         s32 txpwrdbm;
1412         u8 result;
1413         s32 err = 0;
1414
1415         WL_TRACE("Enter\n");
1416         if (!check_sys_up(wiphy))
1417                 return -EIO;
1418
1419         err = brcmf_dev_intvar_get(ndev, "qtxpower", &txpwrdbm);
1420         if (unlikely(err)) {
1421                 WL_ERR("error (%d)\n", err);
1422                 goto done;
1423         }
1424
1425         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1426         *dbm = (s32) brcmu_qdbm_to_mw(result);
1427
1428 done:
1429         WL_TRACE("Exit\n");
1430         return err;
1431 }
1432
1433 static s32
1434 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *dev,
1435                                u8 key_idx, bool unicast, bool multicast)
1436 {
1437         u32 index;
1438         u32 wsec;
1439         s32 err = 0;
1440
1441         WL_TRACE("Enter\n");
1442         WL_CONN("key index (%d)\n", key_idx);
1443         if (!check_sys_up(wiphy))
1444                 return -EIO;
1445
1446         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_GET_WSEC, &wsec);
1447         if (unlikely(err)) {
1448                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1449                 goto done;
1450         }
1451
1452         if (wsec & WEP_ENABLED) {
1453                 /* Just select a new current key */
1454                 index = key_idx;
1455                 err = brcmf_dev_ioctl_u32(dev, BRCMF_C_SET_KEY_PRIMARY, &index);
1456                 if (unlikely(err))
1457                         WL_ERR("error (%d)\n", err);
1458         }
1459 done:
1460         WL_TRACE("Exit\n");
1461         return err;
1462 }
1463
1464 static s32
1465 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *dev,
1466               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1467 {
1468         struct brcmf_wsec_key key;
1469         struct brcmf_wsec_key_le key_le;
1470         s32 err = 0;
1471
1472         memset(&key, 0, sizeof(key));
1473         key.index = (u32) key_idx;
1474         /* Instead of bcast for ea address for default wep keys,
1475                  driver needs it to be Null */
1476         if (!is_multicast_ether_addr(mac_addr))
1477                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1478         key.len = (u32) params->key_len;
1479         /* check for key index change */
1480         if (key.len == 0) {
1481                 /* key delete */
1482                 err = send_key_to_dongle(dev, &key);
1483                 if (err)
1484                         return err;
1485         } else {
1486                 if (key.len > sizeof(key.data)) {
1487                         WL_ERR("Invalid key length (%d)\n", key.len);
1488                         return -EINVAL;
1489                 }
1490
1491                 WL_CONN("Setting the key index %d\n", key.index);
1492                 memcpy(key.data, params->key, key.len);
1493
1494                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1495                         u8 keybuf[8];
1496                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1497                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1498                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1499                 }
1500
1501                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1502                 if (params->seq && params->seq_len == 6) {
1503                         /* rx iv */
1504                         u8 *ivptr;
1505                         ivptr = (u8 *) params->seq;
1506                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1507                             (ivptr[3] << 8) | ivptr[2];
1508                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1509                         key.iv_initialized = true;
1510                 }
1511
1512                 switch (params->cipher) {
1513                 case WLAN_CIPHER_SUITE_WEP40:
1514                         key.algo = CRYPTO_ALGO_WEP1;
1515                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1516                         break;
1517                 case WLAN_CIPHER_SUITE_WEP104:
1518                         key.algo = CRYPTO_ALGO_WEP128;
1519                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1520                         break;
1521                 case WLAN_CIPHER_SUITE_TKIP:
1522                         key.algo = CRYPTO_ALGO_TKIP;
1523                         WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1524                         break;
1525                 case WLAN_CIPHER_SUITE_AES_CMAC:
1526                         key.algo = CRYPTO_ALGO_AES_CCM;
1527                         WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1528                         break;
1529                 case WLAN_CIPHER_SUITE_CCMP:
1530                         key.algo = CRYPTO_ALGO_AES_CCM;
1531                         WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1532                         break;
1533                 default:
1534                         WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1535                         return -EINVAL;
1536                 }
1537                 convert_key_from_CPU(&key, &key_le);
1538
1539                 brcmf_netdev_wait_pend8021x(dev);
1540                 err = brcmf_dev_ioctl(dev, BRCMF_C_SET_KEY, &key_le,
1541                                       sizeof(key_le));
1542                 if (unlikely(err)) {
1543                         WL_ERR("WLC_SET_KEY error (%d)\n", err);
1544                         return err;
1545                 }
1546         }
1547         return err;
1548 }
1549
1550 static s32
1551 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *dev,
1552                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1553                     struct key_params *params)
1554 {
1555         struct brcmf_wsec_key key;
1556         s32 val;
1557         s32 wsec;
1558         s32 err = 0;
1559         u8 keybuf[8];
1560
1561         WL_TRACE("Enter\n");
1562         WL_CONN("key index (%d)\n", key_idx);
1563         if (!check_sys_up(wiphy))
1564                 return -EIO;
1565
1566         if (mac_addr) {
1567                 WL_TRACE("Exit");
1568                 return brcmf_add_keyext(wiphy, dev, key_idx, mac_addr, params);
1569         }
1570         memset(&key, 0, sizeof(key));
1571
1572         key.len = (u32) params->key_len;
1573         key.index = (u32) key_idx;
1574
1575         if (unlikely(key.len > sizeof(key.data))) {
1576                 WL_ERR("Too long key length (%u)\n", key.len);
1577                 err = -EINVAL;
1578                 goto done;
1579         }
1580         memcpy(key.data, params->key, key.len);
1581
1582         key.flags = BRCMF_PRIMARY_KEY;
1583         switch (params->cipher) {
1584         case WLAN_CIPHER_SUITE_WEP40:
1585                 key.algo = CRYPTO_ALGO_WEP1;
1586                 WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1587                 break;
1588         case WLAN_CIPHER_SUITE_WEP104:
1589                 key.algo = CRYPTO_ALGO_WEP128;
1590                 WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1591                 break;
1592         case WLAN_CIPHER_SUITE_TKIP:
1593                 memcpy(keybuf, &key.data[24], sizeof(keybuf));
1594                 memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1595                 memcpy(&key.data[16], keybuf, sizeof(keybuf));
1596                 key.algo = CRYPTO_ALGO_TKIP;
1597                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1598                 break;
1599         case WLAN_CIPHER_SUITE_AES_CMAC:
1600                 key.algo = CRYPTO_ALGO_AES_CCM;
1601                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1602                 break;
1603         case WLAN_CIPHER_SUITE_CCMP:
1604                 key.algo = CRYPTO_ALGO_AES_CCM;
1605                 WL_CONN("WLAN_CIPHER_SUITE_CCMP\n");
1606                 break;
1607         default:
1608                 WL_ERR("Invalid cipher (0x%x)\n", params->cipher);
1609                 err = -EINVAL;
1610                 goto done;
1611         }
1612
1613         err = send_key_to_dongle(dev, &key); /* Set the new key/index */
1614         if (err)
1615                 goto done;
1616
1617         val = WEP_ENABLED;
1618         err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1619         if (unlikely(err)) {
1620                 WL_ERR("get wsec error (%d)\n", err);
1621                 goto done;
1622         }
1623         wsec &= ~(WEP_ENABLED);
1624         wsec |= val;
1625         err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1626         if (unlikely(err)) {
1627                 WL_ERR("set wsec error (%d)\n", err);
1628                 goto done;
1629         }
1630
1631         val = 1;                /* assume shared key. otherwise 0 */
1632         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_SET_AUTH, &val);
1633         if (unlikely(err))
1634                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1635 done:
1636         WL_TRACE("Exit\n");
1637         return err;
1638 }
1639
1640 static s32
1641 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *dev,
1642                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1643 {
1644         struct brcmf_wsec_key key;
1645         s32 err = 0;
1646         s32 val;
1647         s32 wsec;
1648
1649         WL_TRACE("Enter\n");
1650         if (!check_sys_up(wiphy))
1651                 return -EIO;
1652
1653         memset(&key, 0, sizeof(key));
1654
1655         key.index = (u32) key_idx;
1656         key.flags = BRCMF_PRIMARY_KEY;
1657         key.algo = CRYPTO_ALGO_OFF;
1658
1659         WL_CONN("key index (%d)\n", key_idx);
1660
1661         /* Set the new key/index */
1662         err = send_key_to_dongle(dev, &key);
1663         if (err) {
1664                 if (err == -EINVAL) {
1665                         if (key.index >= DOT11_MAX_DEFAULT_KEYS)
1666                                 /* we ignore this key index in this case */
1667                                 WL_ERR("invalid key index (%d)\n", key_idx);
1668                 }
1669                 /* Ignore this error, may happen during DISASSOC */
1670                 err = -EAGAIN;
1671                 goto done;
1672         }
1673
1674         val = 0;
1675         err = brcmf_dev_intvar_get(dev, "wsec", &wsec);
1676         if (unlikely(err)) {
1677                 WL_ERR("get wsec error (%d)\n", err);
1678                 /* Ignore this error, may happen during DISASSOC */
1679                 err = -EAGAIN;
1680                 goto done;
1681         }
1682         wsec &= ~(WEP_ENABLED);
1683         wsec |= val;
1684         err = brcmf_dev_intvar_set(dev, "wsec", wsec);
1685         if (unlikely(err)) {
1686                 WL_ERR("set wsec error (%d)\n", err);
1687                 /* Ignore this error, may happen during DISASSOC */
1688                 err = -EAGAIN;
1689                 goto done;
1690         }
1691
1692         val = 0;                /* assume open key. otherwise 1 */
1693         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_SET_AUTH, &val);
1694         if (unlikely(err)) {
1695                 WL_ERR("WLC_SET_AUTH error (%d)\n", err);
1696                 /* Ignore this error, may happen during DISASSOC */
1697                 err = -EAGAIN;
1698         }
1699 done:
1700         WL_TRACE("Exit\n");
1701         return err;
1702 }
1703
1704 static s32
1705 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *dev,
1706                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1707                     void (*callback) (void *cookie, struct key_params * params))
1708 {
1709         struct key_params params;
1710         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1711         struct brcmf_cfg80211_security *sec;
1712         s32 wsec;
1713         s32 err = 0;
1714
1715         WL_TRACE("Enter\n");
1716         WL_CONN("key index (%d)\n", key_idx);
1717         if (!check_sys_up(wiphy))
1718                 return -EIO;
1719
1720         memset(&params, 0, sizeof(params));
1721
1722         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_GET_WSEC, &wsec);
1723         if (unlikely(err)) {
1724                 WL_ERR("WLC_GET_WSEC error (%d)\n", err);
1725                 /* Ignore this error, may happen during DISASSOC */
1726                 err = -EAGAIN;
1727                 goto done;
1728         }
1729         switch (wsec) {
1730         case WEP_ENABLED:
1731                 sec = brcmf_read_prof(cfg_priv, WL_PROF_SEC);
1732                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1733                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1734                         WL_CONN("WLAN_CIPHER_SUITE_WEP40\n");
1735                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1736                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1737                         WL_CONN("WLAN_CIPHER_SUITE_WEP104\n");
1738                 }
1739                 break;
1740         case TKIP_ENABLED:
1741                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1742                 WL_CONN("WLAN_CIPHER_SUITE_TKIP\n");
1743                 break;
1744         case AES_ENABLED:
1745                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1746                 WL_CONN("WLAN_CIPHER_SUITE_AES_CMAC\n");
1747                 break;
1748         default:
1749                 WL_ERR("Invalid algo (0x%x)\n", wsec);
1750                 err = -EINVAL;
1751                 goto done;
1752         }
1753         callback(cookie, &params);
1754
1755 done:
1756         WL_TRACE("Exit\n");
1757         return err;
1758 }
1759
1760 static s32
1761 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1762                                     struct net_device *dev, u8 key_idx)
1763 {
1764         WL_INFO("Not supported\n");
1765
1766         return -EOPNOTSUPP;
1767 }
1768
1769 static s32
1770 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *dev,
1771                         u8 *mac, struct station_info *sinfo)
1772 {
1773         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1774         struct brcmf_scb_val scb_val;
1775         int rssi;
1776         s32 rate;
1777         s32 err = 0;
1778         u8 *bssid = brcmf_read_prof(cfg_priv, WL_PROF_BSSID);
1779
1780         WL_TRACE("Enter\n");
1781         if (!check_sys_up(wiphy))
1782                 return -EIO;
1783
1784         if (unlikely
1785             (memcmp(mac, bssid, ETH_ALEN))) {
1786                 WL_ERR("Wrong Mac address cfg_mac-%X:%X:%X:%X:%X:%X"
1787                         "wl_bssid-%X:%X:%X:%X:%X:%X\n",
1788                         mac[0], mac[1], mac[2], mac[3], mac[4], mac[5],
1789                         bssid[0], bssid[1], bssid[2], bssid[3],
1790                         bssid[4], bssid[5]);
1791                 err = -ENOENT;
1792                 goto done;
1793         }
1794
1795         /* Report the current tx rate */
1796         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_GET_RATE, &rate);
1797         if (err) {
1798                 WL_ERR("Could not get rate (%d)\n", err);
1799         } else {
1800                 sinfo->filled |= STATION_INFO_TX_BITRATE;
1801                 sinfo->txrate.legacy = rate * 5;
1802                 WL_CONN("Rate %d Mbps\n", rate / 2);
1803         }
1804
1805         if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status)) {
1806                 scb_val.val = 0;
1807                 err = brcmf_dev_ioctl(dev, BRCMF_C_GET_RSSI, &scb_val,
1808                                 sizeof(struct brcmf_scb_val));
1809                 if (unlikely(err))
1810                         WL_ERR("Could not get rssi (%d)\n", err);
1811
1812                 rssi = le32_to_cpu(scb_val.val);
1813                 sinfo->filled |= STATION_INFO_SIGNAL;
1814                 sinfo->signal = rssi;
1815                 WL_CONN("RSSI %d dBm\n", rssi);
1816         }
1817
1818 done:
1819         WL_TRACE("Exit\n");
1820         return err;
1821 }
1822
1823 static s32
1824 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *dev,
1825                            bool enabled, s32 timeout)
1826 {
1827         s32 pm;
1828         s32 err = 0;
1829         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
1830
1831         WL_TRACE("Enter\n");
1832
1833         /*
1834          * Powersave enable/disable request is coming from the
1835          * cfg80211 even before the interface is up. In that
1836          * scenario, driver will be storing the power save
1837          * preference in cfg_priv struct to apply this to
1838          * FW later while initializing the dongle
1839          */
1840         cfg_priv->pwr_save = enabled;
1841         if (!test_bit(WL_STATUS_READY, &cfg_priv->status)) {
1842
1843                 WL_INFO("Device is not ready,"
1844                         "storing the value in cfg_priv struct\n");
1845                 goto done;
1846         }
1847
1848         pm = enabled ? PM_FAST : PM_OFF;
1849         WL_INFO("power save %s\n", (pm ? "enabled" : "disabled"));
1850
1851         err = brcmf_dev_ioctl_u32(dev, BRCMF_C_SET_PM, &pm);
1852         if (unlikely(err)) {
1853                 if (err == -ENODEV)
1854                         WL_ERR("net_device is not ready yet\n");
1855                 else
1856                         WL_ERR("error (%d)\n", err);
1857         }
1858 done:
1859         WL_TRACE("Exit\n");
1860         return err;
1861 }
1862
1863 static s32
1864 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1865                              const u8 *addr,
1866                              const struct cfg80211_bitrate_mask *mask)
1867 {
1868         struct brcm_rateset rateset;
1869         s32 rate;
1870         s32 val;
1871         s32 err_bg;
1872         s32 err_a;
1873         u32 legacy;
1874         s32 err = 0;
1875
1876         WL_TRACE("Enter\n");
1877         if (!check_sys_up(wiphy))
1878                 return -EIO;
1879
1880         /* addr param is always NULL. ignore it */
1881         /* Get current rateset */
1882         err = brcmf_dev_ioctl(dev, BRCM_GET_CURR_RATESET, &rateset,
1883                         sizeof(rateset));
1884         if (unlikely(err)) {
1885                 WL_ERR("could not get current rateset (%d)\n", err);
1886                 goto done;
1887         }
1888
1889         rateset.count = le32_to_cpu(rateset.count);
1890
1891         legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
1892         if (!legacy)
1893                 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
1894                              0xFFFF);
1895
1896         val = wl_g_rates[legacy - 1].bitrate * 100000;
1897
1898         if (val < rateset.count)
1899                 /* Select rate by rateset index */
1900                 rate = rateset.rates[val] & 0x7f;
1901         else
1902                 /* Specified rate in bps */
1903                 rate = val / 500000;
1904
1905         WL_CONN("rate %d mbps\n", rate / 2);
1906
1907         /*
1908          *
1909          *      Set rate override,
1910          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
1911          */
1912         err_bg = brcmf_dev_intvar_set(dev, "bg_rate", rate);
1913         err_a = brcmf_dev_intvar_set(dev, "a_rate", rate);
1914         if (unlikely(err_bg && err_a)) {
1915                 WL_ERR("could not set fixed rate (%d) (%d)\n", err_bg, err_a);
1916                 err = err_bg | err_a;
1917         }
1918
1919 done:
1920         WL_TRACE("Exit\n");
1921         return err;
1922 }
1923
1924 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_priv *cfg_priv,
1925                                    struct brcmf_bss_info *bi)
1926 {
1927         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
1928         struct ieee80211_channel *notify_channel;
1929         struct cfg80211_bss *bss;
1930         struct ieee80211_supported_band *band;
1931         s32 err = 0;
1932         u16 channel;
1933         u32 freq;
1934         u64 notify_timestamp;
1935         u16 notify_capability;
1936         u16 notify_interval;
1937         u8 *notify_ie;
1938         size_t notify_ielen;
1939         s32 notify_signal;
1940
1941         if (unlikely(le32_to_cpu(bi->length) > WL_BSS_INFO_MAX)) {
1942                 WL_ERR("Bss info is larger than buffer. Discarding\n");
1943                 return 0;
1944         }
1945
1946         channel = bi->ctl_ch ? bi->ctl_ch :
1947                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
1948
1949         if (channel <= CH_MAX_2G_CHANNEL)
1950                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
1951         else
1952                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
1953
1954         freq = ieee80211_channel_to_frequency(channel, band->band);
1955         notify_channel = ieee80211_get_channel(wiphy, freq);
1956
1957         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
1958         notify_capability = le16_to_cpu(bi->capability);
1959         notify_interval = le16_to_cpu(bi->beacon_period);
1960         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
1961         notify_ielen = le16_to_cpu(bi->ie_length);
1962         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
1963
1964         WL_CONN("bssid: %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
1965                         bi->BSSID[0], bi->BSSID[1], bi->BSSID[2],
1966                         bi->BSSID[3], bi->BSSID[4], bi->BSSID[5]);
1967         WL_CONN("Channel: %d(%d)\n", channel, freq);
1968         WL_CONN("Capability: %X\n", notify_capability);
1969         WL_CONN("Beacon interval: %d\n", notify_interval);
1970         WL_CONN("Signal: %d\n", notify_signal);
1971         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
1972
1973         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
1974                 notify_timestamp, notify_capability, notify_interval, notify_ie,
1975                 notify_ielen, notify_signal, GFP_KERNEL);
1976
1977         if (unlikely(!bss)) {
1978                 WL_ERR("cfg80211_inform_bss_frame error\n");
1979                 return -EINVAL;
1980         }
1981
1982         return err;
1983 }
1984
1985 static s32 brcmf_inform_bss(struct brcmf_cfg80211_priv *cfg_priv)
1986 {
1987         struct brcmf_scan_results *bss_list;
1988         struct brcmf_bss_info *bi = NULL;       /* must be initialized */
1989         s32 err = 0;
1990         int i;
1991
1992         bss_list = cfg_priv->bss_list;
1993         if (unlikely(bss_list->version != BRCMF_BSS_INFO_VERSION)) {
1994                 WL_ERR("Version %d != WL_BSS_INFO_VERSION\n",
1995                        bss_list->version);
1996                 return -EOPNOTSUPP;
1997         }
1998         WL_SCAN("scanned AP count (%d)\n", bss_list->count);
1999         bi = next_bss(bss_list, bi);
2000         for_each_bss(bss_list, bi, i) {
2001                 err = brcmf_inform_single_bss(cfg_priv, bi);
2002                 if (unlikely(err))
2003                         break;
2004         }
2005         return err;
2006 }
2007
2008 static s32 wl_inform_ibss(struct brcmf_cfg80211_priv *cfg_priv,
2009                           struct net_device *dev, const u8 *bssid)
2010 {
2011         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2012         struct ieee80211_channel *notify_channel;
2013         struct brcmf_bss_info *bi = NULL;
2014         struct ieee80211_supported_band *band;
2015         u8 *buf = NULL;
2016         s32 err = 0;
2017         u16 channel;
2018         u32 freq;
2019         u64 notify_timestamp;
2020         u16 notify_capability;
2021         u16 notify_interval;
2022         u8 *notify_ie;
2023         size_t notify_ielen;
2024         s32 notify_signal;
2025
2026         WL_TRACE("Enter\n");
2027
2028         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2029         if (buf == NULL) {
2030                 WL_ERR("kzalloc() failed\n");
2031                 err = -ENOMEM;
2032                 goto CleanUp;
2033         }
2034
2035         *(u32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2036
2037         err = brcmf_dev_ioctl(dev, BRCMF_C_GET_BSS_INFO, buf, WL_BSS_INFO_MAX);
2038         if (unlikely(err)) {
2039                 WL_ERR("WLC_GET_BSS_INFO failed: %d\n", err);
2040                 goto CleanUp;
2041         }
2042
2043         bi = (struct brcmf_bss_info *)(buf + 4);
2044
2045         channel = bi->ctl_ch ? bi->ctl_ch :
2046                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2047
2048         if (channel <= CH_MAX_2G_CHANNEL)
2049                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2050         else
2051                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2052
2053         freq = ieee80211_channel_to_frequency(channel, band->band);
2054         notify_channel = ieee80211_get_channel(wiphy, freq);
2055
2056         notify_timestamp = jiffies_to_msecs(jiffies)*1000; /* uSec */
2057         notify_capability = le16_to_cpu(bi->capability);
2058         notify_interval = le16_to_cpu(bi->beacon_period);
2059         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2060         notify_ielen = le16_to_cpu(bi->ie_length);
2061         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2062
2063         WL_CONN("channel: %d(%d)\n", channel, freq);
2064         WL_CONN("capability: %X\n", notify_capability);
2065         WL_CONN("beacon interval: %d\n", notify_interval);
2066         WL_CONN("signal: %d\n", notify_signal);
2067         WL_CONN("notify_timestamp: %#018llx\n", notify_timestamp);
2068
2069         cfg80211_inform_bss(wiphy, notify_channel, bssid,
2070                 notify_timestamp, notify_capability, notify_interval,
2071                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2072
2073 CleanUp:
2074
2075         kfree(buf);
2076
2077         WL_TRACE("Exit\n");
2078
2079         return err;
2080 }
2081
2082 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_priv *cfg_priv)
2083 {
2084         return cfg_priv->conf->mode == WL_MODE_IBSS;
2085 }
2086
2087 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_priv *cfg_priv)
2088 {
2089         struct brcmf_bss_info *bi;
2090         struct brcmf_ssid *ssid;
2091         struct brcmu_tlv *tim;
2092         u16 beacon_interval;
2093         u8 dtim_period;
2094         size_t ie_len;
2095         u8 *ie;
2096         s32 err = 0;
2097
2098         WL_TRACE("Enter\n");
2099         if (brcmf_is_ibssmode(cfg_priv))
2100                 return err;
2101
2102         ssid = (struct brcmf_ssid *)brcmf_read_prof(cfg_priv, WL_PROF_SSID);
2103
2104         *(u32 *)cfg_priv->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2105         err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCMF_C_GET_BSS_INFO,
2106                         cfg_priv->extra_buf, WL_EXTRA_BUF_MAX);
2107         if (unlikely(err)) {
2108                 WL_ERR("Could not get bss info %d\n", err);
2109                 goto update_bss_info_out;
2110         }
2111
2112         bi = (struct brcmf_bss_info *)(cfg_priv->extra_buf + 4);
2113         err = brcmf_inform_single_bss(cfg_priv, bi);
2114         if (unlikely(err))
2115                 goto update_bss_info_out;
2116
2117         ie = ((u8 *)bi) + bi->ie_offset;
2118         ie_len = bi->ie_length;
2119         beacon_interval = cpu_to_le16(bi->beacon_period);
2120
2121         tim = brcmu_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2122         if (tim)
2123                 dtim_period = tim->data[1];
2124         else {
2125                 /*
2126                 * active scan was done so we could not get dtim
2127                 * information out of probe response.
2128                 * so we speficially query dtim information to dongle.
2129                 */
2130                 u32 var;
2131                 err = brcmf_dev_intvar_get(cfg_to_ndev(cfg_priv),
2132                                            "dtim_assoc", &var);
2133                 if (unlikely(err)) {
2134                         WL_ERR("wl dtim_assoc failed (%d)\n", err);
2135                         goto update_bss_info_out;
2136                 }
2137                 dtim_period = (u8)var;
2138         }
2139
2140         brcmf_update_prof(cfg_priv, NULL, &beacon_interval, WL_PROF_BEACONINT);
2141         brcmf_update_prof(cfg_priv, NULL, &dtim_period, WL_PROF_DTIMPERIOD);
2142
2143 update_bss_info_out:
2144         WL_TRACE("Exit");
2145         return err;
2146 }
2147
2148 static void brcmf_term_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2149 {
2150         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2151         struct brcmf_ssid ssid;
2152
2153         if (cfg_priv->iscan_on) {
2154                 iscan->state = WL_ISCAN_STATE_IDLE;
2155
2156                 if (iscan->timer_on) {
2157                         del_timer_sync(&iscan->timer);
2158                         iscan->timer_on = 0;
2159                 }
2160
2161                 cancel_work_sync(&iscan->work);
2162
2163                 /* Abort iscan running in FW */
2164                 memset(&ssid, 0, sizeof(ssid));
2165                 brcmf_run_iscan(iscan, &ssid, WL_SCAN_ACTION_ABORT);
2166         }
2167 }
2168
2169 static void brcmf_notify_iscan_complete(struct brcmf_cfg80211_iscan_ctrl *iscan,
2170                                         bool aborted)
2171 {
2172         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2173         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2174
2175         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
2176                                          &cfg_priv->status))) {
2177                 WL_ERR("Scan complete while device not scanning\n");
2178                 return;
2179         }
2180         if (likely(cfg_priv->scan_request)) {
2181                 WL_SCAN("ISCAN Completed scan: %s\n",
2182                                 aborted ? "Aborted" : "Done");
2183                 cfg80211_scan_done(cfg_priv->scan_request, aborted);
2184                 brcmf_set_mpc(ndev, 1);
2185                 cfg_priv->scan_request = NULL;
2186         }
2187         cfg_priv->iscan_kickstart = false;
2188 }
2189
2190 static s32 brcmf_wakeup_iscan(struct brcmf_cfg80211_iscan_ctrl *iscan)
2191 {
2192         if (likely(iscan->state != WL_ISCAN_STATE_IDLE)) {
2193                 WL_SCAN("wake up iscan\n");
2194                 schedule_work(&iscan->work);
2195                 return 0;
2196         }
2197
2198         return -EIO;
2199 }
2200
2201 static s32
2202 brcmf_get_iscan_results(struct brcmf_cfg80211_iscan_ctrl *iscan, u32 *status,
2203                      struct brcmf_scan_results **bss_list)
2204 {
2205         struct brcmf_iscan_results list;
2206         struct brcmf_scan_results *results;
2207         struct brcmf_iscan_results *list_buf;
2208         s32 err = 0;
2209
2210         memset(iscan->scan_buf, 0, WL_ISCAN_BUF_MAX);
2211         list_buf = (struct brcmf_iscan_results *)iscan->scan_buf;
2212         results = &list_buf->results;
2213         results->buflen = BRCMF_ISCAN_RESULTS_FIXED_SIZE;
2214         results->version = 0;
2215         results->count = 0;
2216
2217         memset(&list, 0, sizeof(list));
2218         list.results.buflen = cpu_to_le32(WL_ISCAN_BUF_MAX);
2219         err = brcmf_dev_iovar_getbuf(iscan->dev, "iscanresults", &list,
2220                                 BRCMF_ISCAN_RESULTS_FIXED_SIZE, iscan->scan_buf,
2221                                 WL_ISCAN_BUF_MAX);
2222         if (unlikely(err)) {
2223                 WL_ERR("error (%d)\n", err);
2224                 return err;
2225         }
2226         results->buflen = le32_to_cpu(results->buflen);
2227         results->version = le32_to_cpu(results->version);
2228         results->count = le32_to_cpu(results->count);
2229         WL_SCAN("results->count = %d\n", results->count);
2230         WL_SCAN("results->buflen = %d\n", results->buflen);
2231         *status = le32_to_cpu(list_buf->status);
2232         WL_SCAN("status = %d\n", *status);
2233         *bss_list = results;
2234
2235         return err;
2236 }
2237
2238 static s32 brcmf_iscan_done(struct brcmf_cfg80211_priv *cfg_priv)
2239 {
2240         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2241         s32 err = 0;
2242
2243         iscan->state = WL_ISCAN_STATE_IDLE;
2244         rtnl_lock();
2245         brcmf_inform_bss(cfg_priv);
2246         brcmf_notify_iscan_complete(iscan, false);
2247         rtnl_unlock();
2248
2249         return err;
2250 }
2251
2252 static s32 brcmf_iscan_pending(struct brcmf_cfg80211_priv *cfg_priv)
2253 {
2254         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2255         s32 err = 0;
2256
2257         /* Reschedule the timer */
2258         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2259         iscan->timer_on = 1;
2260
2261         return err;
2262 }
2263
2264 static s32 brcmf_iscan_inprogress(struct brcmf_cfg80211_priv *cfg_priv)
2265 {
2266         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2267         s32 err = 0;
2268
2269         rtnl_lock();
2270         brcmf_inform_bss(cfg_priv);
2271         brcmf_run_iscan(iscan, NULL, BRCMF_SCAN_ACTION_CONTINUE);
2272         rtnl_unlock();
2273         /* Reschedule the timer */
2274         mod_timer(&iscan->timer, jiffies + iscan->timer_ms * HZ / 1000);
2275         iscan->timer_on = 1;
2276
2277         return err;
2278 }
2279
2280 static s32 brcmf_iscan_aborted(struct brcmf_cfg80211_priv *cfg_priv)
2281 {
2282         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_priv->iscan;
2283         s32 err = 0;
2284
2285         iscan->state = WL_ISCAN_STATE_IDLE;
2286         rtnl_lock();
2287         brcmf_notify_iscan_complete(iscan, true);
2288         rtnl_unlock();
2289
2290         return err;
2291 }
2292
2293 static void brcmf_cfg80211_iscan_handler(struct work_struct *work)
2294 {
2295         struct brcmf_cfg80211_iscan_ctrl *iscan =
2296                         container_of(work, struct brcmf_cfg80211_iscan_ctrl,
2297                                      work);
2298         struct brcmf_cfg80211_priv *cfg_priv = iscan_to_cfg(iscan);
2299         struct brcmf_cfg80211_iscan_eloop *el = &iscan->el;
2300         u32 status = BRCMF_SCAN_RESULTS_PARTIAL;
2301
2302         if (iscan->timer_on) {
2303                 del_timer_sync(&iscan->timer);
2304                 iscan->timer_on = 0;
2305         }
2306
2307         rtnl_lock();
2308         if (brcmf_get_iscan_results(iscan, &status, &cfg_priv->bss_list)) {
2309                 status = BRCMF_SCAN_RESULTS_ABORTED;
2310                 WL_ERR("Abort iscan\n");
2311         }
2312         rtnl_unlock();
2313
2314         el->handler[status](cfg_priv);
2315 }
2316
2317 static void brcmf_iscan_timer(unsigned long data)
2318 {
2319         struct brcmf_cfg80211_iscan_ctrl *iscan =
2320                         (struct brcmf_cfg80211_iscan_ctrl *)data;
2321
2322         if (iscan) {
2323                 iscan->timer_on = 0;
2324                 WL_SCAN("timer expired\n");
2325                 brcmf_wakeup_iscan(iscan);
2326         }
2327 }
2328
2329 static s32 brcmf_invoke_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2330 {
2331         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2332
2333         if (cfg_priv->iscan_on) {
2334                 iscan->state = WL_ISCAN_STATE_IDLE;
2335                 INIT_WORK(&iscan->work, brcmf_cfg80211_iscan_handler);
2336         }
2337
2338         return 0;
2339 }
2340
2341 static void brcmf_init_iscan_eloop(struct brcmf_cfg80211_iscan_eloop *el)
2342 {
2343         memset(el, 0, sizeof(*el));
2344         el->handler[BRCMF_SCAN_RESULTS_SUCCESS] = brcmf_iscan_done;
2345         el->handler[BRCMF_SCAN_RESULTS_PARTIAL] = brcmf_iscan_inprogress;
2346         el->handler[BRCMF_SCAN_RESULTS_PENDING] = brcmf_iscan_pending;
2347         el->handler[BRCMF_SCAN_RESULTS_ABORTED] = brcmf_iscan_aborted;
2348         el->handler[BRCMF_SCAN_RESULTS_NO_MEM] = brcmf_iscan_aborted;
2349 }
2350
2351 static s32 brcmf_init_iscan(struct brcmf_cfg80211_priv *cfg_priv)
2352 {
2353         struct brcmf_cfg80211_iscan_ctrl *iscan = cfg_to_iscan(cfg_priv);
2354         int err = 0;
2355
2356         if (cfg_priv->iscan_on) {
2357                 iscan->dev = cfg_to_ndev(cfg_priv);
2358                 brcmf_init_iscan_eloop(&iscan->el);
2359                 iscan->timer_ms = WL_ISCAN_TIMER_INTERVAL_MS;
2360                 init_timer(&iscan->timer);
2361                 iscan->timer.data = (unsigned long) iscan;
2362                 iscan->timer.function = brcmf_iscan_timer;
2363                 err = brcmf_invoke_iscan(cfg_priv);
2364                 if (!err)
2365                         iscan->data = cfg_priv;
2366         }
2367
2368         return err;
2369 }
2370
2371 static void brcmf_delay(u32 ms)
2372 {
2373         if (ms < 1000 / HZ) {
2374                 cond_resched();
2375                 mdelay(ms);
2376         } else {
2377                 msleep(ms);
2378         }
2379 }
2380
2381 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2382 {
2383         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2384
2385         /*
2386          * Check for WL_STATUS_READY before any function call which
2387          * could result is bus access. Don't block the resume for
2388          * any driver error conditions
2389          */
2390         WL_TRACE("Enter\n");
2391
2392         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2393                 brcmf_invoke_iscan(wiphy_to_cfg(wiphy));
2394
2395         WL_TRACE("Exit\n");
2396         return 0;
2397 }
2398
2399 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2400                                   struct cfg80211_wowlan *wow)
2401 {
2402         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2403         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2404
2405         WL_TRACE("Enter\n");
2406
2407         /*
2408          * Check for WL_STATUS_READY before any function call which
2409          * could result is bus access. Don't block the suspend for
2410          * any driver error conditions
2411          */
2412
2413         /*
2414          * While going to suspend if associated with AP disassociate
2415          * from AP to save power while system is in suspended state
2416          */
2417         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
2418              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
2419              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2420                 WL_INFO("Disassociating from AP"
2421                         " while entering suspend state\n");
2422                 brcmf_link_down(cfg_priv);
2423
2424                 /*
2425                  * Make sure WPA_Supplicant receives all the event
2426                  * generated due to DISASSOC call to the fw to keep
2427                  * the state fw and WPA_Supplicant state consistent
2428                  */
2429                 rtnl_unlock();
2430                 brcmf_delay(500);
2431                 rtnl_lock();
2432         }
2433
2434         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2435         if (test_bit(WL_STATUS_READY, &cfg_priv->status))
2436                 brcmf_term_iscan(cfg_priv);
2437
2438         if (cfg_priv->scan_request) {
2439                 /* Indidate scan abort to cfg80211 layer */
2440                 WL_INFO("Terminating scan in progress\n");
2441                 cfg80211_scan_done(cfg_priv->scan_request, true);
2442                 cfg_priv->scan_request = NULL;
2443         }
2444         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
2445         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
2446
2447         /* Turn off watchdog timer */
2448         if (test_bit(WL_STATUS_READY, &cfg_priv->status)) {
2449                 WL_INFO("Enable MPC\n");
2450                 brcmf_set_mpc(ndev, 1);
2451         }
2452
2453         WL_TRACE("Exit\n");
2454
2455         return 0;
2456 }
2457
2458 static __used s32
2459 brcmf_dev_bufvar_set(struct net_device *dev, s8 *name, s8 *buf, s32 len)
2460 {
2461         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2462         u32 buflen;
2463
2464         buflen = brcmu_mkiovar(name, buf, len, cfg_priv->ioctl_buf,
2465                                WL_IOCTL_LEN_MAX);
2466         BUG_ON(!buflen);
2467
2468         return brcmf_dev_ioctl(dev, BRCMF_C_SET_VAR, cfg_priv->ioctl_buf,
2469                                buflen);
2470 }
2471
2472 static s32
2473 brcmf_dev_bufvar_get(struct net_device *dev, s8 *name, s8 *buf,
2474                   s32 buf_len)
2475 {
2476         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(dev);
2477         u32 len;
2478         s32 err = 0;
2479
2480         len = brcmu_mkiovar(name, NULL, 0, cfg_priv->ioctl_buf,
2481                             WL_IOCTL_LEN_MAX);
2482         BUG_ON(!len);
2483         err = brcmf_dev_ioctl(dev, BRCMF_C_GET_VAR, (void *)cfg_priv->ioctl_buf,
2484                         WL_IOCTL_LEN_MAX);
2485         if (unlikely(err)) {
2486                 WL_ERR("error (%d)\n", err);
2487                 return err;
2488         }
2489         memcpy(buf, cfg_priv->ioctl_buf, buf_len);
2490
2491         return err;
2492 }
2493
2494 static __used s32
2495 brcmf_update_pmklist(struct net_device *dev,
2496                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2497 {
2498         int i, j;
2499
2500         WL_CONN("No of elements %d\n", pmk_list->pmkids.npmkid);
2501         for (i = 0; i < pmk_list->pmkids.npmkid; i++) {
2502                 WL_CONN("PMKID[%d]: %pM =\n", i,
2503                         &pmk_list->pmkids.pmkid[i].BSSID);
2504                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2505                         WL_CONN("%02x\n", pmk_list->pmkids.pmkid[i].PMKID[j]);
2506         }
2507
2508         if (likely(!err))
2509                 brcmf_dev_bufvar_set(dev, "pmkid_info", (char *)pmk_list,
2510                                         sizeof(*pmk_list));
2511
2512         return err;
2513 }
2514
2515 static s32
2516 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *dev,
2517                          struct cfg80211_pmksa *pmksa)
2518 {
2519         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2520         struct pmkid_list *pmkids = &cfg_priv->pmk_list->pmkids;
2521         s32 err = 0;
2522         int i;
2523
2524         WL_TRACE("Enter\n");
2525         if (!check_sys_up(wiphy))
2526                 return -EIO;
2527
2528         for (i = 0; i < pmkids->npmkid; i++)
2529                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2530                         break;
2531         if (i < WL_NUM_PMKIDS_MAX) {
2532                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2533                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2534                 if (i == pmkids->npmkid)
2535                         pmkids->npmkid++;
2536         } else
2537                 err = -EINVAL;
2538
2539         WL_CONN("set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2540                 pmkids->pmkid[pmkids->npmkid].BSSID);
2541         for (i = 0; i < WLAN_PMKID_LEN; i++)
2542                 WL_CONN("%02x\n", pmkids->pmkid[pmkids->npmkid].PMKID[i]);
2543
2544         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2545
2546         WL_TRACE("Exit\n");
2547         return err;
2548 }
2549
2550 static s32
2551 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *dev,
2552                       struct cfg80211_pmksa *pmksa)
2553 {
2554         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2555         struct pmkid_list pmkid;
2556         s32 err = 0;
2557         int i;
2558
2559         WL_TRACE("Enter\n");
2560         if (!check_sys_up(wiphy))
2561                 return -EIO;
2562
2563         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2564         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2565
2566         WL_CONN("del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2567                &pmkid.pmkid[0].BSSID);
2568         for (i = 0; i < WLAN_PMKID_LEN; i++)
2569                 WL_CONN("%02x\n", pmkid.pmkid[0].PMKID[i]);
2570
2571         for (i = 0; i < cfg_priv->pmk_list->pmkids.npmkid; i++)
2572                 if (!memcmp
2573                     (pmksa->bssid, &cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2574                      ETH_ALEN))
2575                         break;
2576
2577         if ((cfg_priv->pmk_list->pmkids.npmkid > 0)
2578             && (i < cfg_priv->pmk_list->pmkids.npmkid)) {
2579                 memset(&cfg_priv->pmk_list->pmkids.pmkid[i], 0,
2580                        sizeof(struct pmkid));
2581                 for (; i < (cfg_priv->pmk_list->pmkids.npmkid - 1); i++) {
2582                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].BSSID,
2583                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].BSSID,
2584                                ETH_ALEN);
2585                         memcpy(&cfg_priv->pmk_list->pmkids.pmkid[i].PMKID,
2586                                &cfg_priv->pmk_list->pmkids.pmkid[i + 1].PMKID,
2587                                WLAN_PMKID_LEN);
2588                 }
2589                 cfg_priv->pmk_list->pmkids.npmkid--;
2590         } else
2591                 err = -EINVAL;
2592
2593         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2594
2595         WL_TRACE("Exit\n");
2596         return err;
2597
2598 }
2599
2600 static s32
2601 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *dev)
2602 {
2603         struct brcmf_cfg80211_priv *cfg_priv = wiphy_to_cfg(wiphy);
2604         s32 err = 0;
2605
2606         WL_TRACE("Enter\n");
2607         if (!check_sys_up(wiphy))
2608                 return -EIO;
2609
2610         memset(cfg_priv->pmk_list, 0, sizeof(*cfg_priv->pmk_list));
2611         err = brcmf_update_pmklist(dev, cfg_priv->pmk_list, err);
2612
2613         WL_TRACE("Exit\n");
2614         return err;
2615
2616 }
2617
2618 static struct cfg80211_ops wl_cfg80211_ops = {
2619         .change_virtual_intf = brcmf_cfg80211_change_iface,
2620         .scan = brcmf_cfg80211_scan,
2621         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
2622         .join_ibss = brcmf_cfg80211_join_ibss,
2623         .leave_ibss = brcmf_cfg80211_leave_ibss,
2624         .get_station = brcmf_cfg80211_get_station,
2625         .set_tx_power = brcmf_cfg80211_set_tx_power,
2626         .get_tx_power = brcmf_cfg80211_get_tx_power,
2627         .add_key = brcmf_cfg80211_add_key,
2628         .del_key = brcmf_cfg80211_del_key,
2629         .get_key = brcmf_cfg80211_get_key,
2630         .set_default_key = brcmf_cfg80211_config_default_key,
2631         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
2632         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
2633         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
2634         .connect = brcmf_cfg80211_connect,
2635         .disconnect = brcmf_cfg80211_disconnect,
2636         .suspend = brcmf_cfg80211_suspend,
2637         .resume = brcmf_cfg80211_resume,
2638         .set_pmksa = brcmf_cfg80211_set_pmksa,
2639         .del_pmksa = brcmf_cfg80211_del_pmksa,
2640         .flush_pmksa = brcmf_cfg80211_flush_pmksa
2641 };
2642
2643 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
2644 {
2645         s32 err = 0;
2646
2647         switch (mode) {
2648         case WL_MODE_BSS:
2649                 return NL80211_IFTYPE_STATION;
2650         case WL_MODE_IBSS:
2651                 return NL80211_IFTYPE_ADHOC;
2652         default:
2653                 return NL80211_IFTYPE_UNSPECIFIED;
2654         }
2655
2656         return err;
2657 }
2658
2659 static struct wireless_dev *brcmf_alloc_wdev(s32 sizeof_iface,
2660                                           struct device *dev)
2661 {
2662         struct wireless_dev *wdev;
2663         s32 err = 0;
2664
2665         wdev = kzalloc(sizeof(*wdev), GFP_KERNEL);
2666         if (unlikely(!wdev)) {
2667                 WL_ERR("Could not allocate wireless device\n");
2668                 return ERR_PTR(-ENOMEM);
2669         }
2670         wdev->wiphy =
2671             wiphy_new(&wl_cfg80211_ops,
2672                       sizeof(struct brcmf_cfg80211_priv) + sizeof_iface);
2673         if (unlikely(!wdev->wiphy)) {
2674                 WL_ERR("Couldn not allocate wiphy device\n");
2675                 err = -ENOMEM;
2676                 goto wiphy_new_out;
2677         }
2678         set_wiphy_dev(wdev->wiphy, dev);
2679         wdev->wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
2680         wdev->wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
2681         wdev->wiphy->interface_modes =
2682             BIT(NL80211_IFTYPE_STATION) | BIT(NL80211_IFTYPE_ADHOC);
2683         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
2684         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;    /* Set
2685                                                 * it as 11a by default.
2686                                                 * This will be updated with
2687                                                 * 11n phy tables in
2688                                                 * "ifconfig up"
2689                                                 * if phy has 11n capability
2690                                                 */
2691         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2692         wdev->wiphy->cipher_suites = __wl_cipher_suites;
2693         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
2694         wdev->wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;      /* enable power
2695                                                                  * save mode
2696                                                                  * by default
2697                                                                  */
2698         err = wiphy_register(wdev->wiphy);
2699         if (unlikely(err < 0)) {
2700                 WL_ERR("Couldn not register wiphy device (%d)\n", err);
2701                 goto wiphy_register_out;
2702         }
2703         return wdev;
2704
2705 wiphy_register_out:
2706         wiphy_free(wdev->wiphy);
2707
2708 wiphy_new_out:
2709         kfree(wdev);
2710
2711         return ERR_PTR(err);
2712 }
2713
2714 static void brcmf_free_wdev(struct brcmf_cfg80211_priv *cfg_priv)
2715 {
2716         struct wireless_dev *wdev = cfg_priv->wdev;
2717
2718         if (unlikely(!wdev)) {
2719                 WL_ERR("wdev is invalid\n");
2720                 return;
2721         }
2722         wiphy_unregister(wdev->wiphy);
2723         wiphy_free(wdev->wiphy);
2724         kfree(wdev);
2725         cfg_priv->wdev = NULL;
2726 }
2727
2728 static bool brcmf_is_linkup(struct brcmf_cfg80211_priv *cfg_priv,
2729                             const struct brcmf_event_msg *e)
2730 {
2731         u32 event = be32_to_cpu(e->event_type);
2732         u32 status = be32_to_cpu(e->status);
2733
2734         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
2735                 WL_CONN("Processing set ssid\n");
2736                 cfg_priv->link_up = true;
2737                 return true;
2738         }
2739
2740         return false;
2741 }
2742
2743 static bool brcmf_is_linkdown(struct brcmf_cfg80211_priv *cfg_priv,
2744                               const struct brcmf_event_msg *e)
2745 {
2746         u32 event = be32_to_cpu(e->event_type);
2747         u16 flags = be16_to_cpu(e->flags);
2748
2749         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
2750                 WL_CONN("Processing link down\n");
2751                 return true;
2752         }
2753         return false;
2754 }
2755
2756 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_priv *cfg_priv,
2757                                const struct brcmf_event_msg *e)
2758 {
2759         u32 event = be32_to_cpu(e->event_type);
2760         u32 status = be32_to_cpu(e->status);
2761
2762         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
2763                 WL_CONN("Processing Link %s & no network found\n",
2764                                 be16_to_cpu(e->flags) & BRCMF_EVENT_MSG_LINK ?
2765                                 "up" : "down");
2766                 return true;
2767         }
2768
2769         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
2770                 WL_CONN("Processing connecting & no network found\n");
2771                 return true;
2772         }
2773
2774         return false;
2775 }
2776
2777 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2778 {
2779         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2780
2781         kfree(conn_info->req_ie);
2782         conn_info->req_ie = NULL;
2783         conn_info->req_ie_len = 0;
2784         kfree(conn_info->resp_ie);
2785         conn_info->resp_ie = NULL;
2786         conn_info->resp_ie_len = 0;
2787 }
2788
2789 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_priv *cfg_priv)
2790 {
2791         struct net_device *ndev = cfg_to_ndev(cfg_priv);
2792         struct brcmf_cfg80211_assoc_ielen *assoc_info;
2793         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2794         u32 req_len;
2795         u32 resp_len;
2796         s32 err = 0;
2797
2798         brcmf_clear_assoc_ies(cfg_priv);
2799
2800         err = brcmf_dev_bufvar_get(ndev, "assoc_info", cfg_priv->extra_buf,
2801                                 WL_ASSOC_INFO_MAX);
2802         if (unlikely(err)) {
2803                 WL_ERR("could not get assoc info (%d)\n", err);
2804                 return err;
2805         }
2806         assoc_info = (struct brcmf_cfg80211_assoc_ielen *)cfg_priv->extra_buf;
2807         req_len = assoc_info->req_len;
2808         resp_len = assoc_info->resp_len;
2809         if (req_len) {
2810                 err = brcmf_dev_bufvar_get(ndev, "assoc_req_ies",
2811                                            cfg_priv->extra_buf,
2812                                            WL_ASSOC_INFO_MAX);
2813                 if (unlikely(err)) {
2814                         WL_ERR("could not get assoc req (%d)\n", err);
2815                         return err;
2816                 }
2817                 conn_info->req_ie_len = req_len;
2818                 conn_info->req_ie =
2819                     kmemdup(cfg_priv->extra_buf, conn_info->req_ie_len,
2820                             GFP_KERNEL);
2821         } else {
2822                 conn_info->req_ie_len = 0;
2823                 conn_info->req_ie = NULL;
2824         }
2825         if (resp_len) {
2826                 err = brcmf_dev_bufvar_get(ndev, "assoc_resp_ies",
2827                                            cfg_priv->extra_buf,
2828                                            WL_ASSOC_INFO_MAX);
2829                 if (unlikely(err)) {
2830                         WL_ERR("could not get assoc resp (%d)\n", err);
2831                         return err;
2832                 }
2833                 conn_info->resp_ie_len = resp_len;
2834                 conn_info->resp_ie =
2835                     kmemdup(cfg_priv->extra_buf, conn_info->resp_ie_len,
2836                             GFP_KERNEL);
2837         } else {
2838                 conn_info->resp_ie_len = 0;
2839                 conn_info->resp_ie = NULL;
2840         }
2841         WL_CONN("req len (%d) resp len (%d)\n",
2842                conn_info->req_ie_len, conn_info->resp_ie_len);
2843
2844         return err;
2845 }
2846
2847 static s32
2848 brcmf_bss_roaming_done(struct brcmf_cfg80211_priv *cfg_priv,
2849                        struct net_device *ndev,
2850                        const struct brcmf_event_msg *e)
2851 {
2852         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2853         struct wiphy *wiphy = cfg_to_wiphy(cfg_priv);
2854         struct brcmf_channel_info channel;
2855         struct ieee80211_channel *notify_channel;
2856         struct ieee80211_supported_band *band;
2857         u32 freq;
2858         s32 err = 0;
2859
2860         WL_TRACE("Enter\n");
2861
2862         brcmf_get_assoc_ies(cfg_priv);
2863         brcmf_update_prof(cfg_priv, NULL, &e->addr, WL_PROF_BSSID);
2864         brcmf_update_bss_info(cfg_priv);
2865
2866         brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel, sizeof(channel));
2867
2868         channel.target_channel = le32_to_cpu(channel.target_channel);
2869         WL_CONN("Roamed to channel %d\n", channel.target_channel);
2870
2871         if (channel.target_channel <= CH_MAX_2G_CHANNEL)
2872                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2873         else
2874                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2875
2876         freq = ieee80211_channel_to_frequency(channel.target_channel,
2877                                                 band->band);
2878         notify_channel = ieee80211_get_channel(wiphy, freq);
2879
2880         cfg80211_roamed(ndev, notify_channel,
2881                         (u8 *)brcmf_read_prof(cfg_priv, WL_PROF_BSSID),
2882                         conn_info->req_ie, conn_info->req_ie_len,
2883                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
2884         WL_CONN("Report roaming result\n");
2885
2886         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2887         WL_TRACE("Exit\n");
2888         return err;
2889 }
2890
2891 static s32
2892 brcmf_bss_connect_done(struct brcmf_cfg80211_priv *cfg_priv,
2893                        struct net_device *ndev, const struct brcmf_event_msg *e,
2894                        bool completed)
2895 {
2896         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg_priv);
2897         s32 err = 0;
2898
2899         WL_TRACE("Enter\n");
2900
2901         if (test_and_clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) {
2902                 if (completed) {
2903                         brcmf_get_assoc_ies(cfg_priv);
2904                         brcmf_update_prof(cfg_priv, NULL, &e->addr,
2905                                           WL_PROF_BSSID);
2906                         brcmf_update_bss_info(cfg_priv);
2907                 }
2908                 cfg80211_connect_result(ndev,
2909                                         (u8 *)brcmf_read_prof(cfg_priv,
2910                                                               WL_PROF_BSSID),
2911                                         conn_info->req_ie,
2912                                         conn_info->req_ie_len,
2913                                         conn_info->resp_ie,
2914                                         conn_info->resp_ie_len,
2915                                         completed ? WLAN_STATUS_SUCCESS :
2916                                                     WLAN_STATUS_AUTH_TIMEOUT,
2917                                         GFP_KERNEL);
2918                 if (completed)
2919                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2920                 WL_CONN("Report connect result - connection %s\n",
2921                                 completed ? "succeeded" : "failed");
2922         }
2923         WL_TRACE("Exit\n");
2924         return err;
2925 }
2926
2927 static s32
2928 brcmf_notify_connect_status(struct brcmf_cfg80211_priv *cfg_priv,
2929                             struct net_device *ndev,
2930                             const struct brcmf_event_msg *e, void *data)
2931 {
2932         s32 err = 0;
2933
2934         if (brcmf_is_linkup(cfg_priv, e)) {
2935                 WL_CONN("Linkup\n");
2936                 if (brcmf_is_ibssmode(cfg_priv)) {
2937                         brcmf_update_prof(cfg_priv, NULL, (void *)e->addr,
2938                                 WL_PROF_BSSID);
2939                         wl_inform_ibss(cfg_priv, ndev, e->addr);
2940                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
2941                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2942                         set_bit(WL_STATUS_CONNECTED, &cfg_priv->status);
2943                 } else
2944                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2945         } else if (brcmf_is_linkdown(cfg_priv, e)) {
2946                 WL_CONN("Linkdown\n");
2947                 if (brcmf_is_ibssmode(cfg_priv)) {
2948                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2949                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2950                                 &cfg_priv->status))
2951                                 brcmf_link_down(cfg_priv);
2952                 } else {
2953                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2954                         if (test_and_clear_bit(WL_STATUS_CONNECTED,
2955                                 &cfg_priv->status)) {
2956                                 cfg80211_disconnected(ndev, 0, NULL, 0,
2957                                         GFP_KERNEL);
2958                                 brcmf_link_down(cfg_priv);
2959                         }
2960                 }
2961                 brcmf_init_prof(cfg_priv->profile);
2962         } else if (brcmf_is_nonetwork(cfg_priv, e)) {
2963                 if (brcmf_is_ibssmode(cfg_priv))
2964                         clear_bit(WL_STATUS_CONNECTING, &cfg_priv->status);
2965                 else
2966                         brcmf_bss_connect_done(cfg_priv, ndev, e, false);
2967         }
2968
2969         return err;
2970 }
2971
2972 static s32
2973 brcmf_notify_roaming_status(struct brcmf_cfg80211_priv *cfg_priv,
2974                             struct net_device *ndev,
2975                             const struct brcmf_event_msg *e, void *data)
2976 {
2977         s32 err = 0;
2978         u32 event = be32_to_cpu(e->event_type);
2979         u32 status = be32_to_cpu(e->status);
2980
2981         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
2982                 if (test_bit(WL_STATUS_CONNECTED, &cfg_priv->status))
2983                         brcmf_bss_roaming_done(cfg_priv, ndev, e);
2984                 else
2985                         brcmf_bss_connect_done(cfg_priv, ndev, e, true);
2986         }
2987
2988         return err;
2989 }
2990
2991 static s32
2992 brcmf_notify_mic_status(struct brcmf_cfg80211_priv *cfg_priv,
2993                         struct net_device *ndev,
2994                         const struct brcmf_event_msg *e, void *data)
2995 {
2996         u16 flags = be16_to_cpu(e->flags);
2997         enum nl80211_key_type key_type;
2998
2999         rtnl_lock();
3000         if (flags & BRCMF_EVENT_MSG_GROUP)
3001                 key_type = NL80211_KEYTYPE_GROUP;
3002         else
3003                 key_type = NL80211_KEYTYPE_PAIRWISE;
3004
3005         cfg80211_michael_mic_failure(ndev, (u8 *)&e->addr, key_type, -1,
3006                                      NULL, GFP_KERNEL);
3007         rtnl_unlock();
3008
3009         return 0;
3010 }
3011
3012 static s32
3013 brcmf_notify_scan_status(struct brcmf_cfg80211_priv *cfg_priv,
3014                          struct net_device *ndev,
3015                          const struct brcmf_event_msg *e, void *data)
3016 {
3017         struct brcmf_channel_info channel_inform;
3018         struct brcmf_scan_results *bss_list;
3019         u32 len = WL_SCAN_BUF_MAX;
3020         s32 err = 0;
3021         bool scan_abort = false;
3022
3023         WL_TRACE("Enter\n");
3024
3025         if (cfg_priv->iscan_on && cfg_priv->iscan_kickstart) {
3026                 WL_TRACE("Exit\n");
3027                 return brcmf_wakeup_iscan(cfg_to_iscan(cfg_priv));
3028         }
3029
3030         if (unlikely(!test_and_clear_bit(WL_STATUS_SCANNING,
3031                                          &cfg_priv->status))) {
3032                 WL_ERR("Scan complete while device not scanning\n");
3033                 scan_abort = true;
3034                 err = -EINVAL;
3035                 goto scan_done_out;
3036         }
3037
3038         err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_CHANNEL, &channel_inform,
3039                         sizeof(channel_inform));
3040         if (unlikely(err)) {
3041                 WL_ERR("scan busy (%d)\n", err);
3042                 scan_abort = true;
3043                 goto scan_done_out;
3044         }
3045         channel_inform.scan_channel = le32_to_cpu(channel_inform.scan_channel);
3046         if (unlikely(channel_inform.scan_channel)) {
3047
3048                 WL_CONN("channel_inform.scan_channel (%d)\n",
3049                        channel_inform.scan_channel);
3050         }
3051         cfg_priv->bss_list = cfg_priv->scan_results;
3052         bss_list = cfg_priv->bss_list;
3053         memset(bss_list, 0, len);
3054         bss_list->buflen = cpu_to_le32(len);
3055
3056         err = brcmf_dev_ioctl(ndev, BRCMF_C_SCAN_RESULTS, bss_list, len);
3057         if (unlikely(err)) {
3058                 WL_ERR("%s Scan_results error (%d)\n", ndev->name, err);
3059                 err = -EINVAL;
3060                 scan_abort = true;
3061                 goto scan_done_out;
3062         }
3063         bss_list->buflen = le32_to_cpu(bss_list->buflen);
3064         bss_list->version = le32_to_cpu(bss_list->version);
3065         bss_list->count = le32_to_cpu(bss_list->count);
3066
3067         err = brcmf_inform_bss(cfg_priv);
3068         if (err) {
3069                 scan_abort = true;
3070                 goto scan_done_out;
3071         }
3072
3073 scan_done_out:
3074         if (cfg_priv->scan_request) {
3075                 WL_SCAN("calling cfg80211_scan_done\n");
3076                 cfg80211_scan_done(cfg_priv->scan_request, scan_abort);
3077                 brcmf_set_mpc(ndev, 1);
3078                 cfg_priv->scan_request = NULL;
3079         }
3080
3081         WL_TRACE("Exit\n");
3082
3083         return err;
3084 }
3085
3086 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
3087 {
3088         conf->mode = (u32)-1;
3089         conf->frag_threshold = (u32)-1;
3090         conf->rts_threshold = (u32)-1;
3091         conf->retry_short = (u32)-1;
3092         conf->retry_long = (u32)-1;
3093         conf->tx_power = -1;
3094 }
3095
3096 static void brcmf_init_eloop_handler(struct brcmf_cfg80211_event_loop *el)
3097 {
3098         memset(el, 0, sizeof(*el));
3099         el->handler[BRCMF_E_SCAN_COMPLETE] = brcmf_notify_scan_status;
3100         el->handler[BRCMF_E_LINK] = brcmf_notify_connect_status;
3101         el->handler[BRCMF_E_ROAM] = brcmf_notify_roaming_status;
3102         el->handler[BRCMF_E_MIC_ERROR] = brcmf_notify_mic_status;
3103         el->handler[BRCMF_E_SET_SSID] = brcmf_notify_connect_status;
3104 }
3105
3106 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3107 {
3108         kfree(cfg_priv->scan_results);
3109         cfg_priv->scan_results = NULL;
3110         kfree(cfg_priv->bss_info);
3111         cfg_priv->bss_info = NULL;
3112         kfree(cfg_priv->conf);
3113         cfg_priv->conf = NULL;
3114         kfree(cfg_priv->profile);
3115         cfg_priv->profile = NULL;
3116         kfree(cfg_priv->scan_req_int);
3117         cfg_priv->scan_req_int = NULL;
3118         kfree(cfg_priv->ioctl_buf);
3119         cfg_priv->ioctl_buf = NULL;
3120         kfree(cfg_priv->extra_buf);
3121         cfg_priv->extra_buf = NULL;
3122         kfree(cfg_priv->iscan);
3123         cfg_priv->iscan = NULL;
3124         kfree(cfg_priv->pmk_list);
3125         cfg_priv->pmk_list = NULL;
3126 }
3127
3128 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_priv *cfg_priv)
3129 {
3130         cfg_priv->scan_results = kzalloc(WL_SCAN_BUF_MAX, GFP_KERNEL);
3131         if (unlikely(!cfg_priv->scan_results)) {
3132                 WL_ERR("Scan results alloc failed\n");
3133                 goto init_priv_mem_out;
3134         }
3135         cfg_priv->conf = kzalloc(sizeof(*cfg_priv->conf), GFP_KERNEL);
3136         if (unlikely(!cfg_priv->conf)) {
3137                 WL_ERR("wl_conf alloc failed\n");
3138                 goto init_priv_mem_out;
3139         }
3140         cfg_priv->profile = kzalloc(sizeof(*cfg_priv->profile), GFP_KERNEL);
3141         if (unlikely(!cfg_priv->profile)) {
3142                 WL_ERR("wl_profile alloc failed\n");
3143                 goto init_priv_mem_out;
3144         }
3145         cfg_priv->bss_info = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3146         if (unlikely(!cfg_priv->bss_info)) {
3147                 WL_ERR("Bss information alloc failed\n");
3148                 goto init_priv_mem_out;
3149         }
3150         cfg_priv->scan_req_int = kzalloc(sizeof(*cfg_priv->scan_req_int),
3151                                          GFP_KERNEL);
3152         if (unlikely(!cfg_priv->scan_req_int)) {
3153                 WL_ERR("Scan req alloc failed\n");
3154                 goto init_priv_mem_out;
3155         }
3156         cfg_priv->ioctl_buf = kzalloc(WL_IOCTL_LEN_MAX, GFP_KERNEL);
3157         if (unlikely(!cfg_priv->ioctl_buf)) {
3158                 WL_ERR("Ioctl buf alloc failed\n");
3159                 goto init_priv_mem_out;
3160         }
3161         cfg_priv->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3162         if (unlikely(!cfg_priv->extra_buf)) {
3163                 WL_ERR("Extra buf alloc failed\n");
3164                 goto init_priv_mem_out;
3165         }
3166         cfg_priv->iscan = kzalloc(sizeof(*cfg_priv->iscan), GFP_KERNEL);
3167         if (unlikely(!cfg_priv->iscan)) {
3168                 WL_ERR("Iscan buf alloc failed\n");
3169                 goto init_priv_mem_out;
3170         }
3171         cfg_priv->pmk_list = kzalloc(sizeof(*cfg_priv->pmk_list), GFP_KERNEL);
3172         if (unlikely(!cfg_priv->pmk_list)) {
3173                 WL_ERR("pmk list alloc failed\n");
3174                 goto init_priv_mem_out;
3175         }
3176
3177         return 0;
3178
3179 init_priv_mem_out:
3180         brcmf_deinit_priv_mem(cfg_priv);
3181
3182         return -ENOMEM;
3183 }
3184
3185 static void brcmf_lock_eq(struct brcmf_cfg80211_priv *cfg_priv)
3186 {
3187         spin_lock_irq(&cfg_priv->eq_lock);
3188 }
3189
3190 static void brcmf_unlock_eq(struct brcmf_cfg80211_priv *cfg_priv)
3191 {
3192         spin_unlock_irq(&cfg_priv->eq_lock);
3193 }
3194
3195 static void brcmf_init_eq_lock(struct brcmf_cfg80211_priv *cfg_priv)
3196 {
3197         spin_lock_init(&cfg_priv->eq_lock);
3198 }
3199
3200 /*
3201 * retrieve first queued event from head
3202 */
3203
3204 static struct brcmf_cfg80211_event_q *brcmf_deq_event(
3205         struct brcmf_cfg80211_priv *cfg_priv)
3206 {
3207         struct brcmf_cfg80211_event_q *e = NULL;
3208
3209         brcmf_lock_eq(cfg_priv);
3210         if (likely(!list_empty(&cfg_priv->eq_list))) {
3211                 e = list_first_entry(&cfg_priv->eq_list,
3212                                      struct brcmf_cfg80211_event_q, eq_list);
3213                 list_del(&e->eq_list);
3214         }
3215         brcmf_unlock_eq(cfg_priv);
3216
3217         return e;
3218 }
3219
3220 /*
3221 ** push event to tail of the queue
3222 */
3223
3224 static s32
3225 brcmf_enq_event(struct brcmf_cfg80211_priv *cfg_priv, u32 event,
3226                 const struct brcmf_event_msg *msg)
3227 {
3228         struct brcmf_cfg80211_event_q *e;
3229         s32 err = 0;
3230
3231         e = kzalloc(sizeof(struct brcmf_cfg80211_event_q), GFP_KERNEL);
3232         if (unlikely(!e)) {
3233                 WL_ERR("event alloc failed\n");
3234                 return -ENOMEM;
3235         }
3236
3237         e->etype = event;
3238         memcpy(&e->emsg, msg, sizeof(struct brcmf_event_msg));
3239
3240         brcmf_lock_eq(cfg_priv);
3241         list_add_tail(&e->eq_list, &cfg_priv->eq_list);
3242         brcmf_unlock_eq(cfg_priv);
3243
3244         return err;
3245 }
3246
3247 static void brcmf_put_event(struct brcmf_cfg80211_event_q *e)
3248 {
3249         kfree(e);
3250 }
3251
3252 static s32 brcmf_event_handler(void *data)
3253 {
3254         struct brcmf_cfg80211_priv *cfg_priv =
3255                         (struct brcmf_cfg80211_priv *)data;
3256         struct sched_param param = {.sched_priority = MAX_RT_PRIO - 1 };
3257         struct brcmf_cfg80211_event_q *e;
3258         DECLARE_WAITQUEUE(wait, current);
3259
3260         sched_setscheduler(current, SCHED_FIFO, &param);
3261         allow_signal(SIGTERM);
3262         add_wait_queue(&cfg_priv->event_waitq, &wait);
3263         while (1) {
3264                 prepare_to_wait(&cfg_priv->event_waitq, &wait,
3265                                 TASK_INTERRUPTIBLE);
3266
3267                 schedule();
3268
3269                 if (kthread_should_stop())
3270                         break;
3271
3272                 e = brcmf_deq_event(cfg_priv);
3273                 if (unlikely(!e)) {
3274                         WL_ERR("event queue empty...\n");
3275                         continue;
3276                 }
3277
3278                 do {
3279                         WL_INFO("event type (%d)\n", e->etype);
3280                         if (cfg_priv->el.handler[e->etype])
3281                                 cfg_priv->el.handler[e->etype](cfg_priv,
3282                                         cfg_to_ndev(cfg_priv),
3283                                         &e->emsg, e->edata);
3284                         else
3285                                 WL_INFO("Unknown Event (%d): ignoring\n",
3286                                         e->etype);
3287                         brcmf_put_event(e);
3288                 } while ((e = brcmf_deq_event(cfg_priv)));
3289         }
3290         finish_wait(&cfg_priv->event_waitq, &wait);
3291         WL_INFO("was terminated\n");
3292         return 0;
3293 }
3294
3295 static s32 brcmf_create_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3296 {
3297         init_waitqueue_head(&cfg_priv->event_waitq);
3298         cfg_priv->event_tsk = kthread_run(brcmf_event_handler, cfg_priv,
3299                                           "wl_event_handler");
3300         if (IS_ERR(cfg_priv->event_tsk)) {
3301                 cfg_priv->event_tsk = NULL;
3302                 WL_ERR("failed to create event thread\n");
3303                 return -ENOMEM;
3304         }
3305         return 0;
3306 }
3307
3308 static void brcmf_destroy_event_handler(struct brcmf_cfg80211_priv *cfg_priv)
3309 {
3310         if (cfg_priv->event_tsk) {
3311                 send_sig(SIGTERM, cfg_priv->event_tsk, 1);
3312                 kthread_stop(cfg_priv->event_tsk);
3313                 cfg_priv->event_tsk = NULL;
3314         }
3315 }
3316
3317 static void brcmf_init_eq(struct brcmf_cfg80211_priv *cfg_priv)
3318 {
3319         brcmf_init_eq_lock(cfg_priv);
3320         INIT_LIST_HEAD(&cfg_priv->eq_list);
3321 }
3322
3323 static void brcmf_flush_eq(struct brcmf_cfg80211_priv *cfg_priv)
3324 {
3325         struct brcmf_cfg80211_event_q *e;
3326
3327         brcmf_lock_eq(cfg_priv);
3328         while (!list_empty(&cfg_priv->eq_list)) {
3329                 e = list_first_entry(&cfg_priv->eq_list,
3330                                      struct brcmf_cfg80211_event_q, eq_list);
3331                 list_del(&e->eq_list);
3332                 kfree(e);
3333         }
3334         brcmf_unlock_eq(cfg_priv);
3335 }
3336
3337 static s32 wl_init_priv(struct brcmf_cfg80211_priv *cfg_priv)
3338 {
3339         s32 err = 0;
3340
3341         cfg_priv->scan_request = NULL;
3342         cfg_priv->pwr_save = true;
3343         cfg_priv->iscan_on = true;      /* iscan on & off switch.
3344                                  we enable iscan per default */
3345         cfg_priv->roam_on = true;       /* roam on & off switch.
3346                                  we enable roam per default */
3347
3348         cfg_priv->iscan_kickstart = false;
3349         cfg_priv->active_scan = true;   /* we do active scan for
3350                                  specific scan per default */
3351         cfg_priv->dongle_up = false;    /* dongle is not up yet */
3352         brcmf_init_eq(cfg_priv);
3353         err = brcmf_init_priv_mem(cfg_priv);
3354         if (unlikely(err))
3355                 return err;
3356         if (unlikely(brcmf_create_event_handler(cfg_priv)))
3357                 return -ENOMEM;
3358         brcmf_init_eloop_handler(&cfg_priv->el);
3359         mutex_init(&cfg_priv->usr_sync);
3360         err = brcmf_init_iscan(cfg_priv);
3361         if (unlikely(err))
3362                 return err;
3363         brcmf_init_conf(cfg_priv->conf);
3364         brcmf_init_prof(cfg_priv->profile);
3365         brcmf_link_down(cfg_priv);
3366
3367         return err;
3368 }
3369
3370 static void wl_deinit_priv(struct brcmf_cfg80211_priv *cfg_priv)
3371 {
3372         brcmf_destroy_event_handler(cfg_priv);
3373         cfg_priv->dongle_up = false;    /* dongle down */
3374         brcmf_flush_eq(cfg_priv);
3375         brcmf_link_down(cfg_priv);
3376         brcmf_term_iscan(cfg_priv);
3377         brcmf_deinit_priv_mem(cfg_priv);
3378 }
3379
3380 struct brcmf_cfg80211_dev *brcmf_cfg80211_attach(struct net_device *ndev,
3381                                                  struct device *busdev,
3382                                                  void *data)
3383 {
3384         struct wireless_dev *wdev;
3385         struct brcmf_cfg80211_priv *cfg_priv;
3386         struct brcmf_cfg80211_iface *ci;
3387         struct brcmf_cfg80211_dev *cfg_dev;
3388         s32 err = 0;
3389
3390         if (unlikely(!ndev)) {
3391                 WL_ERR("ndev is invalid\n");
3392                 return NULL;
3393         }
3394         cfg_dev = kzalloc(sizeof(struct brcmf_cfg80211_dev), GFP_KERNEL);
3395         if (unlikely(!cfg_dev)) {
3396                 WL_ERR("wl_cfg80211_dev is invalid\n");
3397                 return NULL;
3398         }
3399
3400         wdev = brcmf_alloc_wdev(sizeof(struct brcmf_cfg80211_iface), busdev);
3401         if (IS_ERR(wdev)) {
3402                 kfree(cfg_dev);
3403                 return NULL;
3404         }
3405
3406         wdev->iftype = brcmf_mode_to_nl80211_iftype(WL_MODE_BSS);
3407         cfg_priv = wdev_to_cfg(wdev);
3408         cfg_priv->wdev = wdev;
3409         cfg_priv->pub = data;
3410         ci = (struct brcmf_cfg80211_iface *)&cfg_priv->ci;
3411         ci->cfg_priv = cfg_priv;
3412         ndev->ieee80211_ptr = wdev;
3413         SET_NETDEV_DEV(ndev, wiphy_dev(wdev->wiphy));
3414         wdev->netdev = ndev;
3415         err = wl_init_priv(cfg_priv);
3416         if (unlikely(err)) {
3417                 WL_ERR("Failed to init iwm_priv (%d)\n", err);
3418                 goto cfg80211_attach_out;
3419         }
3420         brcmf_set_drvdata(cfg_dev, ci);
3421
3422         return cfg_dev;
3423
3424 cfg80211_attach_out:
3425         brcmf_free_wdev(cfg_priv);
3426         kfree(cfg_dev);
3427         return NULL;
3428 }
3429
3430 void brcmf_cfg80211_detach(struct brcmf_cfg80211_dev *cfg_dev)
3431 {
3432         struct brcmf_cfg80211_priv *cfg_priv;
3433
3434         cfg_priv = brcmf_priv_get(cfg_dev);
3435
3436         wl_deinit_priv(cfg_priv);
3437         brcmf_free_wdev(cfg_priv);
3438         brcmf_set_drvdata(cfg_dev, NULL);
3439         kfree(cfg_dev);
3440 }
3441
3442 static void brcmf_wakeup_event(struct brcmf_cfg80211_priv *cfg_priv)
3443 {
3444         wake_up(&cfg_priv->event_waitq);
3445 }
3446
3447 void
3448 brcmf_cfg80211_event(struct net_device *ndev,
3449                   const struct brcmf_event_msg *e, void *data)
3450 {
3451         u32 event_type = be32_to_cpu(e->event_type);
3452         struct brcmf_cfg80211_priv *cfg_priv = ndev_to_cfg(ndev);
3453
3454         if (likely(!brcmf_enq_event(cfg_priv, event_type, e)))
3455                 brcmf_wakeup_event(cfg_priv);
3456 }
3457
3458 static s32 brcmf_dongle_mode(struct net_device *ndev, s32 iftype)
3459 {
3460         s32 infra = 0;
3461         s32 err = 0;
3462
3463         switch (iftype) {
3464         case NL80211_IFTYPE_MONITOR:
3465         case NL80211_IFTYPE_WDS:
3466                 WL_ERR("type (%d) : currently we do not support this mode\n",
3467                        iftype);
3468                 err = -EINVAL;
3469                 return err;
3470         case NL80211_IFTYPE_ADHOC:
3471                 infra = 0;
3472                 break;
3473         case NL80211_IFTYPE_STATION:
3474                 infra = 1;
3475                 break;
3476         default:
3477                 err = -EINVAL;
3478                 WL_ERR("invalid type (%d)\n", iftype);
3479                 return err;
3480         }
3481         err = brcmf_dev_ioctl_u32(ndev, BRCMF_C_SET_INFRA, &infra);
3482         if (unlikely(err)) {
3483                 WL_ERR("WLC_SET_INFRA error (%d)\n", err);
3484                 return err;
3485         }
3486
3487         return 0;
3488 }
3489
3490 static s32 brcmf_dongle_eventmsg(struct net_device *ndev)
3491 {
3492         /* Room for "event_msgs" + '\0' + bitvec */
3493         s8 iovbuf[BRCMF_EVENTING_MASK_LEN + 12];
3494         s8 eventmask[BRCMF_EVENTING_MASK_LEN];
3495         s32 err = 0;
3496
3497         WL_TRACE("Enter\n");
3498
3499         /* Setup event_msgs */
3500         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3501                     sizeof(iovbuf));
3502         err = brcmf_dev_ioctl(ndev, BRCMF_C_GET_VAR, iovbuf, sizeof(iovbuf));
3503         if (unlikely(err)) {
3504                 WL_ERR("Get event_msgs error (%d)\n", err);
3505                 goto dongle_eventmsg_out;
3506         }
3507         memcpy(eventmask, iovbuf, BRCMF_EVENTING_MASK_LEN);
3508
3509         setbit(eventmask, BRCMF_E_SET_SSID);
3510         setbit(eventmask, BRCMF_E_ROAM);
3511         setbit(eventmask, BRCMF_E_PRUNE);
3512         setbit(eventmask, BRCMF_E_AUTH);
3513         setbit(eventmask, BRCMF_E_REASSOC);
3514         setbit(eventmask, BRCMF_E_REASSOC_IND);
3515         setbit(eventmask, BRCMF_E_DEAUTH_IND);
3516         setbit(eventmask, BRCMF_E_DISASSOC_IND);
3517         setbit(eventmask, BRCMF_E_DISASSOC);
3518         setbit(eventmask, BRCMF_E_JOIN);
3519         setbit(eventmask, BRCMF_E_ASSOC_IND);
3520         setbit(eventmask, BRCMF_E_PSK_SUP);
3521         setbit(eventmask, BRCMF_E_LINK);
3522         setbit(eventmask, BRCMF_E_NDIS_LINK);
3523         setbit(eventmask, BRCMF_E_MIC_ERROR);
3524         setbit(eventmask, BRCMF_E_PMKID_CACHE);
3525         setbit(eventmask, BRCMF_E_TXFAIL);
3526         setbit(eventmask, BRCMF_E_JOIN_START);
3527         setbit(eventmask, BRCMF_E_SCAN_COMPLETE);
3528
3529         brcmu_mkiovar("event_msgs", eventmask, BRCMF_EVENTING_MASK_LEN, iovbuf,
3530                     sizeof(iovbuf));
3531         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3532         if (unlikely(err)) {
3533                 WL_ERR("Set event_msgs error (%d)\n", err);
3534                 goto dongle_eventmsg_out;
3535         }
3536
3537 dongle_eventmsg_out:
3538         WL_TRACE("Exit\n");
3539         return err;
3540 }
3541
3542 static s32
3543 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
3544 {
3545         s8 iovbuf[32];
3546         s32 roamtrigger[2];
3547         s32 roam_delta[2];
3548         s32 err = 0;
3549
3550         /*
3551          * Setup timeout if Beacons are lost and roam is
3552          * off to report link down
3553          */
3554         if (roamvar) {
3555                 brcmu_mkiovar("bcn_timeout", (char *)&bcn_timeout,
3556                         sizeof(bcn_timeout), iovbuf, sizeof(iovbuf));
3557                 err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR,
3558                                    iovbuf, sizeof(iovbuf));
3559                 if (unlikely(err)) {
3560                         WL_ERR("bcn_timeout error (%d)\n", err);
3561                         goto dongle_rom_out;
3562                 }
3563         }
3564
3565         /*
3566          * Enable/Disable built-in roaming to allow supplicant
3567          * to take care of roaming
3568          */
3569         WL_INFO("Internal Roaming = %s\n", roamvar ? "Off" : "On");
3570         brcmu_mkiovar("roam_off", (char *)&roamvar,
3571                                 sizeof(roamvar), iovbuf, sizeof(iovbuf));
3572         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_VAR, iovbuf, sizeof(iovbuf));
3573         if (unlikely(err)) {
3574                 WL_ERR("roam_off error (%d)\n", err);
3575                 goto dongle_rom_out;
3576         }
3577
3578         roamtrigger[0] = WL_ROAM_TRIGGER_LEVEL;
3579         roamtrigger[1] = BRCM_BAND_ALL;
3580         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_TRIGGER,
3581                         (void *)roamtrigger, sizeof(roamtrigger));
3582         if (unlikely(err)) {
3583                 WL_ERR("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
3584                 goto dongle_rom_out;
3585         }
3586
3587         roam_delta[0] = WL_ROAM_DELTA;
3588         roam_delta[1] = BRCM_BAND_ALL;
3589         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_ROAM_DELTA,
3590                                 (void *)roam_delta, sizeof(roam_delta));
3591         if (unlikely(err)) {
3592                 WL_ERR("WLC_SET_ROAM_DELTA error (%d)\n", err);
3593                 goto dongle_rom_out;
3594         }
3595
3596 dongle_rom_out:
3597         return err;
3598 }
3599
3600 static s32
3601 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
3602                 s32 scan_unassoc_time, s32 scan_passive_time)
3603 {
3604         s32 err = 0;
3605
3606         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_CHANNEL_TIME,
3607                            &scan_assoc_time, sizeof(scan_assoc_time));
3608         if (err) {
3609                 if (err == -EOPNOTSUPP)
3610                         WL_INFO("Scan assoc time is not supported\n");
3611                 else
3612                         WL_ERR("Scan assoc time error (%d)\n", err);
3613                 goto dongle_scantime_out;
3614         }
3615         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_UNASSOC_TIME,
3616                            &scan_unassoc_time, sizeof(scan_unassoc_time));
3617         if (err) {
3618                 if (err == -EOPNOTSUPP)
3619                         WL_INFO("Scan unassoc time is not supported\n");
3620                 else
3621                         WL_ERR("Scan unassoc time error (%d)\n", err);
3622                 goto dongle_scantime_out;
3623         }
3624
3625         err = brcmf_dev_ioctl(ndev, BRCMF_C_SET_SCAN_PASSIVE_TIME,
3626                            &scan_passive_time, sizeof(scan_passive_time));
3627         if (err) {
3628                 if (err == -EOPNOTSUPP)
3629                         WL_INFO("Scan passive time is not supported\n");
3630                 else
3631                         WL_ERR("Scan passive time error (%d)\n", err);
3632                 goto dongle_scantime_out;
3633         }
3634
3635 dongle_scantime_out:
3636         return err;
3637 }
3638
3639 static s32 wl_update_wiphybands(struct brcmf_cfg80211_priv *cfg_priv)
3640 {
3641         struct wiphy *wiphy;
3642         s32 phy_list;
3643         s8 phy;
3644         s32 err = 0;
3645
3646         err = brcmf_dev_ioctl(cfg_to_ndev(cfg_priv), BRCM_GET_PHYLIST,
3647                               &phy_list, sizeof(phy_list));
3648         if (unlikely(err)) {
3649                 WL_ERR("error (%d)\n", err);
3650                 return err;
3651         }
3652
3653         phy = ((char *)&phy_list)[1];
3654         WL_INFO("%c phy\n", phy);
3655         if (phy == 'n' || phy == 'a') {
3656                 wiphy = cfg_to_wiphy(cfg_priv);
3657                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
3658         }
3659
3660         return err;
3661 }
3662
3663 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_priv *cfg_priv)
3664 {
3665         return wl_update_wiphybands(cfg_priv);
3666 }
3667
3668 static s32 brcmf_config_dongle(struct brcmf_cfg80211_priv *cfg_priv,
3669                                bool need_lock)
3670 {
3671         struct net_device *ndev;
3672         struct wireless_dev *wdev;
3673         s32 power_mode;
3674         s32 err = 0;
3675
3676         if (cfg_priv->dongle_up)
3677                 return err;
3678
3679         ndev = cfg_to_ndev(cfg_priv);
3680         wdev = ndev->ieee80211_ptr;
3681         if (need_lock)
3682                 rtnl_lock();
3683
3684         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
3685                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
3686
3687         err = brcmf_dongle_eventmsg(ndev);
3688         if (unlikely(err))
3689                 goto default_conf_out;
3690
3691         power_mode = cfg_priv->pwr_save ? PM_FAST : PM_OFF;
3692         err = brcmf_dev_ioctl_u32(ndev, BRCMF_C_SET_PM, &power_mode);
3693         if (err)
3694                 goto default_conf_out;
3695         WL_INFO("power save set to %s\n",
3696                 (power_mode ? "enabled" : "disabled"));
3697
3698         err = brcmf_dongle_roam(ndev, (cfg_priv->roam_on ? 0 : 1),
3699                                 WL_BEACON_TIMEOUT);
3700         if (unlikely(err))
3701                 goto default_conf_out;
3702         err = brcmf_dongle_mode(ndev, wdev->iftype);
3703         if (unlikely(err && err != -EINPROGRESS))
3704                 goto default_conf_out;
3705         err = brcmf_dongle_probecap(cfg_priv);
3706         if (unlikely(err))
3707                 goto default_conf_out;
3708
3709         /* -EINPROGRESS: Call commit handler */
3710
3711 default_conf_out:
3712         if (need_lock)
3713                 rtnl_unlock();
3714
3715         cfg_priv->dongle_up = true;
3716
3717         return err;
3718
3719 }
3720
3721 static int brcmf_debugfs_add_netdev_params(struct brcmf_cfg80211_priv *cfg_priv)
3722 {
3723         char buf[10+IFNAMSIZ];
3724         struct dentry *fd;
3725         s32 err = 0;
3726
3727         sprintf(buf, "netdev:%s", cfg_to_ndev(cfg_priv)->name);
3728         cfg_priv->debugfsdir = debugfs_create_dir(buf,
3729                                         cfg_to_wiphy(cfg_priv)->debugfsdir);
3730
3731         fd = debugfs_create_u16("beacon_int", S_IRUGO, cfg_priv->debugfsdir,
3732                 (u16 *)&cfg_priv->profile->beacon_interval);
3733         if (!fd) {
3734                 err = -ENOMEM;
3735                 goto err_out;
3736         }
3737
3738         fd = debugfs_create_u8("dtim_period", S_IRUGO, cfg_priv->debugfsdir,
3739                 (u8 *)&cfg_priv->profile->dtim_period);
3740         if (!fd) {
3741                 err = -ENOMEM;
3742                 goto err_out;
3743         }
3744
3745 err_out:
3746         return err;
3747 }
3748
3749 static void brcmf_debugfs_remove_netdev(struct brcmf_cfg80211_priv *cfg_priv)
3750 {
3751         debugfs_remove_recursive(cfg_priv->debugfsdir);
3752         cfg_priv->debugfsdir = NULL;
3753 }
3754
3755 static s32 __brcmf_cfg80211_up(struct brcmf_cfg80211_priv *cfg_priv)
3756 {
3757         s32 err = 0;
3758
3759         set_bit(WL_STATUS_READY, &cfg_priv->status);
3760
3761         brcmf_debugfs_add_netdev_params(cfg_priv);
3762
3763         err = brcmf_config_dongle(cfg_priv, false);
3764         if (unlikely(err))
3765                 return err;
3766
3767         brcmf_invoke_iscan(cfg_priv);
3768
3769         return err;
3770 }
3771
3772 static s32 __brcmf_cfg80211_down(struct brcmf_cfg80211_priv *cfg_priv)
3773 {
3774         /*
3775          * While going down, if associated with AP disassociate
3776          * from AP to save power
3777          */
3778         if ((test_bit(WL_STATUS_CONNECTED, &cfg_priv->status) ||
3779              test_bit(WL_STATUS_CONNECTING, &cfg_priv->status)) &&
3780              test_bit(WL_STATUS_READY, &cfg_priv->status)) {
3781                 WL_INFO("Disassociating from AP");
3782                 brcmf_link_down(cfg_priv);
3783
3784                 /* Make sure WPA_Supplicant receives all the event
3785                    generated due to DISASSOC call to the fw to keep
3786                    the state fw and WPA_Supplicant state consistent
3787                  */
3788                 rtnl_unlock();
3789                 brcmf_delay(500);
3790                 rtnl_lock();
3791         }
3792
3793         set_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3794         brcmf_term_iscan(cfg_priv);
3795         if (cfg_priv->scan_request) {
3796                 cfg80211_scan_done(cfg_priv->scan_request, true);
3797                 /* May need to perform this to cover rmmod */
3798                 /* wl_set_mpc(cfg_to_ndev(wl), 1); */
3799                 cfg_priv->scan_request = NULL;
3800         }
3801         clear_bit(WL_STATUS_READY, &cfg_priv->status);
3802         clear_bit(WL_STATUS_SCANNING, &cfg_priv->status);
3803         clear_bit(WL_STATUS_SCAN_ABORTING, &cfg_priv->status);
3804
3805         brcmf_debugfs_remove_netdev(cfg_priv);
3806
3807         return 0;
3808 }
3809
3810 s32 brcmf_cfg80211_up(struct brcmf_cfg80211_dev *cfg_dev)
3811 {
3812         struct brcmf_cfg80211_priv *cfg_priv;
3813         s32 err = 0;
3814
3815         cfg_priv = brcmf_priv_get(cfg_dev);
3816         mutex_lock(&cfg_priv->usr_sync);
3817         err = __brcmf_cfg80211_up(cfg_priv);
3818         mutex_unlock(&cfg_priv->usr_sync);
3819
3820         return err;
3821 }
3822
3823 s32 brcmf_cfg80211_down(struct brcmf_cfg80211_dev *cfg_dev)
3824 {
3825         struct brcmf_cfg80211_priv *cfg_priv;
3826         s32 err = 0;
3827
3828         cfg_priv = brcmf_priv_get(cfg_dev);
3829         mutex_lock(&cfg_priv->usr_sync);
3830         err = __brcmf_cfg80211_down(cfg_priv);
3831         mutex_unlock(&cfg_priv->usr_sync);
3832
3833         return err;
3834 }
3835
3836 static __used s32 brcmf_add_ie(struct brcmf_cfg80211_priv *cfg_priv,
3837                                u8 t, u8 l, u8 *v)
3838 {
3839         struct brcmf_cfg80211_ie *ie = &cfg_priv->ie;
3840         s32 err = 0;
3841
3842         if (unlikely(ie->offset + l + 2 > WL_TLV_INFO_MAX)) {
3843                 WL_ERR("ei crosses buffer boundary\n");
3844                 return -ENOSPC;
3845         }
3846         ie->buf[ie->offset] = t;
3847         ie->buf[ie->offset + 1] = l;
3848         memcpy(&ie->buf[ie->offset + 2], v, l);
3849         ie->offset += l + 2;
3850
3851         return err;
3852 }