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