brcmfmac: correct reporting HT40 support in wiphy htcap
[linux-drm-fsl-dcu.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_NO_IR for 5GHz channels (for * 36..48 and 149..165).
206  * With respect to these flags, wpa_supplicant doesn't * start p2p
207  * 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 & BRCMF_BSS_RSSI_ON_CHANNEL) ==
2560                         (bss_info_le->flags & BRCMF_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 & BRCMF_BSS_RSSI_ON_CHANNEL) &&
2570                         (bss_info_le->flags & BRCMF_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 |= BRCMF_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,
3159                                    struct wireless_dev *wdev,
3160                                    void *data, int len)
3161 {
3162         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3163         struct net_device *ndev = cfg_to_ndev(cfg);
3164         struct brcmf_dcmd *dcmd = data;
3165         struct sk_buff *reply;
3166         int ret;
3167
3168         brcmf_dbg(TRACE, "cmd %x set %d buf %p len %d\n", dcmd->cmd, dcmd->set,
3169                   dcmd->buf, dcmd->len);
3170
3171         if (dcmd->set)
3172                 ret = brcmf_fil_cmd_data_set(netdev_priv(ndev), dcmd->cmd,
3173                                              dcmd->buf, dcmd->len);
3174         else
3175                 ret = brcmf_fil_cmd_data_get(netdev_priv(ndev), dcmd->cmd,
3176                                              dcmd->buf, dcmd->len);
3177         if (ret == 0) {
3178                 reply = cfg80211_testmode_alloc_reply_skb(wiphy, sizeof(*dcmd));
3179                 nla_put(reply, NL80211_ATTR_TESTDATA, sizeof(*dcmd), dcmd);
3180                 ret = cfg80211_testmode_reply(reply);
3181         }
3182         return ret;
3183 }
3184 #endif
3185
3186 static s32 brcmf_configure_opensecurity(struct brcmf_if *ifp)
3187 {
3188         s32 err;
3189
3190         /* set auth */
3191         err = brcmf_fil_bsscfg_int_set(ifp, "auth", 0);
3192         if (err < 0) {
3193                 brcmf_err("auth error %d\n", err);
3194                 return err;
3195         }
3196         /* set wsec */
3197         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", 0);
3198         if (err < 0) {
3199                 brcmf_err("wsec error %d\n", err);
3200                 return err;
3201         }
3202         /* set upper-layer auth */
3203         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", WPA_AUTH_NONE);
3204         if (err < 0) {
3205                 brcmf_err("wpa_auth error %d\n", err);
3206                 return err;
3207         }
3208
3209         return 0;
3210 }
3211
3212 static bool brcmf_valid_wpa_oui(u8 *oui, bool is_rsn_ie)
3213 {
3214         if (is_rsn_ie)
3215                 return (memcmp(oui, RSN_OUI, TLV_OUI_LEN) == 0);
3216
3217         return (memcmp(oui, WPA_OUI, TLV_OUI_LEN) == 0);
3218 }
3219
3220 static s32
3221 brcmf_configure_wpaie(struct net_device *ndev, struct brcmf_vs_tlv *wpa_ie,
3222                      bool is_rsn_ie)
3223 {
3224         struct brcmf_if *ifp = netdev_priv(ndev);
3225         u32 auth = 0; /* d11 open authentication */
3226         u16 count;
3227         s32 err = 0;
3228         s32 len = 0;
3229         u32 i;
3230         u32 wsec;
3231         u32 pval = 0;
3232         u32 gval = 0;
3233         u32 wpa_auth = 0;
3234         u32 offset;
3235         u8 *data;
3236         u16 rsn_cap;
3237         u32 wme_bss_disable;
3238
3239         brcmf_dbg(TRACE, "Enter\n");
3240         if (wpa_ie == NULL)
3241                 goto exit;
3242
3243         len = wpa_ie->len + TLV_HDR_LEN;
3244         data = (u8 *)wpa_ie;
3245         offset = TLV_HDR_LEN;
3246         if (!is_rsn_ie)
3247                 offset += VS_IE_FIXED_HDR_LEN;
3248         else
3249                 offset += WPA_IE_VERSION_LEN;
3250
3251         /* check for multicast cipher suite */
3252         if (offset + WPA_IE_MIN_OUI_LEN > len) {
3253                 err = -EINVAL;
3254                 brcmf_err("no multicast cipher suite\n");
3255                 goto exit;
3256         }
3257
3258         if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3259                 err = -EINVAL;
3260                 brcmf_err("ivalid OUI\n");
3261                 goto exit;
3262         }
3263         offset += TLV_OUI_LEN;
3264
3265         /* pick up multicast cipher */
3266         switch (data[offset]) {
3267         case WPA_CIPHER_NONE:
3268                 gval = 0;
3269                 break;
3270         case WPA_CIPHER_WEP_40:
3271         case WPA_CIPHER_WEP_104:
3272                 gval = WEP_ENABLED;
3273                 break;
3274         case WPA_CIPHER_TKIP:
3275                 gval = TKIP_ENABLED;
3276                 break;
3277         case WPA_CIPHER_AES_CCM:
3278                 gval = AES_ENABLED;
3279                 break;
3280         default:
3281                 err = -EINVAL;
3282                 brcmf_err("Invalid multi cast cipher info\n");
3283                 goto exit;
3284         }
3285
3286         offset++;
3287         /* walk thru unicast cipher list and pick up what we recognize */
3288         count = data[offset] + (data[offset + 1] << 8);
3289         offset += WPA_IE_SUITE_COUNT_LEN;
3290         /* Check for unicast suite(s) */
3291         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3292                 err = -EINVAL;
3293                 brcmf_err("no unicast cipher suite\n");
3294                 goto exit;
3295         }
3296         for (i = 0; i < count; i++) {
3297                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3298                         err = -EINVAL;
3299                         brcmf_err("ivalid OUI\n");
3300                         goto exit;
3301                 }
3302                 offset += TLV_OUI_LEN;
3303                 switch (data[offset]) {
3304                 case WPA_CIPHER_NONE:
3305                         break;
3306                 case WPA_CIPHER_WEP_40:
3307                 case WPA_CIPHER_WEP_104:
3308                         pval |= WEP_ENABLED;
3309                         break;
3310                 case WPA_CIPHER_TKIP:
3311                         pval |= TKIP_ENABLED;
3312                         break;
3313                 case WPA_CIPHER_AES_CCM:
3314                         pval |= AES_ENABLED;
3315                         break;
3316                 default:
3317                         brcmf_err("Ivalid unicast security info\n");
3318                 }
3319                 offset++;
3320         }
3321         /* walk thru auth management suite list and pick up what we recognize */
3322         count = data[offset] + (data[offset + 1] << 8);
3323         offset += WPA_IE_SUITE_COUNT_LEN;
3324         /* Check for auth key management suite(s) */
3325         if (offset + (WPA_IE_MIN_OUI_LEN * count) > len) {
3326                 err = -EINVAL;
3327                 brcmf_err("no auth key mgmt suite\n");
3328                 goto exit;
3329         }
3330         for (i = 0; i < count; i++) {
3331                 if (!brcmf_valid_wpa_oui(&data[offset], is_rsn_ie)) {
3332                         err = -EINVAL;
3333                         brcmf_err("ivalid OUI\n");
3334                         goto exit;
3335                 }
3336                 offset += TLV_OUI_LEN;
3337                 switch (data[offset]) {
3338                 case RSN_AKM_NONE:
3339                         brcmf_dbg(TRACE, "RSN_AKM_NONE\n");
3340                         wpa_auth |= WPA_AUTH_NONE;
3341                         break;
3342                 case RSN_AKM_UNSPECIFIED:
3343                         brcmf_dbg(TRACE, "RSN_AKM_UNSPECIFIED\n");
3344                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_UNSPECIFIED) :
3345                                     (wpa_auth |= WPA_AUTH_UNSPECIFIED);
3346                         break;
3347                 case RSN_AKM_PSK:
3348                         brcmf_dbg(TRACE, "RSN_AKM_PSK\n");
3349                         is_rsn_ie ? (wpa_auth |= WPA2_AUTH_PSK) :
3350                                     (wpa_auth |= WPA_AUTH_PSK);
3351                         break;
3352                 default:
3353                         brcmf_err("Ivalid key mgmt info\n");
3354                 }
3355                 offset++;
3356         }
3357
3358         if (is_rsn_ie) {
3359                 wme_bss_disable = 1;
3360                 if ((offset + RSN_CAP_LEN) <= len) {
3361                         rsn_cap = data[offset] + (data[offset + 1] << 8);
3362                         if (rsn_cap & RSN_CAP_PTK_REPLAY_CNTR_MASK)
3363                                 wme_bss_disable = 0;
3364                 }
3365                 /* set wme_bss_disable to sync RSN Capabilities */
3366                 err = brcmf_fil_bsscfg_int_set(ifp, "wme_bss_disable",
3367                                                wme_bss_disable);
3368                 if (err < 0) {
3369                         brcmf_err("wme_bss_disable error %d\n", err);
3370                         goto exit;
3371                 }
3372         }
3373         /* FOR WPS , set SES_OW_ENABLED */
3374         wsec = (pval | gval | SES_OW_ENABLED);
3375
3376         /* set auth */
3377         err = brcmf_fil_bsscfg_int_set(ifp, "auth", auth);
3378         if (err < 0) {
3379                 brcmf_err("auth error %d\n", err);
3380                 goto exit;
3381         }
3382         /* set wsec */
3383         err = brcmf_fil_bsscfg_int_set(ifp, "wsec", wsec);
3384         if (err < 0) {
3385                 brcmf_err("wsec error %d\n", err);
3386                 goto exit;
3387         }
3388         /* set upper-layer auth */
3389         err = brcmf_fil_bsscfg_int_set(ifp, "wpa_auth", wpa_auth);
3390         if (err < 0) {
3391                 brcmf_err("wpa_auth error %d\n", err);
3392                 goto exit;
3393         }
3394
3395 exit:
3396         return err;
3397 }
3398
3399 static s32
3400 brcmf_parse_vndr_ies(const u8 *vndr_ie_buf, u32 vndr_ie_len,
3401                      struct parsed_vndr_ies *vndr_ies)
3402 {
3403         s32 err = 0;
3404         struct brcmf_vs_tlv *vndrie;
3405         struct brcmf_tlv *ie;
3406         struct parsed_vndr_ie_info *parsed_info;
3407         s32 remaining_len;
3408
3409         remaining_len = (s32)vndr_ie_len;
3410         memset(vndr_ies, 0, sizeof(*vndr_ies));
3411
3412         ie = (struct brcmf_tlv *)vndr_ie_buf;
3413         while (ie) {
3414                 if (ie->id != WLAN_EID_VENDOR_SPECIFIC)
3415                         goto next;
3416                 vndrie = (struct brcmf_vs_tlv *)ie;
3417                 /* len should be bigger than OUI length + one */
3418                 if (vndrie->len < (VS_IE_FIXED_HDR_LEN - TLV_HDR_LEN + 1)) {
3419                         brcmf_err("invalid vndr ie. length is too small %d\n",
3420                                   vndrie->len);
3421                         goto next;
3422                 }
3423                 /* if wpa or wme ie, do not add ie */
3424                 if (!memcmp(vndrie->oui, (u8 *)WPA_OUI, TLV_OUI_LEN) &&
3425                     ((vndrie->oui_type == WPA_OUI_TYPE) ||
3426                     (vndrie->oui_type == WME_OUI_TYPE))) {
3427                         brcmf_dbg(TRACE, "Found WPA/WME oui. Do not add it\n");
3428                         goto next;
3429                 }
3430
3431                 parsed_info = &vndr_ies->ie_info[vndr_ies->count];
3432
3433                 /* save vndr ie information */
3434                 parsed_info->ie_ptr = (char *)vndrie;
3435                 parsed_info->ie_len = vndrie->len + TLV_HDR_LEN;
3436                 memcpy(&parsed_info->vndrie, vndrie, sizeof(*vndrie));
3437
3438                 vndr_ies->count++;
3439
3440                 brcmf_dbg(TRACE, "** OUI %02x %02x %02x, type 0x%02x\n",
3441                           parsed_info->vndrie.oui[0],
3442                           parsed_info->vndrie.oui[1],
3443                           parsed_info->vndrie.oui[2],
3444                           parsed_info->vndrie.oui_type);
3445
3446                 if (vndr_ies->count >= VNDR_IE_PARSE_LIMIT)
3447                         break;
3448 next:
3449                 remaining_len -= (ie->len + TLV_HDR_LEN);
3450                 if (remaining_len <= TLV_HDR_LEN)
3451                         ie = NULL;
3452                 else
3453                         ie = (struct brcmf_tlv *)(((u8 *)ie) + ie->len +
3454                                 TLV_HDR_LEN);
3455         }
3456         return err;
3457 }
3458
3459 static u32
3460 brcmf_vndr_ie(u8 *iebuf, s32 pktflag, u8 *ie_ptr, u32 ie_len, s8 *add_del_cmd)
3461 {
3462
3463         __le32 iecount_le;
3464         __le32 pktflag_le;
3465
3466         strncpy(iebuf, add_del_cmd, VNDR_IE_CMD_LEN - 1);
3467         iebuf[VNDR_IE_CMD_LEN - 1] = '\0';
3468
3469         iecount_le = cpu_to_le32(1);
3470         memcpy(&iebuf[VNDR_IE_COUNT_OFFSET], &iecount_le, sizeof(iecount_le));
3471
3472         pktflag_le = cpu_to_le32(pktflag);
3473         memcpy(&iebuf[VNDR_IE_PKTFLAG_OFFSET], &pktflag_le, sizeof(pktflag_le));
3474
3475         memcpy(&iebuf[VNDR_IE_VSIE_OFFSET], ie_ptr, ie_len);
3476
3477         return ie_len + VNDR_IE_HDR_SIZE;
3478 }
3479
3480 s32 brcmf_vif_set_mgmt_ie(struct brcmf_cfg80211_vif *vif, s32 pktflag,
3481                           const u8 *vndr_ie_buf, u32 vndr_ie_len)
3482 {
3483         struct brcmf_if *ifp;
3484         struct vif_saved_ie *saved_ie;
3485         s32 err = 0;
3486         u8  *iovar_ie_buf;
3487         u8  *curr_ie_buf;
3488         u8  *mgmt_ie_buf = NULL;
3489         int mgmt_ie_buf_len;
3490         u32 *mgmt_ie_len;
3491         u32 del_add_ie_buf_len = 0;
3492         u32 total_ie_buf_len = 0;
3493         u32 parsed_ie_buf_len = 0;
3494         struct parsed_vndr_ies old_vndr_ies;
3495         struct parsed_vndr_ies new_vndr_ies;
3496         struct parsed_vndr_ie_info *vndrie_info;
3497         s32 i;
3498         u8 *ptr;
3499         int remained_buf_len;
3500
3501         if (!vif)
3502                 return -ENODEV;
3503         ifp = vif->ifp;
3504         saved_ie = &vif->saved_ie;
3505
3506         brcmf_dbg(TRACE, "bssidx %d, pktflag : 0x%02X\n", ifp->bssidx, pktflag);
3507         iovar_ie_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
3508         if (!iovar_ie_buf)
3509                 return -ENOMEM;
3510         curr_ie_buf = iovar_ie_buf;
3511         switch (pktflag) {
3512         case BRCMF_VNDR_IE_PRBREQ_FLAG:
3513                 mgmt_ie_buf = saved_ie->probe_req_ie;
3514                 mgmt_ie_len = &saved_ie->probe_req_ie_len;
3515                 mgmt_ie_buf_len = sizeof(saved_ie->probe_req_ie);
3516                 break;
3517         case BRCMF_VNDR_IE_PRBRSP_FLAG:
3518                 mgmt_ie_buf = saved_ie->probe_res_ie;
3519                 mgmt_ie_len = &saved_ie->probe_res_ie_len;
3520                 mgmt_ie_buf_len = sizeof(saved_ie->probe_res_ie);
3521                 break;
3522         case BRCMF_VNDR_IE_BEACON_FLAG:
3523                 mgmt_ie_buf = saved_ie->beacon_ie;
3524                 mgmt_ie_len = &saved_ie->beacon_ie_len;
3525                 mgmt_ie_buf_len = sizeof(saved_ie->beacon_ie);
3526                 break;
3527         case BRCMF_VNDR_IE_ASSOCREQ_FLAG:
3528                 mgmt_ie_buf = saved_ie->assoc_req_ie;
3529                 mgmt_ie_len = &saved_ie->assoc_req_ie_len;
3530                 mgmt_ie_buf_len = sizeof(saved_ie->assoc_req_ie);
3531                 break;
3532         default:
3533                 err = -EPERM;
3534                 brcmf_err("not suitable type\n");
3535                 goto exit;
3536         }
3537
3538         if (vndr_ie_len > mgmt_ie_buf_len) {
3539                 err = -ENOMEM;
3540                 brcmf_err("extra IE size too big\n");
3541                 goto exit;
3542         }
3543
3544         /* parse and save new vndr_ie in curr_ie_buff before comparing it */
3545         if (vndr_ie_buf && vndr_ie_len && curr_ie_buf) {
3546                 ptr = curr_ie_buf;
3547                 brcmf_parse_vndr_ies(vndr_ie_buf, vndr_ie_len, &new_vndr_ies);
3548                 for (i = 0; i < new_vndr_ies.count; i++) {
3549                         vndrie_info = &new_vndr_ies.ie_info[i];
3550                         memcpy(ptr + parsed_ie_buf_len, vndrie_info->ie_ptr,
3551                                vndrie_info->ie_len);
3552                         parsed_ie_buf_len += vndrie_info->ie_len;
3553                 }
3554         }
3555
3556         if (mgmt_ie_buf && *mgmt_ie_len) {
3557                 if (parsed_ie_buf_len && (parsed_ie_buf_len == *mgmt_ie_len) &&
3558                     (memcmp(mgmt_ie_buf, curr_ie_buf,
3559                             parsed_ie_buf_len) == 0)) {
3560                         brcmf_dbg(TRACE, "Previous mgmt IE equals to current IE\n");
3561                         goto exit;
3562                 }
3563
3564                 /* parse old vndr_ie */
3565                 brcmf_parse_vndr_ies(mgmt_ie_buf, *mgmt_ie_len, &old_vndr_ies);
3566
3567                 /* make a command to delete old ie */
3568                 for (i = 0; i < old_vndr_ies.count; i++) {
3569                         vndrie_info = &old_vndr_ies.ie_info[i];
3570
3571                         brcmf_dbg(TRACE, "DEL ID : %d, Len: %d , OUI:%02x:%02x:%02x\n",
3572                                   vndrie_info->vndrie.id,
3573                                   vndrie_info->vndrie.len,
3574                                   vndrie_info->vndrie.oui[0],
3575                                   vndrie_info->vndrie.oui[1],
3576                                   vndrie_info->vndrie.oui[2]);
3577
3578                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3579                                                            vndrie_info->ie_ptr,
3580                                                            vndrie_info->ie_len,
3581                                                            "del");
3582                         curr_ie_buf += del_add_ie_buf_len;
3583                         total_ie_buf_len += del_add_ie_buf_len;
3584                 }
3585         }
3586
3587         *mgmt_ie_len = 0;
3588         /* Add if there is any extra IE */
3589         if (mgmt_ie_buf && parsed_ie_buf_len) {
3590                 ptr = mgmt_ie_buf;
3591
3592                 remained_buf_len = mgmt_ie_buf_len;
3593
3594                 /* make a command to add new ie */
3595                 for (i = 0; i < new_vndr_ies.count; i++) {
3596                         vndrie_info = &new_vndr_ies.ie_info[i];
3597
3598                         /* verify remained buf size before copy data */
3599                         if (remained_buf_len < (vndrie_info->vndrie.len +
3600                                                         VNDR_IE_VSIE_OFFSET)) {
3601                                 brcmf_err("no space in mgmt_ie_buf: len left %d",
3602                                           remained_buf_len);
3603                                 break;
3604                         }
3605                         remained_buf_len -= (vndrie_info->ie_len +
3606                                              VNDR_IE_VSIE_OFFSET);
3607
3608                         brcmf_dbg(TRACE, "ADDED ID : %d, Len: %d, OUI:%02x:%02x:%02x\n",
3609                                   vndrie_info->vndrie.id,
3610                                   vndrie_info->vndrie.len,
3611                                   vndrie_info->vndrie.oui[0],
3612                                   vndrie_info->vndrie.oui[1],
3613                                   vndrie_info->vndrie.oui[2]);
3614
3615                         del_add_ie_buf_len = brcmf_vndr_ie(curr_ie_buf, pktflag,
3616                                                            vndrie_info->ie_ptr,
3617                                                            vndrie_info->ie_len,
3618                                                            "add");
3619
3620                         /* save the parsed IE in wl struct */
3621                         memcpy(ptr + (*mgmt_ie_len), vndrie_info->ie_ptr,
3622                                vndrie_info->ie_len);
3623                         *mgmt_ie_len += vndrie_info->ie_len;
3624
3625                         curr_ie_buf += del_add_ie_buf_len;
3626                         total_ie_buf_len += del_add_ie_buf_len;
3627                 }
3628         }
3629         if (total_ie_buf_len) {
3630                 err  = brcmf_fil_bsscfg_data_set(ifp, "vndr_ie", iovar_ie_buf,
3631                                                  total_ie_buf_len);
3632                 if (err)
3633                         brcmf_err("vndr ie set error : %d\n", err);
3634         }
3635
3636 exit:
3637         kfree(iovar_ie_buf);
3638         return err;
3639 }
3640
3641 s32 brcmf_vif_clear_mgmt_ies(struct brcmf_cfg80211_vif *vif)
3642 {
3643         s32 pktflags[] = {
3644                 BRCMF_VNDR_IE_PRBREQ_FLAG,
3645                 BRCMF_VNDR_IE_PRBRSP_FLAG,
3646                 BRCMF_VNDR_IE_BEACON_FLAG
3647         };
3648         int i;
3649
3650         for (i = 0; i < ARRAY_SIZE(pktflags); i++)
3651                 brcmf_vif_set_mgmt_ie(vif, pktflags[i], NULL, 0);
3652
3653         memset(&vif->saved_ie, 0, sizeof(vif->saved_ie));
3654         return 0;
3655 }
3656
3657 static s32
3658 brcmf_config_ap_mgmt_ie(struct brcmf_cfg80211_vif *vif,
3659                         struct cfg80211_beacon_data *beacon)
3660 {
3661         s32 err;
3662
3663         /* Set Beacon IEs to FW */
3664         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_BEACON_FLAG,
3665                                     beacon->tail, beacon->tail_len);
3666         if (err) {
3667                 brcmf_err("Set Beacon IE Failed\n");
3668                 return err;
3669         }
3670         brcmf_dbg(TRACE, "Applied Vndr IEs for Beacon\n");
3671
3672         /* Set Probe Response IEs to FW */
3673         err = brcmf_vif_set_mgmt_ie(vif, BRCMF_VNDR_IE_PRBRSP_FLAG,
3674                                     beacon->proberesp_ies,
3675                                     beacon->proberesp_ies_len);
3676         if (err)
3677                 brcmf_err("Set Probe Resp IE Failed\n");
3678         else
3679                 brcmf_dbg(TRACE, "Applied Vndr IEs for Probe Resp\n");
3680
3681         return err;
3682 }
3683
3684 static s32
3685 brcmf_cfg80211_set_channel(struct brcmf_cfg80211_info *cfg,
3686                            struct brcmf_if *ifp,
3687                            struct ieee80211_channel *channel)
3688 {
3689         u16 chanspec;
3690         s32 err;
3691
3692         brcmf_dbg(TRACE, "band=%d, center_freq=%d\n", channel->band,
3693                   channel->center_freq);
3694
3695         chanspec = channel_to_chanspec(&cfg->d11inf, channel);
3696         err = brcmf_fil_iovar_int_set(ifp, "chanspec", chanspec);
3697
3698         return err;
3699 }
3700
3701 static s32
3702 brcmf_cfg80211_start_ap(struct wiphy *wiphy, struct net_device *ndev,
3703                         struct cfg80211_ap_settings *settings)
3704 {
3705         s32 ie_offset;
3706         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3707         struct brcmf_if *ifp = netdev_priv(ndev);
3708         struct brcmf_tlv *ssid_ie;
3709         struct brcmf_ssid_le ssid_le;
3710         s32 err = -EPERM;
3711         struct brcmf_tlv *rsn_ie;
3712         struct brcmf_vs_tlv *wpa_ie;
3713         struct brcmf_join_params join_params;
3714         enum nl80211_iftype dev_role;
3715         struct brcmf_fil_bss_enable_le bss_enable;
3716
3717         brcmf_dbg(TRACE, "channel_type=%d, beacon_interval=%d, dtim_period=%d,\n",
3718                   cfg80211_get_chandef_type(&settings->chandef),
3719                   settings->beacon_interval,
3720                   settings->dtim_period);
3721         brcmf_dbg(TRACE, "ssid=%s(%zu), auth_type=%d, inactivity_timeout=%d\n",
3722                   settings->ssid, settings->ssid_len, settings->auth_type,
3723                   settings->inactivity_timeout);
3724
3725         dev_role = ifp->vif->wdev.iftype;
3726
3727         memset(&ssid_le, 0, sizeof(ssid_le));
3728         if (settings->ssid == NULL || settings->ssid_len == 0) {
3729                 ie_offset = DOT11_MGMT_HDR_LEN + DOT11_BCN_PRB_FIXED_LEN;
3730                 ssid_ie = brcmf_parse_tlvs(
3731                                 (u8 *)&settings->beacon.head[ie_offset],
3732                                 settings->beacon.head_len - ie_offset,
3733                                 WLAN_EID_SSID);
3734                 if (!ssid_ie)
3735                         return -EINVAL;
3736
3737                 memcpy(ssid_le.SSID, ssid_ie->data, ssid_ie->len);
3738                 ssid_le.SSID_len = cpu_to_le32(ssid_ie->len);
3739                 brcmf_dbg(TRACE, "SSID is (%s) in Head\n", ssid_le.SSID);
3740         } else {
3741                 memcpy(ssid_le.SSID, settings->ssid, settings->ssid_len);
3742                 ssid_le.SSID_len = cpu_to_le32((u32)settings->ssid_len);
3743         }
3744
3745         brcmf_set_mpc(ifp, 0);
3746         brcmf_configure_arp_offload(ifp, false);
3747
3748         /* find the RSN_IE */
3749         rsn_ie = brcmf_parse_tlvs((u8 *)settings->beacon.tail,
3750                                   settings->beacon.tail_len, WLAN_EID_RSN);
3751
3752         /* find the WPA_IE */
3753         wpa_ie = brcmf_find_wpaie((u8 *)settings->beacon.tail,
3754                                   settings->beacon.tail_len);
3755
3756         if ((wpa_ie != NULL || rsn_ie != NULL)) {
3757                 brcmf_dbg(TRACE, "WPA(2) IE is found\n");
3758                 if (wpa_ie != NULL) {
3759                         /* WPA IE */
3760                         err = brcmf_configure_wpaie(ndev, wpa_ie, false);
3761                         if (err < 0)
3762                                 goto exit;
3763                 } else {
3764                         /* RSN IE */
3765                         err = brcmf_configure_wpaie(ndev,
3766                                 (struct brcmf_vs_tlv *)rsn_ie, true);
3767                         if (err < 0)
3768                                 goto exit;
3769                 }
3770         } else {
3771                 brcmf_dbg(TRACE, "No WPA(2) IEs found\n");
3772                 brcmf_configure_opensecurity(ifp);
3773         }
3774
3775         brcmf_config_ap_mgmt_ie(ifp->vif, &settings->beacon);
3776
3777         err = brcmf_cfg80211_set_channel(cfg, ifp, settings->chandef.chan);
3778         if (err < 0) {
3779                 brcmf_err("Set Channel failed, %d\n", err);
3780                 goto exit;
3781         }
3782
3783         if (settings->beacon_interval) {
3784                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_BCNPRD,
3785                                             settings->beacon_interval);
3786                 if (err < 0) {
3787                         brcmf_err("Beacon Interval Set Error, %d\n", err);
3788                         goto exit;
3789                 }
3790         }
3791         if (settings->dtim_period) {
3792                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_DTIMPRD,
3793                                             settings->dtim_period);
3794                 if (err < 0) {
3795                         brcmf_err("DTIM Interval Set Error, %d\n", err);
3796                         goto exit;
3797                 }
3798         }
3799
3800         if (dev_role == NL80211_IFTYPE_AP) {
3801                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_DOWN, 1);
3802                 if (err < 0) {
3803                         brcmf_err("BRCMF_C_DOWN error %d\n", err);
3804                         goto exit;
3805                 }
3806                 brcmf_fil_iovar_int_set(ifp, "apsta", 0);
3807         }
3808
3809         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 1);
3810         if (err < 0) {
3811                 brcmf_err("SET INFRA error %d\n", err);
3812                 goto exit;
3813         }
3814         if (dev_role == NL80211_IFTYPE_AP) {
3815                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 1);
3816                 if (err < 0) {
3817                         brcmf_err("setting AP mode failed %d\n", err);
3818                         goto exit;
3819                 }
3820                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 1);
3821                 if (err < 0) {
3822                         brcmf_err("BRCMF_C_UP error (%d)\n", err);
3823                         goto exit;
3824                 }
3825
3826                 memset(&join_params, 0, sizeof(join_params));
3827                 /* join parameters starts with ssid */
3828                 memcpy(&join_params.ssid_le, &ssid_le, sizeof(ssid_le));
3829                 /* create softap */
3830                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3831                                              &join_params, sizeof(join_params));
3832                 if (err < 0) {
3833                         brcmf_err("SET SSID error (%d)\n", err);
3834                         goto exit;
3835                 }
3836                 brcmf_dbg(TRACE, "AP mode configuration complete\n");
3837         } else {
3838                 err = brcmf_fil_bsscfg_data_set(ifp, "ssid", &ssid_le,
3839                                                 sizeof(ssid_le));
3840                 if (err < 0) {
3841                         brcmf_err("setting ssid failed %d\n", err);
3842                         goto exit;
3843                 }
3844                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3845                 bss_enable.enable = cpu_to_le32(1);
3846                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3847                                                sizeof(bss_enable));
3848                 if (err < 0) {
3849                         brcmf_err("bss_enable config failed %d\n", err);
3850                         goto exit;
3851                 }
3852
3853                 brcmf_dbg(TRACE, "GO mode configuration complete\n");
3854         }
3855         clear_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3856         set_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3857
3858 exit:
3859         if (err) {
3860                 brcmf_set_mpc(ifp, 1);
3861                 brcmf_configure_arp_offload(ifp, true);
3862         }
3863         return err;
3864 }
3865
3866 static int brcmf_cfg80211_stop_ap(struct wiphy *wiphy, struct net_device *ndev)
3867 {
3868         struct brcmf_if *ifp = netdev_priv(ndev);
3869         s32 err;
3870         struct brcmf_fil_bss_enable_le bss_enable;
3871         struct brcmf_join_params join_params;
3872
3873         brcmf_dbg(TRACE, "Enter\n");
3874
3875         if (ifp->vif->wdev.iftype == NL80211_IFTYPE_AP) {
3876                 /* Due to most likely deauths outstanding we sleep */
3877                 /* first to make sure they get processed by fw. */
3878                 msleep(400);
3879
3880                 memset(&join_params, 0, sizeof(join_params));
3881                 err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_SSID,
3882                                              &join_params, sizeof(join_params));
3883                 if (err < 0)
3884                         brcmf_err("SET SSID error (%d)\n", err);
3885                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
3886                 if (err < 0)
3887                         brcmf_err("BRCMF_C_UP error %d\n", err);
3888                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_AP, 0);
3889                 if (err < 0)
3890                         brcmf_err("setting AP mode failed %d\n", err);
3891                 err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_INFRA, 0);
3892                 if (err < 0)
3893                         brcmf_err("setting INFRA mode failed %d\n", err);
3894         } else {
3895                 bss_enable.bsscfg_idx = cpu_to_le32(ifp->bssidx);
3896                 bss_enable.enable = cpu_to_le32(0);
3897                 err = brcmf_fil_iovar_data_set(ifp, "bss", &bss_enable,
3898                                                sizeof(bss_enable));
3899                 if (err < 0)
3900                         brcmf_err("bss_enable config failed %d\n", err);
3901         }
3902         brcmf_set_mpc(ifp, 1);
3903         brcmf_configure_arp_offload(ifp, true);
3904         set_bit(BRCMF_VIF_STATUS_AP_CREATING, &ifp->vif->sme_state);
3905         clear_bit(BRCMF_VIF_STATUS_AP_CREATED, &ifp->vif->sme_state);
3906
3907         return err;
3908 }
3909
3910 static s32
3911 brcmf_cfg80211_change_beacon(struct wiphy *wiphy, struct net_device *ndev,
3912                              struct cfg80211_beacon_data *info)
3913 {
3914         struct brcmf_if *ifp = netdev_priv(ndev);
3915         s32 err;
3916
3917         brcmf_dbg(TRACE, "Enter\n");
3918
3919         err = brcmf_config_ap_mgmt_ie(ifp->vif, info);
3920
3921         return err;
3922 }
3923
3924 static int
3925 brcmf_cfg80211_del_station(struct wiphy *wiphy, struct net_device *ndev,
3926                            u8 *mac)
3927 {
3928         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3929         struct brcmf_scb_val_le scbval;
3930         struct brcmf_if *ifp = netdev_priv(ndev);
3931         s32 err;
3932
3933         if (!mac)
3934                 return -EFAULT;
3935
3936         brcmf_dbg(TRACE, "Enter %pM\n", mac);
3937
3938         if (ifp->vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif)
3939                 ifp = cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif->ifp;
3940         if (!check_vif_up(ifp->vif))
3941                 return -EIO;
3942
3943         memcpy(&scbval.ea, mac, ETH_ALEN);
3944         scbval.val = cpu_to_le32(WLAN_REASON_DEAUTH_LEAVING);
3945         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SCB_DEAUTHENTICATE_FOR_REASON,
3946                                      &scbval, sizeof(scbval));
3947         if (err)
3948                 brcmf_err("SCB_DEAUTHENTICATE_FOR_REASON failed %d\n", err);
3949
3950         brcmf_dbg(TRACE, "Exit\n");
3951         return err;
3952 }
3953
3954
3955 static void
3956 brcmf_cfg80211_mgmt_frame_register(struct wiphy *wiphy,
3957                                    struct wireless_dev *wdev,
3958                                    u16 frame_type, bool reg)
3959 {
3960         struct brcmf_cfg80211_vif *vif;
3961         u16 mgmt_type;
3962
3963         brcmf_dbg(TRACE, "Enter, frame_type %04x, reg=%d\n", frame_type, reg);
3964
3965         mgmt_type = (frame_type & IEEE80211_FCTL_STYPE) >> 4;
3966         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
3967         if (reg)
3968                 vif->mgmt_rx_reg |= BIT(mgmt_type);
3969         else
3970                 vif->mgmt_rx_reg &= ~BIT(mgmt_type);
3971 }
3972
3973
3974 static int
3975 brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
3976                        struct cfg80211_mgmt_tx_params *params, u64 *cookie)
3977 {
3978         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
3979         struct ieee80211_channel *chan = params->chan;
3980         const u8 *buf = params->buf;
3981         size_t len = params->len;
3982         const struct ieee80211_mgmt *mgmt;
3983         struct brcmf_cfg80211_vif *vif;
3984         s32 err = 0;
3985         s32 ie_offset;
3986         s32 ie_len;
3987         struct brcmf_fil_action_frame_le *action_frame;
3988         struct brcmf_fil_af_params_le *af_params;
3989         bool ack;
3990         s32 chan_nr;
3991         u32 freq;
3992
3993         brcmf_dbg(TRACE, "Enter\n");
3994
3995         *cookie = 0;
3996
3997         mgmt = (const struct ieee80211_mgmt *)buf;
3998
3999         if (!ieee80211_is_mgmt(mgmt->frame_control)) {
4000                 brcmf_err("Driver only allows MGMT packet type\n");
4001                 return -EPERM;
4002         }
4003
4004         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4005
4006         if (ieee80211_is_probe_resp(mgmt->frame_control)) {
4007                 /* Right now the only reason to get a probe response */
4008                 /* is for p2p listen response or for p2p GO from     */
4009                 /* wpa_supplicant. Unfortunately the probe is send   */
4010                 /* on primary ndev, while dongle wants it on the p2p */
4011                 /* vif. Since this is only reason for a probe        */
4012                 /* response to be sent, the vif is taken from cfg.   */
4013                 /* If ever desired to send proberesp for non p2p     */
4014                 /* response then data should be checked for          */
4015                 /* "DIRECT-". Note in future supplicant will take    */
4016                 /* dedicated p2p wdev to do this and then this 'hack'*/
4017                 /* is not needed anymore.                            */
4018                 ie_offset =  DOT11_MGMT_HDR_LEN +
4019                              DOT11_BCN_PRB_FIXED_LEN;
4020                 ie_len = len - ie_offset;
4021                 if (vif == cfg->p2p.bss_idx[P2PAPI_BSSCFG_PRIMARY].vif)
4022                         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4023                 err = brcmf_vif_set_mgmt_ie(vif,
4024                                             BRCMF_VNDR_IE_PRBRSP_FLAG,
4025                                             &buf[ie_offset],
4026                                             ie_len);
4027                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, true,
4028                                         GFP_KERNEL);
4029         } else if (ieee80211_is_action(mgmt->frame_control)) {
4030                 af_params = kzalloc(sizeof(*af_params), GFP_KERNEL);
4031                 if (af_params == NULL) {
4032                         brcmf_err("unable to allocate frame\n");
4033                         err = -ENOMEM;
4034                         goto exit;
4035                 }
4036                 action_frame = &af_params->action_frame;
4037                 /* Add the packet Id */
4038                 action_frame->packet_id = cpu_to_le32(*cookie);
4039                 /* Add BSSID */
4040                 memcpy(&action_frame->da[0], &mgmt->da[0], ETH_ALEN);
4041                 memcpy(&af_params->bssid[0], &mgmt->bssid[0], ETH_ALEN);
4042                 /* Add the length exepted for 802.11 header  */
4043                 action_frame->len = cpu_to_le16(len - DOT11_MGMT_HDR_LEN);
4044                 /* Add the channel. Use the one specified as parameter if any or
4045                  * the current one (got from the firmware) otherwise
4046                  */
4047                 if (chan)
4048                         freq = chan->center_freq;
4049                 else
4050                         brcmf_fil_cmd_int_get(vif->ifp, BRCMF_C_GET_CHANNEL,
4051                                               &freq);
4052                 chan_nr = ieee80211_frequency_to_channel(freq);
4053                 af_params->channel = cpu_to_le32(chan_nr);
4054
4055                 memcpy(action_frame->data, &buf[DOT11_MGMT_HDR_LEN],
4056                        le16_to_cpu(action_frame->len));
4057
4058                 brcmf_dbg(TRACE, "Action frame, cookie=%lld, len=%d, freq=%d\n",
4059                           *cookie, le16_to_cpu(action_frame->len), freq);
4060
4061                 ack = brcmf_p2p_send_action_frame(cfg, cfg_to_ndev(cfg),
4062                                                   af_params);
4063
4064                 cfg80211_mgmt_tx_status(wdev, *cookie, buf, len, ack,
4065                                         GFP_KERNEL);
4066                 kfree(af_params);
4067         } else {
4068                 brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control);
4069                 brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len);
4070         }
4071
4072 exit:
4073         return err;
4074 }
4075
4076
4077 static int
4078 brcmf_cfg80211_cancel_remain_on_channel(struct wiphy *wiphy,
4079                                         struct wireless_dev *wdev,
4080                                         u64 cookie)
4081 {
4082         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4083         struct brcmf_cfg80211_vif *vif;
4084         int err = 0;
4085
4086         brcmf_dbg(TRACE, "Enter p2p listen cancel\n");
4087
4088         vif = cfg->p2p.bss_idx[P2PAPI_BSSCFG_DEVICE].vif;
4089         if (vif == NULL) {
4090                 brcmf_err("No p2p device available for probe response\n");
4091                 err = -ENODEV;
4092                 goto exit;
4093         }
4094         brcmf_p2p_cancel_remain_on_channel(vif->ifp);
4095 exit:
4096         return err;
4097 }
4098
4099 static int brcmf_cfg80211_crit_proto_start(struct wiphy *wiphy,
4100                                            struct wireless_dev *wdev,
4101                                            enum nl80211_crit_proto_id proto,
4102                                            u16 duration)
4103 {
4104         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4105         struct brcmf_cfg80211_vif *vif;
4106
4107         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4108
4109         /* only DHCP support for now */
4110         if (proto != NL80211_CRIT_PROTO_DHCP)
4111                 return -EINVAL;
4112
4113         /* suppress and abort scanning */
4114         set_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4115         brcmf_abort_scanning(cfg);
4116
4117         return brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_DISABLED, duration);
4118 }
4119
4120 static void brcmf_cfg80211_crit_proto_stop(struct wiphy *wiphy,
4121                                            struct wireless_dev *wdev)
4122 {
4123         struct brcmf_cfg80211_info *cfg = wiphy_to_cfg(wiphy);
4124         struct brcmf_cfg80211_vif *vif;
4125
4126         vif = container_of(wdev, struct brcmf_cfg80211_vif, wdev);
4127
4128         brcmf_btcoex_set_mode(vif, BRCMF_BTCOEX_ENABLED, 0);
4129         clear_bit(BRCMF_SCAN_STATUS_SUPPRESS, &cfg->scan_status);
4130 }
4131
4132 static int brcmf_convert_nl80211_tdls_oper(enum nl80211_tdls_operation oper)
4133 {
4134         int ret;
4135
4136         switch (oper) {
4137         case NL80211_TDLS_DISCOVERY_REQ:
4138                 ret = BRCMF_TDLS_MANUAL_EP_DISCOVERY;
4139                 break;
4140         case NL80211_TDLS_SETUP:
4141                 ret = BRCMF_TDLS_MANUAL_EP_CREATE;
4142                 break;
4143         case NL80211_TDLS_TEARDOWN:
4144                 ret = BRCMF_TDLS_MANUAL_EP_DELETE;
4145                 break;
4146         default:
4147                 brcmf_err("unsupported operation: %d\n", oper);
4148                 ret = -EOPNOTSUPP;
4149         }
4150         return ret;
4151 }
4152
4153 static int brcmf_cfg80211_tdls_oper(struct wiphy *wiphy,
4154                                     struct net_device *ndev, u8 *peer,
4155                                     enum nl80211_tdls_operation oper)
4156 {
4157         struct brcmf_if *ifp;
4158         struct brcmf_tdls_iovar_le info;
4159         int ret = 0;
4160
4161         ret = brcmf_convert_nl80211_tdls_oper(oper);
4162         if (ret < 0)
4163                 return ret;
4164
4165         ifp = netdev_priv(ndev);
4166         memset(&info, 0, sizeof(info));
4167         info.mode = (u8)ret;
4168         if (peer)
4169                 memcpy(info.ea, peer, ETH_ALEN);
4170
4171         ret = brcmf_fil_iovar_data_set(ifp, "tdls_endpoint",
4172                                        &info, sizeof(info));
4173         if (ret < 0)
4174                 brcmf_err("tdls_endpoint iovar failed: ret=%d\n", ret);
4175
4176         return ret;
4177 }
4178
4179 static struct cfg80211_ops wl_cfg80211_ops = {
4180         .add_virtual_intf = brcmf_cfg80211_add_iface,
4181         .del_virtual_intf = brcmf_cfg80211_del_iface,
4182         .change_virtual_intf = brcmf_cfg80211_change_iface,
4183         .scan = brcmf_cfg80211_scan,
4184         .set_wiphy_params = brcmf_cfg80211_set_wiphy_params,
4185         .join_ibss = brcmf_cfg80211_join_ibss,
4186         .leave_ibss = brcmf_cfg80211_leave_ibss,
4187         .get_station = brcmf_cfg80211_get_station,
4188         .set_tx_power = brcmf_cfg80211_set_tx_power,
4189         .get_tx_power = brcmf_cfg80211_get_tx_power,
4190         .add_key = brcmf_cfg80211_add_key,
4191         .del_key = brcmf_cfg80211_del_key,
4192         .get_key = brcmf_cfg80211_get_key,
4193         .set_default_key = brcmf_cfg80211_config_default_key,
4194         .set_default_mgmt_key = brcmf_cfg80211_config_default_mgmt_key,
4195         .set_power_mgmt = brcmf_cfg80211_set_power_mgmt,
4196         .connect = brcmf_cfg80211_connect,
4197         .disconnect = brcmf_cfg80211_disconnect,
4198         .suspend = brcmf_cfg80211_suspend,
4199         .resume = brcmf_cfg80211_resume,
4200         .set_pmksa = brcmf_cfg80211_set_pmksa,
4201         .del_pmksa = brcmf_cfg80211_del_pmksa,
4202         .flush_pmksa = brcmf_cfg80211_flush_pmksa,
4203         .start_ap = brcmf_cfg80211_start_ap,
4204         .stop_ap = brcmf_cfg80211_stop_ap,
4205         .change_beacon = brcmf_cfg80211_change_beacon,
4206         .del_station = brcmf_cfg80211_del_station,
4207         .sched_scan_start = brcmf_cfg80211_sched_scan_start,
4208         .sched_scan_stop = brcmf_cfg80211_sched_scan_stop,
4209         .mgmt_frame_register = brcmf_cfg80211_mgmt_frame_register,
4210         .mgmt_tx = brcmf_cfg80211_mgmt_tx,
4211         .remain_on_channel = brcmf_p2p_remain_on_channel,
4212         .cancel_remain_on_channel = brcmf_cfg80211_cancel_remain_on_channel,
4213         .start_p2p_device = brcmf_p2p_start_device,
4214         .stop_p2p_device = brcmf_p2p_stop_device,
4215         .crit_proto_start = brcmf_cfg80211_crit_proto_start,
4216         .crit_proto_stop = brcmf_cfg80211_crit_proto_stop,
4217         .tdls_oper = brcmf_cfg80211_tdls_oper,
4218         CFG80211_TESTMODE_CMD(brcmf_cfg80211_testmode)
4219 };
4220
4221 static s32 brcmf_nl80211_iftype_to_mode(enum nl80211_iftype type)
4222 {
4223         switch (type) {
4224         case NL80211_IFTYPE_AP_VLAN:
4225         case NL80211_IFTYPE_WDS:
4226         case NL80211_IFTYPE_MONITOR:
4227         case NL80211_IFTYPE_MESH_POINT:
4228                 return -ENOTSUPP;
4229         case NL80211_IFTYPE_ADHOC:
4230                 return WL_MODE_IBSS;
4231         case NL80211_IFTYPE_STATION:
4232         case NL80211_IFTYPE_P2P_CLIENT:
4233                 return WL_MODE_BSS;
4234         case NL80211_IFTYPE_AP:
4235         case NL80211_IFTYPE_P2P_GO:
4236                 return WL_MODE_AP;
4237         case NL80211_IFTYPE_P2P_DEVICE:
4238                 return WL_MODE_P2P;
4239         case NL80211_IFTYPE_UNSPECIFIED:
4240         default:
4241                 break;
4242         }
4243
4244         return -EINVAL;
4245 }
4246
4247 static void brcmf_wiphy_pno_params(struct wiphy *wiphy)
4248 {
4249         /* scheduled scan settings */
4250         wiphy->max_sched_scan_ssids = BRCMF_PNO_MAX_PFN_COUNT;
4251         wiphy->max_match_sets = BRCMF_PNO_MAX_PFN_COUNT;
4252         wiphy->max_sched_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4253         wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
4254 }
4255
4256 static const struct ieee80211_iface_limit brcmf_iface_limits[] = {
4257         {
4258                 .max = 2,
4259                 .types = BIT(NL80211_IFTYPE_STATION) |
4260                          BIT(NL80211_IFTYPE_ADHOC) |
4261                          BIT(NL80211_IFTYPE_AP)
4262         },
4263         {
4264                 .max = 1,
4265                 .types = BIT(NL80211_IFTYPE_P2P_CLIENT) |
4266                          BIT(NL80211_IFTYPE_P2P_GO)
4267         },
4268         {
4269                 .max = 1,
4270                 .types = BIT(NL80211_IFTYPE_P2P_DEVICE)
4271         }
4272 };
4273 static const struct ieee80211_iface_combination brcmf_iface_combos[] = {
4274         {
4275                  .max_interfaces = BRCMF_IFACE_MAX_CNT,
4276                  .num_different_channels = 2,
4277                  .n_limits = ARRAY_SIZE(brcmf_iface_limits),
4278                  .limits = brcmf_iface_limits
4279         }
4280 };
4281
4282 static const struct ieee80211_txrx_stypes
4283 brcmf_txrx_stypes[NUM_NL80211_IFTYPES] = {
4284         [NL80211_IFTYPE_STATION] = {
4285                 .tx = 0xffff,
4286                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4287                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4288         },
4289         [NL80211_IFTYPE_P2P_CLIENT] = {
4290                 .tx = 0xffff,
4291                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4292                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4293         },
4294         [NL80211_IFTYPE_P2P_GO] = {
4295                 .tx = 0xffff,
4296                 .rx = BIT(IEEE80211_STYPE_ASSOC_REQ >> 4) |
4297                       BIT(IEEE80211_STYPE_REASSOC_REQ >> 4) |
4298                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4) |
4299                       BIT(IEEE80211_STYPE_DISASSOC >> 4) |
4300                       BIT(IEEE80211_STYPE_AUTH >> 4) |
4301                       BIT(IEEE80211_STYPE_DEAUTH >> 4) |
4302                       BIT(IEEE80211_STYPE_ACTION >> 4)
4303         },
4304         [NL80211_IFTYPE_P2P_DEVICE] = {
4305                 .tx = 0xffff,
4306                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
4307                       BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
4308         }
4309 };
4310
4311 static struct wiphy *brcmf_setup_wiphy(struct device *phydev)
4312 {
4313         struct wiphy *wiphy;
4314         s32 err = 0;
4315
4316         wiphy = wiphy_new(&wl_cfg80211_ops, sizeof(struct brcmf_cfg80211_info));
4317         if (!wiphy) {
4318                 brcmf_err("Could not allocate wiphy device\n");
4319                 return ERR_PTR(-ENOMEM);
4320         }
4321         set_wiphy_dev(wiphy, phydev);
4322         wiphy->max_scan_ssids = WL_NUM_SCAN_MAX;
4323         wiphy->max_scan_ie_len = BRCMF_SCAN_IE_LEN_MAX;
4324         wiphy->max_num_pmkids = WL_NUM_PMKIDS_MAX;
4325         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
4326                                  BIT(NL80211_IFTYPE_ADHOC) |
4327                                  BIT(NL80211_IFTYPE_AP) |
4328                                  BIT(NL80211_IFTYPE_P2P_CLIENT) |
4329                                  BIT(NL80211_IFTYPE_P2P_GO) |
4330                                  BIT(NL80211_IFTYPE_P2P_DEVICE);
4331         wiphy->iface_combinations = brcmf_iface_combos;
4332         wiphy->n_iface_combinations = ARRAY_SIZE(brcmf_iface_combos);
4333         wiphy->bands[IEEE80211_BAND_2GHZ] = &__wl_band_2ghz;
4334         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
4335         wiphy->cipher_suites = __wl_cipher_suites;
4336         wiphy->n_cipher_suites = ARRAY_SIZE(__wl_cipher_suites);
4337         wiphy->flags |= WIPHY_FLAG_PS_ON_BY_DEFAULT |
4338                         WIPHY_FLAG_OFFCHAN_TX |
4339                         WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
4340                         WIPHY_FLAG_SUPPORTS_TDLS;
4341         wiphy->mgmt_stypes = brcmf_txrx_stypes;
4342         wiphy->max_remain_on_channel_duration = 5000;
4343         brcmf_wiphy_pno_params(wiphy);
4344         brcmf_dbg(INFO, "Registering custom regulatory\n");
4345         wiphy->regulatory_flags |= REGULATORY_CUSTOM_REG;
4346         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
4347         err = wiphy_register(wiphy);
4348         if (err < 0) {
4349                 brcmf_err("Could not register wiphy device (%d)\n", err);
4350                 wiphy_free(wiphy);
4351                 return ERR_PTR(err);
4352         }
4353         return wiphy;
4354 }
4355
4356 struct brcmf_cfg80211_vif *brcmf_alloc_vif(struct brcmf_cfg80211_info *cfg,
4357                                            enum nl80211_iftype type,
4358                                            bool pm_block)
4359 {
4360         struct brcmf_cfg80211_vif *vif;
4361
4362         if (cfg->vif_cnt == BRCMF_IFACE_MAX_CNT)
4363                 return ERR_PTR(-ENOSPC);
4364
4365         brcmf_dbg(TRACE, "allocating virtual interface (size=%zu)\n",
4366                   sizeof(*vif));
4367         vif = kzalloc(sizeof(*vif), GFP_KERNEL);
4368         if (!vif)
4369                 return ERR_PTR(-ENOMEM);
4370
4371         vif->wdev.wiphy = cfg->wiphy;
4372         vif->wdev.iftype = type;
4373
4374         vif->mode = brcmf_nl80211_iftype_to_mode(type);
4375         vif->pm_block = pm_block;
4376         vif->roam_off = -1;
4377
4378         brcmf_init_prof(&vif->profile);
4379
4380         list_add_tail(&vif->list, &cfg->vif_list);
4381         cfg->vif_cnt++;
4382         return vif;
4383 }
4384
4385 void brcmf_free_vif(struct brcmf_cfg80211_info *cfg,
4386                     struct brcmf_cfg80211_vif *vif)
4387 {
4388         list_del(&vif->list);
4389         cfg->vif_cnt--;
4390
4391         kfree(vif);
4392         if (!cfg->vif_cnt) {
4393                 wiphy_unregister(cfg->wiphy);
4394                 wiphy_free(cfg->wiphy);
4395         }
4396 }
4397
4398 static bool brcmf_is_linkup(const struct brcmf_event_msg *e)
4399 {
4400         u32 event = e->event_code;
4401         u32 status = e->status;
4402
4403         if (event == BRCMF_E_SET_SSID && status == BRCMF_E_STATUS_SUCCESS) {
4404                 brcmf_dbg(CONN, "Processing set ssid\n");
4405                 return true;
4406         }
4407
4408         return false;
4409 }
4410
4411 static bool brcmf_is_linkdown(const struct brcmf_event_msg *e)
4412 {
4413         u32 event = e->event_code;
4414         u16 flags = e->flags;
4415
4416         if (event == BRCMF_E_LINK && (!(flags & BRCMF_EVENT_MSG_LINK))) {
4417                 brcmf_dbg(CONN, "Processing link down\n");
4418                 return true;
4419         }
4420         return false;
4421 }
4422
4423 static bool brcmf_is_nonetwork(struct brcmf_cfg80211_info *cfg,
4424                                const struct brcmf_event_msg *e)
4425 {
4426         u32 event = e->event_code;
4427         u32 status = e->status;
4428
4429         if (event == BRCMF_E_LINK && status == BRCMF_E_STATUS_NO_NETWORKS) {
4430                 brcmf_dbg(CONN, "Processing Link %s & no network found\n",
4431                           e->flags & BRCMF_EVENT_MSG_LINK ? "up" : "down");
4432                 return true;
4433         }
4434
4435         if (event == BRCMF_E_SET_SSID && status != BRCMF_E_STATUS_SUCCESS) {
4436                 brcmf_dbg(CONN, "Processing connecting & no network found\n");
4437                 return true;
4438         }
4439
4440         return false;
4441 }
4442
4443 static void brcmf_clear_assoc_ies(struct brcmf_cfg80211_info *cfg)
4444 {
4445         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4446
4447         kfree(conn_info->req_ie);
4448         conn_info->req_ie = NULL;
4449         conn_info->req_ie_len = 0;
4450         kfree(conn_info->resp_ie);
4451         conn_info->resp_ie = NULL;
4452         conn_info->resp_ie_len = 0;
4453 }
4454
4455 static s32 brcmf_get_assoc_ies(struct brcmf_cfg80211_info *cfg,
4456                                struct brcmf_if *ifp)
4457 {
4458         struct brcmf_cfg80211_assoc_ielen_le *assoc_info;
4459         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4460         u32 req_len;
4461         u32 resp_len;
4462         s32 err = 0;
4463
4464         brcmf_clear_assoc_ies(cfg);
4465
4466         err = brcmf_fil_iovar_data_get(ifp, "assoc_info",
4467                                        cfg->extra_buf, WL_ASSOC_INFO_MAX);
4468         if (err) {
4469                 brcmf_err("could not get assoc info (%d)\n", err);
4470                 return err;
4471         }
4472         assoc_info =
4473                 (struct brcmf_cfg80211_assoc_ielen_le *)cfg->extra_buf;
4474         req_len = le32_to_cpu(assoc_info->req_len);
4475         resp_len = le32_to_cpu(assoc_info->resp_len);
4476         if (req_len) {
4477                 err = brcmf_fil_iovar_data_get(ifp, "assoc_req_ies",
4478                                                cfg->extra_buf,
4479                                                WL_ASSOC_INFO_MAX);
4480                 if (err) {
4481                         brcmf_err("could not get assoc req (%d)\n", err);
4482                         return err;
4483                 }
4484                 conn_info->req_ie_len = req_len;
4485                 conn_info->req_ie =
4486                     kmemdup(cfg->extra_buf, conn_info->req_ie_len,
4487                             GFP_KERNEL);
4488         } else {
4489                 conn_info->req_ie_len = 0;
4490                 conn_info->req_ie = NULL;
4491         }
4492         if (resp_len) {
4493                 err = brcmf_fil_iovar_data_get(ifp, "assoc_resp_ies",
4494                                                cfg->extra_buf,
4495                                                WL_ASSOC_INFO_MAX);
4496                 if (err) {
4497                         brcmf_err("could not get assoc resp (%d)\n", err);
4498                         return err;
4499                 }
4500                 conn_info->resp_ie_len = resp_len;
4501                 conn_info->resp_ie =
4502                     kmemdup(cfg->extra_buf, conn_info->resp_ie_len,
4503                             GFP_KERNEL);
4504         } else {
4505                 conn_info->resp_ie_len = 0;
4506                 conn_info->resp_ie = NULL;
4507         }
4508         brcmf_dbg(CONN, "req len (%d) resp len (%d)\n",
4509                   conn_info->req_ie_len, conn_info->resp_ie_len);
4510
4511         return err;
4512 }
4513
4514 static s32
4515 brcmf_bss_roaming_done(struct brcmf_cfg80211_info *cfg,
4516                        struct net_device *ndev,
4517                        const struct brcmf_event_msg *e)
4518 {
4519         struct brcmf_if *ifp = netdev_priv(ndev);
4520         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4521         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4522         struct wiphy *wiphy = cfg_to_wiphy(cfg);
4523         struct ieee80211_channel *notify_channel = NULL;
4524         struct ieee80211_supported_band *band;
4525         struct brcmf_bss_info_le *bi;
4526         struct brcmu_chan ch;
4527         u32 freq;
4528         s32 err = 0;
4529         u8 *buf;
4530
4531         brcmf_dbg(TRACE, "Enter\n");
4532
4533         brcmf_get_assoc_ies(cfg, ifp);
4534         memcpy(profile->bssid, e->addr, ETH_ALEN);
4535         brcmf_update_bss_info(cfg, ifp);
4536
4537         buf = kzalloc(WL_BSS_INFO_MAX, GFP_KERNEL);
4538         if (buf == NULL) {
4539                 err = -ENOMEM;
4540                 goto done;
4541         }
4542
4543         /* data sent to dongle has to be little endian */
4544         *(__le32 *)buf = cpu_to_le32(WL_BSS_INFO_MAX);
4545         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BSS_INFO,
4546                                      buf, WL_BSS_INFO_MAX);
4547
4548         if (err)
4549                 goto done;
4550
4551         bi = (struct brcmf_bss_info_le *)(buf + 4);
4552         ch.chspec = le16_to_cpu(bi->chanspec);
4553         cfg->d11inf.decchspec(&ch);
4554
4555         if (ch.band == BRCMU_CHAN_BAND_2G)
4556                 band = wiphy->bands[IEEE80211_BAND_2GHZ];
4557         else
4558                 band = wiphy->bands[IEEE80211_BAND_5GHZ];
4559
4560         freq = ieee80211_channel_to_frequency(ch.chnum, band->band);
4561         notify_channel = ieee80211_get_channel(wiphy, freq);
4562
4563 done:
4564         kfree(buf);
4565         cfg80211_roamed(ndev, notify_channel, (u8 *)profile->bssid,
4566                         conn_info->req_ie, conn_info->req_ie_len,
4567                         conn_info->resp_ie, conn_info->resp_ie_len, GFP_KERNEL);
4568         brcmf_dbg(CONN, "Report roaming result\n");
4569
4570         set_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state);
4571         brcmf_dbg(TRACE, "Exit\n");
4572         return err;
4573 }
4574
4575 static s32
4576 brcmf_bss_connect_done(struct brcmf_cfg80211_info *cfg,
4577                        struct net_device *ndev, const struct brcmf_event_msg *e,
4578                        bool completed)
4579 {
4580         struct brcmf_if *ifp = netdev_priv(ndev);
4581         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4582         struct brcmf_cfg80211_connect_info *conn_info = cfg_to_conn(cfg);
4583         s32 err = 0;
4584
4585         brcmf_dbg(TRACE, "Enter\n");
4586
4587         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4588                                &ifp->vif->sme_state)) {
4589                 if (completed) {
4590                         brcmf_get_assoc_ies(cfg, ifp);
4591                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4592                         brcmf_update_bss_info(cfg, ifp);
4593                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4594                                 &ifp->vif->sme_state);
4595                 }
4596                 cfg80211_connect_result(ndev,
4597                                         (u8 *)profile->bssid,
4598                                         conn_info->req_ie,
4599                                         conn_info->req_ie_len,
4600                                         conn_info->resp_ie,
4601                                         conn_info->resp_ie_len,
4602                                         completed ? WLAN_STATUS_SUCCESS :
4603                                                     WLAN_STATUS_AUTH_TIMEOUT,
4604                                         GFP_KERNEL);
4605                 brcmf_dbg(CONN, "Report connect result - connection %s\n",
4606                           completed ? "succeeded" : "failed");
4607         }
4608         brcmf_dbg(TRACE, "Exit\n");
4609         return err;
4610 }
4611
4612 static s32
4613 brcmf_notify_connect_status_ap(struct brcmf_cfg80211_info *cfg,
4614                                struct net_device *ndev,
4615                                const struct brcmf_event_msg *e, void *data)
4616 {
4617         static int generation;
4618         u32 event = e->event_code;
4619         u32 reason = e->reason;
4620         struct station_info sinfo;
4621
4622         brcmf_dbg(CONN, "event %d, reason %d\n", event, reason);
4623         if (event == BRCMF_E_LINK && reason == BRCMF_E_REASON_LINK_BSSCFG_DIS &&
4624             ndev != cfg_to_ndev(cfg)) {
4625                 brcmf_dbg(CONN, "AP mode link down\n");
4626                 complete(&cfg->vif_disabled);
4627                 return 0;
4628         }
4629
4630         if (((event == BRCMF_E_ASSOC_IND) || (event == BRCMF_E_REASSOC_IND)) &&
4631             (reason == BRCMF_E_STATUS_SUCCESS)) {
4632                 memset(&sinfo, 0, sizeof(sinfo));
4633                 sinfo.filled = STATION_INFO_ASSOC_REQ_IES;
4634                 if (!data) {
4635                         brcmf_err("No IEs present in ASSOC/REASSOC_IND");
4636                         return -EINVAL;
4637                 }
4638                 sinfo.assoc_req_ies = data;
4639                 sinfo.assoc_req_ies_len = e->datalen;
4640                 generation++;
4641                 sinfo.generation = generation;
4642                 cfg80211_new_sta(ndev, e->addr, &sinfo, GFP_KERNEL);
4643         } else if ((event == BRCMF_E_DISASSOC_IND) ||
4644                    (event == BRCMF_E_DEAUTH_IND) ||
4645                    (event == BRCMF_E_DEAUTH)) {
4646                 cfg80211_del_sta(ndev, e->addr, GFP_KERNEL);
4647         }
4648         return 0;
4649 }
4650
4651 static s32
4652 brcmf_notify_connect_status(struct brcmf_if *ifp,
4653                             const struct brcmf_event_msg *e, void *data)
4654 {
4655         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4656         struct net_device *ndev = ifp->ndev;
4657         struct brcmf_cfg80211_profile *profile = &ifp->vif->profile;
4658         s32 err = 0;
4659
4660         if (ifp->vif->mode == WL_MODE_AP) {
4661                 err = brcmf_notify_connect_status_ap(cfg, ndev, e, data);
4662         } else if (brcmf_is_linkup(e)) {
4663                 brcmf_dbg(CONN, "Linkup\n");
4664                 if (brcmf_is_ibssmode(ifp->vif)) {
4665                         memcpy(profile->bssid, e->addr, ETH_ALEN);
4666                         wl_inform_ibss(cfg, ndev, e->addr);
4667                         cfg80211_ibss_joined(ndev, e->addr, GFP_KERNEL);
4668                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4669                                   &ifp->vif->sme_state);
4670                         set_bit(BRCMF_VIF_STATUS_CONNECTED,
4671                                 &ifp->vif->sme_state);
4672                 } else
4673                         brcmf_bss_connect_done(cfg, ndev, e, true);
4674         } else if (brcmf_is_linkdown(e)) {
4675                 brcmf_dbg(CONN, "Linkdown\n");
4676                 if (!brcmf_is_ibssmode(ifp->vif)) {
4677                         brcmf_bss_connect_done(cfg, ndev, e, false);
4678                         if (test_and_clear_bit(BRCMF_VIF_STATUS_CONNECTED,
4679                                                &ifp->vif->sme_state))
4680                                 cfg80211_disconnected(ndev, 0, NULL, 0,
4681                                                       GFP_KERNEL);
4682                 }
4683                 brcmf_link_down(ifp->vif);
4684                 brcmf_init_prof(ndev_to_prof(ndev));
4685                 if (ndev != cfg_to_ndev(cfg))
4686                         complete(&cfg->vif_disabled);
4687         } else if (brcmf_is_nonetwork(cfg, e)) {
4688                 if (brcmf_is_ibssmode(ifp->vif))
4689                         clear_bit(BRCMF_VIF_STATUS_CONNECTING,
4690                                   &ifp->vif->sme_state);
4691                 else
4692                         brcmf_bss_connect_done(cfg, ndev, e, false);
4693         }
4694
4695         return err;
4696 }
4697
4698 static s32
4699 brcmf_notify_roaming_status(struct brcmf_if *ifp,
4700                             const struct brcmf_event_msg *e, void *data)
4701 {
4702         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4703         s32 err = 0;
4704         u32 event = e->event_code;
4705         u32 status = e->status;
4706
4707         if (event == BRCMF_E_ROAM && status == BRCMF_E_STATUS_SUCCESS) {
4708                 if (test_bit(BRCMF_VIF_STATUS_CONNECTED, &ifp->vif->sme_state))
4709                         brcmf_bss_roaming_done(cfg, ifp->ndev, e);
4710                 else
4711                         brcmf_bss_connect_done(cfg, ifp->ndev, e, true);
4712         }
4713
4714         return err;
4715 }
4716
4717 static s32
4718 brcmf_notify_mic_status(struct brcmf_if *ifp,
4719                         const struct brcmf_event_msg *e, void *data)
4720 {
4721         u16 flags = e->flags;
4722         enum nl80211_key_type key_type;
4723
4724         if (flags & BRCMF_EVENT_MSG_GROUP)
4725                 key_type = NL80211_KEYTYPE_GROUP;
4726         else
4727                 key_type = NL80211_KEYTYPE_PAIRWISE;
4728
4729         cfg80211_michael_mic_failure(ifp->ndev, (u8 *)&e->addr, key_type, -1,
4730                                      NULL, GFP_KERNEL);
4731
4732         return 0;
4733 }
4734
4735 static s32 brcmf_notify_vif_event(struct brcmf_if *ifp,
4736                                   const struct brcmf_event_msg *e, void *data)
4737 {
4738         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
4739         struct brcmf_if_event *ifevent = (struct brcmf_if_event *)data;
4740         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
4741         struct brcmf_cfg80211_vif *vif;
4742
4743         brcmf_dbg(TRACE, "Enter: action %u flags %u ifidx %u bsscfg %u\n",
4744                   ifevent->action, ifevent->flags, ifevent->ifidx,
4745                   ifevent->bssidx);
4746
4747         mutex_lock(&event->vif_event_lock);
4748         event->action = ifevent->action;
4749         vif = event->vif;
4750
4751         switch (ifevent->action) {
4752         case BRCMF_E_IF_ADD:
4753                 /* waiting process may have timed out */
4754                 if (!cfg->vif_event.vif) {
4755                         mutex_unlock(&event->vif_event_lock);
4756                         return -EBADF;
4757                 }
4758
4759                 ifp->vif = vif;
4760                 vif->ifp = ifp;
4761                 if (ifp->ndev) {
4762                         vif->wdev.netdev = ifp->ndev;
4763                         ifp->ndev->ieee80211_ptr = &vif->wdev;
4764                         SET_NETDEV_DEV(ifp->ndev, wiphy_dev(cfg->wiphy));
4765                 }
4766                 mutex_unlock(&event->vif_event_lock);
4767                 wake_up(&event->vif_wq);
4768                 return 0;
4769
4770         case BRCMF_E_IF_DEL:
4771                 mutex_unlock(&event->vif_event_lock);
4772                 /* event may not be upon user request */
4773                 if (brcmf_cfg80211_vif_event_armed(cfg))
4774                         wake_up(&event->vif_wq);
4775                 return 0;
4776
4777         case BRCMF_E_IF_CHANGE:
4778                 mutex_unlock(&event->vif_event_lock);
4779                 wake_up(&event->vif_wq);
4780                 return 0;
4781
4782         default:
4783                 mutex_unlock(&event->vif_event_lock);
4784                 break;
4785         }
4786         return -EINVAL;
4787 }
4788
4789 static void brcmf_init_conf(struct brcmf_cfg80211_conf *conf)
4790 {
4791         conf->frag_threshold = (u32)-1;
4792         conf->rts_threshold = (u32)-1;
4793         conf->retry_short = (u32)-1;
4794         conf->retry_long = (u32)-1;
4795         conf->tx_power = -1;
4796 }
4797
4798 static void brcmf_register_event_handlers(struct brcmf_cfg80211_info *cfg)
4799 {
4800         brcmf_fweh_register(cfg->pub, BRCMF_E_LINK,
4801                             brcmf_notify_connect_status);
4802         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH_IND,
4803                             brcmf_notify_connect_status);
4804         brcmf_fweh_register(cfg->pub, BRCMF_E_DEAUTH,
4805                             brcmf_notify_connect_status);
4806         brcmf_fweh_register(cfg->pub, BRCMF_E_DISASSOC_IND,
4807                             brcmf_notify_connect_status);
4808         brcmf_fweh_register(cfg->pub, BRCMF_E_ASSOC_IND,
4809                             brcmf_notify_connect_status);
4810         brcmf_fweh_register(cfg->pub, BRCMF_E_REASSOC_IND,
4811                             brcmf_notify_connect_status);
4812         brcmf_fweh_register(cfg->pub, BRCMF_E_ROAM,
4813                             brcmf_notify_roaming_status);
4814         brcmf_fweh_register(cfg->pub, BRCMF_E_MIC_ERROR,
4815                             brcmf_notify_mic_status);
4816         brcmf_fweh_register(cfg->pub, BRCMF_E_SET_SSID,
4817                             brcmf_notify_connect_status);
4818         brcmf_fweh_register(cfg->pub, BRCMF_E_PFN_NET_FOUND,
4819                             brcmf_notify_sched_scan_results);
4820         brcmf_fweh_register(cfg->pub, BRCMF_E_IF,
4821                             brcmf_notify_vif_event);
4822         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_PROBEREQ_MSG,
4823                             brcmf_p2p_notify_rx_mgmt_p2p_probereq);
4824         brcmf_fweh_register(cfg->pub, BRCMF_E_P2P_DISC_LISTEN_COMPLETE,
4825                             brcmf_p2p_notify_listen_complete);
4826         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_RX,
4827                             brcmf_p2p_notify_action_frame_rx);
4828         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_COMPLETE,
4829                             brcmf_p2p_notify_action_tx_complete);
4830         brcmf_fweh_register(cfg->pub, BRCMF_E_ACTION_FRAME_OFF_CHAN_COMPLETE,
4831                             brcmf_p2p_notify_action_tx_complete);
4832 }
4833
4834 static void brcmf_deinit_priv_mem(struct brcmf_cfg80211_info *cfg)
4835 {
4836         kfree(cfg->conf);
4837         cfg->conf = NULL;
4838         kfree(cfg->escan_ioctl_buf);
4839         cfg->escan_ioctl_buf = NULL;
4840         kfree(cfg->extra_buf);
4841         cfg->extra_buf = NULL;
4842         kfree(cfg->pmk_list);
4843         cfg->pmk_list = NULL;
4844 }
4845
4846 static s32 brcmf_init_priv_mem(struct brcmf_cfg80211_info *cfg)
4847 {
4848         cfg->conf = kzalloc(sizeof(*cfg->conf), GFP_KERNEL);
4849         if (!cfg->conf)
4850                 goto init_priv_mem_out;
4851         cfg->escan_ioctl_buf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
4852         if (!cfg->escan_ioctl_buf)
4853                 goto init_priv_mem_out;
4854         cfg->extra_buf = kzalloc(WL_EXTRA_BUF_MAX, GFP_KERNEL);
4855         if (!cfg->extra_buf)
4856                 goto init_priv_mem_out;
4857         cfg->pmk_list = kzalloc(sizeof(*cfg->pmk_list), GFP_KERNEL);
4858         if (!cfg->pmk_list)
4859                 goto init_priv_mem_out;
4860
4861         return 0;
4862
4863 init_priv_mem_out:
4864         brcmf_deinit_priv_mem(cfg);
4865
4866         return -ENOMEM;
4867 }
4868
4869 static s32 wl_init_priv(struct brcmf_cfg80211_info *cfg)
4870 {
4871         s32 err = 0;
4872
4873         cfg->scan_request = NULL;
4874         cfg->pwr_save = true;
4875         cfg->roam_on = true;    /* roam on & off switch.
4876                                  we enable roam per default */
4877         cfg->active_scan = true;        /* we do active scan for
4878                                  specific scan per default */
4879         cfg->dongle_up = false; /* dongle is not up yet */
4880         err = brcmf_init_priv_mem(cfg);
4881         if (err)
4882                 return err;
4883         brcmf_register_event_handlers(cfg);
4884         mutex_init(&cfg->usr_sync);
4885         brcmf_init_escan(cfg);
4886         brcmf_init_conf(cfg->conf);
4887         init_completion(&cfg->vif_disabled);
4888         return err;
4889 }
4890
4891 static void wl_deinit_priv(struct brcmf_cfg80211_info *cfg)
4892 {
4893         cfg->dongle_up = false; /* dongle down */
4894         brcmf_abort_scanning(cfg);
4895         brcmf_deinit_priv_mem(cfg);
4896 }
4897
4898 static void init_vif_event(struct brcmf_cfg80211_vif_event *event)
4899 {
4900         init_waitqueue_head(&event->vif_wq);
4901         mutex_init(&event->vif_event_lock);
4902 }
4903
4904 struct brcmf_cfg80211_info *brcmf_cfg80211_attach(struct brcmf_pub *drvr,
4905                                                   struct device *busdev)
4906 {
4907         struct net_device *ndev = drvr->iflist[0]->ndev;
4908         struct brcmf_cfg80211_info *cfg;
4909         struct wiphy *wiphy;
4910         struct brcmf_cfg80211_vif *vif;
4911         struct brcmf_if *ifp;
4912         s32 err = 0;
4913         s32 io_type;
4914
4915         if (!ndev) {
4916                 brcmf_err("ndev is invalid\n");
4917                 return NULL;
4918         }
4919
4920         ifp = netdev_priv(ndev);
4921         wiphy = brcmf_setup_wiphy(busdev);
4922         if (IS_ERR(wiphy))
4923                 return NULL;
4924
4925         cfg = wiphy_priv(wiphy);
4926         cfg->wiphy = wiphy;
4927         cfg->pub = drvr;
4928         init_vif_event(&cfg->vif_event);
4929         INIT_LIST_HEAD(&cfg->vif_list);
4930
4931         vif = brcmf_alloc_vif(cfg, NL80211_IFTYPE_STATION, false);
4932         if (IS_ERR(vif)) {
4933                 wiphy_free(wiphy);
4934                 return NULL;
4935         }
4936
4937         vif->ifp = ifp;
4938         vif->wdev.netdev = ndev;
4939         ndev->ieee80211_ptr = &vif->wdev;
4940         SET_NETDEV_DEV(ndev, wiphy_dev(cfg->wiphy));
4941
4942         err = wl_init_priv(cfg);
4943         if (err) {
4944                 brcmf_err("Failed to init iwm_priv (%d)\n", err);
4945                 goto cfg80211_attach_out;
4946         }
4947         ifp->vif = vif;
4948
4949         err = brcmf_p2p_attach(cfg);
4950         if (err) {
4951                 brcmf_err("P2P initilisation failed (%d)\n", err);
4952                 goto cfg80211_p2p_attach_out;
4953         }
4954         err = brcmf_btcoex_attach(cfg);
4955         if (err) {
4956                 brcmf_err("BT-coex initialisation failed (%d)\n", err);
4957                 brcmf_p2p_detach(&cfg->p2p);
4958                 goto cfg80211_p2p_attach_out;
4959         }
4960
4961         err = brcmf_fil_iovar_int_set(ifp, "tdls_enable", 1);
4962         if (err) {
4963                 brcmf_dbg(INFO, "TDLS not enabled (%d)\n", err);
4964                 wiphy->flags &= ~WIPHY_FLAG_SUPPORTS_TDLS;
4965         }
4966
4967         err = brcmf_fil_cmd_int_get(ifp, BRCMF_C_GET_VERSION,
4968                                     &io_type);
4969         if (err) {
4970                 brcmf_err("Failed to get D11 version (%d)\n", err);
4971                 goto cfg80211_p2p_attach_out;
4972         }
4973         cfg->d11inf.io_type = (u8)io_type;
4974         brcmu_d11_attach(&cfg->d11inf);
4975
4976         return cfg;
4977
4978 cfg80211_p2p_attach_out:
4979         wl_deinit_priv(cfg);
4980
4981 cfg80211_attach_out:
4982         brcmf_free_vif(cfg, vif);
4983         return NULL;
4984 }
4985
4986 void brcmf_cfg80211_detach(struct brcmf_cfg80211_info *cfg)
4987 {
4988         struct brcmf_cfg80211_vif *vif;
4989         struct brcmf_cfg80211_vif *tmp;
4990
4991         wl_deinit_priv(cfg);
4992         brcmf_btcoex_detach(cfg);
4993         list_for_each_entry_safe(vif, tmp, &cfg->vif_list, list) {
4994                 brcmf_free_vif(cfg, vif);
4995         }
4996 }
4997
4998 static s32
4999 brcmf_dongle_roam(struct brcmf_if *ifp, u32 roamvar, u32 bcn_timeout)
5000 {
5001         s32 err = 0;
5002         __le32 roamtrigger[2];
5003         __le32 roam_delta[2];
5004
5005         /*
5006          * Setup timeout if Beacons are lost and roam is
5007          * off to report link down
5008          */
5009         if (roamvar) {
5010                 err = brcmf_fil_iovar_int_set(ifp, "bcn_timeout", bcn_timeout);
5011                 if (err) {
5012                         brcmf_err("bcn_timeout error (%d)\n", err);
5013                         goto dongle_rom_out;
5014                 }
5015         }
5016
5017         /*
5018          * Enable/Disable built-in roaming to allow supplicant
5019          * to take care of roaming
5020          */
5021         brcmf_dbg(INFO, "Internal Roaming = %s\n", roamvar ? "Off" : "On");
5022         err = brcmf_fil_iovar_int_set(ifp, "roam_off", roamvar);
5023         if (err) {
5024                 brcmf_err("roam_off error (%d)\n", err);
5025                 goto dongle_rom_out;
5026         }
5027
5028         roamtrigger[0] = cpu_to_le32(WL_ROAM_TRIGGER_LEVEL);
5029         roamtrigger[1] = cpu_to_le32(BRCM_BAND_ALL);
5030         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_TRIGGER,
5031                                      (void *)roamtrigger, sizeof(roamtrigger));
5032         if (err) {
5033                 brcmf_err("WLC_SET_ROAM_TRIGGER error (%d)\n", err);
5034                 goto dongle_rom_out;
5035         }
5036
5037         roam_delta[0] = cpu_to_le32(WL_ROAM_DELTA);
5038         roam_delta[1] = cpu_to_le32(BRCM_BAND_ALL);
5039         err = brcmf_fil_cmd_data_set(ifp, BRCMF_C_SET_ROAM_DELTA,
5040                                      (void *)roam_delta, sizeof(roam_delta));
5041         if (err) {
5042                 brcmf_err("WLC_SET_ROAM_DELTA error (%d)\n", err);
5043                 goto dongle_rom_out;
5044         }
5045
5046 dongle_rom_out:
5047         return err;
5048 }
5049
5050 static s32
5051 brcmf_dongle_scantime(struct brcmf_if *ifp, s32 scan_assoc_time,
5052                       s32 scan_unassoc_time, s32 scan_passive_time)
5053 {
5054         s32 err = 0;
5055
5056         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_CHANNEL_TIME,
5057                                     scan_assoc_time);
5058         if (err) {
5059                 if (err == -EOPNOTSUPP)
5060                         brcmf_dbg(INFO, "Scan assoc time is not supported\n");
5061                 else
5062                         brcmf_err("Scan assoc time error (%d)\n", err);
5063                 goto dongle_scantime_out;
5064         }
5065         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_UNASSOC_TIME,
5066                                     scan_unassoc_time);
5067         if (err) {
5068                 if (err == -EOPNOTSUPP)
5069                         brcmf_dbg(INFO, "Scan unassoc time is not supported\n");
5070                 else
5071                         brcmf_err("Scan unassoc time error (%d)\n", err);
5072                 goto dongle_scantime_out;
5073         }
5074
5075         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_SCAN_PASSIVE_TIME,
5076                                     scan_passive_time);
5077         if (err) {
5078                 if (err == -EOPNOTSUPP)
5079                         brcmf_dbg(INFO, "Scan passive time is not supported\n");
5080                 else
5081                         brcmf_err("Scan passive time error (%d)\n", err);
5082                 goto dongle_scantime_out;
5083         }
5084
5085 dongle_scantime_out:
5086         return err;
5087 }
5088
5089
5090 static s32 brcmf_construct_reginfo(struct brcmf_cfg80211_info *cfg,
5091                                    u32 bw_cap[])
5092 {
5093         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5094         struct ieee80211_channel *band_chan_arr;
5095         struct brcmf_chanspec_list *list;
5096         struct brcmu_chan ch;
5097         s32 err;
5098         u8 *pbuf;
5099         u32 i, j;
5100         u32 total;
5101         enum ieee80211_band band;
5102         u32 channel;
5103         u32 *n_cnt;
5104         u32 index;
5105         u32 ht40_flag;
5106         bool update;
5107         u32 array_size;
5108
5109         pbuf = kzalloc(BRCMF_DCMD_MEDLEN, GFP_KERNEL);
5110
5111         if (pbuf == NULL)
5112                 return -ENOMEM;
5113
5114         list = (struct brcmf_chanspec_list *)pbuf;
5115
5116         err = brcmf_fil_iovar_data_get(ifp, "chanspecs", pbuf,
5117                                        BRCMF_DCMD_MEDLEN);
5118         if (err) {
5119                 brcmf_err("get chanspecs error (%d)\n", err);
5120                 goto exit;
5121         }
5122
5123         __wl_band_2ghz.n_channels = 0;
5124         __wl_band_5ghz_a.n_channels = 0;
5125
5126         total = le32_to_cpu(list->count);
5127         for (i = 0; i < total; i++) {
5128                 ch.chspec = (u16)le32_to_cpu(list->element[i]);
5129                 cfg->d11inf.decchspec(&ch);
5130
5131                 if (ch.band == BRCMU_CHAN_BAND_2G) {
5132                         band_chan_arr = __wl_2ghz_channels;
5133                         array_size = ARRAY_SIZE(__wl_2ghz_channels);
5134                         n_cnt = &__wl_band_2ghz.n_channels;
5135                         band = IEEE80211_BAND_2GHZ;
5136                 } else if (ch.band == BRCMU_CHAN_BAND_5G) {
5137                         band_chan_arr = __wl_5ghz_a_channels;
5138                         array_size = ARRAY_SIZE(__wl_5ghz_a_channels);
5139                         n_cnt = &__wl_band_5ghz_a.n_channels;
5140                         band = IEEE80211_BAND_5GHZ;
5141                 } else {
5142                         brcmf_err("Invalid channel Spec. 0x%x.\n", ch.chspec);
5143                         continue;
5144                 }
5145                 if (!(bw_cap[band] & WLC_BW_40MHZ_BIT) &&
5146                     ch.bw == BRCMU_CHAN_BW_40)
5147                         continue;
5148                 update = false;
5149                 for (j = 0; (j < *n_cnt && (*n_cnt < array_size)); j++) {
5150                         if (band_chan_arr[j].hw_value == ch.chnum) {
5151                                 update = true;
5152                                 break;
5153                         }
5154                 }
5155                 if (update)
5156                         index = j;
5157                 else
5158                         index = *n_cnt;
5159                 if (index <  array_size) {
5160                         band_chan_arr[index].center_freq =
5161                                 ieee80211_channel_to_frequency(ch.chnum, band);
5162                         band_chan_arr[index].hw_value = ch.chnum;
5163
5164                         brcmf_err("channel %d: f=%d bw=%d sb=%d\n",
5165                                   ch.chnum, band_chan_arr[index].center_freq,
5166                                   ch.bw, ch.sb);
5167                         if (ch.bw == BRCMU_CHAN_BW_40) {
5168                                 /* assuming the order is HT20, HT40 Upper,
5169                                  * HT40 lower from chanspecs
5170                                  */
5171                                 ht40_flag = band_chan_arr[index].flags &
5172                                             IEEE80211_CHAN_NO_HT40;
5173                                 if (ch.sb == BRCMU_CHAN_SB_U) {
5174                                         if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5175                                                 band_chan_arr[index].flags &=
5176                                                         ~IEEE80211_CHAN_NO_HT40;
5177                                         band_chan_arr[index].flags |=
5178                                                 IEEE80211_CHAN_NO_HT40PLUS;
5179                                 } else {
5180                                         /* It should be one of
5181                                          * IEEE80211_CHAN_NO_HT40 or
5182                                          * IEEE80211_CHAN_NO_HT40PLUS
5183                                          */
5184                                         band_chan_arr[index].flags &=
5185                                                         ~IEEE80211_CHAN_NO_HT40;
5186                                         if (ht40_flag == IEEE80211_CHAN_NO_HT40)
5187                                                 band_chan_arr[index].flags |=
5188                                                     IEEE80211_CHAN_NO_HT40MINUS;
5189                                 }
5190                         } else {
5191                                 band_chan_arr[index].flags =
5192                                                         IEEE80211_CHAN_NO_HT40;
5193                                 ch.bw = BRCMU_CHAN_BW_20;
5194                                 cfg->d11inf.encchspec(&ch);
5195                                 channel = ch.chspec;
5196                                 err = brcmf_fil_bsscfg_int_get(ifp,
5197                                                                "per_chan_info",
5198                                                                &channel);
5199                                 if (!err) {
5200                                         if (channel & WL_CHAN_RADAR)
5201                                                 band_chan_arr[index].flags |=
5202                                                         (IEEE80211_CHAN_RADAR |
5203                                                         IEEE80211_CHAN_NO_IR);
5204                                         if (channel & WL_CHAN_PASSIVE)
5205                                                 band_chan_arr[index].flags |=
5206                                                     IEEE80211_CHAN_NO_IR;
5207                                 }
5208                         }
5209                         if (!update)
5210                                 (*n_cnt)++;
5211                 }
5212         }
5213 exit:
5214         kfree(pbuf);
5215         return err;
5216 }
5217
5218 static void brcmf_get_bwcap(struct brcmf_if *ifp, u32 bw_cap[])
5219 {
5220         u32 band, mimo_bwcap;
5221         int err;
5222
5223         band = WLC_BAND_2G;
5224         err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5225         if (!err) {
5226                 bw_cap[IEEE80211_BAND_2GHZ] = band;
5227                 band = WLC_BAND_5G;
5228                 err = brcmf_fil_iovar_int_get(ifp, "bw_cap", &band);
5229                 if (!err) {
5230                         bw_cap[IEEE80211_BAND_5GHZ] = band;
5231                         return;
5232                 }
5233                 WARN_ON(1);
5234                 return;
5235         }
5236         brcmf_dbg(INFO, "fallback to mimo_bw_cap info\n");
5237         mimo_bwcap = 0;
5238         err = brcmf_fil_iovar_int_get(ifp, "mimo_bw_cap", &mimo_bwcap);
5239         if (err)
5240                 /* assume 20MHz if firmware does not give a clue */
5241                 mimo_bwcap = WLC_N_BW_20ALL;
5242
5243         switch (mimo_bwcap) {
5244         case WLC_N_BW_40ALL:
5245                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_40MHZ_BIT;
5246                 /* fall-thru */
5247         case WLC_N_BW_20IN2G_40IN5G:
5248                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_40MHZ_BIT;
5249                 /* fall-thru */
5250         case WLC_N_BW_20ALL:
5251                 bw_cap[IEEE80211_BAND_2GHZ] |= WLC_BW_20MHZ_BIT;
5252                 bw_cap[IEEE80211_BAND_5GHZ] |= WLC_BW_20MHZ_BIT;
5253                 break;
5254         default:
5255                 brcmf_err("invalid mimo_bw_cap value\n");
5256         }
5257 }
5258
5259 static s32 brcmf_update_wiphybands(struct brcmf_cfg80211_info *cfg)
5260 {
5261         struct brcmf_if *ifp = netdev_priv(cfg_to_ndev(cfg));
5262         struct wiphy *wiphy;
5263         s32 phy_list;
5264         u32 band_list[3];
5265         u32 nmode;
5266         u32 bw_cap[2] = { 0, 0 };
5267         s8 phy;
5268         s32 err;
5269         u32 nband;
5270         s32 i;
5271         struct ieee80211_supported_band *bands[2] = { NULL, NULL };
5272         struct ieee80211_supported_band *band;
5273
5274         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_PHYLIST,
5275                                      &phy_list, sizeof(phy_list));
5276         if (err) {
5277                 brcmf_err("BRCMF_C_GET_PHYLIST error (%d)\n", err);
5278                 return err;
5279         }
5280
5281         phy = ((char *)&phy_list)[0];
5282         brcmf_dbg(INFO, "BRCMF_C_GET_PHYLIST reported: %c phy\n", phy);
5283
5284
5285         err = brcmf_fil_cmd_data_get(ifp, BRCMF_C_GET_BANDLIST,
5286                                      &band_list, sizeof(band_list));
5287         if (err) {
5288                 brcmf_err("BRCMF_C_GET_BANDLIST error (%d)\n", err);
5289                 return err;
5290         }
5291         brcmf_dbg(INFO, "BRCMF_C_GET_BANDLIST reported: 0x%08x 0x%08x 0x%08x phy\n",
5292                   band_list[0], band_list[1], band_list[2]);
5293
5294         err = brcmf_fil_iovar_int_get(ifp, "nmode", &nmode);
5295         if (err) {
5296                 brcmf_err("nmode error (%d)\n", err);
5297         } else {
5298                 brcmf_get_bwcap(ifp, bw_cap);
5299         }
5300         brcmf_dbg(INFO, "nmode=%d, bw_cap=(%d, %d)\n", nmode,
5301                   bw_cap[IEEE80211_BAND_2GHZ], bw_cap[IEEE80211_BAND_5GHZ]);
5302
5303         err = brcmf_construct_reginfo(cfg, bw_cap);
5304         if (err) {
5305                 brcmf_err("brcmf_construct_reginfo failed (%d)\n", err);
5306                 return err;
5307         }
5308
5309         nband = band_list[0];
5310
5311         for (i = 1; i <= nband && i < ARRAY_SIZE(band_list); i++) {
5312                 band = NULL;
5313                 if ((band_list[i] == WLC_BAND_5G) &&
5314                     (__wl_band_5ghz_a.n_channels > 0))
5315                         band = &__wl_band_5ghz_a;
5316                 else if ((band_list[i] == WLC_BAND_2G) &&
5317                          (__wl_band_2ghz.n_channels > 0))
5318                         band = &__wl_band_2ghz;
5319                 else
5320                         continue;
5321
5322                 if (bw_cap[band->band] & WLC_BW_40MHZ_BIT) {
5323                         band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_40;
5324                         band->ht_cap.cap |= IEEE80211_HT_CAP_SUP_WIDTH_20_40;
5325                 }
5326                 band->ht_cap.cap |= IEEE80211_HT_CAP_SGI_20;
5327                 band->ht_cap.cap |= IEEE80211_HT_CAP_DSSSCCK40;
5328                 band->ht_cap.ht_supported = true;
5329                 band->ht_cap.ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
5330                 band->ht_cap.ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
5331                 /* An HT shall support all EQM rates for one spatial
5332                  * stream
5333                  */
5334                 band->ht_cap.mcs.rx_mask[0] = 0xff;
5335                 band->ht_cap.mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
5336                 bands[band->band] = band;
5337         }
5338
5339         wiphy = cfg_to_wiphy(cfg);
5340         wiphy->bands[IEEE80211_BAND_2GHZ] = bands[IEEE80211_BAND_2GHZ];
5341         wiphy->bands[IEEE80211_BAND_5GHZ] = bands[IEEE80211_BAND_5GHZ];
5342         wiphy_apply_custom_regulatory(wiphy, &brcmf_regdom);
5343
5344         return err;
5345 }
5346
5347
5348 static s32 brcmf_dongle_probecap(struct brcmf_cfg80211_info *cfg)
5349 {
5350         return brcmf_update_wiphybands(cfg);
5351 }
5352
5353 static s32 brcmf_config_dongle(struct brcmf_cfg80211_info *cfg)
5354 {
5355         struct net_device *ndev;
5356         struct wireless_dev *wdev;
5357         struct brcmf_if *ifp;
5358         s32 power_mode;
5359         s32 err = 0;
5360
5361         if (cfg->dongle_up)
5362                 return err;
5363
5364         ndev = cfg_to_ndev(cfg);
5365         wdev = ndev->ieee80211_ptr;
5366         ifp = netdev_priv(ndev);
5367
5368         /* make sure RF is ready for work */
5369         brcmf_fil_cmd_int_set(ifp, BRCMF_C_UP, 0);
5370
5371         brcmf_dongle_scantime(ifp, WL_SCAN_CHANNEL_TIME,
5372                               WL_SCAN_UNASSOC_TIME, WL_SCAN_PASSIVE_TIME);
5373
5374         power_mode = cfg->pwr_save ? PM_FAST : PM_OFF;
5375         err = brcmf_fil_cmd_int_set(ifp, BRCMF_C_SET_PM, power_mode);
5376         if (err)
5377                 goto default_conf_out;
5378         brcmf_dbg(INFO, "power save set to %s\n",
5379                   (power_mode ? "enabled" : "disabled"));
5380
5381         err = brcmf_dongle_roam(ifp, (cfg->roam_on ? 0 : 1), WL_BEACON_TIMEOUT);
5382         if (err)
5383                 goto default_conf_out;
5384         err = brcmf_cfg80211_change_iface(wdev->wiphy, ndev, wdev->iftype,
5385                                           NULL, NULL);
5386         if (err)
5387                 goto default_conf_out;
5388         err = brcmf_dongle_probecap(cfg);
5389         if (err)
5390                 goto default_conf_out;
5391
5392         brcmf_configure_arp_offload(ifp, true);
5393
5394         cfg->dongle_up = true;
5395 default_conf_out:
5396
5397         return err;
5398
5399 }
5400
5401 static s32 __brcmf_cfg80211_up(struct brcmf_if *ifp)
5402 {
5403         set_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5404
5405         return brcmf_config_dongle(ifp->drvr->config);
5406 }
5407
5408 static s32 __brcmf_cfg80211_down(struct brcmf_if *ifp)
5409 {
5410         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5411
5412         /*
5413          * While going down, if associated with AP disassociate
5414          * from AP to save power
5415          */
5416         if (check_vif_up(ifp->vif)) {
5417                 brcmf_link_down(ifp->vif);
5418
5419                 /* Make sure WPA_Supplicant receives all the event
5420                    generated due to DISASSOC call to the fw to keep
5421                    the state fw and WPA_Supplicant state consistent
5422                  */
5423                 brcmf_delay(500);
5424         }
5425
5426         brcmf_abort_scanning(cfg);
5427         clear_bit(BRCMF_VIF_STATUS_READY, &ifp->vif->sme_state);
5428
5429         return 0;
5430 }
5431
5432 s32 brcmf_cfg80211_up(struct net_device *ndev)
5433 {
5434         struct brcmf_if *ifp = netdev_priv(ndev);
5435         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5436         s32 err = 0;
5437
5438         mutex_lock(&cfg->usr_sync);
5439         err = __brcmf_cfg80211_up(ifp);
5440         mutex_unlock(&cfg->usr_sync);
5441
5442         return err;
5443 }
5444
5445 s32 brcmf_cfg80211_down(struct net_device *ndev)
5446 {
5447         struct brcmf_if *ifp = netdev_priv(ndev);
5448         struct brcmf_cfg80211_info *cfg = ifp->drvr->config;
5449         s32 err = 0;
5450
5451         mutex_lock(&cfg->usr_sync);
5452         err = __brcmf_cfg80211_down(ifp);
5453         mutex_unlock(&cfg->usr_sync);
5454
5455         return err;
5456 }
5457
5458 enum nl80211_iftype brcmf_cfg80211_get_iftype(struct brcmf_if *ifp)
5459 {
5460         struct wireless_dev *wdev = &ifp->vif->wdev;
5461
5462         return wdev->iftype;
5463 }
5464
5465 u32 wl_get_vif_state_all(struct brcmf_cfg80211_info *cfg, unsigned long state)
5466 {
5467         struct brcmf_cfg80211_vif *vif;
5468         bool result = 0;
5469
5470         list_for_each_entry(vif, &cfg->vif_list, list) {
5471                 if (test_bit(state, &vif->sme_state))
5472                         result++;
5473         }
5474         return result;
5475 }
5476
5477 static inline bool vif_event_equals(struct brcmf_cfg80211_vif_event *event,
5478                                     u8 action)
5479 {
5480         u8 evt_action;
5481
5482         mutex_lock(&event->vif_event_lock);
5483         evt_action = event->action;
5484         mutex_unlock(&event->vif_event_lock);
5485         return evt_action == action;
5486 }
5487
5488 void brcmf_cfg80211_arm_vif_event(struct brcmf_cfg80211_info *cfg,
5489                                   struct brcmf_cfg80211_vif *vif)
5490 {
5491         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5492
5493         mutex_lock(&event->vif_event_lock);
5494         event->vif = vif;
5495         event->action = 0;
5496         mutex_unlock(&event->vif_event_lock);
5497 }
5498
5499 bool brcmf_cfg80211_vif_event_armed(struct brcmf_cfg80211_info *cfg)
5500 {
5501         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5502         bool armed;
5503
5504         mutex_lock(&event->vif_event_lock);
5505         armed = event->vif != NULL;
5506         mutex_unlock(&event->vif_event_lock);
5507
5508         return armed;
5509 }
5510 int brcmf_cfg80211_wait_vif_event_timeout(struct brcmf_cfg80211_info *cfg,
5511                                           u8 action, ulong timeout)
5512 {
5513         struct brcmf_cfg80211_vif_event *event = &cfg->vif_event;
5514
5515         return wait_event_timeout(event->vif_wq,
5516                                   vif_event_equals(event, action), timeout);
5517 }
5518