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