3aff36bad5d3a64194d08c312701ad26ae9a430d
[pandora-kernel.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
643         if (!ath6kl_cfg80211_ready(ar))
644                 return -EIO;
645
646         if (!ar->usr_bss_filter) {
647                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &ar->flag);
648                 ret = ath6kl_wmi_bssfilter_cmd(
649                         ar->wmi,
650                         (test_bit(CONNECTED, &ar->flag) ?
651                          ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
652                 if (ret) {
653                         ath6kl_err("couldn't set bss filtering\n");
654                         return ret;
655                 }
656         }
657
658         if (request->n_ssids && request->ssids[0].ssid_len) {
659                 u8 i;
660
661                 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
662                         request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
663
664                 for (i = 0; i < request->n_ssids; i++)
665                         ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
666                                                   SPECIFIC_SSID_FLAG,
667                                                   request->ssids[i].ssid_len,
668                                                   request->ssids[i].ssid);
669         }
670
671         if (request->ie) {
672                 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
673                                                request->ie, request->ie_len);
674                 if (ret) {
675                         ath6kl_err("failed to set Probe Request appie for "
676                                    "scan");
677                         return ret;
678                 }
679         }
680
681         /*
682          * Scan only the requested channels if the request specifies a set of
683          * channels. If the list is longer than the target supports, do not
684          * configure the list and instead, scan all available channels.
685          */
686         if (request->n_channels > 0 &&
687             request->n_channels <= WMI_MAX_CHANNELS) {
688                 u8 i;
689
690                 n_channels = request->n_channels;
691
692                 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
693                 if (channels == NULL) {
694                         ath6kl_warn("failed to set scan channels, "
695                                     "scan all channels");
696                         n_channels = 0;
697                 }
698
699                 for (i = 0; i < n_channels; i++)
700                         channels[i] = request->channels[i]->center_freq;
701         }
702
703         ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
704                                        false, 0, 0, n_channels, channels);
705         if (ret)
706                 ath6kl_err("wmi_startscan_cmd failed\n");
707         else
708                 ar->scan_req = request;
709
710         kfree(channels);
711
712         return ret;
713 }
714
715 void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
716 {
717         int i;
718
719         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
720
721         if (!ar->scan_req)
722                 return;
723
724         if ((status == -ECANCELED) || (status == -EBUSY)) {
725                 cfg80211_scan_done(ar->scan_req, true);
726                 goto out;
727         }
728
729         cfg80211_scan_done(ar->scan_req, false);
730
731         if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
732                 for (i = 0; i < ar->scan_req->n_ssids; i++) {
733                         ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
734                                                   DISABLE_SSID_FLAG,
735                                                   0, NULL);
736                 }
737         }
738
739 out:
740         ar->scan_req = NULL;
741 }
742
743 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
744                                    u8 key_index, bool pairwise,
745                                    const u8 *mac_addr,
746                                    struct key_params *params)
747 {
748         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
749         struct ath6kl_key *key = NULL;
750         u8 key_usage;
751         u8 key_type;
752         int status = 0;
753
754         if (!ath6kl_cfg80211_ready(ar))
755                 return -EIO;
756
757         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
758                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
759                            "%s: key index %d out of bounds\n", __func__,
760                            key_index);
761                 return -ENOENT;
762         }
763
764         key = &ar->keys[key_index];
765         memset(key, 0, sizeof(struct ath6kl_key));
766
767         if (pairwise)
768                 key_usage = PAIRWISE_USAGE;
769         else
770                 key_usage = GROUP_USAGE;
771
772         if (params) {
773                 if (params->key_len > WLAN_MAX_KEY_LEN ||
774                     params->seq_len > sizeof(key->seq))
775                         return -EINVAL;
776
777                 key->key_len = params->key_len;
778                 memcpy(key->key, params->key, key->key_len);
779                 key->seq_len = params->seq_len;
780                 memcpy(key->seq, params->seq, key->seq_len);
781                 key->cipher = params->cipher;
782         }
783
784         switch (key->cipher) {
785         case WLAN_CIPHER_SUITE_WEP40:
786         case WLAN_CIPHER_SUITE_WEP104:
787                 key_type = WEP_CRYPT;
788                 break;
789
790         case WLAN_CIPHER_SUITE_TKIP:
791                 key_type = TKIP_CRYPT;
792                 break;
793
794         case WLAN_CIPHER_SUITE_CCMP:
795                 key_type = AES_CRYPT;
796                 break;
797
798         default:
799                 return -ENOTSUPP;
800         }
801
802         if (((ar->auth_mode == WPA_PSK_AUTH)
803              || (ar->auth_mode == WPA2_PSK_AUTH))
804             && (key_usage & GROUP_USAGE))
805                 del_timer(&ar->disconnect_timer);
806
807         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
808                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
809                    __func__, key_index, key->key_len, key_type,
810                    key_usage, key->seq_len);
811
812         ar->def_txkey_index = key_index;
813
814         if (ar->nw_type == AP_NETWORK && !pairwise &&
815             (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
816                 ar->ap_mode_bkey.valid = true;
817                 ar->ap_mode_bkey.key_index = key_index;
818                 ar->ap_mode_bkey.key_type = key_type;
819                 ar->ap_mode_bkey.key_len = key->key_len;
820                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
821                 if (!test_bit(CONNECTED, &ar->flag)) {
822                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
823                                    "key configuration until AP mode has been "
824                                    "started\n");
825                         /*
826                          * The key will be set in ath6kl_connect_ap_mode() once
827                          * the connected event is received from the target.
828                          */
829                         return 0;
830                 }
831         }
832
833         if (ar->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
834             !test_bit(CONNECTED, &ar->flag)) {
835                 /*
836                  * Store the key locally so that it can be re-configured after
837                  * the AP mode has properly started
838                  * (ath6kl_install_statioc_wep_keys).
839                  */
840                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
841                            "until AP mode has been started\n");
842                 ar->wep_key_list[key_index].key_len = key->key_len;
843                 memcpy(ar->wep_key_list[key_index].key, key->key, key->key_len);
844                 return 0;
845         }
846
847         status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
848                                        key_type, key_usage, key->key_len,
849                                        key->seq, key->key, KEY_OP_INIT_VAL,
850                                        (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
851
852         if (status)
853                 return -EIO;
854
855         return 0;
856 }
857
858 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
859                                    u8 key_index, bool pairwise,
860                                    const u8 *mac_addr)
861 {
862         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
863
864         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
865
866         if (!ath6kl_cfg80211_ready(ar))
867                 return -EIO;
868
869         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
870                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
871                            "%s: key index %d out of bounds\n", __func__,
872                            key_index);
873                 return -ENOENT;
874         }
875
876         if (!ar->keys[key_index].key_len) {
877                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
878                            "%s: index %d is empty\n", __func__, key_index);
879                 return 0;
880         }
881
882         ar->keys[key_index].key_len = 0;
883
884         return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
885 }
886
887 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
888                                    u8 key_index, bool pairwise,
889                                    const u8 *mac_addr, void *cookie,
890                                    void (*callback) (void *cookie,
891                                                      struct key_params *))
892 {
893         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
894         struct ath6kl_key *key = NULL;
895         struct key_params params;
896
897         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
898
899         if (!ath6kl_cfg80211_ready(ar))
900                 return -EIO;
901
902         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
903                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
904                            "%s: key index %d out of bounds\n", __func__,
905                            key_index);
906                 return -ENOENT;
907         }
908
909         key = &ar->keys[key_index];
910         memset(&params, 0, sizeof(params));
911         params.cipher = key->cipher;
912         params.key_len = key->key_len;
913         params.seq_len = key->seq_len;
914         params.seq = key->seq;
915         params.key = key->key;
916
917         callback(cookie, &params);
918
919         return key->key_len ? 0 : -ENOENT;
920 }
921
922 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
923                                            struct net_device *ndev,
924                                            u8 key_index, bool unicast,
925                                            bool multicast)
926 {
927         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
928         struct ath6kl_key *key = NULL;
929         int status = 0;
930         u8 key_usage;
931         enum crypto_type key_type = NONE_CRYPT;
932
933         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
934
935         if (!ath6kl_cfg80211_ready(ar))
936                 return -EIO;
937
938         if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
939                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
940                            "%s: key index %d out of bounds\n",
941                            __func__, key_index);
942                 return -ENOENT;
943         }
944
945         if (!ar->keys[key_index].key_len) {
946                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
947                            __func__, key_index);
948                 return -EINVAL;
949         }
950
951         ar->def_txkey_index = key_index;
952         key = &ar->keys[ar->def_txkey_index];
953         key_usage = GROUP_USAGE;
954         if (ar->prwise_crypto == WEP_CRYPT)
955                 key_usage |= TX_USAGE;
956         if (unicast)
957                 key_type = ar->prwise_crypto;
958         if (multicast)
959                 key_type = ar->grp_crypto;
960
961         if (ar->next_mode == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
962                 return 0; /* Delay until AP mode has been started */
963
964         status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
965                                        key_type, key_usage,
966                                        key->key_len, key->seq, key->key,
967                                        KEY_OP_INIT_VAL, NULL,
968                                        SYNC_BOTH_WMIFLAG);
969         if (status)
970                 return -EIO;
971
972         return 0;
973 }
974
975 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
976                                        bool ismcast)
977 {
978         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
979                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
980
981         cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
982                                      (ismcast ? NL80211_KEYTYPE_GROUP :
983                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
984                                      GFP_KERNEL);
985 }
986
987 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
988 {
989         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
990         int ret;
991
992         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
993                    changed);
994
995         if (!ath6kl_cfg80211_ready(ar))
996                 return -EIO;
997
998         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
999                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1000                 if (ret != 0) {
1001                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1002                         return -EIO;
1003                 }
1004         }
1005
1006         return 0;
1007 }
1008
1009 /*
1010  * The type nl80211_tx_power_setting replaces the following
1011  * data type from 2.6.36 onwards
1012 */
1013 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1014                                        enum nl80211_tx_power_setting type,
1015                                        int dbm)
1016 {
1017         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1018         u8 ath6kl_dbm;
1019
1020         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1021                    type, dbm);
1022
1023         if (!ath6kl_cfg80211_ready(ar))
1024                 return -EIO;
1025
1026         switch (type) {
1027         case NL80211_TX_POWER_AUTOMATIC:
1028                 return 0;
1029         case NL80211_TX_POWER_LIMITED:
1030                 ar->tx_pwr = ath6kl_dbm = dbm;
1031                 break;
1032         default:
1033                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1034                            __func__, type);
1035                 return -EOPNOTSUPP;
1036         }
1037
1038         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1039
1040         return 0;
1041 }
1042
1043 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1044 {
1045         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1046
1047         if (!ath6kl_cfg80211_ready(ar))
1048                 return -EIO;
1049
1050         if (test_bit(CONNECTED, &ar->flag)) {
1051                 ar->tx_pwr = 0;
1052
1053                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1054                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1055                         return -EIO;
1056                 }
1057
1058                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1059                                                  5 * HZ);
1060
1061                 if (signal_pending(current)) {
1062                         ath6kl_err("target did not respond\n");
1063                         return -EINTR;
1064                 }
1065         }
1066
1067         *dbm = ar->tx_pwr;
1068         return 0;
1069 }
1070
1071 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1072                                           struct net_device *dev,
1073                                           bool pmgmt, int timeout)
1074 {
1075         struct ath6kl *ar = ath6kl_priv(dev);
1076         struct wmi_power_mode_cmd mode;
1077
1078         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1079                    __func__, pmgmt, timeout);
1080
1081         if (!ath6kl_cfg80211_ready(ar))
1082                 return -EIO;
1083
1084         if (pmgmt) {
1085                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1086                 mode.pwr_mode = REC_POWER;
1087         } else {
1088                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1089                 mode.pwr_mode = MAX_PERF_POWER;
1090         }
1091
1092         if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1093                 ath6kl_err("wmi_powermode_cmd failed\n");
1094                 return -EIO;
1095         }
1096
1097         return 0;
1098 }
1099
1100 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1101                                         struct net_device *ndev,
1102                                         enum nl80211_iftype type, u32 *flags,
1103                                         struct vif_params *params)
1104 {
1105         struct ath6kl *ar = ath6kl_priv(ndev);
1106         struct wireless_dev *wdev = ar->wdev;
1107
1108         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1109
1110         if (!ath6kl_cfg80211_ready(ar))
1111                 return -EIO;
1112
1113         switch (type) {
1114         case NL80211_IFTYPE_STATION:
1115                 ar->next_mode = INFRA_NETWORK;
1116                 break;
1117         case NL80211_IFTYPE_ADHOC:
1118                 ar->next_mode = ADHOC_NETWORK;
1119                 break;
1120         case NL80211_IFTYPE_AP:
1121                 ar->next_mode = AP_NETWORK;
1122                 break;
1123         case NL80211_IFTYPE_P2P_CLIENT:
1124                 ar->next_mode = INFRA_NETWORK;
1125                 break;
1126         case NL80211_IFTYPE_P2P_GO:
1127                 ar->next_mode = AP_NETWORK;
1128                 break;
1129         default:
1130                 ath6kl_err("invalid interface type %u\n", type);
1131                 return -EOPNOTSUPP;
1132         }
1133
1134         wdev->iftype = type;
1135
1136         return 0;
1137 }
1138
1139 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1140                                      struct net_device *dev,
1141                                      struct cfg80211_ibss_params *ibss_param)
1142 {
1143         struct ath6kl *ar = ath6kl_priv(dev);
1144         int status;
1145
1146         if (!ath6kl_cfg80211_ready(ar))
1147                 return -EIO;
1148
1149         ar->ssid_len = ibss_param->ssid_len;
1150         memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
1151
1152         if (ibss_param->channel)
1153                 ar->ch_hint = ibss_param->channel->center_freq;
1154
1155         if (ibss_param->channel_fixed) {
1156                 /*
1157                  * TODO: channel_fixed: The channel should be fixed, do not
1158                  * search for IBSSs to join on other channels. Target
1159                  * firmware does not support this feature, needs to be
1160                  * updated.
1161                  */
1162                 return -EOPNOTSUPP;
1163         }
1164
1165         memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
1166         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1167                 memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
1168
1169         ath6kl_set_wpa_version(ar, 0);
1170
1171         status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1172         if (status)
1173                 return status;
1174
1175         if (ibss_param->privacy) {
1176                 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1177                 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1178         } else {
1179                 ath6kl_set_cipher(ar, 0, true);
1180                 ath6kl_set_cipher(ar, 0, false);
1181         }
1182
1183         ar->nw_type = ar->next_mode;
1184
1185         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1186                    "%s: connect called with authmode %d dot11 auth %d"
1187                    " PW crypto %d PW crypto len %d GRP crypto %d"
1188                    " GRP crypto len %d channel hint %u\n",
1189                    __func__,
1190                    ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1191                    ar->prwise_crypto_len, ar->grp_crypto,
1192                    ar->grp_crypto_len, ar->ch_hint);
1193
1194         status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1195                                         ar->dot11_auth_mode, ar->auth_mode,
1196                                         ar->prwise_crypto,
1197                                         ar->prwise_crypto_len,
1198                                         ar->grp_crypto, ar->grp_crypto_len,
1199                                         ar->ssid_len, ar->ssid,
1200                                         ar->req_bssid, ar->ch_hint,
1201                                         ar->connect_ctrl_flags);
1202         set_bit(CONNECT_PEND, &ar->flag);
1203
1204         return 0;
1205 }
1206
1207 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1208                                       struct net_device *dev)
1209 {
1210         struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
1211
1212         if (!ath6kl_cfg80211_ready(ar))
1213                 return -EIO;
1214
1215         ath6kl_disconnect(ar);
1216         memset(ar->ssid, 0, sizeof(ar->ssid));
1217         ar->ssid_len = 0;
1218
1219         return 0;
1220 }
1221
1222 static const u32 cipher_suites[] = {
1223         WLAN_CIPHER_SUITE_WEP40,
1224         WLAN_CIPHER_SUITE_WEP104,
1225         WLAN_CIPHER_SUITE_TKIP,
1226         WLAN_CIPHER_SUITE_CCMP,
1227 };
1228
1229 static bool is_rate_legacy(s32 rate)
1230 {
1231         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1232                 6000, 9000, 12000, 18000, 24000,
1233                 36000, 48000, 54000
1234         };
1235         u8 i;
1236
1237         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1238                 if (rate == legacy[i])
1239                         return true;
1240
1241         return false;
1242 }
1243
1244 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1245 {
1246         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1247                 52000, 58500, 65000, 72200
1248         };
1249         u8 i;
1250
1251         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1252                 if (rate == ht20[i]) {
1253                         if (i == ARRAY_SIZE(ht20) - 1)
1254                                 /* last rate uses sgi */
1255                                 *sgi = true;
1256                         else
1257                                 *sgi = false;
1258
1259                         *mcs = i;
1260                         return true;
1261                 }
1262         }
1263         return false;
1264 }
1265
1266 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1267 {
1268         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1269                 81000, 108000, 121500, 135000,
1270                 150000
1271         };
1272         u8 i;
1273
1274         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1275                 if (rate == ht40[i]) {
1276                         if (i == ARRAY_SIZE(ht40) - 1)
1277                                 /* last rate uses sgi */
1278                                 *sgi = true;
1279                         else
1280                                 *sgi = false;
1281
1282                         *mcs = i;
1283                         return true;
1284                 }
1285         }
1286
1287         return false;
1288 }
1289
1290 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1291                               u8 *mac, struct station_info *sinfo)
1292 {
1293         struct ath6kl *ar = ath6kl_priv(dev);
1294         long left;
1295         bool sgi;
1296         s32 rate;
1297         int ret;
1298         u8 mcs;
1299
1300         if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
1301                 return -ENOENT;
1302
1303         if (down_interruptible(&ar->sem))
1304                 return -EBUSY;
1305
1306         set_bit(STATS_UPDATE_PEND, &ar->flag);
1307
1308         ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1309
1310         if (ret != 0) {
1311                 up(&ar->sem);
1312                 return -EIO;
1313         }
1314
1315         left = wait_event_interruptible_timeout(ar->event_wq,
1316                                                 !test_bit(STATS_UPDATE_PEND,
1317                                                           &ar->flag),
1318                                                 WMI_TIMEOUT);
1319
1320         up(&ar->sem);
1321
1322         if (left == 0)
1323                 return -ETIMEDOUT;
1324         else if (left < 0)
1325                 return left;
1326
1327         if (ar->target_stats.rx_byte) {
1328                 sinfo->rx_bytes = ar->target_stats.rx_byte;
1329                 sinfo->filled |= STATION_INFO_RX_BYTES;
1330                 sinfo->rx_packets = ar->target_stats.rx_pkt;
1331                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1332         }
1333
1334         if (ar->target_stats.tx_byte) {
1335                 sinfo->tx_bytes = ar->target_stats.tx_byte;
1336                 sinfo->filled |= STATION_INFO_TX_BYTES;
1337                 sinfo->tx_packets = ar->target_stats.tx_pkt;
1338                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1339         }
1340
1341         sinfo->signal = ar->target_stats.cs_rssi;
1342         sinfo->filled |= STATION_INFO_SIGNAL;
1343
1344         rate = ar->target_stats.tx_ucast_rate;
1345
1346         if (is_rate_legacy(rate)) {
1347                 sinfo->txrate.legacy = rate / 100;
1348         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1349                 if (sgi) {
1350                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1351                         sinfo->txrate.mcs = mcs - 1;
1352                 } else {
1353                         sinfo->txrate.mcs = mcs;
1354                 }
1355
1356                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1357         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1358                 if (sgi) {
1359                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1360                         sinfo->txrate.mcs = mcs - 1;
1361                 } else {
1362                         sinfo->txrate.mcs = mcs;
1363                 }
1364
1365                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1366                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1367         } else {
1368                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1369                            "invalid rate from stats: %d\n", rate);
1370                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1371                 return 0;
1372         }
1373
1374         sinfo->filled |= STATION_INFO_TX_BITRATE;
1375
1376         if (test_bit(CONNECTED, &ar->flag) &&
1377             test_bit(DTIM_PERIOD_AVAIL, &ar->flag) &&
1378             ar->nw_type == INFRA_NETWORK) {
1379                 sinfo->filled |= STATION_INFO_BSS_PARAM;
1380                 sinfo->bss_param.flags = 0;
1381                 sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
1382                 sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
1383         }
1384
1385         return 0;
1386 }
1387
1388 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1389                             struct cfg80211_pmksa *pmksa)
1390 {
1391         struct ath6kl *ar = ath6kl_priv(netdev);
1392         return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1393                                        pmksa->pmkid, true);
1394 }
1395
1396 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1397                             struct cfg80211_pmksa *pmksa)
1398 {
1399         struct ath6kl *ar = ath6kl_priv(netdev);
1400         return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1401                                        pmksa->pmkid, false);
1402 }
1403
1404 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1405 {
1406         struct ath6kl *ar = ath6kl_priv(netdev);
1407         if (test_bit(CONNECTED, &ar->flag))
1408                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
1409         return 0;
1410 }
1411
1412 #ifdef CONFIG_PM
1413 static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1414                                  struct cfg80211_wowlan *wow)
1415 {
1416         struct ath6kl *ar = wiphy_priv(wiphy);
1417
1418         return ath6kl_hif_suspend(ar);
1419 }
1420 #endif
1421
1422 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1423                               struct ieee80211_channel *chan,
1424                               enum nl80211_channel_type channel_type)
1425 {
1426         struct ath6kl *ar = ath6kl_priv(dev);
1427
1428         if (!ath6kl_cfg80211_ready(ar))
1429                 return -EIO;
1430
1431         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1432                    __func__, chan->center_freq, chan->hw_value);
1433         ar->next_chan = chan->center_freq;
1434
1435         return 0;
1436 }
1437
1438 static bool ath6kl_is_p2p_ie(const u8 *pos)
1439 {
1440         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1441                 pos[2] == 0x50 && pos[3] == 0x6f &&
1442                 pos[4] == 0x9a && pos[5] == 0x09;
1443 }
1444
1445 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1446                                         size_t ies_len)
1447 {
1448         const u8 *pos;
1449         u8 *buf = NULL;
1450         size_t len = 0;
1451         int ret;
1452
1453         /*
1454          * Filter out P2P IE(s) since they will be included depending on
1455          * the Probe Request frame in ath6kl_send_go_probe_resp().
1456          */
1457
1458         if (ies && ies_len) {
1459                 buf = kmalloc(ies_len, GFP_KERNEL);
1460                 if (buf == NULL)
1461                         return -ENOMEM;
1462                 pos = ies;
1463                 while (pos + 1 < ies + ies_len) {
1464                         if (pos + 2 + pos[1] > ies + ies_len)
1465                                 break;
1466                         if (!ath6kl_is_p2p_ie(pos)) {
1467                                 memcpy(buf + len, pos, 2 + pos[1]);
1468                                 len += 2 + pos[1];
1469                         }
1470                         pos += 2 + pos[1];
1471                 }
1472         }
1473
1474         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1475                                        buf, len);
1476         kfree(buf);
1477         return ret;
1478 }
1479
1480 static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1481                             struct beacon_parameters *info, bool add)
1482 {
1483         struct ath6kl *ar = ath6kl_priv(dev);
1484         struct ieee80211_mgmt *mgmt;
1485         u8 *ies;
1486         int ies_len;
1487         struct wmi_connect_cmd p;
1488         int res;
1489         int i;
1490
1491         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1492
1493         if (!ath6kl_cfg80211_ready(ar))
1494                 return -EIO;
1495
1496         if (ar->next_mode != AP_NETWORK)
1497                 return -EOPNOTSUPP;
1498
1499         if (info->beacon_ies) {
1500                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1501                                                info->beacon_ies,
1502                                                info->beacon_ies_len);
1503                 if (res)
1504                         return res;
1505         }
1506         if (info->proberesp_ies) {
1507                 res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1508                                                    info->proberesp_ies_len);
1509                 if (res)
1510                         return res;
1511         }
1512         if (info->assocresp_ies) {
1513                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1514                                                info->assocresp_ies,
1515                                                info->assocresp_ies_len);
1516                 if (res)
1517                         return res;
1518         }
1519
1520         if (!add)
1521                 return 0;
1522
1523         ar->ap_mode_bkey.valid = false;
1524
1525         /* TODO:
1526          * info->interval
1527          * info->dtim_period
1528          */
1529
1530         if (info->head == NULL)
1531                 return -EINVAL;
1532         mgmt = (struct ieee80211_mgmt *) info->head;
1533         ies = mgmt->u.beacon.variable;
1534         if (ies > info->head + info->head_len)
1535                 return -EINVAL;
1536         ies_len = info->head + info->head_len - ies;
1537
1538         if (info->ssid == NULL)
1539                 return -EINVAL;
1540         memcpy(ar->ssid, info->ssid, info->ssid_len);
1541         ar->ssid_len = info->ssid_len;
1542         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1543                 return -EOPNOTSUPP; /* TODO */
1544
1545         ar->dot11_auth_mode = OPEN_AUTH;
1546
1547         memset(&p, 0, sizeof(p));
1548
1549         for (i = 0; i < info->crypto.n_akm_suites; i++) {
1550                 switch (info->crypto.akm_suites[i]) {
1551                 case WLAN_AKM_SUITE_8021X:
1552                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1553                                 p.auth_mode |= WPA_AUTH;
1554                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1555                                 p.auth_mode |= WPA2_AUTH;
1556                         break;
1557                 case WLAN_AKM_SUITE_PSK:
1558                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1559                                 p.auth_mode |= WPA_PSK_AUTH;
1560                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1561                                 p.auth_mode |= WPA2_PSK_AUTH;
1562                         break;
1563                 }
1564         }
1565         if (p.auth_mode == 0)
1566                 p.auth_mode = NONE_AUTH;
1567         ar->auth_mode = p.auth_mode;
1568
1569         for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1570                 switch (info->crypto.ciphers_pairwise[i]) {
1571                 case WLAN_CIPHER_SUITE_WEP40:
1572                 case WLAN_CIPHER_SUITE_WEP104:
1573                         p.prwise_crypto_type |= WEP_CRYPT;
1574                         break;
1575                 case WLAN_CIPHER_SUITE_TKIP:
1576                         p.prwise_crypto_type |= TKIP_CRYPT;
1577                         break;
1578                 case WLAN_CIPHER_SUITE_CCMP:
1579                         p.prwise_crypto_type |= AES_CRYPT;
1580                         break;
1581                 }
1582         }
1583         if (p.prwise_crypto_type == 0) {
1584                 p.prwise_crypto_type = NONE_CRYPT;
1585                 ath6kl_set_cipher(ar, 0, true);
1586         } else if (info->crypto.n_ciphers_pairwise == 1)
1587                 ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
1588
1589         switch (info->crypto.cipher_group) {
1590         case WLAN_CIPHER_SUITE_WEP40:
1591         case WLAN_CIPHER_SUITE_WEP104:
1592                 p.grp_crypto_type = WEP_CRYPT;
1593                 break;
1594         case WLAN_CIPHER_SUITE_TKIP:
1595                 p.grp_crypto_type = TKIP_CRYPT;
1596                 break;
1597         case WLAN_CIPHER_SUITE_CCMP:
1598                 p.grp_crypto_type = AES_CRYPT;
1599                 break;
1600         default:
1601                 p.grp_crypto_type = NONE_CRYPT;
1602                 break;
1603         }
1604         ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
1605
1606         p.nw_type = AP_NETWORK;
1607         ar->nw_type = ar->next_mode;
1608
1609         p.ssid_len = ar->ssid_len;
1610         memcpy(p.ssid, ar->ssid, ar->ssid_len);
1611         p.dot11_auth_mode = ar->dot11_auth_mode;
1612         p.ch = cpu_to_le16(ar->next_chan);
1613
1614         res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1615         if (res < 0)
1616                 return res;
1617
1618         return 0;
1619 }
1620
1621 static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1622                              struct beacon_parameters *info)
1623 {
1624         return ath6kl_ap_beacon(wiphy, dev, info, true);
1625 }
1626
1627 static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1628                              struct beacon_parameters *info)
1629 {
1630         return ath6kl_ap_beacon(wiphy, dev, info, false);
1631 }
1632
1633 static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1634 {
1635         struct ath6kl *ar = ath6kl_priv(dev);
1636
1637         if (ar->nw_type != AP_NETWORK)
1638                 return -EOPNOTSUPP;
1639         if (!test_bit(CONNECTED, &ar->flag))
1640                 return -ENOTCONN;
1641
1642         ath6kl_wmi_disconnect_cmd(ar->wmi);
1643         clear_bit(CONNECTED, &ar->flag);
1644
1645         return 0;
1646 }
1647
1648 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1649                                  u8 *mac, struct station_parameters *params)
1650 {
1651         struct ath6kl *ar = ath6kl_priv(dev);
1652
1653         if (ar->nw_type != AP_NETWORK)
1654                 return -EOPNOTSUPP;
1655
1656         /* Use this only for authorizing/unauthorizing a station */
1657         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1658                 return -EOPNOTSUPP;
1659
1660         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1661                 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1662                                               mac, 0);
1663         return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1664                                       0);
1665 }
1666
1667 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1668                                     struct net_device *dev,
1669                                     struct ieee80211_channel *chan,
1670                                     enum nl80211_channel_type channel_type,
1671                                     unsigned int duration,
1672                                     u64 *cookie)
1673 {
1674         struct ath6kl *ar = ath6kl_priv(dev);
1675
1676         /* TODO: if already pending or ongoing remain-on-channel,
1677          * return -EBUSY */
1678         *cookie = 1; /* only a single pending request is supported */
1679
1680         return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1681                                              duration);
1682 }
1683
1684 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1685                                            struct net_device *dev,
1686                                            u64 cookie)
1687 {
1688         struct ath6kl *ar = ath6kl_priv(dev);
1689
1690         if (cookie != 1)
1691                 return -ENOENT;
1692
1693         return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1694 }
1695
1696 static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1697                                      size_t len, unsigned int freq)
1698 {
1699         const u8 *pos;
1700         u8 *p2p;
1701         int p2p_len;
1702         int ret;
1703         const struct ieee80211_mgmt *mgmt;
1704
1705         mgmt = (const struct ieee80211_mgmt *) buf;
1706
1707         /* Include P2P IE(s) from the frame generated in user space. */
1708
1709         p2p = kmalloc(len, GFP_KERNEL);
1710         if (p2p == NULL)
1711                 return -ENOMEM;
1712         p2p_len = 0;
1713
1714         pos = mgmt->u.probe_resp.variable;
1715         while (pos + 1 < buf + len) {
1716                 if (pos + 2 + pos[1] > buf + len)
1717                         break;
1718                 if (ath6kl_is_p2p_ie(pos)) {
1719                         memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1720                         p2p_len += 2 + pos[1];
1721                 }
1722                 pos += 2 + pos[1];
1723         }
1724
1725         ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1726                                                  p2p, p2p_len);
1727         kfree(p2p);
1728         return ret;
1729 }
1730
1731 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1732                           struct ieee80211_channel *chan, bool offchan,
1733                           enum nl80211_channel_type channel_type,
1734                           bool channel_type_valid, unsigned int wait,
1735                           const u8 *buf, size_t len, bool no_cck, u64 *cookie)
1736 {
1737         struct ath6kl *ar = ath6kl_priv(dev);
1738         u32 id;
1739         const struct ieee80211_mgmt *mgmt;
1740
1741         mgmt = (const struct ieee80211_mgmt *) buf;
1742         if (buf + len >= mgmt->u.probe_resp.variable &&
1743             ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
1744             ieee80211_is_probe_resp(mgmt->frame_control)) {
1745                 /*
1746                  * Send Probe Response frame in AP mode using a separate WMI
1747                  * command to allow the target to fill in the generic IEs.
1748                  */
1749                 *cookie = 0; /* TX status not supported */
1750                 return ath6kl_send_go_probe_resp(ar, buf, len,
1751                                                  chan->center_freq);
1752         }
1753
1754         id = ar->send_action_id++;
1755         if (id == 0) {
1756                 /*
1757                  * 0 is a reserved value in the WMI command and shall not be
1758                  * used for the command.
1759                  */
1760                 id = ar->send_action_id++;
1761         }
1762
1763         *cookie = id;
1764         return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1765                                           buf, len);
1766 }
1767
1768 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1769                                        struct net_device *dev,
1770                                        u16 frame_type, bool reg)
1771 {
1772         struct ath6kl *ar = ath6kl_priv(dev);
1773
1774         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1775                    __func__, frame_type, reg);
1776         if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1777                 /*
1778                  * Note: This notification callback is not allowed to sleep, so
1779                  * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1780                  * hardcode target to report Probe Request frames all the time.
1781                  */
1782                 ar->probe_req_report = reg;
1783         }
1784 }
1785
1786 static const struct ieee80211_txrx_stypes
1787 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1788         [NL80211_IFTYPE_STATION] = {
1789                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1790                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1791                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1792                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1793         },
1794         [NL80211_IFTYPE_P2P_CLIENT] = {
1795                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1796                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1797                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1798                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1799         },
1800         [NL80211_IFTYPE_P2P_GO] = {
1801                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1802                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1803                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1804                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1805         },
1806 };
1807
1808 static struct cfg80211_ops ath6kl_cfg80211_ops = {
1809         .change_virtual_intf = ath6kl_cfg80211_change_iface,
1810         .scan = ath6kl_cfg80211_scan,
1811         .connect = ath6kl_cfg80211_connect,
1812         .disconnect = ath6kl_cfg80211_disconnect,
1813         .add_key = ath6kl_cfg80211_add_key,
1814         .get_key = ath6kl_cfg80211_get_key,
1815         .del_key = ath6kl_cfg80211_del_key,
1816         .set_default_key = ath6kl_cfg80211_set_default_key,
1817         .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1818         .set_tx_power = ath6kl_cfg80211_set_txpower,
1819         .get_tx_power = ath6kl_cfg80211_get_txpower,
1820         .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1821         .join_ibss = ath6kl_cfg80211_join_ibss,
1822         .leave_ibss = ath6kl_cfg80211_leave_ibss,
1823         .get_station = ath6kl_get_station,
1824         .set_pmksa = ath6kl_set_pmksa,
1825         .del_pmksa = ath6kl_del_pmksa,
1826         .flush_pmksa = ath6kl_flush_pmksa,
1827         CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
1828 #ifdef CONFIG_PM
1829         .suspend = ar6k_cfg80211_suspend,
1830 #endif
1831         .set_channel = ath6kl_set_channel,
1832         .add_beacon = ath6kl_add_beacon,
1833         .set_beacon = ath6kl_set_beacon,
1834         .del_beacon = ath6kl_del_beacon,
1835         .change_station = ath6kl_change_station,
1836         .remain_on_channel = ath6kl_remain_on_channel,
1837         .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
1838         .mgmt_tx = ath6kl_mgmt_tx,
1839         .mgmt_frame_register = ath6kl_mgmt_frame_register,
1840 };
1841
1842 struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1843 {
1844         int ret = 0;
1845         struct wireless_dev *wdev;
1846         struct ath6kl *ar;
1847
1848         wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1849         if (!wdev) {
1850                 ath6kl_err("couldn't allocate wireless device\n");
1851                 return NULL;
1852         }
1853
1854         /* create a new wiphy for use with cfg80211 */
1855         wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
1856         if (!wdev->wiphy) {
1857                 ath6kl_err("couldn't allocate wiphy device\n");
1858                 kfree(wdev);
1859                 return NULL;
1860         }
1861
1862         ar = wiphy_priv(wdev->wiphy);
1863         ar->p2p = !!ath6kl_p2p;
1864
1865         wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
1866
1867         wdev->wiphy->max_remain_on_channel_duration = 5000;
1868
1869         /* set device pointer for wiphy */
1870         set_wiphy_dev(wdev->wiphy, dev);
1871
1872         wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1873                 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
1874         if (ar->p2p) {
1875                 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
1876                         BIT(NL80211_IFTYPE_P2P_CLIENT);
1877         }
1878         /* max num of ssids that can be probed during scanning */
1879         wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1880         wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
1881         wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1882         wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1883         wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1884
1885         wdev->wiphy->cipher_suites = cipher_suites;
1886         wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1887
1888         ret = wiphy_register(wdev->wiphy);
1889         if (ret < 0) {
1890                 ath6kl_err("couldn't register wiphy device\n");
1891                 wiphy_free(wdev->wiphy);
1892                 kfree(wdev);
1893                 return NULL;
1894         }
1895
1896         return wdev;
1897 }
1898
1899 void ath6kl_cfg80211_deinit(struct ath6kl *ar)
1900 {
1901         struct wireless_dev *wdev = ar->wdev;
1902
1903         if (ar->scan_req) {
1904                 cfg80211_scan_done(ar->scan_req, true);
1905                 ar->scan_req = NULL;
1906         }
1907
1908         if (!wdev)
1909                 return;
1910
1911         wiphy_unregister(wdev->wiphy);
1912         wiphy_free(wdev->wiphy);
1913         kfree(wdev);
1914 }