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