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