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