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