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