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