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