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