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