]> git.karo-electronics.de Git - karo-tx-linux.git/blob - drivers/net/wireless/ath/ath6kl/cfg80211.c
ath6kl: Fix AP mode operation after interface down/up
[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 < ar->vif_max; 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 < ar->vif_max; 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         } else
435                 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
436
437         if (test_bit(CONNECTED, &vif->flags) &&
438             vif->ssid_len == sme->ssid_len &&
439             !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
440                 vif->reconnect_flag = true;
441                 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
442                                                   vif->req_bssid,
443                                                   vif->ch_hint);
444
445                 up(&ar->sem);
446                 if (status) {
447                         ath6kl_err("wmi_reconnect_cmd failed\n");
448                         return -EIO;
449                 }
450                 return 0;
451         } else if (vif->ssid_len == sme->ssid_len &&
452                    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
453                 ath6kl_disconnect(vif);
454         }
455
456         memset(vif->ssid, 0, sizeof(vif->ssid));
457         vif->ssid_len = sme->ssid_len;
458         memcpy(vif->ssid, sme->ssid, sme->ssid_len);
459
460         if (sme->channel)
461                 vif->ch_hint = sme->channel->center_freq;
462
463         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
464         if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
465                 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
466
467         ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
468
469         status = ath6kl_set_auth_type(vif, sme->auth_type);
470         if (status) {
471                 up(&ar->sem);
472                 return status;
473         }
474
475         if (sme->crypto.n_ciphers_pairwise)
476                 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
477         else
478                 ath6kl_set_cipher(vif, 0, true);
479
480         ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
481
482         if (sme->crypto.n_akm_suites)
483                 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
484
485         if ((sme->key_len) &&
486             (vif->auth_mode == NONE_AUTH) &&
487             (vif->prwise_crypto == WEP_CRYPT)) {
488                 struct ath6kl_key *key = NULL;
489
490                 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
491                     sme->key_idx > WMI_MAX_KEY_INDEX) {
492                         ath6kl_err("key index %d out of bounds\n",
493                                    sme->key_idx);
494                         up(&ar->sem);
495                         return -ENOENT;
496                 }
497
498                 key = &vif->keys[sme->key_idx];
499                 key->key_len = sme->key_len;
500                 memcpy(key->key, sme->key, key->key_len);
501                 key->cipher = vif->prwise_crypto;
502                 vif->def_txkey_index = sme->key_idx;
503
504                 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
505                                       vif->prwise_crypto,
506                                       GROUP_USAGE | TX_USAGE,
507                                       key->key_len,
508                                       NULL, 0,
509                                       key->key, KEY_OP_INIT_VAL, NULL,
510                                       NO_SYNC_WMIFLAG);
511         }
512
513         if (!ar->usr_bss_filter) {
514                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
515                 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
516                     ALL_BSS_FILTER, 0) != 0) {
517                         ath6kl_err("couldn't set bss filtering\n");
518                         up(&ar->sem);
519                         return -EIO;
520                 }
521         }
522
523         vif->nw_type = vif->next_mode;
524
525         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
526                    "%s: connect called with authmode %d dot11 auth %d"
527                    " PW crypto %d PW crypto len %d GRP crypto %d"
528                    " GRP crypto len %d channel hint %u\n",
529                    __func__,
530                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
531                    vif->prwise_crypto_len, vif->grp_crypto,
532                    vif->grp_crypto_len, vif->ch_hint);
533
534         vif->reconnect_flag = 0;
535         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
536                                         vif->dot11_auth_mode, vif->auth_mode,
537                                         vif->prwise_crypto,
538                                         vif->prwise_crypto_len,
539                                         vif->grp_crypto, vif->grp_crypto_len,
540                                         vif->ssid_len, vif->ssid,
541                                         vif->req_bssid, vif->ch_hint,
542                                         ar->connect_ctrl_flags);
543
544         up(&ar->sem);
545
546         if (status == -EINVAL) {
547                 memset(vif->ssid, 0, sizeof(vif->ssid));
548                 vif->ssid_len = 0;
549                 ath6kl_err("invalid request\n");
550                 return -ENOENT;
551         } else if (status) {
552                 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
553                 return -EIO;
554         }
555
556         if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
557             ((vif->auth_mode == WPA_PSK_AUTH)
558              || (vif->auth_mode == WPA2_PSK_AUTH))) {
559                 mod_timer(&vif->disconnect_timer,
560                           jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
561         }
562
563         ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
564         set_bit(CONNECT_PEND, &vif->flags);
565
566         return 0;
567 }
568
569 static int ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
570                                     enum network_type nw_type,
571                                     const u8 *bssid,
572                                     struct ieee80211_channel *chan,
573                                     const u8 *beacon_ie, size_t beacon_ie_len)
574 {
575         struct ath6kl *ar = vif->ar;
576         struct cfg80211_bss *bss;
577         u16 cap_mask, cap_val;
578         u8 *ie;
579
580         if (nw_type & ADHOC_NETWORK) {
581                 cap_mask = WLAN_CAPABILITY_IBSS;
582                 cap_val = WLAN_CAPABILITY_IBSS;
583         } else {
584                 cap_mask = WLAN_CAPABILITY_ESS;
585                 cap_val = WLAN_CAPABILITY_ESS;
586         }
587
588         bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
589                                vif->ssid, vif->ssid_len,
590                                cap_mask, cap_val);
591         if (bss == NULL) {
592                 /*
593                  * Since cfg80211 may not yet know about the BSS,
594                  * generate a partial entry until the first BSS info
595                  * event becomes available.
596                  *
597                  * Prepend SSID element since it is not included in the Beacon
598                  * IEs from the target.
599                  */
600                 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
601                 if (ie == NULL)
602                         return -ENOMEM;
603                 ie[0] = WLAN_EID_SSID;
604                 ie[1] = vif->ssid_len;
605                 memcpy(ie + 2, vif->ssid, vif->ssid_len);
606                 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
607                 bss = cfg80211_inform_bss(ar->wiphy, chan,
608                                           bssid, 0, cap_val, 100,
609                                           ie, 2 + vif->ssid_len + beacon_ie_len,
610                                           0, GFP_KERNEL);
611                 if (bss)
612                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
613                                    "cfg80211\n", bssid);
614                 kfree(ie);
615         } else
616                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
617                            "entry\n");
618
619         if (bss == NULL)
620                 return -ENOMEM;
621
622         cfg80211_put_bss(bss);
623
624         return 0;
625 }
626
627 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
628                                    u8 *bssid, u16 listen_intvl,
629                                    u16 beacon_intvl,
630                                    enum network_type nw_type,
631                                    u8 beacon_ie_len, u8 assoc_req_len,
632                                    u8 assoc_resp_len, u8 *assoc_info)
633 {
634         struct ieee80211_channel *chan;
635         struct ath6kl *ar = vif->ar;
636
637         /* capinfo + listen interval */
638         u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
639
640         /* capinfo + status code +  associd */
641         u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
642
643         u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
644         u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
645             assoc_resp_ie_offset;
646
647         assoc_req_len -= assoc_req_ie_offset;
648         assoc_resp_len -= assoc_resp_ie_offset;
649
650         /*
651          * Store Beacon interval here; DTIM period will be available only once
652          * a Beacon frame from the AP is seen.
653          */
654         vif->assoc_bss_beacon_int = beacon_intvl;
655         clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
656
657         if (nw_type & ADHOC_NETWORK) {
658                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
659                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
660                                    "%s: ath6k not in ibss mode\n", __func__);
661                         return;
662                 }
663         }
664
665         if (nw_type & INFRA_NETWORK) {
666                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
667                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
668                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
669                                    "%s: ath6k not in station mode\n", __func__);
670                         return;
671                 }
672         }
673
674         chan = ieee80211_get_channel(ar->wiphy, (int) channel);
675
676         if (ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan, assoc_info,
677                                      beacon_ie_len) < 0) {
678                 ath6kl_err("could not add cfg80211 bss entry\n");
679                 return;
680         }
681
682         if (nw_type & ADHOC_NETWORK) {
683                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
684                            nw_type & ADHOC_CREATOR ? "creator" : "joiner");
685                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
686                 return;
687         }
688
689         if (vif->sme_state == SME_CONNECTING) {
690                 /* inform connect result to cfg80211 */
691                 vif->sme_state = SME_CONNECTED;
692                 cfg80211_connect_result(vif->ndev, bssid,
693                                         assoc_req_ie, assoc_req_len,
694                                         assoc_resp_ie, assoc_resp_len,
695                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
696         } else if (vif->sme_state == SME_CONNECTED) {
697                 /* inform roam event to cfg80211 */
698                 cfg80211_roamed(vif->ndev, chan, bssid,
699                                 assoc_req_ie, assoc_req_len,
700                                 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
701         }
702 }
703
704 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
705                                       struct net_device *dev, u16 reason_code)
706 {
707         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
708         struct ath6kl_vif *vif = netdev_priv(dev);
709
710         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
711                    reason_code);
712
713         if (!ath6kl_cfg80211_ready(vif))
714                 return -EIO;
715
716         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
717                 ath6kl_err("busy, destroy in progress\n");
718                 return -EBUSY;
719         }
720
721         if (down_interruptible(&ar->sem)) {
722                 ath6kl_err("busy, couldn't get access\n");
723                 return -ERESTARTSYS;
724         }
725
726         vif->reconnect_flag = 0;
727         ath6kl_disconnect(vif);
728         memset(vif->ssid, 0, sizeof(vif->ssid));
729         vif->ssid_len = 0;
730
731         if (!test_bit(SKIP_SCAN, &ar->flag))
732                 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
733
734         up(&ar->sem);
735
736         vif->sme_state = SME_DISCONNECTED;
737
738         return 0;
739 }
740
741 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
742                                       u8 *bssid, u8 assoc_resp_len,
743                                       u8 *assoc_info, u16 proto_reason)
744 {
745         struct ath6kl *ar = vif->ar;
746
747         if (vif->scan_req) {
748                 cfg80211_scan_done(vif->scan_req, true);
749                 vif->scan_req = NULL;
750         }
751
752         if (vif->nw_type & ADHOC_NETWORK) {
753                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
754                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
755                                    "%s: ath6k not in ibss mode\n", __func__);
756                         return;
757                 }
758                 memset(bssid, 0, ETH_ALEN);
759                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
760                 return;
761         }
762
763         if (vif->nw_type & INFRA_NETWORK) {
764                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
765                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
766                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
767                                    "%s: ath6k not in station mode\n", __func__);
768                         return;
769                 }
770         }
771
772         /*
773          * Send a disconnect command to target when a disconnect event is
774          * received with reason code other than 3 (DISCONNECT_CMD - disconnect
775          * request from host) to make the firmware stop trying to connect even
776          * after giving disconnect event. There will be one more disconnect
777          * event for this disconnect command with reason code DISCONNECT_CMD
778          * which will be notified to cfg80211.
779          */
780
781         if (reason != DISCONNECT_CMD) {
782                 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
783                 return;
784         }
785
786         clear_bit(CONNECT_PEND, &vif->flags);
787
788         if (vif->sme_state == SME_CONNECTING) {
789                 cfg80211_connect_result(vif->ndev,
790                                 bssid, NULL, 0,
791                                 NULL, 0,
792                                 WLAN_STATUS_UNSPECIFIED_FAILURE,
793                                 GFP_KERNEL);
794         } else if (vif->sme_state == SME_CONNECTED) {
795                 cfg80211_disconnected(vif->ndev, reason,
796                                 NULL, 0, GFP_KERNEL);
797         }
798
799         vif->sme_state = SME_DISCONNECTED;
800 }
801
802 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
803                                 struct cfg80211_scan_request *request)
804 {
805         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
806         struct ath6kl_vif *vif = netdev_priv(ndev);
807         s8 n_channels = 0;
808         u16 *channels = NULL;
809         int ret = 0;
810         u32 force_fg_scan = 0;
811
812         if (!ath6kl_cfg80211_ready(vif))
813                 return -EIO;
814
815         if (!ar->usr_bss_filter) {
816                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
817                 ret = ath6kl_wmi_bssfilter_cmd(
818                         ar->wmi, vif->fw_vif_idx,
819                         (test_bit(CONNECTED, &vif->flags) ?
820                          ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
821                 if (ret) {
822                         ath6kl_err("couldn't set bss filtering\n");
823                         return ret;
824                 }
825         }
826
827         if (request->n_ssids && request->ssids[0].ssid_len) {
828                 u8 i;
829
830                 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
831                         request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
832
833                 for (i = 0; i < request->n_ssids; i++)
834                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
835                                                   i + 1, SPECIFIC_SSID_FLAG,
836                                                   request->ssids[i].ssid_len,
837                                                   request->ssids[i].ssid);
838         }
839
840         if (request->ie) {
841                 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
842                                                WMI_FRAME_PROBE_REQ,
843                                                request->ie, request->ie_len);
844                 if (ret) {
845                         ath6kl_err("failed to set Probe Request appie for "
846                                    "scan");
847                         return ret;
848                 }
849         }
850
851         /*
852          * Scan only the requested channels if the request specifies a set of
853          * channels. If the list is longer than the target supports, do not
854          * configure the list and instead, scan all available channels.
855          */
856         if (request->n_channels > 0 &&
857             request->n_channels <= WMI_MAX_CHANNELS) {
858                 u8 i;
859
860                 n_channels = request->n_channels;
861
862                 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
863                 if (channels == NULL) {
864                         ath6kl_warn("failed to set scan channels, "
865                                     "scan all channels");
866                         n_channels = 0;
867                 }
868
869                 for (i = 0; i < n_channels; i++)
870                         channels[i] = request->channels[i]->center_freq;
871         }
872
873         if (test_bit(CONNECTED, &vif->flags))
874                 force_fg_scan = 1;
875
876         ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx, WMI_LONG_SCAN,
877                                        force_fg_scan, false, 0, 0, n_channels,
878                                        channels);
879         if (ret)
880                 ath6kl_err("wmi_startscan_cmd failed\n");
881         else
882                 vif->scan_req = request;
883
884         kfree(channels);
885
886         return ret;
887 }
888
889 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
890 {
891         struct ath6kl *ar = vif->ar;
892         int i;
893
894         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
895                    aborted ? " aborted" : "");
896
897         if (!vif->scan_req)
898                 return;
899
900         if (aborted)
901                 goto out;
902
903         if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
904                 for (i = 0; i < vif->scan_req->n_ssids; i++) {
905                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
906                                                   i + 1, DISABLE_SSID_FLAG,
907                                                   0, NULL);
908                 }
909         }
910
911 out:
912         cfg80211_scan_done(vif->scan_req, aborted);
913         vif->scan_req = NULL;
914 }
915
916 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
917                                    u8 key_index, bool pairwise,
918                                    const u8 *mac_addr,
919                                    struct key_params *params)
920 {
921         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
922         struct ath6kl_vif *vif = netdev_priv(ndev);
923         struct ath6kl_key *key = NULL;
924         u8 key_usage;
925         u8 key_type;
926
927         if (!ath6kl_cfg80211_ready(vif))
928                 return -EIO;
929
930         if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
931                 if (params->key_len != WMI_KRK_LEN)
932                         return -EINVAL;
933                 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
934                                               params->key);
935         }
936
937         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
938                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
939                            "%s: key index %d out of bounds\n", __func__,
940                            key_index);
941                 return -ENOENT;
942         }
943
944         key = &vif->keys[key_index];
945         memset(key, 0, sizeof(struct ath6kl_key));
946
947         if (pairwise)
948                 key_usage = PAIRWISE_USAGE;
949         else
950                 key_usage = GROUP_USAGE;
951
952         if (params) {
953                 int seq_len = params->seq_len;
954                 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
955                     seq_len > ATH6KL_KEY_SEQ_LEN) {
956                         /* Only first half of the WPI PN is configured */
957                         seq_len = ATH6KL_KEY_SEQ_LEN;
958                 }
959                 if (params->key_len > WLAN_MAX_KEY_LEN ||
960                     seq_len > sizeof(key->seq))
961                         return -EINVAL;
962
963                 key->key_len = params->key_len;
964                 memcpy(key->key, params->key, key->key_len);
965                 key->seq_len = seq_len;
966                 memcpy(key->seq, params->seq, key->seq_len);
967                 key->cipher = params->cipher;
968         }
969
970         switch (key->cipher) {
971         case WLAN_CIPHER_SUITE_WEP40:
972         case WLAN_CIPHER_SUITE_WEP104:
973                 key_type = WEP_CRYPT;
974                 break;
975
976         case WLAN_CIPHER_SUITE_TKIP:
977                 key_type = TKIP_CRYPT;
978                 break;
979
980         case WLAN_CIPHER_SUITE_CCMP:
981                 key_type = AES_CRYPT;
982                 break;
983         case WLAN_CIPHER_SUITE_SMS4:
984                 key_type = WAPI_CRYPT;
985                 break;
986
987         default:
988                 return -ENOTSUPP;
989         }
990
991         if (((vif->auth_mode == WPA_PSK_AUTH)
992              || (vif->auth_mode == WPA2_PSK_AUTH))
993             && (key_usage & GROUP_USAGE))
994                 del_timer(&vif->disconnect_timer);
995
996         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
997                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
998                    __func__, key_index, key->key_len, key_type,
999                    key_usage, key->seq_len);
1000
1001         if (vif->nw_type == AP_NETWORK && !pairwise &&
1002             (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
1003                 ar->ap_mode_bkey.valid = true;
1004                 ar->ap_mode_bkey.key_index = key_index;
1005                 ar->ap_mode_bkey.key_type = key_type;
1006                 ar->ap_mode_bkey.key_len = key->key_len;
1007                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1008                 if (!test_bit(CONNECTED, &vif->flags)) {
1009                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
1010                                    "key configuration until AP mode has been "
1011                                    "started\n");
1012                         /*
1013                          * The key will be set in ath6kl_connect_ap_mode() once
1014                          * the connected event is received from the target.
1015                          */
1016                         return 0;
1017                 }
1018         }
1019
1020         if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1021             !test_bit(CONNECTED, &vif->flags)) {
1022                 /*
1023                  * Store the key locally so that it can be re-configured after
1024                  * the AP mode has properly started
1025                  * (ath6kl_install_statioc_wep_keys).
1026                  */
1027                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
1028                            "until AP mode has been started\n");
1029                 vif->wep_key_list[key_index].key_len = key->key_len;
1030                 memcpy(vif->wep_key_list[key_index].key, key->key,
1031                        key->key_len);
1032                 return 0;
1033         }
1034
1035         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1036                                      key_type, key_usage, key->key_len,
1037                                      key->seq, key->seq_len, key->key,
1038                                      KEY_OP_INIT_VAL,
1039                                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1040 }
1041
1042 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1043                                    u8 key_index, bool pairwise,
1044                                    const u8 *mac_addr)
1045 {
1046         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1047         struct ath6kl_vif *vif = netdev_priv(ndev);
1048
1049         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1050
1051         if (!ath6kl_cfg80211_ready(vif))
1052                 return -EIO;
1053
1054         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1055                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1056                            "%s: key index %d out of bounds\n", __func__,
1057                            key_index);
1058                 return -ENOENT;
1059         }
1060
1061         if (!vif->keys[key_index].key_len) {
1062                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1063                            "%s: index %d is empty\n", __func__, key_index);
1064                 return 0;
1065         }
1066
1067         vif->keys[key_index].key_len = 0;
1068
1069         return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1070 }
1071
1072 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1073                                    u8 key_index, bool pairwise,
1074                                    const u8 *mac_addr, void *cookie,
1075                                    void (*callback) (void *cookie,
1076                                                      struct key_params *))
1077 {
1078         struct ath6kl_vif *vif = netdev_priv(ndev);
1079         struct ath6kl_key *key = NULL;
1080         struct key_params params;
1081
1082         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1083
1084         if (!ath6kl_cfg80211_ready(vif))
1085                 return -EIO;
1086
1087         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1088                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1089                            "%s: key index %d out of bounds\n", __func__,
1090                            key_index);
1091                 return -ENOENT;
1092         }
1093
1094         key = &vif->keys[key_index];
1095         memset(&params, 0, sizeof(params));
1096         params.cipher = key->cipher;
1097         params.key_len = key->key_len;
1098         params.seq_len = key->seq_len;
1099         params.seq = key->seq;
1100         params.key = key->key;
1101
1102         callback(cookie, &params);
1103
1104         return key->key_len ? 0 : -ENOENT;
1105 }
1106
1107 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1108                                            struct net_device *ndev,
1109                                            u8 key_index, bool unicast,
1110                                            bool multicast)
1111 {
1112         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1113         struct ath6kl_vif *vif = netdev_priv(ndev);
1114         struct ath6kl_key *key = NULL;
1115         u8 key_usage;
1116         enum crypto_type key_type = NONE_CRYPT;
1117
1118         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1119
1120         if (!ath6kl_cfg80211_ready(vif))
1121                 return -EIO;
1122
1123         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1124                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1125                            "%s: key index %d out of bounds\n",
1126                            __func__, key_index);
1127                 return -ENOENT;
1128         }
1129
1130         if (!vif->keys[key_index].key_len) {
1131                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1132                            __func__, key_index);
1133                 return -EINVAL;
1134         }
1135
1136         vif->def_txkey_index = key_index;
1137         key = &vif->keys[vif->def_txkey_index];
1138         key_usage = GROUP_USAGE;
1139         if (vif->prwise_crypto == WEP_CRYPT)
1140                 key_usage |= TX_USAGE;
1141         if (unicast)
1142                 key_type = vif->prwise_crypto;
1143         if (multicast)
1144                 key_type = vif->grp_crypto;
1145
1146         if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1147                 return 0; /* Delay until AP mode has been started */
1148
1149         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1150                                      vif->def_txkey_index,
1151                                      key_type, key_usage,
1152                                      key->key_len, key->seq, key->seq_len,
1153                                      key->key,
1154                                      KEY_OP_INIT_VAL, NULL,
1155                                      SYNC_BOTH_WMIFLAG);
1156 }
1157
1158 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1159                                        bool ismcast)
1160 {
1161         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1162                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1163
1164         cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1165                                      (ismcast ? NL80211_KEYTYPE_GROUP :
1166                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1167                                      GFP_KERNEL);
1168 }
1169
1170 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1171 {
1172         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1173         struct ath6kl_vif *vif;
1174         int ret;
1175
1176         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1177                    changed);
1178
1179         vif = ath6kl_vif_first(ar);
1180         if (!vif)
1181                 return -EIO;
1182
1183         if (!ath6kl_cfg80211_ready(vif))
1184                 return -EIO;
1185
1186         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1187                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1188                 if (ret != 0) {
1189                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1190                         return -EIO;
1191                 }
1192         }
1193
1194         return 0;
1195 }
1196
1197 /*
1198  * The type nl80211_tx_power_setting replaces the following
1199  * data type from 2.6.36 onwards
1200 */
1201 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1202                                        enum nl80211_tx_power_setting type,
1203                                        int dbm)
1204 {
1205         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1206         struct ath6kl_vif *vif;
1207         u8 ath6kl_dbm;
1208
1209         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1210                    type, dbm);
1211
1212         vif = ath6kl_vif_first(ar);
1213         if (!vif)
1214                 return -EIO;
1215
1216         if (!ath6kl_cfg80211_ready(vif))
1217                 return -EIO;
1218
1219         switch (type) {
1220         case NL80211_TX_POWER_AUTOMATIC:
1221                 return 0;
1222         case NL80211_TX_POWER_LIMITED:
1223                 ar->tx_pwr = ath6kl_dbm = dbm;
1224                 break;
1225         default:
1226                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1227                            __func__, type);
1228                 return -EOPNOTSUPP;
1229         }
1230
1231         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
1232
1233         return 0;
1234 }
1235
1236 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1237 {
1238         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1239         struct ath6kl_vif *vif;
1240
1241         vif = ath6kl_vif_first(ar);
1242         if (!vif)
1243                 return -EIO;
1244
1245         if (!ath6kl_cfg80211_ready(vif))
1246                 return -EIO;
1247
1248         if (test_bit(CONNECTED, &vif->flags)) {
1249                 ar->tx_pwr = 0;
1250
1251                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1252                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1253                         return -EIO;
1254                 }
1255
1256                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1257                                                  5 * HZ);
1258
1259                 if (signal_pending(current)) {
1260                         ath6kl_err("target did not respond\n");
1261                         return -EINTR;
1262                 }
1263         }
1264
1265         *dbm = ar->tx_pwr;
1266         return 0;
1267 }
1268
1269 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1270                                           struct net_device *dev,
1271                                           bool pmgmt, int timeout)
1272 {
1273         struct ath6kl *ar = ath6kl_priv(dev);
1274         struct wmi_power_mode_cmd mode;
1275         struct ath6kl_vif *vif = netdev_priv(dev);
1276
1277         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1278                    __func__, pmgmt, timeout);
1279
1280         if (!ath6kl_cfg80211_ready(vif))
1281                 return -EIO;
1282
1283         if (pmgmt) {
1284                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1285                 mode.pwr_mode = REC_POWER;
1286         } else {
1287                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1288                 mode.pwr_mode = MAX_PERF_POWER;
1289         }
1290
1291         if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1292              mode.pwr_mode) != 0) {
1293                 ath6kl_err("wmi_powermode_cmd failed\n");
1294                 return -EIO;
1295         }
1296
1297         return 0;
1298 }
1299
1300 static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1301                                                     char *name,
1302                                                     enum nl80211_iftype type,
1303                                                     u32 *flags,
1304                                                     struct vif_params *params)
1305 {
1306         struct ath6kl *ar = wiphy_priv(wiphy);
1307         struct net_device *ndev;
1308         u8 if_idx, nw_type;
1309
1310         if (ar->num_vif == ar->vif_max) {
1311                 ath6kl_err("Reached maximum number of supported vif\n");
1312                 return ERR_PTR(-EINVAL);
1313         }
1314
1315         if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1316                 ath6kl_err("Not a supported interface type\n");
1317                 return ERR_PTR(-EINVAL);
1318         }
1319
1320         ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1321         if (!ndev)
1322                 return ERR_PTR(-ENOMEM);
1323
1324         ar->num_vif++;
1325
1326         return ndev;
1327 }
1328
1329 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1330                                      struct net_device *ndev)
1331 {
1332         struct ath6kl *ar = wiphy_priv(wiphy);
1333         struct ath6kl_vif *vif = netdev_priv(ndev);
1334
1335         spin_lock_bh(&ar->list_lock);
1336         list_del(&vif->list);
1337         spin_unlock_bh(&ar->list_lock);
1338
1339         ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1340
1341         ath6kl_deinit_if_data(vif);
1342
1343         return 0;
1344 }
1345
1346 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1347                                         struct net_device *ndev,
1348                                         enum nl80211_iftype type, u32 *flags,
1349                                         struct vif_params *params)
1350 {
1351         struct ath6kl_vif *vif = netdev_priv(ndev);
1352
1353         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1354
1355         switch (type) {
1356         case NL80211_IFTYPE_STATION:
1357                 vif->next_mode = INFRA_NETWORK;
1358                 break;
1359         case NL80211_IFTYPE_ADHOC:
1360                 vif->next_mode = ADHOC_NETWORK;
1361                 break;
1362         case NL80211_IFTYPE_AP:
1363                 vif->next_mode = AP_NETWORK;
1364                 break;
1365         case NL80211_IFTYPE_P2P_CLIENT:
1366                 vif->next_mode = INFRA_NETWORK;
1367                 break;
1368         case NL80211_IFTYPE_P2P_GO:
1369                 vif->next_mode = AP_NETWORK;
1370                 break;
1371         default:
1372                 ath6kl_err("invalid interface type %u\n", type);
1373                 return -EOPNOTSUPP;
1374         }
1375
1376         vif->wdev.iftype = type;
1377
1378         return 0;
1379 }
1380
1381 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1382                                      struct net_device *dev,
1383                                      struct cfg80211_ibss_params *ibss_param)
1384 {
1385         struct ath6kl *ar = ath6kl_priv(dev);
1386         struct ath6kl_vif *vif = netdev_priv(dev);
1387         int status;
1388
1389         if (!ath6kl_cfg80211_ready(vif))
1390                 return -EIO;
1391
1392         vif->ssid_len = ibss_param->ssid_len;
1393         memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1394
1395         if (ibss_param->channel)
1396                 vif->ch_hint = ibss_param->channel->center_freq;
1397
1398         if (ibss_param->channel_fixed) {
1399                 /*
1400                  * TODO: channel_fixed: The channel should be fixed, do not
1401                  * search for IBSSs to join on other channels. Target
1402                  * firmware does not support this feature, needs to be
1403                  * updated.
1404                  */
1405                 return -EOPNOTSUPP;
1406         }
1407
1408         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1409         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1410                 memcpy(vif->req_bssid, ibss_param->bssid,
1411                        sizeof(vif->req_bssid));
1412
1413         ath6kl_set_wpa_version(vif, 0);
1414
1415         status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1416         if (status)
1417                 return status;
1418
1419         if (ibss_param->privacy) {
1420                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1421                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1422         } else {
1423                 ath6kl_set_cipher(vif, 0, true);
1424                 ath6kl_set_cipher(vif, 0, false);
1425         }
1426
1427         vif->nw_type = vif->next_mode;
1428
1429         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1430                    "%s: connect called with authmode %d dot11 auth %d"
1431                    " PW crypto %d PW crypto len %d GRP crypto %d"
1432                    " GRP crypto len %d channel hint %u\n",
1433                    __func__,
1434                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1435                    vif->prwise_crypto_len, vif->grp_crypto,
1436                    vif->grp_crypto_len, vif->ch_hint);
1437
1438         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1439                                         vif->dot11_auth_mode, vif->auth_mode,
1440                                         vif->prwise_crypto,
1441                                         vif->prwise_crypto_len,
1442                                         vif->grp_crypto, vif->grp_crypto_len,
1443                                         vif->ssid_len, vif->ssid,
1444                                         vif->req_bssid, vif->ch_hint,
1445                                         ar->connect_ctrl_flags);
1446         set_bit(CONNECT_PEND, &vif->flags);
1447
1448         return 0;
1449 }
1450
1451 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1452                                       struct net_device *dev)
1453 {
1454         struct ath6kl_vif *vif = netdev_priv(dev);
1455
1456         if (!ath6kl_cfg80211_ready(vif))
1457                 return -EIO;
1458
1459         ath6kl_disconnect(vif);
1460         memset(vif->ssid, 0, sizeof(vif->ssid));
1461         vif->ssid_len = 0;
1462
1463         return 0;
1464 }
1465
1466 static const u32 cipher_suites[] = {
1467         WLAN_CIPHER_SUITE_WEP40,
1468         WLAN_CIPHER_SUITE_WEP104,
1469         WLAN_CIPHER_SUITE_TKIP,
1470         WLAN_CIPHER_SUITE_CCMP,
1471         CCKM_KRK_CIPHER_SUITE,
1472         WLAN_CIPHER_SUITE_SMS4,
1473 };
1474
1475 static bool is_rate_legacy(s32 rate)
1476 {
1477         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1478                 6000, 9000, 12000, 18000, 24000,
1479                 36000, 48000, 54000
1480         };
1481         u8 i;
1482
1483         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1484                 if (rate == legacy[i])
1485                         return true;
1486
1487         return false;
1488 }
1489
1490 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1491 {
1492         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1493                 52000, 58500, 65000, 72200
1494         };
1495         u8 i;
1496
1497         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1498                 if (rate == ht20[i]) {
1499                         if (i == ARRAY_SIZE(ht20) - 1)
1500                                 /* last rate uses sgi */
1501                                 *sgi = true;
1502                         else
1503                                 *sgi = false;
1504
1505                         *mcs = i;
1506                         return true;
1507                 }
1508         }
1509         return false;
1510 }
1511
1512 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1513 {
1514         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1515                 81000, 108000, 121500, 135000,
1516                 150000
1517         };
1518         u8 i;
1519
1520         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1521                 if (rate == ht40[i]) {
1522                         if (i == ARRAY_SIZE(ht40) - 1)
1523                                 /* last rate uses sgi */
1524                                 *sgi = true;
1525                         else
1526                                 *sgi = false;
1527
1528                         *mcs = i;
1529                         return true;
1530                 }
1531         }
1532
1533         return false;
1534 }
1535
1536 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1537                               u8 *mac, struct station_info *sinfo)
1538 {
1539         struct ath6kl *ar = ath6kl_priv(dev);
1540         struct ath6kl_vif *vif = netdev_priv(dev);
1541         long left;
1542         bool sgi;
1543         s32 rate;
1544         int ret;
1545         u8 mcs;
1546
1547         if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1548                 return -ENOENT;
1549
1550         if (down_interruptible(&ar->sem))
1551                 return -EBUSY;
1552
1553         set_bit(STATS_UPDATE_PEND, &vif->flags);
1554
1555         ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1556
1557         if (ret != 0) {
1558                 up(&ar->sem);
1559                 return -EIO;
1560         }
1561
1562         left = wait_event_interruptible_timeout(ar->event_wq,
1563                                                 !test_bit(STATS_UPDATE_PEND,
1564                                                           &vif->flags),
1565                                                 WMI_TIMEOUT);
1566
1567         up(&ar->sem);
1568
1569         if (left == 0)
1570                 return -ETIMEDOUT;
1571         else if (left < 0)
1572                 return left;
1573
1574         if (vif->target_stats.rx_byte) {
1575                 sinfo->rx_bytes = vif->target_stats.rx_byte;
1576                 sinfo->filled |= STATION_INFO_RX_BYTES;
1577                 sinfo->rx_packets = vif->target_stats.rx_pkt;
1578                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1579         }
1580
1581         if (vif->target_stats.tx_byte) {
1582                 sinfo->tx_bytes = vif->target_stats.tx_byte;
1583                 sinfo->filled |= STATION_INFO_TX_BYTES;
1584                 sinfo->tx_packets = vif->target_stats.tx_pkt;
1585                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1586         }
1587
1588         sinfo->signal = vif->target_stats.cs_rssi;
1589         sinfo->filled |= STATION_INFO_SIGNAL;
1590
1591         rate = vif->target_stats.tx_ucast_rate;
1592
1593         if (is_rate_legacy(rate)) {
1594                 sinfo->txrate.legacy = rate / 100;
1595         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1596                 if (sgi) {
1597                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1598                         sinfo->txrate.mcs = mcs - 1;
1599                 } else {
1600                         sinfo->txrate.mcs = mcs;
1601                 }
1602
1603                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1604         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1605                 if (sgi) {
1606                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1607                         sinfo->txrate.mcs = mcs - 1;
1608                 } else {
1609                         sinfo->txrate.mcs = mcs;
1610                 }
1611
1612                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1613                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1614         } else {
1615                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1616                            "invalid rate from stats: %d\n", rate);
1617                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1618                 return 0;
1619         }
1620
1621         sinfo->filled |= STATION_INFO_TX_BITRATE;
1622
1623         if (test_bit(CONNECTED, &vif->flags) &&
1624             test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1625             vif->nw_type == INFRA_NETWORK) {
1626                 sinfo->filled |= STATION_INFO_BSS_PARAM;
1627                 sinfo->bss_param.flags = 0;
1628                 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1629                 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1630         }
1631
1632         return 0;
1633 }
1634
1635 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1636                             struct cfg80211_pmksa *pmksa)
1637 {
1638         struct ath6kl *ar = ath6kl_priv(netdev);
1639         struct ath6kl_vif *vif = netdev_priv(netdev);
1640
1641         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1642                                        pmksa->pmkid, true);
1643 }
1644
1645 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1646                             struct cfg80211_pmksa *pmksa)
1647 {
1648         struct ath6kl *ar = ath6kl_priv(netdev);
1649         struct ath6kl_vif *vif = netdev_priv(netdev);
1650
1651         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1652                                        pmksa->pmkid, false);
1653 }
1654
1655 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1656 {
1657         struct ath6kl *ar = ath6kl_priv(netdev);
1658         struct ath6kl_vif *vif = netdev_priv(netdev);
1659
1660         if (test_bit(CONNECTED, &vif->flags))
1661                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1662                                                vif->bssid, NULL, false);
1663         return 0;
1664 }
1665
1666 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1667 {
1668         struct ath6kl_vif *vif;
1669         int ret, pos, left;
1670         u32 filter = 0;
1671         u16 i;
1672         u8 mask[WOW_MASK_SIZE];
1673
1674         vif = ath6kl_vif_first(ar);
1675         if (!vif)
1676                 return -EIO;
1677
1678         if (!ath6kl_cfg80211_ready(vif))
1679                 return -EIO;
1680
1681         if (!test_bit(CONNECTED, &vif->flags))
1682                 return -EINVAL;
1683
1684         /* Clear existing WOW patterns */
1685         for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1686                 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1687                                                WOW_LIST_ID, i);
1688         /* Configure new WOW patterns */
1689         for (i = 0; i < wow->n_patterns; i++) {
1690
1691                 /*
1692                  * Convert given nl80211 specific mask value to equivalent
1693                  * driver specific mask value and send it to the chip along
1694                  * with patterns. For example, If the mask value defined in
1695                  * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1696                  * then equivalent driver specific mask value is
1697                  * "0xFF 0x00 0xFF 0x00".
1698                  */
1699                 memset(&mask, 0, sizeof(mask));
1700                 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1701                         if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1702                                 mask[pos] = 0xFF;
1703                 }
1704                 /*
1705                  * Note: Pattern's offset is not passed as part of wowlan
1706                  * parameter from CFG layer. So it's always passed as ZERO
1707                  * to the firmware. It means, given WOW patterns are always
1708                  * matched from the first byte of received pkt in the firmware.
1709                  */
1710                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1711                                         vif->fw_vif_idx, WOW_LIST_ID,
1712                                         wow->patterns[i].pattern_len,
1713                                         0 /* pattern offset */,
1714                                         wow->patterns[i].pattern, mask);
1715                 if (ret)
1716                         return ret;
1717         }
1718
1719         if (wow->disconnect)
1720                 filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1721
1722         if (wow->magic_pkt)
1723                 filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1724
1725         if (wow->gtk_rekey_failure)
1726                 filter |= WOW_FILTER_OPTION_GTK_ERROR;
1727
1728         if (wow->eap_identity_req)
1729                 filter |= WOW_FILTER_OPTION_EAP_REQ;
1730
1731         if (wow->four_way_handshake)
1732                 filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1733
1734         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
1735                                           ATH6KL_WOW_MODE_ENABLE,
1736                                           filter,
1737                                           WOW_HOST_REQ_DELAY);
1738         if (ret)
1739                 return ret;
1740
1741         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1742                                                  ATH6KL_HOST_MODE_ASLEEP);
1743         if (ret)
1744                 return ret;
1745
1746         if (ar->tx_pending[ar->ctrl_ep]) {
1747                 left = wait_event_interruptible_timeout(ar->event_wq,
1748                                 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
1749                 if (left == 0) {
1750                         ath6kl_warn("clear wmi ctrl data timeout\n");
1751                         ret = -ETIMEDOUT;
1752                 } else if (left < 0) {
1753                         ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
1754                         ret = left;
1755                 }
1756         }
1757
1758         return ret;
1759 }
1760
1761 static int ath6kl_wow_resume(struct ath6kl *ar)
1762 {
1763         struct ath6kl_vif *vif;
1764         int ret;
1765
1766         vif = ath6kl_vif_first(ar);
1767         if (!vif)
1768                 return -EIO;
1769
1770         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1771                                                  ATH6KL_HOST_MODE_AWAKE);
1772         return ret;
1773 }
1774
1775 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
1776                             enum ath6kl_cfg_suspend_mode mode,
1777                             struct cfg80211_wowlan *wow)
1778 {
1779         int ret;
1780
1781         switch (mode) {
1782         case ATH6KL_CFG_SUSPEND_WOW:
1783
1784                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
1785
1786                 /* Flush all non control pkts in TX path */
1787                 ath6kl_tx_data_cleanup(ar);
1788
1789                 ret = ath6kl_wow_suspend(ar, wow);
1790                 if (ret) {
1791                         ath6kl_err("wow suspend failed: %d\n", ret);
1792                         return ret;
1793                 }
1794                 ar->state = ATH6KL_STATE_WOW;
1795                 break;
1796
1797         case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
1798
1799                 ath6kl_cfg80211_stop(ar);
1800
1801                 /* save the current power mode before enabling power save */
1802                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
1803
1804                 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
1805                 if (ret) {
1806                         ath6kl_warn("wmi powermode command failed during suspend: %d\n",
1807                                     ret);
1808                 }
1809
1810                 ar->state = ATH6KL_STATE_DEEPSLEEP;
1811
1812                 break;
1813
1814         case ATH6KL_CFG_SUSPEND_CUTPOWER:
1815
1816                 ath6kl_cfg80211_stop(ar);
1817
1818                 if (ar->state == ATH6KL_STATE_OFF) {
1819                         ath6kl_dbg(ATH6KL_DBG_SUSPEND,
1820                                    "suspend hw off, no action for cutpower\n");
1821                         break;
1822                 }
1823
1824                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
1825
1826                 ret = ath6kl_init_hw_stop(ar);
1827                 if (ret) {
1828                         ath6kl_warn("failed to stop hw during suspend: %d\n",
1829                                     ret);
1830                 }
1831
1832                 ar->state = ATH6KL_STATE_CUTPOWER;
1833
1834                 break;
1835
1836         default:
1837                 break;
1838         }
1839
1840         return 0;
1841 }
1842
1843 int ath6kl_cfg80211_resume(struct ath6kl *ar)
1844 {
1845         int ret;
1846
1847         switch (ar->state) {
1848         case  ATH6KL_STATE_WOW:
1849                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
1850
1851                 ret = ath6kl_wow_resume(ar);
1852                 if (ret) {
1853                         ath6kl_warn("wow mode resume failed: %d\n", ret);
1854                         return ret;
1855                 }
1856
1857                 ar->state = ATH6KL_STATE_ON;
1858                 break;
1859
1860         case ATH6KL_STATE_DEEPSLEEP:
1861                 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
1862                         ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
1863                                                        ar->wmi->saved_pwr_mode);
1864                         if (ret) {
1865                                 ath6kl_warn("wmi powermode command failed during resume: %d\n",
1866                                             ret);
1867                         }
1868                 }
1869
1870                 ar->state = ATH6KL_STATE_ON;
1871
1872                 break;
1873
1874         case ATH6KL_STATE_CUTPOWER:
1875                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
1876
1877                 ret = ath6kl_init_hw_start(ar);
1878                 if (ret) {
1879                         ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
1880                         return ret;
1881                 }
1882                 break;
1883
1884         default:
1885                 break;
1886         }
1887
1888         return 0;
1889 }
1890
1891 #ifdef CONFIG_PM
1892
1893 /* hif layer decides what suspend mode to use */
1894 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
1895                                  struct cfg80211_wowlan *wow)
1896 {
1897         struct ath6kl *ar = wiphy_priv(wiphy);
1898
1899         return ath6kl_hif_suspend(ar, wow);
1900 }
1901
1902 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
1903 {
1904         struct ath6kl *ar = wiphy_priv(wiphy);
1905
1906         return ath6kl_hif_resume(ar);
1907 }
1908
1909 /*
1910  * FIXME: WOW suspend mode is selected if the host sdio controller supports
1911  * both sdio irq wake up and keep power. The target pulls sdio data line to
1912  * wake up the host when WOW pattern matches. This causes sdio irq handler
1913  * is being called in the host side which internally hits ath6kl's RX path.
1914  *
1915  * Since sdio interrupt is not disabled, RX path executes even before
1916  * the host executes the actual resume operation from PM module.
1917  *
1918  * In the current scenario, WOW resume should happen before start processing
1919  * any data from the target. So It's required to perform WOW resume in RX path.
1920  * Ideally we should perform WOW resume only in the actual platform
1921  * resume path. This area needs bit rework to avoid WOW resume in RX path.
1922  *
1923  * ath6kl_check_wow_status() is called from ath6kl_rx().
1924  */
1925 void ath6kl_check_wow_status(struct ath6kl *ar)
1926 {
1927         if (ar->state == ATH6KL_STATE_WOW)
1928                 ath6kl_cfg80211_resume(ar);
1929 }
1930
1931 #else
1932
1933 void ath6kl_check_wow_status(struct ath6kl *ar)
1934 {
1935 }
1936 #endif
1937
1938 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1939                               struct ieee80211_channel *chan,
1940                               enum nl80211_channel_type channel_type)
1941 {
1942         struct ath6kl_vif *vif = netdev_priv(dev);
1943
1944         if (!ath6kl_cfg80211_ready(vif))
1945                 return -EIO;
1946
1947         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1948                    __func__, chan->center_freq, chan->hw_value);
1949         vif->next_chan = chan->center_freq;
1950
1951         return 0;
1952 }
1953
1954 static bool ath6kl_is_p2p_ie(const u8 *pos)
1955 {
1956         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1957                 pos[2] == 0x50 && pos[3] == 0x6f &&
1958                 pos[4] == 0x9a && pos[5] == 0x09;
1959 }
1960
1961 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
1962                                         const u8 *ies, size_t ies_len)
1963 {
1964         struct ath6kl *ar = vif->ar;
1965         const u8 *pos;
1966         u8 *buf = NULL;
1967         size_t len = 0;
1968         int ret;
1969
1970         /*
1971          * Filter out P2P IE(s) since they will be included depending on
1972          * the Probe Request frame in ath6kl_send_go_probe_resp().
1973          */
1974
1975         if (ies && ies_len) {
1976                 buf = kmalloc(ies_len, GFP_KERNEL);
1977                 if (buf == NULL)
1978                         return -ENOMEM;
1979                 pos = ies;
1980                 while (pos + 1 < ies + ies_len) {
1981                         if (pos + 2 + pos[1] > ies + ies_len)
1982                                 break;
1983                         if (!ath6kl_is_p2p_ie(pos)) {
1984                                 memcpy(buf + len, pos, 2 + pos[1]);
1985                                 len += 2 + pos[1];
1986                         }
1987                         pos += 2 + pos[1];
1988                 }
1989         }
1990
1991         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
1992                                        WMI_FRAME_PROBE_RESP, buf, len);
1993         kfree(buf);
1994         return ret;
1995 }
1996
1997 static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1998                             struct beacon_parameters *info, bool add)
1999 {
2000         struct ath6kl *ar = ath6kl_priv(dev);
2001         struct ath6kl_vif *vif = netdev_priv(dev);
2002         struct ieee80211_mgmt *mgmt;
2003         u8 *ies;
2004         int ies_len;
2005         struct wmi_connect_cmd p;
2006         int res;
2007         int i, ret;
2008
2009         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
2010
2011         if (!ath6kl_cfg80211_ready(vif))
2012                 return -EIO;
2013
2014         if (vif->next_mode != AP_NETWORK)
2015                 return -EOPNOTSUPP;
2016
2017         if (info->beacon_ies) {
2018                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2019                                                WMI_FRAME_BEACON,
2020                                                info->beacon_ies,
2021                                                info->beacon_ies_len);
2022                 if (res)
2023                         return res;
2024         }
2025         if (info->proberesp_ies) {
2026                 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2027                                                    info->proberesp_ies_len);
2028                 if (res)
2029                         return res;
2030         }
2031         if (info->assocresp_ies) {
2032                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2033                                                WMI_FRAME_ASSOC_RESP,
2034                                                info->assocresp_ies,
2035                                                info->assocresp_ies_len);
2036                 if (res)
2037                         return res;
2038         }
2039
2040         if (!add)
2041                 return 0;
2042
2043         ar->ap_mode_bkey.valid = false;
2044
2045         /* TODO:
2046          * info->interval
2047          * info->dtim_period
2048          */
2049
2050         if (info->head == NULL)
2051                 return -EINVAL;
2052         mgmt = (struct ieee80211_mgmt *) info->head;
2053         ies = mgmt->u.beacon.variable;
2054         if (ies > info->head + info->head_len)
2055                 return -EINVAL;
2056         ies_len = info->head + info->head_len - ies;
2057
2058         if (info->ssid == NULL)
2059                 return -EINVAL;
2060         memcpy(vif->ssid, info->ssid, info->ssid_len);
2061         vif->ssid_len = info->ssid_len;
2062         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2063                 return -EOPNOTSUPP; /* TODO */
2064
2065         ret = ath6kl_set_auth_type(vif, info->auth_type);
2066         if (ret)
2067                 return ret;
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         ar->vif_max = 1;
2461
2462         if (multi_norm_if_support)
2463                 ar->max_norm_iface = 2;
2464         else
2465                 ar->max_norm_iface = 1;
2466
2467         /* FIXME: Remove this once the multivif support is enabled */
2468         ar->max_norm_iface = 1;
2469
2470         spin_lock_init(&ar->lock);
2471         spin_lock_init(&ar->mcastpsq_lock);
2472         spin_lock_init(&ar->list_lock);
2473
2474         init_waitqueue_head(&ar->event_wq);
2475         sema_init(&ar->sem, 1);
2476
2477         INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
2478         INIT_LIST_HEAD(&ar->vif_list);
2479
2480         clear_bit(WMI_ENABLED, &ar->flag);
2481         clear_bit(SKIP_SCAN, &ar->flag);
2482         clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
2483
2484         ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
2485         ar->listen_intvl_b = 0;
2486         ar->tx_pwr = 0;
2487
2488         ar->intra_bss = 1;
2489         memset(&ar->sc_params, 0, sizeof(ar->sc_params));
2490         ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
2491         ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
2492         ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
2493
2494         ar->state = ATH6KL_STATE_OFF;
2495
2496         memset((u8 *)ar->sta_list, 0,
2497                AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
2498
2499         /* Init the PS queues */
2500         for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
2501                 spin_lock_init(&ar->sta_list[ctr].psq_lock);
2502                 skb_queue_head_init(&ar->sta_list[ctr].psq);
2503         }
2504
2505         skb_queue_head_init(&ar->mcastpsq);
2506
2507         memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2508
2509         return ar;
2510 }
2511
2512 int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
2513 {
2514         struct wiphy *wiphy = ar->wiphy;
2515         int ret;
2516
2517         wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
2518
2519         wiphy->max_remain_on_channel_duration = 5000;
2520
2521         /* set device pointer for wiphy */
2522         set_wiphy_dev(wiphy, ar->dev);
2523
2524         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2525                                  BIT(NL80211_IFTYPE_ADHOC) |
2526                                  BIT(NL80211_IFTYPE_AP);
2527         if (ar->p2p) {
2528                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
2529                                           BIT(NL80211_IFTYPE_P2P_CLIENT);
2530         }
2531
2532         /* max num of ssids that can be probed during scanning */
2533         wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2534         wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2535         wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2536         wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2537         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2538
2539         wiphy->cipher_suites = cipher_suites;
2540         wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2541
2542         wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
2543                               WIPHY_WOWLAN_DISCONNECT |
2544                               WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
2545                               WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
2546                               WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
2547                               WIPHY_WOWLAN_4WAY_HANDSHAKE;
2548         wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
2549         wiphy->wowlan.pattern_min_len = 1;
2550         wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
2551
2552         ret = wiphy_register(wiphy);
2553         if (ret < 0) {
2554                 ath6kl_err("couldn't register wiphy device\n");
2555                 return ret;
2556         }
2557
2558         return 0;
2559 }
2560
2561 static int ath6kl_init_if_data(struct ath6kl_vif *vif)
2562 {
2563         vif->aggr_cntxt = aggr_init(vif->ndev);
2564         if (!vif->aggr_cntxt) {
2565                 ath6kl_err("failed to initialize aggr\n");
2566                 return -ENOMEM;
2567         }
2568
2569         setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
2570                     (unsigned long) vif->ndev);
2571         set_bit(WMM_ENABLED, &vif->flags);
2572         spin_lock_init(&vif->if_lock);
2573
2574         return 0;
2575 }
2576
2577 void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
2578 {
2579         struct ath6kl *ar = vif->ar;
2580
2581         aggr_module_destroy(vif->aggr_cntxt);
2582
2583         ar->avail_idx_map |= BIT(vif->fw_vif_idx);
2584
2585         if (vif->nw_type == ADHOC_NETWORK)
2586                 ar->ibss_if_active = false;
2587
2588         unregister_netdevice(vif->ndev);
2589
2590         ar->num_vif--;
2591 }
2592
2593 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
2594                                         enum nl80211_iftype type, u8 fw_vif_idx,
2595                                         u8 nw_type)
2596 {
2597         struct net_device *ndev;
2598         struct ath6kl_vif *vif;
2599
2600         ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
2601         if (!ndev)
2602                 return NULL;
2603
2604         vif = netdev_priv(ndev);
2605         ndev->ieee80211_ptr = &vif->wdev;
2606         vif->wdev.wiphy = ar->wiphy;
2607         vif->ar = ar;
2608         vif->ndev = ndev;
2609         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
2610         vif->wdev.netdev = ndev;
2611         vif->wdev.iftype = type;
2612         vif->fw_vif_idx = fw_vif_idx;
2613         vif->nw_type = vif->next_mode = nw_type;
2614
2615         memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
2616         if (fw_vif_idx != 0)
2617                 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
2618                                      0x2;
2619
2620         init_netdev(ndev);
2621
2622         ath6kl_init_control_info(vif);
2623
2624         /* TODO: Pass interface specific pointer instead of ar */
2625         if (ath6kl_init_if_data(vif))
2626                 goto err;
2627
2628         if (register_netdevice(ndev))
2629                 goto err;
2630
2631         ar->avail_idx_map &= ~BIT(fw_vif_idx);
2632         vif->sme_state = SME_DISCONNECTED;
2633         set_bit(WLAN_ENABLED, &vif->flags);
2634         ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
2635         set_bit(NETDEV_REGISTERED, &vif->flags);
2636
2637         if (type == NL80211_IFTYPE_ADHOC)
2638                 ar->ibss_if_active = true;
2639
2640         spin_lock_bh(&ar->list_lock);
2641         list_add_tail(&vif->list, &ar->vif_list);
2642         spin_unlock_bh(&ar->list_lock);
2643
2644         return ndev;
2645
2646 err:
2647         aggr_module_destroy(vif->aggr_cntxt);
2648         free_netdev(ndev);
2649         return NULL;
2650 }
2651
2652 void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
2653 {
2654         wiphy_unregister(ar->wiphy);
2655         wiphy_free(ar->wiphy);
2656 }