]> git.kernelconcepts.de Git - karo-tx-linux.git/blob - drivers/net/wireless/brcm80211/brcmfmac/wl_cfg80211.c
regulator: max8997: Convert max8997_safeout_ops to set_voltage_sel and list_voltage_table
[karo-tx-linux.git] / drivers / net / wireless / brcm80211 / brcmfmac / wl_cfg80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
19 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
20
21 #include <linux/kernel.h>
22 #include <linux/etherdevice.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
25
26 #include <brcmu_utils.h>
27 #include <defs.h>
28 #include <brcmu_wifi.h>
29 #include "dhd.h"
30 #include "dhd_dbg.h"
31 #include "wl_cfg80211.h"
32 #include "fwil.h"
33
34 #define BRCMF_SCAN_IE_LEN_MAX           2048
35 #define BRCMF_PNO_VERSION               2
36 #define BRCMF_PNO_TIME                  30
37 #define BRCMF_PNO_REPEAT                4
38 #define BRCMF_PNO_FREQ_EXPO_MAX         3
39 #define BRCMF_PNO_MAX_PFN_COUNT         16
40 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT  6
41 #define BRCMF_PNO_HIDDEN_BIT            2
42 #define BRCMF_PNO_WPA_AUTH_ANY          0xFFFFFFFF
43 #define BRCMF_PNO_SCAN_COMPLETE         1
44 #define BRCMF_PNO_SCAN_INCOMPLETE       0
45
46 #define BRCMF_IFACE_MAX_CNT             2
47
48 #define TLV_LEN_OFF                     1       /* length offset */
49 #define TLV_HDR_LEN                     2       /* header length */
50 #define TLV_BODY_OFF                    2       /* body offset */
51 #define TLV_OUI_LEN                     3       /* oui id length */
52 #define WPA_OUI                         "\x00\x50\xF2"  /* WPA OUI */
53 #define WPA_OUI_TYPE                    1
54 #define RSN_OUI                         "\x00\x0F\xAC"  /* RSN OUI */
55 #define WME_OUI_TYPE                    2
56
57 #define VS_IE_FIXED_HDR_LEN             6
58 #define WPA_IE_VERSION_LEN              2
59 #define WPA_IE_MIN_OUI_LEN              4
60 #define WPA_IE_SUITE_COUNT_LEN          2
61
62 #define WPA_CIPHER_NONE                 0       /* None */
63 #define WPA_CIPHER_WEP_40               1       /* WEP (40-bit) */
64 #define WPA_CIPHER_TKIP                 2       /* TKIP: default for WPA */
65 #define WPA_CIPHER_AES_CCM              4       /* AES (CCM) */
66 #define WPA_CIPHER_WEP_104              5       /* WEP (104-bit) */
67
68 #define RSN_AKM_NONE                    0       /* None (IBSS) */
69 #define RSN_AKM_UNSPECIFIED             1       /* Over 802.1x */
70 #define RSN_AKM_PSK                     2       /* Pre-shared Key */
71 #define RSN_CAP_LEN                     2       /* Length of RSN capabilities */
72 #define RSN_CAP_PTK_REPLAY_CNTR_MASK    0x000C
73
74 #define VNDR_IE_CMD_LEN                 4       /* length of the set command
75                                                  * string :"add", "del" (+ NUL)
76                                                  */
77 #define VNDR_IE_COUNT_OFFSET            4
78 #define VNDR_IE_PKTFLAG_OFFSET          8
79 #define VNDR_IE_VSIE_OFFSET             12
80 #define VNDR_IE_HDR_SIZE                12
81 #define VNDR_IE_BEACON_FLAG             0x1
82 #define VNDR_IE_PRBRSP_FLAG             0x2
83 #define MAX_VNDR_IE_NUMBER              5
84
85 #define DOT11_MGMT_HDR_LEN              24      /* d11 management header len */
86 #define DOT11_BCN_PRB_FIXED_LEN         12      /* beacon/probe fixed length */
87
88 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
89         (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
90
91 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
92 {
93         if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
94                 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
95                           vif->sme_state);
96                 return false;
97         }
98         return true;
99 }
100
101 #define CHAN2G(_channel, _freq, _flags) {                       \
102         .band                   = IEEE80211_BAND_2GHZ,          \
103         .center_freq            = (_freq),                      \
104         .hw_value               = (_channel),                   \
105         .flags                  = (_flags),                     \
106         .max_antenna_gain       = 0,                            \
107         .max_power              = 30,                           \
108 }
109
110 #define CHAN5G(_channel, _flags) {                              \
111         .band                   = IEEE80211_BAND_5GHZ,          \
112         .center_freq            = 5000 + (5 * (_channel)),      \
113         .hw_value               = (_channel),                   \
114         .flags                  = (_flags),                     \
115         .max_antenna_gain       = 0,                            \
116         .max_power              = 30,                           \
117 }
118
119 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
120 #define RATETAB_ENT(_rateid, _flags) \
121         {                                                               \
122                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
123                 .hw_value       = (_rateid),                            \
124                 .flags          = (_flags),                             \
125         }
126
127 static struct ieee80211_rate __wl_rates[] = {
128         RATETAB_ENT(BRCM_RATE_1M, 0),
129         RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
130         RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
131         RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
132         RATETAB_ENT(BRCM_RATE_6M, 0),
133         RATETAB_ENT(BRCM_RATE_9M, 0),
134         RATETAB_ENT(BRCM_RATE_12M, 0),
135         RATETAB_ENT(BRCM_RATE_18M, 0),
136         RATETAB_ENT(BRCM_RATE_24M, 0),
137         RATETAB_ENT(BRCM_RATE_36M, 0),
138         RATETAB_ENT(BRCM_RATE_48M, 0),
139         RATETAB_ENT(BRCM_RATE_54M, 0),
140 };
141
142 #define wl_a_rates              (__wl_rates + 4)
143 #define wl_a_rates_size 8
144 #define wl_g_rates              (__wl_rates + 0)
145 #define wl_g_rates_size 12
146
147 static struct ieee80211_channel __wl_2ghz_channels[] = {
148         CHAN2G(1, 2412, 0),
149         CHAN2G(2, 2417, 0),
150         CHAN2G(3, 2422, 0),
151         CHAN2G(4, 2427, 0),
152         CHAN2G(5, 2432, 0),
153         CHAN2G(6, 2437, 0),
154         CHAN2G(7, 2442, 0),
155         CHAN2G(8, 2447, 0),
156         CHAN2G(9, 2452, 0),
157         CHAN2G(10, 2457, 0),
158         CHAN2G(11, 2462, 0),
159         CHAN2G(12, 2467, 0),
160         CHAN2G(13, 2472, 0),
161         CHAN2G(14, 2484, 0),
162 };
163
164 static struct ieee80211_channel __wl_5ghz_a_channels[] = {
165         CHAN5G(34, 0), CHAN5G(36, 0),
166         CHAN5G(38, 0), CHAN5G(40, 0),
167         CHAN5G(42, 0), CHAN5G(44, 0),
168         CHAN5G(46, 0), CHAN5G(48, 0),
169         CHAN5G(52, 0), CHAN5G(56, 0),
170         CHAN5G(60, 0), CHAN5G(64, 0),
171         CHAN5G(100, 0), CHAN5G(104, 0),
172         CHAN5G(108, 0), CHAN5G(112, 0),
173         CHAN5G(116, 0), CHAN5G(120, 0),
174         CHAN5G(124, 0), CHAN5G(128, 0),
175         CHAN5G(132, 0), CHAN5G(136, 0),
176         CHAN5G(140, 0), CHAN5G(149, 0),
177         CHAN5G(153, 0), CHAN5G(157, 0),
178         CHAN5G(161, 0), CHAN5G(165, 0),
179         CHAN5G(184, 0), CHAN5G(188, 0),
180         CHAN5G(192, 0), CHAN5G(196, 0),
181         CHAN5G(200, 0), CHAN5G(204, 0),
182         CHAN5G(208, 0), CHAN5G(212, 0),
183         CHAN5G(216, 0),
184 };
185
186 static struct ieee80211_channel __wl_5ghz_n_channels[] = {
187         CHAN5G(32, 0), CHAN5G(34, 0),
188         CHAN5G(36, 0), CHAN5G(38, 0),
189         CHAN5G(40, 0), CHAN5G(42, 0),
190         CHAN5G(44, 0), CHAN5G(46, 0),
191         CHAN5G(48, 0), CHAN5G(50, 0),
192         CHAN5G(52, 0), CHAN5G(54, 0),
193         CHAN5G(56, 0), CHAN5G(58, 0),
194         CHAN5G(60, 0), CHAN5G(62, 0),
195         CHAN5G(64, 0), CHAN5G(66, 0),
196         CHAN5G(68, 0), CHAN5G(70, 0),
197         CHAN5G(72, 0), CHAN5G(74, 0),
198         CHAN5G(76, 0), CHAN5G(78, 0),
199         CHAN5G(80, 0), CHAN5G(82, 0),
200         CHAN5G(84, 0), CHAN5G(86, 0),
201         CHAN5G(88, 0), CHAN5G(90, 0),
202         CHAN5G(92, 0), CHAN5G(94, 0),
203         CHAN5G(96, 0), CHAN5G(98, 0),
204         CHAN5G(100, 0), CHAN5G(102, 0),
205         CHAN5G(104, 0), CHAN5G(106, 0),
206         CHAN5G(108, 0), CHAN5G(110, 0),
207         CHAN5G(112, 0), CHAN5G(114, 0),
208         CHAN5G(116, 0), CHAN5G(118, 0),
209         CHAN5G(120, 0), CHAN5G(122, 0),
210         CHAN5G(124, 0), CHAN5G(126, 0),
211         CHAN5G(128, 0), CHAN5G(130, 0),
212         CHAN5G(132, 0), CHAN5G(134, 0),
213         CHAN5G(136, 0), CHAN5G(138, 0),
214         CHAN5G(140, 0), CHAN5G(142, 0),
215         CHAN5G(144, 0), CHAN5G(145, 0),
216         CHAN5G(146, 0), CHAN5G(147, 0),
217         CHAN5G(148, 0), CHAN5G(149, 0),
218         CHAN5G(150, 0), CHAN5G(151, 0),
219         CHAN5G(152, 0), CHAN5G(153, 0),
220         CHAN5G(154, 0), CHAN5G(155, 0),
221         CHAN5G(156, 0), CHAN5G(157, 0),
222         CHAN5G(158, 0), CHAN5G(159, 0),
223         CHAN5G(160, 0), CHAN5G(161, 0),
224         CHAN5G(162, 0), CHAN5G(163, 0),
225         CHAN5G(164, 0), CHAN5G(165, 0),
226         CHAN5G(166, 0), CHAN5G(168, 0),
227         CHAN5G(170, 0), CHAN5G(172, 0),
228         CHAN5G(174, 0), CHAN5G(176, 0),
229         CHAN5G(178, 0), CHAN5G(180, 0),
230         CHAN5G(182, 0), CHAN5G(184, 0),
231         CHAN5G(186, 0), CHAN5G(188, 0),
232         CHAN5G(190, 0), CHAN5G(192, 0),
233         CHAN5G(194, 0), CHAN5G(196, 0),
234         CHAN5G(198, 0), CHAN5G(200, 0),
235         CHAN5G(202, 0), CHAN5G(204, 0),
236         CHAN5G(206, 0), CHAN5G(208, 0),
237         CHAN5G(210, 0), CHAN5G(212, 0),
238         CHAN5G(214, 0), CHAN5G(216, 0),
239         CHAN5G(218, 0), CHAN5G(220, 0),
240         CHAN5G(222, 0), CHAN5G(224, 0),
241         CHAN5G(226, 0), CHAN5G(228, 0),
242 };
243
244 static struct ieee80211_supported_band __wl_band_2ghz = {
245         .band = IEEE80211_BAND_2GHZ,
246         .channels = __wl_2ghz_channels,
247         .n_channels = ARRAY_SIZE(__wl_2ghz_channels),
248         .bitrates = wl_g_rates,
249         .n_bitrates = wl_g_rates_size,
250 };
251
252 static struct ieee80211_supported_band __wl_band_5ghz_a = {
253         .band = IEEE80211_BAND_5GHZ,
254         .channels = __wl_5ghz_a_channels,
255         .n_channels = ARRAY_SIZE(__wl_5ghz_a_channels),
256         .bitrates = wl_a_rates,
257         .n_bitrates = wl_a_rates_size,
258 };
259
260 static struct ieee80211_supported_band __wl_band_5ghz_n = {
261         .band = IEEE80211_BAND_5GHZ,
262         .channels = __wl_5ghz_n_channels,
263         .n_channels = ARRAY_SIZE(__wl_5ghz_n_channels),
264         .bitrates = wl_a_rates,
265         .n_bitrates = wl_a_rates_size,
266 };
267
268 static const u32 __wl_cipher_suites[] = {
269         WLAN_CIPHER_SUITE_WEP40,
270         WLAN_CIPHER_SUITE_WEP104,
271         WLAN_CIPHER_SUITE_TKIP,
272         WLAN_CIPHER_SUITE_CCMP,
273         WLAN_CIPHER_SUITE_AES_CMAC,
274 };
275
276 /* tag_ID/length/value_buffer tuple */
277 struct brcmf_tlv {
278         u8 id;
279         u8 len;
280         u8 data[1];
281 };
282
283 /* Vendor specific ie. id = 221, oui and type defines exact ie */
284 struct brcmf_vs_tlv {
285         u8 id;
286         u8 len;
287         u8 oui[3];
288         u8 oui_type;
289 };
290
291 struct parsed_vndr_ie_info {
292         u8 *ie_ptr;
293         u32 ie_len;     /* total length including id & length field */
294         struct brcmf_vs_tlv vndrie;
295 };
296
297 struct parsed_vndr_ies {
298         u32 count;
299         struct parsed_vndr_ie_info ie_info[MAX_VNDR_IE_NUMBER];
300 };
301
302 /* Quarter dBm units to mW
303  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
304  * Table is offset so the last entry is largest mW value that fits in
305  * a u16.
306  */
307
308 #define QDBM_OFFSET 153         /* Offset for first entry */
309 #define QDBM_TABLE_LEN 40       /* Table size */
310
311 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
312  * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
313  */
314 #define QDBM_TABLE_LOW_BOUND 6493       /* Low bound */
315
316 /* Largest mW value that will round down to the last table entry,
317  * QDBM_OFFSET + QDBM_TABLE_LEN-1.
318  * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
319  * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
320  */
321 #define QDBM_TABLE_HIGH_BOUND 64938     /* High bound */
322
323 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
324 /* qdBm:        +0      +1      +2      +3      +4      +5      +6      +7 */
325 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
326 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
327 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
328 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
329 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
330 };
331
332 static u16 brcmf_qdbm_to_mw(u8 qdbm)
333 {
334         uint factor = 1;
335         int idx = qdbm - QDBM_OFFSET;
336
337         if (idx >= QDBM_TABLE_LEN)
338                 /* clamp to max u16 mW value */
339                 return 0xFFFF;
340
341         /* scale the qdBm index up to the range of the table 0-40
342          * where an offset of 40 qdBm equals a factor of 10 mW.
343          */
344         while (idx < 0) {
345                 idx += 40;
346                 factor *= 10;
347         }
348
349         /* return the mW value scaled down to the correct factor of 10,
350          * adding in factor/2 to get proper rounding.
351          */
352         return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
353 }
354
355 static u8 brcmf_mw_to_qdbm(u16 mw)
356 {
357         u8 qdbm;
358         int offset;
359         uint mw_uint = mw;
360         uint boundary;
361
362         /* handle boundary case */
363         if (mw_uint <= 1)
364                 return 0;
365
366         offset = QDBM_OFFSET;
367
368         /* move mw into the range of the table */
369         while (mw_uint < QDBM_TABLE_LOW_BOUND) {
370                 mw_uint *= 10;
371                 offset -= 40;
372         }
373
374         for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
375                 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
376                                                     nqdBm_to_mW_map[qdbm]) / 2;
377                 if (mw_uint < boundary)
378                         break;
379         }
380
381         qdbm += (u8) offset;
382
383         return qdbm;
384 }
385
386 static u16 channel_to_chanspec(struct ieee80211_channel *ch)
387 {
388         u16 chanspec;
389
390         chanspec = ieee80211_frequency_to_channel(ch->center_freq);
391         chanspec &= WL_CHANSPEC_CHAN_MASK;
392
393         if (ch->band == IEEE80211_BAND_2GHZ)
394                 chanspec |= WL_CHANSPEC_BAND_2G;
395         else
396                 chanspec |= WL_CHANSPEC_BAND_5G;
397
398         if (ch->flags & IEEE80211_CHAN_NO_HT40) {
399                 chanspec |= WL_CHANSPEC_BW_20;
400                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
401         } else {
402                 chanspec |= WL_CHANSPEC_BW_40;
403                 if (ch->flags & IEEE80211_CHAN_NO_HT40PLUS)
404                         chanspec |= WL_CHANSPEC_CTL_SB_LOWER;
405                 else
406                         chanspec |= WL_CHANSPEC_CTL_SB_UPPER;
407         }
408         return chanspec;
409 }
410
411 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
412                                  struct brcmf_wsec_key_le *key_le)
413 {
414         key_le->index = cpu_to_le32(key->index);
415         key_le->len = cpu_to_le32(key->len);
416         key_le->algo = cpu_to_le32(key->algo);
417         key_le->flags = cpu_to_le32(key->flags);
418         key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
419         key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
420         key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
421         memcpy(key_le->data, key->data, sizeof(key->data));
422         memcpy(key_le->ea, key->ea, sizeof(key->ea));
423 }
424
425 static int
426 send_key_to_dongle(struct net_device *ndev, struct brcmf_wsec_key *key)
427 {
428         int err;
429         struct brcmf_wsec_key_le key_le;
430
431         convert_key_from_CPU(key, &key_le);
432
433         brcmf_netdev_wait_pend8021x(ndev);
434
435         err = brcmf_fil_bsscfg_data_set(netdev_priv(ndev), "wsec_key", &key_le,
436                                         sizeof(key_le));
437
438         if (err)
439                 brcmf_err("wsec_key error (%d)\n", err);
440         return err;
441 }
442
443 static s32
444 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
445                          enum nl80211_iftype type, u32 *flags,
446                          struct vif_params *params)
447 {
448         struct brcmf_if *ifp = netdev_priv(ndev);
449         struct brcmf_cfg80211_vif *vif = ifp->vif;
450         s32 infra = 0;
451         s32 ap = 0;
452         s32 err = 0;
453
454         brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
455
456         switch (type) {
457         case NL80211_IFTYPE_MONITOR:
458         case NL80211_IFTYPE_WDS:
459                 brcmf_err("type (%d) : currently we do not support this type\n",
460                           type);
461                 return -EOPNOTSUPP;
462         case NL80211_IFTYPE_ADHOC:
463                 vif->mode = WL_MODE_IBSS;
464                 infra = 0;
465                 break;
466         case NL80211_IFTYPE_STATION:
467                 vif->mode = WL_MODE_BSS;
468                 infra = 1;
469                 break;
470         case NL80211_IFTYPE_AP:
471                 vif->mode = WL_MODE_AP;
472                 ap = 1;
473                 break;
474         default:
475                 err = -EINVAL;
476                 goto done;
477         }
478
479         if (ap) {
480                 set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
481                 brcmf_dbg(INFO, "IF Type = AP\n");
482         } else {
483                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
484                 if (err) {
485                         brcmf_err("WLC_SET_INFRA error (%d)\n", err);
486                         err = -EAGAIN;
487                         goto done;
488                 }
489                 brcmf_dbg(INFO, "IF Type = %s\n", (vif->mode == WL_MODE_IBSS) ?
490                           "Adhoc" : "Infra");
491         }
492         ndev->ieee80211_ptr->iftype = type;
493
494 done:
495         brcmf_dbg(TRACE, "Exit\n");
496
497         return err;
498 }
499
500 static void brcmf_set_mpc(struct net_device *ndev, int mpc)
501 {
502         struct brcmf_if *ifp = netdev_priv(ndev);
503         s32 err = 0;
504
505         if (check_vif_up(ifp->vif)) {
506                 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
507                 if (err) {
508                         brcmf_err("fail to set mpc\n");
509                         return;
510                 }
511                 brcmf_dbg(INFO, "MPC : %d\n", mpc);
512         }
513 }
514
515 static void brcmf_escan_prep(struct brcmf_scan_params_le *params_le,
516                              struct cfg80211_scan_request *request)
517 {
518         u32 n_ssids;
519         u32 n_channels;
520         s32 i;
521         s32 offset;
522         u16 chanspec;
523         char *ptr;
524         struct brcmf_ssid_le ssid_le;
525
526         memset(params_le->bssid, 0xFF, ETH_ALEN);
527         params_le->bss_type = DOT11_BSSTYPE_ANY;
528         params_le->scan_type = 0;
529         params_le->channel_num = 0;
530         params_le->nprobes = cpu_to_le32(-1);
531         params_le->active_time = cpu_to_le32(-1);
532         params_le->passive_time = cpu_to_le32(-1);
533         params_le->home_time = cpu_to_le32(-1);
534         memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
535
536         /* if request is null exit so it will be all channel broadcast scan */
537         if (!request)
538                 return;
539
540         n_ssids = request->n_ssids;
541         n_channels = request->n_channels;
542         /* Copy channel array if applicable */
543         brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
544                   n_channels);
545         if (n_channels > 0) {
546                 for (i = 0; i < n_channels; i++) {
547                         chanspec = channel_to_chanspec(request->channels[i]);
548                         brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
549                                   request->channels[i]->hw_value, chanspec);
550                         params_le->channel_list[i] = cpu_to_le16(chanspec);
551                 }
552         } else {
553                 brcmf_dbg(SCAN, "Scanning all channels\n");
554         }
555         /* Copy ssid array if applicable */
556         brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
557         if (n_ssids > 0) {
558                 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
559                                 n_channels * sizeof(u16);
560                 offset = roundup(offset, sizeof(u32));
561                 ptr = (char *)params_le + offset;
562                 for (i = 0; i < n_ssids; i++) {
563                         memset(&ssid_le, 0, sizeof(ssid_le));
564                         ssid_le.SSID_len =
565                                         cpu_to_le32(request->ssids[i].ssid_len);
566                         memcpy(ssid_le.SSID, request->ssids[i].ssid,
567                                request->ssids[i].ssid_len);
568                         if (!ssid_le.SSID_len)
569                                 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
570                         else
571                                 brcmf_dbg(SCAN, "%d: scan for  %s size =%d\n",
572                                           i, ssid_le.SSID, ssid_le.SSID_len);
573                         memcpy(ptr, &ssid_le, sizeof(ssid_le));
574                         ptr += sizeof(ssid_le);
575                 }
576         } else {
577                 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
578                 if ((request->ssids) && request->ssids->ssid_len) {
579                         brcmf_dbg(SCAN, "SSID %s len=%d\n",
580                                   params_le->ssid_le.SSID,
581                                   request->ssids->ssid_len);
582                         params_le->ssid_le.SSID_len =
583                                 cpu_to_le32(request->ssids->ssid_len);
584                         memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
585                                 request->ssids->ssid_len);
586                 }
587         }
588         /* Adding mask to channel numbers */
589         params_le->channel_num =
590                 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
591                         (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
592 }
593
594 static s32
595 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
596                             struct net_device *ndev,
597                             bool aborted, bool fw_abort)
598 {
599         struct brcmf_scan_params_le params_le;
600         struct cfg80211_scan_request *scan_request;
601         s32 err = 0;
602
603         brcmf_dbg(SCAN, "Enter\n");
604
605         /* clear scan request, because the FW abort can cause a second call */
606         /* to this functon and might cause a double cfg80211_scan_done      */
607         scan_request = cfg->scan_request;
608         cfg->scan_request = NULL;
609
610         if (timer_pending(&cfg->escan_timeout))
611                 del_timer_sync(&cfg->escan_timeout);
612
613         if (fw_abort) {
614                 /* Do a scan abort to stop the driver's scan engine */
615                 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
616                 memset(&params_le, 0, sizeof(params_le));
617                 memset(params_le.bssid, 0xFF, ETH_ALEN);
618                 params_le.bss_type = DOT11_BSSTYPE_ANY;
619                 params_le.scan_type = 0;
620                 params_le.channel_num = cpu_to_le32(1);
621                 params_le.nprobes = cpu_to_le32(1);
622                 params_le.active_time = cpu_to_le32(-1);
623                 params_le.passive_time = cpu_to_le32(-1);
624                 params_le.home_time = cpu_to_le32(-1);
625                 /* Scan is aborted by setting channel_list[0] to -1 */
626                 params_le.channel_list[0] = cpu_to_le16(-1);
627                 /* E-Scan (or anyother type) can be aborted by SCAN */
628                 err = brcmf_fil_cmd_data_set(netdev_priv(ndev), BRCMF_C_SCAN,
629                                              &params_le, sizeof(params_le));
630                 if (err)
631                         brcmf_err("Scan abort  failed\n");
632         }
633         /*
634          * e-scan can be initiated by scheduled scan
635          * which takes precedence.
636          */
637         if (cfg->sched_escan) {
638                 brcmf_dbg(SCAN, "scheduled scan completed\n");
639                 cfg->sched_escan = false;
640                 if (!aborted)
641                         cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
642                 brcmf_set_mpc(ndev, 1);
643         } else if (scan_request) {
644                 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
645                           aborted ? "Aborted" : "Done");
646                 cfg80211_scan_done(scan_request, aborted);
647                 brcmf_set_mpc(ndev, 1);
648         }
649         if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
650                 brcmf_err("Scan complete while device not scanning\n");
651                 return -EPERM;
652         }
653
654         return err;
655 }
656
657 static s32
658 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct net_device *ndev,
659                 struct cfg80211_scan_request *request, u16 action)
660 {
661         s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
662                           offsetof(struct brcmf_escan_params_le, params_le);
663         struct brcmf_escan_params_le *params;
664         s32 err = 0;
665
666         brcmf_dbg(SCAN, "E-SCAN START\n");
667
668         if (request != NULL) {
669                 /* Allocate space for populating ssids in struct */
670                 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
671
672                 /* Allocate space for populating ssids in struct */
673                 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
674         }
675
676         params = kzalloc(params_size, GFP_KERNEL);
677         if (!params) {
678                 err = -ENOMEM;
679                 goto exit;
680         }
681         BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
682         brcmf_escan_prep(&params->params_le, request);
683         params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
684         params->action = cpu_to_le16(action);
685         params->sync_id = cpu_to_le16(0x1234);
686
687         err = brcmf_fil_iovar_data_set(netdev_priv(ndev), "escan",
688                                        params, params_size);
689         if (err) {
690                 if (err == -EBUSY)
691                         brcmf_dbg(INFO, "system busy : escan canceled\n");
692                 else
693                         brcmf_err("error (%d)\n", err);
694         }
695
696         kfree(params);
697 exit:
698         return err;
699 }
700
701 static s32
702 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
703                struct net_device *ndev, struct cfg80211_scan_request *request)
704 {
705         s32 err;
706         u32 passive_scan;
707         struct brcmf_scan_results *results;
708
709         brcmf_dbg(SCAN, "Enter\n");
710         cfg->escan_info.ndev = ndev;
711         cfg->escan_info.wiphy = wiphy;
712         cfg->escan_info.escan_state = WL_ESCAN_STATE_SCANNING;
713         passive_scan = cfg->active_scan ? 0 : 1;
714         err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PASSIVE_SCAN,
715                                     passive_scan);
716         if (err) {
717                 brcmf_err("error (%d)\n", err);
718                 return err;
719         }
720         brcmf_set_mpc(ndev, 0);
721         results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
722         results->version = 0;
723         results->count = 0;
724         results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
725
726         err = brcmf_run_escan(cfg, ndev, request, WL_ESCAN_ACTION_START);
727         if (err)
728                 brcmf_set_mpc(ndev, 1);
729         return err;
730 }
731
732 static s32
733 brcmf_cfg80211_escan(struct wiphy *wiphy, struct net_device *ndev,
734                      struct cfg80211_scan_request *request,
735                      struct cfg80211_ssid *this_ssid)
736 {
737         struct brcmf_if *ifp = netdev_priv(ndev);
738         struct brcmf_cfg80211_info *cfg = ndev_to_cfg(ndev);
739         struct cfg80211_ssid *ssids;
740         struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
741         u32 passive_scan;
742         bool escan_req;
743         bool spec_scan;
744         s32 err;
745         u32 SSID_len;
746
747         brcmf_dbg(SCAN, "START ESCAN\n");
748
749         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
750                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
751                 return -EAGAIN;
752         }
753         if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
754                 brcmf_err("Scanning being aborted: status (%lu)\n",
755                           cfg->scan_status);
756                 return -EAGAIN;
757         }
758         if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
759                 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
760                 return -EAGAIN;
761         }
762
763         /* Arm scan timeout timer */
764         mod_timer(&cfg->escan_timeout, jiffies +
765                         WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
766
767         escan_req = false;
768         if (request) {
769                 /* scan bss */
770                 ssids = request->ssids;
771                 escan_req = true;
772         } else {
773                 /* scan in ibss */
774                 /* we don't do escan in ibss */
775                 ssids = this_ssid;
776         }
777
778         cfg->scan_request = request;
779         set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
780         if (escan_req) {
781                 err = brcmf_do_escan(cfg, wiphy, ndev, request);
782                 if (err)
783                         goto scan_out;
784         } else {
785                 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
786                           ssids->ssid, ssids->ssid_len);
787                 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
788                 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
789                 sr->ssid_le.SSID_len = cpu_to_le32(0);
790                 spec_scan = false;
791                 if (SSID_len) {
792                         memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
793                         sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
794                         spec_scan = true;
795                 } else
796                         brcmf_dbg(SCAN, "Broadcast scan\n");
797
798                 passive_scan = cfg->active_scan ? 0 : 1;
799                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
800                                             passive_scan);
801                 if (err) {
802                         brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
803                         goto scan_out;
804                 }
805                 brcmf_set_mpc(ndev, 0);
806                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
807                                              &sr->ssid_le, sizeof(sr->ssid_le));
808                 if (err) {
809                         if (err == -EBUSY)
810                                 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
811                                           sr->ssid_le.SSID);
812                         else
813                                 brcmf_err("WLC_SCAN error (%d)\n", err);
814
815                         brcmf_set_mpc(ndev, 1);
816                         goto scan_out;
817                 }
818         }
819
820         return 0;
821
822 scan_out:
823         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
824         if (timer_pending(&cfg->escan_timeout))
825                 del_timer_sync(&cfg->escan_timeout);
826         cfg->scan_request = NULL;
827         return err;
828 }
829
830 static s32
831 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
832 {
833         struct net_device *ndev = request->wdev->netdev;
834         s32 err = 0;
835
836         brcmf_dbg(TRACE, "Enter\n");
837
838         if (!check_vif_up(container_of(request->wdev,
839                                        struct brcmf_cfg80211_vif, wdev)))
840                 return -EIO;
841
842         err = brcmf_cfg80211_escan(wiphy, ndev, request, NULL);
843
844         if (err)
845                 brcmf_err("scan error (%d)\n", err);
846
847         brcmf_dbg(TRACE, "Exit\n");
848         return err;
849 }
850
851 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
852 {
853         s32 err = 0;
854
855         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
856                                       rts_threshold);
857         if (err)
858                 brcmf_err("Error (%d)\n", err);
859
860         return err;
861 }
862
863 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
864 {
865         s32 err = 0;
866
867         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
868                                       frag_threshold);
869         if (err)
870                 brcmf_err("Error (%d)\n", err);
871
872         return err;
873 }
874
875 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
876 {
877         s32 err = 0;
878         u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
879
880         err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
881         if (err) {
882                 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
883                 return err;
884         }
885         return err;
886 }
887
888 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
889 {
890         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
891         struct net_device *ndev = cfg_to_ndev(cfg);
892         struct brcmf_if *ifp = netdev_priv(ndev);
893         s32 err = 0;
894
895         brcmf_dbg(TRACE, "Enter\n");
896         if (!check_vif_up(ifp->vif))
897                 return -EIO;
898
899         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
900             (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
901                 cfg->conf->rts_threshold = wiphy->rts_threshold;
902                 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
903                 if (!err)
904                         goto done;
905         }
906         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
907             (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
908                 cfg->conf->frag_threshold = wiphy->frag_threshold;
909                 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
910                 if (!err)
911                         goto done;
912         }
913         if (changed & WIPHY_PARAM_RETRY_LONG
914             && (cfg->conf->retry_long != wiphy->retry_long)) {
915                 cfg->conf->retry_long = wiphy->retry_long;
916                 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
917                 if (!err)
918                         goto done;
919         }
920         if (changed & WIPHY_PARAM_RETRY_SHORT
921             && (cfg->conf->retry_short != wiphy->retry_short)) {
922                 cfg->conf->retry_short = wiphy->retry_short;
923                 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
924                 if (!err)
925                         goto done;
926         }
927
928 done:
929         brcmf_dbg(TRACE, "Exit\n");
930         return err;
931 }
932
933 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
934 {
935         memset(prof, 0, sizeof(*prof));
936 }
937
938 static void brcmf_ch_to_chanspec(int ch, struct brcmf_join_params *join_params,
939         size_t *join_params_size)
940 {
941         u16 chanspec = 0;
942
943         if (ch != 0) {
944                 if (ch <= CH_MAX_2G_CHANNEL)
945                         chanspec |= WL_CHANSPEC_BAND_2G;
946                 else
947                         chanspec |= WL_CHANSPEC_BAND_5G;
948
949                 chanspec |= WL_CHANSPEC_BW_20;
950                 chanspec |= WL_CHANSPEC_CTL_SB_NONE;
951
952                 *join_params_size += BRCMF_ASSOC_PARAMS_FIXED_SIZE +
953                                      sizeof(u16);
954
955                 chanspec |= (ch & WL_CHANSPEC_CHAN_MASK);
956                 join_params->params_le.chanspec_list[0] = cpu_to_le16(chanspec);
957                 join_params->params_le.chanspec_num = cpu_to_le32(1);
958
959                 brcmf_dbg(CONN, "channel %d, chanspec %#X\n", ch, chanspec);
960         }
961 }
962
963 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif)
964 {
965         s32 err = 0;
966
967         brcmf_dbg(TRACE, "Enter\n");
968
969         if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
970                 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
971                 err = brcmf_fil_cmd_data_set(vif->ifp,
972                                              BRCMF_C_DISASSOC, NULL, 0);
973                 if (err)
974                         brcmf_err("WLC_DISASSOC failed (%d)\n", err);
975                 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
976         }
977         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
978         brcmf_dbg(TRACE, "Exit\n");
979 }
980
981 static s32
982 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
983                       struct cfg80211_ibss_params *params)
984 {
985         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
986         struct brcmf_if *ifp = netdev_priv(ndev);
987         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
988         struct brcmf_join_params join_params;
989         size_t join_params_size = 0;
990         s32 err = 0;
991         s32 wsec = 0;
992         s32 bcnprd;
993
994         brcmf_dbg(TRACE, "Enter\n");
995         if (!check_vif_up(ifp->vif))
996                 return -EIO;
997
998         if (params->ssid)
999                 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1000         else {
1001                 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1002                 return -EOPNOTSUPP;
1003         }
1004
1005         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1006
1007         if (params->bssid)
1008                 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1009         else
1010                 brcmf_dbg(CONN, "No BSSID specified\n");
1011
1012         if (params->chandef.chan)
1013                 brcmf_dbg(CONN, "channel: %d\n",
1014                           params->chandef.chan->center_freq);
1015         else
1016                 brcmf_dbg(CONN, "no channel specified\n");
1017
1018         if (params->channel_fixed)
1019                 brcmf_dbg(CONN, "fixed channel required\n");
1020         else
1021                 brcmf_dbg(CONN, "no fixed channel required\n");
1022
1023         if (params->ie && params->ie_len)
1024                 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1025         else
1026                 brcmf_dbg(CONN, "no ie specified\n");
1027
1028         if (params->beacon_interval)
1029                 brcmf_dbg(CONN, "beacon interval: %d\n",
1030                           params->beacon_interval);
1031         else
1032                 brcmf_dbg(CONN, "no beacon interval specified\n");
1033
1034         if (params->basic_rates)
1035                 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1036         else
1037                 brcmf_dbg(CONN, "no basic rates specified\n");
1038
1039         if (params->privacy)
1040                 brcmf_dbg(CONN, "privacy required\n");
1041         else
1042                 brcmf_dbg(CONN, "no privacy required\n");
1043
1044         /* Configure Privacy for starter */
1045         if (params->privacy)
1046                 wsec |= WEP_ENABLED;
1047
1048         err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1049         if (err) {
1050                 brcmf_err("wsec failed (%d)\n", err);
1051                 goto done;
1052         }
1053
1054         /* Configure Beacon Interval for starter */
1055         if (params->beacon_interval)
1056                 bcnprd = params->beacon_interval;
1057         else
1058                 bcnprd = 100;
1059
1060         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1061         if (err) {
1062                 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1063                 goto done;
1064         }
1065
1066         /* Configure required join parameter */
1067         memset(&join_params, 0, sizeof(struct brcmf_join_params));
1068
1069         /* SSID */
1070         profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1071         memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1072         memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1073         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1074         join_params_size = sizeof(join_params.ssid_le);
1075
1076         /* BSSID */
1077         if (params->bssid) {
1078                 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1079                 join_params_size = sizeof(join_params.ssid_le) +
1080                                    BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1081                 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1082         } else {
1083                 memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1084                 memset(profile->bssid, 0, ETH_ALEN);
1085         }
1086
1087         /* Channel */
1088         if (params->chandef.chan) {
1089                 u32 target_channel;
1090
1091                 cfg->channel =
1092                         ieee80211_frequency_to_channel(
1093                                 params->chandef.chan->center_freq);
1094                 if (params->channel_fixed) {
1095                         /* adding chanspec */
1096                         brcmf_ch_to_chanspec(cfg->channel,
1097                                 &join_params, &join_params_size);
1098                 }
1099
1100                 /* set channel for starter */
1101                 target_channel = cfg->channel;
1102                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1103                                             target_channel);
1104                 if (err) {
1105                         brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1106                         goto done;
1107                 }
1108         } else
1109                 cfg->channel = 0;
1110
1111         cfg->ibss_starter = false;
1112
1113
1114         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1115                                      &join_params, join_params_size);
1116         if (err) {
1117                 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1118                 goto done;
1119         }
1120
1121 done:
1122         if (err)
1123                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1124         brcmf_dbg(TRACE, "Exit\n");
1125         return err;
1126 }
1127
1128 static s32
1129 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1130 {
1131         struct brcmf_if *ifp = netdev_priv(ndev);
1132         s32 err = 0;
1133
1134         brcmf_dbg(TRACE, "Enter\n");
1135         if (!check_vif_up(ifp->vif))
1136                 return -EIO;
1137
1138         brcmf_link_down(ifp->vif);
1139
1140         brcmf_dbg(TRACE, "Exit\n");
1141
1142         return err;
1143 }
1144
1145 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1146                                  struct cfg80211_connect_params *sme)
1147 {
1148         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1149         struct brcmf_cfg80211_security *sec;
1150         s32 val = 0;
1151         s32 err = 0;
1152
1153         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1154                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1155         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1156                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1157         else
1158                 val = WPA_AUTH_DISABLED;
1159         brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1160         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wpa_auth", val);
1161         if (err) {
1162                 brcmf_err("set wpa_auth failed (%d)\n", err);
1163                 return err;
1164         }
1165         sec = &profile->sec;
1166         sec->wpa_versions = sme->crypto.wpa_versions;
1167         return err;
1168 }
1169
1170 static s32 brcmf_set_auth_type(struct net_device *ndev,
1171                                struct cfg80211_connect_params *sme)
1172 {
1173         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1174         struct brcmf_cfg80211_security *sec;
1175         s32 val = 0;
1176         s32 err = 0;
1177
1178         switch (sme->auth_type) {
1179         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1180                 val = 0;
1181                 brcmf_dbg(CONN, "open system\n");
1182                 break;
1183         case NL80211_AUTHTYPE_SHARED_KEY:
1184                 val = 1;
1185                 brcmf_dbg(CONN, "shared key\n");
1186                 break;
1187         case NL80211_AUTHTYPE_AUTOMATIC:
1188                 val = 2;
1189                 brcmf_dbg(CONN, "automatic\n");
1190                 break;
1191         case NL80211_AUTHTYPE_NETWORK_EAP:
1192                 brcmf_dbg(CONN, "network eap\n");
1193         default:
1194                 val = 2;
1195                 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1196                 break;
1197         }
1198
1199         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "auth", val);
1200         if (err) {
1201                 brcmf_err("set auth failed (%d)\n", err);
1202                 return err;
1203         }
1204         sec = &profile->sec;
1205         sec->auth_type = sme->auth_type;
1206         return err;
1207 }
1208
1209 static s32
1210 brcmf_set_set_cipher(struct net_device *ndev,
1211                      struct cfg80211_connect_params *sme)
1212 {
1213         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1214         struct brcmf_cfg80211_security *sec;
1215         s32 pval = 0;
1216         s32 gval = 0;
1217         s32 err = 0;
1218
1219         if (sme->crypto.n_ciphers_pairwise) {
1220                 switch (sme->crypto.ciphers_pairwise[0]) {
1221                 case WLAN_CIPHER_SUITE_WEP40:
1222                 case WLAN_CIPHER_SUITE_WEP104:
1223                         pval = WEP_ENABLED;
1224                         break;
1225                 case WLAN_CIPHER_SUITE_TKIP:
1226                         pval = TKIP_ENABLED;
1227                         break;
1228                 case WLAN_CIPHER_SUITE_CCMP:
1229                         pval = AES_ENABLED;
1230                         break;
1231                 case WLAN_CIPHER_SUITE_AES_CMAC:
1232                         pval = AES_ENABLED;
1233                         break;
1234                 default:
1235                         brcmf_err("invalid cipher pairwise (%d)\n",
1236                                   sme->crypto.ciphers_pairwise[0]);
1237                         return -EINVAL;
1238                 }
1239         }
1240         if (sme->crypto.cipher_group) {
1241                 switch (sme->crypto.cipher_group) {
1242                 case WLAN_CIPHER_SUITE_WEP40:
1243                 case WLAN_CIPHER_SUITE_WEP104:
1244                         gval = WEP_ENABLED;
1245                         break;
1246                 case WLAN_CIPHER_SUITE_TKIP:
1247                         gval = TKIP_ENABLED;
1248                         break;
1249                 case WLAN_CIPHER_SUITE_CCMP:
1250                         gval = AES_ENABLED;
1251                         break;
1252                 case WLAN_CIPHER_SUITE_AES_CMAC:
1253                         gval = AES_ENABLED;
1254                         break;
1255                 default:
1256                         brcmf_err("invalid cipher group (%d)\n",
1257                                   sme->crypto.cipher_group);
1258                         return -EINVAL;
1259                 }
1260         }
1261
1262         brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1263         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "wsec", pval | gval);
1264         if (err) {
1265                 brcmf_err("error (%d)\n", err);
1266                 return err;
1267         }
1268
1269         sec = &profile->sec;
1270         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1271         sec->cipher_group = sme->crypto.cipher_group;
1272
1273         return err;
1274 }
1275
1276 static s32
1277 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1278 {
1279         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1280         struct brcmf_cfg80211_security *sec;
1281         s32 val = 0;
1282         s32 err = 0;
1283
1284         if (sme->crypto.n_akm_suites) {
1285                 err = brcmf_fil_iovar_int_get(netdev_priv(ndev),
1286                                               "wpa_auth", &val);
1287                 if (err) {
1288                         brcmf_err("could not get wpa_auth (%d)\n", err);
1289                         return err;
1290                 }
1291                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1292                         switch (sme->crypto.akm_suites[0]) {
1293                         case WLAN_AKM_SUITE_8021X:
1294                                 val = WPA_AUTH_UNSPECIFIED;
1295                                 break;
1296                         case WLAN_AKM_SUITE_PSK:
1297                                 val = WPA_AUTH_PSK;
1298                                 break;
1299                         default:
1300                                 brcmf_err("invalid cipher group (%d)\n",
1301                                           sme->crypto.cipher_group);
1302                                 return -EINVAL;
1303                         }
1304                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1305                         switch (sme->crypto.akm_suites[0]) {
1306                         case WLAN_AKM_SUITE_8021X:
1307                                 val = WPA2_AUTH_UNSPECIFIED;
1308                                 break;
1309                         case WLAN_AKM_SUITE_PSK:
1310                                 val = WPA2_AUTH_PSK;
1311                                 break;
1312                         default:
1313                                 brcmf_err("invalid cipher group (%d)\n",
1314                                           sme->crypto.cipher_group);
1315                                 return -EINVAL;
1316                         }
1317                 }
1318
1319                 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1320                 err = brcmf_fil_iovar_int_set(netdev_priv(ndev),
1321                                               "wpa_auth", val);
1322                 if (err) {
1323                         brcmf_err("could not set wpa_auth (%d)\n", err);
1324                         return err;
1325                 }
1326         }
1327         sec = &profile->sec;
1328         sec->wpa_auth = sme->crypto.akm_suites[0];
1329
1330         return err;
1331 }
1332
1333 static s32
1334 brcmf_set_sharedkey(struct net_device *ndev,
1335                     struct cfg80211_connect_params *sme)
1336 {
1337         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1338         struct brcmf_cfg80211_security *sec;
1339         struct brcmf_wsec_key key;
1340         s32 val;
1341         s32 err = 0;
1342
1343         brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1344
1345         if (sme->key_len == 0)
1346                 return 0;
1347
1348         sec = &profile->sec;
1349         brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1350                   sec->wpa_versions, sec->cipher_pairwise);
1351
1352         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1353                 return 0;
1354
1355         if (!(sec->cipher_pairwise &
1356             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1357                 return 0;
1358
1359         memset(&key, 0, sizeof(key));
1360         key.len = (u32) sme->key_len;
1361         key.index = (u32) sme->key_idx;
1362         if (key.len > sizeof(key.data)) {
1363                 brcmf_err("Too long key length (%u)\n", key.len);
1364                 return -EINVAL;
1365         }
1366         memcpy(key.data, sme->key, key.len);
1367         key.flags = BRCMF_PRIMARY_KEY;
1368         switch (sec->cipher_pairwise) {
1369         case WLAN_CIPHER_SUITE_WEP40:
1370                 key.algo = CRYPTO_ALGO_WEP1;
1371                 break;
1372         case WLAN_CIPHER_SUITE_WEP104:
1373                 key.algo = CRYPTO_ALGO_WEP128;
1374                 break;
1375         default:
1376                 brcmf_err("Invalid algorithm (%d)\n",
1377                           sme->crypto.ciphers_pairwise[0]);
1378                 return -EINVAL;
1379         }
1380         /* Set the new key/index */
1381         brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1382                   key.len, key.index, key.algo);
1383         brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1384         err = send_key_to_dongle(ndev, &key);
1385         if (err)
1386                 return err;
1387
1388         if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1389                 brcmf_dbg(CONN, "set auth_type to shared key\n");
1390                 val = WL_AUTH_SHARED_KEY;       /* shared key */
1391                 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1392                 if (err)
1393                         brcmf_err("set auth failed (%d)\n", err);
1394         }
1395         return err;
1396 }
1397
1398 static s32
1399 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1400                     struct cfg80211_connect_params *sme)
1401 {
1402         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1403         struct brcmf_if *ifp = netdev_priv(ndev);
1404         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1405         struct ieee80211_channel *chan = sme->channel;
1406         struct brcmf_join_params join_params;
1407         size_t join_params_size;
1408         struct brcmf_ssid ssid;
1409
1410         s32 err = 0;
1411
1412         brcmf_dbg(TRACE, "Enter\n");
1413         if (!check_vif_up(ifp->vif))
1414                 return -EIO;
1415
1416         if (!sme->ssid) {
1417                 brcmf_err("Invalid ssid\n");
1418                 return -EOPNOTSUPP;
1419         }
1420
1421         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1422
1423         if (chan) {
1424                 cfg->channel =
1425                         ieee80211_frequency_to_channel(chan->center_freq);
1426                 brcmf_dbg(CONN, "channel (%d), center_req (%d)\n",
1427                           cfg->channel, chan->center_freq);
1428         } else
1429                 cfg->channel = 0;
1430
1431         brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1432
1433         err = brcmf_set_wpa_version(ndev, sme);
1434         if (err) {
1435                 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1436                 goto done;
1437         }
1438
1439         err = brcmf_set_auth_type(ndev, sme);
1440         if (err) {
1441                 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1442                 goto done;
1443         }
1444
1445         err = brcmf_set_set_cipher(ndev, sme);
1446         if (err) {
1447                 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1448                 goto done;
1449         }
1450
1451         err = brcmf_set_key_mgmt(ndev, sme);
1452         if (err) {
1453                 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1454                 goto done;
1455         }
1456
1457         err = brcmf_set_sharedkey(ndev, sme);
1458         if (err) {
1459                 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1460                 goto done;
1461         }
1462
1463         memset(&join_params, 0, sizeof(join_params));
1464         join_params_size = sizeof(join_params.ssid_le);
1465
1466         profile->ssid.SSID_len = min_t(u32,
1467                                        sizeof(ssid.SSID), (u32)sme->ssid_len);
1468         memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1469         memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1470         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1471
1472         memset(join_params.params_le.bssid, 0xFF, ETH_ALEN);
1473
1474         if (ssid.SSID_len < IEEE80211_MAX_SSID_LEN)
1475                 brcmf_dbg(CONN, "ssid \"%s\", len (%d)\n",
1476                           ssid.SSID, ssid.SSID_len);
1477
1478         brcmf_ch_to_chanspec(cfg->channel,
1479                              &join_params, &join_params_size);
1480         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1481                                      &join_params, join_params_size);
1482         if (err)
1483                 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1484
1485 done:
1486         if (err)
1487                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1488         brcmf_dbg(TRACE, "Exit\n");
1489         return err;
1490 }
1491
1492 static s32
1493 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1494                        u16 reason_code)
1495 {
1496         struct brcmf_if *ifp = netdev_priv(ndev);
1497         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1498         struct brcmf_scb_val_le scbval;
1499         s32 err = 0;
1500
1501         brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1502         if (!check_vif_up(ifp->vif))
1503                 return -EIO;
1504
1505         clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1506
1507         memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1508         scbval.val = cpu_to_le32(reason_code);
1509         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1510                                      &scbval, sizeof(scbval));
1511         if (err)
1512                 brcmf_err("error (%d)\n", err);
1513
1514         brcmf_dbg(TRACE, "Exit\n");
1515         return err;
1516 }
1517
1518 static s32
1519 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1520                             enum nl80211_tx_power_setting type, s32 mbm)
1521 {
1522
1523         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1524         struct net_device *ndev = cfg_to_ndev(cfg);
1525         struct brcmf_if *ifp = netdev_priv(ndev);
1526         u16 txpwrmw;
1527         s32 err = 0;
1528         s32 disable = 0;
1529         s32 dbm = MBM_TO_DBM(mbm);
1530
1531         brcmf_dbg(TRACE, "Enter\n");
1532         if (!check_vif_up(ifp->vif))
1533                 return -EIO;
1534
1535         switch (type) {
1536         case NL80211_TX_POWER_AUTOMATIC:
1537                 break;
1538         case NL80211_TX_POWER_LIMITED:
1539         case NL80211_TX_POWER_FIXED:
1540                 if (dbm < 0) {
1541                         brcmf_err("TX_POWER_FIXED - dbm is negative\n");
1542                         err = -EINVAL;
1543                         goto done;
1544                 }
1545                 break;
1546         }
1547         /* Make sure radio is off or on as far as software is concerned */
1548         disable = WL_RADIO_SW_DISABLE << 16;
1549         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
1550         if (err)
1551                 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
1552
1553         if (dbm > 0xffff)
1554                 txpwrmw = 0xffff;
1555         else
1556                 txpwrmw = (u16) dbm;
1557         err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
1558                                       (s32)brcmf_mw_to_qdbm(txpwrmw));
1559         if (err)
1560                 brcmf_err("qtxpower error (%d)\n", err);
1561         cfg->conf->tx_power = dbm;
1562
1563 done:
1564         brcmf_dbg(TRACE, "Exit\n");
1565         return err;
1566 }
1567
1568 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
1569                                        struct wireless_dev *wdev,
1570                                        s32 *dbm)
1571 {
1572         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1573         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
1574         s32 txpwrdbm;
1575         u8 result;
1576         s32 err = 0;
1577
1578         brcmf_dbg(TRACE, "Enter\n");
1579         if (!check_vif_up(ifp->vif))
1580                 return -EIO;
1581
1582         err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
1583         if (err) {
1584                 brcmf_err("error (%d)\n", err);
1585                 goto done;
1586         }
1587
1588         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
1589         *dbm = (s32) brcmf_qdbm_to_mw(result);
1590
1591 done:
1592         brcmf_dbg(TRACE, "Exit\n");
1593         return err;
1594 }
1595
1596 static s32
1597 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
1598                                u8 key_idx, bool unicast, bool multicast)
1599 {
1600         struct brcmf_if *ifp = netdev_priv(ndev);
1601         u32 index;
1602         u32 wsec;
1603         s32 err = 0;
1604
1605         brcmf_dbg(TRACE, "Enter\n");
1606         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1607         if (!check_vif_up(ifp->vif))
1608                 return -EIO;
1609
1610         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1611         if (err) {
1612                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1613                 goto done;
1614         }
1615
1616         if (wsec & WEP_ENABLED) {
1617                 /* Just select a new current key */
1618                 index = key_idx;
1619                 err = brcmf_fil_cmd_int_set(ifp,
1620                                             BRCMF_C_SET_KEY_PRIMARY, index);
1621                 if (err)
1622                         brcmf_err("error (%d)\n", err);
1623         }
1624 done:
1625         brcmf_dbg(TRACE, "Exit\n");
1626         return err;
1627 }
1628
1629 static s32
1630 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
1631               u8 key_idx, const u8 *mac_addr, struct key_params *params)
1632 {
1633         struct brcmf_wsec_key key;
1634         s32 err = 0;
1635
1636         memset(&key, 0, sizeof(key));
1637         key.index = (u32) key_idx;
1638         /* Instead of bcast for ea address for default wep keys,
1639                  driver needs it to be Null */
1640         if (!is_multicast_ether_addr(mac_addr))
1641                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
1642         key.len = (u32) params->key_len;
1643         /* check for key index change */
1644         if (key.len == 0) {
1645                 /* key delete */
1646                 err = send_key_to_dongle(ndev, &key);
1647                 if (err)
1648                         brcmf_err("key delete error (%d)\n", err);
1649         } else {
1650                 if (key.len > sizeof(key.data)) {
1651                         brcmf_err("Invalid key length (%d)\n", key.len);
1652                         return -EINVAL;
1653                 }
1654
1655                 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
1656                 memcpy(key.data, params->key, key.len);
1657
1658                 if (params->cipher == WLAN_CIPHER_SUITE_TKIP) {
1659                         u8 keybuf[8];
1660                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1661                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1662                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1663                 }
1664
1665                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
1666                 if (params->seq && params->seq_len == 6) {
1667                         /* rx iv */
1668                         u8 *ivptr;
1669                         ivptr = (u8 *) params->seq;
1670                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
1671                             (ivptr[3] << 8) | ivptr[2];
1672                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
1673                         key.iv_initialized = true;
1674                 }
1675
1676                 switch (params->cipher) {
1677                 case WLAN_CIPHER_SUITE_WEP40:
1678                         key.algo = CRYPTO_ALGO_WEP1;
1679                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1680                         break;
1681                 case WLAN_CIPHER_SUITE_WEP104:
1682                         key.algo = CRYPTO_ALGO_WEP128;
1683                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1684                         break;
1685                 case WLAN_CIPHER_SUITE_TKIP:
1686                         key.algo = CRYPTO_ALGO_TKIP;
1687                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1688                         break;
1689                 case WLAN_CIPHER_SUITE_AES_CMAC:
1690                         key.algo = CRYPTO_ALGO_AES_CCM;
1691                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1692                         break;
1693                 case WLAN_CIPHER_SUITE_CCMP:
1694                         key.algo = CRYPTO_ALGO_AES_CCM;
1695                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1696                         break;
1697                 default:
1698                         brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1699                         return -EINVAL;
1700                 }
1701                 err = send_key_to_dongle(ndev, &key);
1702                 if (err)
1703                         brcmf_err("wsec_key error (%d)\n", err);
1704         }
1705         return err;
1706 }
1707
1708 static s32
1709 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1710                     u8 key_idx, bool pairwise, const u8 *mac_addr,
1711                     struct key_params *params)
1712 {
1713         struct brcmf_if *ifp = netdev_priv(ndev);
1714         struct brcmf_wsec_key key;
1715         s32 val;
1716         s32 wsec;
1717         s32 err = 0;
1718         u8 keybuf[8];
1719
1720         brcmf_dbg(TRACE, "Enter\n");
1721         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1722         if (!check_vif_up(ifp->vif))
1723                 return -EIO;
1724
1725         if (mac_addr) {
1726                 brcmf_dbg(TRACE, "Exit");
1727                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
1728         }
1729         memset(&key, 0, sizeof(key));
1730
1731         key.len = (u32) params->key_len;
1732         key.index = (u32) key_idx;
1733
1734         if (key.len > sizeof(key.data)) {
1735                 brcmf_err("Too long key length (%u)\n", key.len);
1736                 err = -EINVAL;
1737                 goto done;
1738         }
1739         memcpy(key.data, params->key, key.len);
1740
1741         key.flags = BRCMF_PRIMARY_KEY;
1742         switch (params->cipher) {
1743         case WLAN_CIPHER_SUITE_WEP40:
1744                 key.algo = CRYPTO_ALGO_WEP1;
1745                 val = WEP_ENABLED;
1746                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1747                 break;
1748         case WLAN_CIPHER_SUITE_WEP104:
1749                 key.algo = CRYPTO_ALGO_WEP128;
1750                 val = WEP_ENABLED;
1751                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1752                 break;
1753         case WLAN_CIPHER_SUITE_TKIP:
1754                 if (ifp->vif->mode != WL_MODE_AP) {
1755                         brcmf_dbg(CONN, "Swapping key\n");
1756                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
1757                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
1758                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
1759                 }
1760                 key.algo = CRYPTO_ALGO_TKIP;
1761                 val = TKIP_ENABLED;
1762                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1763                 break;
1764         case WLAN_CIPHER_SUITE_AES_CMAC:
1765                 key.algo = CRYPTO_ALGO_AES_CCM;
1766                 val = AES_ENABLED;
1767                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1768                 break;
1769         case WLAN_CIPHER_SUITE_CCMP:
1770                 key.algo = CRYPTO_ALGO_AES_CCM;
1771                 val = AES_ENABLED;
1772                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
1773                 break;
1774         default:
1775                 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
1776                 err = -EINVAL;
1777                 goto done;
1778         }
1779
1780         err = send_key_to_dongle(ndev, &key);
1781         if (err)
1782                 goto done;
1783
1784         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1785         if (err) {
1786                 brcmf_err("get wsec error (%d)\n", err);
1787                 goto done;
1788         }
1789         wsec |= val;
1790         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
1791         if (err) {
1792                 brcmf_err("set wsec error (%d)\n", err);
1793                 goto done;
1794         }
1795
1796 done:
1797         brcmf_dbg(TRACE, "Exit\n");
1798         return err;
1799 }
1800
1801 static s32
1802 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1803                     u8 key_idx, bool pairwise, const u8 *mac_addr)
1804 {
1805         struct brcmf_if *ifp = netdev_priv(ndev);
1806         struct brcmf_wsec_key key;
1807         s32 err = 0;
1808
1809         brcmf_dbg(TRACE, "Enter\n");
1810         if (!check_vif_up(ifp->vif))
1811                 return -EIO;
1812
1813         if (key_idx >= DOT11_MAX_DEFAULT_KEYS) {
1814                 /* we ignore this key index in this case */
1815                 brcmf_err("invalid key index (%d)\n", key_idx);
1816                 return -EINVAL;
1817         }
1818
1819         memset(&key, 0, sizeof(key));
1820
1821         key.index = (u32) key_idx;
1822         key.flags = BRCMF_PRIMARY_KEY;
1823         key.algo = CRYPTO_ALGO_OFF;
1824
1825         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1826
1827         /* Set the new key/index */
1828         err = send_key_to_dongle(ndev, &key);
1829
1830         brcmf_dbg(TRACE, "Exit\n");
1831         return err;
1832 }
1833
1834 static s32
1835 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1836                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
1837                     void (*callback) (void *cookie, struct key_params * params))
1838 {
1839         struct key_params params;
1840         struct brcmf_if *ifp = netdev_priv(ndev);
1841         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1842         struct brcmf_cfg80211_security *sec;
1843         s32 wsec;
1844         s32 err = 0;
1845
1846         brcmf_dbg(TRACE, "Enter\n");
1847         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
1848         if (!check_vif_up(ifp->vif))
1849                 return -EIO;
1850
1851         memset(&params, 0, sizeof(params));
1852
1853         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
1854         if (err) {
1855                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
1856                 /* Ignore this error, may happen during DISASSOC */
1857                 err = -EAGAIN;
1858                 goto done;
1859         }
1860         switch (wsec & ~SES_OW_ENABLED) {
1861         case WEP_ENABLED:
1862                 sec = &profile->sec;
1863                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
1864                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
1865                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
1866                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
1867                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
1868                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
1869                 }
1870                 break;
1871         case TKIP_ENABLED:
1872                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
1873                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
1874                 break;
1875         case AES_ENABLED:
1876                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
1877                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
1878                 break;
1879         default:
1880                 brcmf_err("Invalid algo (0x%x)\n", wsec);
1881                 err = -EINVAL;
1882                 goto done;
1883         }
1884         callback(cookie, &params);
1885
1886 done:
1887         brcmf_dbg(TRACE, "Exit\n");
1888         return err;
1889 }
1890
1891 static s32
1892 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
1893                                     struct net_device *ndev, u8 key_idx)
1894 {
1895         brcmf_dbg(INFO, "Not supported\n");
1896
1897         return -EOPNOTSUPP;
1898 }
1899
1900 static s32
1901 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
1902                            u8 *mac, struct station_info *sinfo)
1903 {
1904         struct brcmf_if *ifp = netdev_priv(ndev);
1905         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1906         struct brcmf_scb_val_le scb_val;
1907         int rssi;
1908         s32 rate;
1909         s32 err = 0;
1910         u8 *bssid = profile->bssid;
1911         struct brcmf_sta_info_le sta_info_le;
1912
1913         brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
1914         if (!check_vif_up(ifp->vif))
1915                 return -EIO;
1916
1917         if (ifp->vif->mode == WL_MODE_AP) {
1918                 memcpy(&sta_info_le, mac, ETH_ALEN);
1919                 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
1920                                                &sta_info_le,
1921                                                sizeof(sta_info_le));
1922                 if (err < 0) {
1923                         brcmf_err("GET STA INFO failed, %d\n", err);
1924                         goto done;
1925                 }
1926                 sinfo->filled = STATION_INFO_INACTIVE_TIME;
1927                 sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
1928                 if (le32_to_cpu(sta_info_le.flags) & BRCMF_STA_ASSOC) {
1929                         sinfo->filled |= STATION_INFO_CONNECTED_TIME;
1930                         sinfo->connected_time = le32_to_cpu(sta_info_le.in);
1931                 }
1932                 brcmf_dbg(TRACE, "STA idle time : %d ms, connected time :%d sec\n",
1933                           sinfo->inactive_time, sinfo->connected_time);
1934         } else if (ifp->vif->mode == WL_MODE_BSS) {
1935                 if (memcmp(mac, bssid, ETH_ALEN)) {
1936                         brcmf_err("Wrong Mac address cfg_mac-%pM wl_bssid-%pM\n",
1937                                   mac, bssid);
1938                         err = -ENOENT;
1939                         goto done;
1940                 }
1941                 /* Report the current tx rate */
1942         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_RATE, &rate);
1943                 if (err) {
1944                         brcmf_err("Could not get rate (%d)\n", err);
1945                         goto done;
1946                 } else {
1947                         sinfo->filled |= STATION_INFO_TX_BITRATE;
1948                         sinfo->txrate.legacy = rate * 5;
1949                         brcmf_dbg(CONN, "Rate %d Mbps\n", rate / 2);
1950                 }
1951
1952                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED,
1953                              &ifp->vif->sme_state)) {
1954                         memset(&scb_val, 0, sizeof(scb_val));
1955                         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_RSSI,
1956                                                      &scb_val, sizeof(scb_val));
1957                         if (err) {
1958                                 brcmf_err("Could not get rssi (%d)\n", err);
1959                                 goto done;
1960                         } else {
1961                                 rssi = le32_to_cpu(scb_val.val);
1962                                 sinfo->filled |= STATION_INFO_SIGNAL;
1963                                 sinfo->signal = rssi;
1964                                 brcmf_dbg(CONN, "RSSI %d dBm\n", rssi);
1965                         }
1966                 }
1967         } else
1968                 err = -EPERM;
1969 done:
1970         brcmf_dbg(TRACE, "Exit\n");
1971         return err;
1972 }
1973
1974 static s32
1975 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
1976                            bool enabled, s32 timeout)
1977 {
1978         s32 pm;
1979         s32 err = 0;
1980         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1981         struct brcmf_if *ifp = netdev_priv(ndev);
1982
1983         brcmf_dbg(TRACE, "Enter\n");
1984
1985         /*
1986          * Powersave enable/disable request is coming from the
1987          * cfg80211 even before the interface is up. In that
1988          * scenario, driver will be storing the power save
1989          * preference in cfg struct to apply this to
1990          * FW later while initializing the dongle
1991          */
1992         cfg->pwr_save = enabled;
1993         if (!check_vif_up(ifp->vif)) {
1994
1995                 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
1996                 goto done;
1997         }
1998
1999         pm = enabled ? PM_FAST : PM_OFF;
2000         brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2001
2002         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2003         if (err) {
2004                 if (err == -ENODEV)
2005                         brcmf_err("net_device is not ready yet\n");
2006                 else
2007                         brcmf_err("error (%d)\n", err);
2008         }
2009 done:
2010         brcmf_dbg(TRACE, "Exit\n");
2011         return err;
2012 }
2013
2014 static s32
2015 brcmf_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *ndev,
2016                              const u8 *addr,
2017                              const struct cfg80211_bitrate_mask *mask)
2018 {
2019         struct brcmf_if *ifp = netdev_priv(ndev);
2020         struct brcm_rateset_le rateset_le;
2021         s32 rate;
2022         s32 val;
2023         s32 err_bg;
2024         s32 err_a;
2025         u32 legacy;
2026         s32 err = 0;
2027
2028         brcmf_dbg(TRACE, "Enter\n");
2029         if (!check_vif_up(ifp->vif))
2030                 return -EIO;
2031
2032         /* addr param is always NULL. ignore it */
2033         /* Get current rateset */
2034         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_CURR_RATESET,
2035                                      &rateset_le, sizeof(rateset_le));
2036         if (err) {
2037                 brcmf_err("could not get current rateset (%d)\n", err);
2038                 goto done;
2039         }
2040
2041         legacy = ffs(mask->control[IEEE80211_BAND_2GHZ].legacy & 0xFFFF);
2042         if (!legacy)
2043                 legacy = ffs(mask->control[IEEE80211_BAND_5GHZ].legacy &
2044                              0xFFFF);
2045
2046         val = wl_g_rates[legacy - 1].bitrate * 100000;
2047
2048         if (val < le32_to_cpu(rateset_le.count))
2049                 /* Select rate by rateset index */
2050                 rate = rateset_le.rates[val] & 0x7f;
2051         else
2052                 /* Specified rate in bps */
2053                 rate = val / 500000;
2054
2055         brcmf_dbg(CONN, "rate %d mbps\n", rate / 2);
2056
2057         /*
2058          *
2059          *      Set rate override,
2060          *      Since the is a/b/g-blind, both a/bg_rate are enforced.
2061          */
2062         err_bg = brcmf_fil_iovar_int_set(ifp, "bg_rate", rate);
2063         err_a = brcmf_fil_iovar_int_set(ifp, "a_rate", rate);
2064         if (err_bg && err_a) {
2065                 brcmf_err("could not set fixed rate (%d) (%d)\n", err_bg,
2066                           err_a);
2067                 err = err_bg | err_a;
2068         }
2069
2070 done:
2071         brcmf_dbg(TRACE, "Exit\n");
2072         return err;
2073 }
2074
2075 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2076                                    struct brcmf_bss_info_le *bi)
2077 {
2078         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2079         struct ieee80211_channel *notify_channel;
2080         struct cfg80211_bss *bss;
2081         struct ieee80211_supported_band *band;
2082         s32 err = 0;
2083         u16 channel;
2084         u32 freq;
2085         u16 notify_capability;
2086         u16 notify_interval;
2087         u8 *notify_ie;
2088         size_t notify_ielen;
2089         s32 notify_signal;
2090
2091         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2092                 brcmf_err("Bss info is larger than buffer. Discarding\n");
2093                 return 0;
2094         }
2095
2096         channel = bi->ctl_ch ? bi->ctl_ch :
2097                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2098
2099         if (channel <= CH_MAX_2G_CHANNEL)
2100                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2101         else
2102                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2103
2104         freq = ieee80211_channel_to_frequency(channel, band->band);
2105         notify_channel = ieee80211_get_channel(wiphy, freq);
2106
2107         notify_capability = le16_to_cpu(bi->capability);
2108         notify_interval = le16_to_cpu(bi->beacon_period);
2109         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2110         notify_ielen = le32_to_cpu(bi->ie_length);
2111         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2112
2113         brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2114         brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2115         brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2116         brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2117         brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2118
2119         bss = cfg80211_inform_bss(wiphy, notify_channel, (const u8 *)bi->BSSID,
2120                 0, notify_capability, notify_interval, notify_ie,
2121                 notify_ielen, notify_signal, GFP_KERNEL);
2122
2123         if (!bss)
2124                 return -ENOMEM;
2125
2126         cfg80211_put_bss(bss);
2127
2128         return err;
2129 }
2130
2131 static struct brcmf_bss_info_le *
2132 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2133 {
2134         if (bss == NULL)
2135                 return list->bss_info_le;
2136         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2137                                             le32_to_cpu(bss->length));
2138 }
2139
2140 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2141 {
2142         struct brcmf_scan_results *bss_list;
2143         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2144         s32 err = 0;
2145         int i;
2146
2147         bss_list = cfg->bss_list;
2148         if (bss_list->count != 0 &&
2149             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2150                 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2151                           bss_list->version);
2152                 return -EOPNOTSUPP;
2153         }
2154         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2155         for (i = 0; i < bss_list->count; i++) {
2156                 bi = next_bss_le(bss_list, bi);
2157                 err = brcmf_inform_single_bss(cfg, bi);
2158                 if (err)
2159                         break;
2160         }
2161         return err;
2162 }
2163
2164 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2165                           struct net_device *ndev, const u8 *bssid)
2166 {
2167         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2168         struct ieee80211_channel *notify_channel;
2169         struct brcmf_bss_info_le *bi = NULL;
2170         struct ieee80211_supported_band *band;
2171         struct cfg80211_bss *bss;
2172         u8 *buf = NULL;
2173         s32 err = 0;
2174         u16 channel;
2175         u32 freq;
2176         u16 notify_capability;
2177         u16 notify_interval;
2178         u8 *notify_ie;
2179         size_t notify_ielen;
2180         s32 notify_signal;
2181
2182         brcmf_dbg(TRACE, "Enter\n");
2183
2184         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2185         if (buf == NULL) {
2186                 err = -ENOMEM;
2187                 goto CleanUp;
2188         }
2189
2190         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2191
2192         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2193                                      buf, WL_BSS_INFO_MAX);
2194         if (err) {
2195                 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2196                 goto CleanUp;
2197         }
2198
2199         bi = (struct brcmf_bss_info_le *)(buf + 4);
2200
2201         channel = bi->ctl_ch ? bi->ctl_ch :
2202                                 CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
2203
2204         if (channel <= CH_MAX_2G_CHANNEL)
2205                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2206         else
2207                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2208
2209         freq = ieee80211_channel_to_frequency(channel, band->band);
2210         notify_channel = ieee80211_get_channel(wiphy, freq);
2211
2212         notify_capability = le16_to_cpu(bi->capability);
2213         notify_interval = le16_to_cpu(bi->beacon_period);
2214         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2215         notify_ielen = le32_to_cpu(bi->ie_length);
2216         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2217
2218         brcmf_dbg(CONN, "channel: %d(%d)\n", channel, freq);
2219         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2220         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2221         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2222
2223         bss = cfg80211_inform_bss(wiphy, notify_channel, bssid,
2224                 0, notify_capability, notify_interval,
2225                 notify_ie, notify_ielen, notify_signal, GFP_KERNEL);
2226
2227         if (!bss) {
2228                 err = -ENOMEM;
2229                 goto CleanUp;
2230         }
2231
2232         cfg80211_put_bss(bss);
2233
2234 CleanUp:
2235
2236         kfree(buf);
2237
2238         brcmf_dbg(TRACE, "Exit\n");
2239
2240         return err;
2241 }
2242
2243 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
2244 {
2245         return vif->mode == WL_MODE_IBSS;
2246 }
2247
2248 /*
2249  * Traverse a string of 1-byte tag/1-byte length/variable-length value
2250  * triples, returning a pointer to the substring whose first element
2251  * matches tag
2252  */
2253 static struct brcmf_tlv *brcmf_parse_tlvs(void *buf, int buflen, uint key)
2254 {
2255         struct brcmf_tlv *elt;
2256         int totlen;
2257
2258         elt = (struct brcmf_tlv *) buf;
2259         totlen = buflen;
2260
2261         /* find tagged parameter */
2262         while (totlen >= TLV_HDR_LEN) {
2263                 int len = elt->len;
2264
2265                 /* validate remaining totlen */
2266                 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
2267                         return elt;
2268
2269                 elt = (struct brcmf_tlv *) ((u8 *) elt + (len + TLV_HDR_LEN));
2270                 totlen -= (len + TLV_HDR_LEN);
2271         }
2272
2273         return NULL;
2274 }
2275
2276 /* Is any of the tlvs the expected entry? If
2277  * not update the tlvs buffer pointer/length.
2278  */
2279 static bool
2280 brcmf_tlv_has_ie(u8 *ie, u8 **tlvs, u32 *tlvs_len,
2281                  u8 *oui, u32 oui_len, u8 type)
2282 {
2283         /* If the contents match the OUI and the type */
2284         if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
2285             !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
2286             type == ie[TLV_BODY_OFF + oui_len]) {
2287                 return true;
2288         }
2289
2290         if (tlvs == NULL)
2291                 return false;
2292         /* point to the next ie */
2293         ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
2294         /* calculate the length of the rest of the buffer */
2295         *tlvs_len -= (int)(ie - *tlvs);
2296         /* update the pointer to the start of the buffer */
2297         *tlvs = ie;
2298
2299         return false;
2300 }
2301
2302 static struct brcmf_vs_tlv *
2303 brcmf_find_wpaie(u8 *parse, u32 len)
2304 {
2305         struct brcmf_tlv *ie;
2306
2307         while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
2308                 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
2309                                      WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
2310                         return (struct brcmf_vs_tlv *)ie;
2311         }
2312         return NULL;
2313 }
2314
2315 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg)
2316 {
2317         struct net_device *ndev = cfg_to_ndev(cfg);
2318         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
2319         struct brcmf_if *ifp = netdev_priv(ndev);
2320         struct brcmf_bss_info_le *bi;
2321         struct brcmf_ssid *ssid;
2322         struct brcmf_tlv *tim;
2323         u16 beacon_interval;
2324         u8 dtim_period;
2325         size_t ie_len;
2326         u8 *ie;
2327         s32 err = 0;
2328
2329         brcmf_dbg(TRACE, "Enter\n");
2330         if (brcmf_is_ibssmode(ifp->vif))
2331                 return err;
2332
2333         ssid = &profile->ssid;
2334
2335         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2336         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2337                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2338         if (err) {
2339                 brcmf_err("Could not get bss info %d\n", err);
2340                 goto update_bss_info_out;
2341         }
2342
2343         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2344         err = brcmf_inform_single_bss(cfg, bi);
2345         if (err)
2346                 goto update_bss_info_out;
2347
2348         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2349         ie_len = le32_to_cpu(bi->ie_length);
2350         beacon_interval = le16_to_cpu(bi->beacon_period);
2351
2352         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2353         if (tim)
2354                 dtim_period = tim->data[1];
2355         else {
2356                 /*
2357                 * active scan was done so we could not get dtim
2358                 * information out of probe response.
2359                 * so we speficially query dtim information to dongle.
2360                 */
2361                 u32 var;
2362                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2363                 if (err) {
2364                         brcmf_err("wl dtim_assoc failed (%d)\n", err);
2365                         goto update_bss_info_out;
2366                 }
2367                 dtim_period = (u8)var;
2368         }
2369
2370 update_bss_info_out:
2371         brcmf_dbg(TRACE, "Exit");
2372         return err;
2373 }
2374
2375 static void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2376 {
2377         struct escan_info *escan = &cfg->escan_info;
2378
2379         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2380         if (cfg->scan_request) {
2381                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2382                 brcmf_notify_escan_complete(cfg, escan->ndev, true, true);
2383         }
2384         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2385         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2386 }
2387
2388 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2389 {
2390         struct brcmf_cfg80211_info *cfg =
2391                         container_of(work, struct brcmf_cfg80211_info,
2392                                      escan_timeout_work);
2393
2394         brcmf_notify_escan_complete(cfg,
2395                 cfg->escan_info.ndev, true, true);
2396 }
2397
2398 static void brcmf_escan_timeout(unsigned long data)
2399 {
2400         struct brcmf_cfg80211_info *cfg =
2401                         (struct brcmf_cfg80211_info *)data;
2402
2403         if (cfg->scan_request) {
2404                 brcmf_err("timer expired\n");
2405                 schedule_work(&cfg->escan_timeout_work);
2406         }
2407 }
2408
2409 static s32
2410 brcmf_compare_update_same_bss(struct brcmf_bss_info_le *bss,
2411                               struct brcmf_bss_info_le *bss_info_le)
2412 {
2413         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2414                 (CHSPEC_BAND(le16_to_cpu(bss_info_le->chanspec)) ==
2415                 CHSPEC_BAND(le16_to_cpu(bss->chanspec))) &&
2416                 bss_info_le->SSID_len == bss->SSID_len &&
2417                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2418                 if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) ==
2419                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL)) {
2420                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
2421                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2422
2423                         /* preserve max RSSI if the measurements are
2424                         * both on-channel or both off-channel
2425                         */
2426                         if (bss_info_rssi > bss_rssi)
2427                                 bss->RSSI = bss_info_le->RSSI;
2428                 } else if ((bss->flags & WLC_BSS_RSSI_ON_CHANNEL) &&
2429                         (bss_info_le->flags & WLC_BSS_RSSI_ON_CHANNEL) == 0) {
2430                         /* preserve the on-channel rssi measurement
2431                         * if the new measurement is off channel
2432                         */
2433                         bss->RSSI = bss_info_le->RSSI;
2434                         bss->flags |= WLC_BSS_RSSI_ON_CHANNEL;
2435                 }
2436                 return 1;
2437         }
2438         return 0;
2439 }
2440
2441 static s32
2442 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2443                              const struct brcmf_event_msg *e, void *data)
2444 {
2445         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2446         struct net_device *ndev = ifp->ndev;
2447         s32 status;
2448         s32 err = 0;
2449         struct brcmf_escan_result_le *escan_result_le;
2450         struct brcmf_bss_info_le *bss_info_le;
2451         struct brcmf_bss_info_le *bss = NULL;
2452         u32 bi_length;
2453         struct brcmf_scan_results *list;
2454         u32 i;
2455         bool aborted;
2456
2457         status = e->status;
2458
2459         if (!ndev || !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2460                 brcmf_err("scan not ready ndev %p drv_status %x\n", ndev,
2461                           !test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status));
2462                 return -EPERM;
2463         }
2464
2465         if (status == BRCMF_E_STATUS_PARTIAL) {
2466                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2467                 escan_result_le = (struct brcmf_escan_result_le *) data;
2468                 if (!escan_result_le) {
2469                         brcmf_err("Invalid escan result (NULL pointer)\n");
2470                         goto exit;
2471                 }
2472                 if (!cfg->scan_request) {
2473                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
2474                         goto exit;
2475                 }
2476
2477                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2478                         brcmf_err("Invalid bss_count %d: ignoring\n",
2479                                   escan_result_le->bss_count);
2480                         goto exit;
2481                 }
2482                 bss_info_le = &escan_result_le->bss_info_le;
2483
2484                 bi_length = le32_to_cpu(bss_info_le->length);
2485                 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2486                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
2487                         brcmf_err("Invalid bss_info length %d: ignoring\n",
2488                                   bi_length);
2489                         goto exit;
2490                 }
2491
2492                 if (!(cfg_to_wiphy(cfg)->interface_modes &
2493                                         BIT(NL80211_IFTYPE_ADHOC))) {
2494                         if (le16_to_cpu(bss_info_le->capability) &
2495                                                 WLAN_CAPABILITY_IBSS) {
2496                                 brcmf_err("Ignoring IBSS result\n");
2497                                 goto exit;
2498                         }
2499                 }
2500
2501                 list = (struct brcmf_scan_results *)
2502                                 cfg->escan_info.escan_buf;
2503                 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2504                         brcmf_err("Buffer is too small: ignoring\n");
2505                         goto exit;
2506                 }
2507
2508                 for (i = 0; i < list->count; i++) {
2509                         bss = bss ? (struct brcmf_bss_info_le *)
2510                                 ((unsigned char *)bss +
2511                                 le32_to_cpu(bss->length)) : list->bss_info_le;
2512                         if (brcmf_compare_update_same_bss(bss, bss_info_le))
2513                                 goto exit;
2514                 }
2515                 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2516                         bss_info_le, bi_length);
2517                 list->version = le32_to_cpu(bss_info_le->version);
2518                 list->buflen += bi_length;
2519                 list->count++;
2520         } else {
2521                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2522                 if (cfg->scan_request) {
2523                         cfg->bss_list = (struct brcmf_scan_results *)
2524                                 cfg->escan_info.escan_buf;
2525                         brcmf_inform_bss(cfg);
2526                         aborted = status != BRCMF_E_STATUS_SUCCESS;
2527                         brcmf_notify_escan_complete(cfg, ndev, aborted,
2528                                                     false);
2529                 } else
2530                         brcmf_err("Unexpected scan result 0x%x\n", status);
2531         }
2532 exit:
2533         return err;
2534 }
2535
2536 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2537 {
2538         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2539                             brcmf_cfg80211_escan_handler);
2540         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2541         /* Init scan_timeout timer */
2542         init_timer(&cfg->escan_timeout);
2543         cfg->escan_timeout.data = (unsigned long) cfg;
2544         cfg->escan_timeout.function = brcmf_escan_timeout;
2545         INIT_WORK(&cfg->escan_timeout_work,
2546                   brcmf_cfg80211_escan_timeout_worker);
2547 }
2548
2549 static __always_inline void brcmf_delay(u32 ms)
2550 {
2551         if (ms < 1000 / HZ) {
2552                 cond_resched();
2553                 mdelay(ms);
2554         } else {
2555                 msleep(ms);
2556         }
2557 }
2558
2559 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
2560 {
2561         brcmf_dbg(TRACE, "Enter\n");
2562
2563         return 0;
2564 }
2565
2566 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
2567                                   struct cfg80211_wowlan *wow)
2568 {
2569         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2570         struct net_device *ndev = cfg_to_ndev(cfg);
2571         struct brcmf_cfg80211_vif *vif;
2572
2573         brcmf_dbg(TRACE, "Enter\n");
2574
2575         /*
2576          * if the primary net_device is not READY there is nothing
2577          * we can do but pray resume goes smoothly.
2578          */
2579         vif = ((struct brcmf_if *)netdev_priv(ndev))->vif;
2580         if (!check_vif_up(vif))
2581                 goto exit;
2582
2583         list_for_each_entry(vif, &cfg->vif_list, list) {
2584                 if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
2585                         continue;
2586                 /*
2587                  * While going to suspend if associated with AP disassociate
2588                  * from AP to save power while system is in suspended state
2589                  */
2590                 brcmf_link_down(vif);
2591
2592                 /* Make sure WPA_Supplicant receives all the event
2593                  * generated due to DISASSOC call to the fw to keep
2594                  * the state fw and WPA_Supplicant state consistent
2595                  */
2596                 brcmf_delay(500);
2597         }
2598
2599         /* end any scanning */
2600         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
2601                 brcmf_abort_scanning(cfg);
2602
2603         /* Turn off watchdog timer */
2604         brcmf_set_mpc(ndev, 1);
2605
2606 exit:
2607         brcmf_dbg(TRACE, "Exit\n");
2608         /* clear any scanning activity */
2609         cfg->scan_status = 0;
2610         return 0;
2611 }
2612
2613 static __used s32
2614 brcmf_update_pmklist(struct net_device *ndev,
2615                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
2616 {
2617         int i, j;
2618         int pmkid_len;
2619
2620         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
2621
2622         brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
2623         for (i = 0; i < pmkid_len; i++) {
2624                 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
2625                           &pmk_list->pmkids.pmkid[i].BSSID);
2626                 for (j = 0; j < WLAN_PMKID_LEN; j++)
2627                         brcmf_dbg(CONN, "%02x\n",
2628                                   pmk_list->pmkids.pmkid[i].PMKID[j]);
2629         }
2630
2631         if (!err)
2632                 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
2633                                          (char *)pmk_list, sizeof(*pmk_list));
2634
2635         return err;
2636 }
2637
2638 static s32
2639 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2640                          struct cfg80211_pmksa *pmksa)
2641 {
2642         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2643         struct brcmf_if *ifp = netdev_priv(ndev);
2644         struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
2645         s32 err = 0;
2646         int i;
2647         int pmkid_len;
2648
2649         brcmf_dbg(TRACE, "Enter\n");
2650         if (!check_vif_up(ifp->vif))
2651                 return -EIO;
2652
2653         pmkid_len = le32_to_cpu(pmkids->npmkid);
2654         for (i = 0; i < pmkid_len; i++)
2655                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
2656                         break;
2657         if (i < WL_NUM_PMKIDS_MAX) {
2658                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
2659                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2660                 if (i == pmkid_len) {
2661                         pmkid_len++;
2662                         pmkids->npmkid = cpu_to_le32(pmkid_len);
2663                 }
2664         } else
2665                 err = -EINVAL;
2666
2667         brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
2668                   pmkids->pmkid[pmkid_len].BSSID);
2669         for (i = 0; i < WLAN_PMKID_LEN; i++)
2670                 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
2671
2672         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2673
2674         brcmf_dbg(TRACE, "Exit\n");
2675         return err;
2676 }
2677
2678 static s32
2679 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
2680                       struct cfg80211_pmksa *pmksa)
2681 {
2682         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2683         struct brcmf_if *ifp = netdev_priv(ndev);
2684         struct pmkid_list pmkid;
2685         s32 err = 0;
2686         int i, pmkid_len;
2687
2688         brcmf_dbg(TRACE, "Enter\n");
2689         if (!check_vif_up(ifp->vif))
2690                 return -EIO;
2691
2692         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
2693         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
2694
2695         brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
2696                   &pmkid.pmkid[0].BSSID);
2697         for (i = 0; i < WLAN_PMKID_LEN; i++)
2698                 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
2699
2700         pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
2701         for (i = 0; i < pmkid_len; i++)
2702                 if (!memcmp
2703                     (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
2704                      ETH_ALEN))
2705                         break;
2706
2707         if ((pmkid_len > 0)
2708             && (i < pmkid_len)) {
2709                 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
2710                        sizeof(struct pmkid));
2711                 for (; i < (pmkid_len - 1); i++) {
2712                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
2713                                &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
2714                                ETH_ALEN);
2715                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
2716                                &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
2717                                WLAN_PMKID_LEN);
2718                 }
2719                 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
2720         } else
2721                 err = -EINVAL;
2722
2723         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2724
2725         brcmf_dbg(TRACE, "Exit\n");
2726         return err;
2727
2728 }
2729
2730 static s32
2731 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
2732 {
2733         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2734         struct brcmf_if *ifp = netdev_priv(ndev);
2735         s32 err = 0;
2736
2737         brcmf_dbg(TRACE, "Enter\n");
2738         if (!check_vif_up(ifp->vif))
2739                 return -EIO;
2740
2741         memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
2742         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
2743
2744         brcmf_dbg(TRACE, "Exit\n");
2745         return err;
2746
2747 }
2748
2749 /*
2750  * PFN result doesn't have all the info which are
2751  * required by the supplicant
2752  * (For e.g IEs) Do a target Escan so that sched scan results are reported
2753  * via wl_inform_single_bss in the required format. Escan does require the
2754  * scan request in the form of cfg80211_scan_request. For timebeing, create
2755  * cfg80211_scan_request one out of the received PNO event.
2756  */
2757 static s32
2758 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
2759                                 const struct brcmf_event_msg *e, void *data)
2760 {
2761         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2762         struct net_device *ndev = ifp->ndev;
2763         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
2764         struct cfg80211_scan_request *request = NULL;
2765         struct cfg80211_ssid *ssid = NULL;
2766         struct ieee80211_channel *channel = NULL;
2767         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2768         int err = 0;
2769         int channel_req = 0;
2770         int band = 0;
2771         struct brcmf_pno_scanresults_le *pfn_result;
2772         u32 result_count;
2773         u32 status;
2774
2775         brcmf_dbg(SCAN, "Enter\n");
2776
2777         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
2778                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
2779                 return 0;
2780         }
2781
2782         pfn_result = (struct brcmf_pno_scanresults_le *)data;
2783         result_count = le32_to_cpu(pfn_result->count);
2784         status = le32_to_cpu(pfn_result->status);
2785
2786         /*
2787          * PFN event is limited to fit 512 bytes so we may get
2788          * multiple NET_FOUND events. For now place a warning here.
2789          */
2790         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
2791         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
2792         if (result_count > 0) {
2793                 int i;
2794
2795                 request = kzalloc(sizeof(*request), GFP_KERNEL);
2796                 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
2797                 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
2798                 if (!request || !ssid || !channel) {
2799                         err = -ENOMEM;
2800                         goto out_err;
2801                 }
2802
2803                 request->wiphy = wiphy;
2804                 data += sizeof(struct brcmf_pno_scanresults_le);
2805                 netinfo_start = (struct brcmf_pno_net_info_le *)data;
2806
2807                 for (i = 0; i < result_count; i++) {
2808                         netinfo = &netinfo_start[i];
2809                         if (!netinfo) {
2810                                 brcmf_err("Invalid netinfo ptr. index: %d\n",
2811                                           i);
2812                                 err = -EINVAL;
2813                                 goto out_err;
2814                         }
2815
2816                         brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
2817                                   netinfo->SSID, netinfo->channel);
2818                         memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
2819                         ssid[i].ssid_len = netinfo->SSID_len;
2820                         request->n_ssids++;
2821
2822                         channel_req = netinfo->channel;
2823                         if (channel_req <= CH_MAX_2G_CHANNEL)
2824                                 band = NL80211_BAND_2GHZ;
2825                         else
2826                                 band = NL80211_BAND_5GHZ;
2827                         channel[i].center_freq =
2828                                 ieee80211_channel_to_frequency(channel_req,
2829                                                                band);
2830                         channel[i].band = band;
2831                         channel[i].flags |= IEEE80211_CHAN_NO_HT40;
2832                         request->channels[i] = &channel[i];
2833                         request->n_channels++;
2834                 }
2835
2836                 /* assign parsed ssid array */
2837                 if (request->n_ssids)
2838                         request->ssids = &ssid[0];
2839
2840                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2841                         /* Abort any on-going scan */
2842                         brcmf_abort_scanning(cfg);
2843                 }
2844
2845                 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2846                 err = brcmf_do_escan(cfg, wiphy, ndev, request);
2847                 if (err) {
2848                         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2849                         goto out_err;
2850                 }
2851                 cfg->sched_escan = true;
2852                 cfg->scan_request = request;
2853         } else {
2854                 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
2855                 goto out_err;
2856         }
2857
2858         kfree(ssid);
2859         kfree(channel);
2860         kfree(request);
2861         return 0;
2862
2863 out_err:
2864         kfree(ssid);
2865         kfree(channel);
2866         kfree(request);
2867         cfg80211_sched_scan_stopped(wiphy);
2868         return err;
2869 }
2870
2871 static int brcmf_dev_pno_clean(struct net_device *ndev)
2872 {
2873         int ret;
2874
2875         /* Disable pfn */
2876         ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
2877         if (ret == 0) {
2878                 /* clear pfn */
2879                 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
2880                                                NULL, 0);
2881         }
2882         if (ret < 0)
2883                 brcmf_err("failed code %d\n", ret);
2884
2885         return ret;
2886 }
2887
2888 static int brcmf_dev_pno_config(struct net_device *ndev)
2889 {
2890         struct brcmf_pno_param_le pfn_param;
2891
2892         memset(&pfn_param, 0, sizeof(pfn_param));
2893         pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
2894
2895         /* set extra pno params */
2896         pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
2897         pfn_param.repeat = BRCMF_PNO_REPEAT;
2898         pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
2899
2900         /* set up pno scan fr */
2901         pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
2902
2903         return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
2904                                         &pfn_param, sizeof(pfn_param));
2905 }
2906
2907 static int
2908 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
2909                                 struct net_device *ndev,
2910                                 struct cfg80211_sched_scan_request *request)
2911 {
2912         struct brcmf_if *ifp = netdev_priv(ndev);
2913         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
2914         struct brcmf_pno_net_param_le pfn;
2915         int i;
2916         int ret = 0;
2917
2918         brcmf_dbg(SCAN, "Enter n_match_sets:%d   n_ssids:%d\n",
2919                   request->n_match_sets, request->n_ssids);
2920         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2921                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
2922                 return -EAGAIN;
2923         }
2924
2925         if (!request || !request->n_ssids || !request->n_match_sets) {
2926                 brcmf_err("Invalid sched scan req!! n_ssids:%d\n",
2927                           request ? request->n_ssids : 0);
2928                 return -EINVAL;
2929         }
2930
2931         if (request->n_ssids > 0) {
2932                 for (i = 0; i < request->n_ssids; i++) {
2933                         /* Active scan req for ssids */
2934                         brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
2935                                   request->ssids[i].ssid);
2936
2937                         /*
2938                          * match_set ssids is a supert set of n_ssid list,
2939                          * so we need not add these set seperately.
2940                          */
2941                 }
2942         }
2943
2944         if (request->n_match_sets > 0) {
2945                 /* clean up everything */
2946                 ret = brcmf_dev_pno_clean(ndev);
2947                 if  (ret < 0) {
2948                         brcmf_err("failed error=%d\n", ret);
2949                         return ret;
2950                 }
2951
2952                 /* configure pno */
2953                 ret = brcmf_dev_pno_config(ndev);
2954                 if (ret < 0) {
2955                         brcmf_err("PNO setup failed!! ret=%d\n", ret);
2956                         return -EINVAL;
2957                 }
2958
2959                 /* configure each match set */
2960                 for (i = 0; i < request->n_match_sets; i++) {
2961                         struct cfg80211_ssid *ssid;
2962                         u32 ssid_len;
2963
2964                         ssid = &request->match_sets[i].ssid;
2965                         ssid_len = ssid->ssid_len;
2966
2967                         if (!ssid_len) {
2968                                 brcmf_err("skip broadcast ssid\n");
2969                                 continue;
2970                         }
2971                         pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
2972                         pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
2973                         pfn.wsec = cpu_to_le32(0);
2974                         pfn.infra = cpu_to_le32(1);
2975                         pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
2976                         pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
2977                         memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
2978                         ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
2979                                                        sizeof(pfn));
2980                         brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
2981                                   ret == 0 ? "set" : "failed", ssid->ssid);
2982                 }
2983                 /* Enable the PNO */
2984                 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
2985                         brcmf_err("PNO enable failed!! ret=%d\n", ret);
2986                         return -EINVAL;
2987                 }
2988         } else {
2989                 return -EINVAL;
2990         }
2991
2992         return 0;
2993 }
2994
2995 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
2996                                           struct net_device *ndev)
2997 {
2998         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2999
3000         brcmf_dbg(SCAN, "enter\n");
3001         brcmf_dev_pno_clean(ndev);
3002         if (cfg->sched_escan)
3003                 brcmf_notify_escan_complete(cfg, ndev, true, true);
3004         return 0;
3005 }
3006
3007 #ifdef CONFIG_NL80211_TESTMODE
3008 static int brcmf_cfg80211_testmode(struct wiphy *wiphy, void *data, int len)
3009 {
3010         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3011         struct net_device *ndev = cfg_to_ndev(cfg);
3012         struct brcmf_dcmd *dcmd = data;
3013         struct sk_buff *reply;
3014         int ret;
3015
3016         brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3017                   dcmd->buf, dcmd->len);
3018
3019         if (dcmd->set)
3020                 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3021                                              dcmd->buf, dcmd->len);
3022         else
3023                 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3024                                              dcmd->buf, dcmd->len);
3025         if (ret == 0) {
3026                 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3027                 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3028                 ret = cfg80211_testmode_reply(reply);
3029         }
3030         return ret;
3031 }
3032 #endif
3033
3034 static s32 brcmf_configure_opensecurity(struct net_device *ndev, s32 bssidx)
3035 {
3036         struct brcmf_if *ifp = netdev_priv(ndev);
3037         s32 err;
3038
3039         /* set auth */
3040         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3041         if (err < 0) {
3042                 brcmf_err("auth error %d\n", err);
3043                 return err;
3044         }
3045         /* set wsec */
3046         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3047         if (err < 0) {
3048                 brcmf_err("wsec error %d\n", err);
3049                 return err;
3050         }
3051         /* set upper-layer auth */
3052         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3053         if (err < 0) {
3054                 brcmf_err("wpa_auth error %d\n", err);
3055                 return err;
3056         }
3057
3058         return 0;
3059 }
3060
3061 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3062 {
3063         if (is_rsn_ie)
3064                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3065
3066         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3067 }
3068
3069 static s32
3070 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3071                      bool is_rsn_ie)
3072 {
3073         struct brcmf_if *ifp = netdev_priv(ndev);
3074         u32 auth = 0; /* d11 open authentication */
3075         u16 count;
3076         s32 err = 0;
3077         s32 len = 0;
3078         u32 i;
3079         u32 wsec;
3080         u32 pval = 0;
3081         u32 gval = 0;
3082         u32 wpa_auth = 0;
3083         u32 offset;
3084         u8 *data;
3085         u16 rsn_cap;
3086         u32 wme_bss_disable;
3087
3088         brcmf_dbg(TRACE, "Enter\n");
3089         if (wpa_ie == NULL)
3090                 goto exit;
3091
3092         len = wpa_ie->len + TLV_HDR_LEN;
3093         data = (u8 *)wpa_ie;
3094         offset = 0;
3095         if (!is_rsn_ie)
3096                 offset += VS_IE_FIXED_HDR_LEN;
3097         offset += WPA_IE_VERSION_LEN;
3098
3099         /* check for multicast cipher suite */
3100         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3101                 err = -EINVAL;
3102                 brcmf_err("no multicast cipher suite\n");
3103                 goto exit;
3104         }
3105
3106         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3107                 err = -EINVAL;
3108                 brcmf_err("ivalid OUI\n");
3109                 goto exit;
3110         }
3111         offset += TLV_OUI_LEN;
3112
3113         /* pick up multicast cipher */
3114         switch (data[offset]) {
3115         case WPA_CIPHER_NONE:
3116                 gval = 0;
3117                 break;
3118         case WPA_CIPHER_WEP_40:
3119         case WPA_CIPHER_WEP_104:
3120                 gval = WEP_ENABLED;
3121                 break;
3122         case WPA_CIPHER_TKIP:
3123                 gval = TKIP_ENABLED;
3124                 break;
3125         case WPA_CIPHER_AES_CCM:
3126                 gval = AES_ENABLED;
3127                 break;
3128         default:
3129                 err = -EINVAL;
3130                 brcmf_err("Invalid multi cast cipher info\n");
3131                 goto exit;
3132         }
3133
3134         offset++;
3135         /* walk thru unicast cipher list and pick up what we recognize */
3136         count = data[offset] + (data[offset + 1] << 8);
3137         offset += WPA_IE_SUITE_COUNT_LEN;
3138         /* Check for unicast suite(s) */
3139         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3140                 err = -EINVAL;
3141                 brcmf_err("no unicast cipher suite\n");
3142                 goto exit;
3143         }
3144         for (i = 0; i < count; i++) {
3145                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3146                         err = -EINVAL;
3147                         brcmf_err("ivalid OUI\n");
3148                         goto exit;
3149                 }
3150                 offset += TLV_OUI_LEN;
3151                 switch (data[offset]) {
3152                 case WPA_CIPHER_NONE:
3153                         break;
3154                 case WPA_CIPHER_WEP_40:
3155                 case WPA_CIPHER_WEP_104:
3156                         pval |= WEP_ENABLED;
3157                         break;
3158                 case WPA_CIPHER_TKIP:
3159                         pval |= TKIP_ENABLED;
3160                         break;
3161                 case WPA_CIPHER_AES_CCM:
3162                         pval |= AES_ENABLED;
3163                         break;
3164                 default:
3165                         brcmf_err("Ivalid unicast security info\n");
3166                 }
3167                 offset++;
3168         }
3169         /* walk thru auth management suite list and pick up what we recognize */
3170         count = data[offset] + (data[offset + 1] << 8);
3171         offset += WPA_IE_SUITE_COUNT_LEN;
3172         /* Check for auth key management suite(s) */
3173         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3174                 err = -EINVAL;
3175                 brcmf_err("no auth key mgmt suite\n");
3176                 goto exit;
3177         }
3178         for (i = 0; i < count; i++) {
3179                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3180                         err = -EINVAL;
3181                         brcmf_err("ivalid OUI\n");
3182                         goto exit;
3183                 }
3184                 offset += TLV_OUI_LEN;
3185                 switch (data[offset]) {
3186                 case RSN_AKM_NONE:
3187                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3188                         wpa_auth |= WPA_AUTH_NONE;
3189                         break;
3190                 case RSN_AKM_UNSPECIFIED:
3191                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3192                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3193                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3194                         break;
3195                 case RSN_AKM_PSK:
3196                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3197                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3198                                     (wpa_auth |= WPA_AUTH_PSK);
3199                         break;
3200                 default:
3201                         brcmf_err("Ivalid key mgmt info\n");
3202                 }
3203                 offset++;
3204         }
3205
3206         if (is_rsn_ie) {
3207                 wme_bss_disable = 1;
3208                 if ((offset + RSN_CAP_LEN) <= len) {
3209                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3210                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3211                                 wme_bss_disable = 0;
3212                 }
3213                 /* set wme_bss_disable to sync RSN Capabilities */
3214                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3215                                                wme_bss_disable);
3216                 if (err < 0) {
3217                         brcmf_err("wme_bss_disable error %d\n", err);
3218                         goto exit;
3219                 }
3220         }
3221         /* FOR WPS , set SES_OW_ENABLED */
3222         wsec = (pval | gval | SES_OW_ENABLED);
3223
3224         /* set auth */
3225         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3226         if (err < 0) {
3227                 brcmf_err("auth error %d\n", err);
3228                 goto exit;
3229         }
3230         /* set wsec */
3231         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3232         if (err < 0) {
3233                 brcmf_err("wsec error %d\n", err);
3234                 goto exit;
3235         }
3236         /* set upper-layer auth */
3237         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3238         if (err < 0) {
3239                 brcmf_err("wpa_auth error %d\n", err);
3240                 goto exit;
3241         }
3242
3243 exit:
3244         return err;
3245 }
3246
3247 static s32
3248 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3249                      struct parsed_vndr_ies *vndr_ies)
3250 {
3251         s32 err = 0;
3252         struct brcmf_vs_tlv *vndrie;
3253         struct brcmf_tlv *ie;
3254         struct parsed_vndr_ie_info *parsed_info;
3255         s32 remaining_len;
3256
3257         remaining_len = (s32)vndr_ie_len;
3258         memset(vndr_ies, 0, sizeof(*vndr_ies));
3259
3260         ie = (struct brcmf_tlv *)vndr_ie_buf;
3261         while (ie) {
3262                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3263                         goto next;
3264                 vndrie = (struct brcmf_vs_tlv *)ie;
3265                 /* len should be bigger than OUI length + one */
3266                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3267                         brcmf_err("invalid vndr ie. length is too small %d\n",
3268                                   vndrie->len);
3269                         goto next;
3270                 }
3271                 /* if wpa or wme ie, do not add ie */
3272                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3273                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3274                     (vndrie->oui_type == WME_OUI_TYPE))) {
3275                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3276                         goto next;
3277                 }
3278
3279                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3280
3281                 /* save vndr ie information */
3282                 parsed_info->ie_ptr = (char *)vndrie;
3283                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3284                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3285
3286                 vndr_ies->count++;
3287
3288                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3289                           parsed_info->vndrie.oui[0],
3290                           parsed_info->vndrie.oui[1],
3291                           parsed_info->vndrie.oui[2],
3292                           parsed_info->vndrie.oui_type);
3293
3294                 if (vndr_ies->count >= MAX_VNDR_IE_NUMBER)
3295                         break;
3296 next:
3297                 remaining_len -= (ie->len + TLV_HDR_LEN);
3298                 if (remaining_len <= TLV_HDR_LEN)
3299                         ie = NULL;
3300                 else
3301                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3302                                 TLV_HDR_LEN);
3303         }
3304         return err;
3305 }
3306
3307 static u32
3308 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3309 {
3310
3311         __le32 iecount_le;
3312         __le32 pktflag_le;
3313
3314         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3315         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3316
3317         iecount_le = cpu_to_le32(1);
3318         memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3319
3320         pktflag_le = cpu_to_le32(pktflag);
3321         memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3322
3323         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3324
3325         return ie_len + VNDR_IE_HDR_SIZE;
3326 }
3327
3328 static
3329 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3330                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3331 {
3332         struct brcmf_if *ifp;
3333         struct vif_saved_ie *saved_ie;
3334         s32 err = 0;
3335         u8  *iovar_ie_buf;
3336         u8  *curr_ie_buf;
3337         u8  *mgmt_ie_buf = NULL;
3338         int mgmt_ie_buf_len;
3339         u32 *mgmt_ie_len;
3340         u32 del_add_ie_buf_len = 0;
3341         u32 total_ie_buf_len = 0;
3342         u32 parsed_ie_buf_len = 0;
3343         struct parsed_vndr_ies old_vndr_ies;
3344         struct parsed_vndr_ies new_vndr_ies;
3345         struct parsed_vndr_ie_info *vndrie_info;
3346         s32 i;
3347         u8 *ptr;
3348         int remained_buf_len;
3349
3350         if (!vif)
3351                 return -ENODEV;
3352         ifp = vif->ifp;
3353         saved_ie = &vif->saved_ie;
3354
3355         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3356         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3357         if (!iovar_ie_buf)
3358                 return -ENOMEM;
3359         curr_ie_buf = iovar_ie_buf;
3360         if (ifp->vif->mode == WL_MODE_AP) {
3361                 switch (pktflag) {
3362                 case VNDR_IE_PRBRSP_FLAG:
3363                         mgmt_ie_buf = saved_ie->probe_res_ie;
3364                         mgmt_ie_len = &saved_ie->probe_res_ie_len;
3365                         mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3366                         break;
3367                 case VNDR_IE_BEACON_FLAG:
3368                         mgmt_ie_buf = saved_ie->beacon_ie;
3369                         mgmt_ie_len = &saved_ie->beacon_ie_len;
3370                         mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3371                         break;
3372                 default:
3373                         err = -EPERM;
3374                         brcmf_err("not suitable type\n");
3375                         goto exit;
3376                 }
3377         } else {
3378                 err = -EPERM;
3379                 brcmf_err("not suitable type\n");
3380                 goto exit;
3381         }
3382
3383         if (vndr_ie_len > mgmt_ie_buf_len) {
3384                 err = -ENOMEM;
3385                 brcmf_err("extra IE size too big\n");
3386                 goto exit;
3387         }
3388
3389         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3390         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3391                 ptr = curr_ie_buf;
3392                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3393                 for (i = 0; i < new_vndr_ies.count; i++) {
3394                         vndrie_info = &new_vndr_ies.ie_info[i];
3395                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3396                                vndrie_info->ie_len);
3397                         parsed_ie_buf_len += vndrie_info->ie_len;
3398                 }
3399         }
3400
3401         if (mgmt_ie_buf && *mgmt_ie_len) {
3402                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3403                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3404                             parsed_ie_buf_len) == 0)) {
3405                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3406                         goto exit;
3407                 }
3408
3409                 /* parse old vndr_ie */
3410                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3411
3412                 /* make a command to delete old ie */
3413                 for (i = 0; i < old_vndr_ies.count; i++) {
3414                         vndrie_info = &old_vndr_ies.ie_info[i];
3415
3416                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3417                                   vndrie_info->vndrie.id,
3418                                   vndrie_info->vndrie.len,
3419                                   vndrie_info->vndrie.oui[0],
3420                                   vndrie_info->vndrie.oui[1],
3421                                   vndrie_info->vndrie.oui[2]);
3422
3423                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3424                                                            vndrie_info->ie_ptr,
3425                                                            vndrie_info->ie_len,
3426                                                            "del");
3427                         curr_ie_buf += del_add_ie_buf_len;
3428                         total_ie_buf_len += del_add_ie_buf_len;
3429                 }
3430         }
3431
3432         *mgmt_ie_len = 0;
3433         /* Add if there is any extra IE */
3434         if (mgmt_ie_buf && parsed_ie_buf_len) {
3435                 ptr = mgmt_ie_buf;
3436
3437                 remained_buf_len = mgmt_ie_buf_len;
3438
3439                 /* make a command to add new ie */
3440                 for (i = 0; i < new_vndr_ies.count; i++) {
3441                         vndrie_info = &new_vndr_ies.ie_info[i];
3442
3443                         /* verify remained buf size before copy data */
3444                         if (remained_buf_len < (vndrie_info->vndrie.len +
3445                                                         VNDR_IE_VSIE_OFFSET)) {
3446                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3447                                           remained_buf_len);
3448                                 break;
3449                         }
3450                         remained_buf_len -= (vndrie_info->ie_len +
3451                                              VNDR_IE_VSIE_OFFSET);
3452
3453                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3454                                   vndrie_info->vndrie.id,
3455                                   vndrie_info->vndrie.len,
3456                                   vndrie_info->vndrie.oui[0],
3457                                   vndrie_info->vndrie.oui[1],
3458                                   vndrie_info->vndrie.oui[2]);
3459
3460                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3461                                                            vndrie_info->ie_ptr,
3462                                                            vndrie_info->ie_len,
3463                                                            "add");
3464
3465                         /* save the parsed IE in wl struct */
3466                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3467                                vndrie_info->ie_len);
3468                         *mgmt_ie_len += vndrie_info->ie_len;
3469
3470                         curr_ie_buf += del_add_ie_buf_len;
3471                         total_ie_buf_len += del_add_ie_buf_len;
3472                 }
3473         }
3474         if (total_ie_buf_len) {
3475                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3476                                                  total_ie_buf_len);
3477                 if (err)
3478                         brcmf_err("vndr ie set error : %d\n", err);
3479         }
3480
3481 exit:
3482         kfree(iovar_ie_buf);
3483         return err;
3484 }
3485
3486 static s32
3487 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3488                         struct cfg80211_ap_settings *settings)
3489 {
3490         s32 ie_offset;
3491         struct brcmf_if *ifp = netdev_priv(ndev);
3492         struct brcmf_tlv *ssid_ie;
3493         struct brcmf_ssid_le ssid_le;
3494         s32 err = -EPERM;
3495         struct brcmf_tlv *rsn_ie;
3496         struct brcmf_vs_tlv *wpa_ie;
3497         struct brcmf_join_params join_params;
3498         s32 bssidx = 0;
3499
3500         brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3501                   cfg80211_get_chandef_type(&settings->chandef),
3502                   settings->beacon_interval,
3503                   settings->dtim_period);
3504         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3505                   settings->ssid, settings->ssid_len, settings->auth_type,
3506                   settings->inactivity_timeout);
3507
3508         if (!test_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state)) {
3509                 brcmf_err("Not in AP creation mode\n");
3510                 return -EPERM;
3511         }
3512
3513         memset(&ssid_le, 0, sizeof(ssid_le));
3514         if (settings->ssid == NULL || settings->ssid_len == 0) {
3515                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3516                 ssid_ie = brcmf_parse_tlvs(
3517                                 (u8 *)&settings->beacon.head[ie_offset],
3518                                 settings->beacon.head_len - ie_offset,
3519                                 WLAN_EID_SSID);
3520                 if (!ssid_ie)
3521                         return -EINVAL;
3522
3523                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3524                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3525                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3526         } else {
3527                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3528                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3529         }
3530
3531         brcmf_set_mpc(ndev, 0);
3532         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3533         if (err < 0) {
3534                 brcmf_err("BRCMF_C_DOWN error %d\n", err);
3535                 goto exit;
3536         }
3537         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3538         if (err < 0) {
3539                 brcmf_err("SET INFRA error %d\n", err);
3540                 goto exit;
3541         }
3542         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3543         if (err < 0) {
3544                 brcmf_err("setting AP mode failed %d\n", err);
3545                 goto exit;
3546         }
3547
3548         /* find the RSN_IE */
3549         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3550                                   settings->beacon.tail_len, WLAN_EID_RSN);
3551
3552         /* find the WPA_IE */
3553         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3554                                   settings->beacon.tail_len);
3555
3556         if ((wpa_ie != NULL || rsn_ie != NULL)) {
3557                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3558                 if (wpa_ie != NULL) {
3559                         /* WPA IE */
3560                         err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3561                         if (err < 0)
3562                                 goto exit;
3563                 } else {
3564                         /* RSN IE */
3565                         err = brcmf_configure_wpaie(ndev,
3566                                 (struct brcmf_vs_tlv *)rsn_ie, true);
3567                         if (err < 0)
3568                                 goto exit;
3569                 }
3570         } else {
3571                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3572                 brcmf_configure_opensecurity(ndev, bssidx);
3573         }
3574         /* Set Beacon IEs to FW */
3575         err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3576                                     VNDR_IE_BEACON_FLAG,
3577                                     settings->beacon.tail,
3578                                     settings->beacon.tail_len);
3579         if (err)
3580                 brcmf_err("Set Beacon IE Failed\n");
3581         else
3582                 brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3583
3584         /* Set Probe Response IEs to FW */
3585         err = brcmf_vif_set_mgmt_ie(ndev_to_vif(ndev),
3586                                     VNDR_IE_PRBRSP_FLAG,
3587                                     settings->beacon.proberesp_ies,
3588                                     settings->beacon.proberesp_ies_len);
3589         if (err)
3590                 brcmf_err("Set Probe Resp IE Failed\n");
3591         else
3592                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3593
3594         if (settings->beacon_interval) {
3595                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3596                                             settings->beacon_interval);
3597                 if (err < 0) {
3598                         brcmf_err("Beacon Interval Set Error, %d\n", err);
3599                         goto exit;
3600                 }
3601         }
3602         if (settings->dtim_period) {
3603                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3604                                             settings->dtim_period);
3605                 if (err < 0) {
3606                         brcmf_err("DTIM Interval Set Error, %d\n", err);
3607                         goto exit;
3608                 }
3609         }
3610         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3611         if (err < 0) {
3612                 brcmf_err("BRCMF_C_UP error (%d)\n", err);
3613                 goto exit;
3614         }
3615
3616         memset(&join_params, 0, sizeof(join_params));
3617         /* join parameters starts with ssid */
3618         memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3619         /* create softap */
3620         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3621                                      &join_params, sizeof(join_params));
3622         if (err < 0) {
3623                 brcmf_err("SET SSID error (%d)\n", err);
3624                 goto exit;
3625         }
3626         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3627         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3628
3629 exit:
3630         if (err)
3631                 brcmf_set_mpc(ndev, 1);
3632         return err;
3633 }
3634
3635 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3636 {
3637         struct brcmf_if *ifp = netdev_priv(ndev);
3638         s32 err = -EPERM;
3639
3640         brcmf_dbg(TRACE, "Enter\n");
3641
3642         if (ifp->vif->mode == WL_MODE_AP) {
3643                 /* Due to most likely deauths outstanding we sleep */
3644                 /* first to make sure they get processed by fw. */
3645                 msleep(400);
3646                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3647                 if (err < 0) {
3648                         brcmf_err("setting AP mode failed %d\n", err);
3649                         goto exit;
3650                 }
3651                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3652                 if (err < 0) {
3653                         brcmf_err("BRCMF_C_UP error %d\n", err);
3654                         goto exit;
3655                 }
3656                 brcmf_set_mpc(ndev, 1);
3657                 clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3658                 clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3659         }
3660 exit:
3661         return err;
3662 }
3663
3664 static int
3665 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3666                            u8 *mac)
3667 {
3668         struct brcmf_scb_val_le scbval;
3669         struct brcmf_if *ifp = netdev_priv(ndev);
3670         s32 err;
3671
3672         if (!mac)
3673                 return -EFAULT;
3674
3675         brcmf_dbg(TRACE, "Enter %pM\n", mac);
3676
3677         if (!check_vif_up(ifp->vif))
3678                 return -EIO;
3679
3680         memcpy(&scbval.ea, mac, ETH_ALEN);
3681         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3682         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3683                                      &scbval, sizeof(scbval));
3684         if (err)
3685                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3686
3687         brcmf_dbg(TRACE, "Exit\n");
3688         return err;
3689 }
3690
3691 static struct cfg80211_ops wl_cfg80211_ops = {
3692         .change_virtual_intf = brcmf_cfg80211_change_iface,
3693         .scan = brcmf_cfg80211_scan,
3694         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
3695         .join_ibss = brcmf_cfg80211_join_ibss,
3696         .leave_ibss = brcmf_cfg80211_leave_ibss,
3697         .get_station = brcmf_cfg80211_get_station,
3698         .set_tx_power = brcmf_cfg80211_set_tx_power,
3699         .get_tx_power = brcmf_cfg80211_get_tx_power,
3700         .add_key = brcmf_cfg80211_add_key,
3701         .del_key = brcmf_cfg80211_del_key,
3702         .get_key = brcmf_cfg80211_get_key,
3703         .set_default_key = brcmf_cfg80211_config_default_key,
3704         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
3705         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
3706         .set_bitrate_mask = brcmf_cfg80211_set_bitrate_mask,
3707         .connect = brcmf_cfg80211_connect,
3708         .disconnect = brcmf_cfg80211_disconnect,
3709         .suspend = brcmf_cfg80211_suspend,
3710         .resume = brcmf_cfg80211_resume,
3711         .set_pmksa = brcmf_cfg80211_set_pmksa,
3712         .del_pmksa = brcmf_cfg80211_del_pmksa,
3713         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
3714         .start_ap = brcmf_cfg80211_start_ap,
3715         .stop_ap = brcmf_cfg80211_stop_ap,
3716         .del_station = brcmf_cfg80211_del_station,
3717         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
3718         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
3719 #ifdef CONFIG_NL80211_TESTMODE
3720         .testmode_cmd = brcmf_cfg80211_testmode
3721 #endif
3722 };
3723
3724 static s32 brcmf_mode_to_nl80211_iftype(s32 mode)
3725 {
3726         s32 err = 0;
3727
3728         switch (mode) {
3729         case WL_MODE_BSS:
3730                 return NL80211_IFTYPE_STATION;
3731         case WL_MODE_IBSS:
3732                 return NL80211_IFTYPE_ADHOC;
3733         default:
3734                 return NL80211_IFTYPE_UNSPECIFIED;
3735         }
3736
3737         return err;
3738 }
3739
3740 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
3741 {
3742         /* scheduled scan settings */
3743         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
3744         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
3745         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
3746         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3747 }
3748
3749 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
3750 {
3751         struct wiphy *wiphy;
3752         s32 err = 0;
3753
3754         wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
3755         if (!wiphy) {
3756                 brcmf_err("Could not allocate wiphy device\n");
3757                 return ERR_PTR(-ENOMEM);
3758         }
3759         set_wiphy_dev(wiphy, phydev);
3760         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
3761         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
3762         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3763                                  BIT(NL80211_IFTYPE_ADHOC) |
3764                                  BIT(NL80211_IFTYPE_AP);
3765         wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
3766         wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_a;  /* Set
3767                                                 * it as 11a by default.
3768                                                 * This will be updated with
3769                                                 * 11n phy tables in
3770                                                 * "ifconfig up"
3771                                                 * if phy has 11n capability
3772                                                 */
3773         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3774         wiphy->cipher_suites = __wl_cipher_suites;
3775         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
3776         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT;    /* enable power
3777                                                                  * save mode
3778                                                                  * by default
3779                                                                  */
3780         brcmf_wiphy_pno_params(wiphy);
3781         err = wiphy_register(wiphy);
3782         if (err < 0) {
3783                 brcmf_err("Could not register wiphy device (%d)\n", err);
3784                 wiphy_free(wiphy);
3785                 return ERR_PTR(err);
3786         }
3787         return wiphy;
3788 }
3789
3790 static
3791 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
3792                                            struct net_device *netdev,
3793                                            s32 mode, bool pm_block)
3794 {
3795         struct brcmf_cfg80211_vif *vif;
3796
3797         if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
3798                 return ERR_PTR(-ENOSPC);
3799
3800         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
3801         if (!vif)
3802                 return ERR_PTR(-ENOMEM);
3803
3804         vif->wdev.wiphy = cfg->wiphy;
3805         vif->wdev.netdev = netdev;
3806         vif->wdev.iftype = brcmf_mode_to_nl80211_iftype(mode);
3807
3808         if (netdev) {
3809                 vif->ifp = netdev_priv(netdev);
3810                 netdev->ieee80211_ptr = &vif->wdev;
3811                 SET_NETDEV_DEV(netdev, wiphy_dev(cfg->wiphy));
3812         }
3813
3814         vif->mode = mode;
3815         vif->pm_block = pm_block;
3816         vif->roam_off = -1;
3817
3818         brcmf_init_prof(&vif->profile);
3819
3820         list_add_tail(&vif->list, &cfg->vif_list);
3821         cfg->vif_cnt++;
3822         return vif;
3823 }
3824
3825 static void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
3826 {
3827         struct brcmf_cfg80211_info *cfg;
3828         struct wiphy *wiphy;
3829
3830         wiphy = vif->wdev.wiphy;
3831         cfg = wiphy_priv(wiphy);
3832         list_del(&vif->list);
3833         cfg->vif_cnt--;
3834
3835         kfree(vif);
3836         if (!cfg->vif_cnt) {
3837                 wiphy_unregister(wiphy);
3838                 wiphy_free(wiphy);
3839         }
3840 }
3841
3842 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
3843 {
3844         u32 event = e->event_code;
3845         u32 status = e->status;
3846
3847         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
3848                 brcmf_dbg(CONN, "Processing set ssid\n");
3849                 return true;
3850         }
3851
3852         return false;
3853 }
3854
3855 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
3856 {
3857         u32 event = e->event_code;
3858         u16 flags = e->flags;
3859
3860         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
3861                 brcmf_dbg(CONN, "Processing link down\n");
3862                 return true;
3863         }
3864         return false;
3865 }
3866
3867 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
3868                                const struct brcmf_event_msg *e)
3869 {
3870         u32 event = e->event_code;
3871         u32 status = e->status;
3872
3873         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
3874                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
3875                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
3876                 return true;
3877         }
3878
3879         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
3880                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
3881                 return true;
3882         }
3883
3884         return false;
3885 }
3886
3887 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
3888 {
3889         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3890
3891         kfree(conn_info->req_ie);
3892         conn_info->req_ie = NULL;
3893         conn_info->req_ie_len = 0;
3894         kfree(conn_info->resp_ie);
3895         conn_info->resp_ie = NULL;
3896         conn_info->resp_ie_len = 0;
3897 }
3898
3899 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg)
3900 {
3901         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
3902         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
3903         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3904         u32 req_len;
3905         u32 resp_len;
3906         s32 err = 0;
3907
3908         brcmf_clear_assoc_ies(cfg);
3909
3910         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
3911                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
3912         if (err) {
3913                 brcmf_err("could not get assoc info (%d)\n", err);
3914                 return err;
3915         }
3916         assoc_info =
3917                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
3918         req_len = le32_to_cpu(assoc_info->req_len);
3919         resp_len = le32_to_cpu(assoc_info->resp_len);
3920         if (req_len) {
3921                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
3922                                                cfg->extra_buf,
3923                                                WL_ASSOC_INFO_MAX);
3924                 if (err) {
3925                         brcmf_err("could not get assoc req (%d)\n", err);
3926                         return err;
3927                 }
3928                 conn_info->req_ie_len = req_len;
3929                 conn_info->req_ie =
3930                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
3931                             GFP_KERNEL);
3932         } else {
3933                 conn_info->req_ie_len = 0;
3934                 conn_info->req_ie = NULL;
3935         }
3936         if (resp_len) {
3937                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
3938                                                cfg->extra_buf,
3939                                                WL_ASSOC_INFO_MAX);
3940                 if (err) {
3941                         brcmf_err("could not get assoc resp (%d)\n", err);
3942                         return err;
3943                 }
3944                 conn_info->resp_ie_len = resp_len;
3945                 conn_info->resp_ie =
3946                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
3947                             GFP_KERNEL);
3948         } else {
3949                 conn_info->resp_ie_len = 0;
3950                 conn_info->resp_ie = NULL;
3951         }
3952         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
3953                   conn_info->req_ie_len, conn_info->resp_ie_len);
3954
3955         return err;
3956 }
3957
3958 static s32
3959 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
3960                        struct net_device *ndev,
3961                        const struct brcmf_event_msg *e)
3962 {
3963         struct brcmf_if *ifp = netdev_priv(ndev);
3964         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
3965         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
3966         struct wiphy *wiphy = cfg_to_wiphy(cfg);
3967         struct ieee80211_channel *notify_channel = NULL;
3968         struct ieee80211_supported_band *band;
3969         struct brcmf_bss_info_le *bi;
3970         u32 freq;
3971         s32 err = 0;
3972         u32 target_channel;
3973         u8 *buf;
3974
3975         brcmf_dbg(TRACE, "Enter\n");
3976
3977         brcmf_get_assoc_ies(cfg);
3978         memcpy(profile->bssid, e->addr, ETH_ALEN);
3979         brcmf_update_bss_info(cfg);
3980
3981         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
3982         if (buf == NULL) {
3983                 err = -ENOMEM;
3984                 goto done;
3985         }
3986
3987         /* data sent to dongle has to be little endian */
3988         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
3989         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
3990                                      buf, WL_BSS_INFO_MAX);
3991
3992         if (err)
3993                 goto done;
3994
3995         bi = (struct brcmf_bss_info_le *)(buf + 4);
3996         target_channel = bi->ctl_ch ? bi->ctl_ch :
3997                                       CHSPEC_CHANNEL(le16_to_cpu(bi->chanspec));
3998
3999         if (target_channel <= CH_MAX_2G_CHANNEL)
4000                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4001         else
4002                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4003
4004         freq = ieee80211_channel_to_frequency(target_channel, band->band);
4005         notify_channel = ieee80211_get_channel(wiphy, freq);
4006
4007 done:
4008         kfree(buf);
4009         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4010                         conn_info->req_ie, conn_info->req_ie_len,
4011                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4012         brcmf_dbg(CONN, "Report roaming result\n");
4013
4014         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4015         brcmf_dbg(TRACE, "Exit\n");
4016         return err;
4017 }
4018
4019 static s32
4020 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4021                        struct net_device *ndev, const struct brcmf_event_msg *e,
4022                        bool completed)
4023 {
4024         struct brcmf_if *ifp = netdev_priv(ndev);
4025         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4026         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4027         s32 err = 0;
4028
4029         brcmf_dbg(TRACE, "Enter\n");
4030
4031         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4032                                &ifp->vif->sme_state)) {
4033                 if (completed) {
4034                         brcmf_get_assoc_ies(cfg);
4035                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4036                         brcmf_update_bss_info(cfg);
4037                 }
4038                 cfg80211_connect_result(ndev,
4039                                         (u8 *)profile->bssid,
4040                                         conn_info->req_ie,
4041                                         conn_info->req_ie_len,
4042                                         conn_info->resp_ie,
4043                                         conn_info->resp_ie_len,
4044                                         completed ? WLAN_STATUS_SUCCESS :
4045                                                     WLAN_STATUS_AUTH_TIMEOUT,
4046                                         GFP_KERNEL);
4047                 if (completed)
4048                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4049                                 &ifp->vif->sme_state);
4050                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4051                           completed ? "succeeded" : "failed");
4052         }
4053         brcmf_dbg(TRACE, "Exit\n");
4054         return err;
4055 }
4056
4057 static s32
4058 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4059                                struct net_device *ndev,
4060                                const struct brcmf_event_msg *e, void *data)
4061 {
4062         s32 err = 0;
4063         u32 event = e->event_code;
4064         u32 reason = e->reason;
4065         u32 len = e->datalen;
4066         static int generation;
4067
4068         struct station_info sinfo;
4069
4070         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4071         memset(&sinfo, 0, sizeof(sinfo));
4072
4073         sinfo.filled = 0;
4074         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4075             reason == BRCMF_E_STATUS_SUCCESS) {
4076                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4077                 if (!data) {
4078                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4079                         return -EINVAL;
4080                 }
4081                 sinfo.assoc_req_ies = data;
4082                 sinfo.assoc_req_ies_len = len;
4083                 generation++;
4084                 sinfo.generation = generation;
4085                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_ATOMIC);
4086         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4087                    (event == BRCMF_E_DEAUTH_IND) ||
4088                    (event == BRCMF_E_DEAUTH)) {
4089                 generation++;
4090                 sinfo.generation = generation;
4091                 cfg80211_del_sta(ndev, e->addr, GFP_ATOMIC);
4092         }
4093         return err;
4094 }
4095
4096 static s32
4097 brcmf_notify_connect_status(struct brcmf_if *ifp,
4098                             const struct brcmf_event_msg *e, void *data)
4099 {
4100         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4101         struct net_device *ndev = ifp->ndev;
4102         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4103         s32 err = 0;
4104
4105         if (ifp->vif->mode == WL_MODE_AP) {
4106                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4107         } else if (brcmf_is_linkup(e)) {
4108                 brcmf_dbg(CONN, "Linkup\n");
4109                 if (brcmf_is_ibssmode(ifp->vif)) {
4110                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4111                         wl_inform_ibss(cfg, ndev, e->addr);
4112                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4113                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4114                                   &ifp->vif->sme_state);
4115                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4116                                 &ifp->vif->sme_state);
4117                 } else
4118                         brcmf_bss_connect_done(cfg, ndev, e, true);
4119         } else if (brcmf_is_linkdown(e)) {
4120                 brcmf_dbg(CONN, "Linkdown\n");
4121                 if (!brcmf_is_ibssmode(ifp->vif)) {
4122                         brcmf_bss_connect_done(cfg, ndev, e, false);
4123                         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4124                                                &ifp->vif->sme_state))
4125                                 cfg80211_disconnected(ndev, 0, NULL, 0,
4126                                                       GFP_KERNEL);
4127                 }
4128                 brcmf_link_down(ifp->vif);
4129                 brcmf_init_prof(ndev_to_prof(ndev));
4130         } else if (brcmf_is_nonetwork(cfg, e)) {
4131                 if (brcmf_is_ibssmode(ifp->vif))
4132                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4133                                   &ifp->vif->sme_state);
4134                 else
4135                         brcmf_bss_connect_done(cfg, ndev, e, false);
4136         }
4137
4138         return err;
4139 }
4140
4141 static s32
4142 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4143                             const struct brcmf_event_msg *e, void *data)
4144 {
4145         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4146         s32 err = 0;
4147         u32 event = e->event_code;
4148         u32 status = e->status;
4149
4150         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4151                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4152                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4153                 else
4154                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4155         }
4156
4157         return err;
4158 }
4159
4160 static s32
4161 brcmf_notify_mic_status(struct brcmf_if *ifp,
4162                         const struct brcmf_event_msg *e, void *data)
4163 {
4164         u16 flags = e->flags;
4165         enum nl80211_key_type key_type;
4166
4167         if (flags & BRCMF_EVENT_MSG_GROUP)
4168                 key_type = NL80211_KEYTYPE_GROUP;
4169         else
4170                 key_type = NL80211_KEYTYPE_PAIRWISE;
4171
4172         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4173                                      NULL, GFP_KERNEL);
4174
4175         return 0;
4176 }
4177
4178 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4179 {
4180         conf->frag_threshold = (u32)-1;
4181         conf->rts_threshold = (u32)-1;
4182         conf->retry_short = (u32)-1;
4183         conf->retry_long = (u32)-1;
4184         conf->tx_power = -1;
4185 }
4186
4187 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4188 {
4189         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4190                             brcmf_notify_connect_status);
4191         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4192                             brcmf_notify_connect_status);
4193         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4194                             brcmf_notify_connect_status);
4195         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4196                             brcmf_notify_connect_status);
4197         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4198                             brcmf_notify_connect_status);
4199         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4200                             brcmf_notify_connect_status);
4201         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4202                             brcmf_notify_roaming_status);
4203         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4204                             brcmf_notify_mic_status);
4205         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4206                             brcmf_notify_connect_status);
4207         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4208                             brcmf_notify_sched_scan_results);
4209 }
4210
4211 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4212 {
4213         kfree(cfg->conf);
4214         cfg->conf = NULL;
4215         kfree(cfg->escan_ioctl_buf);
4216         cfg->escan_ioctl_buf = NULL;
4217         kfree(cfg->extra_buf);
4218         cfg->extra_buf = NULL;
4219         kfree(cfg->pmk_list);
4220         cfg->pmk_list = NULL;
4221 }
4222
4223 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4224 {
4225         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4226         if (!cfg->conf)
4227                 goto init_priv_mem_out;
4228         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4229         if (!cfg->escan_ioctl_buf)
4230                 goto init_priv_mem_out;
4231         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4232         if (!cfg->extra_buf)
4233                 goto init_priv_mem_out;
4234         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4235         if (!cfg->pmk_list)
4236                 goto init_priv_mem_out;
4237
4238         return 0;
4239
4240 init_priv_mem_out:
4241         brcmf_deinit_priv_mem(cfg);
4242
4243         return -ENOMEM;
4244 }
4245
4246 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4247 {
4248         s32 err = 0;
4249
4250         cfg->scan_request = NULL;
4251         cfg->pwr_save = true;
4252         cfg->roam_on = true;    /* roam on & off switch.
4253                                  we enable roam per default */
4254         cfg->active_scan = true;        /* we do active scan for
4255                                  specific scan per default */
4256         cfg->dongle_up = false; /* dongle is not up yet */
4257         err = brcmf_init_priv_mem(cfg);
4258         if (err)
4259                 return err;
4260         brcmf_register_event_handlers(cfg);
4261         mutex_init(&cfg->usr_sync);
4262         brcmf_init_escan(cfg);
4263         brcmf_init_conf(cfg->conf);
4264
4265         return err;
4266 }
4267
4268 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4269 {
4270         cfg->dongle_up = false; /* dongle down */
4271         brcmf_abort_scanning(cfg);
4272         brcmf_deinit_priv_mem(cfg);
4273 }
4274
4275 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4276                                                   struct device *busdev)
4277 {
4278         struct net_device *ndev = drvr->iflist[0]->ndev;
4279         struct brcmf_cfg80211_info *cfg;
4280         struct wiphy *wiphy;
4281         struct brcmf_cfg80211_vif *vif;
4282         struct brcmf_if *ifp;
4283         s32 err = 0;
4284
4285         if (!ndev) {
4286                 brcmf_err("ndev is invalid\n");
4287                 return NULL;
4288         }
4289
4290         ifp = netdev_priv(ndev);
4291         wiphy = brcmf_setup_wiphy(busdev);
4292         if (IS_ERR(wiphy))
4293                 return NULL;
4294
4295         cfg = wiphy_priv(wiphy);
4296         cfg->wiphy = wiphy;
4297         cfg->pub = drvr;
4298         INIT_LIST_HEAD(&cfg->vif_list);
4299
4300         vif = brcmf_alloc_vif(cfg, ndev, WL_MODE_BSS, false);
4301         if (IS_ERR(vif)) {
4302                 wiphy_free(wiphy);
4303                 return NULL;
4304         }
4305
4306         err = wl_init_priv(cfg);
4307         if (err) {
4308                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4309                 goto cfg80211_attach_out;
4310         }
4311
4312         ifp->vif = vif;
4313         return cfg;
4314
4315 cfg80211_attach_out:
4316         brcmf_free_vif(vif);
4317         return NULL;
4318 }
4319
4320 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4321 {
4322         struct brcmf_cfg80211_vif *vif;
4323         struct brcmf_cfg80211_vif *tmp;
4324
4325         wl_deinit_priv(cfg);
4326         list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4327                 brcmf_free_vif(vif);
4328         }
4329 }
4330
4331 static s32
4332 brcmf_dongle_roam(struct net_device *ndev, u32 roamvar, u32 bcn_timeout)
4333 {
4334         struct brcmf_if *ifp = netdev_priv(ndev);
4335         s32 err = 0;
4336         __le32 roamtrigger[2];
4337         __le32 roam_delta[2];
4338
4339         /*
4340          * Setup timeout if Beacons are lost and roam is
4341          * off to report link down
4342          */
4343         if (roamvar) {
4344                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
4345                 if (err) {
4346                         brcmf_err("bcn_timeout error (%d)\n", err);
4347                         goto dongle_rom_out;
4348                 }
4349         }
4350
4351         /*
4352          * Enable/Disable built-in roaming to allow supplicant
4353          * to take care of roaming
4354          */
4355         brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
4356         err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
4357         if (err) {
4358                 brcmf_err("roam_off error (%d)\n", err);
4359                 goto dongle_rom_out;
4360         }
4361
4362         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
4363         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
4364         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
4365                                      (void *)roamtrigger, sizeof(roamtrigger));
4366         if (err) {
4367                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
4368                 goto dongle_rom_out;
4369         }
4370
4371         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
4372         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
4373         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
4374                                      (void *)roam_delta, sizeof(roam_delta));
4375         if (err) {
4376                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
4377                 goto dongle_rom_out;
4378         }
4379
4380 dongle_rom_out:
4381         return err;
4382 }
4383
4384 static s32
4385 brcmf_dongle_scantime(struct net_device *ndev, s32 scan_assoc_time,
4386                       s32 scan_unassoc_time, s32 scan_passive_time)
4387 {
4388         struct brcmf_if *ifp = netdev_priv(ndev);
4389         s32 err = 0;
4390
4391         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
4392                                     scan_assoc_time);
4393         if (err) {
4394                 if (err == -EOPNOTSUPP)
4395                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
4396                 else
4397                         brcmf_err("Scan assoc time error (%d)\n", err);
4398                 goto dongle_scantime_out;
4399         }
4400         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
4401                                     scan_unassoc_time);
4402         if (err) {
4403                 if (err == -EOPNOTSUPP)
4404                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
4405                 else
4406                         brcmf_err("Scan unassoc time error (%d)\n", err);
4407                 goto dongle_scantime_out;
4408         }
4409
4410         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
4411                                     scan_passive_time);
4412         if (err) {
4413                 if (err == -EOPNOTSUPP)
4414                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
4415                 else
4416                         brcmf_err("Scan passive time error (%d)\n", err);
4417                 goto dongle_scantime_out;
4418         }
4419
4420 dongle_scantime_out:
4421         return err;
4422 }
4423
4424 static s32 wl_update_wiphybands(struct brcmf_cfg80211_info *cfg)
4425 {
4426         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
4427         struct wiphy *wiphy;
4428         s32 phy_list;
4429         s8 phy;
4430         s32 err = 0;
4431
4432         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
4433                                      &phy_list, sizeof(phy_list));
4434         if (err) {
4435                 brcmf_err("error (%d)\n", err);
4436                 return err;
4437         }
4438
4439         phy = ((char *)&phy_list)[0];
4440         brcmf_dbg(INFO, "%c phy\n", phy);
4441         if (phy == 'n' || phy == 'a') {
4442                 wiphy = cfg_to_wiphy(cfg);
4443                 wiphy->bands[IEEE80211_BAND_5GHZ] = &__wl_band_5ghz_n;
4444         }
4445
4446         return err;
4447 }
4448
4449 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
4450 {
4451         return wl_update_wiphybands(cfg);
4452 }
4453
4454 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
4455 {
4456         struct net_device *ndev;
4457         struct wireless_dev *wdev;
4458         s32 power_mode;
4459         s32 err = 0;
4460
4461         if (cfg->dongle_up)
4462                 return err;
4463
4464         ndev = cfg_to_ndev(cfg);
4465         wdev = ndev->ieee80211_ptr;
4466
4467         brcmf_dongle_scantime(ndev, WL_SCAN_CHANNEL_TIME,
4468                         WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
4469
4470         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
4471         err = brcmf_fil_cmd_int_set(netdev_priv(ndev), BRCMF_C_SET_PM,
4472                                     power_mode);
4473         if (err)
4474                 goto default_conf_out;
4475         brcmf_dbg(INFO, "power save set to %s\n",
4476                   (power_mode ? "enabled" : "disabled"));
4477
4478         err = brcmf_dongle_roam(ndev, (cfg->roam_on ? 0 : 1),
4479                                 WL_BEACON_TIMEOUT);
4480         if (err)
4481                 goto default_conf_out;
4482         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
4483                                           NULL, NULL);
4484         if (err && err != -EINPROGRESS)
4485                 goto default_conf_out;
4486         err = brcmf_dongle_probecap(cfg);
4487         if (err)
4488                 goto default_conf_out;
4489
4490         /* -EINPROGRESS: Call commit handler */
4491
4492 default_conf_out:
4493
4494         cfg->dongle_up = true;
4495
4496         return err;
4497
4498 }
4499
4500 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
4501 {
4502         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4503         if (ifp->idx)
4504                 return 0;
4505
4506         return brcmf_config_dongle(ifp->drvr->config);
4507 }
4508
4509 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
4510 {
4511         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4512
4513         /*
4514          * While going down, if associated with AP disassociate
4515          * from AP to save power
4516          */
4517         if (check_vif_up(ifp->vif)) {
4518                 brcmf_link_down(ifp->vif);
4519
4520                 /* Make sure WPA_Supplicant receives all the event
4521                    generated due to DISASSOC call to the fw to keep
4522                    the state fw and WPA_Supplicant state consistent
4523                  */
4524                 brcmf_delay(500);
4525         }
4526
4527         brcmf_abort_scanning(cfg);
4528         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
4529
4530         return 0;
4531 }
4532
4533 s32 brcmf_cfg80211_up(struct net_device *ndev)
4534 {
4535         struct brcmf_if *ifp = netdev_priv(ndev);
4536         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4537         s32 err = 0;
4538
4539         mutex_lock(&cfg->usr_sync);
4540         err = __brcmf_cfg80211_up(ifp);
4541         mutex_unlock(&cfg->usr_sync);
4542
4543         return err;
4544 }
4545
4546 s32 brcmf_cfg80211_down(struct net_device *ndev)
4547 {
4548         struct brcmf_if *ifp = netdev_priv(ndev);
4549         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4550         s32 err = 0;
4551
4552         mutex_lock(&cfg->usr_sync);
4553         err = __brcmf_cfg80211_down(ifp);
4554         mutex_unlock(&cfg->usr_sync);
4555
4556         return err;
4557 }
4558