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