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