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