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