Merge tag 'dm-4.3-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/device...
[linux-2.6-microblaze.git] / drivers / net / wireless / brcm80211 / brcmfmac / cfg80211.c
1 /*
2  * Copyright (c) 2010 Broadcom Corporation
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
11  * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
13  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
14  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 /* Toplevel file. Relies on dhd_linux.c to send commands to the dongle. */
18
19 #include <linux/kernel.h>
20 #include <linux/etherdevice.h>
21 #include <linux/module.h>
22 #include <linux/vmalloc.h>
23 #include <net/cfg80211.h>
24 #include <net/netlink.h>
25
26 #include <brcmu_utils.h>
27 #include <defs.h>
28 #include <brcmu_wifi.h>
29 #include "core.h"
30 #include "debug.h"
31 #include "tracepoint.h"
32 #include "fwil_types.h"
33 #include "p2p.h"
34 #include "btcoex.h"
35 #include "cfg80211.h"
36 #include "feature.h"
37 #include "fwil.h"
38 #include "proto.h"
39 #include "vendor.h"
40 #include "bus.h"
41 #include "common.h"
42
43 #define BRCMF_SCAN_IE_LEN_MAX           2048
44 #define BRCMF_PNO_VERSION               2
45 #define BRCMF_PNO_TIME                  30
46 #define BRCMF_PNO_REPEAT                4
47 #define BRCMF_PNO_FREQ_EXPO_MAX         3
48 #define BRCMF_PNO_MAX_PFN_COUNT         16
49 #define BRCMF_PNO_ENABLE_ADAPTSCAN_BIT  6
50 #define BRCMF_PNO_HIDDEN_BIT            2
51 #define BRCMF_PNO_WPA_AUTH_ANY          0xFFFFFFFF
52 #define BRCMF_PNO_SCAN_COMPLETE         1
53 #define BRCMF_PNO_SCAN_INCOMPLETE       0
54
55 #define WPA_OUI                         "\x00\x50\xF2"  /* WPA OUI */
56 #define WPA_OUI_TYPE                    1
57 #define RSN_OUI                         "\x00\x0F\xAC"  /* RSN OUI */
58 #define WME_OUI_TYPE                    2
59 #define WPS_OUI_TYPE                    4
60
61 #define VS_IE_FIXED_HDR_LEN             6
62 #define WPA_IE_VERSION_LEN              2
63 #define WPA_IE_MIN_OUI_LEN              4
64 #define WPA_IE_SUITE_COUNT_LEN          2
65
66 #define WPA_CIPHER_NONE                 0       /* None */
67 #define WPA_CIPHER_WEP_40               1       /* WEP (40-bit) */
68 #define WPA_CIPHER_TKIP                 2       /* TKIP: default for WPA */
69 #define WPA_CIPHER_AES_CCM              4       /* AES (CCM) */
70 #define WPA_CIPHER_WEP_104              5       /* WEP (104-bit) */
71
72 #define RSN_AKM_NONE                    0       /* None (IBSS) */
73 #define RSN_AKM_UNSPECIFIED             1       /* Over 802.1x */
74 #define RSN_AKM_PSK                     2       /* Pre-shared Key */
75 #define RSN_CAP_LEN                     2       /* Length of RSN capabilities */
76 #define RSN_CAP_PTK_REPLAY_CNTR_MASK    0x000C
77
78 #define VNDR_IE_CMD_LEN                 4       /* length of the set command
79                                                  * string :"add", "del" (+ NUL)
80                                                  */
81 #define VNDR_IE_COUNT_OFFSET            4
82 #define VNDR_IE_PKTFLAG_OFFSET          8
83 #define VNDR_IE_VSIE_OFFSET             12
84 #define VNDR_IE_HDR_SIZE                12
85 #define VNDR_IE_PARSE_LIMIT             5
86
87 #define DOT11_MGMT_HDR_LEN              24      /* d11 management header len */
88 #define DOT11_BCN_PRB_FIXED_LEN         12      /* beacon/probe fixed length */
89
90 #define BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS    320
91 #define BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS   400
92 #define BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS       20
93
94 #define BRCMF_ASSOC_PARAMS_FIXED_SIZE \
95         (sizeof(struct brcmf_assoc_params_le) - sizeof(u16))
96
97 static bool check_vif_up(struct brcmf_cfg80211_vif *vif)
98 {
99         if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state)) {
100                 brcmf_dbg(INFO, "device is not ready : status (%lu)\n",
101                           vif->sme_state);
102                 return false;
103         }
104         return true;
105 }
106
107 #define RATE_TO_BASE100KBPS(rate)   (((rate) * 10) / 2)
108 #define RATETAB_ENT(_rateid, _flags) \
109         {                                                               \
110                 .bitrate        = RATE_TO_BASE100KBPS(_rateid),     \
111                 .hw_value       = (_rateid),                            \
112                 .flags          = (_flags),                             \
113         }
114
115 static struct ieee80211_rate __wl_rates[] = {
116         RATETAB_ENT(BRCM_RATE_1M, 0),
117         RATETAB_ENT(BRCM_RATE_2M, IEEE80211_RATE_SHORT_PREAMBLE),
118         RATETAB_ENT(BRCM_RATE_5M5, IEEE80211_RATE_SHORT_PREAMBLE),
119         RATETAB_ENT(BRCM_RATE_11M, IEEE80211_RATE_SHORT_PREAMBLE),
120         RATETAB_ENT(BRCM_RATE_6M, 0),
121         RATETAB_ENT(BRCM_RATE_9M, 0),
122         RATETAB_ENT(BRCM_RATE_12M, 0),
123         RATETAB_ENT(BRCM_RATE_18M, 0),
124         RATETAB_ENT(BRCM_RATE_24M, 0),
125         RATETAB_ENT(BRCM_RATE_36M, 0),
126         RATETAB_ENT(BRCM_RATE_48M, 0),
127         RATETAB_ENT(BRCM_RATE_54M, 0),
128 };
129
130 #define wl_g_rates              (__wl_rates + 0)
131 #define wl_g_rates_size         ARRAY_SIZE(__wl_rates)
132 #define wl_a_rates              (__wl_rates + 4)
133 #define wl_a_rates_size         (wl_g_rates_size - 4)
134
135 #define CHAN2G(_channel, _freq) {                               \
136         .band                   = IEEE80211_BAND_2GHZ,          \
137         .center_freq            = (_freq),                      \
138         .hw_value               = (_channel),                   \
139         .flags                  = IEEE80211_CHAN_DISABLED,      \
140         .max_antenna_gain       = 0,                            \
141         .max_power              = 30,                           \
142 }
143
144 #define CHAN5G(_channel) {                                      \
145         .band                   = IEEE80211_BAND_5GHZ,          \
146         .center_freq            = 5000 + (5 * (_channel)),      \
147         .hw_value               = (_channel),                   \
148         .flags                  = IEEE80211_CHAN_DISABLED,      \
149         .max_antenna_gain       = 0,                            \
150         .max_power              = 30,                           \
151 }
152
153 static struct ieee80211_channel __wl_2ghz_channels[] = {
154         CHAN2G(1, 2412), CHAN2G(2, 2417), CHAN2G(3, 2422), CHAN2G(4, 2427),
155         CHAN2G(5, 2432), CHAN2G(6, 2437), CHAN2G(7, 2442), CHAN2G(8, 2447),
156         CHAN2G(9, 2452), CHAN2G(10, 2457), CHAN2G(11, 2462), CHAN2G(12, 2467),
157         CHAN2G(13, 2472), CHAN2G(14, 2484)
158 };
159
160 static struct ieee80211_channel __wl_5ghz_channels[] = {
161         CHAN5G(34), CHAN5G(36), CHAN5G(38), CHAN5G(40), CHAN5G(42),
162         CHAN5G(44), CHAN5G(46), CHAN5G(48), CHAN5G(52), CHAN5G(56),
163         CHAN5G(60), CHAN5G(64), CHAN5G(100), CHAN5G(104), CHAN5G(108),
164         CHAN5G(112), CHAN5G(116), CHAN5G(120), CHAN5G(124), CHAN5G(128),
165         CHAN5G(132), CHAN5G(136), CHAN5G(140), CHAN5G(144), CHAN5G(149),
166         CHAN5G(153), CHAN5G(157), CHAN5G(161), CHAN5G(165)
167 };
168
169 /* Band templates duplicated per wiphy. The channel info
170  * above is added to the band during setup.
171  */
172 static const struct ieee80211_supported_band __wl_band_2ghz = {
173         .band = IEEE80211_BAND_2GHZ,
174         .bitrates = wl_g_rates,
175         .n_bitrates = wl_g_rates_size,
176 };
177
178 static const struct ieee80211_supported_band __wl_band_5ghz = {
179         .band = IEEE80211_BAND_5GHZ,
180         .bitrates = wl_a_rates,
181         .n_bitrates = wl_a_rates_size,
182 };
183
184 /* This is to override regulatory domains defined in cfg80211 module (reg.c)
185  * By default world regulatory domain defined in reg.c puts the flags
186  * NL80211_RRF_NO_IR for 5GHz channels (for * 36..48 and 149..165).
187  * With respect to these flags, wpa_supplicant doesn't * start p2p
188  * operations on 5GHz channels. All the changes in world regulatory
189  * domain are to be done here.
190  */
191 static const struct ieee80211_regdomain brcmf_regdom = {
192         .n_reg_rules = 4,
193         .alpha2 =  "99",
194         .reg_rules = {
195                 /* IEEE 802.11b/g, channels 1..11 */
196                 REG_RULE(2412-10, 2472+10, 40, 6, 20, 0),
197                 /* If any */
198                 /* IEEE 802.11 channel 14 - Only JP enables
199                  * this and for 802.11b only
200                  */
201                 REG_RULE(2484-10, 2484+10, 20, 6, 20, 0),
202                 /* IEEE 802.11a, channel 36..64 */
203                 REG_RULE(5150-10, 5350+10, 80, 6, 20, 0),
204                 /* IEEE 802.11a, channel 100..165 */
205                 REG_RULE(5470-10, 5850+10, 80, 6, 20, 0), }
206 };
207
208 static const u32 __wl_cipher_suites[] = {
209         WLAN_CIPHER_SUITE_WEP40,
210         WLAN_CIPHER_SUITE_WEP104,
211         WLAN_CIPHER_SUITE_TKIP,
212         WLAN_CIPHER_SUITE_CCMP,
213         WLAN_CIPHER_SUITE_AES_CMAC,
214 };
215
216 /* Vendor specific ie. id = 221, oui and type defines exact ie */
217 struct brcmf_vs_tlv {
218         u8 id;
219         u8 len;
220         u8 oui[3];
221         u8 oui_type;
222 };
223
224 struct parsed_vndr_ie_info {
225         u8 *ie_ptr;
226         u32 ie_len;     /* total length including id & length field */
227         struct brcmf_vs_tlv vndrie;
228 };
229
230 struct parsed_vndr_ies {
231         u32 count;
232         struct parsed_vndr_ie_info ie_info[VNDR_IE_PARSE_LIMIT];
233 };
234
235 static int brcmf_roamoff;
236 module_param_named(roamoff, brcmf_roamoff, int, S_IRUSR);
237 MODULE_PARM_DESC(roamoff, "do not use internal roaming engine");
238
239 /* Quarter dBm units to mW
240  * Table starts at QDBM_OFFSET, so the first entry is mW for qdBm=153
241  * Table is offset so the last entry is largest mW value that fits in
242  * a u16.
243  */
244
245 #define QDBM_OFFSET 153         /* Offset for first entry */
246 #define QDBM_TABLE_LEN 40       /* Table size */
247
248 /* Smallest mW value that will round up to the first table entry, QDBM_OFFSET.
249  * Value is ( mW(QDBM_OFFSET - 1) + mW(QDBM_OFFSET) ) / 2
250  */
251 #define QDBM_TABLE_LOW_BOUND 6493       /* Low bound */
252
253 /* Largest mW value that will round down to the last table entry,
254  * QDBM_OFFSET + QDBM_TABLE_LEN-1.
255  * Value is ( mW(QDBM_OFFSET + QDBM_TABLE_LEN - 1) +
256  * mW(QDBM_OFFSET + QDBM_TABLE_LEN) ) / 2.
257  */
258 #define QDBM_TABLE_HIGH_BOUND 64938     /* High bound */
259
260 static const u16 nqdBm_to_mW_map[QDBM_TABLE_LEN] = {
261 /* qdBm:        +0      +1      +2      +3      +4      +5      +6      +7 */
262 /* 153: */ 6683, 7079, 7499, 7943, 8414, 8913, 9441, 10000,
263 /* 161: */ 10593, 11220, 11885, 12589, 13335, 14125, 14962, 15849,
264 /* 169: */ 16788, 17783, 18836, 19953, 21135, 22387, 23714, 25119,
265 /* 177: */ 26607, 28184, 29854, 31623, 33497, 35481, 37584, 39811,
266 /* 185: */ 42170, 44668, 47315, 50119, 53088, 56234, 59566, 63096
267 };
268
269 static u16 brcmf_qdbm_to_mw(u8 qdbm)
270 {
271         uint factor = 1;
272         int idx = qdbm - QDBM_OFFSET;
273
274         if (idx >= QDBM_TABLE_LEN)
275                 /* clamp to max u16 mW value */
276                 return 0xFFFF;
277
278         /* scale the qdBm index up to the range of the table 0-40
279          * where an offset of 40 qdBm equals a factor of 10 mW.
280          */
281         while (idx < 0) {
282                 idx += 40;
283                 factor *= 10;
284         }
285
286         /* return the mW value scaled down to the correct factor of 10,
287          * adding in factor/2 to get proper rounding.
288          */
289         return (nqdBm_to_mW_map[idx] + factor / 2) / factor;
290 }
291
292 static u8 brcmf_mw_to_qdbm(u16 mw)
293 {
294         u8 qdbm;
295         int offset;
296         uint mw_uint = mw;
297         uint boundary;
298
299         /* handle boundary case */
300         if (mw_uint <= 1)
301                 return 0;
302
303         offset = QDBM_OFFSET;
304
305         /* move mw into the range of the table */
306         while (mw_uint < QDBM_TABLE_LOW_BOUND) {
307                 mw_uint *= 10;
308                 offset -= 40;
309         }
310
311         for (qdbm = 0; qdbm < QDBM_TABLE_LEN - 1; qdbm++) {
312                 boundary = nqdBm_to_mW_map[qdbm] + (nqdBm_to_mW_map[qdbm + 1] -
313                                                     nqdBm_to_mW_map[qdbm]) / 2;
314                 if (mw_uint < boundary)
315                         break;
316         }
317
318         qdbm += (u8) offset;
319
320         return qdbm;
321 }
322
323 static u16 chandef_to_chanspec(struct brcmu_d11inf *d11inf,
324                                struct cfg80211_chan_def *ch)
325 {
326         struct brcmu_chan ch_inf;
327         s32 primary_offset;
328
329         brcmf_dbg(TRACE, "chandef: control %d center %d width %d\n",
330                   ch->chan->center_freq, ch->center_freq1, ch->width);
331         ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq1);
332         primary_offset = ch->center_freq1 - ch->chan->center_freq;
333         switch (ch->width) {
334         case NL80211_CHAN_WIDTH_20:
335         case NL80211_CHAN_WIDTH_20_NOHT:
336                 ch_inf.bw = BRCMU_CHAN_BW_20;
337                 WARN_ON(primary_offset != 0);
338                 break;
339         case NL80211_CHAN_WIDTH_40:
340                 ch_inf.bw = BRCMU_CHAN_BW_40;
341                 if (primary_offset < 0)
342                         ch_inf.sb = BRCMU_CHAN_SB_U;
343                 else
344                         ch_inf.sb = BRCMU_CHAN_SB_L;
345                 break;
346         case NL80211_CHAN_WIDTH_80:
347                 ch_inf.bw = BRCMU_CHAN_BW_80;
348                 if (primary_offset < 0) {
349                         if (primary_offset < -CH_10MHZ_APART)
350                                 ch_inf.sb = BRCMU_CHAN_SB_UU;
351                         else
352                                 ch_inf.sb = BRCMU_CHAN_SB_UL;
353                 } else {
354                         if (primary_offset > CH_10MHZ_APART)
355                                 ch_inf.sb = BRCMU_CHAN_SB_LL;
356                         else
357                                 ch_inf.sb = BRCMU_CHAN_SB_LU;
358                 }
359                 break;
360         case NL80211_CHAN_WIDTH_80P80:
361         case NL80211_CHAN_WIDTH_160:
362         case NL80211_CHAN_WIDTH_5:
363         case NL80211_CHAN_WIDTH_10:
364         default:
365                 WARN_ON_ONCE(1);
366         }
367         switch (ch->chan->band) {
368         case IEEE80211_BAND_2GHZ:
369                 ch_inf.band = BRCMU_CHAN_BAND_2G;
370                 break;
371         case IEEE80211_BAND_5GHZ:
372                 ch_inf.band = BRCMU_CHAN_BAND_5G;
373                 break;
374         case IEEE80211_BAND_60GHZ:
375         default:
376                 WARN_ON_ONCE(1);
377         }
378         d11inf->encchspec(&ch_inf);
379
380         return ch_inf.chspec;
381 }
382
383 u16 channel_to_chanspec(struct brcmu_d11inf *d11inf,
384                         struct ieee80211_channel *ch)
385 {
386         struct brcmu_chan ch_inf;
387
388         ch_inf.chnum = ieee80211_frequency_to_channel(ch->center_freq);
389         ch_inf.bw = BRCMU_CHAN_BW_20;
390         d11inf->encchspec(&ch_inf);
391
392         return ch_inf.chspec;
393 }
394
395 /* Traverse a string of 1-byte tag/1-byte length/variable-length value
396  * triples, returning a pointer to the substring whose first element
397  * matches tag
398  */
399 const struct brcmf_tlv *
400 brcmf_parse_tlvs(const void *buf, int buflen, uint key)
401 {
402         const struct brcmf_tlv *elt = buf;
403         int totlen = buflen;
404
405         /* find tagged parameter */
406         while (totlen >= TLV_HDR_LEN) {
407                 int len = elt->len;
408
409                 /* validate remaining totlen */
410                 if ((elt->id == key) && (totlen >= (len + TLV_HDR_LEN)))
411                         return elt;
412
413                 elt = (struct brcmf_tlv *)((u8 *)elt + (len + TLV_HDR_LEN));
414                 totlen -= (len + TLV_HDR_LEN);
415         }
416
417         return NULL;
418 }
419
420 /* Is any of the tlvs the expected entry? If
421  * not update the tlvs buffer pointer/length.
422  */
423 static bool
424 brcmf_tlv_has_ie(const u8 *ie, const u8 **tlvs, u32 *tlvs_len,
425                  const u8 *oui, u32 oui_len, u8 type)
426 {
427         /* If the contents match the OUI and the type */
428         if (ie[TLV_LEN_OFF] >= oui_len + 1 &&
429             !memcmp(&ie[TLV_BODY_OFF], oui, oui_len) &&
430             type == ie[TLV_BODY_OFF + oui_len]) {
431                 return true;
432         }
433
434         if (tlvs == NULL)
435                 return false;
436         /* point to the next ie */
437         ie += ie[TLV_LEN_OFF] + TLV_HDR_LEN;
438         /* calculate the length of the rest of the buffer */
439         *tlvs_len -= (int)(ie - *tlvs);
440         /* update the pointer to the start of the buffer */
441         *tlvs = ie;
442
443         return false;
444 }
445
446 static struct brcmf_vs_tlv *
447 brcmf_find_wpaie(const u8 *parse, u32 len)
448 {
449         const struct brcmf_tlv *ie;
450
451         while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
452                 if (brcmf_tlv_has_ie((const u8 *)ie, &parse, &len,
453                                      WPA_OUI, TLV_OUI_LEN, WPA_OUI_TYPE))
454                         return (struct brcmf_vs_tlv *)ie;
455         }
456         return NULL;
457 }
458
459 static struct brcmf_vs_tlv *
460 brcmf_find_wpsie(const u8 *parse, u32 len)
461 {
462         const struct brcmf_tlv *ie;
463
464         while ((ie = brcmf_parse_tlvs(parse, len, WLAN_EID_VENDOR_SPECIFIC))) {
465                 if (brcmf_tlv_has_ie((u8 *)ie, &parse, &len,
466                                      WPA_OUI, TLV_OUI_LEN, WPS_OUI_TYPE))
467                         return (struct brcmf_vs_tlv *)ie;
468         }
469         return NULL;
470 }
471
472
473 static void convert_key_from_CPU(struct brcmf_wsec_key *key,
474                                  struct brcmf_wsec_key_le *key_le)
475 {
476         key_le->index = cpu_to_le32(key->index);
477         key_le->len = cpu_to_le32(key->len);
478         key_le->algo = cpu_to_le32(key->algo);
479         key_le->flags = cpu_to_le32(key->flags);
480         key_le->rxiv.hi = cpu_to_le32(key->rxiv.hi);
481         key_le->rxiv.lo = cpu_to_le16(key->rxiv.lo);
482         key_le->iv_initialized = cpu_to_le32(key->iv_initialized);
483         memcpy(key_le->data, key->data, sizeof(key->data));
484         memcpy(key_le->ea, key->ea, sizeof(key->ea));
485 }
486
487 static int
488 send_key_to_dongle(struct brcmf_if *ifp, struct brcmf_wsec_key *key)
489 {
490         int err;
491         struct brcmf_wsec_key_le key_le;
492
493         convert_key_from_CPU(key, &key_le);
494
495         brcmf_netdev_wait_pend8021x(ifp);
496
497         err = brcmf_fil_bsscfg_data_set(ifp, "wsec_key", &key_le,
498                                         sizeof(key_le));
499
500         if (err)
501                 brcmf_err("wsec_key error (%d)\n", err);
502         return err;
503 }
504
505 static s32
506 brcmf_configure_arp_offload(struct brcmf_if *ifp, bool enable)
507 {
508         s32 err;
509         u32 mode;
510
511         if (enable)
512                 mode = BRCMF_ARP_OL_AGENT | BRCMF_ARP_OL_PEER_AUTO_REPLY;
513         else
514                 mode = 0;
515
516         /* Try to set and enable ARP offload feature, this may fail, then it  */
517         /* is simply not supported and err 0 will be returned                 */
518         err = brcmf_fil_iovar_int_set(ifp, "arp_ol", mode);
519         if (err) {
520                 brcmf_dbg(TRACE, "failed to set ARP offload mode to 0x%x, err = %d\n",
521                           mode, err);
522                 err = 0;
523         } else {
524                 err = brcmf_fil_iovar_int_set(ifp, "arpoe", enable);
525                 if (err) {
526                         brcmf_dbg(TRACE, "failed to configure (%d) ARP offload err = %d\n",
527                                   enable, err);
528                         err = 0;
529                 } else
530                         brcmf_dbg(TRACE, "successfully configured (%d) ARP offload to 0x%x\n",
531                                   enable, mode);
532         }
533
534         return err;
535 }
536
537 static void
538 brcmf_cfg80211_update_proto_addr_mode(struct wireless_dev *wdev)
539 {
540         struct brcmf_cfg80211_vif *vif;
541         struct brcmf_if *ifp;
542
543         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
544         ifp = vif->ifp;
545
546         if ((wdev->iftype == NL80211_IFTYPE_ADHOC) ||
547             (wdev->iftype == NL80211_IFTYPE_AP) ||
548             (wdev->iftype == NL80211_IFTYPE_P2P_GO))
549                 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
550                                                 ADDR_DIRECT);
551         else
552                 brcmf_proto_configure_addr_mode(ifp->drvr, ifp->ifidx,
553                                                 ADDR_INDIRECT);
554 }
555
556 static int brcmf_cfg80211_request_ap_if(struct brcmf_if *ifp)
557 {
558         struct brcmf_mbss_ssid_le mbss_ssid_le;
559         int bsscfgidx;
560         int err;
561
562         memset(&mbss_ssid_le, 0, sizeof(mbss_ssid_le));
563         bsscfgidx = brcmf_get_next_free_bsscfgidx(ifp->drvr);
564         if (bsscfgidx < 0)
565                 return bsscfgidx;
566
567         mbss_ssid_le.bsscfgidx = cpu_to_le32(bsscfgidx);
568         mbss_ssid_le.SSID_len = cpu_to_le32(5);
569         sprintf(mbss_ssid_le.SSID, "ssid%d" , bsscfgidx);
570
571         err = brcmf_fil_bsscfg_data_set(ifp, "bsscfg:ssid", &mbss_ssid_le,
572                                         sizeof(mbss_ssid_le));
573         if (err < 0)
574                 brcmf_err("setting ssid failed %d\n", err);
575
576         return err;
577 }
578
579 /**
580  * brcmf_ap_add_vif() - create a new AP virtual interface for multiple BSS
581  *
582  * @wiphy: wiphy device of new interface.
583  * @name: name of the new interface.
584  * @flags: not used.
585  * @params: contains mac address for AP device.
586  */
587 static
588 struct wireless_dev *brcmf_ap_add_vif(struct wiphy *wiphy, const char *name,
589                                       u32 *flags, struct vif_params *params)
590 {
591         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
592         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
593         struct brcmf_cfg80211_vif *vif;
594         int err;
595
596         if (brcmf_cfg80211_vif_event_armed(cfg))
597                 return ERR_PTR(-EBUSY);
598
599         brcmf_dbg(INFO, "Adding vif \"%s\"\n", name);
600
601         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_AP, false);
602         if (IS_ERR(vif))
603                 return (struct wireless_dev *)vif;
604
605         brcmf_cfg80211_arm_vif_event(cfg, vif);
606
607         err = brcmf_cfg80211_request_ap_if(ifp);
608         if (err) {
609                 brcmf_cfg80211_arm_vif_event(cfg, NULL);
610                 goto fail;
611         }
612
613         /* wait for firmware event */
614         err = brcmf_cfg80211_wait_vif_event_timeout(cfg, BRCMF_E_IF_ADD,
615                                                     msecs_to_jiffies(1500));
616         brcmf_cfg80211_arm_vif_event(cfg, NULL);
617         if (!err) {
618                 brcmf_err("timeout occurred\n");
619                 err = -EIO;
620                 goto fail;
621         }
622
623         /* interface created in firmware */
624         ifp = vif->ifp;
625         if (!ifp) {
626                 brcmf_err("no if pointer provided\n");
627                 err = -ENOENT;
628                 goto fail;
629         }
630
631         strncpy(ifp->ndev->name, name, sizeof(ifp->ndev->name) - 1);
632         err = brcmf_net_attach(ifp, true);
633         if (err) {
634                 brcmf_err("Registering netdevice failed\n");
635                 goto fail;
636         }
637
638         return &ifp->vif->wdev;
639
640 fail:
641         brcmf_free_vif(vif);
642         return ERR_PTR(err);
643 }
644
645 static bool brcmf_is_apmode(struct brcmf_cfg80211_vif *vif)
646 {
647         enum nl80211_iftype iftype;
648
649         iftype = vif->wdev.iftype;
650         return iftype == NL80211_IFTYPE_AP || iftype == NL80211_IFTYPE_P2P_GO;
651 }
652
653 static bool brcmf_is_ibssmode(struct brcmf_cfg80211_vif *vif)
654 {
655         return vif->wdev.iftype == NL80211_IFTYPE_ADHOC;
656 }
657
658 static struct wireless_dev *brcmf_cfg80211_add_iface(struct wiphy *wiphy,
659                                                      const char *name,
660                                                      unsigned char name_assign_type,
661                                                      enum nl80211_iftype type,
662                                                      u32 *flags,
663                                                      struct vif_params *params)
664 {
665         struct wireless_dev *wdev;
666
667         brcmf_dbg(TRACE, "enter: %s type %d\n", name, type);
668         switch (type) {
669         case NL80211_IFTYPE_ADHOC:
670         case NL80211_IFTYPE_STATION:
671         case NL80211_IFTYPE_AP_VLAN:
672         case NL80211_IFTYPE_WDS:
673         case NL80211_IFTYPE_MONITOR:
674         case NL80211_IFTYPE_MESH_POINT:
675                 return ERR_PTR(-EOPNOTSUPP);
676         case NL80211_IFTYPE_AP:
677                 wdev = brcmf_ap_add_vif(wiphy, name, flags, params);
678                 if (!IS_ERR(wdev))
679                         brcmf_cfg80211_update_proto_addr_mode(wdev);
680                 return wdev;
681         case NL80211_IFTYPE_P2P_CLIENT:
682         case NL80211_IFTYPE_P2P_GO:
683         case NL80211_IFTYPE_P2P_DEVICE:
684                 wdev = brcmf_p2p_add_vif(wiphy, name, name_assign_type, type, flags, params);
685                 if (!IS_ERR(wdev))
686                         brcmf_cfg80211_update_proto_addr_mode(wdev);
687                 return wdev;
688         case NL80211_IFTYPE_UNSPECIFIED:
689         default:
690                 return ERR_PTR(-EINVAL);
691         }
692 }
693
694 static void brcmf_scan_config_mpc(struct brcmf_if *ifp, int mpc)
695 {
696         if (brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_NEED_MPC))
697                 brcmf_set_mpc(ifp, mpc);
698 }
699
700 void brcmf_set_mpc(struct brcmf_if *ifp, int mpc)
701 {
702         s32 err = 0;
703
704         if (check_vif_up(ifp->vif)) {
705                 err = brcmf_fil_iovar_int_set(ifp, "mpc", mpc);
706                 if (err) {
707                         brcmf_err("fail to set mpc\n");
708                         return;
709                 }
710                 brcmf_dbg(INFO, "MPC : %d\n", mpc);
711         }
712 }
713
714 s32 brcmf_notify_escan_complete(struct brcmf_cfg80211_info *cfg,
715                                 struct brcmf_if *ifp, bool aborted,
716                                 bool fw_abort)
717 {
718         struct brcmf_scan_params_le params_le;
719         struct cfg80211_scan_request *scan_request;
720         s32 err = 0;
721
722         brcmf_dbg(SCAN, "Enter\n");
723
724         /* clear scan request, because the FW abort can cause a second call */
725         /* to this functon and might cause a double cfg80211_scan_done      */
726         scan_request = cfg->scan_request;
727         cfg->scan_request = NULL;
728
729         if (timer_pending(&cfg->escan_timeout))
730                 del_timer_sync(&cfg->escan_timeout);
731
732         if (fw_abort) {
733                 /* Do a scan abort to stop the driver's scan engine */
734                 brcmf_dbg(SCAN, "ABORT scan in firmware\n");
735                 memset(&params_le, 0, sizeof(params_le));
736                 eth_broadcast_addr(params_le.bssid);
737                 params_le.bss_type = DOT11_BSSTYPE_ANY;
738                 params_le.scan_type = 0;
739                 params_le.channel_num = cpu_to_le32(1);
740                 params_le.nprobes = cpu_to_le32(1);
741                 params_le.active_time = cpu_to_le32(-1);
742                 params_le.passive_time = cpu_to_le32(-1);
743                 params_le.home_time = cpu_to_le32(-1);
744                 /* Scan is aborted by setting channel_list[0] to -1 */
745                 params_le.channel_list[0] = cpu_to_le16(-1);
746                 /* E-Scan (or anyother type) can be aborted by SCAN */
747                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
748                                              &params_le, sizeof(params_le));
749                 if (err)
750                         brcmf_err("Scan abort  failed\n");
751         }
752
753         brcmf_scan_config_mpc(ifp, 1);
754
755         /*
756          * e-scan can be initiated by scheduled scan
757          * which takes precedence.
758          */
759         if (cfg->sched_escan) {
760                 brcmf_dbg(SCAN, "scheduled scan completed\n");
761                 cfg->sched_escan = false;
762                 if (!aborted)
763                         cfg80211_sched_scan_results(cfg_to_wiphy(cfg));
764         } else if (scan_request) {
765                 brcmf_dbg(SCAN, "ESCAN Completed scan: %s\n",
766                           aborted ? "Aborted" : "Done");
767                 cfg80211_scan_done(scan_request, aborted);
768         }
769         if (!test_and_clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
770                 brcmf_dbg(SCAN, "Scan complete, probably P2P scan\n");
771
772         return err;
773 }
774
775 static
776 int brcmf_cfg80211_del_iface(struct wiphy *wiphy, struct wireless_dev *wdev)
777 {
778         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
779         struct net_device *ndev = wdev->netdev;
780
781         /* vif event pending in firmware */
782         if (brcmf_cfg80211_vif_event_armed(cfg))
783                 return -EBUSY;
784
785         if (ndev) {
786                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status) &&
787                     cfg->escan_info.ifp == netdev_priv(ndev))
788                         brcmf_notify_escan_complete(cfg, netdev_priv(ndev),
789                                                     true, true);
790
791                 brcmf_fil_iovar_int_set(netdev_priv(ndev), "mpc", 1);
792         }
793
794         switch (wdev->iftype) {
795         case NL80211_IFTYPE_ADHOC:
796         case NL80211_IFTYPE_STATION:
797         case NL80211_IFTYPE_AP:
798         case NL80211_IFTYPE_AP_VLAN:
799         case NL80211_IFTYPE_WDS:
800         case NL80211_IFTYPE_MONITOR:
801         case NL80211_IFTYPE_MESH_POINT:
802                 return -EOPNOTSUPP;
803         case NL80211_IFTYPE_P2P_CLIENT:
804         case NL80211_IFTYPE_P2P_GO:
805         case NL80211_IFTYPE_P2P_DEVICE:
806                 return brcmf_p2p_del_vif(wiphy, wdev);
807         case NL80211_IFTYPE_UNSPECIFIED:
808         default:
809                 return -EINVAL;
810         }
811         return -EOPNOTSUPP;
812 }
813
814 static s32
815 brcmf_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
816                          enum nl80211_iftype type, u32 *flags,
817                          struct vif_params *params)
818 {
819         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
820         struct brcmf_if *ifp = netdev_priv(ndev);
821         struct brcmf_cfg80211_vif *vif = ifp->vif;
822         s32 infra = 0;
823         s32 ap = 0;
824         s32 err = 0;
825
826         brcmf_dbg(TRACE, "Enter, ndev=%p, type=%d\n", ndev, type);
827
828         switch (type) {
829         case NL80211_IFTYPE_MONITOR:
830         case NL80211_IFTYPE_WDS:
831                 brcmf_err("type (%d) : currently we do not support this type\n",
832                           type);
833                 return -EOPNOTSUPP;
834         case NL80211_IFTYPE_ADHOC:
835                 infra = 0;
836                 break;
837         case NL80211_IFTYPE_STATION:
838                 /* Ignore change for p2p IF. Unclear why supplicant does this */
839                 if ((vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) ||
840                     (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO)) {
841                         brcmf_dbg(TRACE, "Ignoring cmd for p2p if\n");
842                         /* WAR: It is unexpected to get a change of VIF for P2P
843                          * IF, but it happens. The request can not be handled
844                          * but returning EPERM causes a crash. Returning 0
845                          * without setting ieee80211_ptr->iftype causes trace
846                          * (WARN_ON) but it works with wpa_supplicant
847                          */
848                         return 0;
849                 }
850                 infra = 1;
851                 break;
852         case NL80211_IFTYPE_AP:
853         case NL80211_IFTYPE_P2P_GO:
854                 ap = 1;
855                 break;
856         default:
857                 err = -EINVAL;
858                 goto done;
859         }
860
861         if (ap) {
862                 if (type == NL80211_IFTYPE_P2P_GO) {
863                         brcmf_dbg(INFO, "IF Type = P2P GO\n");
864                         err = brcmf_p2p_ifchange(cfg, BRCMF_FIL_P2P_IF_GO);
865                 }
866                 if (!err) {
867                         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &vif->sme_state);
868                         brcmf_dbg(INFO, "IF Type = AP\n");
869                 }
870         } else {
871                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, infra);
872                 if (err) {
873                         brcmf_err("WLC_SET_INFRA error (%d)\n", err);
874                         err = -EAGAIN;
875                         goto done;
876                 }
877                 brcmf_dbg(INFO, "IF Type = %s\n", brcmf_is_ibssmode(vif) ?
878                           "Adhoc" : "Infra");
879         }
880         ndev->ieee80211_ptr->iftype = type;
881
882         brcmf_cfg80211_update_proto_addr_mode(&vif->wdev);
883
884 done:
885         brcmf_dbg(TRACE, "Exit\n");
886
887         return err;
888 }
889
890 static void brcmf_escan_prep(struct brcmf_cfg80211_info *cfg,
891                              struct brcmf_scan_params_le *params_le,
892                              struct cfg80211_scan_request *request)
893 {
894         u32 n_ssids;
895         u32 n_channels;
896         s32 i;
897         s32 offset;
898         u16 chanspec;
899         char *ptr;
900         struct brcmf_ssid_le ssid_le;
901
902         eth_broadcast_addr(params_le->bssid);
903         params_le->bss_type = DOT11_BSSTYPE_ANY;
904         params_le->scan_type = 0;
905         params_le->channel_num = 0;
906         params_le->nprobes = cpu_to_le32(-1);
907         params_le->active_time = cpu_to_le32(-1);
908         params_le->passive_time = cpu_to_le32(-1);
909         params_le->home_time = cpu_to_le32(-1);
910         memset(&params_le->ssid_le, 0, sizeof(params_le->ssid_le));
911
912         /* if request is null exit so it will be all channel broadcast scan */
913         if (!request)
914                 return;
915
916         n_ssids = request->n_ssids;
917         n_channels = request->n_channels;
918         /* Copy channel array if applicable */
919         brcmf_dbg(SCAN, "### List of channelspecs to scan ### %d\n",
920                   n_channels);
921         if (n_channels > 0) {
922                 for (i = 0; i < n_channels; i++) {
923                         chanspec = channel_to_chanspec(&cfg->d11inf,
924                                                        request->channels[i]);
925                         brcmf_dbg(SCAN, "Chan : %d, Channel spec: %x\n",
926                                   request->channels[i]->hw_value, chanspec);
927                         params_le->channel_list[i] = cpu_to_le16(chanspec);
928                 }
929         } else {
930                 brcmf_dbg(SCAN, "Scanning all channels\n");
931         }
932         /* Copy ssid array if applicable */
933         brcmf_dbg(SCAN, "### List of SSIDs to scan ### %d\n", n_ssids);
934         if (n_ssids > 0) {
935                 offset = offsetof(struct brcmf_scan_params_le, channel_list) +
936                                 n_channels * sizeof(u16);
937                 offset = roundup(offset, sizeof(u32));
938                 ptr = (char *)params_le + offset;
939                 for (i = 0; i < n_ssids; i++) {
940                         memset(&ssid_le, 0, sizeof(ssid_le));
941                         ssid_le.SSID_len =
942                                         cpu_to_le32(request->ssids[i].ssid_len);
943                         memcpy(ssid_le.SSID, request->ssids[i].ssid,
944                                request->ssids[i].ssid_len);
945                         if (!ssid_le.SSID_len)
946                                 brcmf_dbg(SCAN, "%d: Broadcast scan\n", i);
947                         else
948                                 brcmf_dbg(SCAN, "%d: scan for  %s size =%d\n",
949                                           i, ssid_le.SSID, ssid_le.SSID_len);
950                         memcpy(ptr, &ssid_le, sizeof(ssid_le));
951                         ptr += sizeof(ssid_le);
952                 }
953         } else {
954                 brcmf_dbg(SCAN, "Broadcast scan %p\n", request->ssids);
955                 if ((request->ssids) && request->ssids->ssid_len) {
956                         brcmf_dbg(SCAN, "SSID %s len=%d\n",
957                                   params_le->ssid_le.SSID,
958                                   request->ssids->ssid_len);
959                         params_le->ssid_le.SSID_len =
960                                 cpu_to_le32(request->ssids->ssid_len);
961                         memcpy(&params_le->ssid_le.SSID, request->ssids->ssid,
962                                 request->ssids->ssid_len);
963                 }
964         }
965         /* Adding mask to channel numbers */
966         params_le->channel_num =
967                 cpu_to_le32((n_ssids << BRCMF_SCAN_PARAMS_NSSID_SHIFT) |
968                         (n_channels & BRCMF_SCAN_PARAMS_COUNT_MASK));
969 }
970
971 static s32
972 brcmf_run_escan(struct brcmf_cfg80211_info *cfg, struct brcmf_if *ifp,
973                 struct cfg80211_scan_request *request, u16 action)
974 {
975         s32 params_size = BRCMF_SCAN_PARAMS_FIXED_SIZE +
976                           offsetof(struct brcmf_escan_params_le, params_le);
977         struct brcmf_escan_params_le *params;
978         s32 err = 0;
979
980         brcmf_dbg(SCAN, "E-SCAN START\n");
981
982         if (request != NULL) {
983                 /* Allocate space for populating ssids in struct */
984                 params_size += sizeof(u32) * ((request->n_channels + 1) / 2);
985
986                 /* Allocate space for populating ssids in struct */
987                 params_size += sizeof(struct brcmf_ssid) * request->n_ssids;
988         }
989
990         params = kzalloc(params_size, GFP_KERNEL);
991         if (!params) {
992                 err = -ENOMEM;
993                 goto exit;
994         }
995         BUG_ON(params_size + sizeof("escan") >= BRCMF_DCMD_MEDLEN);
996         brcmf_escan_prep(cfg, &params->params_le, request);
997         params->version = cpu_to_le32(BRCMF_ESCAN_REQ_VERSION);
998         params->action = cpu_to_le16(action);
999         params->sync_id = cpu_to_le16(0x1234);
1000
1001         err = brcmf_fil_iovar_data_set(ifp, "escan", params, params_size);
1002         if (err) {
1003                 if (err == -EBUSY)
1004                         brcmf_dbg(INFO, "system busy : escan canceled\n");
1005                 else
1006                         brcmf_err("error (%d)\n", err);
1007         }
1008
1009         kfree(params);
1010 exit:
1011         return err;
1012 }
1013
1014 static s32
1015 brcmf_do_escan(struct brcmf_cfg80211_info *cfg, struct wiphy *wiphy,
1016                struct brcmf_if *ifp, struct cfg80211_scan_request *request)
1017 {
1018         s32 err;
1019         u32 passive_scan;
1020         struct brcmf_scan_results *results;
1021         struct escan_info *escan = &cfg->escan_info;
1022
1023         brcmf_dbg(SCAN, "Enter\n");
1024         escan->ifp = ifp;
1025         escan->wiphy = wiphy;
1026         escan->escan_state = WL_ESCAN_STATE_SCANNING;
1027         passive_scan = cfg->active_scan ? 0 : 1;
1028         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1029                                     passive_scan);
1030         if (err) {
1031                 brcmf_err("error (%d)\n", err);
1032                 return err;
1033         }
1034         brcmf_scan_config_mpc(ifp, 0);
1035         results = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
1036         results->version = 0;
1037         results->count = 0;
1038         results->buflen = WL_ESCAN_RESULTS_FIXED_SIZE;
1039
1040         err = escan->run(cfg, ifp, request, WL_ESCAN_ACTION_START);
1041         if (err)
1042                 brcmf_scan_config_mpc(ifp, 1);
1043         return err;
1044 }
1045
1046 static s32
1047 brcmf_cfg80211_escan(struct wiphy *wiphy, struct brcmf_cfg80211_vif *vif,
1048                      struct cfg80211_scan_request *request,
1049                      struct cfg80211_ssid *this_ssid)
1050 {
1051         struct brcmf_if *ifp = vif->ifp;
1052         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1053         struct cfg80211_ssid *ssids;
1054         struct brcmf_cfg80211_scan_req *sr = &cfg->scan_req_int;
1055         u32 passive_scan;
1056         bool escan_req;
1057         bool spec_scan;
1058         s32 err;
1059         u32 SSID_len;
1060
1061         brcmf_dbg(SCAN, "START ESCAN\n");
1062
1063         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
1064                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
1065                 return -EAGAIN;
1066         }
1067         if (test_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status)) {
1068                 brcmf_err("Scanning being aborted: status (%lu)\n",
1069                           cfg->scan_status);
1070                 return -EAGAIN;
1071         }
1072         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
1073                 brcmf_err("Scanning suppressed: status (%lu)\n",
1074                           cfg->scan_status);
1075                 return -EAGAIN;
1076         }
1077         if (test_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state)) {
1078                 brcmf_err("Connecting: status (%lu)\n", ifp->vif->sme_state);
1079                 return -EAGAIN;
1080         }
1081
1082         /* If scan req comes for p2p0, send it over primary I/F */
1083         if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
1084                 vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif;
1085
1086         escan_req = false;
1087         if (request) {
1088                 /* scan bss */
1089                 ssids = request->ssids;
1090                 escan_req = true;
1091         } else {
1092                 /* scan in ibss */
1093                 /* we don't do escan in ibss */
1094                 ssids = this_ssid;
1095         }
1096
1097         cfg->scan_request = request;
1098         set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1099         if (escan_req) {
1100                 cfg->escan_info.run = brcmf_run_escan;
1101                 err = brcmf_p2p_scan_prep(wiphy, request, vif);
1102                 if (err)
1103                         goto scan_out;
1104
1105                 err = brcmf_do_escan(cfg, wiphy, vif->ifp, request);
1106                 if (err)
1107                         goto scan_out;
1108         } else {
1109                 brcmf_dbg(SCAN, "ssid \"%s\", ssid_len (%d)\n",
1110                           ssids->ssid, ssids->ssid_len);
1111                 memset(&sr->ssid_le, 0, sizeof(sr->ssid_le));
1112                 SSID_len = min_t(u8, sizeof(sr->ssid_le.SSID), ssids->ssid_len);
1113                 sr->ssid_le.SSID_len = cpu_to_le32(0);
1114                 spec_scan = false;
1115                 if (SSID_len) {
1116                         memcpy(sr->ssid_le.SSID, ssids->ssid, SSID_len);
1117                         sr->ssid_le.SSID_len = cpu_to_le32(SSID_len);
1118                         spec_scan = true;
1119                 } else
1120                         brcmf_dbg(SCAN, "Broadcast scan\n");
1121
1122                 passive_scan = cfg->active_scan ? 0 : 1;
1123                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PASSIVE_SCAN,
1124                                             passive_scan);
1125                 if (err) {
1126                         brcmf_err("WLC_SET_PASSIVE_SCAN error (%d)\n", err);
1127                         goto scan_out;
1128                 }
1129                 brcmf_scan_config_mpc(ifp, 0);
1130                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCAN,
1131                                              &sr->ssid_le, sizeof(sr->ssid_le));
1132                 if (err) {
1133                         if (err == -EBUSY)
1134                                 brcmf_dbg(INFO, "BUSY: scan for \"%s\" canceled\n",
1135                                           sr->ssid_le.SSID);
1136                         else
1137                                 brcmf_err("WLC_SCAN error (%d)\n", err);
1138
1139                         brcmf_scan_config_mpc(ifp, 1);
1140                         goto scan_out;
1141                 }
1142         }
1143
1144         /* Arm scan timeout timer */
1145         mod_timer(&cfg->escan_timeout, jiffies +
1146                         WL_ESCAN_TIMER_INTERVAL_MS * HZ / 1000);
1147
1148         return 0;
1149
1150 scan_out:
1151         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
1152         cfg->scan_request = NULL;
1153         return err;
1154 }
1155
1156 static s32
1157 brcmf_cfg80211_scan(struct wiphy *wiphy, struct cfg80211_scan_request *request)
1158 {
1159         struct brcmf_cfg80211_vif *vif;
1160         s32 err = 0;
1161
1162         brcmf_dbg(TRACE, "Enter\n");
1163         vif = container_of(request->wdev, struct brcmf_cfg80211_vif, wdev);
1164         if (!check_vif_up(vif))
1165                 return -EIO;
1166
1167         err = brcmf_cfg80211_escan(wiphy, vif, request, NULL);
1168
1169         if (err)
1170                 brcmf_err("scan error (%d)\n", err);
1171
1172         brcmf_dbg(TRACE, "Exit\n");
1173         return err;
1174 }
1175
1176 static s32 brcmf_set_rts(struct net_device *ndev, u32 rts_threshold)
1177 {
1178         s32 err = 0;
1179
1180         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "rtsthresh",
1181                                       rts_threshold);
1182         if (err)
1183                 brcmf_err("Error (%d)\n", err);
1184
1185         return err;
1186 }
1187
1188 static s32 brcmf_set_frag(struct net_device *ndev, u32 frag_threshold)
1189 {
1190         s32 err = 0;
1191
1192         err = brcmf_fil_iovar_int_set(netdev_priv(ndev), "fragthresh",
1193                                       frag_threshold);
1194         if (err)
1195                 brcmf_err("Error (%d)\n", err);
1196
1197         return err;
1198 }
1199
1200 static s32 brcmf_set_retry(struct net_device *ndev, u32 retry, bool l)
1201 {
1202         s32 err = 0;
1203         u32 cmd = (l ? BRCMF_C_SET_LRL : BRCMF_C_SET_SRL);
1204
1205         err = brcmf_fil_cmd_int_set(netdev_priv(ndev), cmd, retry);
1206         if (err) {
1207                 brcmf_err("cmd (%d) , error (%d)\n", cmd, err);
1208                 return err;
1209         }
1210         return err;
1211 }
1212
1213 static s32 brcmf_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1214 {
1215         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1216         struct net_device *ndev = cfg_to_ndev(cfg);
1217         struct brcmf_if *ifp = netdev_priv(ndev);
1218         s32 err = 0;
1219
1220         brcmf_dbg(TRACE, "Enter\n");
1221         if (!check_vif_up(ifp->vif))
1222                 return -EIO;
1223
1224         if (changed & WIPHY_PARAM_RTS_THRESHOLD &&
1225             (cfg->conf->rts_threshold != wiphy->rts_threshold)) {
1226                 cfg->conf->rts_threshold = wiphy->rts_threshold;
1227                 err = brcmf_set_rts(ndev, cfg->conf->rts_threshold);
1228                 if (!err)
1229                         goto done;
1230         }
1231         if (changed & WIPHY_PARAM_FRAG_THRESHOLD &&
1232             (cfg->conf->frag_threshold != wiphy->frag_threshold)) {
1233                 cfg->conf->frag_threshold = wiphy->frag_threshold;
1234                 err = brcmf_set_frag(ndev, cfg->conf->frag_threshold);
1235                 if (!err)
1236                         goto done;
1237         }
1238         if (changed & WIPHY_PARAM_RETRY_LONG
1239             && (cfg->conf->retry_long != wiphy->retry_long)) {
1240                 cfg->conf->retry_long = wiphy->retry_long;
1241                 err = brcmf_set_retry(ndev, cfg->conf->retry_long, true);
1242                 if (!err)
1243                         goto done;
1244         }
1245         if (changed & WIPHY_PARAM_RETRY_SHORT
1246             && (cfg->conf->retry_short != wiphy->retry_short)) {
1247                 cfg->conf->retry_short = wiphy->retry_short;
1248                 err = brcmf_set_retry(ndev, cfg->conf->retry_short, false);
1249                 if (!err)
1250                         goto done;
1251         }
1252
1253 done:
1254         brcmf_dbg(TRACE, "Exit\n");
1255         return err;
1256 }
1257
1258 static void brcmf_init_prof(struct brcmf_cfg80211_profile *prof)
1259 {
1260         memset(prof, 0, sizeof(*prof));
1261 }
1262
1263 static u16 brcmf_map_fw_linkdown_reason(const struct brcmf_event_msg *e)
1264 {
1265         u16 reason;
1266
1267         switch (e->event_code) {
1268         case BRCMF_E_DEAUTH:
1269         case BRCMF_E_DEAUTH_IND:
1270         case BRCMF_E_DISASSOC_IND:
1271                 reason = e->reason;
1272                 break;
1273         case BRCMF_E_LINK:
1274         default:
1275                 reason = 0;
1276                 break;
1277         }
1278         return reason;
1279 }
1280
1281 static void brcmf_link_down(struct brcmf_cfg80211_vif *vif, u16 reason)
1282 {
1283         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(vif->wdev.wiphy);
1284         s32 err = 0;
1285
1286         brcmf_dbg(TRACE, "Enter\n");
1287
1288         if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state)) {
1289                 brcmf_dbg(INFO, "Call WLC_DISASSOC to stop excess roaming\n ");
1290                 err = brcmf_fil_cmd_data_set(vif->ifp,
1291                                              BRCMF_C_DISASSOC, NULL, 0);
1292                 if (err) {
1293                         brcmf_err("WLC_DISASSOC failed (%d)\n", err);
1294                 }
1295                 clear_bit(BRCMF_VIF_STATUS_CONNECTED, &vif->sme_state);
1296                 cfg80211_disconnected(vif->wdev.netdev, reason, NULL, 0,
1297                                       true, GFP_KERNEL);
1298
1299         }
1300         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &vif->sme_state);
1301         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
1302         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
1303         brcmf_dbg(TRACE, "Exit\n");
1304 }
1305
1306 static s32
1307 brcmf_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *ndev,
1308                       struct cfg80211_ibss_params *params)
1309 {
1310         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1311         struct brcmf_if *ifp = netdev_priv(ndev);
1312         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1313         struct brcmf_join_params join_params;
1314         size_t join_params_size = 0;
1315         s32 err = 0;
1316         s32 wsec = 0;
1317         s32 bcnprd;
1318         u16 chanspec;
1319
1320         brcmf_dbg(TRACE, "Enter\n");
1321         if (!check_vif_up(ifp->vif))
1322                 return -EIO;
1323
1324         if (params->ssid)
1325                 brcmf_dbg(CONN, "SSID: %s\n", params->ssid);
1326         else {
1327                 brcmf_dbg(CONN, "SSID: NULL, Not supported\n");
1328                 return -EOPNOTSUPP;
1329         }
1330
1331         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1332
1333         if (params->bssid)
1334                 brcmf_dbg(CONN, "BSSID: %pM\n", params->bssid);
1335         else
1336                 brcmf_dbg(CONN, "No BSSID specified\n");
1337
1338         if (params->chandef.chan)
1339                 brcmf_dbg(CONN, "channel: %d\n",
1340                           params->chandef.chan->center_freq);
1341         else
1342                 brcmf_dbg(CONN, "no channel specified\n");
1343
1344         if (params->channel_fixed)
1345                 brcmf_dbg(CONN, "fixed channel required\n");
1346         else
1347                 brcmf_dbg(CONN, "no fixed channel required\n");
1348
1349         if (params->ie && params->ie_len)
1350                 brcmf_dbg(CONN, "ie len: %d\n", params->ie_len);
1351         else
1352                 brcmf_dbg(CONN, "no ie specified\n");
1353
1354         if (params->beacon_interval)
1355                 brcmf_dbg(CONN, "beacon interval: %d\n",
1356                           params->beacon_interval);
1357         else
1358                 brcmf_dbg(CONN, "no beacon interval specified\n");
1359
1360         if (params->basic_rates)
1361                 brcmf_dbg(CONN, "basic rates: %08X\n", params->basic_rates);
1362         else
1363                 brcmf_dbg(CONN, "no basic rates specified\n");
1364
1365         if (params->privacy)
1366                 brcmf_dbg(CONN, "privacy required\n");
1367         else
1368                 brcmf_dbg(CONN, "no privacy required\n");
1369
1370         /* Configure Privacy for starter */
1371         if (params->privacy)
1372                 wsec |= WEP_ENABLED;
1373
1374         err = brcmf_fil_iovar_int_set(ifp, "wsec", wsec);
1375         if (err) {
1376                 brcmf_err("wsec failed (%d)\n", err);
1377                 goto done;
1378         }
1379
1380         /* Configure Beacon Interval for starter */
1381         if (params->beacon_interval)
1382                 bcnprd = params->beacon_interval;
1383         else
1384                 bcnprd = 100;
1385
1386         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD, bcnprd);
1387         if (err) {
1388                 brcmf_err("WLC_SET_BCNPRD failed (%d)\n", err);
1389                 goto done;
1390         }
1391
1392         /* Configure required join parameter */
1393         memset(&join_params, 0, sizeof(struct brcmf_join_params));
1394
1395         /* SSID */
1396         profile->ssid.SSID_len = min_t(u32, params->ssid_len, 32);
1397         memcpy(profile->ssid.SSID, params->ssid, profile->ssid.SSID_len);
1398         memcpy(join_params.ssid_le.SSID, params->ssid, profile->ssid.SSID_len);
1399         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1400         join_params_size = sizeof(join_params.ssid_le);
1401
1402         /* BSSID */
1403         if (params->bssid) {
1404                 memcpy(join_params.params_le.bssid, params->bssid, ETH_ALEN);
1405                 join_params_size = sizeof(join_params.ssid_le) +
1406                                    BRCMF_ASSOC_PARAMS_FIXED_SIZE;
1407                 memcpy(profile->bssid, params->bssid, ETH_ALEN);
1408         } else {
1409                 eth_broadcast_addr(join_params.params_le.bssid);
1410                 eth_zero_addr(profile->bssid);
1411         }
1412
1413         /* Channel */
1414         if (params->chandef.chan) {
1415                 u32 target_channel;
1416
1417                 cfg->channel =
1418                         ieee80211_frequency_to_channel(
1419                                 params->chandef.chan->center_freq);
1420                 if (params->channel_fixed) {
1421                         /* adding chanspec */
1422                         chanspec = chandef_to_chanspec(&cfg->d11inf,
1423                                                        &params->chandef);
1424                         join_params.params_le.chanspec_list[0] =
1425                                 cpu_to_le16(chanspec);
1426                         join_params.params_le.chanspec_num = cpu_to_le32(1);
1427                         join_params_size += sizeof(join_params.params_le);
1428                 }
1429
1430                 /* set channel for starter */
1431                 target_channel = cfg->channel;
1432                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_CHANNEL,
1433                                             target_channel);
1434                 if (err) {
1435                         brcmf_err("WLC_SET_CHANNEL failed (%d)\n", err);
1436                         goto done;
1437                 }
1438         } else
1439                 cfg->channel = 0;
1440
1441         cfg->ibss_starter = false;
1442
1443
1444         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1445                                      &join_params, join_params_size);
1446         if (err) {
1447                 brcmf_err("WLC_SET_SSID failed (%d)\n", err);
1448                 goto done;
1449         }
1450
1451 done:
1452         if (err)
1453                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1454         brcmf_dbg(TRACE, "Exit\n");
1455         return err;
1456 }
1457
1458 static s32
1459 brcmf_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *ndev)
1460 {
1461         struct brcmf_if *ifp = netdev_priv(ndev);
1462
1463         brcmf_dbg(TRACE, "Enter\n");
1464         if (!check_vif_up(ifp->vif))
1465                 return -EIO;
1466
1467         brcmf_link_down(ifp->vif, WLAN_REASON_DEAUTH_LEAVING);
1468
1469         brcmf_dbg(TRACE, "Exit\n");
1470
1471         return 0;
1472 }
1473
1474 static s32 brcmf_set_wpa_version(struct net_device *ndev,
1475                                  struct cfg80211_connect_params *sme)
1476 {
1477         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1478         struct brcmf_cfg80211_security *sec;
1479         s32 val = 0;
1480         s32 err = 0;
1481
1482         if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1483                 val = WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED;
1484         else if (sme->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1485                 val = WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED;
1486         else
1487                 val = WPA_AUTH_DISABLED;
1488         brcmf_dbg(CONN, "setting wpa_auth to 0x%0x\n", val);
1489         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wpa_auth", val);
1490         if (err) {
1491                 brcmf_err("set wpa_auth failed (%d)\n", err);
1492                 return err;
1493         }
1494         sec = &profile->sec;
1495         sec->wpa_versions = sme->crypto.wpa_versions;
1496         return err;
1497 }
1498
1499 static s32 brcmf_set_auth_type(struct net_device *ndev,
1500                                struct cfg80211_connect_params *sme)
1501 {
1502         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1503         struct brcmf_cfg80211_security *sec;
1504         s32 val = 0;
1505         s32 err = 0;
1506
1507         switch (sme->auth_type) {
1508         case NL80211_AUTHTYPE_OPEN_SYSTEM:
1509                 val = 0;
1510                 brcmf_dbg(CONN, "open system\n");
1511                 break;
1512         case NL80211_AUTHTYPE_SHARED_KEY:
1513                 val = 1;
1514                 brcmf_dbg(CONN, "shared key\n");
1515                 break;
1516         case NL80211_AUTHTYPE_AUTOMATIC:
1517                 val = 2;
1518                 brcmf_dbg(CONN, "automatic\n");
1519                 break;
1520         case NL80211_AUTHTYPE_NETWORK_EAP:
1521                 brcmf_dbg(CONN, "network eap\n");
1522         default:
1523                 val = 2;
1524                 brcmf_err("invalid auth type (%d)\n", sme->auth_type);
1525                 break;
1526         }
1527
1528         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1529         if (err) {
1530                 brcmf_err("set auth failed (%d)\n", err);
1531                 return err;
1532         }
1533         sec = &profile->sec;
1534         sec->auth_type = sme->auth_type;
1535         return err;
1536 }
1537
1538 static s32
1539 brcmf_set_wsec_mode(struct net_device *ndev,
1540                      struct cfg80211_connect_params *sme, bool mfp)
1541 {
1542         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1543         struct brcmf_cfg80211_security *sec;
1544         s32 pval = 0;
1545         s32 gval = 0;
1546         s32 wsec;
1547         s32 err = 0;
1548
1549         if (sme->crypto.n_ciphers_pairwise) {
1550                 switch (sme->crypto.ciphers_pairwise[0]) {
1551                 case WLAN_CIPHER_SUITE_WEP40:
1552                 case WLAN_CIPHER_SUITE_WEP104:
1553                         pval = WEP_ENABLED;
1554                         break;
1555                 case WLAN_CIPHER_SUITE_TKIP:
1556                         pval = TKIP_ENABLED;
1557                         break;
1558                 case WLAN_CIPHER_SUITE_CCMP:
1559                         pval = AES_ENABLED;
1560                         break;
1561                 case WLAN_CIPHER_SUITE_AES_CMAC:
1562                         pval = AES_ENABLED;
1563                         break;
1564                 default:
1565                         brcmf_err("invalid cipher pairwise (%d)\n",
1566                                   sme->crypto.ciphers_pairwise[0]);
1567                         return -EINVAL;
1568                 }
1569         }
1570         if (sme->crypto.cipher_group) {
1571                 switch (sme->crypto.cipher_group) {
1572                 case WLAN_CIPHER_SUITE_WEP40:
1573                 case WLAN_CIPHER_SUITE_WEP104:
1574                         gval = WEP_ENABLED;
1575                         break;
1576                 case WLAN_CIPHER_SUITE_TKIP:
1577                         gval = TKIP_ENABLED;
1578                         break;
1579                 case WLAN_CIPHER_SUITE_CCMP:
1580                         gval = AES_ENABLED;
1581                         break;
1582                 case WLAN_CIPHER_SUITE_AES_CMAC:
1583                         gval = AES_ENABLED;
1584                         break;
1585                 default:
1586                         brcmf_err("invalid cipher group (%d)\n",
1587                                   sme->crypto.cipher_group);
1588                         return -EINVAL;
1589                 }
1590         }
1591
1592         brcmf_dbg(CONN, "pval (%d) gval (%d)\n", pval, gval);
1593         /* In case of privacy, but no security and WPS then simulate */
1594         /* setting AES. WPS-2.0 allows no security                   */
1595         if (brcmf_find_wpsie(sme->ie, sme->ie_len) && !pval && !gval &&
1596             sme->privacy)
1597                 pval = AES_ENABLED;
1598
1599         if (mfp)
1600                 wsec = pval | gval | MFP_CAPABLE;
1601         else
1602                 wsec = pval | gval;
1603         err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "wsec", wsec);
1604         if (err) {
1605                 brcmf_err("error (%d)\n", err);
1606                 return err;
1607         }
1608
1609         sec = &profile->sec;
1610         sec->cipher_pairwise = sme->crypto.ciphers_pairwise[0];
1611         sec->cipher_group = sme->crypto.cipher_group;
1612
1613         return err;
1614 }
1615
1616 static s32
1617 brcmf_set_key_mgmt(struct net_device *ndev, struct cfg80211_connect_params *sme)
1618 {
1619         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1620         struct brcmf_cfg80211_security *sec;
1621         s32 val = 0;
1622         s32 err = 0;
1623
1624         if (sme->crypto.n_akm_suites) {
1625                 err = brcmf_fil_bsscfg_int_get(netdev_priv(ndev),
1626                                                "wpa_auth", &val);
1627                 if (err) {
1628                         brcmf_err("could not get wpa_auth (%d)\n", err);
1629                         return err;
1630                 }
1631                 if (val & (WPA_AUTH_PSK | WPA_AUTH_UNSPECIFIED)) {
1632                         switch (sme->crypto.akm_suites[0]) {
1633                         case WLAN_AKM_SUITE_8021X:
1634                                 val = WPA_AUTH_UNSPECIFIED;
1635                                 break;
1636                         case WLAN_AKM_SUITE_PSK:
1637                                 val = WPA_AUTH_PSK;
1638                                 break;
1639                         default:
1640                                 brcmf_err("invalid cipher group (%d)\n",
1641                                           sme->crypto.cipher_group);
1642                                 return -EINVAL;
1643                         }
1644                 } else if (val & (WPA2_AUTH_PSK | WPA2_AUTH_UNSPECIFIED)) {
1645                         switch (sme->crypto.akm_suites[0]) {
1646                         case WLAN_AKM_SUITE_8021X:
1647                                 val = WPA2_AUTH_UNSPECIFIED;
1648                                 break;
1649                         case WLAN_AKM_SUITE_PSK:
1650                                 val = WPA2_AUTH_PSK;
1651                                 break;
1652                         default:
1653                                 brcmf_err("invalid cipher group (%d)\n",
1654                                           sme->crypto.cipher_group);
1655                                 return -EINVAL;
1656                         }
1657                 }
1658
1659                 brcmf_dbg(CONN, "setting wpa_auth to %d\n", val);
1660                 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev),
1661                                                "wpa_auth", val);
1662                 if (err) {
1663                         brcmf_err("could not set wpa_auth (%d)\n", err);
1664                         return err;
1665                 }
1666         }
1667         sec = &profile->sec;
1668         sec->wpa_auth = sme->crypto.akm_suites[0];
1669
1670         return err;
1671 }
1672
1673 static s32
1674 brcmf_set_sharedkey(struct net_device *ndev,
1675                     struct cfg80211_connect_params *sme)
1676 {
1677         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ndev);
1678         struct brcmf_cfg80211_security *sec;
1679         struct brcmf_wsec_key key;
1680         s32 val;
1681         s32 err = 0;
1682
1683         brcmf_dbg(CONN, "key len (%d)\n", sme->key_len);
1684
1685         if (sme->key_len == 0)
1686                 return 0;
1687
1688         sec = &profile->sec;
1689         brcmf_dbg(CONN, "wpa_versions 0x%x cipher_pairwise 0x%x\n",
1690                   sec->wpa_versions, sec->cipher_pairwise);
1691
1692         if (sec->wpa_versions & (NL80211_WPA_VERSION_1 | NL80211_WPA_VERSION_2))
1693                 return 0;
1694
1695         if (!(sec->cipher_pairwise &
1696             (WLAN_CIPHER_SUITE_WEP40 | WLAN_CIPHER_SUITE_WEP104)))
1697                 return 0;
1698
1699         memset(&key, 0, sizeof(key));
1700         key.len = (u32) sme->key_len;
1701         key.index = (u32) sme->key_idx;
1702         if (key.len > sizeof(key.data)) {
1703                 brcmf_err("Too long key length (%u)\n", key.len);
1704                 return -EINVAL;
1705         }
1706         memcpy(key.data, sme->key, key.len);
1707         key.flags = BRCMF_PRIMARY_KEY;
1708         switch (sec->cipher_pairwise) {
1709         case WLAN_CIPHER_SUITE_WEP40:
1710                 key.algo = CRYPTO_ALGO_WEP1;
1711                 break;
1712         case WLAN_CIPHER_SUITE_WEP104:
1713                 key.algo = CRYPTO_ALGO_WEP128;
1714                 break;
1715         default:
1716                 brcmf_err("Invalid algorithm (%d)\n",
1717                           sme->crypto.ciphers_pairwise[0]);
1718                 return -EINVAL;
1719         }
1720         /* Set the new key/index */
1721         brcmf_dbg(CONN, "key length (%d) key index (%d) algo (%d)\n",
1722                   key.len, key.index, key.algo);
1723         brcmf_dbg(CONN, "key \"%s\"\n", key.data);
1724         err = send_key_to_dongle(netdev_priv(ndev), &key);
1725         if (err)
1726                 return err;
1727
1728         if (sec->auth_type == NL80211_AUTHTYPE_SHARED_KEY) {
1729                 brcmf_dbg(CONN, "set auth_type to shared key\n");
1730                 val = WL_AUTH_SHARED_KEY;       /* shared key */
1731                 err = brcmf_fil_bsscfg_int_set(netdev_priv(ndev), "auth", val);
1732                 if (err)
1733                         brcmf_err("set auth failed (%d)\n", err);
1734         }
1735         return err;
1736 }
1737
1738 static
1739 enum nl80211_auth_type brcmf_war_auth_type(struct brcmf_if *ifp,
1740                                            enum nl80211_auth_type type)
1741 {
1742         if (type == NL80211_AUTHTYPE_AUTOMATIC &&
1743             brcmf_feat_is_quirk_enabled(ifp, BRCMF_FEAT_QUIRK_AUTO_AUTH)) {
1744                 brcmf_dbg(CONN, "WAR: use OPEN instead of AUTO\n");
1745                 type = NL80211_AUTHTYPE_OPEN_SYSTEM;
1746         }
1747         return type;
1748 }
1749
1750 static s32
1751 brcmf_cfg80211_connect(struct wiphy *wiphy, struct net_device *ndev,
1752                        struct cfg80211_connect_params *sme)
1753 {
1754         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1755         struct brcmf_if *ifp = netdev_priv(ndev);
1756         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1757         struct ieee80211_channel *chan = sme->channel;
1758         struct brcmf_join_params join_params;
1759         size_t join_params_size;
1760         const struct brcmf_tlv *rsn_ie;
1761         const struct brcmf_vs_tlv *wpa_ie;
1762         const void *ie;
1763         u32 ie_len;
1764         struct brcmf_ext_join_params_le *ext_join_params;
1765         u16 chanspec;
1766         s32 err = 0;
1767
1768         brcmf_dbg(TRACE, "Enter\n");
1769         if (!check_vif_up(ifp->vif))
1770                 return -EIO;
1771
1772         if (!sme->ssid) {
1773                 brcmf_err("Invalid ssid\n");
1774                 return -EOPNOTSUPP;
1775         }
1776
1777         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif) {
1778                 /* A normal (non P2P) connection request setup. */
1779                 ie = NULL;
1780                 ie_len = 0;
1781                 /* find the WPA_IE */
1782                 wpa_ie = brcmf_find_wpaie((u8 *)sme->ie, sme->ie_len);
1783                 if (wpa_ie) {
1784                         ie = wpa_ie;
1785                         ie_len = wpa_ie->len + TLV_HDR_LEN;
1786                 } else {
1787                         /* find the RSN_IE */
1788                         rsn_ie = brcmf_parse_tlvs((const u8 *)sme->ie,
1789                                                   sme->ie_len,
1790                                                   WLAN_EID_RSN);
1791                         if (rsn_ie) {
1792                                 ie = rsn_ie;
1793                                 ie_len = rsn_ie->len + TLV_HDR_LEN;
1794                         }
1795                 }
1796                 brcmf_fil_iovar_data_set(ifp, "wpaie", ie, ie_len);
1797         }
1798
1799         err = brcmf_vif_set_mgmt_ie(ifp->vif, BRCMF_VNDR_IE_ASSOCREQ_FLAG,
1800                                     sme->ie, sme->ie_len);
1801         if (err)
1802                 brcmf_err("Set Assoc REQ IE Failed\n");
1803         else
1804                 brcmf_dbg(TRACE, "Applied Vndr IEs for Assoc request\n");
1805
1806         set_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1807
1808         if (chan) {
1809                 cfg->channel =
1810                         ieee80211_frequency_to_channel(chan->center_freq);
1811                 chanspec = channel_to_chanspec(&cfg->d11inf, chan);
1812                 brcmf_dbg(CONN, "channel=%d, center_req=%d, chanspec=0x%04x\n",
1813                           cfg->channel, chan->center_freq, chanspec);
1814         } else {
1815                 cfg->channel = 0;
1816                 chanspec = 0;
1817         }
1818
1819         brcmf_dbg(INFO, "ie (%p), ie_len (%zd)\n", sme->ie, sme->ie_len);
1820
1821         err = brcmf_set_wpa_version(ndev, sme);
1822         if (err) {
1823                 brcmf_err("wl_set_wpa_version failed (%d)\n", err);
1824                 goto done;
1825         }
1826
1827         sme->auth_type = brcmf_war_auth_type(ifp, sme->auth_type);
1828         err = brcmf_set_auth_type(ndev, sme);
1829         if (err) {
1830                 brcmf_err("wl_set_auth_type failed (%d)\n", err);
1831                 goto done;
1832         }
1833
1834         err = brcmf_set_wsec_mode(ndev, sme, sme->mfp == NL80211_MFP_REQUIRED);
1835         if (err) {
1836                 brcmf_err("wl_set_set_cipher failed (%d)\n", err);
1837                 goto done;
1838         }
1839
1840         err = brcmf_set_key_mgmt(ndev, sme);
1841         if (err) {
1842                 brcmf_err("wl_set_key_mgmt failed (%d)\n", err);
1843                 goto done;
1844         }
1845
1846         err = brcmf_set_sharedkey(ndev, sme);
1847         if (err) {
1848                 brcmf_err("brcmf_set_sharedkey failed (%d)\n", err);
1849                 goto done;
1850         }
1851
1852         profile->ssid.SSID_len = min_t(u32, (u32)sizeof(profile->ssid.SSID),
1853                                        (u32)sme->ssid_len);
1854         memcpy(&profile->ssid.SSID, sme->ssid, profile->ssid.SSID_len);
1855         if (profile->ssid.SSID_len < IEEE80211_MAX_SSID_LEN) {
1856                 profile->ssid.SSID[profile->ssid.SSID_len] = 0;
1857                 brcmf_dbg(CONN, "SSID \"%s\", len (%d)\n", profile->ssid.SSID,
1858                           profile->ssid.SSID_len);
1859         }
1860
1861         /* Join with specific BSSID and cached SSID
1862          * If SSID is zero join based on BSSID only
1863          */
1864         join_params_size = offsetof(struct brcmf_ext_join_params_le, assoc_le) +
1865                 offsetof(struct brcmf_assoc_params_le, chanspec_list);
1866         if (cfg->channel)
1867                 join_params_size += sizeof(u16);
1868         ext_join_params = kzalloc(join_params_size, GFP_KERNEL);
1869         if (ext_join_params == NULL) {
1870                 err = -ENOMEM;
1871                 goto done;
1872         }
1873         ext_join_params->ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1874         memcpy(&ext_join_params->ssid_le.SSID, sme->ssid,
1875                profile->ssid.SSID_len);
1876
1877         /* Set up join scan parameters */
1878         ext_join_params->scan_le.scan_type = -1;
1879         ext_join_params->scan_le.home_time = cpu_to_le32(-1);
1880
1881         if (sme->bssid)
1882                 memcpy(&ext_join_params->assoc_le.bssid, sme->bssid, ETH_ALEN);
1883         else
1884                 eth_broadcast_addr(ext_join_params->assoc_le.bssid);
1885
1886         if (cfg->channel) {
1887                 ext_join_params->assoc_le.chanspec_num = cpu_to_le32(1);
1888
1889                 ext_join_params->assoc_le.chanspec_list[0] =
1890                         cpu_to_le16(chanspec);
1891                 /* Increase dwell time to receive probe response or detect
1892                  * beacon from target AP at a noisy air only during connect
1893                  * command.
1894                  */
1895                 ext_join_params->scan_le.active_time =
1896                         cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS);
1897                 ext_join_params->scan_le.passive_time =
1898                         cpu_to_le32(BRCMF_SCAN_JOIN_PASSIVE_DWELL_TIME_MS);
1899                 /* To sync with presence period of VSDB GO send probe request
1900                  * more frequently. Probe request will be stopped when it gets
1901                  * probe response from target AP/GO.
1902                  */
1903                 ext_join_params->scan_le.nprobes =
1904                         cpu_to_le32(BRCMF_SCAN_JOIN_ACTIVE_DWELL_TIME_MS /
1905                                     BRCMF_SCAN_JOIN_PROBE_INTERVAL_MS);
1906         } else {
1907                 ext_join_params->scan_le.active_time = cpu_to_le32(-1);
1908                 ext_join_params->scan_le.passive_time = cpu_to_le32(-1);
1909                 ext_join_params->scan_le.nprobes = cpu_to_le32(-1);
1910         }
1911
1912         err  = brcmf_fil_bsscfg_data_set(ifp, "join", ext_join_params,
1913                                          join_params_size);
1914         kfree(ext_join_params);
1915         if (!err)
1916                 /* This is it. join command worked, we are done */
1917                 goto done;
1918
1919         /* join command failed, fallback to set ssid */
1920         memset(&join_params, 0, sizeof(join_params));
1921         join_params_size = sizeof(join_params.ssid_le);
1922
1923         memcpy(&join_params.ssid_le.SSID, sme->ssid, profile->ssid.SSID_len);
1924         join_params.ssid_le.SSID_len = cpu_to_le32(profile->ssid.SSID_len);
1925
1926         if (sme->bssid)
1927                 memcpy(join_params.params_le.bssid, sme->bssid, ETH_ALEN);
1928         else
1929                 eth_broadcast_addr(join_params.params_le.bssid);
1930
1931         if (cfg->channel) {
1932                 join_params.params_le.chanspec_list[0] = cpu_to_le16(chanspec);
1933                 join_params.params_le.chanspec_num = cpu_to_le32(1);
1934                 join_params_size += sizeof(join_params.params_le);
1935         }
1936         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
1937                                      &join_params, join_params_size);
1938         if (err)
1939                 brcmf_err("BRCMF_C_SET_SSID failed (%d)\n", err);
1940
1941 done:
1942         if (err)
1943                 clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1944         brcmf_dbg(TRACE, "Exit\n");
1945         return err;
1946 }
1947
1948 static s32
1949 brcmf_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *ndev,
1950                        u16 reason_code)
1951 {
1952         struct brcmf_if *ifp = netdev_priv(ndev);
1953         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
1954         struct brcmf_scb_val_le scbval;
1955         s32 err = 0;
1956
1957         brcmf_dbg(TRACE, "Enter. Reason code = %d\n", reason_code);
1958         if (!check_vif_up(ifp->vif))
1959                 return -EIO;
1960
1961         clear_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
1962         clear_bit(BRCMF_VIF_STATUS_CONNECTING, &ifp->vif->sme_state);
1963         cfg80211_disconnected(ndev, reason_code, NULL, 0, true, GFP_KERNEL);
1964
1965         memcpy(&scbval.ea, &profile->bssid, ETH_ALEN);
1966         scbval.val = cpu_to_le32(reason_code);
1967         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_DISASSOC,
1968                                      &scbval, sizeof(scbval));
1969         if (err)
1970                 brcmf_err("error (%d)\n", err);
1971
1972         brcmf_dbg(TRACE, "Exit\n");
1973         return err;
1974 }
1975
1976 static s32
1977 brcmf_cfg80211_set_tx_power(struct wiphy *wiphy, struct wireless_dev *wdev,
1978                             enum nl80211_tx_power_setting type, s32 mbm)
1979 {
1980
1981         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
1982         struct net_device *ndev = cfg_to_ndev(cfg);
1983         struct brcmf_if *ifp = netdev_priv(ndev);
1984         u16 txpwrmw;
1985         s32 err = 0;
1986         s32 disable = 0;
1987         s32 dbm = MBM_TO_DBM(mbm);
1988
1989         brcmf_dbg(TRACE, "Enter\n");
1990         if (!check_vif_up(ifp->vif))
1991                 return -EIO;
1992
1993         switch (type) {
1994         case NL80211_TX_POWER_AUTOMATIC:
1995                 break;
1996         case NL80211_TX_POWER_LIMITED:
1997         case NL80211_TX_POWER_FIXED:
1998                 if (dbm < 0) {
1999                         brcmf_err("TX_POWER_FIXED - dbm is negative\n");
2000                         err = -EINVAL;
2001                         goto done;
2002                 }
2003                 break;
2004         }
2005         /* Make sure radio is off or on as far as software is concerned */
2006         disable = WL_RADIO_SW_DISABLE << 16;
2007         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_RADIO, disable);
2008         if (err)
2009                 brcmf_err("WLC_SET_RADIO error (%d)\n", err);
2010
2011         if (dbm > 0xffff)
2012                 txpwrmw = 0xffff;
2013         else
2014                 txpwrmw = (u16) dbm;
2015         err = brcmf_fil_iovar_int_set(ifp, "qtxpower",
2016                                       (s32)brcmf_mw_to_qdbm(txpwrmw));
2017         if (err)
2018                 brcmf_err("qtxpower error (%d)\n", err);
2019         cfg->conf->tx_power = dbm;
2020
2021 done:
2022         brcmf_dbg(TRACE, "Exit\n");
2023         return err;
2024 }
2025
2026 static s32 brcmf_cfg80211_get_tx_power(struct wiphy *wiphy,
2027                                        struct wireless_dev *wdev,
2028                                        s32 *dbm)
2029 {
2030         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2031         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
2032         s32 txpwrdbm;
2033         u8 result;
2034         s32 err = 0;
2035
2036         brcmf_dbg(TRACE, "Enter\n");
2037         if (!check_vif_up(ifp->vif))
2038                 return -EIO;
2039
2040         err = brcmf_fil_iovar_int_get(ifp, "qtxpower", &txpwrdbm);
2041         if (err) {
2042                 brcmf_err("error (%d)\n", err);
2043                 goto done;
2044         }
2045
2046         result = (u8) (txpwrdbm & ~WL_TXPWR_OVERRIDE);
2047         *dbm = (s32) brcmf_qdbm_to_mw(result);
2048
2049 done:
2050         brcmf_dbg(TRACE, "Exit\n");
2051         return err;
2052 }
2053
2054 static s32
2055 brcmf_cfg80211_config_default_key(struct wiphy *wiphy, struct net_device *ndev,
2056                                u8 key_idx, bool unicast, bool multicast)
2057 {
2058         struct brcmf_if *ifp = netdev_priv(ndev);
2059         u32 index;
2060         u32 wsec;
2061         s32 err = 0;
2062
2063         brcmf_dbg(TRACE, "Enter\n");
2064         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2065         if (!check_vif_up(ifp->vif))
2066                 return -EIO;
2067
2068         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2069         if (err) {
2070                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2071                 goto done;
2072         }
2073
2074         if (wsec & WEP_ENABLED) {
2075                 /* Just select a new current key */
2076                 index = key_idx;
2077                 err = brcmf_fil_cmd_int_set(ifp,
2078                                             BRCMF_C_SET_KEY_PRIMARY, index);
2079                 if (err)
2080                         brcmf_err("error (%d)\n", err);
2081         }
2082 done:
2083         brcmf_dbg(TRACE, "Exit\n");
2084         return err;
2085 }
2086
2087 static s32
2088 brcmf_add_keyext(struct wiphy *wiphy, struct net_device *ndev,
2089               u8 key_idx, const u8 *mac_addr, struct key_params *params)
2090 {
2091         struct brcmf_if *ifp = netdev_priv(ndev);
2092         struct brcmf_wsec_key key;
2093         s32 err = 0;
2094         u8 keybuf[8];
2095
2096         memset(&key, 0, sizeof(key));
2097         key.index = (u32) key_idx;
2098         /* Instead of bcast for ea address for default wep keys,
2099                  driver needs it to be Null */
2100         if (!is_multicast_ether_addr(mac_addr))
2101                 memcpy((char *)&key.ea, (void *)mac_addr, ETH_ALEN);
2102         key.len = (u32) params->key_len;
2103         /* check for key index change */
2104         if (key.len == 0) {
2105                 /* key delete */
2106                 err = send_key_to_dongle(ifp, &key);
2107                 if (err)
2108                         brcmf_err("key delete error (%d)\n", err);
2109         } else {
2110                 if (key.len > sizeof(key.data)) {
2111                         brcmf_err("Invalid key length (%d)\n", key.len);
2112                         return -EINVAL;
2113                 }
2114
2115                 brcmf_dbg(CONN, "Setting the key index %d\n", key.index);
2116                 memcpy(key.data, params->key, key.len);
2117
2118                 if (!brcmf_is_apmode(ifp->vif) &&
2119                     (params->cipher == WLAN_CIPHER_SUITE_TKIP)) {
2120                         brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2121                         memcpy(keybuf, &key.data[24], sizeof(keybuf));
2122                         memcpy(&key.data[24], &key.data[16], sizeof(keybuf));
2123                         memcpy(&key.data[16], keybuf, sizeof(keybuf));
2124                 }
2125
2126                 /* if IW_ENCODE_EXT_RX_SEQ_VALID set */
2127                 if (params->seq && params->seq_len == 6) {
2128                         /* rx iv */
2129                         u8 *ivptr;
2130                         ivptr = (u8 *) params->seq;
2131                         key.rxiv.hi = (ivptr[5] << 24) | (ivptr[4] << 16) |
2132                             (ivptr[3] << 8) | ivptr[2];
2133                         key.rxiv.lo = (ivptr[1] << 8) | ivptr[0];
2134                         key.iv_initialized = true;
2135                 }
2136
2137                 switch (params->cipher) {
2138                 case WLAN_CIPHER_SUITE_WEP40:
2139                         key.algo = CRYPTO_ALGO_WEP1;
2140                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2141                         break;
2142                 case WLAN_CIPHER_SUITE_WEP104:
2143                         key.algo = CRYPTO_ALGO_WEP128;
2144                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2145                         break;
2146                 case WLAN_CIPHER_SUITE_TKIP:
2147                         key.algo = CRYPTO_ALGO_TKIP;
2148                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2149                         break;
2150                 case WLAN_CIPHER_SUITE_AES_CMAC:
2151                         key.algo = CRYPTO_ALGO_AES_CCM;
2152                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2153                         break;
2154                 case WLAN_CIPHER_SUITE_CCMP:
2155                         key.algo = CRYPTO_ALGO_AES_CCM;
2156                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2157                         break;
2158                 default:
2159                         brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2160                         return -EINVAL;
2161                 }
2162                 err = send_key_to_dongle(ifp, &key);
2163                 if (err)
2164                         brcmf_err("wsec_key error (%d)\n", err);
2165         }
2166         return err;
2167 }
2168
2169 static s32
2170 brcmf_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
2171                     u8 key_idx, bool pairwise, const u8 *mac_addr,
2172                     struct key_params *params)
2173 {
2174         struct brcmf_if *ifp = netdev_priv(ndev);
2175         struct brcmf_wsec_key *key;
2176         s32 val;
2177         s32 wsec;
2178         s32 err = 0;
2179         u8 keybuf[8];
2180
2181         brcmf_dbg(TRACE, "Enter\n");
2182         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2183         if (!check_vif_up(ifp->vif))
2184                 return -EIO;
2185
2186         if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2187                 /* we ignore this key index in this case */
2188                 brcmf_err("invalid key index (%d)\n", key_idx);
2189                 return -EINVAL;
2190         }
2191
2192         if (mac_addr &&
2193                 (params->cipher != WLAN_CIPHER_SUITE_WEP40) &&
2194                 (params->cipher != WLAN_CIPHER_SUITE_WEP104)) {
2195                 brcmf_dbg(TRACE, "Exit");
2196                 return brcmf_add_keyext(wiphy, ndev, key_idx, mac_addr, params);
2197         }
2198
2199         key = &ifp->vif->profile.key[key_idx];
2200         memset(key, 0, sizeof(*key));
2201
2202         if (params->key_len > sizeof(key->data)) {
2203                 brcmf_err("Too long key length (%u)\n", params->key_len);
2204                 err = -EINVAL;
2205                 goto done;
2206         }
2207         key->len = params->key_len;
2208         key->index = key_idx;
2209
2210         memcpy(key->data, params->key, key->len);
2211
2212         key->flags = BRCMF_PRIMARY_KEY;
2213         switch (params->cipher) {
2214         case WLAN_CIPHER_SUITE_WEP40:
2215                 key->algo = CRYPTO_ALGO_WEP1;
2216                 val = WEP_ENABLED;
2217                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2218                 break;
2219         case WLAN_CIPHER_SUITE_WEP104:
2220                 key->algo = CRYPTO_ALGO_WEP128;
2221                 val = WEP_ENABLED;
2222                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2223                 break;
2224         case WLAN_CIPHER_SUITE_TKIP:
2225                 if (!brcmf_is_apmode(ifp->vif)) {
2226                         brcmf_dbg(CONN, "Swapping RX/TX MIC key\n");
2227                         memcpy(keybuf, &key->data[24], sizeof(keybuf));
2228                         memcpy(&key->data[24], &key->data[16], sizeof(keybuf));
2229                         memcpy(&key->data[16], keybuf, sizeof(keybuf));
2230                 }
2231                 key->algo = CRYPTO_ALGO_TKIP;
2232                 val = TKIP_ENABLED;
2233                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2234                 break;
2235         case WLAN_CIPHER_SUITE_AES_CMAC:
2236                 key->algo = CRYPTO_ALGO_AES_CCM;
2237                 val = AES_ENABLED;
2238                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2239                 break;
2240         case WLAN_CIPHER_SUITE_CCMP:
2241                 key->algo = CRYPTO_ALGO_AES_CCM;
2242                 val = AES_ENABLED;
2243                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_CCMP\n");
2244                 break;
2245         default:
2246                 brcmf_err("Invalid cipher (0x%x)\n", params->cipher);
2247                 err = -EINVAL;
2248                 goto done;
2249         }
2250
2251         err = send_key_to_dongle(ifp, key);
2252         if (err)
2253                 goto done;
2254
2255         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2256         if (err) {
2257                 brcmf_err("get wsec error (%d)\n", err);
2258                 goto done;
2259         }
2260         wsec |= val;
2261         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2262         if (err) {
2263                 brcmf_err("set wsec error (%d)\n", err);
2264                 goto done;
2265         }
2266
2267 done:
2268         brcmf_dbg(TRACE, "Exit\n");
2269         return err;
2270 }
2271
2272 static s32
2273 brcmf_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
2274                     u8 key_idx, bool pairwise, const u8 *mac_addr)
2275 {
2276         struct brcmf_if *ifp = netdev_priv(ndev);
2277         struct brcmf_wsec_key key;
2278         s32 err = 0;
2279
2280         brcmf_dbg(TRACE, "Enter\n");
2281         if (!check_vif_up(ifp->vif))
2282                 return -EIO;
2283
2284         if (key_idx >= BRCMF_MAX_DEFAULT_KEYS) {
2285                 /* we ignore this key index in this case */
2286                 return -EINVAL;
2287         }
2288
2289         memset(&key, 0, sizeof(key));
2290
2291         key.index = (u32) key_idx;
2292         key.flags = BRCMF_PRIMARY_KEY;
2293         key.algo = CRYPTO_ALGO_OFF;
2294
2295         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2296
2297         /* Set the new key/index */
2298         err = send_key_to_dongle(ifp, &key);
2299
2300         brcmf_dbg(TRACE, "Exit\n");
2301         return err;
2302 }
2303
2304 static s32
2305 brcmf_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
2306                     u8 key_idx, bool pairwise, const u8 *mac_addr, void *cookie,
2307                     void (*callback) (void *cookie, struct key_params * params))
2308 {
2309         struct key_params params;
2310         struct brcmf_if *ifp = netdev_priv(ndev);
2311         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
2312         struct brcmf_cfg80211_security *sec;
2313         s32 wsec;
2314         s32 err = 0;
2315
2316         brcmf_dbg(TRACE, "Enter\n");
2317         brcmf_dbg(CONN, "key index (%d)\n", key_idx);
2318         if (!check_vif_up(ifp->vif))
2319                 return -EIO;
2320
2321         memset(&params, 0, sizeof(params));
2322
2323         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2324         if (err) {
2325                 brcmf_err("WLC_GET_WSEC error (%d)\n", err);
2326                 /* Ignore this error, may happen during DISASSOC */
2327                 err = -EAGAIN;
2328                 goto done;
2329         }
2330         if (wsec & WEP_ENABLED) {
2331                 sec = &profile->sec;
2332                 if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP40) {
2333                         params.cipher = WLAN_CIPHER_SUITE_WEP40;
2334                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP40\n");
2335                 } else if (sec->cipher_pairwise & WLAN_CIPHER_SUITE_WEP104) {
2336                         params.cipher = WLAN_CIPHER_SUITE_WEP104;
2337                         brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_WEP104\n");
2338                 }
2339         } else if (wsec & TKIP_ENABLED) {
2340                 params.cipher = WLAN_CIPHER_SUITE_TKIP;
2341                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_TKIP\n");
2342         } else if (wsec & AES_ENABLED) {
2343                 params.cipher = WLAN_CIPHER_SUITE_AES_CMAC;
2344                 brcmf_dbg(CONN, "WLAN_CIPHER_SUITE_AES_CMAC\n");
2345         } else  {
2346                 brcmf_err("Invalid algo (0x%x)\n", wsec);
2347                 err = -EINVAL;
2348                 goto done;
2349         }
2350         callback(cookie, &params);
2351
2352 done:
2353         brcmf_dbg(TRACE, "Exit\n");
2354         return err;
2355 }
2356
2357 static s32
2358 brcmf_cfg80211_config_default_mgmt_key(struct wiphy *wiphy,
2359                                     struct net_device *ndev, u8 key_idx)
2360 {
2361         brcmf_dbg(INFO, "Not supported\n");
2362
2363         return -EOPNOTSUPP;
2364 }
2365
2366 static void
2367 brcmf_cfg80211_reconfigure_wep(struct brcmf_if *ifp)
2368 {
2369         s32 err;
2370         u8 key_idx;
2371         struct brcmf_wsec_key *key;
2372         s32 wsec;
2373
2374         for (key_idx = 0; key_idx < BRCMF_MAX_DEFAULT_KEYS; key_idx++) {
2375                 key = &ifp->vif->profile.key[key_idx];
2376                 if ((key->algo == CRYPTO_ALGO_WEP1) ||
2377                     (key->algo == CRYPTO_ALGO_WEP128))
2378                         break;
2379         }
2380         if (key_idx == BRCMF_MAX_DEFAULT_KEYS)
2381                 return;
2382
2383         err = send_key_to_dongle(ifp, key);
2384         if (err) {
2385                 brcmf_err("Setting WEP key failed (%d)\n", err);
2386                 return;
2387         }
2388         err = brcmf_fil_bsscfg_int_get(ifp, "wsec", &wsec);
2389         if (err) {
2390                 brcmf_err("get wsec error (%d)\n", err);
2391                 return;
2392         }
2393         wsec |= WEP_ENABLED;
2394         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
2395         if (err)
2396                 brcmf_err("set wsec error (%d)\n", err);
2397 }
2398
2399 static void brcmf_convert_sta_flags(u32 fw_sta_flags, struct station_info *si)
2400 {
2401         struct nl80211_sta_flag_update *sfu;
2402
2403         brcmf_dbg(TRACE, "flags %08x\n", fw_sta_flags);
2404         si->filled |= BIT(NL80211_STA_INFO_STA_FLAGS);
2405         sfu = &si->sta_flags;
2406         sfu->mask = BIT(NL80211_STA_FLAG_WME) |
2407                     BIT(NL80211_STA_FLAG_AUTHENTICATED) |
2408                     BIT(NL80211_STA_FLAG_ASSOCIATED) |
2409                     BIT(NL80211_STA_FLAG_AUTHORIZED);
2410         if (fw_sta_flags & BRCMF_STA_WME)
2411                 sfu->set |= BIT(NL80211_STA_FLAG_WME);
2412         if (fw_sta_flags & BRCMF_STA_AUTHE)
2413                 sfu->set |= BIT(NL80211_STA_FLAG_AUTHENTICATED);
2414         if (fw_sta_flags & BRCMF_STA_ASSOC)
2415                 sfu->set |= BIT(NL80211_STA_FLAG_ASSOCIATED);
2416         if (fw_sta_flags & BRCMF_STA_AUTHO)
2417                 sfu->set |= BIT(NL80211_STA_FLAG_AUTHORIZED);
2418 }
2419
2420 static void brcmf_fill_bss_param(struct brcmf_if *ifp, struct station_info *si)
2421 {
2422         struct {
2423                 __le32 len;
2424                 struct brcmf_bss_info_le bss_le;
2425         } *buf;
2426         u16 capability;
2427         int err;
2428
2429         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2430         if (!buf)
2431                 return;
2432
2433         buf->len = cpu_to_le32(WL_BSS_INFO_MAX);
2434         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO, buf,
2435                                      WL_BSS_INFO_MAX);
2436         if (err) {
2437                 brcmf_err("Failed to get bss info (%d)\n", err);
2438                 return;
2439         }
2440         si->filled |= BIT(NL80211_STA_INFO_BSS_PARAM);
2441         si->bss_param.beacon_interval = le16_to_cpu(buf->bss_le.beacon_period);
2442         si->bss_param.dtim_period = buf->bss_le.dtim_period;
2443         capability = le16_to_cpu(buf->bss_le.capability);
2444         if (capability & IEEE80211_HT_STBC_PARAM_DUAL_CTS_PROT)
2445                 si->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
2446         if (capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
2447                 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
2448         if (capability & WLAN_CAPABILITY_SHORT_SLOT_TIME)
2449                 si->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
2450 }
2451
2452 static s32
2453 brcmf_cfg80211_get_station(struct wiphy *wiphy, struct net_device *ndev,
2454                            const u8 *mac, struct station_info *sinfo)
2455 {
2456         struct brcmf_if *ifp = netdev_priv(ndev);
2457         s32 err = 0;
2458         struct brcmf_sta_info_le sta_info_le;
2459         u32 sta_flags;
2460         u32 is_tdls_peer;
2461
2462         brcmf_dbg(TRACE, "Enter, MAC %pM\n", mac);
2463         if (!check_vif_up(ifp->vif))
2464                 return -EIO;
2465
2466         memset(&sta_info_le, 0, sizeof(sta_info_le));
2467         memcpy(&sta_info_le, mac, ETH_ALEN);
2468         err = brcmf_fil_iovar_data_get(ifp, "tdls_sta_info",
2469                                        &sta_info_le,
2470                                        sizeof(sta_info_le));
2471         is_tdls_peer = !err;
2472         if (err) {
2473                 err = brcmf_fil_iovar_data_get(ifp, "sta_info",
2474                                                &sta_info_le,
2475                                                sizeof(sta_info_le));
2476                 if (err < 0) {
2477                         brcmf_err("GET STA INFO failed, %d\n", err);
2478                         goto done;
2479                 }
2480         }
2481         brcmf_dbg(TRACE, "version %d\n", le16_to_cpu(sta_info_le.ver));
2482         sinfo->filled = BIT(NL80211_STA_INFO_INACTIVE_TIME);
2483         sinfo->inactive_time = le32_to_cpu(sta_info_le.idle) * 1000;
2484         sta_flags = le32_to_cpu(sta_info_le.flags);
2485         brcmf_convert_sta_flags(sta_flags, sinfo);
2486         sinfo->sta_flags.mask |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2487         if (is_tdls_peer)
2488                 sinfo->sta_flags.set |= BIT(NL80211_STA_FLAG_TDLS_PEER);
2489         else
2490                 sinfo->sta_flags.set &= ~BIT(NL80211_STA_FLAG_TDLS_PEER);
2491         if (sta_flags & BRCMF_STA_ASSOC) {
2492                 sinfo->filled |= BIT(NL80211_STA_INFO_CONNECTED_TIME);
2493                 sinfo->connected_time = le32_to_cpu(sta_info_le.in);
2494                 brcmf_fill_bss_param(ifp, sinfo);
2495         }
2496         if (sta_flags & BRCMF_STA_SCBSTATS) {
2497                 sinfo->filled |= BIT(NL80211_STA_INFO_TX_FAILED);
2498                 sinfo->tx_failed = le32_to_cpu(sta_info_le.tx_failures);
2499                 sinfo->filled |= BIT(NL80211_STA_INFO_TX_PACKETS);
2500                 sinfo->tx_packets = le32_to_cpu(sta_info_le.tx_pkts);
2501                 sinfo->tx_packets += le32_to_cpu(sta_info_le.tx_mcast_pkts);
2502                 sinfo->filled |= BIT(NL80211_STA_INFO_RX_PACKETS);
2503                 sinfo->rx_packets = le32_to_cpu(sta_info_le.rx_ucast_pkts);
2504                 sinfo->rx_packets += le32_to_cpu(sta_info_le.rx_mcast_pkts);
2505                 if (sinfo->tx_packets) {
2506                         sinfo->filled |= BIT(NL80211_STA_INFO_TX_BITRATE);
2507                         sinfo->txrate.legacy = le32_to_cpu(sta_info_le.tx_rate);
2508                         sinfo->txrate.legacy /= 100;
2509                 }
2510                 if (sinfo->rx_packets) {
2511                         sinfo->filled |= BIT(NL80211_STA_INFO_RX_BITRATE);
2512                         sinfo->rxrate.legacy = le32_to_cpu(sta_info_le.rx_rate);
2513                         sinfo->rxrate.legacy /= 100;
2514                 }
2515                 if (le16_to_cpu(sta_info_le.ver) >= 4) {
2516                         sinfo->filled |= BIT(NL80211_STA_INFO_TX_BYTES);
2517                         sinfo->tx_bytes = le64_to_cpu(sta_info_le.tx_tot_bytes);
2518                         sinfo->filled |= BIT(NL80211_STA_INFO_RX_BYTES);
2519                         sinfo->rx_bytes = le64_to_cpu(sta_info_le.rx_tot_bytes);
2520                 }
2521         }
2522 done:
2523         brcmf_dbg(TRACE, "Exit\n");
2524         return err;
2525 }
2526
2527 static s32
2528 brcmf_cfg80211_set_power_mgmt(struct wiphy *wiphy, struct net_device *ndev,
2529                            bool enabled, s32 timeout)
2530 {
2531         s32 pm;
2532         s32 err = 0;
2533         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
2534         struct brcmf_if *ifp = netdev_priv(ndev);
2535
2536         brcmf_dbg(TRACE, "Enter\n");
2537
2538         /*
2539          * Powersave enable/disable request is coming from the
2540          * cfg80211 even before the interface is up. In that
2541          * scenario, driver will be storing the power save
2542          * preference in cfg struct to apply this to
2543          * FW later while initializing the dongle
2544          */
2545         cfg->pwr_save = enabled;
2546         if (!check_vif_up(ifp->vif)) {
2547
2548                 brcmf_dbg(INFO, "Device is not ready, storing the value in cfg_info struct\n");
2549                 goto done;
2550         }
2551
2552         pm = enabled ? PM_FAST : PM_OFF;
2553         /* Do not enable the power save after assoc if it is a p2p interface */
2554         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT) {
2555                 brcmf_dbg(INFO, "Do not enable power save for P2P clients\n");
2556                 pm = PM_OFF;
2557         }
2558         brcmf_dbg(INFO, "power save %s\n", (pm ? "enabled" : "disabled"));
2559
2560         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, pm);
2561         if (err) {
2562                 if (err == -ENODEV)
2563                         brcmf_err("net_device is not ready yet\n");
2564                 else
2565                         brcmf_err("error (%d)\n", err);
2566         }
2567 done:
2568         brcmf_dbg(TRACE, "Exit\n");
2569         return err;
2570 }
2571
2572 static s32 brcmf_inform_single_bss(struct brcmf_cfg80211_info *cfg,
2573                                    struct brcmf_bss_info_le *bi)
2574 {
2575         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2576         struct ieee80211_channel *notify_channel;
2577         struct cfg80211_bss *bss;
2578         struct ieee80211_supported_band *band;
2579         struct brcmu_chan ch;
2580         u16 channel;
2581         u32 freq;
2582         u16 notify_capability;
2583         u16 notify_interval;
2584         u8 *notify_ie;
2585         size_t notify_ielen;
2586         s32 notify_signal;
2587
2588         if (le32_to_cpu(bi->length) > WL_BSS_INFO_MAX) {
2589                 brcmf_err("Bss info is larger than buffer. Discarding\n");
2590                 return 0;
2591         }
2592
2593         if (!bi->ctl_ch) {
2594                 ch.chspec = le16_to_cpu(bi->chanspec);
2595                 cfg->d11inf.decchspec(&ch);
2596                 bi->ctl_ch = ch.chnum;
2597         }
2598         channel = bi->ctl_ch;
2599
2600         if (channel <= CH_MAX_2G_CHANNEL)
2601                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2602         else
2603                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2604
2605         freq = ieee80211_channel_to_frequency(channel, band->band);
2606         notify_channel = ieee80211_get_channel(wiphy, freq);
2607
2608         notify_capability = le16_to_cpu(bi->capability);
2609         notify_interval = le16_to_cpu(bi->beacon_period);
2610         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2611         notify_ielen = le32_to_cpu(bi->ie_length);
2612         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2613
2614         brcmf_dbg(CONN, "bssid: %pM\n", bi->BSSID);
2615         brcmf_dbg(CONN, "Channel: %d(%d)\n", channel, freq);
2616         brcmf_dbg(CONN, "Capability: %X\n", notify_capability);
2617         brcmf_dbg(CONN, "Beacon interval: %d\n", notify_interval);
2618         brcmf_dbg(CONN, "Signal: %d\n", notify_signal);
2619
2620         bss = cfg80211_inform_bss(wiphy, notify_channel,
2621                                   CFG80211_BSS_FTYPE_UNKNOWN,
2622                                   (const u8 *)bi->BSSID,
2623                                   0, notify_capability,
2624                                   notify_interval, notify_ie,
2625                                   notify_ielen, notify_signal,
2626                                   GFP_KERNEL);
2627
2628         if (!bss)
2629                 return -ENOMEM;
2630
2631         cfg80211_put_bss(wiphy, bss);
2632
2633         return 0;
2634 }
2635
2636 static struct brcmf_bss_info_le *
2637 next_bss_le(struct brcmf_scan_results *list, struct brcmf_bss_info_le *bss)
2638 {
2639         if (bss == NULL)
2640                 return list->bss_info_le;
2641         return (struct brcmf_bss_info_le *)((unsigned long)bss +
2642                                             le32_to_cpu(bss->length));
2643 }
2644
2645 static s32 brcmf_inform_bss(struct brcmf_cfg80211_info *cfg)
2646 {
2647         struct brcmf_scan_results *bss_list;
2648         struct brcmf_bss_info_le *bi = NULL;    /* must be initialized */
2649         s32 err = 0;
2650         int i;
2651
2652         bss_list = (struct brcmf_scan_results *)cfg->escan_info.escan_buf;
2653         if (bss_list->count != 0 &&
2654             bss_list->version != BRCMF_BSS_INFO_VERSION) {
2655                 brcmf_err("Version %d != WL_BSS_INFO_VERSION\n",
2656                           bss_list->version);
2657                 return -EOPNOTSUPP;
2658         }
2659         brcmf_dbg(SCAN, "scanned AP count (%d)\n", bss_list->count);
2660         for (i = 0; i < bss_list->count; i++) {
2661                 bi = next_bss_le(bss_list, bi);
2662                 err = brcmf_inform_single_bss(cfg, bi);
2663                 if (err)
2664                         break;
2665         }
2666         return err;
2667 }
2668
2669 static s32 wl_inform_ibss(struct brcmf_cfg80211_info *cfg,
2670                           struct net_device *ndev, const u8 *bssid)
2671 {
2672         struct wiphy *wiphy = cfg_to_wiphy(cfg);
2673         struct ieee80211_channel *notify_channel;
2674         struct brcmf_bss_info_le *bi = NULL;
2675         struct ieee80211_supported_band *band;
2676         struct cfg80211_bss *bss;
2677         struct brcmu_chan ch;
2678         u8 *buf = NULL;
2679         s32 err = 0;
2680         u32 freq;
2681         u16 notify_capability;
2682         u16 notify_interval;
2683         u8 *notify_ie;
2684         size_t notify_ielen;
2685         s32 notify_signal;
2686
2687         brcmf_dbg(TRACE, "Enter\n");
2688
2689         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
2690         if (buf == NULL) {
2691                 err = -ENOMEM;
2692                 goto CleanUp;
2693         }
2694
2695         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
2696
2697         err = brcmf_fil_cmd_data_get(netdev_priv(ndev), BRCMF_C_GET_BSS_INFO,
2698                                      buf, WL_BSS_INFO_MAX);
2699         if (err) {
2700                 brcmf_err("WLC_GET_BSS_INFO failed: %d\n", err);
2701                 goto CleanUp;
2702         }
2703
2704         bi = (struct brcmf_bss_info_le *)(buf + 4);
2705
2706         ch.chspec = le16_to_cpu(bi->chanspec);
2707         cfg->d11inf.decchspec(&ch);
2708
2709         if (ch.band == BRCMU_CHAN_BAND_2G)
2710                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
2711         else
2712                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
2713
2714         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
2715         notify_channel = ieee80211_get_channel(wiphy, freq);
2716
2717         notify_capability = le16_to_cpu(bi->capability);
2718         notify_interval = le16_to_cpu(bi->beacon_period);
2719         notify_ie = (u8 *)bi + le16_to_cpu(bi->ie_offset);
2720         notify_ielen = le32_to_cpu(bi->ie_length);
2721         notify_signal = (s16)le16_to_cpu(bi->RSSI) * 100;
2722
2723         brcmf_dbg(CONN, "channel: %d(%d)\n", ch.chnum, freq);
2724         brcmf_dbg(CONN, "capability: %X\n", notify_capability);
2725         brcmf_dbg(CONN, "beacon interval: %d\n", notify_interval);
2726         brcmf_dbg(CONN, "signal: %d\n", notify_signal);
2727
2728         bss = cfg80211_inform_bss(wiphy, notify_channel,
2729                                   CFG80211_BSS_FTYPE_UNKNOWN, bssid, 0,
2730                                   notify_capability, notify_interval,
2731                                   notify_ie, notify_ielen, notify_signal,
2732                                   GFP_KERNEL);
2733
2734         if (!bss) {
2735                 err = -ENOMEM;
2736                 goto CleanUp;
2737         }
2738
2739         cfg80211_put_bss(wiphy, bss);
2740
2741 CleanUp:
2742
2743         kfree(buf);
2744
2745         brcmf_dbg(TRACE, "Exit\n");
2746
2747         return err;
2748 }
2749
2750 static s32 brcmf_update_bss_info(struct brcmf_cfg80211_info *cfg,
2751                                  struct brcmf_if *ifp)
2752 {
2753         struct brcmf_cfg80211_profile *profile = ndev_to_prof(ifp->ndev);
2754         struct brcmf_bss_info_le *bi;
2755         struct brcmf_ssid *ssid;
2756         const struct brcmf_tlv *tim;
2757         u16 beacon_interval;
2758         u8 dtim_period;
2759         size_t ie_len;
2760         u8 *ie;
2761         s32 err = 0;
2762
2763         brcmf_dbg(TRACE, "Enter\n");
2764         if (brcmf_is_ibssmode(ifp->vif))
2765                 return err;
2766
2767         ssid = &profile->ssid;
2768
2769         *(__le32 *)cfg->extra_buf = cpu_to_le32(WL_EXTRA_BUF_MAX);
2770         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
2771                                      cfg->extra_buf, WL_EXTRA_BUF_MAX);
2772         if (err) {
2773                 brcmf_err("Could not get bss info %d\n", err);
2774                 goto update_bss_info_out;
2775         }
2776
2777         bi = (struct brcmf_bss_info_le *)(cfg->extra_buf + 4);
2778         err = brcmf_inform_single_bss(cfg, bi);
2779         if (err)
2780                 goto update_bss_info_out;
2781
2782         ie = ((u8 *)bi) + le16_to_cpu(bi->ie_offset);
2783         ie_len = le32_to_cpu(bi->ie_length);
2784         beacon_interval = le16_to_cpu(bi->beacon_period);
2785
2786         tim = brcmf_parse_tlvs(ie, ie_len, WLAN_EID_TIM);
2787         if (tim)
2788                 dtim_period = tim->data[1];
2789         else {
2790                 /*
2791                 * active scan was done so we could not get dtim
2792                 * information out of probe response.
2793                 * so we speficially query dtim information to dongle.
2794                 */
2795                 u32 var;
2796                 err = brcmf_fil_iovar_int_get(ifp, "dtim_assoc", &var);
2797                 if (err) {
2798                         brcmf_err("wl dtim_assoc failed (%d)\n", err);
2799                         goto update_bss_info_out;
2800                 }
2801                 dtim_period = (u8)var;
2802         }
2803
2804 update_bss_info_out:
2805         brcmf_dbg(TRACE, "Exit");
2806         return err;
2807 }
2808
2809 void brcmf_abort_scanning(struct brcmf_cfg80211_info *cfg)
2810 {
2811         struct escan_info *escan = &cfg->escan_info;
2812
2813         set_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2814         if (cfg->scan_request) {
2815                 escan->escan_state = WL_ESCAN_STATE_IDLE;
2816                 brcmf_notify_escan_complete(cfg, escan->ifp, true, true);
2817         }
2818         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
2819         clear_bit(BRCMF_SCAN_STATUS_ABORT, &cfg->scan_status);
2820 }
2821
2822 static void brcmf_cfg80211_escan_timeout_worker(struct work_struct *work)
2823 {
2824         struct brcmf_cfg80211_info *cfg =
2825                         container_of(work, struct brcmf_cfg80211_info,
2826                                      escan_timeout_work);
2827
2828         brcmf_inform_bss(cfg);
2829         brcmf_notify_escan_complete(cfg, cfg->escan_info.ifp, true, true);
2830 }
2831
2832 static void brcmf_escan_timeout(unsigned long data)
2833 {
2834         struct brcmf_cfg80211_info *cfg =
2835                         (struct brcmf_cfg80211_info *)data;
2836
2837         if (cfg->scan_request) {
2838                 brcmf_err("timer expired\n");
2839                 schedule_work(&cfg->escan_timeout_work);
2840         }
2841 }
2842
2843 static s32
2844 brcmf_compare_update_same_bss(struct brcmf_cfg80211_info *cfg,
2845                               struct brcmf_bss_info_le *bss,
2846                               struct brcmf_bss_info_le *bss_info_le)
2847 {
2848         struct brcmu_chan ch_bss, ch_bss_info_le;
2849
2850         ch_bss.chspec = le16_to_cpu(bss->chanspec);
2851         cfg->d11inf.decchspec(&ch_bss);
2852         ch_bss_info_le.chspec = le16_to_cpu(bss_info_le->chanspec);
2853         cfg->d11inf.decchspec(&ch_bss_info_le);
2854
2855         if (!memcmp(&bss_info_le->BSSID, &bss->BSSID, ETH_ALEN) &&
2856                 ch_bss.band == ch_bss_info_le.band &&
2857                 bss_info_le->SSID_len == bss->SSID_len &&
2858                 !memcmp(bss_info_le->SSID, bss->SSID, bss_info_le->SSID_len)) {
2859                 if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2860                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL)) {
2861                         s16 bss_rssi = le16_to_cpu(bss->RSSI);
2862                         s16 bss_info_rssi = le16_to_cpu(bss_info_le->RSSI);
2863
2864                         /* preserve max RSSI if the measurements are
2865                         * both on-channel or both off-channel
2866                         */
2867                         if (bss_info_rssi > bss_rssi)
2868                                 bss->RSSI = bss_info_le->RSSI;
2869                 } else if ((bss->flags & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2870                         (bss_info_le->flags & BRCMF_BSS_RSSI_ON_CHANNEL) == 0) {
2871                         /* preserve the on-channel rssi measurement
2872                         * if the new measurement is off channel
2873                         */
2874                         bss->RSSI = bss_info_le->RSSI;
2875                         bss->flags |= BRCMF_BSS_RSSI_ON_CHANNEL;
2876                 }
2877                 return 1;
2878         }
2879         return 0;
2880 }
2881
2882 static s32
2883 brcmf_cfg80211_escan_handler(struct brcmf_if *ifp,
2884                              const struct brcmf_event_msg *e, void *data)
2885 {
2886         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
2887         s32 status;
2888         struct brcmf_escan_result_le *escan_result_le;
2889         struct brcmf_bss_info_le *bss_info_le;
2890         struct brcmf_bss_info_le *bss = NULL;
2891         u32 bi_length;
2892         struct brcmf_scan_results *list;
2893         u32 i;
2894         bool aborted;
2895
2896         status = e->status;
2897
2898         if (!test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
2899                 brcmf_err("scan not ready, bssidx=%d\n", ifp->bssidx);
2900                 return -EPERM;
2901         }
2902
2903         if (status == BRCMF_E_STATUS_PARTIAL) {
2904                 brcmf_dbg(SCAN, "ESCAN Partial result\n");
2905                 escan_result_le = (struct brcmf_escan_result_le *) data;
2906                 if (!escan_result_le) {
2907                         brcmf_err("Invalid escan result (NULL pointer)\n");
2908                         goto exit;
2909                 }
2910                 if (le16_to_cpu(escan_result_le->bss_count) != 1) {
2911                         brcmf_err("Invalid bss_count %d: ignoring\n",
2912                                   escan_result_le->bss_count);
2913                         goto exit;
2914                 }
2915                 bss_info_le = &escan_result_le->bss_info_le;
2916
2917                 if (brcmf_p2p_scan_finding_common_channel(cfg, bss_info_le))
2918                         goto exit;
2919
2920                 if (!cfg->scan_request) {
2921                         brcmf_dbg(SCAN, "result without cfg80211 request\n");
2922                         goto exit;
2923                 }
2924
2925                 bi_length = le32_to_cpu(bss_info_le->length);
2926                 if (bi_length != (le32_to_cpu(escan_result_le->buflen) -
2927                                         WL_ESCAN_RESULTS_FIXED_SIZE)) {
2928                         brcmf_err("Invalid bss_info length %d: ignoring\n",
2929                                   bi_length);
2930                         goto exit;
2931                 }
2932
2933                 if (!(cfg_to_wiphy(cfg)->interface_modes &
2934                                         BIT(NL80211_IFTYPE_ADHOC))) {
2935                         if (le16_to_cpu(bss_info_le->capability) &
2936                                                 WLAN_CAPABILITY_IBSS) {
2937                                 brcmf_err("Ignoring IBSS result\n");
2938                                 goto exit;
2939                         }
2940                 }
2941
2942                 list = (struct brcmf_scan_results *)
2943                                 cfg->escan_info.escan_buf;
2944                 if (bi_length > WL_ESCAN_BUF_SIZE - list->buflen) {
2945                         brcmf_err("Buffer is too small: ignoring\n");
2946                         goto exit;
2947                 }
2948
2949                 for (i = 0; i < list->count; i++) {
2950                         bss = bss ? (struct brcmf_bss_info_le *)
2951                                 ((unsigned char *)bss +
2952                                 le32_to_cpu(bss->length)) : list->bss_info_le;
2953                         if (brcmf_compare_update_same_bss(cfg, bss,
2954                                                           bss_info_le))
2955                                 goto exit;
2956                 }
2957                 memcpy(&(cfg->escan_info.escan_buf[list->buflen]),
2958                         bss_info_le, bi_length);
2959                 list->version = le32_to_cpu(bss_info_le->version);
2960                 list->buflen += bi_length;
2961                 list->count++;
2962         } else {
2963                 cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2964                 if (brcmf_p2p_scan_finding_common_channel(cfg, NULL))
2965                         goto exit;
2966                 if (cfg->scan_request) {
2967                         brcmf_inform_bss(cfg);
2968                         aborted = status != BRCMF_E_STATUS_SUCCESS;
2969                         brcmf_notify_escan_complete(cfg, ifp, aborted, false);
2970                 } else
2971                         brcmf_dbg(SCAN, "Ignored scan complete result 0x%x\n",
2972                                   status);
2973         }
2974 exit:
2975         return 0;
2976 }
2977
2978 static void brcmf_init_escan(struct brcmf_cfg80211_info *cfg)
2979 {
2980         brcmf_fweh_register(cfg->pub, BRCMF_E_ESCAN_RESULT,
2981                             brcmf_cfg80211_escan_handler);
2982         cfg->escan_info.escan_state = WL_ESCAN_STATE_IDLE;
2983         /* Init scan_timeout timer */
2984         init_timer(&cfg->escan_timeout);
2985         cfg->escan_timeout.data = (unsigned long) cfg;
2986         cfg->escan_timeout.function = brcmf_escan_timeout;
2987         INIT_WORK(&cfg->escan_timeout_work,
2988                   brcmf_cfg80211_escan_timeout_worker);
2989 }
2990
2991 static __always_inline void brcmf_delay(u32 ms)
2992 {
2993         if (ms < 1000 / HZ) {
2994                 cond_resched();
2995                 mdelay(ms);
2996         } else {
2997                 msleep(ms);
2998         }
2999 }
3000
3001 static s32 brcmf_config_wowl_pattern(struct brcmf_if *ifp, u8 cmd[4],
3002                                      u8 *pattern, u32 patternsize, u8 *mask,
3003                                      u32 packet_offset)
3004 {
3005         struct brcmf_fil_wowl_pattern_le *filter;
3006         u32 masksize;
3007         u32 patternoffset;
3008         u8 *buf;
3009         u32 bufsize;
3010         s32 ret;
3011
3012         masksize = (patternsize + 7) / 8;
3013         patternoffset = sizeof(*filter) - sizeof(filter->cmd) + masksize;
3014
3015         bufsize = sizeof(*filter) + patternsize + masksize;
3016         buf = kzalloc(bufsize, GFP_KERNEL);
3017         if (!buf)
3018                 return -ENOMEM;
3019         filter = (struct brcmf_fil_wowl_pattern_le *)buf;
3020
3021         memcpy(filter->cmd, cmd, 4);
3022         filter->masksize = cpu_to_le32(masksize);
3023         filter->offset = cpu_to_le32(packet_offset);
3024         filter->patternoffset = cpu_to_le32(patternoffset);
3025         filter->patternsize = cpu_to_le32(patternsize);
3026         filter->type = cpu_to_le32(BRCMF_WOWL_PATTERN_TYPE_BITMAP);
3027
3028         if ((mask) && (masksize))
3029                 memcpy(buf + sizeof(*filter), mask, masksize);
3030         if ((pattern) && (patternsize))
3031                 memcpy(buf + sizeof(*filter) + masksize, pattern, patternsize);
3032
3033         ret = brcmf_fil_iovar_data_set(ifp, "wowl_pattern", buf, bufsize);
3034
3035         kfree(buf);
3036         return ret;
3037 }
3038
3039 static s32 brcmf_cfg80211_resume(struct wiphy *wiphy)
3040 {
3041         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3042         struct net_device *ndev = cfg_to_ndev(cfg);
3043         struct brcmf_if *ifp = netdev_priv(ndev);
3044
3045         brcmf_dbg(TRACE, "Enter\n");
3046
3047         if (cfg->wowl_enabled) {
3048                 brcmf_configure_arp_offload(ifp, true);
3049                 brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM,
3050                                       cfg->pre_wowl_pmmode);
3051                 brcmf_fil_iovar_int_set(ifp, "wowl_clear", 0);
3052                 brcmf_config_wowl_pattern(ifp, "clr", NULL, 0, NULL, 0);
3053                 cfg->wowl_enabled = false;
3054         }
3055         return 0;
3056 }
3057
3058 static void brcmf_configure_wowl(struct brcmf_cfg80211_info *cfg,
3059                                  struct brcmf_if *ifp,
3060                                  struct cfg80211_wowlan *wowl)
3061 {
3062         u32 wowl_config;
3063         u32 i;
3064
3065         brcmf_dbg(TRACE, "Suspend, wowl config.\n");
3066
3067         brcmf_configure_arp_offload(ifp, false);
3068         brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_PM, &cfg->pre_wowl_pmmode);
3069         brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, PM_MAX);
3070
3071         wowl_config = 0;
3072         if (wowl->disconnect)
3073                 wowl_config = BRCMF_WOWL_DIS | BRCMF_WOWL_BCN | BRCMF_WOWL_RETR;
3074         if (wowl->magic_pkt)
3075                 wowl_config |= BRCMF_WOWL_MAGIC;
3076         if ((wowl->patterns) && (wowl->n_patterns)) {
3077                 wowl_config |= BRCMF_WOWL_NET;
3078                 for (i = 0; i < wowl->n_patterns; i++) {
3079                         brcmf_config_wowl_pattern(ifp, "add",
3080                                 (u8 *)wowl->patterns[i].pattern,
3081                                 wowl->patterns[i].pattern_len,
3082                                 (u8 *)wowl->patterns[i].mask,
3083                                 wowl->patterns[i].pkt_offset);
3084                 }
3085         }
3086         brcmf_fil_iovar_int_set(ifp, "wowl", wowl_config);
3087         brcmf_fil_iovar_int_set(ifp, "wowl_activate", 1);
3088         brcmf_bus_wowl_config(cfg->pub->bus_if, true);
3089         cfg->wowl_enabled = true;
3090 }
3091
3092 static s32 brcmf_cfg80211_suspend(struct wiphy *wiphy,
3093                                   struct cfg80211_wowlan *wowl)
3094 {
3095         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3096         struct net_device *ndev = cfg_to_ndev(cfg);
3097         struct brcmf_if *ifp = netdev_priv(ndev);
3098         struct brcmf_cfg80211_vif *vif;
3099
3100         brcmf_dbg(TRACE, "Enter\n");
3101
3102         /* if the primary net_device is not READY there is nothing
3103          * we can do but pray resume goes smoothly.
3104          */
3105         if (!check_vif_up(ifp->vif))
3106                 goto exit;
3107
3108         /* end any scanning */
3109         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status))
3110                 brcmf_abort_scanning(cfg);
3111
3112         if (wowl == NULL) {
3113                 brcmf_bus_wowl_config(cfg->pub->bus_if, false);
3114                 list_for_each_entry(vif, &cfg->vif_list, list) {
3115                         if (!test_bit(BRCMF_VIF_STATUS_READY, &vif->sme_state))
3116                                 continue;
3117                         /* While going to suspend if associated with AP
3118                          * disassociate from AP to save power while system is
3119                          * in suspended state
3120                          */
3121                         brcmf_link_down(vif, WLAN_REASON_UNSPECIFIED);
3122                         /* Make sure WPA_Supplicant receives all the event
3123                          * generated due to DISASSOC call to the fw to keep
3124                          * the state fw and WPA_Supplicant state consistent
3125                          */
3126                         brcmf_delay(500);
3127                 }
3128                 /* Configure MPC */
3129                 brcmf_set_mpc(ifp, 1);
3130
3131         } else {
3132                 /* Configure WOWL paramaters */
3133                 brcmf_configure_wowl(cfg, ifp, wowl);
3134         }
3135
3136 exit:
3137         brcmf_dbg(TRACE, "Exit\n");
3138         /* clear any scanning activity */
3139         cfg->scan_status = 0;
3140         return 0;
3141 }
3142
3143 static __used s32
3144 brcmf_update_pmklist(struct net_device *ndev,
3145                      struct brcmf_cfg80211_pmk_list *pmk_list, s32 err)
3146 {
3147         int i, j;
3148         u32 pmkid_len;
3149
3150         pmkid_len = le32_to_cpu(pmk_list->pmkids.npmkid);
3151
3152         brcmf_dbg(CONN, "No of elements %d\n", pmkid_len);
3153         for (i = 0; i < pmkid_len; i++) {
3154                 brcmf_dbg(CONN, "PMKID[%d]: %pM =\n", i,
3155                           &pmk_list->pmkids.pmkid[i].BSSID);
3156                 for (j = 0; j < WLAN_PMKID_LEN; j++)
3157                         brcmf_dbg(CONN, "%02x\n",
3158                                   pmk_list->pmkids.pmkid[i].PMKID[j]);
3159         }
3160
3161         if (!err)
3162                 brcmf_fil_iovar_data_set(netdev_priv(ndev), "pmkid_info",
3163                                          (char *)pmk_list, sizeof(*pmk_list));
3164
3165         return err;
3166 }
3167
3168 static s32
3169 brcmf_cfg80211_set_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3170                          struct cfg80211_pmksa *pmksa)
3171 {
3172         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3173         struct brcmf_if *ifp = netdev_priv(ndev);
3174         struct pmkid_list *pmkids = &cfg->pmk_list->pmkids;
3175         s32 err = 0;
3176         u32 pmkid_len, i;
3177
3178         brcmf_dbg(TRACE, "Enter\n");
3179         if (!check_vif_up(ifp->vif))
3180                 return -EIO;
3181
3182         pmkid_len = le32_to_cpu(pmkids->npmkid);
3183         for (i = 0; i < pmkid_len; i++)
3184                 if (!memcmp(pmksa->bssid, pmkids->pmkid[i].BSSID, ETH_ALEN))
3185                         break;
3186         if (i < WL_NUM_PMKIDS_MAX) {
3187                 memcpy(pmkids->pmkid[i].BSSID, pmksa->bssid, ETH_ALEN);
3188                 memcpy(pmkids->pmkid[i].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3189                 if (i == pmkid_len) {
3190                         pmkid_len++;
3191                         pmkids->npmkid = cpu_to_le32(pmkid_len);
3192                 }
3193         } else
3194                 err = -EINVAL;
3195
3196         brcmf_dbg(CONN, "set_pmksa,IW_PMKSA_ADD - PMKID: %pM =\n",
3197                   pmkids->pmkid[pmkid_len].BSSID);
3198         for (i = 0; i < WLAN_PMKID_LEN; i++)
3199                 brcmf_dbg(CONN, "%02x\n", pmkids->pmkid[pmkid_len].PMKID[i]);
3200
3201         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3202
3203         brcmf_dbg(TRACE, "Exit\n");
3204         return err;
3205 }
3206
3207 static s32
3208 brcmf_cfg80211_del_pmksa(struct wiphy *wiphy, struct net_device *ndev,
3209                       struct cfg80211_pmksa *pmksa)
3210 {
3211         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3212         struct brcmf_if *ifp = netdev_priv(ndev);
3213         struct pmkid_list pmkid;
3214         s32 err = 0;
3215         u32 pmkid_len, i;
3216
3217         brcmf_dbg(TRACE, "Enter\n");
3218         if (!check_vif_up(ifp->vif))
3219                 return -EIO;
3220
3221         memcpy(&pmkid.pmkid[0].BSSID, pmksa->bssid, ETH_ALEN);
3222         memcpy(&pmkid.pmkid[0].PMKID, pmksa->pmkid, WLAN_PMKID_LEN);
3223
3224         brcmf_dbg(CONN, "del_pmksa,IW_PMKSA_REMOVE - PMKID: %pM =\n",
3225                   &pmkid.pmkid[0].BSSID);
3226         for (i = 0; i < WLAN_PMKID_LEN; i++)
3227                 brcmf_dbg(CONN, "%02x\n", pmkid.pmkid[0].PMKID[i]);
3228
3229         pmkid_len = le32_to_cpu(cfg->pmk_list->pmkids.npmkid);
3230         for (i = 0; i < pmkid_len; i++)
3231                 if (!memcmp
3232                     (pmksa->bssid, &cfg->pmk_list->pmkids.pmkid[i].BSSID,
3233                      ETH_ALEN))
3234                         break;
3235
3236         if ((pmkid_len > 0)
3237             && (i < pmkid_len)) {
3238                 memset(&cfg->pmk_list->pmkids.pmkid[i], 0,
3239                        sizeof(struct pmkid));
3240                 for (; i < (pmkid_len - 1); i++) {
3241                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].BSSID,
3242                                &cfg->pmk_list->pmkids.pmkid[i + 1].BSSID,
3243                                ETH_ALEN);
3244                         memcpy(&cfg->pmk_list->pmkids.pmkid[i].PMKID,
3245                                &cfg->pmk_list->pmkids.pmkid[i + 1].PMKID,
3246                                WLAN_PMKID_LEN);
3247                 }
3248                 cfg->pmk_list->pmkids.npmkid = cpu_to_le32(pmkid_len - 1);
3249         } else
3250                 err = -EINVAL;
3251
3252         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3253
3254         brcmf_dbg(TRACE, "Exit\n");
3255         return err;
3256
3257 }
3258
3259 static s32
3260 brcmf_cfg80211_flush_pmksa(struct wiphy *wiphy, struct net_device *ndev)
3261 {
3262         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3263         struct brcmf_if *ifp = netdev_priv(ndev);
3264         s32 err = 0;
3265
3266         brcmf_dbg(TRACE, "Enter\n");
3267         if (!check_vif_up(ifp->vif))
3268                 return -EIO;
3269
3270         memset(cfg->pmk_list, 0, sizeof(*cfg->pmk_list));
3271         err = brcmf_update_pmklist(ndev, cfg->pmk_list, err);
3272
3273         brcmf_dbg(TRACE, "Exit\n");
3274         return err;
3275
3276 }
3277
3278 /*
3279  * PFN result doesn't have all the info which are
3280  * required by the supplicant
3281  * (For e.g IEs) Do a target Escan so that sched scan results are reported
3282  * via wl_inform_single_bss in the required format. Escan does require the
3283  * scan request in the form of cfg80211_scan_request. For timebeing, create
3284  * cfg80211_scan_request one out of the received PNO event.
3285  */
3286 static s32
3287 brcmf_notify_sched_scan_results(struct brcmf_if *ifp,
3288                                 const struct brcmf_event_msg *e, void *data)
3289 {
3290         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
3291         struct brcmf_pno_net_info_le *netinfo, *netinfo_start;
3292         struct cfg80211_scan_request *request = NULL;
3293         struct cfg80211_ssid *ssid = NULL;
3294         struct ieee80211_channel *channel = NULL;
3295         struct wiphy *wiphy = cfg_to_wiphy(cfg);
3296         int err = 0;
3297         int channel_req = 0;
3298         int band = 0;
3299         struct brcmf_pno_scanresults_le *pfn_result;
3300         u32 result_count;
3301         u32 status;
3302
3303         brcmf_dbg(SCAN, "Enter\n");
3304
3305         if (e->event_code == BRCMF_E_PFN_NET_LOST) {
3306                 brcmf_dbg(SCAN, "PFN NET LOST event. Do Nothing\n");
3307                 return 0;
3308         }
3309
3310         pfn_result = (struct brcmf_pno_scanresults_le *)data;
3311         result_count = le32_to_cpu(pfn_result->count);
3312         status = le32_to_cpu(pfn_result->status);
3313
3314         /*
3315          * PFN event is limited to fit 512 bytes so we may get
3316          * multiple NET_FOUND events. For now place a warning here.
3317          */
3318         WARN_ON(status != BRCMF_PNO_SCAN_COMPLETE);
3319         brcmf_dbg(SCAN, "PFN NET FOUND event. count: %d\n", result_count);
3320         if (result_count > 0) {
3321                 int i;
3322
3323                 request = kzalloc(sizeof(*request), GFP_KERNEL);
3324                 ssid = kcalloc(result_count, sizeof(*ssid), GFP_KERNEL);
3325                 channel = kcalloc(result_count, sizeof(*channel), GFP_KERNEL);
3326                 if (!request || !ssid || !channel) {
3327                         err = -ENOMEM;
3328                         goto out_err;
3329                 }
3330
3331                 request->wiphy = wiphy;
3332                 data += sizeof(struct brcmf_pno_scanresults_le);
3333                 netinfo_start = (struct brcmf_pno_net_info_le *)data;
3334
3335                 for (i = 0; i < result_count; i++) {
3336                         netinfo = &netinfo_start[i];
3337                         if (!netinfo) {
3338                                 brcmf_err("Invalid netinfo ptr. index: %d\n",
3339                                           i);
3340                                 err = -EINVAL;
3341                                 goto out_err;
3342                         }
3343
3344                         brcmf_dbg(SCAN, "SSID:%s Channel:%d\n",
3345                                   netinfo->SSID, netinfo->channel);
3346                         memcpy(ssid[i].ssid, netinfo->SSID, netinfo->SSID_len);
3347                         ssid[i].ssid_len = netinfo->SSID_len;
3348                         request->n_ssids++;
3349
3350                         channel_req = netinfo->channel;
3351                         if (channel_req <= CH_MAX_2G_CHANNEL)
3352                                 band = NL80211_BAND_2GHZ;
3353                         else
3354                                 band = NL80211_BAND_5GHZ;
3355                         channel[i].center_freq =
3356                                 ieee80211_channel_to_frequency(channel_req,
3357                                                                band);
3358                         channel[i].band = band;
3359                         channel[i].flags |= IEEE80211_CHAN_NO_HT40;
3360                         request->channels[i] = &channel[i];
3361                         request->n_channels++;
3362                 }
3363
3364                 /* assign parsed ssid array */
3365                 if (request->n_ssids)
3366                         request->ssids = &ssid[0];
3367
3368                 if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3369                         /* Abort any on-going scan */
3370                         brcmf_abort_scanning(cfg);
3371                 }
3372
3373                 set_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3374                 cfg->escan_info.run = brcmf_run_escan;
3375                 err = brcmf_do_escan(cfg, wiphy, ifp, request);
3376                 if (err) {
3377                         clear_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status);
3378                         goto out_err;
3379                 }
3380                 cfg->sched_escan = true;
3381                 cfg->scan_request = request;
3382         } else {
3383                 brcmf_err("FALSE PNO Event. (pfn_count == 0)\n");
3384                 goto out_err;
3385         }
3386
3387         kfree(ssid);
3388         kfree(channel);
3389         kfree(request);
3390         return 0;
3391
3392 out_err:
3393         kfree(ssid);
3394         kfree(channel);
3395         kfree(request);
3396         cfg80211_sched_scan_stopped(wiphy);
3397         return err;
3398 }
3399
3400 static int brcmf_dev_pno_clean(struct net_device *ndev)
3401 {
3402         int ret;
3403
3404         /* Disable pfn */
3405         ret = brcmf_fil_iovar_int_set(netdev_priv(ndev), "pfn", 0);
3406         if (ret == 0) {
3407                 /* clear pfn */
3408                 ret = brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfnclear",
3409                                                NULL, 0);
3410         }
3411         if (ret < 0)
3412                 brcmf_err("failed code %d\n", ret);
3413
3414         return ret;
3415 }
3416
3417 static int brcmf_dev_pno_config(struct net_device *ndev)
3418 {
3419         struct brcmf_pno_param_le pfn_param;
3420
3421         memset(&pfn_param, 0, sizeof(pfn_param));
3422         pfn_param.version = cpu_to_le32(BRCMF_PNO_VERSION);
3423
3424         /* set extra pno params */
3425         pfn_param.flags = cpu_to_le16(1 << BRCMF_PNO_ENABLE_ADAPTSCAN_BIT);
3426         pfn_param.repeat = BRCMF_PNO_REPEAT;
3427         pfn_param.exp = BRCMF_PNO_FREQ_EXPO_MAX;
3428
3429         /* set up pno scan fr */
3430         pfn_param.scan_freq = cpu_to_le32(BRCMF_PNO_TIME);
3431
3432         return brcmf_fil_iovar_data_set(netdev_priv(ndev), "pfn_set",
3433                                         &pfn_param, sizeof(pfn_param));
3434 }
3435
3436 static int
3437 brcmf_cfg80211_sched_scan_start(struct wiphy *wiphy,
3438                                 struct net_device *ndev,
3439                                 struct cfg80211_sched_scan_request *request)
3440 {
3441         struct brcmf_if *ifp = netdev_priv(ndev);
3442         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
3443         struct brcmf_pno_net_param_le pfn;
3444         int i;
3445         int ret = 0;
3446
3447         brcmf_dbg(SCAN, "Enter n_match_sets:%d n_ssids:%d\n",
3448                   request->n_match_sets, request->n_ssids);
3449         if (test_bit(BRCMF_SCAN_STATUS_BUSY, &cfg->scan_status)) {
3450                 brcmf_err("Scanning already: status (%lu)\n", cfg->scan_status);
3451                 return -EAGAIN;
3452         }
3453         if (test_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status)) {
3454                 brcmf_err("Scanning suppressed: status (%lu)\n",
3455                           cfg->scan_status);
3456                 return -EAGAIN;
3457         }
3458
3459         if (!request->n_ssids || !request->n_match_sets) {
3460                 brcmf_dbg(SCAN, "Invalid sched scan req!! n_ssids:%d\n",
3461                           request->n_ssids);
3462                 return -EINVAL;
3463         }
3464
3465         if (request->n_ssids > 0) {
3466                 for (i = 0; i < request->n_ssids; i++) {
3467                         /* Active scan req for ssids */
3468                         brcmf_dbg(SCAN, ">>> Active scan req for ssid (%s)\n",
3469                                   request->ssids[i].ssid);
3470
3471                         /*
3472                          * match_set ssids is a supert set of n_ssid list,
3473                          * so we need not add these set seperately.
3474                          */
3475                 }
3476         }
3477
3478         if (request->n_match_sets > 0) {
3479                 /* clean up everything */
3480                 ret = brcmf_dev_pno_clean(ndev);
3481                 if  (ret < 0) {
3482                         brcmf_err("failed error=%d\n", ret);
3483                         return ret;
3484                 }
3485
3486                 /* configure pno */
3487                 ret = brcmf_dev_pno_config(ndev);
3488                 if (ret < 0) {
3489                         brcmf_err("PNO setup failed!! ret=%d\n", ret);
3490                         return -EINVAL;
3491                 }
3492
3493                 /* configure each match set */
3494                 for (i = 0; i < request->n_match_sets; i++) {
3495                         struct cfg80211_ssid *ssid;
3496                         u32 ssid_len;
3497
3498                         ssid = &request->match_sets[i].ssid;
3499                         ssid_len = ssid->ssid_len;
3500
3501                         if (!ssid_len) {
3502                                 brcmf_err("skip broadcast ssid\n");
3503                                 continue;
3504                         }
3505                         pfn.auth = cpu_to_le32(WLAN_AUTH_OPEN);
3506                         pfn.wpa_auth = cpu_to_le32(BRCMF_PNO_WPA_AUTH_ANY);
3507                         pfn.wsec = cpu_to_le32(0);
3508                         pfn.infra = cpu_to_le32(1);
3509                         pfn.flags = cpu_to_le32(1 << BRCMF_PNO_HIDDEN_BIT);
3510                         pfn.ssid.SSID_len = cpu_to_le32(ssid_len);
3511                         memcpy(pfn.ssid.SSID, ssid->ssid, ssid_len);
3512                         ret = brcmf_fil_iovar_data_set(ifp, "pfn_add", &pfn,
3513                                                        sizeof(pfn));
3514                         brcmf_dbg(SCAN, ">>> PNO filter %s for ssid (%s)\n",
3515                                   ret == 0 ? "set" : "failed", ssid->ssid);
3516                 }
3517                 /* Enable the PNO */
3518                 if (brcmf_fil_iovar_int_set(ifp, "pfn", 1) < 0) {
3519                         brcmf_err("PNO enable failed!! ret=%d\n", ret);
3520                         return -EINVAL;
3521                 }
3522         } else {
3523                 return -EINVAL;
3524         }
3525
3526         return 0;
3527 }
3528
3529 static int brcmf_cfg80211_sched_scan_stop(struct wiphy *wiphy,
3530                                           struct net_device *ndev)
3531 {
3532         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3533
3534         brcmf_dbg(SCAN, "enter\n");
3535         brcmf_dev_pno_clean(ndev);
3536         if (cfg->sched_escan)
3537                 brcmf_notify_escan_complete(cfg, netdev_priv(ndev), true, true);
3538         return 0;
3539 }
3540
3541 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3542 {
3543         s32 err;
3544
3545         /* set auth */
3546         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3547         if (err < 0) {
3548                 brcmf_err("auth error %d\n", err);
3549                 return err;
3550         }
3551         /* set wsec */
3552         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3553         if (err < 0) {
3554                 brcmf_err("wsec error %d\n", err);
3555                 return err;
3556         }
3557         /* set upper-layer auth */
3558         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3559         if (err < 0) {
3560                 brcmf_err("wpa_auth error %d\n", err);
3561                 return err;
3562         }
3563
3564         return 0;
3565 }
3566
3567 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3568 {
3569         if (is_rsn_ie)
3570                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3571
3572         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3573 }
3574
3575 static s32
3576 brcmf_configure_wpaie(struct brcmf_if *ifp,
3577                       const struct brcmf_vs_tlv *wpa_ie,
3578                       bool is_rsn_ie)
3579 {
3580         u32 auth = 0; /* d11 open authentication */
3581         u16 count;
3582         s32 err = 0;
3583         s32 len = 0;
3584         u32 i;
3585         u32 wsec;
3586         u32 pval = 0;
3587         u32 gval = 0;
3588         u32 wpa_auth = 0;
3589         u32 offset;
3590         u8 *data;
3591         u16 rsn_cap;
3592         u32 wme_bss_disable;
3593
3594         brcmf_dbg(TRACE, "Enter\n");
3595         if (wpa_ie == NULL)
3596                 goto exit;
3597
3598         len = wpa_ie->len + TLV_HDR_LEN;
3599         data = (u8 *)wpa_ie;
3600         offset = TLV_HDR_LEN;
3601         if (!is_rsn_ie)
3602                 offset += VS_IE_FIXED_HDR_LEN;
3603         else
3604                 offset += WPA_IE_VERSION_LEN;
3605
3606         /* check for multicast cipher suite */
3607         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3608                 err = -EINVAL;
3609                 brcmf_err("no multicast cipher suite\n");
3610                 goto exit;
3611         }
3612
3613         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3614                 err = -EINVAL;
3615                 brcmf_err("ivalid OUI\n");
3616                 goto exit;
3617         }
3618         offset += TLV_OUI_LEN;
3619
3620         /* pick up multicast cipher */
3621         switch (data[offset]) {
3622         case WPA_CIPHER_NONE:
3623                 gval = 0;
3624                 break;
3625         case WPA_CIPHER_WEP_40:
3626         case WPA_CIPHER_WEP_104:
3627                 gval = WEP_ENABLED;
3628                 break;
3629         case WPA_CIPHER_TKIP:
3630                 gval = TKIP_ENABLED;
3631                 break;
3632         case WPA_CIPHER_AES_CCM:
3633                 gval = AES_ENABLED;
3634                 break;
3635         default:
3636                 err = -EINVAL;
3637                 brcmf_err("Invalid multi cast cipher info\n");
3638                 goto exit;
3639         }
3640
3641         offset++;
3642         /* walk thru unicast cipher list and pick up what we recognize */
3643         count = data[offset] + (data[offset + 1] << 8);
3644         offset += WPA_IE_SUITE_COUNT_LEN;
3645         /* Check for unicast suite(s) */
3646         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3647                 err = -EINVAL;
3648                 brcmf_err("no unicast cipher suite\n");
3649                 goto exit;
3650         }
3651         for (i = 0; i < count; i++) {
3652                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3653                         err = -EINVAL;
3654                         brcmf_err("ivalid OUI\n");
3655                         goto exit;
3656                 }
3657                 offset += TLV_OUI_LEN;
3658                 switch (data[offset]) {
3659                 case WPA_CIPHER_NONE:
3660                         break;
3661                 case WPA_CIPHER_WEP_40:
3662                 case WPA_CIPHER_WEP_104:
3663                         pval |= WEP_ENABLED;
3664                         break;
3665                 case WPA_CIPHER_TKIP:
3666                         pval |= TKIP_ENABLED;
3667                         break;
3668                 case WPA_CIPHER_AES_CCM:
3669                         pval |= AES_ENABLED;
3670                         break;
3671                 default:
3672                         brcmf_err("Ivalid unicast security info\n");
3673                 }
3674                 offset++;
3675         }
3676         /* walk thru auth management suite list and pick up what we recognize */
3677         count = data[offset] + (data[offset + 1] << 8);
3678         offset += WPA_IE_SUITE_COUNT_LEN;
3679         /* Check for auth key management suite(s) */
3680         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3681                 err = -EINVAL;
3682                 brcmf_err("no auth key mgmt suite\n");
3683                 goto exit;
3684         }
3685         for (i = 0; i < count; i++) {
3686                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3687                         err = -EINVAL;
3688                         brcmf_err("ivalid OUI\n");
3689                         goto exit;
3690                 }
3691                 offset += TLV_OUI_LEN;
3692                 switch (data[offset]) {
3693                 case RSN_AKM_NONE:
3694                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3695                         wpa_auth |= WPA_AUTH_NONE;
3696                         break;
3697                 case RSN_AKM_UNSPECIFIED:
3698                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3699                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3700                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3701                         break;
3702                 case RSN_AKM_PSK:
3703                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3704                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3705                                     (wpa_auth |= WPA_AUTH_PSK);
3706                         break;
3707                 default:
3708                         brcmf_err("Ivalid key mgmt info\n");
3709                 }
3710                 offset++;
3711         }
3712
3713         if (is_rsn_ie) {
3714                 wme_bss_disable = 1;
3715                 if ((offset + RSN_CAP_LEN) <= len) {
3716                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3717                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3718                                 wme_bss_disable = 0;
3719                 }
3720                 /* set wme_bss_disable to sync RSN Capabilities */
3721                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3722                                                wme_bss_disable);
3723                 if (err < 0) {
3724                         brcmf_err("wme_bss_disable error %d\n", err);
3725                         goto exit;
3726                 }
3727         }
3728         /* FOR WPS , set SES_OW_ENABLED */
3729         wsec = (pval | gval | SES_OW_ENABLED);
3730
3731         /* set auth */
3732         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3733         if (err < 0) {
3734                 brcmf_err("auth error %d\n", err);
3735                 goto exit;
3736         }
3737         /* set wsec */
3738         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3739         if (err < 0) {
3740                 brcmf_err("wsec error %d\n", err);
3741                 goto exit;
3742         }
3743         /* set upper-layer auth */
3744         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3745         if (err < 0) {
3746                 brcmf_err("wpa_auth error %d\n", err);
3747                 goto exit;
3748         }
3749
3750 exit:
3751         return err;
3752 }
3753
3754 static s32
3755 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3756                      struct parsed_vndr_ies *vndr_ies)
3757 {
3758         struct brcmf_vs_tlv *vndrie;
3759         struct brcmf_tlv *ie;
3760         struct parsed_vndr_ie_info *parsed_info;
3761         s32 remaining_len;
3762
3763         remaining_len = (s32)vndr_ie_len;
3764         memset(vndr_ies, 0, sizeof(*vndr_ies));
3765
3766         ie = (struct brcmf_tlv *)vndr_ie_buf;
3767         while (ie) {
3768                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3769                         goto next;
3770                 vndrie = (struct brcmf_vs_tlv *)ie;
3771                 /* len should be bigger than OUI length + one */
3772                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3773                         brcmf_err("invalid vndr ie. length is too small %d\n",
3774                                   vndrie->len);
3775                         goto next;
3776                 }
3777                 /* if wpa or wme ie, do not add ie */
3778                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3779                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3780                     (vndrie->oui_type == WME_OUI_TYPE))) {
3781                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3782                         goto next;
3783                 }
3784
3785                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3786
3787                 /* save vndr ie information */
3788                 parsed_info->ie_ptr = (char *)vndrie;
3789                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3790                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3791
3792                 vndr_ies->count++;
3793
3794                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3795                           parsed_info->vndrie.oui[0],
3796                           parsed_info->vndrie.oui[1],
3797                           parsed_info->vndrie.oui[2],
3798                           parsed_info->vndrie.oui_type);
3799
3800                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3801                         break;
3802 next:
3803                 remaining_len -= (ie->len + TLV_HDR_LEN);
3804                 if (remaining_len <= TLV_HDR_LEN)
3805                         ie = NULL;
3806                 else
3807                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3808                                 TLV_HDR_LEN);
3809         }
3810         return 0;
3811 }
3812
3813 static u32
3814 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3815 {
3816
3817         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3818         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3819
3820         put_unaligned_le32(1, &iebuf[VNDR_IE_COUNT_OFFSET]);
3821
3822         put_unaligned_le32(pktflag, &iebuf[VNDR_IE_PKTFLAG_OFFSET]);
3823
3824         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3825
3826         return ie_len + VNDR_IE_HDR_SIZE;
3827 }
3828
3829 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3830                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3831 {
3832         struct brcmf_if *ifp;
3833         struct vif_saved_ie *saved_ie;
3834         s32 err = 0;
3835         u8  *iovar_ie_buf;
3836         u8  *curr_ie_buf;
3837         u8  *mgmt_ie_buf = NULL;
3838         int mgmt_ie_buf_len;
3839         u32 *mgmt_ie_len;
3840         u32 del_add_ie_buf_len = 0;
3841         u32 total_ie_buf_len = 0;
3842         u32 parsed_ie_buf_len = 0;
3843         struct parsed_vndr_ies old_vndr_ies;
3844         struct parsed_vndr_ies new_vndr_ies;
3845         struct parsed_vndr_ie_info *vndrie_info;
3846         s32 i;
3847         u8 *ptr;
3848         int remained_buf_len;
3849
3850         if (!vif)
3851                 return -ENODEV;
3852         ifp = vif->ifp;
3853         saved_ie = &vif->saved_ie;
3854
3855         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3856         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3857         if (!iovar_ie_buf)
3858                 return -ENOMEM;
3859         curr_ie_buf = iovar_ie_buf;
3860         switch (pktflag) {
3861         case BRCMF_VNDR_IE_PRBREQ_FLAG:
3862                 mgmt_ie_buf = saved_ie->probe_req_ie;
3863                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3864                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3865                 break;
3866         case BRCMF_VNDR_IE_PRBRSP_FLAG:
3867                 mgmt_ie_buf = saved_ie->probe_res_ie;
3868                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3869                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3870                 break;
3871         case BRCMF_VNDR_IE_BEACON_FLAG:
3872                 mgmt_ie_buf = saved_ie->beacon_ie;
3873                 mgmt_ie_len = &saved_ie->beacon_ie_len;
3874                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3875                 break;
3876         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3877                 mgmt_ie_buf = saved_ie->assoc_req_ie;
3878                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3879                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3880                 break;
3881         default:
3882                 err = -EPERM;
3883                 brcmf_err("not suitable type\n");
3884                 goto exit;
3885         }
3886
3887         if (vndr_ie_len > mgmt_ie_buf_len) {
3888                 err = -ENOMEM;
3889                 brcmf_err("extra IE size too big\n");
3890                 goto exit;
3891         }
3892
3893         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3894         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3895                 ptr = curr_ie_buf;
3896                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3897                 for (i = 0; i < new_vndr_ies.count; i++) {
3898                         vndrie_info = &new_vndr_ies.ie_info[i];
3899                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3900                                vndrie_info->ie_len);
3901                         parsed_ie_buf_len += vndrie_info->ie_len;
3902                 }
3903         }
3904
3905         if (mgmt_ie_buf && *mgmt_ie_len) {
3906                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3907                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3908                             parsed_ie_buf_len) == 0)) {
3909                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3910                         goto exit;
3911                 }
3912
3913                 /* parse old vndr_ie */
3914                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3915
3916                 /* make a command to delete old ie */
3917                 for (i = 0; i < old_vndr_ies.count; i++) {
3918                         vndrie_info = &old_vndr_ies.ie_info[i];
3919
3920                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3921                                   vndrie_info->vndrie.id,
3922                                   vndrie_info->vndrie.len,
3923                                   vndrie_info->vndrie.oui[0],
3924                                   vndrie_info->vndrie.oui[1],
3925                                   vndrie_info->vndrie.oui[2]);
3926
3927                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3928                                                            vndrie_info->ie_ptr,
3929                                                            vndrie_info->ie_len,
3930                                                            "del");
3931                         curr_ie_buf += del_add_ie_buf_len;
3932                         total_ie_buf_len += del_add_ie_buf_len;
3933                 }
3934         }
3935
3936         *mgmt_ie_len = 0;
3937         /* Add if there is any extra IE */
3938         if (mgmt_ie_buf && parsed_ie_buf_len) {
3939                 ptr = mgmt_ie_buf;
3940
3941                 remained_buf_len = mgmt_ie_buf_len;
3942
3943                 /* make a command to add new ie */
3944                 for (i = 0; i < new_vndr_ies.count; i++) {
3945                         vndrie_info = &new_vndr_ies.ie_info[i];
3946
3947                         /* verify remained buf size before copy data */
3948                         if (remained_buf_len < (vndrie_info->vndrie.len +
3949                                                         VNDR_IE_VSIE_OFFSET)) {
3950                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3951                                           remained_buf_len);
3952                                 break;
3953                         }
3954                         remained_buf_len -= (vndrie_info->ie_len +
3955                                              VNDR_IE_VSIE_OFFSET);
3956
3957                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3958                                   vndrie_info->vndrie.id,
3959                                   vndrie_info->vndrie.len,
3960                                   vndrie_info->vndrie.oui[0],
3961                                   vndrie_info->vndrie.oui[1],
3962                                   vndrie_info->vndrie.oui[2]);
3963
3964                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3965                                                            vndrie_info->ie_ptr,
3966                                                            vndrie_info->ie_len,
3967                                                            "add");
3968
3969                         /* save the parsed IE in wl struct */
3970                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3971                                vndrie_info->ie_len);
3972                         *mgmt_ie_len += vndrie_info->ie_len;
3973
3974                         curr_ie_buf += del_add_ie_buf_len;
3975                         total_ie_buf_len += del_add_ie_buf_len;
3976                 }
3977         }
3978         if (total_ie_buf_len) {
3979                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3980                                                  total_ie_buf_len);
3981                 if (err)
3982                         brcmf_err("vndr ie set error : %d\n", err);
3983         }
3984
3985 exit:
3986         kfree(iovar_ie_buf);
3987         return err;
3988 }
3989
3990 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3991 {
3992         s32 pktflags[] = {
3993                 BRCMF_VNDR_IE_PRBREQ_FLAG,
3994                 BRCMF_VNDR_IE_PRBRSP_FLAG,
3995                 BRCMF_VNDR_IE_BEACON_FLAG
3996         };
3997         int i;
3998
3999         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
4000                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
4001
4002         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
4003         return 0;
4004 }
4005
4006 static s32
4007 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
4008                         struct cfg80211_beacon_data *beacon)
4009 {
4010         s32 err;
4011
4012         /* Set Beacon IEs to FW */
4013         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
4014                                     beacon->tail, beacon->tail_len);
4015         if (err) {
4016                 brcmf_err("Set Beacon IE Failed\n");
4017                 return err;
4018         }
4019         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
4020
4021         /* Set Probe Response IEs to FW */
4022         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
4023                                     beacon->proberesp_ies,
4024                                     beacon->proberesp_ies_len);
4025         if (err)
4026                 brcmf_err("Set Probe Resp IE Failed\n");
4027         else
4028                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
4029
4030         return err;
4031 }
4032
4033 static s32
4034 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
4035                         struct cfg80211_ap_settings *settings)
4036 {
4037         s32 ie_offset;
4038         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4039         struct brcmf_if *ifp = netdev_priv(ndev);
4040         const struct brcmf_tlv *ssid_ie;
4041         const struct brcmf_tlv *country_ie;
4042         struct brcmf_ssid_le ssid_le;
4043         s32 err = -EPERM;
4044         const struct brcmf_tlv *rsn_ie;
4045         const struct brcmf_vs_tlv *wpa_ie;
4046         struct brcmf_join_params join_params;
4047         enum nl80211_iftype dev_role;
4048         struct brcmf_fil_bss_enable_le bss_enable;
4049         u16 chanspec;
4050         bool mbss;
4051         int is_11d;
4052
4053         brcmf_dbg(TRACE, "ctrlchn=%d, center=%d, bw=%d, beacon_interval=%d, dtim_period=%d,\n",
4054                   settings->chandef.chan->hw_value,
4055                   settings->chandef.center_freq1, settings->chandef.width,
4056                   settings->beacon_interval, settings->dtim_period);
4057         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
4058                   settings->ssid, settings->ssid_len, settings->auth_type,
4059                   settings->inactivity_timeout);
4060         dev_role = ifp->vif->wdev.iftype;
4061         mbss = ifp->vif->mbss;
4062
4063         /* store current 11d setting */
4064         brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_REGULATORY, &ifp->vif->is_11d);
4065         country_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4066                                       settings->beacon.tail_len,
4067                                       WLAN_EID_COUNTRY);
4068         is_11d = country_ie ? 1 : 0;
4069
4070         memset(&ssid_le, 0, sizeof(ssid_le));
4071         if (settings->ssid == NULL || settings->ssid_len == 0) {
4072                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
4073                 ssid_ie = brcmf_parse_tlvs(
4074                                 (u8 *)&settings->beacon.head[ie_offset],
4075                                 settings->beacon.head_len - ie_offset,
4076                                 WLAN_EID_SSID);
4077                 if (!ssid_ie)
4078                         return -EINVAL;
4079
4080                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
4081                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
4082                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
4083         } else {
4084                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
4085                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
4086         }
4087
4088         if (!mbss) {
4089                 brcmf_set_mpc(ifp, 0);
4090                 brcmf_configure_arp_offload(ifp, false);
4091         }
4092
4093         /* find the RSN_IE */
4094         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
4095                                   settings->beacon.tail_len, WLAN_EID_RSN);
4096
4097         /* find the WPA_IE */
4098         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
4099                                   settings->beacon.tail_len);
4100
4101         if ((wpa_ie != NULL || rsn_ie != NULL)) {
4102                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
4103                 if (wpa_ie != NULL) {
4104                         /* WPA IE */
4105                         err = brcmf_configure_wpaie(ifp, wpa_ie, false);
4106                         if (err < 0)
4107                                 goto exit;
4108                 } else {
4109                         struct brcmf_vs_tlv *tmp_ie;
4110
4111                         tmp_ie = (struct brcmf_vs_tlv *)rsn_ie;
4112
4113                         /* RSN IE */
4114                         err = brcmf_configure_wpaie(ifp, tmp_ie, true);
4115                         if (err < 0)
4116                                 goto exit;
4117                 }
4118         } else {
4119                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
4120                 brcmf_configure_opensecurity(ifp);
4121         }
4122
4123         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
4124
4125         if (!mbss) {
4126                 chanspec = chandef_to_chanspec(&cfg->d11inf,
4127                                                &settings->chandef);
4128                 err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
4129                 if (err < 0) {
4130                         brcmf_err("Set Channel failed: chspec=%d, %d\n",
4131                                   chanspec, err);
4132                         goto exit;
4133                 }
4134
4135                 if (is_11d != ifp->vif->is_11d) {
4136                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4137                                                     is_11d);
4138                         if (err < 0) {
4139                                 brcmf_err("Regulatory Set Error, %d\n", err);
4140                                 goto exit;
4141                         }
4142                 }
4143                 if (settings->beacon_interval) {
4144                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
4145                                                     settings->beacon_interval);
4146                         if (err < 0) {
4147                                 brcmf_err("Beacon Interval Set Error, %d\n",
4148                                           err);
4149                                 goto exit;
4150                         }
4151                 }
4152                 if (settings->dtim_period) {
4153                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
4154                                                     settings->dtim_period);
4155                         if (err < 0) {
4156                                 brcmf_err("DTIM Interval Set Error, %d\n", err);
4157                                 goto exit;
4158                         }
4159                 }
4160
4161                 if (dev_role == NL80211_IFTYPE_AP) {
4162                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4163                         if (err < 0) {
4164                                 brcmf_err("BRCMF_C_DOWN error %d\n", err);
4165                                 goto exit;
4166                         }
4167                         brcmf_fil_iovar_int_set(ifp, "apsta", 0);
4168                 }
4169
4170                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
4171                 if (err < 0) {
4172                         brcmf_err("SET INFRA error %d\n", err);
4173                         goto exit;
4174                 }
4175         } else if (WARN_ON(is_11d != ifp->vif->is_11d)) {
4176                 /* Multiple-BSS should use same 11d configuration */
4177                 err = -EINVAL;
4178                 goto exit;
4179         }
4180         if (dev_role == NL80211_IFTYPE_AP) {
4181                 if ((brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) && (!mbss))
4182                         brcmf_fil_iovar_int_set(ifp, "mbss", 1);
4183
4184                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
4185                 if (err < 0) {
4186                         brcmf_err("setting AP mode failed %d\n", err);
4187                         goto exit;
4188                 }
4189                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4190                 if (err < 0) {
4191                         brcmf_err("BRCMF_C_UP error (%d)\n", err);
4192                         goto exit;
4193                 }
4194                 /* On DOWN the firmware removes the WEP keys, reconfigure
4195                  * them if they were set.
4196                  */
4197                 brcmf_cfg80211_reconfigure_wep(ifp);
4198
4199                 memset(&join_params, 0, sizeof(join_params));
4200                 /* join parameters starts with ssid */
4201                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
4202                 /* create softap */
4203                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4204                                              &join_params, sizeof(join_params));
4205                 if (err < 0) {
4206                         brcmf_err("SET SSID error (%d)\n", err);
4207                         goto exit;
4208                 }
4209                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
4210         } else {
4211                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
4212                                                 sizeof(ssid_le));
4213                 if (err < 0) {
4214                         brcmf_err("setting ssid failed %d\n", err);
4215                         goto exit;
4216                 }
4217                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4218                 bss_enable.enable = cpu_to_le32(1);
4219                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4220                                                sizeof(bss_enable));
4221                 if (err < 0) {
4222                         brcmf_err("bss_enable config failed %d\n", err);
4223                         goto exit;
4224                 }
4225
4226                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
4227         }
4228         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4229         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4230
4231 exit:
4232         if ((err) && (!mbss)) {
4233                 brcmf_set_mpc(ifp, 1);
4234                 brcmf_configure_arp_offload(ifp, true);
4235         }
4236         return err;
4237 }
4238
4239 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
4240 {
4241         struct brcmf_if *ifp = netdev_priv(ndev);
4242         s32 err;
4243         struct brcmf_fil_bss_enable_le bss_enable;
4244         struct brcmf_join_params join_params;
4245
4246         brcmf_dbg(TRACE, "Enter\n");
4247
4248         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
4249                 /* Due to most likely deauths outstanding we sleep */
4250                 /* first to make sure they get processed by fw. */
4251                 msleep(400);
4252
4253                 if (ifp->vif->mbss) {
4254                         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4255                         return err;
4256                 }
4257
4258                 memset(&join_params, 0, sizeof(join_params));
4259                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
4260                                              &join_params, sizeof(join_params));
4261                 if (err < 0)
4262                         brcmf_err("SET SSID error (%d)\n", err);
4263                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
4264                 if (err < 0)
4265                         brcmf_err("BRCMF_C_DOWN error %d\n", err);
4266                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
4267                 if (err < 0)
4268                         brcmf_err("setting AP mode failed %d\n", err);
4269                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
4270                 if (err < 0)
4271                         brcmf_err("setting INFRA mode failed %d\n", err);
4272                 if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS))
4273                         brcmf_fil_iovar_int_set(ifp, "mbss", 0);
4274                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_REGULATORY,
4275                                             ifp->vif->is_11d);
4276                 if (err < 0)
4277                         brcmf_err("restoring REGULATORY setting failed %d\n",
4278                                   err);
4279                 /* Bring device back up so it can be used again */
4280                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
4281                 if (err < 0)
4282                         brcmf_err("BRCMF_C_UP error %d\n", err);
4283         } else {
4284                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
4285                 bss_enable.enable = cpu_to_le32(0);
4286                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
4287                                                sizeof(bss_enable));
4288                 if (err < 0)
4289                         brcmf_err("bss_enable config failed %d\n", err);
4290         }
4291         brcmf_set_mpc(ifp, 1);
4292         brcmf_configure_arp_offload(ifp, true);
4293         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
4294         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
4295
4296         return err;
4297 }
4298
4299 static s32
4300 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
4301                              struct cfg80211_beacon_data *info)
4302 {
4303         struct brcmf_if *ifp = netdev_priv(ndev);
4304         s32 err;
4305
4306         brcmf_dbg(TRACE, "Enter\n");
4307
4308         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
4309
4310         return err;
4311 }
4312
4313 static int
4314 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
4315                            struct station_del_parameters *params)
4316 {
4317         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4318         struct brcmf_scb_val_le scbval;
4319         struct brcmf_if *ifp = netdev_priv(ndev);
4320         s32 err;
4321
4322         if (!params->mac)
4323                 return -EFAULT;
4324
4325         brcmf_dbg(TRACE, "Enter %pM\n", params->mac);
4326
4327         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
4328                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
4329         if (!check_vif_up(ifp->vif))
4330                 return -EIO;
4331
4332         memcpy(&scbval.ea, params->mac, ETH_ALEN);
4333         scbval.val = cpu_to_le32(params->reason_code);
4334         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
4335                                      &scbval, sizeof(scbval));
4336         if (err)
4337                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
4338
4339         brcmf_dbg(TRACE, "Exit\n");
4340         return err;
4341 }
4342
4343 static int
4344 brcmf_cfg80211_change_station(struct wiphy *wiphy, struct net_device *ndev,
4345                               const u8 *mac, struct station_parameters *params)
4346 {
4347         struct brcmf_if *ifp = netdev_priv(ndev);
4348         s32 err;
4349
4350         brcmf_dbg(TRACE, "Enter, MAC %pM, mask 0x%04x set 0x%04x\n", mac,
4351                   params->sta_flags_mask, params->sta_flags_set);
4352
4353         /* Ignore all 00 MAC */
4354         if (is_zero_ether_addr(mac))
4355                 return 0;
4356
4357         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
4358                 return 0;
4359
4360         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
4361                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_AUTHORIZE,
4362                                              (void *)mac, ETH_ALEN);
4363         else
4364                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SCB_DEAUTHORIZE,
4365                                              (void *)mac, ETH_ALEN);
4366         if (err < 0)
4367                 brcmf_err("Setting SCB (de-)authorize failed, %d\n", err);
4368
4369         return err;
4370 }
4371
4372 static void
4373 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
4374                                    struct wireless_dev *wdev,
4375                                    u16 frame_type, bool reg)
4376 {
4377         struct brcmf_cfg80211_vif *vif;
4378         u16 mgmt_type;
4379
4380         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
4381
4382         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
4383         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4384         if (reg)
4385                 vif->mgmt_rx_reg |= BIT(mgmt_type);
4386         else
4387                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
4388 }
4389
4390
4391 static int
4392 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
4393                        struct cfg80211_mgmt_tx_params *params, u64 *cookie)
4394 {
4395         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4396         struct ieee80211_channel *chan = params->chan;
4397         const u8 *buf = params->buf;
4398         size_t len = params->len;
4399         const struct ieee80211_mgmt *mgmt;
4400         struct brcmf_cfg80211_vif *vif;
4401         s32 err = 0;
4402         s32 ie_offset;
4403         s32 ie_len;
4404         struct brcmf_fil_action_frame_le *action_frame;
4405         struct brcmf_fil_af_params_le *af_params;
4406         bool ack;
4407         s32 chan_nr;
4408         u32 freq;
4409
4410         brcmf_dbg(TRACE, "Enter\n");
4411
4412         *cookie = 0;
4413
4414         mgmt = (const struct ieee80211_mgmt *)buf;
4415
4416         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4417                 brcmf_err("Driver only allows MGMT packet type\n");
4418                 return -EPERM;
4419         }
4420
4421         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4422
4423         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4424                 /* Right now the only reason to get a probe response */
4425                 /* is for p2p listen response or for p2p GO from     */
4426                 /* wpa_supplicant. Unfortunately the probe is send   */
4427                 /* on primary ndev, while dongle wants it on the p2p */
4428                 /* vif. Since this is only reason for a probe        */
4429                 /* response to be sent, the vif is taken from cfg.   */
4430                 /* If ever desired to send proberesp for non p2p     */
4431                 /* response then data should be checked for          */
4432                 /* "DIRECT-". Note in future supplicant will take    */
4433                 /* dedicated p2p wdev to do this and then this 'hack'*/
4434                 /* is not needed anymore.                            */
4435                 ie_offset =  DOT11_MGMT_HDR_LEN +
4436                              DOT11_BCN_PRB_FIXED_LEN;
4437                 ie_len = len - ie_offset;
4438                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4439                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4440                 err = brcmf_vif_set_mgmt_ie(vif,
4441                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
4442                                             &buf[ie_offset],
4443                                             ie_len);
4444                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4445                                         GFP_KERNEL);
4446         } else if (ieee80211_is_action(mgmt->frame_control)) {
4447                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4448                 if (af_params == NULL) {
4449                         brcmf_err("unable to allocate frame\n");
4450                         err = -ENOMEM;
4451                         goto exit;
4452                 }
4453                 action_frame = &af_params->action_frame;
4454                 /* Add the packet Id */
4455                 action_frame->packet_id = cpu_to_le32(*cookie);
4456                 /* Add BSSID */
4457                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4458                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4459                 /* Add the length exepted for 802.11 header  */
4460                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4461                 /* Add the channel. Use the one specified as parameter if any or
4462                  * the current one (got from the firmware) otherwise
4463                  */
4464                 if (chan)
4465                         freq = chan->center_freq;
4466                 else
4467                         brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4468                                               &freq);
4469                 chan_nr = ieee80211_frequency_to_channel(freq);
4470                 af_params->channel = cpu_to_le32(chan_nr);
4471
4472                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4473                        le16_to_cpu(action_frame->len));
4474
4475                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4476                           *cookie, le16_to_cpu(action_frame->len), freq);
4477
4478                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4479                                                   af_params);
4480
4481                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4482                                         GFP_KERNEL);
4483                 kfree(af_params);
4484         } else {
4485                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4486                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4487         }
4488
4489 exit:
4490         return err;
4491 }
4492
4493
4494 static int
4495 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4496                                         struct wireless_dev *wdev,
4497                                         u64 cookie)
4498 {
4499         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4500         struct brcmf_cfg80211_vif *vif;
4501         int err = 0;
4502
4503         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4504
4505         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4506         if (vif == NULL) {
4507                 brcmf_err("No p2p device available for probe response\n");
4508                 err = -ENODEV;
4509                 goto exit;
4510         }
4511         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4512 exit:
4513         return err;
4514 }
4515
4516 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4517                                            struct wireless_dev *wdev,
4518                                            enum nl80211_crit_proto_id proto,
4519                                            u16 duration)
4520 {
4521         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4522         struct brcmf_cfg80211_vif *vif;
4523
4524         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4525
4526         /* only DHCP support for now */
4527         if (proto != NL80211_CRIT_PROTO_DHCP)
4528                 return -EINVAL;
4529
4530         /* suppress and abort scanning */
4531         set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4532         brcmf_abort_scanning(cfg);
4533
4534         return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4535 }
4536
4537 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4538                                            struct wireless_dev *wdev)
4539 {
4540         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4541         struct brcmf_cfg80211_vif *vif;
4542
4543         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4544
4545         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4546         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4547 }
4548
4549 static s32
4550 brcmf_notify_tdls_peer_event(struct brcmf_if *ifp,
4551                              const struct brcmf_event_msg *e, void *data)
4552 {
4553         switch (e->reason) {
4554         case BRCMF_E_REASON_TDLS_PEER_DISCOVERED:
4555                 brcmf_dbg(TRACE, "TDLS Peer Discovered\n");
4556                 break;
4557         case BRCMF_E_REASON_TDLS_PEER_CONNECTED:
4558                 brcmf_dbg(TRACE, "TDLS Peer Connected\n");
4559                 brcmf_proto_add_tdls_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4560                 break;
4561         case BRCMF_E_REASON_TDLS_PEER_DISCONNECTED:
4562                 brcmf_dbg(TRACE, "TDLS Peer Disconnected\n");
4563                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4564                 break;
4565         }
4566
4567         return 0;
4568 }
4569
4570 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4571 {
4572         int ret;
4573
4574         switch (oper) {
4575         case NL80211_TDLS_DISCOVERY_REQ:
4576                 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4577                 break;
4578         case NL80211_TDLS_SETUP:
4579                 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4580                 break;
4581         case NL80211_TDLS_TEARDOWN:
4582                 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4583                 break;
4584         default:
4585                 brcmf_err("unsupported operation: %d\n", oper);
4586                 ret = -EOPNOTSUPP;
4587         }
4588         return ret;
4589 }
4590
4591 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4592                                     struct net_device *ndev, const u8 *peer,
4593                                     enum nl80211_tdls_operation oper)
4594 {
4595         struct brcmf_if *ifp;
4596         struct brcmf_tdls_iovar_le info;
4597         int ret = 0;
4598
4599         ret = brcmf_convert_nl80211_tdls_oper(oper);
4600         if (ret < 0)
4601                 return ret;
4602
4603         ifp = netdev_priv(ndev);
4604         memset(&info, 0, sizeof(info));
4605         info.mode = (u8)ret;
4606         if (peer)
4607                 memcpy(info.ea, peer, ETH_ALEN);
4608
4609         ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4610                                        &info, sizeof(info));
4611         if (ret < 0)
4612                 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4613
4614         return ret;
4615 }
4616
4617 static struct cfg80211_ops wl_cfg80211_ops = {
4618         .add_virtual_intf = brcmf_cfg80211_add_iface,
4619         .del_virtual_intf = brcmf_cfg80211_del_iface,
4620         .change_virtual_intf = brcmf_cfg80211_change_iface,
4621         .scan = brcmf_cfg80211_scan,
4622         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4623         .join_ibss = brcmf_cfg80211_join_ibss,
4624         .leave_ibss = brcmf_cfg80211_leave_ibss,
4625         .get_station = brcmf_cfg80211_get_station,
4626         .set_tx_power = brcmf_cfg80211_set_tx_power,
4627         .get_tx_power = brcmf_cfg80211_get_tx_power,
4628         .add_key = brcmf_cfg80211_add_key,
4629         .del_key = brcmf_cfg80211_del_key,
4630         .get_key = brcmf_cfg80211_get_key,
4631         .set_default_key = brcmf_cfg80211_config_default_key,
4632         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4633         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4634         .connect = brcmf_cfg80211_connect,
4635         .disconnect = brcmf_cfg80211_disconnect,
4636         .suspend = brcmf_cfg80211_suspend,
4637         .resume = brcmf_cfg80211_resume,
4638         .set_pmksa = brcmf_cfg80211_set_pmksa,
4639         .del_pmksa = brcmf_cfg80211_del_pmksa,
4640         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4641         .start_ap = brcmf_cfg80211_start_ap,
4642         .stop_ap = brcmf_cfg80211_stop_ap,
4643         .change_beacon = brcmf_cfg80211_change_beacon,
4644         .del_station = brcmf_cfg80211_del_station,
4645         .change_station = brcmf_cfg80211_change_station,
4646         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4647         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4648         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4649         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4650         .remain_on_channel = brcmf_p2p_remain_on_channel,
4651         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4652         .start_p2p_device = brcmf_p2p_start_device,
4653         .stop_p2p_device = brcmf_p2p_stop_device,
4654         .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4655         .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4656         .tdls_oper = brcmf_cfg80211_tdls_oper,
4657 };
4658
4659 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4660                                            enum nl80211_iftype type,
4661                                            bool pm_block)
4662 {
4663         struct brcmf_cfg80211_vif *vif_walk;
4664         struct brcmf_cfg80211_vif *vif;
4665         bool mbss;
4666
4667         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4668                   sizeof(*vif));
4669         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4670         if (!vif)
4671                 return ERR_PTR(-ENOMEM);
4672
4673         vif->wdev.wiphy = cfg->wiphy;
4674         vif->wdev.iftype = type;
4675
4676         vif->pm_block = pm_block;
4677         vif->roam_off = -1;
4678
4679         brcmf_init_prof(&vif->profile);
4680
4681         if (type == NL80211_IFTYPE_AP) {
4682                 mbss = false;
4683                 list_for_each_entry(vif_walk, &cfg->vif_list, list) {
4684                         if (vif_walk->wdev.iftype == NL80211_IFTYPE_AP) {
4685                                 mbss = true;
4686                                 break;
4687                         }
4688                 }
4689                 vif->mbss = mbss;
4690         }
4691
4692         list_add_tail(&vif->list, &cfg->vif_list);
4693         return vif;
4694 }
4695
4696 void brcmf_free_vif(struct brcmf_cfg80211_vif *vif)
4697 {
4698         list_del(&vif->list);
4699         kfree(vif);
4700 }
4701
4702 void brcmf_cfg80211_free_netdev(struct net_device *ndev)
4703 {
4704         struct brcmf_cfg80211_vif *vif;
4705         struct brcmf_if *ifp;
4706
4707         ifp = netdev_priv(ndev);
4708         vif = ifp->vif;
4709
4710         brcmf_free_vif(vif);
4711         free_netdev(ndev);
4712 }
4713
4714 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4715 {
4716         u32 event = e->event_code;
4717         u32 status = e->status;
4718
4719         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4720                 brcmf_dbg(CONN, "Processing set ssid\n");
4721                 return true;
4722         }
4723
4724         return false;
4725 }
4726
4727 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4728 {
4729         u32 event = e->event_code;
4730         u16 flags = e->flags;
4731
4732         if ((event == BRCMF_E_DEAUTH) || (event == BRCMF_E_DEAUTH_IND) ||
4733             (event == BRCMF_E_DISASSOC_IND) ||
4734             ((event == BRCMF_E_LINK) && (!(flags & BRCMF_EVENT_MSG_LINK)))) {
4735                 brcmf_dbg(CONN, "Processing link down\n");
4736                 return true;
4737         }
4738         return false;
4739 }
4740
4741 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4742                                const struct brcmf_event_msg *e)
4743 {
4744         u32 event = e->event_code;
4745         u32 status = e->status;
4746
4747         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4748                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4749                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4750                 return true;
4751         }
4752
4753         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4754                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4755                 return true;
4756         }
4757
4758         return false;
4759 }
4760
4761 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4762 {
4763         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4764
4765         kfree(conn_info->req_ie);
4766         conn_info->req_ie = NULL;
4767         conn_info->req_ie_len = 0;
4768         kfree(conn_info->resp_ie);
4769         conn_info->resp_ie = NULL;
4770         conn_info->resp_ie_len = 0;
4771 }
4772
4773 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4774                                struct brcmf_if *ifp)
4775 {
4776         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4777         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4778         u32 req_len;
4779         u32 resp_len;
4780         s32 err = 0;
4781
4782         brcmf_clear_assoc_ies(cfg);
4783
4784         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4785                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
4786         if (err) {
4787                 brcmf_err("could not get assoc info (%d)\n", err);
4788                 return err;
4789         }
4790         assoc_info =
4791                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4792         req_len = le32_to_cpu(assoc_info->req_len);
4793         resp_len = le32_to_cpu(assoc_info->resp_len);
4794         if (req_len) {
4795                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4796                                                cfg->extra_buf,
4797                                                WL_ASSOC_INFO_MAX);
4798                 if (err) {
4799                         brcmf_err("could not get assoc req (%d)\n", err);
4800                         return err;
4801                 }
4802                 conn_info->req_ie_len = req_len;
4803                 conn_info->req_ie =
4804                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4805                             GFP_KERNEL);
4806         } else {
4807                 conn_info->req_ie_len = 0;
4808                 conn_info->req_ie = NULL;
4809         }
4810         if (resp_len) {
4811                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4812                                                cfg->extra_buf,
4813                                                WL_ASSOC_INFO_MAX);
4814                 if (err) {
4815                         brcmf_err("could not get assoc resp (%d)\n", err);
4816                         return err;
4817                 }
4818                 conn_info->resp_ie_len = resp_len;
4819                 conn_info->resp_ie =
4820                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4821                             GFP_KERNEL);
4822         } else {
4823                 conn_info->resp_ie_len = 0;
4824                 conn_info->resp_ie = NULL;
4825         }
4826         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4827                   conn_info->req_ie_len, conn_info->resp_ie_len);
4828
4829         return err;
4830 }
4831
4832 static s32
4833 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4834                        struct net_device *ndev,
4835                        const struct brcmf_event_msg *e)
4836 {
4837         struct brcmf_if *ifp = netdev_priv(ndev);
4838         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4839         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4840         struct wiphy *wiphy = cfg_to_wiphy(cfg);
4841         struct ieee80211_channel *notify_channel = NULL;
4842         struct ieee80211_supported_band *band;
4843         struct brcmf_bss_info_le *bi;
4844         struct brcmu_chan ch;
4845         u32 freq;
4846         s32 err = 0;
4847         u8 *buf;
4848
4849         brcmf_dbg(TRACE, "Enter\n");
4850
4851         brcmf_get_assoc_ies(cfg, ifp);
4852         memcpy(profile->bssid, e->addr, ETH_ALEN);
4853         brcmf_update_bss_info(cfg, ifp);
4854
4855         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4856         if (buf == NULL) {
4857                 err = -ENOMEM;
4858                 goto done;
4859         }
4860
4861         /* data sent to dongle has to be little endian */
4862         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4863         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4864                                      buf, WL_BSS_INFO_MAX);
4865
4866         if (err)
4867                 goto done;
4868
4869         bi = (struct brcmf_bss_info_le *)(buf + 4);
4870         ch.chspec = le16_to_cpu(bi->chanspec);
4871         cfg->d11inf.decchspec(&ch);
4872
4873         if (ch.band == BRCMU_CHAN_BAND_2G)
4874                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4875         else
4876                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4877
4878         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4879         notify_channel = ieee80211_get_channel(wiphy, freq);
4880
4881 done:
4882         kfree(buf);
4883         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4884                         conn_info->req_ie, conn_info->req_ie_len,
4885                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4886         brcmf_dbg(CONN, "Report roaming result\n");
4887
4888         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4889         brcmf_dbg(TRACE, "Exit\n");
4890         return err;
4891 }
4892
4893 static s32
4894 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4895                        struct net_device *ndev, const struct brcmf_event_msg *e,
4896                        bool completed)
4897 {
4898         struct brcmf_if *ifp = netdev_priv(ndev);
4899         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4900         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4901
4902         brcmf_dbg(TRACE, "Enter\n");
4903
4904         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4905                                &ifp->vif->sme_state)) {
4906                 if (completed) {
4907                         brcmf_get_assoc_ies(cfg, ifp);
4908                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4909                         brcmf_update_bss_info(cfg, ifp);
4910                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4911                                 &ifp->vif->sme_state);
4912                 }
4913                 cfg80211_connect_result(ndev,
4914                                         (u8 *)profile->bssid,
4915                                         conn_info->req_ie,
4916                                         conn_info->req_ie_len,
4917                                         conn_info->resp_ie,
4918                                         conn_info->resp_ie_len,
4919                                         completed ? WLAN_STATUS_SUCCESS :
4920                                                     WLAN_STATUS_AUTH_TIMEOUT,
4921                                         GFP_KERNEL);
4922                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4923                           completed ? "succeeded" : "failed");
4924         }
4925         brcmf_dbg(TRACE, "Exit\n");
4926         return 0;
4927 }
4928
4929 static s32
4930 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4931                                struct net_device *ndev,
4932                                const struct brcmf_event_msg *e, void *data)
4933 {
4934         struct brcmf_if *ifp = netdev_priv(ndev);
4935         static int generation;
4936         u32 event = e->event_code;
4937         u32 reason = e->reason;
4938         struct station_info sinfo;
4939
4940         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4941         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4942             ndev != cfg_to_ndev(cfg)) {
4943                 brcmf_dbg(CONN, "AP mode link down\n");
4944                 complete(&cfg->vif_disabled);
4945                 if (ifp->vif->mbss)
4946                         brcmf_remove_interface(ifp->drvr, ifp->bssidx);
4947                 return 0;
4948         }
4949
4950         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4951             (reason == BRCMF_E_STATUS_SUCCESS)) {
4952                 memset(&sinfo, 0, sizeof(sinfo));
4953                 if (!data) {
4954                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4955                         return -EINVAL;
4956                 }
4957                 sinfo.assoc_req_ies = data;
4958                 sinfo.assoc_req_ies_len = e->datalen;
4959                 generation++;
4960                 sinfo.generation = generation;
4961                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4962         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4963                    (event == BRCMF_E_DEAUTH_IND) ||
4964                    (event == BRCMF_E_DEAUTH)) {
4965                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4966         }
4967         return 0;
4968 }
4969
4970 static s32
4971 brcmf_notify_connect_status(struct brcmf_if *ifp,
4972                             const struct brcmf_event_msg *e, void *data)
4973 {
4974         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4975         struct net_device *ndev = ifp->ndev;
4976         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4977         struct ieee80211_channel *chan;
4978         s32 err = 0;
4979
4980         if ((e->event_code == BRCMF_E_DEAUTH) ||
4981             (e->event_code == BRCMF_E_DEAUTH_IND) ||
4982             (e->event_code == BRCMF_E_DISASSOC_IND) ||
4983             ((e->event_code == BRCMF_E_LINK) && (!e->flags))) {
4984                 brcmf_proto_delete_peer(ifp->drvr, ifp->ifidx, (u8 *)e->addr);
4985         }
4986
4987         if (brcmf_is_apmode(ifp->vif)) {
4988                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4989         } else if (brcmf_is_linkup(e)) {
4990                 brcmf_dbg(CONN, "Linkup\n");
4991                 if (brcmf_is_ibssmode(ifp->vif)) {
4992                         chan = ieee80211_get_channel(cfg->wiphy, cfg->channel);
4993                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4994                         wl_inform_ibss(cfg, ndev, e->addr);
4995                         cfg80211_ibss_joined(ndev, e->addr, chan, GFP_KERNEL);
4996                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4997                                   &ifp->vif->sme_state);
4998                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4999                                 &ifp->vif->sme_state);
5000                 } else
5001                         brcmf_bss_connect_done(cfg, ndev, e, true);
5002         } else if (brcmf_is_linkdown(e)) {
5003                 brcmf_dbg(CONN, "Linkdown\n");
5004                 if (!brcmf_is_ibssmode(ifp->vif)) {
5005                         brcmf_bss_connect_done(cfg, ndev, e, false);
5006                 }
5007                 brcmf_link_down(ifp->vif, brcmf_map_fw_linkdown_reason(e));
5008                 brcmf_init_prof(ndev_to_prof(ndev));
5009                 if (ndev != cfg_to_ndev(cfg))
5010                         complete(&cfg->vif_disabled);
5011         } else if (brcmf_is_nonetwork(cfg, e)) {
5012                 if (brcmf_is_ibssmode(ifp->vif))
5013                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
5014                                   &ifp->vif->sme_state);
5015                 else
5016                         brcmf_bss_connect_done(cfg, ndev, e, false);
5017         }
5018
5019         return err;
5020 }
5021
5022 static s32
5023 brcmf_notify_roaming_status(struct brcmf_if *ifp,
5024                             const struct brcmf_event_msg *e, void *data)
5025 {
5026         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5027         u32 event = e->event_code;
5028         u32 status = e->status;
5029
5030         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
5031                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
5032                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
5033                 else
5034                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
5035         }
5036
5037         return 0;
5038 }
5039
5040 static s32
5041 brcmf_notify_mic_status(struct brcmf_if *ifp,
5042                         const struct brcmf_event_msg *e, void *data)
5043 {
5044         u16 flags = e->flags;
5045         enum nl80211_key_type key_type;
5046
5047         if (flags & BRCMF_EVENT_MSG_GROUP)
5048                 key_type = NL80211_KEYTYPE_GROUP;
5049         else
5050                 key_type = NL80211_KEYTYPE_PAIRWISE;
5051
5052         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
5053                                      NULL, GFP_KERNEL);
5054
5055         return 0;
5056 }
5057
5058 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
5059                                   const struct brcmf_event_msg *e, void *data)
5060 {
5061         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5062         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
5063         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5064         struct brcmf_cfg80211_vif *vif;
5065
5066         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
5067                   ifevent->action, ifevent->flags, ifevent->ifidx,
5068                   ifevent->bssidx);
5069
5070         mutex_lock(&event->vif_event_lock);
5071         event->action = ifevent->action;
5072         vif = event->vif;
5073
5074         switch (ifevent->action) {
5075         case BRCMF_E_IF_ADD:
5076                 /* waiting process may have timed out */
5077                 if (!cfg->vif_event.vif) {
5078                         mutex_unlock(&event->vif_event_lock);
5079                         return -EBADF;
5080                 }
5081
5082                 ifp->vif = vif;
5083                 vif->ifp = ifp;
5084                 if (ifp->ndev) {
5085                         vif->wdev.netdev = ifp->ndev;
5086                         ifp->ndev->ieee80211_ptr = &vif->wdev;
5087                         SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
5088                 }
5089                 mutex_unlock(&event->vif_event_lock);
5090                 wake_up(&event->vif_wq);
5091                 return 0;
5092
5093         case BRCMF_E_IF_DEL:
5094                 mutex_unlock(&event->vif_event_lock);
5095                 /* event may not be upon user request */
5096                 if (brcmf_cfg80211_vif_event_armed(cfg))
5097                         wake_up(&event->vif_wq);
5098                 return 0;
5099
5100         case BRCMF_E_IF_CHANGE:
5101                 mutex_unlock(&event->vif_event_lock);
5102                 wake_up(&event->vif_wq);
5103                 return 0;
5104
5105         default:
5106                 mutex_unlock(&event->vif_event_lock);
5107                 break;
5108         }
5109         return -EINVAL;
5110 }
5111
5112 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
5113 {
5114         conf->frag_threshold = (u32)-1;
5115         conf->rts_threshold = (u32)-1;
5116         conf->retry_short = (u32)-1;
5117         conf->retry_long = (u32)-1;
5118         conf->tx_power = -1;
5119 }
5120
5121 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
5122 {
5123         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
5124                             brcmf_notify_connect_status);
5125         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
5126                             brcmf_notify_connect_status);
5127         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
5128                             brcmf_notify_connect_status);
5129         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
5130                             brcmf_notify_connect_status);
5131         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
5132                             brcmf_notify_connect_status);
5133         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
5134                             brcmf_notify_connect_status);
5135         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
5136                             brcmf_notify_roaming_status);
5137         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
5138                             brcmf_notify_mic_status);
5139         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
5140                             brcmf_notify_connect_status);
5141         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
5142                             brcmf_notify_sched_scan_results);
5143         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
5144                             brcmf_notify_vif_event);
5145         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
5146                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
5147         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
5148                             brcmf_p2p_notify_listen_complete);
5149         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
5150                             brcmf_p2p_notify_action_frame_rx);
5151         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
5152                             brcmf_p2p_notify_action_tx_complete);
5153         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
5154                             brcmf_p2p_notify_action_tx_complete);
5155 }
5156
5157 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
5158 {
5159         kfree(cfg->conf);
5160         cfg->conf = NULL;
5161         kfree(cfg->escan_ioctl_buf);
5162         cfg->escan_ioctl_buf = NULL;
5163         kfree(cfg->extra_buf);
5164         cfg->extra_buf = NULL;
5165         kfree(cfg->pmk_list);
5166         cfg->pmk_list = NULL;
5167 }
5168
5169 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
5170 {
5171         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
5172         if (!cfg->conf)
5173                 goto init_priv_mem_out;
5174         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5175         if (!cfg->escan_ioctl_buf)
5176                 goto init_priv_mem_out;
5177         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
5178         if (!cfg->extra_buf)
5179                 goto init_priv_mem_out;
5180         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
5181         if (!cfg->pmk_list)
5182                 goto init_priv_mem_out;
5183
5184         return 0;
5185
5186 init_priv_mem_out:
5187         brcmf_deinit_priv_mem(cfg);
5188
5189         return -ENOMEM;
5190 }
5191
5192 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
5193 {
5194         s32 err = 0;
5195
5196         cfg->scan_request = NULL;
5197         cfg->pwr_save = true;
5198         cfg->active_scan = true;        /* we do active scan per default */
5199         cfg->dongle_up = false;         /* dongle is not up yet */
5200         err = brcmf_init_priv_mem(cfg);
5201         if (err)
5202                 return err;
5203         brcmf_register_event_handlers(cfg);
5204         mutex_init(&cfg->usr_sync);
5205         brcmf_init_escan(cfg);
5206         brcmf_init_conf(cfg->conf);
5207         init_completion(&cfg->vif_disabled);
5208         return err;
5209 }
5210
5211 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
5212 {
5213         cfg->dongle_up = false; /* dongle down */
5214         brcmf_abort_scanning(cfg);
5215         brcmf_deinit_priv_mem(cfg);
5216 }
5217
5218 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
5219 {
5220         init_waitqueue_head(&event->vif_wq);
5221         mutex_init(&event->vif_event_lock);
5222 }
5223
5224 static s32
5225 brcmf_dongle_roam(struct brcmf_if *ifp, u32 bcn_timeout)
5226 {
5227         s32 err = 0;
5228         __le32 roamtrigger[2];
5229         __le32 roam_delta[2];
5230
5231         /*
5232          * Setup timeout if Beacons are lost and roam is
5233          * off to report link down
5234          */
5235         if (brcmf_roamoff) {
5236                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5237                 if (err) {
5238                         brcmf_err("bcn_timeout error (%d)\n", err);
5239                         goto dongle_rom_out;
5240                 }
5241         }
5242
5243         /*
5244          * Enable/Disable built-in roaming to allow supplicant
5245          * to take care of roaming
5246          */
5247         brcmf_dbg(INFO, "Internal Roaming = %s\n",
5248                   brcmf_roamoff ? "Off" : "On");
5249         err = brcmf_fil_iovar_int_set(ifp, "roam_off", !!(brcmf_roamoff));
5250         if (err) {
5251                 brcmf_err("roam_off error (%d)\n", err);
5252                 goto dongle_rom_out;
5253         }
5254
5255         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5256         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5257         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5258                                      (void *)roamtrigger, sizeof(roamtrigger));
5259         if (err) {
5260                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5261                 goto dongle_rom_out;
5262         }
5263
5264         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5265         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5266         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5267                                      (void *)roam_delta, sizeof(roam_delta));
5268         if (err) {
5269                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5270                 goto dongle_rom_out;
5271         }
5272
5273 dongle_rom_out:
5274         return err;
5275 }
5276
5277 static s32
5278 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5279                       s32 scan_unassoc_time, s32 scan_passive_time)
5280 {
5281         s32 err = 0;
5282
5283         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5284                                     scan_assoc_time);
5285         if (err) {
5286                 if (err == -EOPNOTSUPP)
5287                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5288                 else
5289                         brcmf_err("Scan assoc time error (%d)\n", err);
5290                 goto dongle_scantime_out;
5291         }
5292         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5293                                     scan_unassoc_time);
5294         if (err) {
5295                 if (err == -EOPNOTSUPP)
5296                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5297                 else
5298                         brcmf_err("Scan unassoc time error (%d)\n", err);
5299                 goto dongle_scantime_out;
5300         }
5301
5302         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5303                                     scan_passive_time);
5304         if (err) {
5305                 if (err == -EOPNOTSUPP)
5306                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
5307                 else
5308                         brcmf_err("Scan passive time error (%d)\n", err);
5309                 goto dongle_scantime_out;
5310         }
5311
5312 dongle_scantime_out:
5313         return err;
5314 }
5315
5316 static void brcmf_update_bw40_channel_flag(struct ieee80211_channel *channel,
5317                                            struct brcmu_chan *ch)
5318 {
5319         u32 ht40_flag;
5320
5321         ht40_flag = channel->flags & IEEE80211_CHAN_NO_HT40;
5322         if (ch->sb == BRCMU_CHAN_SB_U) {
5323                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5324                         channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5325                 channel->flags |= IEEE80211_CHAN_NO_HT40PLUS;
5326         } else {
5327                 /* It should be one of
5328                  * IEEE80211_CHAN_NO_HT40 or
5329                  * IEEE80211_CHAN_NO_HT40PLUS
5330                  */
5331                 channel->flags &= ~IEEE80211_CHAN_NO_HT40;
5332                 if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5333                         channel->flags |= IEEE80211_CHAN_NO_HT40MINUS;
5334         }
5335 }
5336
5337 static int brcmf_construct_chaninfo(struct brcmf_cfg80211_info *cfg,
5338                                     u32 bw_cap[])
5339 {
5340         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5341         struct ieee80211_supported_band *band;
5342         struct ieee80211_channel *channel;
5343         struct wiphy *wiphy;
5344         struct brcmf_chanspec_list *list;
5345         struct brcmu_chan ch;
5346         int err;
5347         u8 *pbuf;
5348         u32 i, j;
5349         u32 total;
5350         u32 chaninfo;
5351         u32 index;
5352
5353         pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5354
5355         if (pbuf == NULL)
5356                 return -ENOMEM;
5357
5358         list = (struct brcmf_chanspec_list *)pbuf;
5359
5360         err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5361                                        BRCMF_DCMD_MEDLEN);
5362         if (err) {
5363                 brcmf_err("get chanspecs error (%d)\n", err);
5364                 goto fail_pbuf;
5365         }
5366
5367         wiphy = cfg_to_wiphy(cfg);
5368         band = wiphy->bands[IEEE80211_BAND_2GHZ];
5369         if (band)
5370                 for (i = 0; i < band->n_channels; i++)
5371                         band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5372         band = wiphy->bands[IEEE80211_BAND_5GHZ];
5373         if (band)
5374                 for (i = 0; i < band->n_channels; i++)
5375                         band->channels[i].flags = IEEE80211_CHAN_DISABLED;
5376
5377         total = le32_to_cpu(list->count);
5378         for (i = 0; i < total; i++) {
5379                 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5380                 cfg->d11inf.decchspec(&ch);
5381
5382                 if (ch.band == BRCMU_CHAN_BAND_2G) {
5383                         band = wiphy->bands[IEEE80211_BAND_2GHZ];
5384                 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5385                         band = wiphy->bands[IEEE80211_BAND_5GHZ];
5386                 } else {
5387                         brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5388                         continue;
5389                 }
5390                 if (!band)
5391                         continue;
5392                 if (!(bw_cap[band->band] & WLC_BW_40MHZ_BIT) &&
5393                     ch.bw == BRCMU_CHAN_BW_40)
5394                         continue;
5395                 if (!(bw_cap[band->band] & WLC_BW_80MHZ_BIT) &&
5396                     ch.bw == BRCMU_CHAN_BW_80)
5397                         continue;
5398
5399                 channel = band->channels;
5400                 index = band->n_channels;
5401                 for (j = 0; j < band->n_channels; j++) {
5402                         if (channel[j].hw_value == ch.chnum) {
5403                                 index = j;
5404                                 break;
5405                         }
5406                 }
5407                 channel[index].center_freq =
5408                         ieee80211_channel_to_frequency(ch.chnum, band->band);
5409                 channel[index].hw_value = ch.chnum;
5410
5411                 /* assuming the chanspecs order is HT20,
5412                  * HT40 upper, HT40 lower, and VHT80.
5413                  */
5414                 if (ch.bw == BRCMU_CHAN_BW_80) {
5415                         channel[index].flags &= ~IEEE80211_CHAN_NO_80MHZ;
5416                 } else if (ch.bw == BRCMU_CHAN_BW_40) {
5417                         brcmf_update_bw40_channel_flag(&channel[index], &ch);
5418                 } else {
5419                         /* enable the channel and disable other bandwidths
5420                          * for now as mentioned order assure they are enabled
5421                          * for subsequent chanspecs.
5422                          */
5423                         channel[index].flags = IEEE80211_CHAN_NO_HT40 |
5424                                                IEEE80211_CHAN_NO_80MHZ;
5425                         ch.bw = BRCMU_CHAN_BW_20;
5426                         cfg->d11inf.encchspec(&ch);
5427                         chaninfo = ch.chspec;
5428                         err = brcmf_fil_bsscfg_int_get(ifp, "per_chan_info",
5429                                                        &chaninfo);
5430                         if (!err) {
5431                                 if (chaninfo & WL_CHAN_RADAR)
5432                                         channel[index].flags |=
5433                                                 (IEEE80211_CHAN_RADAR |
5434                                                  IEEE80211_CHAN_NO_IR);
5435                                 if (chaninfo & WL_CHAN_PASSIVE)
5436                                         channel[index].flags |=
5437                                                 IEEE80211_CHAN_NO_IR;
5438                         }
5439                 }
5440         }
5441
5442 fail_pbuf:
5443         kfree(pbuf);
5444         return err;
5445 }
5446
5447 static int brcmf_enable_bw40_2g(struct brcmf_cfg80211_info *cfg)
5448 {
5449         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5450         struct ieee80211_supported_band *band;
5451         struct brcmf_fil_bwcap_le band_bwcap;
5452         struct brcmf_chanspec_list *list;
5453         u8 *pbuf;
5454         u32 val;
5455         int err;
5456         struct brcmu_chan ch;
5457         u32 num_chan;
5458         int i, j;
5459
5460         /* verify support for bw_cap command */
5461         val = WLC_BAND_5G;
5462         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &val);
5463
5464         if (!err) {
5465                 /* only set 2G bandwidth using bw_cap command */
5466                 band_bwcap.band = cpu_to_le32(WLC_BAND_2G);
5467                 band_bwcap.bw_cap = cpu_to_le32(WLC_BW_CAP_40MHZ);
5468                 err = brcmf_fil_iovar_data_set(ifp, "bw_cap", &band_bwcap,
5469                                                sizeof(band_bwcap));
5470         } else {
5471                 brcmf_dbg(INFO, "fallback to mimo_bw_cap\n");
5472                 val = WLC_N_BW_40ALL;
5473                 err = brcmf_fil_iovar_int_set(ifp, "mimo_bw_cap", val);
5474         }
5475
5476         if (!err) {
5477                 /* update channel info in 2G band */
5478                 pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5479
5480                 if (pbuf == NULL)
5481                         return -ENOMEM;
5482
5483                 ch.band = BRCMU_CHAN_BAND_2G;
5484                 ch.bw = BRCMU_CHAN_BW_40;
5485                 ch.sb = BRCMU_CHAN_SB_NONE;
5486                 ch.chnum = 0;
5487                 cfg->d11inf.encchspec(&ch);
5488
5489                 /* pass encoded chanspec in query */
5490                 *(__le16 *)pbuf = cpu_to_le16(ch.chspec);
5491
5492                 err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5493                                                BRCMF_DCMD_MEDLEN);
5494                 if (err) {
5495                         brcmf_err("get chanspecs error (%d)\n", err);
5496                         kfree(pbuf);
5497                         return err;
5498                 }
5499
5500                 band = cfg_to_wiphy(cfg)->bands[IEEE80211_BAND_2GHZ];
5501                 list = (struct brcmf_chanspec_list *)pbuf;
5502                 num_chan = le32_to_cpu(list->count);
5503                 for (i = 0; i < num_chan; i++) {
5504                         ch.chspec = (u16)le32_to_cpu(list->element[i]);
5505                         cfg->d11inf.decchspec(&ch);
5506                         if (WARN_ON(ch.band != BRCMU_CHAN_BAND_2G))
5507                                 continue;
5508                         if (WARN_ON(ch.bw != BRCMU_CHAN_BW_40))
5509                                 continue;
5510                         for (j = 0; j < band->n_channels; j++) {
5511                                 if (band->channels[j].hw_value == ch.chnum)
5512                                         break;
5513                         }
5514                         if (WARN_ON(j == band->n_channels))
5515                                 continue;
5516
5517                         brcmf_update_bw40_channel_flag(&band->channels[j], &ch);
5518                 }
5519                 kfree(pbuf);
5520         }
5521         return err;
5522 }
5523
5524 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5525 {
5526         u32 band, mimo_bwcap;
5527         int err;
5528
5529         band = WLC_BAND_2G;
5530         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5531         if (!err) {
5532                 bw_cap[IEEE80211_BAND_2GHZ] = band;
5533                 band = WLC_BAND_5G;
5534                 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5535                 if (!err) {
5536                         bw_cap[IEEE80211_BAND_5GHZ] = band;
5537                         return;
5538                 }
5539                 WARN_ON(1);
5540                 return;
5541         }
5542         brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5543         mimo_bwcap = 0;
5544         err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5545         if (err)
5546                 /* assume 20MHz if firmware does not give a clue */
5547                 mimo_bwcap = WLC_N_BW_20ALL;
5548
5549         switch (mimo_bwcap) {
5550         case WLC_N_BW_40ALL:
5551                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5552                 /* fall-thru */
5553         case WLC_N_BW_20IN2G_40IN5G:
5554                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5555                 /* fall-thru */
5556         case WLC_N_BW_20ALL:
5557                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5558                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5559                 break;
5560         default:
5561                 brcmf_err("invalid mimo_bw_cap value\n");
5562         }
5563 }
5564
5565 static void brcmf_update_ht_cap(struct ieee80211_supported_band *band,
5566                                 u32 bw_cap[2], u32 nchain)
5567 {
5568         band->ht_cap.ht_supported = true;
5569         if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5570                 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5571                 band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5572         }
5573         band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5574         band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5575         band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5576         band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5577         memset(band->ht_cap.mcs.rx_mask, 0xff, nchain);
5578         band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5579 }
5580
5581 static __le16 brcmf_get_mcs_map(u32 nchain, enum ieee80211_vht_mcs_support supp)
5582 {
5583         u16 mcs_map;
5584         int i;
5585
5586         for (i = 0, mcs_map = 0xFFFF; i < nchain; i++)
5587                 mcs_map = (mcs_map << 2) | supp;
5588
5589         return cpu_to_le16(mcs_map);
5590 }
5591
5592 static void brcmf_update_vht_cap(struct ieee80211_supported_band *band,
5593                                  u32 bw_cap[2], u32 nchain)
5594 {
5595         __le16 mcs_map;
5596
5597         /* not allowed in 2.4G band */
5598         if (band->band == IEEE80211_BAND_2GHZ)
5599                 return;
5600
5601         band->vht_cap.vht_supported = true;
5602         /* 80MHz is mandatory */
5603         band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_80;
5604         if (bw_cap[band->band] & WLC_BW_160MHZ_BIT) {
5605                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SUPP_CHAN_WIDTH_160MHZ;
5606                 band->vht_cap.cap |= IEEE80211_VHT_CAP_SHORT_GI_160;
5607         }
5608         /* all support 256-QAM */
5609         mcs_map = brcmf_get_mcs_map(nchain, IEEE80211_VHT_MCS_SUPPORT_0_9);
5610         band->vht_cap.vht_mcs.rx_mcs_map = mcs_map;
5611         band->vht_cap.vht_mcs.tx_mcs_map = mcs_map;
5612 }
5613
5614 static int brcmf_setup_wiphybands(struct wiphy *wiphy)
5615 {
5616         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
5617         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5618         u32 nmode = 0;
5619         u32 vhtmode = 0;
5620         u32 bw_cap[2] = { WLC_BW_20MHZ_BIT, WLC_BW_20MHZ_BIT };
5621         u32 rxchain;
5622         u32 nchain;
5623         int err;
5624         s32 i;
5625         struct ieee80211_supported_band *band;
5626
5627         (void)brcmf_fil_iovar_int_get(ifp, "vhtmode", &vhtmode);
5628         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5629         if (err) {
5630                 brcmf_err("nmode error (%d)\n", err);
5631         } else {
5632                 brcmf_get_bwcap(ifp, bw_cap);
5633         }
5634         brcmf_dbg(INFO, "nmode=%d, vhtmode=%d, bw_cap=(%d, %d)\n",
5635                   nmode, vhtmode, bw_cap[IEEE80211_BAND_2GHZ],
5636                   bw_cap[IEEE80211_BAND_5GHZ]);
5637
5638         err = brcmf_fil_iovar_int_get(ifp, "rxchain", &rxchain);
5639         if (err) {
5640                 brcmf_err("rxchain error (%d)\n", err);
5641                 nchain = 1;
5642         } else {
5643                 for (nchain = 0; rxchain; nchain++)
5644                         rxchain = rxchain & (rxchain - 1);
5645         }
5646         brcmf_dbg(INFO, "nchain=%d\n", nchain);
5647
5648         err = brcmf_construct_chaninfo(cfg, bw_cap);
5649         if (err) {
5650                 brcmf_err("brcmf_construct_chaninfo failed (%d)\n", err);
5651                 return err;
5652         }
5653
5654         wiphy = cfg_to_wiphy(cfg);
5655         for (i = 0; i < ARRAY_SIZE(wiphy->bands); i++) {
5656                 band = wiphy->bands[i];
5657                 if (band == NULL)
5658                         continue;
5659
5660                 if (nmode)
5661                         brcmf_update_ht_cap(band, bw_cap, nchain);
5662                 if (vhtmode)
5663                         brcmf_update_vht_cap(band, bw_cap, nchain);
5664         }
5665
5666         return 0;
5667 }
5668
5669 static const struct ieee80211_txrx_stypes
5670 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
5671         [NL80211_IFTYPE_STATION] = {
5672                 .tx = 0xffff,
5673                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5674                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5675         },
5676         [NL80211_IFTYPE_P2P_CLIENT] = {
5677                 .tx = 0xffff,
5678                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5679                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5680         },
5681         [NL80211_IFTYPE_P2P_GO] = {
5682                 .tx = 0xffff,
5683                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
5684                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
5685                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
5686                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
5687                       BIT(IEEE80211_STYPE_AUTH >> 4) |
5688                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
5689                       BIT(IEEE80211_STYPE_ACTION >> 4)
5690         },
5691         [NL80211_IFTYPE_P2P_DEVICE] = {
5692                 .tx = 0xffff,
5693                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
5694                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
5695         }
5696 };
5697
5698 static int brcmf_setup_ifmodes(struct wiphy *wiphy, struct brcmf_if *ifp)
5699 {
5700         struct ieee80211_iface_combination *combo = NULL;
5701         struct ieee80211_iface_limit *limits = NULL;
5702         int i = 0, max_iface_cnt;
5703
5704         combo = kzalloc(sizeof(*combo), GFP_KERNEL);
5705         if (!combo)
5706                 goto err;
5707
5708         limits = kzalloc(sizeof(*limits) * 4, GFP_KERNEL);
5709         if (!limits)
5710                 goto err;
5711
5712         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
5713                                  BIT(NL80211_IFTYPE_ADHOC) |
5714                                  BIT(NL80211_IFTYPE_AP);
5715
5716         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MCHAN))
5717                 combo->num_different_channels = 2;
5718         else
5719                 combo->num_different_channels = 1;
5720
5721         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_MBSS)) {
5722                 limits[i].max = 1;
5723                 limits[i++].types = BIT(NL80211_IFTYPE_STATION);
5724                 limits[i].max = 4;
5725                 limits[i++].types = BIT(NL80211_IFTYPE_AP);
5726                 max_iface_cnt = 5;
5727         } else {
5728                 limits[i].max = 2;
5729                 limits[i++].types = BIT(NL80211_IFTYPE_STATION) |
5730                                     BIT(NL80211_IFTYPE_AP);
5731                 max_iface_cnt = 2;
5732         }
5733
5734         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_P2P)) {
5735                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_CLIENT) |
5736                                           BIT(NL80211_IFTYPE_P2P_GO) |
5737                                           BIT(NL80211_IFTYPE_P2P_DEVICE);
5738                 limits[i].max = 1;
5739                 limits[i++].types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
5740                                     BIT(NL80211_IFTYPE_P2P_GO);
5741                 limits[i].max = 1;
5742                 limits[i++].types = BIT(NL80211_IFTYPE_P2P_DEVICE);
5743                 max_iface_cnt += 2;
5744         }
5745         combo->max_interfaces = max_iface_cnt;
5746         combo->limits = limits;
5747         combo->n_limits = i;
5748
5749         wiphy->iface_combinations = combo;
5750         wiphy->n_iface_combinations = 1;
5751         return 0;
5752
5753 err:
5754         kfree(limits);
5755         kfree(combo);
5756         return -ENOMEM;
5757 }
5758
5759 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
5760 {
5761         /* scheduled scan settings */
5762         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
5763         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
5764         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5765         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
5766 }
5767
5768 #ifdef CONFIG_PM
5769 static const struct wiphy_wowlan_support brcmf_wowlan_support = {
5770         .flags = WIPHY_WOWLAN_MAGIC_PKT | WIPHY_WOWLAN_DISCONNECT,
5771         .n_patterns = BRCMF_WOWL_MAXPATTERNS,
5772         .pattern_max_len = BRCMF_WOWL_MAXPATTERNSIZE,
5773         .pattern_min_len = 1,
5774         .max_pkt_offset = 1500,
5775 };
5776 #endif
5777
5778 static void brcmf_wiphy_wowl_params(struct wiphy *wiphy)
5779 {
5780 #ifdef CONFIG_PM
5781         /* wowl settings */
5782         wiphy->wowlan = &brcmf_wowlan_support;
5783 #endif
5784 }
5785
5786 static int brcmf_setup_wiphy(struct wiphy *wiphy, struct brcmf_if *ifp)
5787 {
5788         struct ieee80211_supported_band *band;
5789         __le32 bandlist[3];
5790         u32 n_bands;
5791         int err, i;
5792
5793         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
5794         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
5795         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
5796
5797         err = brcmf_setup_ifmodes(wiphy, ifp);
5798         if (err)
5799                 return err;
5800
5801         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
5802         wiphy->cipher_suites = __wl_cipher_suites;
5803         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
5804         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
5805                         WIPHY_FLAG_OFFCHAN_TX |
5806                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
5807                         WIPHY_FLAG_SUPPORTS_TDLS;
5808         if (!brcmf_roamoff)
5809                 wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM;
5810         wiphy->mgmt_stypes = brcmf_txrx_stypes;
5811         wiphy->max_remain_on_channel_duration = 5000;
5812         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_PNO))
5813                 brcmf_wiphy_pno_params(wiphy);
5814
5815         /* vendor commands/events support */
5816         wiphy->vendor_commands = brcmf_vendor_cmds;
5817         wiphy->n_vendor_commands = BRCMF_VNDR_CMDS_LAST - 1;
5818
5819         if (brcmf_feat_is_enabled(ifp, BRCMF_FEAT_WOWL))
5820                 brcmf_wiphy_wowl_params(wiphy);
5821
5822         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST, &bandlist,
5823                                      sizeof(bandlist));
5824         if (err) {
5825                 brcmf_err("could not obtain band info: err=%d\n", err);
5826                 return err;
5827         }
5828         /* first entry in bandlist is number of bands */
5829         n_bands = le32_to_cpu(bandlist[0]);
5830         for (i = 1; i <= n_bands && i < ARRAY_SIZE(bandlist); i++) {
5831                 if (bandlist[i] == cpu_to_le32(WLC_BAND_2G)) {
5832                         band = kmemdup(&__wl_band_2ghz, sizeof(__wl_band_2ghz),
5833                                        GFP_KERNEL);
5834                         if (!band)
5835                                 return -ENOMEM;
5836
5837                         band->channels = kmemdup(&__wl_2ghz_channels,
5838                                                  sizeof(__wl_2ghz_channels),
5839                                                  GFP_KERNEL);
5840                         if (!band->channels) {
5841                                 kfree(band);
5842                                 return -ENOMEM;
5843                         }
5844
5845                         band->n_channels = ARRAY_SIZE(__wl_2ghz_channels);
5846                         wiphy->bands[IEEE80211_BAND_2GHZ] = band;
5847                 }
5848                 if (bandlist[i] == cpu_to_le32(WLC_BAND_5G)) {
5849                         band = kmemdup(&__wl_band_5ghz, sizeof(__wl_band_5ghz),
5850                                        GFP_KERNEL);
5851                         if (!band)
5852                                 return -ENOMEM;
5853
5854                         band->channels = kmemdup(&__wl_5ghz_channels,
5855                                                  sizeof(__wl_5ghz_channels),
5856                                                  GFP_KERNEL);
5857                         if (!band->channels) {
5858                                 kfree(band);
5859                                 return -ENOMEM;
5860                         }
5861
5862                         band->n_channels = ARRAY_SIZE(__wl_5ghz_channels);
5863                         wiphy->bands[IEEE80211_BAND_5GHZ] = band;
5864                 }
5865         }
5866         err = brcmf_setup_wiphybands(wiphy);
5867         return err;
5868 }
5869
5870 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5871 {
5872         struct net_device *ndev;
5873         struct wireless_dev *wdev;
5874         struct brcmf_if *ifp;
5875         s32 power_mode;
5876         s32 err = 0;
5877
5878         if (cfg->dongle_up)
5879                 return err;
5880
5881         ndev = cfg_to_ndev(cfg);
5882         wdev = ndev->ieee80211_ptr;
5883         ifp = netdev_priv(ndev);
5884
5885         /* make sure RF is ready for work */
5886         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5887
5888         brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5889                               WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5890
5891         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5892         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5893         if (err)
5894                 goto default_conf_out;
5895         brcmf_dbg(INFO, "power save set to %s\n",
5896                   (power_mode ? "enabled" : "disabled"));
5897
5898         err = brcmf_dongle_roam(ifp, WL_BEACON_TIMEOUT);
5899         if (err)
5900                 goto default_conf_out;
5901         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5902                                           NULL, NULL);
5903         if (err)
5904                 goto default_conf_out;
5905
5906         brcmf_configure_arp_offload(ifp, true);
5907
5908         cfg->dongle_up = true;
5909 default_conf_out:
5910
5911         return err;
5912
5913 }
5914
5915 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5916 {
5917         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5918
5919         return brcmf_config_dongle(ifp->drvr->config);
5920 }
5921
5922 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5923 {
5924         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5925
5926         /*
5927          * While going down, if associated with AP disassociate
5928          * from AP to save power
5929          */
5930         if (check_vif_up(ifp->vif)) {
5931                 brcmf_link_down(ifp->vif, WLAN_REASON_UNSPECIFIED);
5932
5933                 /* Make sure WPA_Supplicant receives all the event
5934                    generated due to DISASSOC call to the fw to keep
5935                    the state fw and WPA_Supplicant state consistent
5936                  */
5937                 brcmf_delay(500);
5938         }
5939
5940         brcmf_abort_scanning(cfg);
5941         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5942
5943         return 0;
5944 }
5945
5946 s32 brcmf_cfg80211_up(struct net_device *ndev)
5947 {
5948         struct brcmf_if *ifp = netdev_priv(ndev);
5949         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5950         s32 err = 0;
5951
5952         mutex_lock(&cfg->usr_sync);
5953         err = __brcmf_cfg80211_up(ifp);
5954         mutex_unlock(&cfg->usr_sync);
5955
5956         return err;
5957 }
5958
5959 s32 brcmf_cfg80211_down(struct net_device *ndev)
5960 {
5961         struct brcmf_if *ifp = netdev_priv(ndev);
5962         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5963         s32 err = 0;
5964
5965         mutex_lock(&cfg->usr_sync);
5966         err = __brcmf_cfg80211_down(ifp);
5967         mutex_unlock(&cfg->usr_sync);
5968
5969         return err;
5970 }
5971
5972 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5973 {
5974         struct wireless_dev *wdev = &ifp->vif->wdev;
5975
5976         return wdev->iftype;
5977 }
5978
5979 bool brcmf_get_vif_state_any(struct brcmf_cfg80211_info *cfg,
5980                              unsigned long state)
5981 {
5982         struct brcmf_cfg80211_vif *vif;
5983
5984         list_for_each_entry(vif, &cfg->vif_list, list) {
5985                 if (test_bit(state, &vif->sme_state))
5986                         return true;
5987         }
5988         return false;
5989 }
5990
5991 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5992                                     u8 action)
5993 {
5994         u8 evt_action;
5995
5996         mutex_lock(&event->vif_event_lock);
5997         evt_action = event->action;
5998         mutex_unlock(&event->vif_event_lock);
5999         return evt_action == action;
6000 }
6001
6002 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
6003                                   struct brcmf_cfg80211_vif *vif)
6004 {
6005         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6006
6007         mutex_lock(&event->vif_event_lock);
6008         event->vif = vif;
6009         event->action = 0;
6010         mutex_unlock(&event->vif_event_lock);
6011 }
6012
6013 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
6014 {
6015         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6016         bool armed;
6017
6018         mutex_lock(&event->vif_event_lock);
6019         armed = event->vif != NULL;
6020         mutex_unlock(&event->vif_event_lock);
6021
6022         return armed;
6023 }
6024 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
6025                                           u8 action, ulong timeout)
6026 {
6027         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
6028
6029         return wait_event_timeout(event->vif_wq,
6030                                   vif_event_equals(event, action), timeout);
6031 }
6032
6033 static void brcmf_cfg80211_reg_notifier(struct wiphy *wiphy,
6034                                         struct regulatory_request *req)
6035 {
6036         struct brcmf_cfg80211_info *cfg = wiphy_priv(wiphy);
6037         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
6038         struct brcmf_fil_country_le ccreq;
6039         int i;
6040
6041         brcmf_dbg(TRACE, "enter: initiator=%d, alpha=%c%c\n", req->initiator,
6042                   req->alpha2[0], req->alpha2[1]);
6043
6044         /* ignore non-ISO3166 country codes */
6045         for (i = 0; i < sizeof(req->alpha2); i++)
6046                 if (req->alpha2[i] < 'A' || req->alpha2[i] > 'Z') {
6047                         brcmf_err("not a ISO3166 code\n");
6048                         return;
6049                 }
6050         memset(&ccreq, 0, sizeof(ccreq));
6051         ccreq.rev = cpu_to_le32(-1);
6052         memcpy(ccreq.ccode, req->alpha2, sizeof(req->alpha2));
6053         if (brcmf_fil_iovar_data_set(ifp, "country", &ccreq, sizeof(ccreq))) {
6054                 brcmf_err("firmware rejected country setting\n");
6055                 return;
6056         }
6057         brcmf_setup_wiphybands(wiphy);
6058 }
6059
6060 static void brcmf_free_wiphy(struct wiphy *wiphy)
6061 {
6062         if (!wiphy)
6063                 return;
6064
6065         if (wiphy->iface_combinations)
6066                 kfree(wiphy->iface_combinations->limits);
6067         kfree(wiphy->iface_combinations);
6068         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6069                 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]->channels);
6070                 kfree(wiphy->bands[IEEE80211_BAND_2GHZ]);
6071         }
6072         if (wiphy->bands[IEEE80211_BAND_5GHZ]) {
6073                 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]->channels);
6074                 kfree(wiphy->bands[IEEE80211_BAND_5GHZ]);
6075         }
6076         wiphy_free(wiphy);
6077 }
6078
6079 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
6080                                                   struct device *busdev)
6081 {
6082         struct net_device *ndev = drvr->iflist[0]->ndev;
6083         struct brcmf_cfg80211_info *cfg;
6084         struct wiphy *wiphy;
6085         struct brcmf_cfg80211_vif *vif;
6086         struct brcmf_if *ifp;
6087         s32 err = 0;
6088         s32 io_type;
6089         u16 *cap = NULL;
6090
6091         if (!ndev) {
6092                 brcmf_err("ndev is invalid\n");
6093                 return NULL;
6094         }
6095
6096         ifp = netdev_priv(ndev);
6097         wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
6098         if (!wiphy) {
6099                 brcmf_err("Could not allocate wiphy device\n");
6100                 return NULL;
6101         }
6102         memcpy(wiphy->perm_addr, drvr->mac, ETH_ALEN);
6103         set_wiphy_dev(wiphy, busdev);
6104
6105         cfg = wiphy_priv(wiphy);
6106         cfg->wiphy = wiphy;
6107         cfg->pub = drvr;
6108         init_vif_event(&cfg->vif_event);
6109         INIT_LIST_HEAD(&cfg->vif_list);
6110
6111         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
6112         if (IS_ERR(vif))
6113                 goto wiphy_out;
6114
6115         vif->ifp = ifp;
6116         vif->wdev.netdev = ndev;
6117         ndev->ieee80211_ptr = &vif->wdev;
6118         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
6119
6120         err = wl_init_priv(cfg);
6121         if (err) {
6122                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
6123                 brcmf_free_vif(vif);
6124                 goto wiphy_out;
6125         }
6126         ifp->vif = vif;
6127
6128         /* determine d11 io type before wiphy setup */
6129         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION, &io_type);
6130         if (err) {
6131                 brcmf_err("Failed to get D11 version (%d)\n", err);
6132                 goto priv_out;
6133         }
6134         cfg->d11inf.io_type = (u8)io_type;
6135         brcmu_d11_attach(&cfg->d11inf);
6136
6137         err = brcmf_setup_wiphy(wiphy, ifp);
6138         if (err < 0)
6139                 goto priv_out;
6140
6141         brcmf_dbg(INFO, "Registering custom regulatory\n");
6142         wiphy->reg_notifier = brcmf_cfg80211_reg_notifier;
6143         wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
6144         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
6145
6146         /* firmware defaults to 40MHz disabled in 2G band. We signal
6147          * cfg80211 here that we do and have it decide we can enable
6148          * it. But first check if device does support 2G operation.
6149          */
6150         if (wiphy->bands[IEEE80211_BAND_2GHZ]) {
6151                 cap = &wiphy->bands[IEEE80211_BAND_2GHZ]->ht_cap.cap;
6152                 *cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6153         }
6154         err = wiphy_register(wiphy);
6155         if (err < 0) {
6156                 brcmf_err("Could not register wiphy device (%d)\n", err);
6157                 goto priv_out;
6158         }
6159
6160         /* If cfg80211 didn't disable 40MHz HT CAP in wiphy_register(),
6161          * setup 40MHz in 2GHz band and enable OBSS scanning.
6162          */
6163         if (cap && (*cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40)) {
6164                 err = brcmf_enable_bw40_2g(cfg);
6165                 if (!err)
6166                         err = brcmf_fil_iovar_int_set(ifp, "obss_coex",
6167                                                       BRCMF_OBSS_COEX_AUTO);
6168                 else
6169                         *cap &= ~IEEE80211_HT_CAP_SUP_WIDTH_20_40;
6170         }
6171
6172         err = brcmf_p2p_attach(cfg);
6173         if (err) {
6174                 brcmf_err("P2P initilisation failed (%d)\n", err);
6175                 goto wiphy_unreg_out;
6176         }
6177         err = brcmf_btcoex_attach(cfg);
6178         if (err) {
6179                 brcmf_err("BT-coex initialisation failed (%d)\n", err);
6180                 brcmf_p2p_detach(&cfg->p2p);
6181                 goto wiphy_unreg_out;
6182         }
6183
6184         err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
6185         if (err) {
6186                 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
6187                 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
6188         } else {
6189                 brcmf_fweh_register(cfg->pub, BRCMF_E_TDLS_PEER_EVENT,
6190                                     brcmf_notify_tdls_peer_event);
6191         }
6192
6193         return cfg;
6194
6195 wiphy_unreg_out:
6196         wiphy_unregister(cfg->wiphy);
6197 priv_out:
6198         wl_deinit_priv(cfg);
6199         brcmf_free_vif(vif);
6200 wiphy_out:
6201         brcmf_free_wiphy(wiphy);
6202         return NULL;
6203 }
6204
6205 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
6206 {
6207         if (!cfg)
6208                 return;
6209
6210         brcmf_btcoex_detach(cfg);
6211         wiphy_unregister(cfg->wiphy);
6212         wl_deinit_priv(cfg);
6213         brcmf_free_wiphy(cfg->wiphy);
6214 }