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