ath6kl: Enable force foreground scan in connected state
[cascardo/linux.git] / drivers / net / wireless / ath / ath6kl / cfg80211.c
1 /*
2  * Copyright (c) 2004-2011 Atheros Communications Inc.
3  *
4  * Permission to use, copy, modify, and/or distribute this software for any
5  * purpose with or without fee is hereby granted, provided that the above
6  * copyright notice and this permission notice appear in all copies.
7  *
8  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15  */
16
17 #include "core.h"
18 #include "cfg80211.h"
19 #include "debug.h"
20 #include "hif-ops.h"
21 #include "testmode.h"
22
23 static unsigned int ath6kl_p2p;
24
25 module_param(ath6kl_p2p, uint, 0644);
26
27 #define RATETAB_ENT(_rate, _rateid, _flags) {   \
28         .bitrate    = (_rate),                  \
29         .flags      = (_flags),                 \
30         .hw_value   = (_rateid),                \
31 }
32
33 #define CHAN2G(_channel, _freq, _flags) {   \
34         .band           = IEEE80211_BAND_2GHZ,  \
35         .hw_value       = (_channel),           \
36         .center_freq    = (_freq),              \
37         .flags          = (_flags),             \
38         .max_antenna_gain   = 0,                \
39         .max_power      = 30,                   \
40 }
41
42 #define CHAN5G(_channel, _flags) {                  \
43         .band           = IEEE80211_BAND_5GHZ,      \
44         .hw_value       = (_channel),               \
45         .center_freq    = 5000 + (5 * (_channel)),  \
46         .flags          = (_flags),                 \
47         .max_antenna_gain   = 0,                    \
48         .max_power      = 30,                       \
49 }
50
51 static struct ieee80211_rate ath6kl_rates[] = {
52         RATETAB_ENT(10, 0x1, 0),
53         RATETAB_ENT(20, 0x2, 0),
54         RATETAB_ENT(55, 0x4, 0),
55         RATETAB_ENT(110, 0x8, 0),
56         RATETAB_ENT(60, 0x10, 0),
57         RATETAB_ENT(90, 0x20, 0),
58         RATETAB_ENT(120, 0x40, 0),
59         RATETAB_ENT(180, 0x80, 0),
60         RATETAB_ENT(240, 0x100, 0),
61         RATETAB_ENT(360, 0x200, 0),
62         RATETAB_ENT(480, 0x400, 0),
63         RATETAB_ENT(540, 0x800, 0),
64 };
65
66 #define ath6kl_a_rates     (ath6kl_rates + 4)
67 #define ath6kl_a_rates_size    8
68 #define ath6kl_g_rates     (ath6kl_rates + 0)
69 #define ath6kl_g_rates_size    12
70
71 static struct ieee80211_channel ath6kl_2ghz_channels[] = {
72         CHAN2G(1, 2412, 0),
73         CHAN2G(2, 2417, 0),
74         CHAN2G(3, 2422, 0),
75         CHAN2G(4, 2427, 0),
76         CHAN2G(5, 2432, 0),
77         CHAN2G(6, 2437, 0),
78         CHAN2G(7, 2442, 0),
79         CHAN2G(8, 2447, 0),
80         CHAN2G(9, 2452, 0),
81         CHAN2G(10, 2457, 0),
82         CHAN2G(11, 2462, 0),
83         CHAN2G(12, 2467, 0),
84         CHAN2G(13, 2472, 0),
85         CHAN2G(14, 2484, 0),
86 };
87
88 static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
89         CHAN5G(34, 0), CHAN5G(36, 0),
90         CHAN5G(38, 0), CHAN5G(40, 0),
91         CHAN5G(42, 0), CHAN5G(44, 0),
92         CHAN5G(46, 0), CHAN5G(48, 0),
93         CHAN5G(52, 0), CHAN5G(56, 0),
94         CHAN5G(60, 0), CHAN5G(64, 0),
95         CHAN5G(100, 0), CHAN5G(104, 0),
96         CHAN5G(108, 0), CHAN5G(112, 0),
97         CHAN5G(116, 0), CHAN5G(120, 0),
98         CHAN5G(124, 0), CHAN5G(128, 0),
99         CHAN5G(132, 0), CHAN5G(136, 0),
100         CHAN5G(140, 0), CHAN5G(149, 0),
101         CHAN5G(153, 0), CHAN5G(157, 0),
102         CHAN5G(161, 0), CHAN5G(165, 0),
103         CHAN5G(184, 0), CHAN5G(188, 0),
104         CHAN5G(192, 0), CHAN5G(196, 0),
105         CHAN5G(200, 0), CHAN5G(204, 0),
106         CHAN5G(208, 0), CHAN5G(212, 0),
107         CHAN5G(216, 0),
108 };
109
110 static struct ieee80211_supported_band ath6kl_band_2ghz = {
111         .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
112         .channels = ath6kl_2ghz_channels,
113         .n_bitrates = ath6kl_g_rates_size,
114         .bitrates = ath6kl_g_rates,
115 };
116
117 static struct ieee80211_supported_band ath6kl_band_5ghz = {
118         .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
119         .channels = ath6kl_5ghz_a_channels,
120         .n_bitrates = ath6kl_a_rates_size,
121         .bitrates = ath6kl_a_rates,
122 };
123
124 static int ath6kl_set_wpa_version(struct ath6kl *ar,
125                                   enum nl80211_wpa_versions wpa_version)
126 {
127         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
128
129         if (!wpa_version) {
130                 ar->auth_mode = NONE_AUTH;
131         } else if (wpa_version & NL80211_WPA_VERSION_2) {
132                 ar->auth_mode = WPA2_AUTH;
133         } else if (wpa_version & NL80211_WPA_VERSION_1) {
134                 ar->auth_mode = WPA_AUTH;
135         } else {
136                 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
137                 return -ENOTSUPP;
138         }
139
140         return 0;
141 }
142
143 static int ath6kl_set_auth_type(struct ath6kl *ar,
144                                 enum nl80211_auth_type auth_type)
145 {
146
147         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
148
149         switch (auth_type) {
150         case NL80211_AUTHTYPE_OPEN_SYSTEM:
151                 ar->dot11_auth_mode = OPEN_AUTH;
152                 break;
153         case NL80211_AUTHTYPE_SHARED_KEY:
154                 ar->dot11_auth_mode = SHARED_AUTH;
155                 break;
156         case NL80211_AUTHTYPE_NETWORK_EAP:
157                 ar->dot11_auth_mode = LEAP_AUTH;
158                 break;
159
160         case NL80211_AUTHTYPE_AUTOMATIC:
161                 ar->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
162                 break;
163
164         default:
165                 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
166                 return -ENOTSUPP;
167         }
168
169         return 0;
170 }
171
172 static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
173 {
174         u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
175         u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
176                 &ar->grp_crypto_len;
177
178         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
179                    __func__, cipher, ucast);
180
181         switch (cipher) {
182         case 0:
183                 /* our own hack to use value 0 as no crypto used */
184                 *ar_cipher = NONE_CRYPT;
185                 *ar_cipher_len = 0;
186                 break;
187         case WLAN_CIPHER_SUITE_WEP40:
188                 *ar_cipher = WEP_CRYPT;
189                 *ar_cipher_len = 5;
190                 break;
191         case WLAN_CIPHER_SUITE_WEP104:
192                 *ar_cipher = WEP_CRYPT;
193                 *ar_cipher_len = 13;
194                 break;
195         case WLAN_CIPHER_SUITE_TKIP:
196                 *ar_cipher = TKIP_CRYPT;
197                 *ar_cipher_len = 0;
198                 break;
199         case WLAN_CIPHER_SUITE_CCMP:
200                 *ar_cipher = AES_CRYPT;
201                 *ar_cipher_len = 0;
202                 break;
203         default:
204                 ath6kl_err("cipher 0x%x not supported\n", cipher);
205                 return -ENOTSUPP;
206         }
207
208         return 0;
209 }
210
211 static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
212 {
213         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
214
215         if (key_mgmt == WLAN_AKM_SUITE_PSK) {
216                 if (ar->auth_mode == WPA_AUTH)
217                         ar->auth_mode = WPA_PSK_AUTH;
218                 else if (ar->auth_mode == WPA2_AUTH)
219                         ar->auth_mode = WPA2_PSK_AUTH;
220         } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
221                 ar->auth_mode = NONE_AUTH;
222         }
223 }
224
225 static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
226 {
227         if (!test_bit(WMI_READY, &ar->flag)) {
228                 ath6kl_err("wmi is not ready\n");
229                 return false;
230         }
231
232         if (!test_bit(WLAN_ENABLED, &ar->flag)) {
233                 ath6kl_err("wlan disabled\n");
234                 return false;
235         }
236
237         return true;
238 }
239
240 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
241                                    struct cfg80211_connect_params *sme)
242 {
243         struct ath6kl *ar = ath6kl_priv(dev);
244         int status;
245
246         ar->sme_state = SME_CONNECTING;
247
248         if (!ath6kl_cfg80211_ready(ar))
249                 return -EIO;
250
251         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
252                 ath6kl_err("destroy in progress\n");
253                 return -EBUSY;
254         }
255
256         if (test_bit(SKIP_SCAN, &ar->flag) &&
257             ((sme->channel && sme->channel->center_freq == 0) ||
258              (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
259                 ath6kl_err("SkipScan: channel or bssid invalid\n");
260                 return -EINVAL;
261         }
262
263         if (down_interruptible(&ar->sem)) {
264                 ath6kl_err("busy, couldn't get access\n");
265                 return -ERESTARTSYS;
266         }
267
268         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
269                 ath6kl_err("busy, destroy in progress\n");
270                 up(&ar->sem);
271                 return -EBUSY;
272         }
273
274         if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
275                 /*
276                  * sleep until the command queue drains
277                  */
278                 wait_event_interruptible_timeout(ar->event_wq,
279                         ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
280                         WMI_TIMEOUT);
281                 if (signal_pending(current)) {
282                         ath6kl_err("cmd queue drain timeout\n");
283                         up(&ar->sem);
284                         return -EINTR;
285                 }
286         }
287
288         if (test_bit(CONNECTED, &ar->flag) &&
289             ar->ssid_len == sme->ssid_len &&
290             !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
291                 ar->reconnect_flag = true;
292                 status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
293                                                   ar->ch_hint);
294
295                 up(&ar->sem);
296                 if (status) {
297                         ath6kl_err("wmi_reconnect_cmd failed\n");
298                         return -EIO;
299                 }
300                 return 0;
301         } else if (ar->ssid_len == sme->ssid_len &&
302                    !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
303                 ath6kl_disconnect(ar);
304         }
305
306         memset(ar->ssid, 0, sizeof(ar->ssid));
307         ar->ssid_len = sme->ssid_len;
308         memcpy(ar->ssid, sme->ssid, sme->ssid_len);
309
310         if (sme->channel)
311                 ar->ch_hint = sme->channel->center_freq;
312
313         memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
314         if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
315                 memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
316
317         ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
318
319         status = ath6kl_set_auth_type(ar, sme->auth_type);
320         if (status) {
321                 up(&ar->sem);
322                 return status;
323         }
324
325         if (sme->crypto.n_ciphers_pairwise)
326                 ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
327         else
328                 ath6kl_set_cipher(ar, 0, true);
329
330         ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
331
332         if (sme->crypto.n_akm_suites)
333                 ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
334
335         if ((sme->key_len) &&
336             (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
337                 struct ath6kl_key *key = NULL;
338
339                 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
340                     sme->key_idx > WMI_MAX_KEY_INDEX) {
341                         ath6kl_err("key index %d out of bounds\n",
342                                    sme->key_idx);
343                         up(&ar->sem);
344                         return -ENOENT;
345                 }
346
347                 key = &ar->keys[sme->key_idx];
348                 key->key_len = sme->key_len;
349                 memcpy(key->key, sme->key, key->key_len);
350                 key->cipher = ar->prwise_crypto;
351                 ar->def_txkey_index = sme->key_idx;
352
353                 ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
354                                       ar->prwise_crypto,
355                                       GROUP_USAGE | TX_USAGE,
356                                       key->key_len,
357                                       NULL,
358                                       key->key, KEY_OP_INIT_VAL, NULL,
359                                       NO_SYNC_WMIFLAG);
360         }
361
362         if (!ar->usr_bss_filter) {
363                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
364                 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
365                         ath6kl_err("couldn't set bss filtering\n");
366                         up(&ar->sem);
367                         return -EIO;
368                 }
369         }
370
371         ar->nw_type = ar->next_mode;
372
373         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
374                    "%s: connect called with authmode %d dot11 auth %d"
375                    " PW crypto %d PW crypto len %d GRP crypto %d"
376                    " GRP crypto len %d channel hint %u\n",
377                    __func__,
378                    ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
379                    ar->prwise_crypto_len, ar->grp_crypto,
380                    ar->grp_crypto_len, ar->ch_hint);
381
382         ar->reconnect_flag = 0;
383         status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
384                                         ar->dot11_auth_mode, ar->auth_mode,
385                                         ar->prwise_crypto,
386                                         ar->prwise_crypto_len,
387                                         ar->grp_crypto, ar->grp_crypto_len,
388                                         ar->ssid_len, ar->ssid,
389                                         ar->req_bssid, ar->ch_hint,
390                                         ar->connect_ctrl_flags);
391
392         up(&ar->sem);
393
394         if (status == -EINVAL) {
395                 memset(ar->ssid, 0, sizeof(ar->ssid));
396                 ar->ssid_len = 0;
397                 ath6kl_err("invalid request\n");
398                 return -ENOENT;
399         } else if (status) {
400                 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
401                 return -EIO;
402         }
403
404         if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
405             ((ar->auth_mode == WPA_PSK_AUTH)
406              || (ar->auth_mode == WPA2_PSK_AUTH))) {
407                 mod_timer(&ar->disconnect_timer,
408                           jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
409         }
410
411         ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
412         set_bit(CONNECT_PEND, &ar->flag);
413
414         return 0;
415 }
416
417 static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
418                                     struct ieee80211_channel *chan,
419                                     const u8 *beacon_ie, size_t beacon_ie_len)
420 {
421         struct cfg80211_bss *bss;
422         u8 *ie;
423
424         bss = cfg80211_get_bss(ar->wdev->wiphy, chan, bssid,
425                                ar->ssid, ar->ssid_len, WLAN_CAPABILITY_ESS,
426                                WLAN_CAPABILITY_ESS);
427         if (bss == NULL) {
428                 /*
429                  * Since cfg80211 may not yet know about the BSS,
430                  * generate a partial entry until the first BSS info
431                  * event becomes available.
432                  *
433                  * Prepend SSID element since it is not included in the Beacon
434                  * IEs from the target.
435                  */
436                 ie = kmalloc(2 + ar->ssid_len + beacon_ie_len, GFP_KERNEL);
437                 if (ie == NULL)
438                         return -ENOMEM;
439                 ie[0] = WLAN_EID_SSID;
440                 ie[1] = ar->ssid_len;
441                 memcpy(ie + 2, ar->ssid, ar->ssid_len);
442                 memcpy(ie + 2 + ar->ssid_len, beacon_ie, beacon_ie_len);
443                 bss = cfg80211_inform_bss(ar->wdev->wiphy, chan,
444                                           bssid, 0, WLAN_CAPABILITY_ESS, 100,
445                                           ie, 2 + ar->ssid_len + beacon_ie_len,
446                                           0, GFP_KERNEL);
447                 if (bss)
448                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
449                                    "%pM prior to indicating connect/roamed "
450                                    "event\n", bssid);
451                 kfree(ie);
452         } else
453                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
454                            "entry\n");
455
456         if (bss == NULL)
457                 return -ENOMEM;
458
459         cfg80211_put_bss(bss);
460
461         return 0;
462 }
463
464 void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
465                                    u8 *bssid, u16 listen_intvl,
466                                    u16 beacon_intvl,
467                                    enum network_type nw_type,
468                                    u8 beacon_ie_len, u8 assoc_req_len,
469                                    u8 assoc_resp_len, u8 *assoc_info)
470 {
471         struct ieee80211_channel *chan;
472
473         /* capinfo + listen interval */
474         u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
475
476         /* capinfo + status code +  associd */
477         u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
478
479         u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
480         u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
481             assoc_resp_ie_offset;
482
483         assoc_req_len -= assoc_req_ie_offset;
484         assoc_resp_len -= assoc_resp_ie_offset;
485
486         /*
487          * Store Beacon interval here; DTIM period will be available only once
488          * a Beacon frame from the AP is seen.
489          */
490         ar->assoc_bss_beacon_int = beacon_intvl;
491         clear_bit(DTIM_PERIOD_AVAIL, &ar->flag);
492
493         if (nw_type & ADHOC_NETWORK) {
494                 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
495                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
496                                    "%s: ath6k not in ibss mode\n", __func__);
497                         return;
498                 }
499         }
500
501         if (nw_type & INFRA_NETWORK) {
502                 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
503                     ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
504                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
505                                    "%s: ath6k not in station mode\n", __func__);
506                         return;
507                 }
508         }
509
510         chan = ieee80211_get_channel(ar->wdev->wiphy, (int) channel);
511
512
513         if (nw_type & ADHOC_NETWORK) {
514                 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
515                 return;
516         }
517
518         if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
519                                      beacon_ie_len) < 0) {
520                 ath6kl_err("could not add cfg80211 bss entry for "
521                            "connect/roamed notification\n");
522                 return;
523         }
524
525         if (ar->sme_state == SME_CONNECTING) {
526                 /* inform connect result to cfg80211 */
527                 ar->sme_state = SME_CONNECTED;
528                 cfg80211_connect_result(ar->net_dev, bssid,
529                                         assoc_req_ie, assoc_req_len,
530                                         assoc_resp_ie, assoc_resp_len,
531                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
532         } else if (ar->sme_state == SME_CONNECTED) {
533                 /* inform roam event to cfg80211 */
534                 cfg80211_roamed(ar->net_dev, chan, bssid,
535                                 assoc_req_ie, assoc_req_len,
536                                 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
537         }
538 }
539
540 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
541                                       struct net_device *dev, u16 reason_code)
542 {
543         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
544
545         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
546                    reason_code);
547
548         if (!ath6kl_cfg80211_ready(ar))
549                 return -EIO;
550
551         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
552                 ath6kl_err("busy, destroy in progress\n");
553                 return -EBUSY;
554         }
555
556         if (down_interruptible(&ar->sem)) {
557                 ath6kl_err("busy, couldn't get access\n");
558                 return -ERESTARTSYS;
559         }
560
561         ar->reconnect_flag = 0;
562         ath6kl_disconnect(ar);
563         memset(ar->ssid, 0, sizeof(ar->ssid));
564         ar->ssid_len = 0;
565
566         if (!test_bit(SKIP_SCAN, &ar->flag))
567                 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
568
569         up(&ar->sem);
570
571         ar->sme_state = SME_DISCONNECTED;
572
573         return 0;
574 }
575
576 void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
577                                       u8 *bssid, u8 assoc_resp_len,
578                                       u8 *assoc_info, u16 proto_reason)
579 {
580         if (ar->scan_req) {
581                 cfg80211_scan_done(ar->scan_req, true);
582                 ar->scan_req = NULL;
583         }
584
585         if (ar->nw_type & ADHOC_NETWORK) {
586                 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
587                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
588                                    "%s: ath6k not in ibss mode\n", __func__);
589                         return;
590                 }
591                 memset(bssid, 0, ETH_ALEN);
592                 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
593                 return;
594         }
595
596         if (ar->nw_type & INFRA_NETWORK) {
597                 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
598                     ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
599                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
600                                    "%s: ath6k not in station mode\n", __func__);
601                         return;
602                 }
603         }
604
605         /*
606          * Send a disconnect command to target when a disconnect event is
607          * received with reason code other than 3 (DISCONNECT_CMD - disconnect
608          * request from host) to make the firmware stop trying to connect even
609          * after giving disconnect event. There will be one more disconnect
610          * event for this disconnect command with reason code DISCONNECT_CMD
611          * which will be notified to cfg80211.
612          */
613
614         if (reason != DISCONNECT_CMD) {
615                 ath6kl_wmi_disconnect_cmd(ar->wmi);
616                 return;
617         }
618
619         clear_bit(CONNECT_PEND, &ar->flag);
620
621         if (ar->sme_state == SME_CONNECTING) {
622                 cfg80211_connect_result(ar->net_dev,
623                                 bssid, NULL, 0,
624                                 NULL, 0,
625                                 WLAN_STATUS_UNSPECIFIED_FAILURE,
626                                 GFP_KERNEL);
627         } else if (ar->sme_state == SME_CONNECTED) {
628                 cfg80211_disconnected(ar->net_dev, reason,
629                                 NULL, 0, GFP_KERNEL);
630         }
631
632         ar->sme_state = SME_DISCONNECTED;
633 }
634
635 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
636                                 struct cfg80211_scan_request *request)
637 {
638         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
639         s8 n_channels = 0;
640         u16 *channels = NULL;
641         int ret = 0;
642         u32 force_fg_scan = 0;
643
644         if (!ath6kl_cfg80211_ready(ar))
645                 return -EIO;
646
647         if (!ar->usr_bss_filter) {
648                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
649                 ret = ath6kl_wmi_bssfilter_cmd(
650                         ar->wmi,
651                         (test_bit(CONNECTED, &ar->flag) ?
652                          ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
653                 if (ret) {
654                         ath6kl_err("couldn't set bss filtering\n");
655                         return ret;
656                 }
657         }
658
659         if (request->n_ssids && request->ssids[0].ssid_len) {
660                 u8 i;
661
662                 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
663                         request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
664
665                 for (i = 0; i < request->n_ssids; i++)
666                         ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
667                                                   SPECIFIC_SSID_FLAG,
668                                                   request->ssids[i].ssid_len,
669                                                   request->ssids[i].ssid);
670         }
671
672         if (request->ie) {
673                 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
674                                                request->ie, request->ie_len);
675                 if (ret) {
676                         ath6kl_err("failed to set Probe Request appie for "
677                                    "scan");
678                         return ret;
679                 }
680         }
681
682         /*
683          * Scan only the requested channels if the request specifies a set of
684          * channels. If the list is longer than the target supports, do not
685          * configure the list and instead, scan all available channels.
686          */
687         if (request->n_channels > 0 &&
688             request->n_channels <= WMI_MAX_CHANNELS) {
689                 u8 i;
690
691                 n_channels = request->n_channels;
692
693                 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
694                 if (channels == NULL) {
695                         ath6kl_warn("failed to set scan channels, "
696                                     "scan all channels");
697                         n_channels = 0;
698                 }
699
700                 for (i = 0; i < n_channels; i++)
701                         channels[i] = request->channels[i]->center_freq;
702         }
703
704         if (test_bit(CONNECTED, &ar->flag))
705                 force_fg_scan = 1;
706
707         ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, force_fg_scan,
708                                        false, 0, 0, n_channels, channels);
709         if (ret)
710                 ath6kl_err("wmi_startscan_cmd failed\n");
711         else
712                 ar->scan_req = request;
713
714         kfree(channels);
715
716         return ret;
717 }
718
719 void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
720 {
721         int i;
722
723         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
724
725         if (!ar->scan_req)
726                 return;
727
728         if ((status == -ECANCELED) || (status == -EBUSY)) {
729                 cfg80211_scan_done(ar->scan_req, true);
730                 goto out;
731         }
732
733         cfg80211_scan_done(ar->scan_req, false);
734
735         if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
736                 for (i = 0; i < ar->scan_req->n_ssids; i++) {
737                         ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
738                                                   DISABLE_SSID_FLAG,
739                                                   0, NULL);
740                 }
741         }
742
743 out:
744         ar->scan_req = NULL;
745 }
746
747 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
748                                    u8 key_index, bool pairwise,
749                                    const u8 *mac_addr,
750                                    struct key_params *params)
751 {
752         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
753         struct ath6kl_key *key = NULL;
754         u8 key_usage;
755         u8 key_type;
756         int status = 0;
757
758         if (!ath6kl_cfg80211_ready(ar))
759                 return -EIO;
760
761         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
762                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
763                            "%s: key index %d out of bounds\n", __func__,
764                            key_index);
765                 return -ENOENT;
766         }
767
768         key = &ar->keys[key_index];
769         memset(key, 0, sizeof(struct ath6kl_key));
770
771         if (pairwise)
772                 key_usage = PAIRWISE_USAGE;
773         else
774                 key_usage = GROUP_USAGE;
775
776         if (params) {
777                 if (params->key_len > WLAN_MAX_KEY_LEN ||
778                     params->seq_len > sizeof(key->seq))
779                         return -EINVAL;
780
781                 key->key_len = params->key_len;
782                 memcpy(key->key, params->key, key->key_len);
783                 key->seq_len = params->seq_len;
784                 memcpy(key->seq, params->seq, key->seq_len);
785                 key->cipher = params->cipher;
786         }
787
788         switch (key->cipher) {
789         case WLAN_CIPHER_SUITE_WEP40:
790         case WLAN_CIPHER_SUITE_WEP104:
791                 key_type = WEP_CRYPT;
792                 break;
793
794         case WLAN_CIPHER_SUITE_TKIP:
795                 key_type = TKIP_CRYPT;
796                 break;
797
798         case WLAN_CIPHER_SUITE_CCMP:
799                 key_type = AES_CRYPT;
800                 break;
801
802         default:
803                 return -ENOTSUPP;
804         }
805
806         if (((ar->auth_mode == WPA_PSK_AUTH)
807              || (ar->auth_mode == WPA2_PSK_AUTH))
808             && (key_usage & GROUP_USAGE))
809                 del_timer(&ar->disconnect_timer);
810
811         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
812                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
813                    __func__, key_index, key->key_len, key_type,
814                    key_usage, key->seq_len);
815
816         ar->def_txkey_index = key_index;
817
818         if (ar->nw_type == AP_NETWORK && !pairwise &&
819             (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
820                 ar->ap_mode_bkey.valid = true;
821                 ar->ap_mode_bkey.key_index = key_index;
822                 ar->ap_mode_bkey.key_type = key_type;
823                 ar->ap_mode_bkey.key_len = key->key_len;
824                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
825                 if (!test_bit(CONNECTED, &ar->flag)) {
826                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
827                                    "key configuration until AP mode has been "
828                                    "started\n");
829                         /*
830                          * The key will be set in ath6kl_connect_ap_mode() once
831                          * the connected event is received from the target.
832                          */
833                         return 0;
834                 }
835         }
836
837         if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
838             !test_bit(CONNECTED, &ar->flag)) {
839                 /*
840                  * Store the key locally so that it can be re-configured after
841                  * the AP mode has properly started
842                  * (ath6kl_install_statioc_wep_keys).
843                  */
844                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
845                            "until AP mode has been started\n");
846                 ar->wep_key_list[key_index].key_len = key->key_len;
847                 memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
848                 return 0;
849         }
850
851         status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
852                                        key_type, key_usage, key->key_len,
853                                        key->seq, key->key, KEY_OP_INIT_VAL,
854                                        (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
855
856         if (status)
857                 return -EIO;
858
859         return 0;
860 }
861
862 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
863                                    u8 key_index, bool pairwise,
864                                    const u8 *mac_addr)
865 {
866         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
867
868         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
869
870         if (!ath6kl_cfg80211_ready(ar))
871                 return -EIO;
872
873         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
874                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
875                            "%s: key index %d out of bounds\n", __func__,
876                            key_index);
877                 return -ENOENT;
878         }
879
880         if (!ar->keys[key_index].key_len) {
881                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
882                            "%s: index %d is empty\n", __func__, key_index);
883                 return 0;
884         }
885
886         ar->keys[key_index].key_len = 0;
887
888         return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
889 }
890
891 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
892                                    u8 key_index, bool pairwise,
893                                    const u8 *mac_addr, void *cookie,
894                                    void (*callback) (void *cookie,
895                                                      struct key_params *))
896 {
897         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
898         struct ath6kl_key *key = NULL;
899         struct key_params params;
900
901         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
902
903         if (!ath6kl_cfg80211_ready(ar))
904                 return -EIO;
905
906         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
907                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
908                            "%s: key index %d out of bounds\n", __func__,
909                            key_index);
910                 return -ENOENT;
911         }
912
913         key = &ar->keys[key_index];
914         memset(&params, 0, sizeof(params));
915         params.cipher = key->cipher;
916         params.key_len = key->key_len;
917         params.seq_len = key->seq_len;
918         params.seq = key->seq;
919         params.key = key->key;
920
921         callback(cookie, &params);
922
923         return key->key_len ? 0 : -ENOENT;
924 }
925
926 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
927                                            struct net_device *ndev,
928                                            u8 key_index, bool unicast,
929                                            bool multicast)
930 {
931         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
932         struct ath6kl_key *key = NULL;
933         int status = 0;
934         u8 key_usage;
935         enum crypto_type key_type = NONE_CRYPT;
936
937         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
938
939         if (!ath6kl_cfg80211_ready(ar))
940                 return -EIO;
941
942         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
943                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
944                            "%s: key index %d out of bounds\n",
945                            __func__, key_index);
946                 return -ENOENT;
947         }
948
949         if (!ar->keys[key_index].key_len) {
950                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
951                            __func__, key_index);
952                 return -EINVAL;
953         }
954
955         ar->def_txkey_index = key_index;
956         key = &ar->keys[ar->def_txkey_index];
957         key_usage = GROUP_USAGE;
958         if (ar->prwise_crypto == WEP_CRYPT)
959                 key_usage |= TX_USAGE;
960         if (unicast)
961                 key_type = ar->prwise_crypto;
962         if (multicast)
963                 key_type = ar->grp_crypto;
964
965         if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
966                 return 0; /* Delay until AP mode has been started */
967
968         status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
969                                        key_type, key_usage,
970                                        key->key_len, key->seq, key->key,
971                                        KEY_OP_INIT_VAL, NULL,
972                                        SYNC_BOTH_WMIFLAG);
973         if (status)
974                 return -EIO;
975
976         return 0;
977 }
978
979 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
980                                        bool ismcast)
981 {
982         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
983                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
984
985         cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
986                                      (ismcast ? NL80211_KEYTYPE_GROUP :
987                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
988                                      GFP_KERNEL);
989 }
990
991 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
992 {
993         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
994         int ret;
995
996         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
997                    changed);
998
999         if (!ath6kl_cfg80211_ready(ar))
1000                 return -EIO;
1001
1002         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1003                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1004                 if (ret != 0) {
1005                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1006                         return -EIO;
1007                 }
1008         }
1009
1010         return 0;
1011 }
1012
1013 /*
1014  * The type nl80211_tx_power_setting replaces the following
1015  * data type from 2.6.36 onwards
1016 */
1017 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1018                                        enum nl80211_tx_power_setting type,
1019                                        int dbm)
1020 {
1021         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1022         u8 ath6kl_dbm;
1023
1024         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1025                    type, dbm);
1026
1027         if (!ath6kl_cfg80211_ready(ar))
1028                 return -EIO;
1029
1030         switch (type) {
1031         case NL80211_TX_POWER_AUTOMATIC:
1032                 return 0;
1033         case NL80211_TX_POWER_LIMITED:
1034                 ar->tx_pwr = ath6kl_dbm = dbm;
1035                 break;
1036         default:
1037                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1038                            __func__, type);
1039                 return -EOPNOTSUPP;
1040         }
1041
1042         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1043
1044         return 0;
1045 }
1046
1047 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1048 {
1049         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1050
1051         if (!ath6kl_cfg80211_ready(ar))
1052                 return -EIO;
1053
1054         if (test_bit(CONNECTED, &ar->flag)) {
1055                 ar->tx_pwr = 0;
1056
1057                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1058                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1059                         return -EIO;
1060                 }
1061
1062                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1063                                                  5 * HZ);
1064
1065                 if (signal_pending(current)) {
1066                         ath6kl_err("target did not respond\n");
1067                         return -EINTR;
1068                 }
1069         }
1070
1071         *dbm = ar->tx_pwr;
1072         return 0;
1073 }
1074
1075 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1076                                           struct net_device *dev,
1077                                           bool pmgmt, int timeout)
1078 {
1079         struct ath6kl *ar = ath6kl_priv(dev);
1080         struct wmi_power_mode_cmd mode;
1081
1082         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1083                    __func__, pmgmt, timeout);
1084
1085         if (!ath6kl_cfg80211_ready(ar))
1086                 return -EIO;
1087
1088         if (pmgmt) {
1089                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1090                 mode.pwr_mode = REC_POWER;
1091         } else {
1092                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1093                 mode.pwr_mode = MAX_PERF_POWER;
1094         }
1095
1096         if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1097                 ath6kl_err("wmi_powermode_cmd failed\n");
1098                 return -EIO;
1099         }
1100
1101         return 0;
1102 }
1103
1104 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1105                                         struct net_device *ndev,
1106                                         enum nl80211_iftype type, u32 *flags,
1107                                         struct vif_params *params)
1108 {
1109         struct ath6kl *ar = ath6kl_priv(ndev);
1110         struct wireless_dev *wdev = ar->wdev;
1111
1112         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1113
1114         if (!ath6kl_cfg80211_ready(ar))
1115                 return -EIO;
1116
1117         switch (type) {
1118         case NL80211_IFTYPE_STATION:
1119                 ar->next_mode = INFRA_NETWORK;
1120                 break;
1121         case NL80211_IFTYPE_ADHOC:
1122                 ar->next_mode = ADHOC_NETWORK;
1123                 break;
1124         case NL80211_IFTYPE_AP:
1125                 ar->next_mode = AP_NETWORK;
1126                 break;
1127         case NL80211_IFTYPE_P2P_CLIENT:
1128                 ar->next_mode = INFRA_NETWORK;
1129                 break;
1130         case NL80211_IFTYPE_P2P_GO:
1131                 ar->next_mode = AP_NETWORK;
1132                 break;
1133         default:
1134                 ath6kl_err("invalid interface type %u\n", type);
1135                 return -EOPNOTSUPP;
1136         }
1137
1138         wdev->iftype = type;
1139
1140         return 0;
1141 }
1142
1143 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1144                                      struct net_device *dev,
1145                                      struct cfg80211_ibss_params *ibss_param)
1146 {
1147         struct ath6kl *ar = ath6kl_priv(dev);
1148         int status;
1149
1150         if (!ath6kl_cfg80211_ready(ar))
1151                 return -EIO;
1152
1153         ar->ssid_len = ibss_param->ssid_len;
1154         memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
1155
1156         if (ibss_param->channel)
1157                 ar->ch_hint = ibss_param->channel->center_freq;
1158
1159         if (ibss_param->channel_fixed) {
1160                 /*
1161                  * TODO: channel_fixed: The channel should be fixed, do not
1162                  * search for IBSSs to join on other channels. Target
1163                  * firmware does not support this feature, needs to be
1164                  * updated.
1165                  */
1166                 return -EOPNOTSUPP;
1167         }
1168
1169         memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
1170         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1171                 memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
1172
1173         ath6kl_set_wpa_version(ar, 0);
1174
1175         status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1176         if (status)
1177                 return status;
1178
1179         if (ibss_param->privacy) {
1180                 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1181                 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1182         } else {
1183                 ath6kl_set_cipher(ar, 0, true);
1184                 ath6kl_set_cipher(ar, 0, false);
1185         }
1186
1187         ar->nw_type = ar->next_mode;
1188
1189         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1190                    "%s: connect called with authmode %d dot11 auth %d"
1191                    " PW crypto %d PW crypto len %d GRP crypto %d"
1192                    " GRP crypto len %d channel hint %u\n",
1193                    __func__,
1194                    ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1195                    ar->prwise_crypto_len, ar->grp_crypto,
1196                    ar->grp_crypto_len, ar->ch_hint);
1197
1198         status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1199                                         ar->dot11_auth_mode, ar->auth_mode,
1200                                         ar->prwise_crypto,
1201                                         ar->prwise_crypto_len,
1202                                         ar->grp_crypto, ar->grp_crypto_len,
1203                                         ar->ssid_len, ar->ssid,
1204                                         ar->req_bssid, ar->ch_hint,
1205                                         ar->connect_ctrl_flags);
1206         set_bit(CONNECT_PEND, &ar->flag);
1207
1208         return 0;
1209 }
1210
1211 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1212                                       struct net_device *dev)
1213 {
1214         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
1215
1216         if (!ath6kl_cfg80211_ready(ar))
1217                 return -EIO;
1218
1219         ath6kl_disconnect(ar);
1220         memset(ar->ssid, 0, sizeof(ar->ssid));
1221         ar->ssid_len = 0;
1222
1223         return 0;
1224 }
1225
1226 static const u32 cipher_suites[] = {
1227         WLAN_CIPHER_SUITE_WEP40,
1228         WLAN_CIPHER_SUITE_WEP104,
1229         WLAN_CIPHER_SUITE_TKIP,
1230         WLAN_CIPHER_SUITE_CCMP,
1231 };
1232
1233 static bool is_rate_legacy(s32 rate)
1234 {
1235         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1236                 6000, 9000, 12000, 18000, 24000,
1237                 36000, 48000, 54000
1238         };
1239         u8 i;
1240
1241         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1242                 if (rate == legacy[i])
1243                         return true;
1244
1245         return false;
1246 }
1247
1248 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1249 {
1250         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1251                 52000, 58500, 65000, 72200
1252         };
1253         u8 i;
1254
1255         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1256                 if (rate == ht20[i]) {
1257                         if (i == ARRAY_SIZE(ht20) - 1)
1258                                 /* last rate uses sgi */
1259                                 *sgi = true;
1260                         else
1261                                 *sgi = false;
1262
1263                         *mcs = i;
1264                         return true;
1265                 }
1266         }
1267         return false;
1268 }
1269
1270 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1271 {
1272         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1273                 81000, 108000, 121500, 135000,
1274                 150000
1275         };
1276         u8 i;
1277
1278         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1279                 if (rate == ht40[i]) {
1280                         if (i == ARRAY_SIZE(ht40) - 1)
1281                                 /* last rate uses sgi */
1282                                 *sgi = true;
1283                         else
1284                                 *sgi = false;
1285
1286                         *mcs = i;
1287                         return true;
1288                 }
1289         }
1290
1291         return false;
1292 }
1293
1294 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1295                               u8 *mac, struct station_info *sinfo)
1296 {
1297         struct ath6kl *ar = ath6kl_priv(dev);
1298         long left;
1299         bool sgi;
1300         s32 rate;
1301         int ret;
1302         u8 mcs;
1303
1304         if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
1305                 return -ENOENT;
1306
1307         if (down_interruptible(&ar->sem))
1308                 return -EBUSY;
1309
1310         set_bit(STATS_UPDATE_PEND, &ar->flag);
1311
1312         ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1313
1314         if (ret != 0) {
1315                 up(&ar->sem);
1316                 return -EIO;
1317         }
1318
1319         left = wait_event_interruptible_timeout(ar->event_wq,
1320                                                 !test_bit(STATS_UPDATE_PEND,
1321                                                           &ar->flag),
1322                                                 WMI_TIMEOUT);
1323
1324         up(&ar->sem);
1325
1326         if (left == 0)
1327                 return -ETIMEDOUT;
1328         else if (left < 0)
1329                 return left;
1330
1331         if (ar->target_stats.rx_byte) {
1332                 sinfo->rx_bytes = ar->target_stats.rx_byte;
1333                 sinfo->filled |= STATION_INFO_RX_BYTES;
1334                 sinfo->rx_packets = ar->target_stats.rx_pkt;
1335                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1336         }
1337
1338         if (ar->target_stats.tx_byte) {
1339                 sinfo->tx_bytes = ar->target_stats.tx_byte;
1340                 sinfo->filled |= STATION_INFO_TX_BYTES;
1341                 sinfo->tx_packets = ar->target_stats.tx_pkt;
1342                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1343         }
1344
1345         sinfo->signal = ar->target_stats.cs_rssi;
1346         sinfo->filled |= STATION_INFO_SIGNAL;
1347
1348         rate = ar->target_stats.tx_ucast_rate;
1349
1350         if (is_rate_legacy(rate)) {
1351                 sinfo->txrate.legacy = rate / 100;
1352         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1353                 if (sgi) {
1354                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1355                         sinfo->txrate.mcs = mcs - 1;
1356                 } else {
1357                         sinfo->txrate.mcs = mcs;
1358                 }
1359
1360                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1361         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1362                 if (sgi) {
1363                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1364                         sinfo->txrate.mcs = mcs - 1;
1365                 } else {
1366                         sinfo->txrate.mcs = mcs;
1367                 }
1368
1369                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1370                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1371         } else {
1372                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1373                            "invalid rate from stats: %d\n", rate);
1374                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1375                 return 0;
1376         }
1377
1378         sinfo->filled |= STATION_INFO_TX_BITRATE;
1379
1380         if (test_bit(CONNECTED, &ar->flag) &&
1381             test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
1382             ar->nw_type == INFRA_NETWORK) {
1383                 sinfo->filled |= STATION_INFO_BSS_PARAM;
1384                 sinfo->bss_param.flags = 0;
1385                 sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
1386                 sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
1387         }
1388
1389         return 0;
1390 }
1391
1392 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1393                             struct cfg80211_pmksa *pmksa)
1394 {
1395         struct ath6kl *ar = ath6kl_priv(netdev);
1396         return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1397                                        pmksa->pmkid, true);
1398 }
1399
1400 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1401                             struct cfg80211_pmksa *pmksa)
1402 {
1403         struct ath6kl *ar = ath6kl_priv(netdev);
1404         return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1405                                        pmksa->pmkid, false);
1406 }
1407
1408 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1409 {
1410         struct ath6kl *ar = ath6kl_priv(netdev);
1411         if (test_bit(CONNECTED, &ar->flag))
1412                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
1413         return 0;
1414 }
1415
1416 #ifdef CONFIG_PM
1417 static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1418                                  struct cfg80211_wowlan *wow)
1419 {
1420         struct ath6kl *ar = wiphy_priv(wiphy);
1421
1422         return ath6kl_hif_suspend(ar);
1423 }
1424 #endif
1425
1426 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1427                               struct ieee80211_channel *chan,
1428                               enum nl80211_channel_type channel_type)
1429 {
1430         struct ath6kl *ar = ath6kl_priv(dev);
1431
1432         if (!ath6kl_cfg80211_ready(ar))
1433                 return -EIO;
1434
1435         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1436                    __func__, chan->center_freq, chan->hw_value);
1437         ar->next_chan = chan->center_freq;
1438
1439         return 0;
1440 }
1441
1442 static bool ath6kl_is_p2p_ie(const u8 *pos)
1443 {
1444         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1445                 pos[2] == 0x50 && pos[3] == 0x6f &&
1446                 pos[4] == 0x9a && pos[5] == 0x09;
1447 }
1448
1449 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1450                                         size_t ies_len)
1451 {
1452         const u8 *pos;
1453         u8 *buf = NULL;
1454         size_t len = 0;
1455         int ret;
1456
1457         /*
1458          * Filter out P2P IE(s) since they will be included depending on
1459          * the Probe Request frame in ath6kl_send_go_probe_resp().
1460          */
1461
1462         if (ies && ies_len) {
1463                 buf = kmalloc(ies_len, GFP_KERNEL);
1464                 if (buf == NULL)
1465                         return -ENOMEM;
1466                 pos = ies;
1467                 while (pos + 1 < ies + ies_len) {
1468                         if (pos + 2 + pos[1] > ies + ies_len)
1469                                 break;
1470                         if (!ath6kl_is_p2p_ie(pos)) {
1471                                 memcpy(buf + len, pos, 2 + pos[1]);
1472                                 len += 2 + pos[1];
1473                         }
1474                         pos += 2 + pos[1];
1475                 }
1476         }
1477
1478         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1479                                        buf, len);
1480         kfree(buf);
1481         return ret;
1482 }
1483
1484 static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1485                             struct beacon_parameters *info, bool add)
1486 {
1487         struct ath6kl *ar = ath6kl_priv(dev);
1488         struct ieee80211_mgmt *mgmt;
1489         u8 *ies;
1490         int ies_len;
1491         struct wmi_connect_cmd p;
1492         int res;
1493         int i;
1494
1495         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1496
1497         if (!ath6kl_cfg80211_ready(ar))
1498                 return -EIO;
1499
1500         if (ar->next_mode != AP_NETWORK)
1501                 return -EOPNOTSUPP;
1502
1503         if (info->beacon_ies) {
1504                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1505                                                info->beacon_ies,
1506                                                info->beacon_ies_len);
1507                 if (res)
1508                         return res;
1509         }
1510         if (info->proberesp_ies) {
1511                 res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1512                                                    info->proberesp_ies_len);
1513                 if (res)
1514                         return res;
1515         }
1516         if (info->assocresp_ies) {
1517                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1518                                                info->assocresp_ies,
1519                                                info->assocresp_ies_len);
1520                 if (res)
1521                         return res;
1522         }
1523
1524         if (!add)
1525                 return 0;
1526
1527         ar->ap_mode_bkey.valid = false;
1528
1529         /* TODO:
1530          * info->interval
1531          * info->dtim_period
1532          */
1533
1534         if (info->head == NULL)
1535                 return -EINVAL;
1536         mgmt = (struct ieee80211_mgmt *) info->head;
1537         ies = mgmt->u.beacon.variable;
1538         if (ies > info->head + info->head_len)
1539                 return -EINVAL;
1540         ies_len = info->head + info->head_len - ies;
1541
1542         if (info->ssid == NULL)
1543                 return -EINVAL;
1544         memcpy(ar->ssid, info->ssid, info->ssid_len);
1545         ar->ssid_len = info->ssid_len;
1546         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1547                 return -EOPNOTSUPP; /* TODO */
1548
1549         ar->dot11_auth_mode = OPEN_AUTH;
1550
1551         memset(&p, 0, sizeof(p));
1552
1553         for (i = 0; i < info->crypto.n_akm_suites; i++) {
1554                 switch (info->crypto.akm_suites[i]) {
1555                 case WLAN_AKM_SUITE_8021X:
1556                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1557                                 p.auth_mode |= WPA_AUTH;
1558                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1559                                 p.auth_mode |= WPA2_AUTH;
1560                         break;
1561                 case WLAN_AKM_SUITE_PSK:
1562                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1563                                 p.auth_mode |= WPA_PSK_AUTH;
1564                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1565                                 p.auth_mode |= WPA2_PSK_AUTH;
1566                         break;
1567                 }
1568         }
1569         if (p.auth_mode == 0)
1570                 p.auth_mode = NONE_AUTH;
1571         ar->auth_mode = p.auth_mode;
1572
1573         for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1574                 switch (info->crypto.ciphers_pairwise[i]) {
1575                 case WLAN_CIPHER_SUITE_WEP40:
1576                 case WLAN_CIPHER_SUITE_WEP104:
1577                         p.prwise_crypto_type |= WEP_CRYPT;
1578                         break;
1579                 case WLAN_CIPHER_SUITE_TKIP:
1580                         p.prwise_crypto_type |= TKIP_CRYPT;
1581                         break;
1582                 case WLAN_CIPHER_SUITE_CCMP:
1583                         p.prwise_crypto_type |= AES_CRYPT;
1584                         break;
1585                 }
1586         }
1587         if (p.prwise_crypto_type == 0) {
1588                 p.prwise_crypto_type = NONE_CRYPT;
1589                 ath6kl_set_cipher(ar, 0, true);
1590         } else if (info->crypto.n_ciphers_pairwise == 1)
1591                 ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
1592
1593         switch (info->crypto.cipher_group) {
1594         case WLAN_CIPHER_SUITE_WEP40:
1595         case WLAN_CIPHER_SUITE_WEP104:
1596                 p.grp_crypto_type = WEP_CRYPT;
1597                 break;
1598         case WLAN_CIPHER_SUITE_TKIP:
1599                 p.grp_crypto_type = TKIP_CRYPT;
1600                 break;
1601         case WLAN_CIPHER_SUITE_CCMP:
1602                 p.grp_crypto_type = AES_CRYPT;
1603                 break;
1604         default:
1605                 p.grp_crypto_type = NONE_CRYPT;
1606                 break;
1607         }
1608         ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
1609
1610         p.nw_type = AP_NETWORK;
1611         ar->nw_type = ar->next_mode;
1612
1613         p.ssid_len = ar->ssid_len;
1614         memcpy(p.ssid, ar->ssid, ar->ssid_len);
1615         p.dot11_auth_mode = ar->dot11_auth_mode;
1616         p.ch = cpu_to_le16(ar->next_chan);
1617
1618         res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1619         if (res < 0)
1620                 return res;
1621
1622         return 0;
1623 }
1624
1625 static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1626                              struct beacon_parameters *info)
1627 {
1628         return ath6kl_ap_beacon(wiphy, dev, info, true);
1629 }
1630
1631 static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1632                              struct beacon_parameters *info)
1633 {
1634         return ath6kl_ap_beacon(wiphy, dev, info, false);
1635 }
1636
1637 static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1638 {
1639         struct ath6kl *ar = ath6kl_priv(dev);
1640
1641         if (ar->nw_type != AP_NETWORK)
1642                 return -EOPNOTSUPP;
1643         if (!test_bit(CONNECTED, &ar->flag))
1644                 return -ENOTCONN;
1645
1646         ath6kl_wmi_disconnect_cmd(ar->wmi);
1647         clear_bit(CONNECTED, &ar->flag);
1648
1649         return 0;
1650 }
1651
1652 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1653                                  u8 *mac, struct station_parameters *params)
1654 {
1655         struct ath6kl *ar = ath6kl_priv(dev);
1656
1657         if (ar->nw_type != AP_NETWORK)
1658                 return -EOPNOTSUPP;
1659
1660         /* Use this only for authorizing/unauthorizing a station */
1661         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1662                 return -EOPNOTSUPP;
1663
1664         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1665                 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1666                                               mac, 0);
1667         return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1668                                       0);
1669 }
1670
1671 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1672                                     struct net_device *dev,
1673                                     struct ieee80211_channel *chan,
1674                                     enum nl80211_channel_type channel_type,
1675                                     unsigned int duration,
1676                                     u64 *cookie)
1677 {
1678         struct ath6kl *ar = ath6kl_priv(dev);
1679
1680         /* TODO: if already pending or ongoing remain-on-channel,
1681          * return -EBUSY */
1682         *cookie = 1; /* only a single pending request is supported */
1683
1684         return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1685                                              duration);
1686 }
1687
1688 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1689                                            struct net_device *dev,
1690                                            u64 cookie)
1691 {
1692         struct ath6kl *ar = ath6kl_priv(dev);
1693
1694         if (cookie != 1)
1695                 return -ENOENT;
1696
1697         return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1698 }
1699
1700 static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1701                                      size_t len, unsigned int freq)
1702 {
1703         const u8 *pos;
1704         u8 *p2p;
1705         int p2p_len;
1706         int ret;
1707         const struct ieee80211_mgmt *mgmt;
1708
1709         mgmt = (const struct ieee80211_mgmt *) buf;
1710
1711         /* Include P2P IE(s) from the frame generated in user space. */
1712
1713         p2p = kmalloc(len, GFP_KERNEL);
1714         if (p2p == NULL)
1715                 return -ENOMEM;
1716         p2p_len = 0;
1717
1718         pos = mgmt->u.probe_resp.variable;
1719         while (pos + 1 < buf + len) {
1720                 if (pos + 2 + pos[1] > buf + len)
1721                         break;
1722                 if (ath6kl_is_p2p_ie(pos)) {
1723                         memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1724                         p2p_len += 2 + pos[1];
1725                 }
1726                 pos += 2 + pos[1];
1727         }
1728
1729         ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1730                                                  p2p, p2p_len);
1731         kfree(p2p);
1732         return ret;
1733 }
1734
1735 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1736                           struct ieee80211_channel *chan, bool offchan,
1737                           enum nl80211_channel_type channel_type,
1738                           bool channel_type_valid, unsigned int wait,
1739                           const u8 *buf, size_t len, bool no_cck,
1740                           bool dont_wait_for_ack, u64 *cookie)
1741 {
1742         struct ath6kl *ar = ath6kl_priv(dev);
1743         u32 id;
1744         const struct ieee80211_mgmt *mgmt;
1745
1746         mgmt = (const struct ieee80211_mgmt *) buf;
1747         if (buf + len >= mgmt->u.probe_resp.variable &&
1748             ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
1749             ieee80211_is_probe_resp(mgmt->frame_control)) {
1750                 /*
1751                  * Send Probe Response frame in AP mode using a separate WMI
1752                  * command to allow the target to fill in the generic IEs.
1753                  */
1754                 *cookie = 0; /* TX status not supported */
1755                 return ath6kl_send_go_probe_resp(ar, buf, len,
1756                                                  chan->center_freq);
1757         }
1758
1759         id = ar->send_action_id++;
1760         if (id == 0) {
1761                 /*
1762                  * 0 is a reserved value in the WMI command and shall not be
1763                  * used for the command.
1764                  */
1765                 id = ar->send_action_id++;
1766         }
1767
1768         *cookie = id;
1769         return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1770                                           buf, len);
1771 }
1772
1773 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1774                                        struct net_device *dev,
1775                                        u16 frame_type, bool reg)
1776 {
1777         struct ath6kl *ar = ath6kl_priv(dev);
1778
1779         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1780                    __func__, frame_type, reg);
1781         if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1782                 /*
1783                  * Note: This notification callback is not allowed to sleep, so
1784                  * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1785                  * hardcode target to report Probe Request frames all the time.
1786                  */
1787                 ar->probe_req_report = reg;
1788         }
1789 }
1790
1791 static const struct ieee80211_txrx_stypes
1792 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1793         [NL80211_IFTYPE_STATION] = {
1794                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1795                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1796                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1797                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1798         },
1799         [NL80211_IFTYPE_P2P_CLIENT] = {
1800                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1801                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1802                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1803                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1804         },
1805         [NL80211_IFTYPE_P2P_GO] = {
1806                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1807                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1808                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1809                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1810         },
1811 };
1812
1813 static struct cfg80211_ops ath6kl_cfg80211_ops = {
1814         .change_virtual_intf = ath6kl_cfg80211_change_iface,
1815         .scan = ath6kl_cfg80211_scan,
1816         .connect = ath6kl_cfg80211_connect,
1817         .disconnect = ath6kl_cfg80211_disconnect,
1818         .add_key = ath6kl_cfg80211_add_key,
1819         .get_key = ath6kl_cfg80211_get_key,
1820         .del_key = ath6kl_cfg80211_del_key,
1821         .set_default_key = ath6kl_cfg80211_set_default_key,
1822         .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1823         .set_tx_power = ath6kl_cfg80211_set_txpower,
1824         .get_tx_power = ath6kl_cfg80211_get_txpower,
1825         .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1826         .join_ibss = ath6kl_cfg80211_join_ibss,
1827         .leave_ibss = ath6kl_cfg80211_leave_ibss,
1828         .get_station = ath6kl_get_station,
1829         .set_pmksa = ath6kl_set_pmksa,
1830         .del_pmksa = ath6kl_del_pmksa,
1831         .flush_pmksa = ath6kl_flush_pmksa,
1832         CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
1833 #ifdef CONFIG_PM
1834         .suspend = ar6k_cfg80211_suspend,
1835 #endif
1836         .set_channel = ath6kl_set_channel,
1837         .add_beacon = ath6kl_add_beacon,
1838         .set_beacon = ath6kl_set_beacon,
1839         .del_beacon = ath6kl_del_beacon,
1840         .change_station = ath6kl_change_station,
1841         .remain_on_channel = ath6kl_remain_on_channel,
1842         .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
1843         .mgmt_tx = ath6kl_mgmt_tx,
1844         .mgmt_frame_register = ath6kl_mgmt_frame_register,
1845 };
1846
1847 struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1848 {
1849         int ret = 0;
1850         struct wireless_dev *wdev;
1851         struct ath6kl *ar;
1852
1853         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1854         if (!wdev) {
1855                 ath6kl_err("couldn't allocate wireless device\n");
1856                 return NULL;
1857         }
1858
1859         /* create a new wiphy for use with cfg80211 */
1860         wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
1861         if (!wdev->wiphy) {
1862                 ath6kl_err("couldn't allocate wiphy device\n");
1863                 kfree(wdev);
1864                 return NULL;
1865         }
1866
1867         ar = wiphy_priv(wdev->wiphy);
1868         ar->p2p = !!ath6kl_p2p;
1869
1870         wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
1871
1872         wdev->wiphy->max_remain_on_channel_duration = 5000;
1873
1874         /* set device pointer for wiphy */
1875         set_wiphy_dev(wdev->wiphy, dev);
1876
1877         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1878                 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
1879         if (ar->p2p) {
1880                 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
1881                         BIT(NL80211_IFTYPE_P2P_CLIENT);
1882         }
1883         /* max num of ssids that can be probed during scanning */
1884         wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1885         wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
1886         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1887         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1888         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1889
1890         wdev->wiphy->cipher_suites = cipher_suites;
1891         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1892
1893         ret = wiphy_register(wdev->wiphy);
1894         if (ret < 0) {
1895                 ath6kl_err("couldn't register wiphy device\n");
1896                 wiphy_free(wdev->wiphy);
1897                 kfree(wdev);
1898                 return NULL;
1899         }
1900
1901         return wdev;
1902 }
1903
1904 void ath6kl_cfg80211_deinit(struct ath6kl *ar)
1905 {
1906         struct wireless_dev *wdev = ar->wdev;
1907
1908         if (ar->scan_req) {
1909                 cfg80211_scan_done(ar->scan_req, true);
1910                 ar->scan_req = NULL;
1911         }
1912
1913         if (!wdev)
1914                 return;
1915
1916         wiphy_unregister(wdev->wiphy);
1917         wiphy_free(wdev->wiphy);
1918         kfree(wdev);
1919 }