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