ath6kl: logical continuations should be on the previous line
[cascardo/linux.git] / drivers / net / wireless / ath / ath6kl / cfg80211.c
1 /*
2  * Copyright (c) 2004-2011 Atheros Communications Inc.
3  * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
4  *
5  * Permission to use, copy, modify, and/or distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 #include <linux/moduleparam.h>
19 #include <linux/inetdevice.h>
20 #include <linux/export.h>
21
22 #include "core.h"
23 #include "cfg80211.h"
24 #include "debug.h"
25 #include "hif-ops.h"
26 #include "testmode.h"
27
28 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
29         .bitrate    = (_rate),                  \
30         .flags      = (_flags),                 \
31         .hw_value   = (_rateid),                \
32 }
33
34 #define CHAN2G(_channel, _freq, _flags) {   \
35         .band           = IEEE80211_BAND_2GHZ,  \
36         .hw_value       = (_channel),           \
37         .center_freq    = (_freq),              \
38         .flags          = (_flags),             \
39         .max_antenna_gain   = 0,                \
40         .max_power      = 30,                   \
41 }
42
43 #define CHAN5G(_channel, _flags) {                  \
44         .band           = IEEE80211_BAND_5GHZ,      \
45         .hw_value       = (_channel),               \
46         .center_freq    = 5000 + (5 * (_channel)),  \
47         .flags          = (_flags),                 \
48         .max_antenna_gain   = 0,                    \
49         .max_power      = 30,                       \
50 }
51
52 static struct ieee80211_rate ath6kl_rates[] = {
53         RATETAB_ENT(10, 0x1, 0),
54         RATETAB_ENT(20, 0x2, 0),
55         RATETAB_ENT(55, 0x4, 0),
56         RATETAB_ENT(110, 0x8, 0),
57         RATETAB_ENT(60, 0x10, 0),
58         RATETAB_ENT(90, 0x20, 0),
59         RATETAB_ENT(120, 0x40, 0),
60         RATETAB_ENT(180, 0x80, 0),
61         RATETAB_ENT(240, 0x100, 0),
62         RATETAB_ENT(360, 0x200, 0),
63         RATETAB_ENT(480, 0x400, 0),
64         RATETAB_ENT(540, 0x800, 0),
65 };
66
67 #define ath6kl_a_rates     (ath6kl_rates + 4)
68 #define ath6kl_a_rates_size    8
69 #define ath6kl_g_rates     (ath6kl_rates + 0)
70 #define ath6kl_g_rates_size    12
71
72 #define ath6kl_g_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
73                         IEEE80211_HT_CAP_SGI_20          | \
74                         IEEE80211_HT_CAP_SGI_40)
75
76 static struct ieee80211_channel ath6kl_2ghz_channels[] = {
77         CHAN2G(1, 2412, 0),
78         CHAN2G(2, 2417, 0),
79         CHAN2G(3, 2422, 0),
80         CHAN2G(4, 2427, 0),
81         CHAN2G(5, 2432, 0),
82         CHAN2G(6, 2437, 0),
83         CHAN2G(7, 2442, 0),
84         CHAN2G(8, 2447, 0),
85         CHAN2G(9, 2452, 0),
86         CHAN2G(10, 2457, 0),
87         CHAN2G(11, 2462, 0),
88         CHAN2G(12, 2467, 0),
89         CHAN2G(13, 2472, 0),
90         CHAN2G(14, 2484, 0),
91 };
92
93 static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
94         CHAN5G(34, 0), CHAN5G(36, 0),
95         CHAN5G(38, 0), CHAN5G(40, 0),
96         CHAN5G(42, 0), CHAN5G(44, 0),
97         CHAN5G(46, 0), CHAN5G(48, 0),
98         CHAN5G(52, 0), CHAN5G(56, 0),
99         CHAN5G(60, 0), CHAN5G(64, 0),
100         CHAN5G(100, 0), CHAN5G(104, 0),
101         CHAN5G(108, 0), CHAN5G(112, 0),
102         CHAN5G(116, 0), CHAN5G(120, 0),
103         CHAN5G(124, 0), CHAN5G(128, 0),
104         CHAN5G(132, 0), CHAN5G(136, 0),
105         CHAN5G(140, 0), CHAN5G(149, 0),
106         CHAN5G(153, 0), CHAN5G(157, 0),
107         CHAN5G(161, 0), CHAN5G(165, 0),
108         CHAN5G(184, 0), CHAN5G(188, 0),
109         CHAN5G(192, 0), CHAN5G(196, 0),
110         CHAN5G(200, 0), CHAN5G(204, 0),
111         CHAN5G(208, 0), CHAN5G(212, 0),
112         CHAN5G(216, 0),
113 };
114
115 static struct ieee80211_supported_band ath6kl_band_2ghz = {
116         .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
117         .channels = ath6kl_2ghz_channels,
118         .n_bitrates = ath6kl_g_rates_size,
119         .bitrates = ath6kl_g_rates,
120         .ht_cap.cap = ath6kl_g_htcap,
121         .ht_cap.ht_supported = true,
122 };
123
124 static struct ieee80211_supported_band ath6kl_band_5ghz = {
125         .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
126         .channels = ath6kl_5ghz_a_channels,
127         .n_bitrates = ath6kl_a_rates_size,
128         .bitrates = ath6kl_a_rates,
129         .ht_cap.cap = ath6kl_g_htcap,
130         .ht_cap.ht_supported = true,
131 };
132
133 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
134
135 /* returns true if scheduled scan was stopped */
136 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
137 {
138         struct ath6kl *ar = vif->ar;
139
140         if (ar->state != ATH6KL_STATE_SCHED_SCAN)
141                 return false;
142
143         del_timer_sync(&vif->sched_scan_timer);
144
145         ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
146                                            ATH6KL_HOST_MODE_AWAKE);
147
148         ar->state = ATH6KL_STATE_ON;
149
150         return true;
151 }
152
153 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
154 {
155         struct ath6kl *ar = vif->ar;
156         bool stopped;
157
158         stopped = __ath6kl_cfg80211_sscan_stop(vif);
159
160         if (!stopped)
161                 return;
162
163         cfg80211_sched_scan_stopped(ar->wiphy);
164 }
165
166 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
167                                   enum nl80211_wpa_versions wpa_version)
168 {
169         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
170
171         if (!wpa_version) {
172                 vif->auth_mode = NONE_AUTH;
173         } else if (wpa_version & NL80211_WPA_VERSION_2) {
174                 vif->auth_mode = WPA2_AUTH;
175         } else if (wpa_version & NL80211_WPA_VERSION_1) {
176                 vif->auth_mode = WPA_AUTH;
177         } else {
178                 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
179                 return -ENOTSUPP;
180         }
181
182         return 0;
183 }
184
185 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
186                                 enum nl80211_auth_type auth_type)
187 {
188         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
189
190         switch (auth_type) {
191         case NL80211_AUTHTYPE_OPEN_SYSTEM:
192                 vif->dot11_auth_mode = OPEN_AUTH;
193                 break;
194         case NL80211_AUTHTYPE_SHARED_KEY:
195                 vif->dot11_auth_mode = SHARED_AUTH;
196                 break;
197         case NL80211_AUTHTYPE_NETWORK_EAP:
198                 vif->dot11_auth_mode = LEAP_AUTH;
199                 break;
200
201         case NL80211_AUTHTYPE_AUTOMATIC:
202                 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
203                 break;
204
205         default:
206                 ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
207                 return -ENOTSUPP;
208         }
209
210         return 0;
211 }
212
213 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
214 {
215         u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
216         u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
217                 &vif->grp_crypto_len;
218
219         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
220                    __func__, cipher, ucast);
221
222         switch (cipher) {
223         case 0:
224                 /* our own hack to use value 0 as no crypto used */
225                 *ar_cipher = NONE_CRYPT;
226                 *ar_cipher_len = 0;
227                 break;
228         case WLAN_CIPHER_SUITE_WEP40:
229                 *ar_cipher = WEP_CRYPT;
230                 *ar_cipher_len = 5;
231                 break;
232         case WLAN_CIPHER_SUITE_WEP104:
233                 *ar_cipher = WEP_CRYPT;
234                 *ar_cipher_len = 13;
235                 break;
236         case WLAN_CIPHER_SUITE_TKIP:
237                 *ar_cipher = TKIP_CRYPT;
238                 *ar_cipher_len = 0;
239                 break;
240         case WLAN_CIPHER_SUITE_CCMP:
241                 *ar_cipher = AES_CRYPT;
242                 *ar_cipher_len = 0;
243                 break;
244         case WLAN_CIPHER_SUITE_SMS4:
245                 *ar_cipher = WAPI_CRYPT;
246                 *ar_cipher_len = 0;
247                 break;
248         default:
249                 ath6kl_err("cipher 0x%x not supported\n", cipher);
250                 return -ENOTSUPP;
251         }
252
253         return 0;
254 }
255
256 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
257 {
258         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
259
260         if (key_mgmt == WLAN_AKM_SUITE_PSK) {
261                 if (vif->auth_mode == WPA_AUTH)
262                         vif->auth_mode = WPA_PSK_AUTH;
263                 else if (vif->auth_mode == WPA2_AUTH)
264                         vif->auth_mode = WPA2_PSK_AUTH;
265         } else if (key_mgmt == 0x00409600) {
266                 if (vif->auth_mode == WPA_AUTH)
267                         vif->auth_mode = WPA_AUTH_CCKM;
268                 else if (vif->auth_mode == WPA2_AUTH)
269                         vif->auth_mode = WPA2_AUTH_CCKM;
270         } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
271                 vif->auth_mode = NONE_AUTH;
272         }
273 }
274
275 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
276 {
277         struct ath6kl *ar = vif->ar;
278
279         if (!test_bit(WMI_READY, &ar->flag)) {
280                 ath6kl_err("wmi is not ready\n");
281                 return false;
282         }
283
284         if (!test_bit(WLAN_ENABLED, &vif->flags)) {
285                 ath6kl_err("wlan disabled\n");
286                 return false;
287         }
288
289         return true;
290 }
291
292 static bool ath6kl_is_wpa_ie(const u8 *pos)
293 {
294         return pos[0] == WLAN_EID_WPA && pos[1] >= 4 &&
295                 pos[2] == 0x00 && pos[3] == 0x50 &&
296                 pos[4] == 0xf2 && pos[5] == 0x01;
297 }
298
299 static bool ath6kl_is_rsn_ie(const u8 *pos)
300 {
301         return pos[0] == WLAN_EID_RSN;
302 }
303
304 static bool ath6kl_is_wps_ie(const u8 *pos)
305 {
306         return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
307                 pos[1] >= 4 &&
308                 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
309                 pos[5] == 0x04);
310 }
311
312 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
313                                     size_t ies_len)
314 {
315         struct ath6kl *ar = vif->ar;
316         const u8 *pos;
317         u8 *buf = NULL;
318         size_t len = 0;
319         int ret;
320
321         /*
322          * Clear previously set flag
323          */
324
325         ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
326
327         /*
328          * Filter out RSN/WPA IE(s)
329          */
330
331         if (ies && ies_len) {
332                 buf = kmalloc(ies_len, GFP_KERNEL);
333                 if (buf == NULL)
334                         return -ENOMEM;
335                 pos = ies;
336
337                 while (pos + 1 < ies + ies_len) {
338                         if (pos + 2 + pos[1] > ies + ies_len)
339                                 break;
340                         if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
341                                 memcpy(buf + len, pos, 2 + pos[1]);
342                                 len += 2 + pos[1];
343                         }
344
345                         if (ath6kl_is_wps_ie(pos))
346                                 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
347
348                         pos += 2 + pos[1];
349                 }
350         }
351
352         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
353                                        WMI_FRAME_ASSOC_REQ, buf, len);
354         kfree(buf);
355         return ret;
356 }
357
358 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
359 {
360         switch (type) {
361         case NL80211_IFTYPE_STATION:
362                 *nw_type = INFRA_NETWORK;
363                 break;
364         case NL80211_IFTYPE_ADHOC:
365                 *nw_type = ADHOC_NETWORK;
366                 break;
367         case NL80211_IFTYPE_AP:
368                 *nw_type = AP_NETWORK;
369                 break;
370         case NL80211_IFTYPE_P2P_CLIENT:
371                 *nw_type = INFRA_NETWORK;
372                 break;
373         case NL80211_IFTYPE_P2P_GO:
374                 *nw_type = AP_NETWORK;
375                 break;
376         default:
377                 ath6kl_err("invalid interface type %u\n", type);
378                 return -ENOTSUPP;
379         }
380
381         return 0;
382 }
383
384 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
385                                    u8 *if_idx, u8 *nw_type)
386 {
387         int i;
388
389         if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
390                 return false;
391
392         if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
393                                    ar->num_vif))
394                 return false;
395
396         if (type == NL80211_IFTYPE_STATION ||
397             type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
398                 for (i = 0; i < ar->vif_max; i++) {
399                         if ((ar->avail_idx_map >> i) & BIT(0)) {
400                                 *if_idx = i;
401                                 return true;
402                         }
403                 }
404         }
405
406         if (type == NL80211_IFTYPE_P2P_CLIENT ||
407             type == NL80211_IFTYPE_P2P_GO) {
408                 for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
409                         if ((ar->avail_idx_map >> i) & BIT(0)) {
410                                 *if_idx = i;
411                                 return true;
412                         }
413                 }
414         }
415
416         return false;
417 }
418
419 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
420                                    struct cfg80211_connect_params *sme)
421 {
422         struct ath6kl *ar = ath6kl_priv(dev);
423         struct ath6kl_vif *vif = netdev_priv(dev);
424         int status;
425         u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
426         u16 interval;
427
428         ath6kl_cfg80211_sscan_disable(vif);
429
430         vif->sme_state = SME_CONNECTING;
431
432         if (!ath6kl_cfg80211_ready(vif))
433                 return -EIO;
434
435         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
436                 ath6kl_err("destroy in progress\n");
437                 return -EBUSY;
438         }
439
440         if (test_bit(SKIP_SCAN, &ar->flag) &&
441             ((sme->channel && sme->channel->center_freq == 0) ||
442              (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
443                 ath6kl_err("SkipScan: channel or bssid invalid\n");
444                 return -EINVAL;
445         }
446
447         if (down_interruptible(&ar->sem)) {
448                 ath6kl_err("busy, couldn't get access\n");
449                 return -ERESTARTSYS;
450         }
451
452         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
453                 ath6kl_err("busy, destroy in progress\n");
454                 up(&ar->sem);
455                 return -EBUSY;
456         }
457
458         if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
459                 /*
460                  * sleep until the command queue drains
461                  */
462                 wait_event_interruptible_timeout(ar->event_wq,
463                         ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
464                         WMI_TIMEOUT);
465                 if (signal_pending(current)) {
466                         ath6kl_err("cmd queue drain timeout\n");
467                         up(&ar->sem);
468                         return -EINTR;
469                 }
470         }
471
472         status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
473         if (status) {
474                 up(&ar->sem);
475                 return status;
476         }
477
478         if (sme->ie == NULL || sme->ie_len == 0)
479                 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
480
481         if (test_bit(CONNECTED, &vif->flags) &&
482             vif->ssid_len == sme->ssid_len &&
483             !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
484                 vif->reconnect_flag = true;
485                 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
486                                                   vif->req_bssid,
487                                                   vif->ch_hint);
488
489                 up(&ar->sem);
490                 if (status) {
491                         ath6kl_err("wmi_reconnect_cmd failed\n");
492                         return -EIO;
493                 }
494                 return 0;
495         } else if (vif->ssid_len == sme->ssid_len &&
496                    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
497                 ath6kl_disconnect(vif);
498         }
499
500         memset(vif->ssid, 0, sizeof(vif->ssid));
501         vif->ssid_len = sme->ssid_len;
502         memcpy(vif->ssid, sme->ssid, sme->ssid_len);
503
504         if (sme->channel)
505                 vif->ch_hint = sme->channel->center_freq;
506
507         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
508         if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
509                 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
510
511         ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
512
513         status = ath6kl_set_auth_type(vif, sme->auth_type);
514         if (status) {
515                 up(&ar->sem);
516                 return status;
517         }
518
519         if (sme->crypto.n_ciphers_pairwise)
520                 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
521         else
522                 ath6kl_set_cipher(vif, 0, true);
523
524         ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
525
526         if (sme->crypto.n_akm_suites)
527                 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
528
529         if ((sme->key_len) &&
530             (vif->auth_mode == NONE_AUTH) &&
531             (vif->prwise_crypto == WEP_CRYPT)) {
532                 struct ath6kl_key *key = NULL;
533
534                 if (sme->key_idx > WMI_MAX_KEY_INDEX) {
535                         ath6kl_err("key index %d out of bounds\n",
536                                    sme->key_idx);
537                         up(&ar->sem);
538                         return -ENOENT;
539                 }
540
541                 key = &vif->keys[sme->key_idx];
542                 key->key_len = sme->key_len;
543                 memcpy(key->key, sme->key, key->key_len);
544                 key->cipher = vif->prwise_crypto;
545                 vif->def_txkey_index = sme->key_idx;
546
547                 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
548                                       vif->prwise_crypto,
549                                       GROUP_USAGE | TX_USAGE,
550                                       key->key_len,
551                                       NULL, 0,
552                                       key->key, KEY_OP_INIT_VAL, NULL,
553                                       NO_SYNC_WMIFLAG);
554         }
555
556         if (!ar->usr_bss_filter) {
557                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
558                 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
559                                              ALL_BSS_FILTER, 0) != 0) {
560                         ath6kl_err("couldn't set bss filtering\n");
561                         up(&ar->sem);
562                         return -EIO;
563                 }
564         }
565
566         vif->nw_type = vif->next_mode;
567
568         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
569                 nw_subtype = SUBTYPE_P2PCLIENT;
570
571         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
572                    "%s: connect called with authmode %d dot11 auth %d"
573                    " PW crypto %d PW crypto len %d GRP crypto %d"
574                    " GRP crypto len %d channel hint %u\n",
575                    __func__,
576                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
577                    vif->prwise_crypto_len, vif->grp_crypto,
578                    vif->grp_crypto_len, vif->ch_hint);
579
580         vif->reconnect_flag = 0;
581
582         if (vif->nw_type == INFRA_NETWORK) {
583                 interval = max(vif->listen_intvl_t,
584                                (u16) ATH6KL_MAX_WOW_LISTEN_INTL);
585                 status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
586                                                        interval,
587                                                        0);
588                 if (status) {
589                         ath6kl_err("couldn't set listen intervel\n");
590                         up(&ar->sem);
591                         return status;
592                 }
593         }
594
595         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
596                                         vif->dot11_auth_mode, vif->auth_mode,
597                                         vif->prwise_crypto,
598                                         vif->prwise_crypto_len,
599                                         vif->grp_crypto, vif->grp_crypto_len,
600                                         vif->ssid_len, vif->ssid,
601                                         vif->req_bssid, vif->ch_hint,
602                                         ar->connect_ctrl_flags, nw_subtype);
603
604         up(&ar->sem);
605
606         if (status == -EINVAL) {
607                 memset(vif->ssid, 0, sizeof(vif->ssid));
608                 vif->ssid_len = 0;
609                 ath6kl_err("invalid request\n");
610                 return -ENOENT;
611         } else if (status) {
612                 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
613                 return -EIO;
614         }
615
616         if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
617             ((vif->auth_mode == WPA_PSK_AUTH) ||
618              (vif->auth_mode == WPA2_PSK_AUTH))) {
619                 mod_timer(&vif->disconnect_timer,
620                           jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
621         }
622
623         ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
624         set_bit(CONNECT_PEND, &vif->flags);
625
626         return 0;
627 }
628
629 static struct cfg80211_bss *
630 ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
631                          enum network_type nw_type,
632                          const u8 *bssid,
633                          struct ieee80211_channel *chan,
634                          const u8 *beacon_ie,
635                          size_t beacon_ie_len)
636 {
637         struct ath6kl *ar = vif->ar;
638         struct cfg80211_bss *bss;
639         u16 cap_mask, cap_val;
640         u8 *ie;
641
642         if (nw_type & ADHOC_NETWORK) {
643                 cap_mask = WLAN_CAPABILITY_IBSS;
644                 cap_val = WLAN_CAPABILITY_IBSS;
645         } else {
646                 cap_mask = WLAN_CAPABILITY_ESS;
647                 cap_val = WLAN_CAPABILITY_ESS;
648         }
649
650         bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
651                                vif->ssid, vif->ssid_len,
652                                cap_mask, cap_val);
653         if (bss == NULL) {
654                 /*
655                  * Since cfg80211 may not yet know about the BSS,
656                  * generate a partial entry until the first BSS info
657                  * event becomes available.
658                  *
659                  * Prepend SSID element since it is not included in the Beacon
660                  * IEs from the target.
661                  */
662                 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
663                 if (ie == NULL)
664                         return NULL;
665                 ie[0] = WLAN_EID_SSID;
666                 ie[1] = vif->ssid_len;
667                 memcpy(ie + 2, vif->ssid, vif->ssid_len);
668                 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
669                 bss = cfg80211_inform_bss(ar->wiphy, chan,
670                                           bssid, 0, cap_val, 100,
671                                           ie, 2 + vif->ssid_len + beacon_ie_len,
672                                           0, GFP_KERNEL);
673                 if (bss)
674                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
675                                    "cfg80211\n", bssid);
676                 kfree(ie);
677         } else
678                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
679
680         return bss;
681 }
682
683 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
684                                    u8 *bssid, u16 listen_intvl,
685                                    u16 beacon_intvl,
686                                    enum network_type nw_type,
687                                    u8 beacon_ie_len, u8 assoc_req_len,
688                                    u8 assoc_resp_len, u8 *assoc_info)
689 {
690         struct ieee80211_channel *chan;
691         struct ath6kl *ar = vif->ar;
692         struct cfg80211_bss *bss;
693
694         /* capinfo + listen interval */
695         u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
696
697         /* capinfo + status code +  associd */
698         u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
699
700         u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
701         u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
702             assoc_resp_ie_offset;
703
704         assoc_req_len -= assoc_req_ie_offset;
705         assoc_resp_len -= assoc_resp_ie_offset;
706
707         /*
708          * Store Beacon interval here; DTIM period will be available only once
709          * a Beacon frame from the AP is seen.
710          */
711         vif->assoc_bss_beacon_int = beacon_intvl;
712         clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
713
714         if (nw_type & ADHOC_NETWORK) {
715                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
716                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
717                                    "%s: ath6k not in ibss mode\n", __func__);
718                         return;
719                 }
720         }
721
722         if (nw_type & INFRA_NETWORK) {
723                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
724                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
725                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
726                                    "%s: ath6k not in station mode\n", __func__);
727                         return;
728                 }
729         }
730
731         chan = ieee80211_get_channel(ar->wiphy, (int) channel);
732
733         bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
734                                        assoc_info, beacon_ie_len);
735         if (!bss) {
736                 ath6kl_err("could not add cfg80211 bss entry\n");
737                 return;
738         }
739
740         if (nw_type & ADHOC_NETWORK) {
741                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
742                            nw_type & ADHOC_CREATOR ? "creator" : "joiner");
743                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
744                 cfg80211_put_bss(bss);
745                 return;
746         }
747
748         if (vif->sme_state == SME_CONNECTING) {
749                 /* inform connect result to cfg80211 */
750                 vif->sme_state = SME_CONNECTED;
751                 cfg80211_connect_result(vif->ndev, bssid,
752                                         assoc_req_ie, assoc_req_len,
753                                         assoc_resp_ie, assoc_resp_len,
754                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
755                 cfg80211_put_bss(bss);
756         } else if (vif->sme_state == SME_CONNECTED) {
757                 /* inform roam event to cfg80211 */
758                 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
759                                     assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
760         }
761 }
762
763 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
764                                       struct net_device *dev, u16 reason_code)
765 {
766         struct ath6kl *ar = ath6kl_priv(dev);
767         struct ath6kl_vif *vif = netdev_priv(dev);
768
769         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
770                    reason_code);
771
772         ath6kl_cfg80211_sscan_disable(vif);
773
774         if (!ath6kl_cfg80211_ready(vif))
775                 return -EIO;
776
777         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
778                 ath6kl_err("busy, destroy in progress\n");
779                 return -EBUSY;
780         }
781
782         if (down_interruptible(&ar->sem)) {
783                 ath6kl_err("busy, couldn't get access\n");
784                 return -ERESTARTSYS;
785         }
786
787         vif->reconnect_flag = 0;
788         ath6kl_disconnect(vif);
789         memset(vif->ssid, 0, sizeof(vif->ssid));
790         vif->ssid_len = 0;
791
792         if (!test_bit(SKIP_SCAN, &ar->flag))
793                 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
794
795         up(&ar->sem);
796
797         vif->sme_state = SME_DISCONNECTED;
798
799         return 0;
800 }
801
802 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
803                                       u8 *bssid, u8 assoc_resp_len,
804                                       u8 *assoc_info, u16 proto_reason)
805 {
806         struct ath6kl *ar = vif->ar;
807
808         if (vif->scan_req) {
809                 cfg80211_scan_done(vif->scan_req, true);
810                 vif->scan_req = NULL;
811         }
812
813         if (vif->nw_type & ADHOC_NETWORK) {
814                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
815                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
816                                    "%s: ath6k not in ibss mode\n", __func__);
817                         return;
818                 }
819                 memset(bssid, 0, ETH_ALEN);
820                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
821                 return;
822         }
823
824         if (vif->nw_type & INFRA_NETWORK) {
825                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
826                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
827                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
828                                    "%s: ath6k not in station mode\n", __func__);
829                         return;
830                 }
831         }
832
833         /*
834          * Send a disconnect command to target when a disconnect event is
835          * received with reason code other than 3 (DISCONNECT_CMD - disconnect
836          * request from host) to make the firmware stop trying to connect even
837          * after giving disconnect event. There will be one more disconnect
838          * event for this disconnect command with reason code DISCONNECT_CMD
839          * which will be notified to cfg80211.
840          */
841
842         if (reason != DISCONNECT_CMD) {
843                 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
844                 return;
845         }
846
847         clear_bit(CONNECT_PEND, &vif->flags);
848
849         if (vif->sme_state == SME_CONNECTING) {
850                 cfg80211_connect_result(vif->ndev,
851                                         bssid, NULL, 0,
852                                         NULL, 0,
853                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
854                                         GFP_KERNEL);
855         } else if (vif->sme_state == SME_CONNECTED) {
856                 cfg80211_disconnected(vif->ndev, reason,
857                                       NULL, 0, GFP_KERNEL);
858         }
859
860         vif->sme_state = SME_DISCONNECTED;
861 }
862
863 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
864                                 struct cfg80211_scan_request *request)
865 {
866         struct ath6kl *ar = ath6kl_priv(ndev);
867         struct ath6kl_vif *vif = netdev_priv(ndev);
868         s8 n_channels = 0;
869         u16 *channels = NULL;
870         int ret = 0;
871         u32 force_fg_scan = 0;
872
873         if (!ath6kl_cfg80211_ready(vif))
874                 return -EIO;
875
876         ath6kl_cfg80211_sscan_disable(vif);
877
878         if (!ar->usr_bss_filter) {
879                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
880                 ret = ath6kl_wmi_bssfilter_cmd(
881                         ar->wmi, vif->fw_vif_idx,
882                         (test_bit(CONNECTED, &vif->flags) ?
883                          ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
884                 if (ret) {
885                         ath6kl_err("couldn't set bss filtering\n");
886                         return ret;
887                 }
888         }
889
890         if (request->n_ssids && request->ssids[0].ssid_len) {
891                 u8 i;
892
893                 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
894                         request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
895
896                 for (i = 0; i < request->n_ssids; i++)
897                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
898                                                   i + 1, SPECIFIC_SSID_FLAG,
899                                                   request->ssids[i].ssid_len,
900                                                   request->ssids[i].ssid);
901         }
902
903         /* this also clears IE in fw if it's not set */
904         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
905                                        WMI_FRAME_PROBE_REQ,
906                                        request->ie, request->ie_len);
907         if (ret) {
908                 ath6kl_err("failed to set Probe Request appie for "
909                            "scan");
910                 return ret;
911         }
912
913         /*
914          * Scan only the requested channels if the request specifies a set of
915          * channels. If the list is longer than the target supports, do not
916          * configure the list and instead, scan all available channels.
917          */
918         if (request->n_channels > 0 &&
919             request->n_channels <= WMI_MAX_CHANNELS) {
920                 u8 i;
921
922                 n_channels = request->n_channels;
923
924                 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
925                 if (channels == NULL) {
926                         ath6kl_warn("failed to set scan channels, "
927                                     "scan all channels");
928                         n_channels = 0;
929                 }
930
931                 for (i = 0; i < n_channels; i++)
932                         channels[i] = request->channels[i]->center_freq;
933         }
934
935         if (test_bit(CONNECTED, &vif->flags))
936                 force_fg_scan = 1;
937
938         if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
939                      ar->fw_capabilities)) {
940                 /*
941                  * If capable of doing P2P mgmt operations using
942                  * station interface, send additional information like
943                  * supported rates to advertise and xmit rates for
944                  * probe requests
945                  */
946                 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
947                                                 WMI_LONG_SCAN, force_fg_scan,
948                                                 false, 0,
949                                                 ATH6KL_FG_SCAN_INTERVAL,
950                                                 n_channels, channels,
951                                                 request->no_cck,
952                                                 request->rates);
953         } else {
954                 ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
955                                                 WMI_LONG_SCAN, force_fg_scan,
956                                                 false, 0,
957                                                 ATH6KL_FG_SCAN_INTERVAL,
958                                                 n_channels, channels);
959         }
960         if (ret)
961                 ath6kl_err("wmi_startscan_cmd failed\n");
962         else
963                 vif->scan_req = request;
964
965         kfree(channels);
966
967         return ret;
968 }
969
970 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
971 {
972         struct ath6kl *ar = vif->ar;
973         int i;
974
975         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
976                    aborted ? " aborted" : "");
977
978         if (!vif->scan_req)
979                 return;
980
981         if (aborted)
982                 goto out;
983
984         if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
985                 for (i = 0; i < vif->scan_req->n_ssids; i++) {
986                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
987                                                   i + 1, DISABLE_SSID_FLAG,
988                                                   0, NULL);
989                 }
990         }
991
992 out:
993         cfg80211_scan_done(vif->scan_req, aborted);
994         vif->scan_req = NULL;
995 }
996
997 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
998                                    u8 key_index, bool pairwise,
999                                    const u8 *mac_addr,
1000                                    struct key_params *params)
1001 {
1002         struct ath6kl *ar = ath6kl_priv(ndev);
1003         struct ath6kl_vif *vif = netdev_priv(ndev);
1004         struct ath6kl_key *key = NULL;
1005         int seq_len;
1006         u8 key_usage;
1007         u8 key_type;
1008
1009         if (!ath6kl_cfg80211_ready(vif))
1010                 return -EIO;
1011
1012         if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1013                 if (params->key_len != WMI_KRK_LEN)
1014                         return -EINVAL;
1015                 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1016                                               params->key);
1017         }
1018
1019         if (key_index > WMI_MAX_KEY_INDEX) {
1020                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1021                            "%s: key index %d out of bounds\n", __func__,
1022                            key_index);
1023                 return -ENOENT;
1024         }
1025
1026         key = &vif->keys[key_index];
1027         memset(key, 0, sizeof(struct ath6kl_key));
1028
1029         if (pairwise)
1030                 key_usage = PAIRWISE_USAGE;
1031         else
1032                 key_usage = GROUP_USAGE;
1033
1034         seq_len = params->seq_len;
1035         if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1036             seq_len > ATH6KL_KEY_SEQ_LEN) {
1037                 /* Only first half of the WPI PN is configured */
1038                 seq_len = ATH6KL_KEY_SEQ_LEN;
1039         }
1040         if (params->key_len > WLAN_MAX_KEY_LEN ||
1041             seq_len > sizeof(key->seq))
1042                 return -EINVAL;
1043
1044         key->key_len = params->key_len;
1045         memcpy(key->key, params->key, key->key_len);
1046         key->seq_len = seq_len;
1047         memcpy(key->seq, params->seq, key->seq_len);
1048         key->cipher = params->cipher;
1049
1050         switch (key->cipher) {
1051         case WLAN_CIPHER_SUITE_WEP40:
1052         case WLAN_CIPHER_SUITE_WEP104:
1053                 key_type = WEP_CRYPT;
1054                 break;
1055
1056         case WLAN_CIPHER_SUITE_TKIP:
1057                 key_type = TKIP_CRYPT;
1058                 break;
1059
1060         case WLAN_CIPHER_SUITE_CCMP:
1061                 key_type = AES_CRYPT;
1062                 break;
1063         case WLAN_CIPHER_SUITE_SMS4:
1064                 key_type = WAPI_CRYPT;
1065                 break;
1066
1067         default:
1068                 return -ENOTSUPP;
1069         }
1070
1071         if (((vif->auth_mode == WPA_PSK_AUTH) ||
1072              (vif->auth_mode == WPA2_PSK_AUTH)) &&
1073             (key_usage & GROUP_USAGE))
1074                 del_timer(&vif->disconnect_timer);
1075
1076         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1077                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1078                    __func__, key_index, key->key_len, key_type,
1079                    key_usage, key->seq_len);
1080
1081         if (vif->nw_type == AP_NETWORK && !pairwise &&
1082             (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1083              key_type == WAPI_CRYPT)) {
1084                 ar->ap_mode_bkey.valid = true;
1085                 ar->ap_mode_bkey.key_index = key_index;
1086                 ar->ap_mode_bkey.key_type = key_type;
1087                 ar->ap_mode_bkey.key_len = key->key_len;
1088                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1089                 if (!test_bit(CONNECTED, &vif->flags)) {
1090                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
1091                                    "key configuration until AP mode has been "
1092                                    "started\n");
1093                         /*
1094                          * The key will be set in ath6kl_connect_ap_mode() once
1095                          * the connected event is received from the target.
1096                          */
1097                         return 0;
1098                 }
1099         }
1100
1101         if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1102             !test_bit(CONNECTED, &vif->flags)) {
1103                 /*
1104                  * Store the key locally so that it can be re-configured after
1105                  * the AP mode has properly started
1106                  * (ath6kl_install_statioc_wep_keys).
1107                  */
1108                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
1109                            "until AP mode has been started\n");
1110                 vif->wep_key_list[key_index].key_len = key->key_len;
1111                 memcpy(vif->wep_key_list[key_index].key, key->key,
1112                        key->key_len);
1113                 return 0;
1114         }
1115
1116         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1117                                      key_type, key_usage, key->key_len,
1118                                      key->seq, key->seq_len, key->key,
1119                                      KEY_OP_INIT_VAL,
1120                                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1121 }
1122
1123 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1124                                    u8 key_index, bool pairwise,
1125                                    const u8 *mac_addr)
1126 {
1127         struct ath6kl *ar = ath6kl_priv(ndev);
1128         struct ath6kl_vif *vif = netdev_priv(ndev);
1129
1130         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1131
1132         if (!ath6kl_cfg80211_ready(vif))
1133                 return -EIO;
1134
1135         if (key_index > WMI_MAX_KEY_INDEX) {
1136                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1137                            "%s: key index %d out of bounds\n", __func__,
1138                            key_index);
1139                 return -ENOENT;
1140         }
1141
1142         if (!vif->keys[key_index].key_len) {
1143                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1144                            "%s: index %d is empty\n", __func__, key_index);
1145                 return 0;
1146         }
1147
1148         vif->keys[key_index].key_len = 0;
1149
1150         return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1151 }
1152
1153 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1154                                    u8 key_index, bool pairwise,
1155                                    const u8 *mac_addr, void *cookie,
1156                                    void (*callback) (void *cookie,
1157                                                      struct key_params *))
1158 {
1159         struct ath6kl_vif *vif = netdev_priv(ndev);
1160         struct ath6kl_key *key = NULL;
1161         struct key_params params;
1162
1163         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1164
1165         if (!ath6kl_cfg80211_ready(vif))
1166                 return -EIO;
1167
1168         if (key_index > WMI_MAX_KEY_INDEX) {
1169                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1170                            "%s: key index %d out of bounds\n", __func__,
1171                            key_index);
1172                 return -ENOENT;
1173         }
1174
1175         key = &vif->keys[key_index];
1176         memset(&params, 0, sizeof(params));
1177         params.cipher = key->cipher;
1178         params.key_len = key->key_len;
1179         params.seq_len = key->seq_len;
1180         params.seq = key->seq;
1181         params.key = key->key;
1182
1183         callback(cookie, &params);
1184
1185         return key->key_len ? 0 : -ENOENT;
1186 }
1187
1188 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1189                                            struct net_device *ndev,
1190                                            u8 key_index, bool unicast,
1191                                            bool multicast)
1192 {
1193         struct ath6kl *ar = ath6kl_priv(ndev);
1194         struct ath6kl_vif *vif = netdev_priv(ndev);
1195         struct ath6kl_key *key = NULL;
1196         u8 key_usage;
1197         enum crypto_type key_type = NONE_CRYPT;
1198
1199         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1200
1201         if (!ath6kl_cfg80211_ready(vif))
1202                 return -EIO;
1203
1204         if (key_index > WMI_MAX_KEY_INDEX) {
1205                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1206                            "%s: key index %d out of bounds\n",
1207                            __func__, key_index);
1208                 return -ENOENT;
1209         }
1210
1211         if (!vif->keys[key_index].key_len) {
1212                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1213                            __func__, key_index);
1214                 return -EINVAL;
1215         }
1216
1217         vif->def_txkey_index = key_index;
1218         key = &vif->keys[vif->def_txkey_index];
1219         key_usage = GROUP_USAGE;
1220         if (vif->prwise_crypto == WEP_CRYPT)
1221                 key_usage |= TX_USAGE;
1222         if (unicast)
1223                 key_type = vif->prwise_crypto;
1224         if (multicast)
1225                 key_type = vif->grp_crypto;
1226
1227         if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1228                 return 0; /* Delay until AP mode has been started */
1229
1230         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1231                                      vif->def_txkey_index,
1232                                      key_type, key_usage,
1233                                      key->key_len, key->seq, key->seq_len,
1234                                      key->key,
1235                                      KEY_OP_INIT_VAL, NULL,
1236                                      SYNC_BOTH_WMIFLAG);
1237 }
1238
1239 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1240                                        bool ismcast)
1241 {
1242         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1243                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1244
1245         cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1246                                      (ismcast ? NL80211_KEYTYPE_GROUP :
1247                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1248                                      GFP_KERNEL);
1249 }
1250
1251 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1252 {
1253         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1254         struct ath6kl_vif *vif;
1255         int ret;
1256
1257         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1258                    changed);
1259
1260         vif = ath6kl_vif_first(ar);
1261         if (!vif)
1262                 return -EIO;
1263
1264         if (!ath6kl_cfg80211_ready(vif))
1265                 return -EIO;
1266
1267         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1268                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1269                 if (ret != 0) {
1270                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1271                         return -EIO;
1272                 }
1273         }
1274
1275         return 0;
1276 }
1277
1278 /*
1279  * The type nl80211_tx_power_setting replaces the following
1280  * data type from 2.6.36 onwards
1281 */
1282 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1283                                        enum nl80211_tx_power_setting type,
1284                                        int mbm)
1285 {
1286         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1287         struct ath6kl_vif *vif;
1288         u8 ath6kl_dbm;
1289         int dbm = MBM_TO_DBM(mbm);
1290
1291         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1292                    type, dbm);
1293
1294         vif = ath6kl_vif_first(ar);
1295         if (!vif)
1296                 return -EIO;
1297
1298         if (!ath6kl_cfg80211_ready(vif))
1299                 return -EIO;
1300
1301         switch (type) {
1302         case NL80211_TX_POWER_AUTOMATIC:
1303                 return 0;
1304         case NL80211_TX_POWER_LIMITED:
1305                 ar->tx_pwr = ath6kl_dbm = dbm;
1306                 break;
1307         default:
1308                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1309                            __func__, type);
1310                 return -EOPNOTSUPP;
1311         }
1312
1313         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
1314
1315         return 0;
1316 }
1317
1318 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1319 {
1320         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1321         struct ath6kl_vif *vif;
1322
1323         vif = ath6kl_vif_first(ar);
1324         if (!vif)
1325                 return -EIO;
1326
1327         if (!ath6kl_cfg80211_ready(vif))
1328                 return -EIO;
1329
1330         if (test_bit(CONNECTED, &vif->flags)) {
1331                 ar->tx_pwr = 0;
1332
1333                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1334                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1335                         return -EIO;
1336                 }
1337
1338                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1339                                                  5 * HZ);
1340
1341                 if (signal_pending(current)) {
1342                         ath6kl_err("target did not respond\n");
1343                         return -EINTR;
1344                 }
1345         }
1346
1347         *dbm = ar->tx_pwr;
1348         return 0;
1349 }
1350
1351 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1352                                           struct net_device *dev,
1353                                           bool pmgmt, int timeout)
1354 {
1355         struct ath6kl *ar = ath6kl_priv(dev);
1356         struct wmi_power_mode_cmd mode;
1357         struct ath6kl_vif *vif = netdev_priv(dev);
1358
1359         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1360                    __func__, pmgmt, timeout);
1361
1362         if (!ath6kl_cfg80211_ready(vif))
1363                 return -EIO;
1364
1365         if (pmgmt) {
1366                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1367                 mode.pwr_mode = REC_POWER;
1368         } else {
1369                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1370                 mode.pwr_mode = MAX_PERF_POWER;
1371         }
1372
1373         if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1374                                      mode.pwr_mode) != 0) {
1375                 ath6kl_err("wmi_powermode_cmd failed\n");
1376                 return -EIO;
1377         }
1378
1379         return 0;
1380 }
1381
1382 static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1383                                                     char *name,
1384                                                     enum nl80211_iftype type,
1385                                                     u32 *flags,
1386                                                     struct vif_params *params)
1387 {
1388         struct ath6kl *ar = wiphy_priv(wiphy);
1389         struct net_device *ndev;
1390         u8 if_idx, nw_type;
1391
1392         if (ar->num_vif == ar->vif_max) {
1393                 ath6kl_err("Reached maximum number of supported vif\n");
1394                 return ERR_PTR(-EINVAL);
1395         }
1396
1397         if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1398                 ath6kl_err("Not a supported interface type\n");
1399                 return ERR_PTR(-EINVAL);
1400         }
1401
1402         ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1403         if (!ndev)
1404                 return ERR_PTR(-ENOMEM);
1405
1406         ar->num_vif++;
1407
1408         return ndev;
1409 }
1410
1411 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1412                                      struct net_device *ndev)
1413 {
1414         struct ath6kl *ar = wiphy_priv(wiphy);
1415         struct ath6kl_vif *vif = netdev_priv(ndev);
1416
1417         spin_lock_bh(&ar->list_lock);
1418         list_del(&vif->list);
1419         spin_unlock_bh(&ar->list_lock);
1420
1421         ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1422
1423         ath6kl_cfg80211_vif_cleanup(vif);
1424
1425         return 0;
1426 }
1427
1428 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1429                                         struct net_device *ndev,
1430                                         enum nl80211_iftype type, u32 *flags,
1431                                         struct vif_params *params)
1432 {
1433         struct ath6kl_vif *vif = netdev_priv(ndev);
1434
1435         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1436
1437         switch (type) {
1438         case NL80211_IFTYPE_STATION:
1439                 vif->next_mode = INFRA_NETWORK;
1440                 break;
1441         case NL80211_IFTYPE_ADHOC:
1442                 vif->next_mode = ADHOC_NETWORK;
1443                 break;
1444         case NL80211_IFTYPE_AP:
1445                 vif->next_mode = AP_NETWORK;
1446                 break;
1447         case NL80211_IFTYPE_P2P_CLIENT:
1448                 vif->next_mode = INFRA_NETWORK;
1449                 break;
1450         case NL80211_IFTYPE_P2P_GO:
1451                 vif->next_mode = AP_NETWORK;
1452                 break;
1453         default:
1454                 ath6kl_err("invalid interface type %u\n", type);
1455                 return -EOPNOTSUPP;
1456         }
1457
1458         vif->wdev.iftype = type;
1459
1460         return 0;
1461 }
1462
1463 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1464                                      struct net_device *dev,
1465                                      struct cfg80211_ibss_params *ibss_param)
1466 {
1467         struct ath6kl *ar = ath6kl_priv(dev);
1468         struct ath6kl_vif *vif = netdev_priv(dev);
1469         int status;
1470
1471         if (!ath6kl_cfg80211_ready(vif))
1472                 return -EIO;
1473
1474         vif->ssid_len = ibss_param->ssid_len;
1475         memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1476
1477         if (ibss_param->channel)
1478                 vif->ch_hint = ibss_param->channel->center_freq;
1479
1480         if (ibss_param->channel_fixed) {
1481                 /*
1482                  * TODO: channel_fixed: The channel should be fixed, do not
1483                  * search for IBSSs to join on other channels. Target
1484                  * firmware does not support this feature, needs to be
1485                  * updated.
1486                  */
1487                 return -EOPNOTSUPP;
1488         }
1489
1490         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1491         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1492                 memcpy(vif->req_bssid, ibss_param->bssid,
1493                        sizeof(vif->req_bssid));
1494
1495         ath6kl_set_wpa_version(vif, 0);
1496
1497         status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1498         if (status)
1499                 return status;
1500
1501         if (ibss_param->privacy) {
1502                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1503                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1504         } else {
1505                 ath6kl_set_cipher(vif, 0, true);
1506                 ath6kl_set_cipher(vif, 0, false);
1507         }
1508
1509         vif->nw_type = vif->next_mode;
1510
1511         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1512                    "%s: connect called with authmode %d dot11 auth %d"
1513                    " PW crypto %d PW crypto len %d GRP crypto %d"
1514                    " GRP crypto len %d channel hint %u\n",
1515                    __func__,
1516                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1517                    vif->prwise_crypto_len, vif->grp_crypto,
1518                    vif->grp_crypto_len, vif->ch_hint);
1519
1520         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1521                                         vif->dot11_auth_mode, vif->auth_mode,
1522                                         vif->prwise_crypto,
1523                                         vif->prwise_crypto_len,
1524                                         vif->grp_crypto, vif->grp_crypto_len,
1525                                         vif->ssid_len, vif->ssid,
1526                                         vif->req_bssid, vif->ch_hint,
1527                                         ar->connect_ctrl_flags, SUBTYPE_NONE);
1528         set_bit(CONNECT_PEND, &vif->flags);
1529
1530         return 0;
1531 }
1532
1533 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1534                                       struct net_device *dev)
1535 {
1536         struct ath6kl_vif *vif = netdev_priv(dev);
1537
1538         if (!ath6kl_cfg80211_ready(vif))
1539                 return -EIO;
1540
1541         ath6kl_disconnect(vif);
1542         memset(vif->ssid, 0, sizeof(vif->ssid));
1543         vif->ssid_len = 0;
1544
1545         return 0;
1546 }
1547
1548 static const u32 cipher_suites[] = {
1549         WLAN_CIPHER_SUITE_WEP40,
1550         WLAN_CIPHER_SUITE_WEP104,
1551         WLAN_CIPHER_SUITE_TKIP,
1552         WLAN_CIPHER_SUITE_CCMP,
1553         CCKM_KRK_CIPHER_SUITE,
1554         WLAN_CIPHER_SUITE_SMS4,
1555 };
1556
1557 static bool is_rate_legacy(s32 rate)
1558 {
1559         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1560                 6000, 9000, 12000, 18000, 24000,
1561                 36000, 48000, 54000
1562         };
1563         u8 i;
1564
1565         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1566                 if (rate == legacy[i])
1567                         return true;
1568
1569         return false;
1570 }
1571
1572 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1573 {
1574         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1575                 52000, 58500, 65000, 72200
1576         };
1577         u8 i;
1578
1579         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1580                 if (rate == ht20[i]) {
1581                         if (i == ARRAY_SIZE(ht20) - 1)
1582                                 /* last rate uses sgi */
1583                                 *sgi = true;
1584                         else
1585                                 *sgi = false;
1586
1587                         *mcs = i;
1588                         return true;
1589                 }
1590         }
1591         return false;
1592 }
1593
1594 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1595 {
1596         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1597                 81000, 108000, 121500, 135000,
1598                 150000
1599         };
1600         u8 i;
1601
1602         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1603                 if (rate == ht40[i]) {
1604                         if (i == ARRAY_SIZE(ht40) - 1)
1605                                 /* last rate uses sgi */
1606                                 *sgi = true;
1607                         else
1608                                 *sgi = false;
1609
1610                         *mcs = i;
1611                         return true;
1612                 }
1613         }
1614
1615         return false;
1616 }
1617
1618 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1619                               u8 *mac, struct station_info *sinfo)
1620 {
1621         struct ath6kl *ar = ath6kl_priv(dev);
1622         struct ath6kl_vif *vif = netdev_priv(dev);
1623         long left;
1624         bool sgi;
1625         s32 rate;
1626         int ret;
1627         u8 mcs;
1628
1629         if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1630                 return -ENOENT;
1631
1632         if (down_interruptible(&ar->sem))
1633                 return -EBUSY;
1634
1635         set_bit(STATS_UPDATE_PEND, &vif->flags);
1636
1637         ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1638
1639         if (ret != 0) {
1640                 up(&ar->sem);
1641                 return -EIO;
1642         }
1643
1644         left = wait_event_interruptible_timeout(ar->event_wq,
1645                                                 !test_bit(STATS_UPDATE_PEND,
1646                                                           &vif->flags),
1647                                                 WMI_TIMEOUT);
1648
1649         up(&ar->sem);
1650
1651         if (left == 0)
1652                 return -ETIMEDOUT;
1653         else if (left < 0)
1654                 return left;
1655
1656         if (vif->target_stats.rx_byte) {
1657                 sinfo->rx_bytes = vif->target_stats.rx_byte;
1658                 sinfo->filled |= STATION_INFO_RX_BYTES;
1659                 sinfo->rx_packets = vif->target_stats.rx_pkt;
1660                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1661         }
1662
1663         if (vif->target_stats.tx_byte) {
1664                 sinfo->tx_bytes = vif->target_stats.tx_byte;
1665                 sinfo->filled |= STATION_INFO_TX_BYTES;
1666                 sinfo->tx_packets = vif->target_stats.tx_pkt;
1667                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1668         }
1669
1670         sinfo->signal = vif->target_stats.cs_rssi;
1671         sinfo->filled |= STATION_INFO_SIGNAL;
1672
1673         rate = vif->target_stats.tx_ucast_rate;
1674
1675         if (is_rate_legacy(rate)) {
1676                 sinfo->txrate.legacy = rate / 100;
1677         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1678                 if (sgi) {
1679                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1680                         sinfo->txrate.mcs = mcs - 1;
1681                 } else {
1682                         sinfo->txrate.mcs = mcs;
1683                 }
1684
1685                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1686         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1687                 if (sgi) {
1688                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1689                         sinfo->txrate.mcs = mcs - 1;
1690                 } else {
1691                         sinfo->txrate.mcs = mcs;
1692                 }
1693
1694                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1695                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1696         } else {
1697                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1698                            "invalid rate from stats: %d\n", rate);
1699                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1700                 return 0;
1701         }
1702
1703         sinfo->filled |= STATION_INFO_TX_BITRATE;
1704
1705         if (test_bit(CONNECTED, &vif->flags) &&
1706             test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1707             vif->nw_type == INFRA_NETWORK) {
1708                 sinfo->filled |= STATION_INFO_BSS_PARAM;
1709                 sinfo->bss_param.flags = 0;
1710                 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1711                 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1712         }
1713
1714         return 0;
1715 }
1716
1717 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1718                             struct cfg80211_pmksa *pmksa)
1719 {
1720         struct ath6kl *ar = ath6kl_priv(netdev);
1721         struct ath6kl_vif *vif = netdev_priv(netdev);
1722
1723         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1724                                        pmksa->pmkid, true);
1725 }
1726
1727 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1728                             struct cfg80211_pmksa *pmksa)
1729 {
1730         struct ath6kl *ar = ath6kl_priv(netdev);
1731         struct ath6kl_vif *vif = netdev_priv(netdev);
1732
1733         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1734                                        pmksa->pmkid, false);
1735 }
1736
1737 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1738 {
1739         struct ath6kl *ar = ath6kl_priv(netdev);
1740         struct ath6kl_vif *vif = netdev_priv(netdev);
1741
1742         if (test_bit(CONNECTED, &vif->flags))
1743                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1744                                                vif->bssid, NULL, false);
1745         return 0;
1746 }
1747
1748 static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1749                           struct cfg80211_wowlan *wow, u32 *filter)
1750 {
1751         int ret, pos;
1752         u8 mask[WOW_MASK_SIZE];
1753         u16 i;
1754
1755         /* Configure the patterns that we received from the user. */
1756         for (i = 0; i < wow->n_patterns; i++) {
1757
1758                 /*
1759                  * Convert given nl80211 specific mask value to equivalent
1760                  * driver specific mask value and send it to the chip along
1761                  * with patterns. For example, If the mask value defined in
1762                  * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1763                  * then equivalent driver specific mask value is
1764                  * "0xFF 0x00 0xFF 0x00".
1765                  */
1766                 memset(&mask, 0, sizeof(mask));
1767                 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1768                         if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1769                                 mask[pos] = 0xFF;
1770                 }
1771                 /*
1772                  * Note: Pattern's offset is not passed as part of wowlan
1773                  * parameter from CFG layer. So it's always passed as ZERO
1774                  * to the firmware. It means, given WOW patterns are always
1775                  * matched from the first byte of received pkt in the firmware.
1776                  */
1777                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1778                                 vif->fw_vif_idx, WOW_LIST_ID,
1779                                 wow->patterns[i].pattern_len,
1780                                 0 /* pattern offset */,
1781                                 wow->patterns[i].pattern, mask);
1782                 if (ret)
1783                         return ret;
1784         }
1785
1786         if (wow->disconnect)
1787                 *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1788
1789         if (wow->magic_pkt)
1790                 *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1791
1792         if (wow->gtk_rekey_failure)
1793                 *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1794
1795         if (wow->eap_identity_req)
1796                 *filter |= WOW_FILTER_OPTION_EAP_REQ;
1797
1798         if (wow->four_way_handshake)
1799                 *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1800
1801         return 0;
1802 }
1803
1804 static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1805 {
1806         static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1807                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1808                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809                 0x00, 0x08 };
1810         static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1811                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1812                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1813                 0x00, 0x7f };
1814         u8 unicst_offset = 0;
1815         static const u8 arp_pattern[] = { 0x08, 0x06 };
1816         static const u8 arp_mask[] = { 0xff, 0xff };
1817         u8 arp_offset = 20;
1818         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1819         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1820         u8 discvr_offset = 38;
1821         static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1822                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1823                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1824                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1825                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1826                 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1827         static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1828                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1829                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1830                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1831                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1832                 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1833         u8 dhcp_offset = 0;
1834         int ret;
1835
1836         /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1837         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1838                         vif->fw_vif_idx, WOW_LIST_ID,
1839                         sizeof(unicst_pattern), unicst_offset,
1840                         unicst_pattern, unicst_mask);
1841         if (ret) {
1842                 ath6kl_err("failed to add WOW unicast IP pattern\n");
1843                 return ret;
1844         }
1845
1846         /* Setup all ARP pkt pattern */
1847         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1848                         vif->fw_vif_idx, WOW_LIST_ID,
1849                         sizeof(arp_pattern), arp_offset,
1850                         arp_pattern, arp_mask);
1851         if (ret) {
1852                 ath6kl_err("failed to add WOW ARP pattern\n");
1853                 return ret;
1854         }
1855
1856         /*
1857          * Setup multicast pattern for mDNS 224.0.0.251,
1858          * SSDP 239.255.255.250 and LLMNR  224.0.0.252
1859          */
1860         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1861                         vif->fw_vif_idx, WOW_LIST_ID,
1862                         sizeof(discvr_pattern), discvr_offset,
1863                         discvr_pattern, discvr_mask);
1864         if (ret) {
1865                 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
1866                 return ret;
1867         }
1868
1869         /* Setup all DHCP broadcast pkt pattern */
1870         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1871                         vif->fw_vif_idx, WOW_LIST_ID,
1872                         sizeof(dhcp_pattern), dhcp_offset,
1873                         dhcp_pattern, dhcp_mask);
1874         if (ret) {
1875                 ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
1876                 return ret;
1877         }
1878
1879         return 0;
1880 }
1881
1882 static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
1883 {
1884         struct net_device *ndev = vif->ndev;
1885         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1886         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1887         u8 discvr_offset = 38;
1888         u8 mac_mask[ETH_ALEN];
1889         int ret;
1890
1891         /* Setup unicast pkt pattern */
1892         memset(mac_mask, 0xff, ETH_ALEN);
1893         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1894                                 vif->fw_vif_idx, WOW_LIST_ID,
1895                                 ETH_ALEN, 0, ndev->dev_addr,
1896                                 mac_mask);
1897         if (ret) {
1898                 ath6kl_err("failed to add WOW unicast pattern\n");
1899                 return ret;
1900         }
1901
1902         /*
1903          * Setup multicast pattern for mDNS 224.0.0.251,
1904          * SSDP 239.255.255.250 and LLMNR 224.0.0.252
1905          */
1906         if ((ndev->flags & IFF_ALLMULTI) ||
1907             (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
1908                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1909                                 vif->fw_vif_idx, WOW_LIST_ID,
1910                                 sizeof(discvr_pattern), discvr_offset,
1911                                 discvr_pattern, discvr_mask);
1912                 if (ret) {
1913                         ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
1914                                    "pattern\n");
1915                         return ret;
1916                 }
1917         }
1918
1919         return 0;
1920 }
1921
1922 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1923 {
1924         struct in_device *in_dev;
1925         struct in_ifaddr *ifa;
1926         struct ath6kl_vif *vif;
1927         int ret, left;
1928         u32 filter = 0;
1929         u16 i, bmiss_time;
1930         u8 index = 0;
1931         __be32 ips[MAX_IP_ADDRS];
1932
1933         vif = ath6kl_vif_first(ar);
1934         if (!vif)
1935                 return -EIO;
1936
1937         if (!ath6kl_cfg80211_ready(vif))
1938                 return -EIO;
1939
1940         if (!test_bit(CONNECTED, &vif->flags))
1941                 return -ENOTCONN;
1942
1943         if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
1944                 return -EINVAL;
1945
1946         /* Clear existing WOW patterns */
1947         for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1948                 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1949                                                WOW_LIST_ID, i);
1950
1951         /*
1952          * Skip the default WOW pattern configuration
1953          * if the driver receives any WOW patterns from
1954          * the user.
1955          */
1956         if (wow)
1957                 ret = ath6kl_wow_usr(ar, vif, wow, &filter);
1958         else if (vif->nw_type == AP_NETWORK)
1959                 ret = ath6kl_wow_ap(ar, vif);
1960         else
1961                 ret = ath6kl_wow_sta(ar, vif);
1962
1963         if (ret)
1964                 return ret;
1965
1966         netif_stop_queue(vif->ndev);
1967
1968         if (vif->nw_type != AP_NETWORK) {
1969                 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
1970                                                     ATH6KL_MAX_WOW_LISTEN_INTL,
1971                                                     0);
1972                 if (ret)
1973                         return ret;
1974
1975                 /* Set listen interval x 15 times as bmiss time */
1976                 bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
1977                 if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
1978                         bmiss_time = ATH6KL_MAX_BMISS_TIME;
1979
1980                 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
1981                                                bmiss_time, 0);
1982                 if (ret)
1983                         return ret;
1984
1985                 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
1986                                                 0xFFFF, 0, 0xFFFF, 0, 0, 0,
1987                                                 0, 0, 0, 0);
1988                 if (ret)
1989                         return ret;
1990         }
1991
1992         ar->state = ATH6KL_STATE_SUSPENDING;
1993
1994         /* Setup own IP addr for ARP agent. */
1995         in_dev = __in_dev_get_rtnl(vif->ndev);
1996         if (!in_dev)
1997                 goto skip_arp;
1998
1999         ifa = in_dev->ifa_list;
2000         memset(&ips, 0, sizeof(ips));
2001
2002         /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2003         while (index < MAX_IP_ADDRS && ifa) {
2004                 ips[index] = ifa->ifa_local;
2005                 ifa = ifa->ifa_next;
2006                 index++;
2007         }
2008
2009         if (ifa) {
2010                 ath6kl_err("total IP addr count is exceeding fw limit\n");
2011                 return -EINVAL;
2012         }
2013
2014         ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2015         if (ret) {
2016                 ath6kl_err("fail to setup ip for arp agent\n");
2017                 return ret;
2018         }
2019
2020 skip_arp:
2021         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2022                                           ATH6KL_WOW_MODE_ENABLE,
2023                                           filter,
2024                                           WOW_HOST_REQ_DELAY);
2025         if (ret)
2026                 return ret;
2027
2028         clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2029
2030         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2031                                                  ATH6KL_HOST_MODE_ASLEEP);
2032         if (ret)
2033                 return ret;
2034
2035         left = wait_event_interruptible_timeout(ar->event_wq,
2036                         test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
2037                         WMI_TIMEOUT);
2038         if (left == 0) {
2039                 ath6kl_warn("timeout, didn't get host sleep cmd "
2040                             "processed event\n");
2041                 ret = -ETIMEDOUT;
2042         } else if (left < 0) {
2043                 ath6kl_warn("error while waiting for host sleep cmd "
2044                             "processed event %d\n", left);
2045                 ret = left;
2046         }
2047
2048         if (ar->tx_pending[ar->ctrl_ep]) {
2049                 left = wait_event_interruptible_timeout(ar->event_wq,
2050                                 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
2051                 if (left == 0) {
2052                         ath6kl_warn("clear wmi ctrl data timeout\n");
2053                         ret = -ETIMEDOUT;
2054                 } else if (left < 0) {
2055                         ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2056                         ret = left;
2057                 }
2058         }
2059
2060         return ret;
2061 }
2062
2063 static int ath6kl_wow_resume(struct ath6kl *ar)
2064 {
2065         struct ath6kl_vif *vif;
2066         int ret;
2067
2068         vif = ath6kl_vif_first(ar);
2069         if (!vif)
2070                 return -EIO;
2071
2072         ar->state = ATH6KL_STATE_RESUMING;
2073
2074         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2075                                                  ATH6KL_HOST_MODE_AWAKE);
2076         if (ret) {
2077                 ath6kl_warn("Failed to configure host sleep mode for "
2078                             "wow resume: %d\n", ret);
2079                 ar->state = ATH6KL_STATE_WOW;
2080                 return ret;
2081         }
2082
2083         if (vif->nw_type != AP_NETWORK) {
2084                 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2085                                                 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2086                 if (ret)
2087                         return ret;
2088
2089                 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2090                                                     vif->listen_intvl_t, 0);
2091                 if (ret)
2092                         return ret;
2093
2094                 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2095                                                vif->bmiss_time_t, 0);
2096                 if (ret)
2097                         return ret;
2098         }
2099
2100         ar->state = ATH6KL_STATE_ON;
2101
2102         netif_wake_queue(vif->ndev);
2103
2104         return 0;
2105 }
2106
2107 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2108                             enum ath6kl_cfg_suspend_mode mode,
2109                             struct cfg80211_wowlan *wow)
2110 {
2111         enum ath6kl_state prev_state;
2112         int ret;
2113
2114         switch (mode) {
2115         case ATH6KL_CFG_SUSPEND_WOW:
2116
2117                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2118
2119                 /* Flush all non control pkts in TX path */
2120                 ath6kl_tx_data_cleanup(ar);
2121
2122                 prev_state = ar->state;
2123
2124                 ret = ath6kl_wow_suspend(ar, wow);
2125                 if (ret) {
2126                         ar->state = prev_state;
2127                         return ret;
2128                 }
2129
2130                 ar->state = ATH6KL_STATE_WOW;
2131                 break;
2132
2133         case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2134
2135                 ath6kl_cfg80211_stop_all(ar);
2136
2137                 /* save the current power mode before enabling power save */
2138                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2139
2140                 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2141                 if (ret) {
2142                         ath6kl_warn("wmi powermode command failed during suspend: %d\n",
2143                                     ret);
2144                 }
2145
2146                 ar->state = ATH6KL_STATE_DEEPSLEEP;
2147
2148                 break;
2149
2150         case ATH6KL_CFG_SUSPEND_CUTPOWER:
2151
2152                 ath6kl_cfg80211_stop_all(ar);
2153
2154                 if (ar->state == ATH6KL_STATE_OFF) {
2155                         ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2156                                    "suspend hw off, no action for cutpower\n");
2157                         break;
2158                 }
2159
2160                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2161
2162                 ret = ath6kl_init_hw_stop(ar);
2163                 if (ret) {
2164                         ath6kl_warn("failed to stop hw during suspend: %d\n",
2165                                     ret);
2166                 }
2167
2168                 ar->state = ATH6KL_STATE_CUTPOWER;
2169
2170                 break;
2171
2172         case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
2173                 /*
2174                  * Nothing needed for schedule scan, firmware is already in
2175                  * wow mode and sleeping most of the time.
2176                  */
2177                 break;
2178
2179         default:
2180                 break;
2181         }
2182
2183         return 0;
2184 }
2185 EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2186
2187 int ath6kl_cfg80211_resume(struct ath6kl *ar)
2188 {
2189         int ret;
2190
2191         switch (ar->state) {
2192         case  ATH6KL_STATE_WOW:
2193                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2194
2195                 ret = ath6kl_wow_resume(ar);
2196                 if (ret) {
2197                         ath6kl_warn("wow mode resume failed: %d\n", ret);
2198                         return ret;
2199                 }
2200
2201                 break;
2202
2203         case ATH6KL_STATE_DEEPSLEEP:
2204                 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2205                         ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2206                                                        ar->wmi->saved_pwr_mode);
2207                         if (ret) {
2208                                 ath6kl_warn("wmi powermode command failed during resume: %d\n",
2209                                             ret);
2210                         }
2211                 }
2212
2213                 ar->state = ATH6KL_STATE_ON;
2214
2215                 break;
2216
2217         case ATH6KL_STATE_CUTPOWER:
2218                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2219
2220                 ret = ath6kl_init_hw_start(ar);
2221                 if (ret) {
2222                         ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2223                         return ret;
2224                 }
2225                 break;
2226
2227         case ATH6KL_STATE_SCHED_SCAN:
2228                 break;
2229
2230         default:
2231                 break;
2232         }
2233
2234         return 0;
2235 }
2236 EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2237
2238 #ifdef CONFIG_PM
2239
2240 /* hif layer decides what suspend mode to use */
2241 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2242                                  struct cfg80211_wowlan *wow)
2243 {
2244         struct ath6kl *ar = wiphy_priv(wiphy);
2245
2246         return ath6kl_hif_suspend(ar, wow);
2247 }
2248
2249 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2250 {
2251         struct ath6kl *ar = wiphy_priv(wiphy);
2252
2253         return ath6kl_hif_resume(ar);
2254 }
2255
2256 /*
2257  * FIXME: WOW suspend mode is selected if the host sdio controller supports
2258  * both sdio irq wake up and keep power. The target pulls sdio data line to
2259  * wake up the host when WOW pattern matches. This causes sdio irq handler
2260  * is being called in the host side which internally hits ath6kl's RX path.
2261  *
2262  * Since sdio interrupt is not disabled, RX path executes even before
2263  * the host executes the actual resume operation from PM module.
2264  *
2265  * In the current scenario, WOW resume should happen before start processing
2266  * any data from the target. So It's required to perform WOW resume in RX path.
2267  * Ideally we should perform WOW resume only in the actual platform
2268  * resume path. This area needs bit rework to avoid WOW resume in RX path.
2269  *
2270  * ath6kl_check_wow_status() is called from ath6kl_rx().
2271  */
2272 void ath6kl_check_wow_status(struct ath6kl *ar)
2273 {
2274         if (ar->state == ATH6KL_STATE_SUSPENDING)
2275                 return;
2276
2277         if (ar->state == ATH6KL_STATE_WOW)
2278                 ath6kl_cfg80211_resume(ar);
2279 }
2280
2281 #else
2282
2283 void ath6kl_check_wow_status(struct ath6kl *ar)
2284 {
2285 }
2286 #endif
2287
2288 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
2289                               struct ieee80211_channel *chan,
2290                               enum nl80211_channel_type channel_type)
2291 {
2292         struct ath6kl_vif *vif;
2293
2294         /*
2295          * 'dev' could be NULL if a channel change is required for the hardware
2296          * device itself, instead of a particular VIF.
2297          *
2298          * FIXME: To be handled properly when monitor mode is supported.
2299          */
2300         if (!dev)
2301                 return -EBUSY;
2302
2303         vif = netdev_priv(dev);
2304
2305         if (!ath6kl_cfg80211_ready(vif))
2306                 return -EIO;
2307
2308         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
2309                    __func__, chan->center_freq, chan->hw_value);
2310         vif->next_chan = chan->center_freq;
2311
2312         return 0;
2313 }
2314
2315 static bool ath6kl_is_p2p_ie(const u8 *pos)
2316 {
2317         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2318                 pos[2] == 0x50 && pos[3] == 0x6f &&
2319                 pos[4] == 0x9a && pos[5] == 0x09;
2320 }
2321
2322 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2323                                         const u8 *ies, size_t ies_len)
2324 {
2325         struct ath6kl *ar = vif->ar;
2326         const u8 *pos;
2327         u8 *buf = NULL;
2328         size_t len = 0;
2329         int ret;
2330
2331         /*
2332          * Filter out P2P IE(s) since they will be included depending on
2333          * the Probe Request frame in ath6kl_send_go_probe_resp().
2334          */
2335
2336         if (ies && ies_len) {
2337                 buf = kmalloc(ies_len, GFP_KERNEL);
2338                 if (buf == NULL)
2339                         return -ENOMEM;
2340                 pos = ies;
2341                 while (pos + 1 < ies + ies_len) {
2342                         if (pos + 2 + pos[1] > ies + ies_len)
2343                                 break;
2344                         if (!ath6kl_is_p2p_ie(pos)) {
2345                                 memcpy(buf + len, pos, 2 + pos[1]);
2346                                 len += 2 + pos[1];
2347                         }
2348                         pos += 2 + pos[1];
2349                 }
2350         }
2351
2352         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2353                                        WMI_FRAME_PROBE_RESP, buf, len);
2354         kfree(buf);
2355         return ret;
2356 }
2357
2358 static int ath6kl_set_ies(struct ath6kl_vif *vif,
2359                           struct cfg80211_beacon_data *info)
2360 {
2361         struct ath6kl *ar = vif->ar;
2362         int res;
2363
2364         if (info->beacon_ies) {
2365                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2366                                                WMI_FRAME_BEACON,
2367                                                info->beacon_ies,
2368                                                info->beacon_ies_len);
2369                 if (res)
2370                         return res;
2371         }
2372
2373         if (info->proberesp_ies) {
2374                 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2375                                                    info->proberesp_ies_len);
2376                 if (res)
2377                         return res;
2378         }
2379
2380         if (info->assocresp_ies) {
2381                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2382                                                WMI_FRAME_ASSOC_RESP,
2383                                                info->assocresp_ies,
2384                                                info->assocresp_ies_len);
2385                 if (res)
2386                         return res;
2387         }
2388
2389         return 0;
2390 }
2391
2392 static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2393                            struct cfg80211_ap_settings *info)
2394 {
2395         struct ath6kl *ar = ath6kl_priv(dev);
2396         struct ath6kl_vif *vif = netdev_priv(dev);
2397         struct ieee80211_mgmt *mgmt;
2398         bool hidden = false;
2399         u8 *ies;
2400         int ies_len;
2401         struct wmi_connect_cmd p;
2402         int res;
2403         int i, ret;
2404
2405         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2406
2407         if (!ath6kl_cfg80211_ready(vif))
2408                 return -EIO;
2409
2410         if (vif->next_mode != AP_NETWORK)
2411                 return -EOPNOTSUPP;
2412
2413         res = ath6kl_set_ies(vif, &info->beacon);
2414
2415         ar->ap_mode_bkey.valid = false;
2416
2417         /* TODO:
2418          * info->interval
2419          * info->dtim_period
2420          */
2421
2422         if (info->beacon.head == NULL)
2423                 return -EINVAL;
2424         mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2425         ies = mgmt->u.beacon.variable;
2426         if (ies > info->beacon.head + info->beacon.head_len)
2427                 return -EINVAL;
2428         ies_len = info->beacon.head + info->beacon.head_len - ies;
2429
2430         if (info->ssid == NULL)
2431                 return -EINVAL;
2432         memcpy(vif->ssid, info->ssid, info->ssid_len);
2433         vif->ssid_len = info->ssid_len;
2434         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2435                 hidden = true;
2436
2437         res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2438         if (res)
2439                 return res;
2440
2441         ret = ath6kl_set_auth_type(vif, info->auth_type);
2442         if (ret)
2443                 return ret;
2444
2445         memset(&p, 0, sizeof(p));
2446
2447         for (i = 0; i < info->crypto.n_akm_suites; i++) {
2448                 switch (info->crypto.akm_suites[i]) {
2449                 case WLAN_AKM_SUITE_8021X:
2450                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2451                                 p.auth_mode |= WPA_AUTH;
2452                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2453                                 p.auth_mode |= WPA2_AUTH;
2454                         break;
2455                 case WLAN_AKM_SUITE_PSK:
2456                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2457                                 p.auth_mode |= WPA_PSK_AUTH;
2458                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2459                                 p.auth_mode |= WPA2_PSK_AUTH;
2460                         break;
2461                 }
2462         }
2463         if (p.auth_mode == 0)
2464                 p.auth_mode = NONE_AUTH;
2465         vif->auth_mode = p.auth_mode;
2466
2467         for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2468                 switch (info->crypto.ciphers_pairwise[i]) {
2469                 case WLAN_CIPHER_SUITE_WEP40:
2470                 case WLAN_CIPHER_SUITE_WEP104:
2471                         p.prwise_crypto_type |= WEP_CRYPT;
2472                         break;
2473                 case WLAN_CIPHER_SUITE_TKIP:
2474                         p.prwise_crypto_type |= TKIP_CRYPT;
2475                         break;
2476                 case WLAN_CIPHER_SUITE_CCMP:
2477                         p.prwise_crypto_type |= AES_CRYPT;
2478                         break;
2479                 case WLAN_CIPHER_SUITE_SMS4:
2480                         p.prwise_crypto_type |= WAPI_CRYPT;
2481                         break;
2482                 }
2483         }
2484         if (p.prwise_crypto_type == 0) {
2485                 p.prwise_crypto_type = NONE_CRYPT;
2486                 ath6kl_set_cipher(vif, 0, true);
2487         } else if (info->crypto.n_ciphers_pairwise == 1)
2488                 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2489
2490         switch (info->crypto.cipher_group) {
2491         case WLAN_CIPHER_SUITE_WEP40:
2492         case WLAN_CIPHER_SUITE_WEP104:
2493                 p.grp_crypto_type = WEP_CRYPT;
2494                 break;
2495         case WLAN_CIPHER_SUITE_TKIP:
2496                 p.grp_crypto_type = TKIP_CRYPT;
2497                 break;
2498         case WLAN_CIPHER_SUITE_CCMP:
2499                 p.grp_crypto_type = AES_CRYPT;
2500                 break;
2501         case WLAN_CIPHER_SUITE_SMS4:
2502                 p.grp_crypto_type = WAPI_CRYPT;
2503                 break;
2504         default:
2505                 p.grp_crypto_type = NONE_CRYPT;
2506                 break;
2507         }
2508         ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2509
2510         p.nw_type = AP_NETWORK;
2511         vif->nw_type = vif->next_mode;
2512
2513         p.ssid_len = vif->ssid_len;
2514         memcpy(p.ssid, vif->ssid, vif->ssid_len);
2515         p.dot11_auth_mode = vif->dot11_auth_mode;
2516         p.ch = cpu_to_le16(vif->next_chan);
2517
2518         /* Enable uAPSD support by default */
2519         res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2520         if (res < 0)
2521                 return res;
2522
2523         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2524                 p.nw_subtype = SUBTYPE_P2PGO;
2525         } else {
2526                 /*
2527                  * Due to firmware limitation, it is not possible to
2528                  * do P2P mgmt operations in AP mode
2529                  */
2530                 p.nw_subtype = SUBTYPE_NONE;
2531         }
2532
2533         res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2534         if (res < 0)
2535                 return res;
2536
2537         return 0;
2538 }
2539
2540 static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2541                                 struct cfg80211_beacon_data *beacon)
2542 {
2543         struct ath6kl_vif *vif = netdev_priv(dev);
2544
2545         if (!ath6kl_cfg80211_ready(vif))
2546                 return -EIO;
2547
2548         if (vif->next_mode != AP_NETWORK)
2549                 return -EOPNOTSUPP;
2550
2551         return ath6kl_set_ies(vif, beacon);
2552 }
2553
2554 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2555 {
2556         struct ath6kl *ar = ath6kl_priv(dev);
2557         struct ath6kl_vif *vif = netdev_priv(dev);
2558
2559         if (vif->nw_type != AP_NETWORK)
2560                 return -EOPNOTSUPP;
2561         if (!test_bit(CONNECTED, &vif->flags))
2562                 return -ENOTCONN;
2563
2564         ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2565         clear_bit(CONNECTED, &vif->flags);
2566
2567         return 0;
2568 }
2569
2570 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2571
2572 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2573                               u8 *mac)
2574 {
2575         struct ath6kl *ar = ath6kl_priv(dev);
2576         struct ath6kl_vif *vif = netdev_priv(dev);
2577         const u8 *addr = mac ? mac : bcast_addr;
2578
2579         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2580                                       addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2581 }
2582
2583 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2584                                  u8 *mac, struct station_parameters *params)
2585 {
2586         struct ath6kl *ar = ath6kl_priv(dev);
2587         struct ath6kl_vif *vif = netdev_priv(dev);
2588
2589         if (vif->nw_type != AP_NETWORK)
2590                 return -EOPNOTSUPP;
2591
2592         /* Use this only for authorizing/unauthorizing a station */
2593         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
2594                 return -EOPNOTSUPP;
2595
2596         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2597                 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2598                                               WMI_AP_MLME_AUTHORIZE, mac, 0);
2599         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2600                                       WMI_AP_MLME_UNAUTHORIZE, mac, 0);
2601 }
2602
2603 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
2604                                     struct net_device *dev,
2605                                     struct ieee80211_channel *chan,
2606                                     enum nl80211_channel_type channel_type,
2607                                     unsigned int duration,
2608                                     u64 *cookie)
2609 {
2610         struct ath6kl *ar = ath6kl_priv(dev);
2611         struct ath6kl_vif *vif = netdev_priv(dev);
2612         u32 id;
2613
2614         /* TODO: if already pending or ongoing remain-on-channel,
2615          * return -EBUSY */
2616         id = ++vif->last_roc_id;
2617         if (id == 0) {
2618                 /* Do not use 0 as the cookie value */
2619                 id = ++vif->last_roc_id;
2620         }
2621         *cookie = id;
2622
2623         return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
2624                                              chan->center_freq, duration);
2625 }
2626
2627 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
2628                                            struct net_device *dev,
2629                                            u64 cookie)
2630 {
2631         struct ath6kl *ar = ath6kl_priv(dev);
2632         struct ath6kl_vif *vif = netdev_priv(dev);
2633
2634         if (cookie != vif->last_roc_id)
2635                 return -ENOENT;
2636         vif->last_cancel_roc_id = cookie;
2637
2638         return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
2639 }
2640
2641 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
2642                                      const u8 *buf, size_t len,
2643                                      unsigned int freq)
2644 {
2645         struct ath6kl *ar = vif->ar;
2646         const u8 *pos;
2647         u8 *p2p;
2648         int p2p_len;
2649         int ret;
2650         const struct ieee80211_mgmt *mgmt;
2651
2652         mgmt = (const struct ieee80211_mgmt *) buf;
2653
2654         /* Include P2P IE(s) from the frame generated in user space. */
2655
2656         p2p = kmalloc(len, GFP_KERNEL);
2657         if (p2p == NULL)
2658                 return -ENOMEM;
2659         p2p_len = 0;
2660
2661         pos = mgmt->u.probe_resp.variable;
2662         while (pos + 1 < buf + len) {
2663                 if (pos + 2 + pos[1] > buf + len)
2664                         break;
2665                 if (ath6kl_is_p2p_ie(pos)) {
2666                         memcpy(p2p + p2p_len, pos, 2 + pos[1]);
2667                         p2p_len += 2 + pos[1];
2668                 }
2669                 pos += 2 + pos[1];
2670         }
2671
2672         ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
2673                                                  mgmt->da, p2p, p2p_len);
2674         kfree(p2p);
2675         return ret;
2676 }
2677
2678 static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
2679                                      u32 id,
2680                                      u32 freq,
2681                                      u32 wait,
2682                                      const u8 *buf,
2683                                      size_t len,
2684                                      bool *more_data,
2685                                      bool no_cck)
2686 {
2687         struct ieee80211_mgmt *mgmt;
2688         struct ath6kl_sta *conn;
2689         bool is_psq_empty = false;
2690         struct ath6kl_mgmt_buff *mgmt_buf;
2691         size_t mgmt_buf_size;
2692         struct ath6kl *ar = vif->ar;
2693
2694         mgmt = (struct ieee80211_mgmt *) buf;
2695         if (is_multicast_ether_addr(mgmt->da))
2696                 return false;
2697
2698         conn = ath6kl_find_sta(vif, mgmt->da);
2699         if (!conn)
2700                 return false;
2701
2702         if (conn->sta_flags & STA_PS_SLEEP) {
2703                 if (!(conn->sta_flags & STA_PS_POLLED)) {
2704                         /* Queue the frames if the STA is sleeping */
2705                         mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
2706                         mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
2707                         if (!mgmt_buf)
2708                                 return false;
2709
2710                         INIT_LIST_HEAD(&mgmt_buf->list);
2711                         mgmt_buf->id = id;
2712                         mgmt_buf->freq = freq;
2713                         mgmt_buf->wait = wait;
2714                         mgmt_buf->len = len;
2715                         mgmt_buf->no_cck = no_cck;
2716                         memcpy(mgmt_buf->buf, buf, len);
2717                         spin_lock_bh(&conn->psq_lock);
2718                         is_psq_empty = skb_queue_empty(&conn->psq) &&
2719                                         (conn->mgmt_psq_len == 0);
2720                         list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
2721                         conn->mgmt_psq_len++;
2722                         spin_unlock_bh(&conn->psq_lock);
2723
2724                         /*
2725                          * If this is the first pkt getting queued
2726                          * for this STA, update the PVB for this
2727                          * STA.
2728                          */
2729                         if (is_psq_empty)
2730                                 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
2731                                                        conn->aid, 1);
2732                         return true;
2733                 }
2734
2735                 /*
2736                  * This tx is because of a PsPoll.
2737                  * Determine if MoreData bit has to be set.
2738                  */
2739                 spin_lock_bh(&conn->psq_lock);
2740                 if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
2741                         *more_data = true;
2742                 spin_unlock_bh(&conn->psq_lock);
2743         }
2744
2745         return false;
2746 }
2747
2748 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2749                           struct ieee80211_channel *chan, bool offchan,
2750                           enum nl80211_channel_type channel_type,
2751                           bool channel_type_valid, unsigned int wait,
2752                           const u8 *buf, size_t len, bool no_cck,
2753                           bool dont_wait_for_ack, u64 *cookie)
2754 {
2755         struct ath6kl *ar = ath6kl_priv(dev);
2756         struct ath6kl_vif *vif = netdev_priv(dev);
2757         u32 id;
2758         const struct ieee80211_mgmt *mgmt;
2759         bool more_data, queued;
2760
2761         mgmt = (const struct ieee80211_mgmt *) buf;
2762         if (buf + len >= mgmt->u.probe_resp.variable &&
2763             vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
2764             ieee80211_is_probe_resp(mgmt->frame_control)) {
2765                 /*
2766                  * Send Probe Response frame in AP mode using a separate WMI
2767                  * command to allow the target to fill in the generic IEs.
2768                  */
2769                 *cookie = 0; /* TX status not supported */
2770                 return ath6kl_send_go_probe_resp(vif, buf, len,
2771                                                  chan->center_freq);
2772         }
2773
2774         id = vif->send_action_id++;
2775         if (id == 0) {
2776                 /*
2777                  * 0 is a reserved value in the WMI command and shall not be
2778                  * used for the command.
2779                  */
2780                 id = vif->send_action_id++;
2781         }
2782
2783         *cookie = id;
2784
2785         /* AP mode Power saving processing */
2786         if (vif->nw_type == AP_NETWORK) {
2787                 queued = ath6kl_mgmt_powersave_ap(vif,
2788                                         id, chan->center_freq,
2789                                         wait, buf,
2790                                         len, &more_data, no_cck);
2791                 if (queued)
2792                         return 0;
2793         }
2794
2795         return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
2796                                         chan->center_freq, wait,
2797                                         buf, len, no_cck);
2798 }
2799
2800 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
2801                                        struct net_device *dev,
2802                                        u16 frame_type, bool reg)
2803 {
2804         struct ath6kl_vif *vif = netdev_priv(dev);
2805
2806         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
2807                    __func__, frame_type, reg);
2808         if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
2809                 /*
2810                  * Note: This notification callback is not allowed to sleep, so
2811                  * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2812                  * hardcode target to report Probe Request frames all the time.
2813                  */
2814                 vif->probe_req_report = reg;
2815         }
2816 }
2817
2818 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
2819                         struct net_device *dev,
2820                         struct cfg80211_sched_scan_request *request)
2821 {
2822         struct ath6kl *ar = ath6kl_priv(dev);
2823         struct ath6kl_vif *vif = netdev_priv(dev);
2824         u16 interval;
2825         int ret;
2826         u8 i;
2827
2828         if (ar->state != ATH6KL_STATE_ON)
2829                 return -EIO;
2830
2831         if (vif->sme_state != SME_DISCONNECTED)
2832                 return -EBUSY;
2833
2834         for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) {
2835                 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
2836                                           i, DISABLE_SSID_FLAG,
2837                                           0, NULL);
2838         }
2839
2840         /* fw uses seconds, also make sure that it's >0 */
2841         interval = max_t(u16, 1, request->interval / 1000);
2842
2843         ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2844                                   interval, interval,
2845                                   10, 0, 0, 0, 3, 0, 0, 0);
2846
2847         if (request->n_ssids && request->ssids[0].ssid_len) {
2848                 for (i = 0; i < request->n_ssids; i++) {
2849                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
2850                                                   i, SPECIFIC_SSID_FLAG,
2851                                                   request->ssids[i].ssid_len,
2852                                                   request->ssids[i].ssid);
2853                 }
2854         }
2855
2856         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2857                                           ATH6KL_WOW_MODE_ENABLE,
2858                                           WOW_FILTER_SSID,
2859                                           WOW_HOST_REQ_DELAY);
2860         if (ret) {
2861                 ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
2862                 return ret;
2863         }
2864
2865         /* this also clears IE in fw if it's not set */
2866         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2867                                        WMI_FRAME_PROBE_REQ,
2868                                        request->ie, request->ie_len);
2869         if (ret) {
2870                 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
2871                             ret);
2872                 return ret;
2873         }
2874
2875         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2876                                                  ATH6KL_HOST_MODE_ASLEEP);
2877         if (ret) {
2878                 ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
2879                             ret);
2880                 return ret;
2881         }
2882
2883         ar->state = ATH6KL_STATE_SCHED_SCAN;
2884
2885         return ret;
2886 }
2887
2888 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
2889                                       struct net_device *dev)
2890 {
2891         struct ath6kl_vif *vif = netdev_priv(dev);
2892         bool stopped;
2893
2894         stopped = __ath6kl_cfg80211_sscan_stop(vif);
2895
2896         if (!stopped)
2897                 return -EIO;
2898
2899         return 0;
2900 }
2901
2902 static const struct ieee80211_txrx_stypes
2903 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2904         [NL80211_IFTYPE_STATION] = {
2905                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2906                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2907                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2908                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2909         },
2910         [NL80211_IFTYPE_AP] = {
2911                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2912                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2913                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2914                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2915         },
2916         [NL80211_IFTYPE_P2P_CLIENT] = {
2917                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2918                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2919                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2920                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2921         },
2922         [NL80211_IFTYPE_P2P_GO] = {
2923                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2924                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2925                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2926                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2927         },
2928 };
2929
2930 static struct cfg80211_ops ath6kl_cfg80211_ops = {
2931         .add_virtual_intf = ath6kl_cfg80211_add_iface,
2932         .del_virtual_intf = ath6kl_cfg80211_del_iface,
2933         .change_virtual_intf = ath6kl_cfg80211_change_iface,
2934         .scan = ath6kl_cfg80211_scan,
2935         .connect = ath6kl_cfg80211_connect,
2936         .disconnect = ath6kl_cfg80211_disconnect,
2937         .add_key = ath6kl_cfg80211_add_key,
2938         .get_key = ath6kl_cfg80211_get_key,
2939         .del_key = ath6kl_cfg80211_del_key,
2940         .set_default_key = ath6kl_cfg80211_set_default_key,
2941         .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
2942         .set_tx_power = ath6kl_cfg80211_set_txpower,
2943         .get_tx_power = ath6kl_cfg80211_get_txpower,
2944         .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
2945         .join_ibss = ath6kl_cfg80211_join_ibss,
2946         .leave_ibss = ath6kl_cfg80211_leave_ibss,
2947         .get_station = ath6kl_get_station,
2948         .set_pmksa = ath6kl_set_pmksa,
2949         .del_pmksa = ath6kl_del_pmksa,
2950         .flush_pmksa = ath6kl_flush_pmksa,
2951         CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
2952 #ifdef CONFIG_PM
2953         .suspend = __ath6kl_cfg80211_suspend,
2954         .resume = __ath6kl_cfg80211_resume,
2955 #endif
2956         .set_channel = ath6kl_set_channel,
2957         .start_ap = ath6kl_start_ap,
2958         .change_beacon = ath6kl_change_beacon,
2959         .stop_ap = ath6kl_stop_ap,
2960         .del_station = ath6kl_del_station,
2961         .change_station = ath6kl_change_station,
2962         .remain_on_channel = ath6kl_remain_on_channel,
2963         .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
2964         .mgmt_tx = ath6kl_mgmt_tx,
2965         .mgmt_frame_register = ath6kl_mgmt_frame_register,
2966         .sched_scan_start = ath6kl_cfg80211_sscan_start,
2967         .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
2968 };
2969
2970 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
2971 {
2972         ath6kl_cfg80211_sscan_disable(vif);
2973
2974         switch (vif->sme_state) {
2975         case SME_DISCONNECTED:
2976                 break;
2977         case SME_CONNECTING:
2978                 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
2979                                         NULL, 0,
2980                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
2981                                         GFP_KERNEL);
2982                 break;
2983         case SME_CONNECTED:
2984                 cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
2985                 break;
2986         }
2987
2988         if (test_bit(CONNECTED, &vif->flags) ||
2989             test_bit(CONNECT_PEND, &vif->flags))
2990                 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
2991
2992         vif->sme_state = SME_DISCONNECTED;
2993         clear_bit(CONNECTED, &vif->flags);
2994         clear_bit(CONNECT_PEND, &vif->flags);
2995
2996         /* disable scanning */
2997         if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
2998                                       0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
2999                 ath6kl_warn("failed to disable scan during stop\n");
3000
3001         ath6kl_cfg80211_scan_complete_event(vif, true);
3002 }
3003
3004 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3005 {
3006         struct ath6kl_vif *vif;
3007
3008         vif = ath6kl_vif_first(ar);
3009         if (!vif) {
3010                 /* save the current power mode before enabling power save */
3011                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3012
3013                 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
3014                         ath6kl_warn("ath6kl_deep_sleep_enable: "
3015                                     "wmi_powermode_cmd failed\n");
3016                 return;
3017         }
3018
3019         /*
3020          * FIXME: we should take ar->list_lock to protect changes in the
3021          * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3022          * sleeps.
3023          */
3024         list_for_each_entry(vif, &ar->vif_list, list)
3025                 ath6kl_cfg80211_stop(vif);
3026 }
3027
3028 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
3029 {
3030         vif->aggr_cntxt = aggr_init(vif);
3031         if (!vif->aggr_cntxt) {
3032                 ath6kl_err("failed to initialize aggr\n");
3033                 return -ENOMEM;
3034         }
3035
3036         setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
3037                     (unsigned long) vif->ndev);
3038         setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3039                     (unsigned long) vif);
3040
3041         set_bit(WMM_ENABLED, &vif->flags);
3042         spin_lock_init(&vif->if_lock);
3043
3044         INIT_LIST_HEAD(&vif->mc_filter);
3045
3046         return 0;
3047 }
3048
3049 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
3050 {
3051         struct ath6kl *ar = vif->ar;
3052         struct ath6kl_mc_filter *mc_filter, *tmp;
3053
3054         aggr_module_destroy(vif->aggr_cntxt);
3055
3056         ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3057
3058         if (vif->nw_type == ADHOC_NETWORK)
3059                 ar->ibss_if_active = false;
3060
3061         list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3062                 list_del(&mc_filter->list);
3063                 kfree(mc_filter);
3064         }
3065
3066         unregister_netdevice(vif->ndev);
3067
3068         ar->num_vif--;
3069 }
3070
3071 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
3072                                         enum nl80211_iftype type, u8 fw_vif_idx,
3073                                         u8 nw_type)
3074 {
3075         struct net_device *ndev;
3076         struct ath6kl_vif *vif;
3077
3078         ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
3079         if (!ndev)
3080                 return NULL;
3081
3082         vif = netdev_priv(ndev);
3083         ndev->ieee80211_ptr = &vif->wdev;
3084         vif->wdev.wiphy = ar->wiphy;
3085         vif->ar = ar;
3086         vif->ndev = ndev;
3087         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3088         vif->wdev.netdev = ndev;
3089         vif->wdev.iftype = type;
3090         vif->fw_vif_idx = fw_vif_idx;
3091         vif->nw_type = vif->next_mode = nw_type;
3092         vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
3093         vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
3094
3095         memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
3096         if (fw_vif_idx != 0)
3097                 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3098                                      0x2;
3099
3100         init_netdev(ndev);
3101
3102         ath6kl_init_control_info(vif);
3103
3104         if (ath6kl_cfg80211_vif_init(vif))
3105                 goto err;
3106
3107         if (register_netdevice(ndev))
3108                 goto err;
3109
3110         ar->avail_idx_map &= ~BIT(fw_vif_idx);
3111         vif->sme_state = SME_DISCONNECTED;
3112         set_bit(WLAN_ENABLED, &vif->flags);
3113         ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
3114         set_bit(NETDEV_REGISTERED, &vif->flags);
3115
3116         if (type == NL80211_IFTYPE_ADHOC)
3117                 ar->ibss_if_active = true;
3118
3119         spin_lock_bh(&ar->list_lock);
3120         list_add_tail(&vif->list, &ar->vif_list);
3121         spin_unlock_bh(&ar->list_lock);
3122
3123         return ndev;
3124
3125 err:
3126         aggr_module_destroy(vif->aggr_cntxt);
3127         free_netdev(ndev);
3128         return NULL;
3129 }
3130
3131 int ath6kl_cfg80211_init(struct ath6kl *ar)
3132 {
3133         struct wiphy *wiphy = ar->wiphy;
3134         int ret;
3135
3136         wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3137
3138         wiphy->max_remain_on_channel_duration = 5000;
3139
3140         /* set device pointer for wiphy */
3141         set_wiphy_dev(wiphy, ar->dev);
3142
3143         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3144                                  BIT(NL80211_IFTYPE_ADHOC) |
3145                                  BIT(NL80211_IFTYPE_AP);
3146         if (ar->p2p) {
3147                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3148                                           BIT(NL80211_IFTYPE_P2P_CLIENT);
3149         }
3150
3151         /* max num of ssids that can be probed during scanning */
3152         wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
3153         wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
3154         wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3155         wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3156         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3157
3158         wiphy->cipher_suites = cipher_suites;
3159         wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3160
3161         wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
3162                               WIPHY_WOWLAN_DISCONNECT |
3163                               WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3164                               WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3165                               WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3166                               WIPHY_WOWLAN_4WAY_HANDSHAKE;
3167         wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
3168         wiphy->wowlan.pattern_min_len = 1;
3169         wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
3170
3171         wiphy->max_sched_scan_ssids = 10;
3172
3173         ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3174                             WIPHY_FLAG_HAVE_AP_SME |
3175                             WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3176                             WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3177
3178         if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN, ar->fw_capabilities))
3179                 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3180
3181         ar->wiphy->probe_resp_offload =
3182                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3183                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
3184                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P |
3185                 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_80211U;
3186
3187         ret = wiphy_register(wiphy);
3188         if (ret < 0) {
3189                 ath6kl_err("couldn't register wiphy device\n");
3190                 return ret;
3191         }
3192
3193         ar->wiphy_registered = true;
3194
3195         return 0;
3196 }
3197
3198 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
3199 {
3200         wiphy_unregister(ar->wiphy);
3201
3202         ar->wiphy_registered = false;
3203 }
3204
3205 struct ath6kl *ath6kl_cfg80211_create(void)
3206 {
3207         struct ath6kl *ar;
3208         struct wiphy *wiphy;
3209
3210         /* create a new wiphy for use with cfg80211 */
3211         wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
3212
3213         if (!wiphy) {
3214                 ath6kl_err("couldn't allocate wiphy device\n");
3215                 return NULL;
3216         }
3217
3218         ar = wiphy_priv(wiphy);
3219         ar->wiphy = wiphy;
3220
3221         return ar;
3222 }
3223
3224 /* Note: ar variable must not be accessed after calling this! */
3225 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
3226 {
3227         int i;
3228
3229         for (i = 0; i < AP_MAX_NUM_STA; i++)
3230                 kfree(ar->sta_list[i].aggr_conn);
3231
3232         wiphy_free(ar->wiphy);
3233 }
3234