OSDN Git Service

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