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