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