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