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