cfg80211: restructure AP/GO mode API
[linux-block.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 #include <linux/inetdevice.h>
19 #include <linux/export.h>
20
21 #include "core.h"
22 #include "cfg80211.h"
23 #include "debug.h"
24 #include "hif-ops.h"
25 #include "testmode.h"
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 #define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
125
126 /* returns true if scheduled scan was stopped */
127 static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
128 {
129         struct ath6kl *ar = vif->ar;
130
131         if (ar->state != ATH6KL_STATE_SCHED_SCAN)
132                 return false;
133
134         del_timer_sync(&vif->sched_scan_timer);
135
136         ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
137                                            ATH6KL_HOST_MODE_AWAKE);
138
139         ar->state = ATH6KL_STATE_ON;
140
141         return true;
142 }
143
144 static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
145 {
146         struct ath6kl *ar = vif->ar;
147         bool stopped;
148
149         stopped = __ath6kl_cfg80211_sscan_stop(vif);
150
151         if (!stopped)
152                 return;
153
154         cfg80211_sched_scan_stopped(ar->wiphy);
155 }
156
157 static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
158                                   enum nl80211_wpa_versions wpa_version)
159 {
160         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
161
162         if (!wpa_version) {
163                 vif->auth_mode = NONE_AUTH;
164         } else if (wpa_version & NL80211_WPA_VERSION_2) {
165                 vif->auth_mode = WPA2_AUTH;
166         } else if (wpa_version & NL80211_WPA_VERSION_1) {
167                 vif->auth_mode = WPA_AUTH;
168         } else {
169                 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
170                 return -ENOTSUPP;
171         }
172
173         return 0;
174 }
175
176 static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
177                                 enum nl80211_auth_type auth_type)
178 {
179         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
180
181         switch (auth_type) {
182         case NL80211_AUTHTYPE_OPEN_SYSTEM:
183                 vif->dot11_auth_mode = OPEN_AUTH;
184                 break;
185         case NL80211_AUTHTYPE_SHARED_KEY:
186                 vif->dot11_auth_mode = SHARED_AUTH;
187                 break;
188         case NL80211_AUTHTYPE_NETWORK_EAP:
189                 vif->dot11_auth_mode = LEAP_AUTH;
190                 break;
191
192         case NL80211_AUTHTYPE_AUTOMATIC:
193                 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
194                 break;
195
196         default:
197                 ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
198                 return -ENOTSUPP;
199         }
200
201         return 0;
202 }
203
204 static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
205 {
206         u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
207         u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
208                 &vif->grp_crypto_len;
209
210         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
211                    __func__, cipher, ucast);
212
213         switch (cipher) {
214         case 0:
215                 /* our own hack to use value 0 as no crypto used */
216                 *ar_cipher = NONE_CRYPT;
217                 *ar_cipher_len = 0;
218                 break;
219         case WLAN_CIPHER_SUITE_WEP40:
220                 *ar_cipher = WEP_CRYPT;
221                 *ar_cipher_len = 5;
222                 break;
223         case WLAN_CIPHER_SUITE_WEP104:
224                 *ar_cipher = WEP_CRYPT;
225                 *ar_cipher_len = 13;
226                 break;
227         case WLAN_CIPHER_SUITE_TKIP:
228                 *ar_cipher = TKIP_CRYPT;
229                 *ar_cipher_len = 0;
230                 break;
231         case WLAN_CIPHER_SUITE_CCMP:
232                 *ar_cipher = AES_CRYPT;
233                 *ar_cipher_len = 0;
234                 break;
235         case WLAN_CIPHER_SUITE_SMS4:
236                 *ar_cipher = WAPI_CRYPT;
237                 *ar_cipher_len = 0;
238                 break;
239         default:
240                 ath6kl_err("cipher 0x%x not supported\n", cipher);
241                 return -ENOTSUPP;
242         }
243
244         return 0;
245 }
246
247 static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
248 {
249         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
250
251         if (key_mgmt == WLAN_AKM_SUITE_PSK) {
252                 if (vif->auth_mode == WPA_AUTH)
253                         vif->auth_mode = WPA_PSK_AUTH;
254                 else if (vif->auth_mode == WPA2_AUTH)
255                         vif->auth_mode = WPA2_PSK_AUTH;
256         } else if (key_mgmt == 0x00409600) {
257                 if (vif->auth_mode == WPA_AUTH)
258                         vif->auth_mode = WPA_AUTH_CCKM;
259                 else if (vif->auth_mode == WPA2_AUTH)
260                         vif->auth_mode = WPA2_AUTH_CCKM;
261         } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
262                 vif->auth_mode = NONE_AUTH;
263         }
264 }
265
266 static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
267 {
268         struct ath6kl *ar = vif->ar;
269
270         if (!test_bit(WMI_READY, &ar->flag)) {
271                 ath6kl_err("wmi is not ready\n");
272                 return false;
273         }
274
275         if (!test_bit(WLAN_ENABLED, &vif->flags)) {
276                 ath6kl_err("wlan disabled\n");
277                 return false;
278         }
279
280         return true;
281 }
282
283 static bool ath6kl_is_wpa_ie(const u8 *pos)
284 {
285         return pos[0] == WLAN_EID_WPA && pos[1] >= 4 &&
286                 pos[2] == 0x00 && pos[3] == 0x50 &&
287                 pos[4] == 0xf2 && pos[5] == 0x01;
288 }
289
290 static bool ath6kl_is_rsn_ie(const u8 *pos)
291 {
292         return pos[0] == WLAN_EID_RSN;
293 }
294
295 static bool ath6kl_is_wps_ie(const u8 *pos)
296 {
297         return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
298                 pos[1] >= 4 &&
299                 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
300                 pos[5] == 0x04);
301 }
302
303 static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
304                                     size_t ies_len)
305 {
306         struct ath6kl *ar = vif->ar;
307         const u8 *pos;
308         u8 *buf = NULL;
309         size_t len = 0;
310         int ret;
311
312         /*
313          * Clear previously set flag
314          */
315
316         ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
317
318         /*
319          * Filter out RSN/WPA IE(s)
320          */
321
322         if (ies && ies_len) {
323                 buf = kmalloc(ies_len, GFP_KERNEL);
324                 if (buf == NULL)
325                         return -ENOMEM;
326                 pos = ies;
327
328                 while (pos + 1 < ies + ies_len) {
329                         if (pos + 2 + pos[1] > ies + ies_len)
330                                 break;
331                         if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
332                                 memcpy(buf + len, pos, 2 + pos[1]);
333                                 len += 2 + pos[1];
334                         }
335
336                         if (ath6kl_is_wps_ie(pos))
337                                 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
338
339                         pos += 2 + pos[1];
340                 }
341         }
342
343         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
344                                        WMI_FRAME_ASSOC_REQ, buf, len);
345         kfree(buf);
346         return ret;
347 }
348
349 static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
350 {
351         switch (type) {
352         case NL80211_IFTYPE_STATION:
353                 *nw_type = INFRA_NETWORK;
354                 break;
355         case NL80211_IFTYPE_ADHOC:
356                 *nw_type = ADHOC_NETWORK;
357                 break;
358         case NL80211_IFTYPE_AP:
359                 *nw_type = AP_NETWORK;
360                 break;
361         case NL80211_IFTYPE_P2P_CLIENT:
362                 *nw_type = INFRA_NETWORK;
363                 break;
364         case NL80211_IFTYPE_P2P_GO:
365                 *nw_type = AP_NETWORK;
366                 break;
367         default:
368                 ath6kl_err("invalid interface type %u\n", type);
369                 return -ENOTSUPP;
370         }
371
372         return 0;
373 }
374
375 static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
376                                    u8 *if_idx, u8 *nw_type)
377 {
378         int i;
379
380         if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
381                 return false;
382
383         if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
384             ar->num_vif))
385                 return false;
386
387         if (type == NL80211_IFTYPE_STATION ||
388             type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
389                 for (i = 0; i < ar->vif_max; i++) {
390                         if ((ar->avail_idx_map >> i) & BIT(0)) {
391                                 *if_idx = i;
392                                 return true;
393                         }
394                 }
395         }
396
397         if (type == NL80211_IFTYPE_P2P_CLIENT ||
398             type == NL80211_IFTYPE_P2P_GO) {
399                 for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
400                         if ((ar->avail_idx_map >> i) & BIT(0)) {
401                                 *if_idx = i;
402                                 return true;
403                         }
404                 }
405         }
406
407         return false;
408 }
409
410 static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
411                                    struct cfg80211_connect_params *sme)
412 {
413         struct ath6kl *ar = ath6kl_priv(dev);
414         struct ath6kl_vif *vif = netdev_priv(dev);
415         int status;
416         u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
417
418         ath6kl_cfg80211_sscan_disable(vif);
419
420         vif->sme_state = SME_CONNECTING;
421
422         if (!ath6kl_cfg80211_ready(vif))
423                 return -EIO;
424
425         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
426                 ath6kl_err("destroy in progress\n");
427                 return -EBUSY;
428         }
429
430         if (test_bit(SKIP_SCAN, &ar->flag) &&
431             ((sme->channel && sme->channel->center_freq == 0) ||
432              (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
433                 ath6kl_err("SkipScan: channel or bssid invalid\n");
434                 return -EINVAL;
435         }
436
437         if (down_interruptible(&ar->sem)) {
438                 ath6kl_err("busy, couldn't get access\n");
439                 return -ERESTARTSYS;
440         }
441
442         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
443                 ath6kl_err("busy, destroy in progress\n");
444                 up(&ar->sem);
445                 return -EBUSY;
446         }
447
448         if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
449                 /*
450                  * sleep until the command queue drains
451                  */
452                 wait_event_interruptible_timeout(ar->event_wq,
453                         ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
454                         WMI_TIMEOUT);
455                 if (signal_pending(current)) {
456                         ath6kl_err("cmd queue drain timeout\n");
457                         up(&ar->sem);
458                         return -EINTR;
459                 }
460         }
461
462         status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
463         if (status) {
464                 up(&ar->sem);
465                 return status;
466         }
467
468         if (sme->ie == NULL || sme->ie_len == 0)
469                 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
470
471         if (test_bit(CONNECTED, &vif->flags) &&
472             vif->ssid_len == sme->ssid_len &&
473             !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
474                 vif->reconnect_flag = true;
475                 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
476                                                   vif->req_bssid,
477                                                   vif->ch_hint);
478
479                 up(&ar->sem);
480                 if (status) {
481                         ath6kl_err("wmi_reconnect_cmd failed\n");
482                         return -EIO;
483                 }
484                 return 0;
485         } else if (vif->ssid_len == sme->ssid_len &&
486                    !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
487                 ath6kl_disconnect(vif);
488         }
489
490         memset(vif->ssid, 0, sizeof(vif->ssid));
491         vif->ssid_len = sme->ssid_len;
492         memcpy(vif->ssid, sme->ssid, sme->ssid_len);
493
494         if (sme->channel)
495                 vif->ch_hint = sme->channel->center_freq;
496
497         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
498         if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
499                 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
500
501         ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
502
503         status = ath6kl_set_auth_type(vif, sme->auth_type);
504         if (status) {
505                 up(&ar->sem);
506                 return status;
507         }
508
509         if (sme->crypto.n_ciphers_pairwise)
510                 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
511         else
512                 ath6kl_set_cipher(vif, 0, true);
513
514         ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
515
516         if (sme->crypto.n_akm_suites)
517                 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
518
519         if ((sme->key_len) &&
520             (vif->auth_mode == NONE_AUTH) &&
521             (vif->prwise_crypto == WEP_CRYPT)) {
522                 struct ath6kl_key *key = NULL;
523
524                 if (sme->key_idx > WMI_MAX_KEY_INDEX) {
525                         ath6kl_err("key index %d out of bounds\n",
526                                    sme->key_idx);
527                         up(&ar->sem);
528                         return -ENOENT;
529                 }
530
531                 key = &vif->keys[sme->key_idx];
532                 key->key_len = sme->key_len;
533                 memcpy(key->key, sme->key, key->key_len);
534                 key->cipher = vif->prwise_crypto;
535                 vif->def_txkey_index = sme->key_idx;
536
537                 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
538                                       vif->prwise_crypto,
539                                       GROUP_USAGE | TX_USAGE,
540                                       key->key_len,
541                                       NULL, 0,
542                                       key->key, KEY_OP_INIT_VAL, NULL,
543                                       NO_SYNC_WMIFLAG);
544         }
545
546         if (!ar->usr_bss_filter) {
547                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
548                 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
549                     ALL_BSS_FILTER, 0) != 0) {
550                         ath6kl_err("couldn't set bss filtering\n");
551                         up(&ar->sem);
552                         return -EIO;
553                 }
554         }
555
556         vif->nw_type = vif->next_mode;
557
558         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
559                 nw_subtype = SUBTYPE_P2PCLIENT;
560
561         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
562                    "%s: connect called with authmode %d dot11 auth %d"
563                    " PW crypto %d PW crypto len %d GRP crypto %d"
564                    " GRP crypto len %d channel hint %u\n",
565                    __func__,
566                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
567                    vif->prwise_crypto_len, vif->grp_crypto,
568                    vif->grp_crypto_len, vif->ch_hint);
569
570         vif->reconnect_flag = 0;
571         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
572                                         vif->dot11_auth_mode, vif->auth_mode,
573                                         vif->prwise_crypto,
574                                         vif->prwise_crypto_len,
575                                         vif->grp_crypto, vif->grp_crypto_len,
576                                         vif->ssid_len, vif->ssid,
577                                         vif->req_bssid, vif->ch_hint,
578                                         ar->connect_ctrl_flags, nw_subtype);
579
580         up(&ar->sem);
581
582         if (status == -EINVAL) {
583                 memset(vif->ssid, 0, sizeof(vif->ssid));
584                 vif->ssid_len = 0;
585                 ath6kl_err("invalid request\n");
586                 return -ENOENT;
587         } else if (status) {
588                 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
589                 return -EIO;
590         }
591
592         if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
593             ((vif->auth_mode == WPA_PSK_AUTH)
594              || (vif->auth_mode == WPA2_PSK_AUTH))) {
595                 mod_timer(&vif->disconnect_timer,
596                           jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
597         }
598
599         ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
600         set_bit(CONNECT_PEND, &vif->flags);
601
602         return 0;
603 }
604
605 static struct cfg80211_bss *
606 ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
607                          enum network_type nw_type,
608                          const u8 *bssid,
609                          struct ieee80211_channel *chan,
610                          const u8 *beacon_ie,
611                          size_t beacon_ie_len)
612 {
613         struct ath6kl *ar = vif->ar;
614         struct cfg80211_bss *bss;
615         u16 cap_mask, cap_val;
616         u8 *ie;
617
618         if (nw_type & ADHOC_NETWORK) {
619                 cap_mask = WLAN_CAPABILITY_IBSS;
620                 cap_val = WLAN_CAPABILITY_IBSS;
621         } else {
622                 cap_mask = WLAN_CAPABILITY_ESS;
623                 cap_val = WLAN_CAPABILITY_ESS;
624         }
625
626         bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
627                                vif->ssid, vif->ssid_len,
628                                cap_mask, cap_val);
629         if (bss == NULL) {
630                 /*
631                  * Since cfg80211 may not yet know about the BSS,
632                  * generate a partial entry until the first BSS info
633                  * event becomes available.
634                  *
635                  * Prepend SSID element since it is not included in the Beacon
636                  * IEs from the target.
637                  */
638                 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
639                 if (ie == NULL)
640                         return NULL;
641                 ie[0] = WLAN_EID_SSID;
642                 ie[1] = vif->ssid_len;
643                 memcpy(ie + 2, vif->ssid, vif->ssid_len);
644                 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
645                 bss = cfg80211_inform_bss(ar->wiphy, chan,
646                                           bssid, 0, cap_val, 100,
647                                           ie, 2 + vif->ssid_len + beacon_ie_len,
648                                           0, GFP_KERNEL);
649                 if (bss)
650                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added bss %pM to "
651                                    "cfg80211\n", bssid);
652                 kfree(ie);
653         } else
654                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
655
656         return bss;
657 }
658
659 void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
660                                    u8 *bssid, u16 listen_intvl,
661                                    u16 beacon_intvl,
662                                    enum network_type nw_type,
663                                    u8 beacon_ie_len, u8 assoc_req_len,
664                                    u8 assoc_resp_len, u8 *assoc_info)
665 {
666         struct ieee80211_channel *chan;
667         struct ath6kl *ar = vif->ar;
668         struct cfg80211_bss *bss;
669
670         /* capinfo + listen interval */
671         u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
672
673         /* capinfo + status code +  associd */
674         u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
675
676         u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
677         u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
678             assoc_resp_ie_offset;
679
680         assoc_req_len -= assoc_req_ie_offset;
681         assoc_resp_len -= assoc_resp_ie_offset;
682
683         /*
684          * Store Beacon interval here; DTIM period will be available only once
685          * a Beacon frame from the AP is seen.
686          */
687         vif->assoc_bss_beacon_int = beacon_intvl;
688         clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
689
690         if (nw_type & ADHOC_NETWORK) {
691                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
692                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
693                                    "%s: ath6k not in ibss mode\n", __func__);
694                         return;
695                 }
696         }
697
698         if (nw_type & INFRA_NETWORK) {
699                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
700                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
701                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
702                                    "%s: ath6k not in station mode\n", __func__);
703                         return;
704                 }
705         }
706
707         chan = ieee80211_get_channel(ar->wiphy, (int) channel);
708
709         bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
710                                        assoc_info, beacon_ie_len);
711         if (!bss) {
712                 ath6kl_err("could not add cfg80211 bss entry\n");
713                 return;
714         }
715
716         if (nw_type & ADHOC_NETWORK) {
717                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
718                            nw_type & ADHOC_CREATOR ? "creator" : "joiner");
719                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
720                 cfg80211_put_bss(bss);
721                 return;
722         }
723
724         if (vif->sme_state == SME_CONNECTING) {
725                 /* inform connect result to cfg80211 */
726                 vif->sme_state = SME_CONNECTED;
727                 cfg80211_connect_result(vif->ndev, bssid,
728                                         assoc_req_ie, assoc_req_len,
729                                         assoc_resp_ie, assoc_resp_len,
730                                         WLAN_STATUS_SUCCESS, GFP_KERNEL);
731                 cfg80211_put_bss(bss);
732         } else if (vif->sme_state == SME_CONNECTED) {
733                 /* inform roam event to cfg80211 */
734                 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
735                                     assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
736         }
737 }
738
739 static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
740                                       struct net_device *dev, u16 reason_code)
741 {
742         struct ath6kl *ar = ath6kl_priv(dev);
743         struct ath6kl_vif *vif = netdev_priv(dev);
744
745         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
746                    reason_code);
747
748         ath6kl_cfg80211_sscan_disable(vif);
749
750         if (!ath6kl_cfg80211_ready(vif))
751                 return -EIO;
752
753         if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
754                 ath6kl_err("busy, destroy in progress\n");
755                 return -EBUSY;
756         }
757
758         if (down_interruptible(&ar->sem)) {
759                 ath6kl_err("busy, couldn't get access\n");
760                 return -ERESTARTSYS;
761         }
762
763         vif->reconnect_flag = 0;
764         ath6kl_disconnect(vif);
765         memset(vif->ssid, 0, sizeof(vif->ssid));
766         vif->ssid_len = 0;
767
768         if (!test_bit(SKIP_SCAN, &ar->flag))
769                 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
770
771         up(&ar->sem);
772
773         vif->sme_state = SME_DISCONNECTED;
774
775         return 0;
776 }
777
778 void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
779                                       u8 *bssid, u8 assoc_resp_len,
780                                       u8 *assoc_info, u16 proto_reason)
781 {
782         struct ath6kl *ar = vif->ar;
783
784         if (vif->scan_req) {
785                 cfg80211_scan_done(vif->scan_req, true);
786                 vif->scan_req = NULL;
787         }
788
789         if (vif->nw_type & ADHOC_NETWORK) {
790                 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
791                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
792                                    "%s: ath6k not in ibss mode\n", __func__);
793                         return;
794                 }
795                 memset(bssid, 0, ETH_ALEN);
796                 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
797                 return;
798         }
799
800         if (vif->nw_type & INFRA_NETWORK) {
801                 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
802                     vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
803                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
804                                    "%s: ath6k not in station mode\n", __func__);
805                         return;
806                 }
807         }
808
809         /*
810          * Send a disconnect command to target when a disconnect event is
811          * received with reason code other than 3 (DISCONNECT_CMD - disconnect
812          * request from host) to make the firmware stop trying to connect even
813          * after giving disconnect event. There will be one more disconnect
814          * event for this disconnect command with reason code DISCONNECT_CMD
815          * which will be notified to cfg80211.
816          */
817
818         if (reason != DISCONNECT_CMD) {
819                 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
820                 return;
821         }
822
823         clear_bit(CONNECT_PEND, &vif->flags);
824
825         if (vif->sme_state == SME_CONNECTING) {
826                 cfg80211_connect_result(vif->ndev,
827                                 bssid, NULL, 0,
828                                 NULL, 0,
829                                 WLAN_STATUS_UNSPECIFIED_FAILURE,
830                                 GFP_KERNEL);
831         } else if (vif->sme_state == SME_CONNECTED) {
832                 cfg80211_disconnected(vif->ndev, reason,
833                                 NULL, 0, GFP_KERNEL);
834         }
835
836         vif->sme_state = SME_DISCONNECTED;
837 }
838
839 static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
840                                 struct cfg80211_scan_request *request)
841 {
842         struct ath6kl *ar = ath6kl_priv(ndev);
843         struct ath6kl_vif *vif = netdev_priv(ndev);
844         s8 n_channels = 0;
845         u16 *channels = NULL;
846         int ret = 0;
847         u32 force_fg_scan = 0;
848
849         if (!ath6kl_cfg80211_ready(vif))
850                 return -EIO;
851
852         ath6kl_cfg80211_sscan_disable(vif);
853
854         if (!ar->usr_bss_filter) {
855                 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
856                 ret = ath6kl_wmi_bssfilter_cmd(
857                         ar->wmi, vif->fw_vif_idx,
858                         (test_bit(CONNECTED, &vif->flags) ?
859                          ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
860                 if (ret) {
861                         ath6kl_err("couldn't set bss filtering\n");
862                         return ret;
863                 }
864         }
865
866         if (request->n_ssids && request->ssids[0].ssid_len) {
867                 u8 i;
868
869                 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
870                         request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
871
872                 for (i = 0; i < request->n_ssids; i++)
873                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
874                                                   i + 1, SPECIFIC_SSID_FLAG,
875                                                   request->ssids[i].ssid_len,
876                                                   request->ssids[i].ssid);
877         }
878
879         /*
880          * FIXME: we should clear the IE in fw if it's not set so just
881          * remove the check altogether
882          */
883         if (request->ie) {
884                 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
885                                                WMI_FRAME_PROBE_REQ,
886                                                request->ie, request->ie_len);
887                 if (ret) {
888                         ath6kl_err("failed to set Probe Request appie for "
889                                    "scan");
890                         return ret;
891                 }
892         }
893
894         /*
895          * Scan only the requested channels if the request specifies a set of
896          * channels. If the list is longer than the target supports, do not
897          * configure the list and instead, scan all available channels.
898          */
899         if (request->n_channels > 0 &&
900             request->n_channels <= WMI_MAX_CHANNELS) {
901                 u8 i;
902
903                 n_channels = request->n_channels;
904
905                 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
906                 if (channels == NULL) {
907                         ath6kl_warn("failed to set scan channels, "
908                                     "scan all channels");
909                         n_channels = 0;
910                 }
911
912                 for (i = 0; i < n_channels; i++)
913                         channels[i] = request->channels[i]->center_freq;
914         }
915
916         if (test_bit(CONNECTED, &vif->flags))
917                 force_fg_scan = 1;
918
919         if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
920                     ar->fw_capabilities)) {
921                 /*
922                  * If capable of doing P2P mgmt operations using
923                  * station interface, send additional information like
924                  * supported rates to advertise and xmit rates for
925                  * probe requests
926                  */
927                 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
928                                                 WMI_LONG_SCAN, force_fg_scan,
929                                                 false, 0, 0, n_channels,
930                                                 channels, request->no_cck,
931                                                 request->rates);
932         } else {
933                 ret = ath6kl_wmi_startscan_cmd(ar->wmi, vif->fw_vif_idx,
934                                                 WMI_LONG_SCAN, force_fg_scan,
935                                                 false, 0, 0, n_channels,
936                                                 channels);
937         }
938         if (ret)
939                 ath6kl_err("wmi_startscan_cmd failed\n");
940         else
941                 vif->scan_req = request;
942
943         kfree(channels);
944
945         return ret;
946 }
947
948 void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
949 {
950         struct ath6kl *ar = vif->ar;
951         int i;
952
953         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
954                    aborted ? " aborted" : "");
955
956         if (!vif->scan_req)
957                 return;
958
959         if (aborted)
960                 goto out;
961
962         if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
963                 for (i = 0; i < vif->scan_req->n_ssids; i++) {
964                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
965                                                   i + 1, DISABLE_SSID_FLAG,
966                                                   0, NULL);
967                 }
968         }
969
970 out:
971         cfg80211_scan_done(vif->scan_req, aborted);
972         vif->scan_req = NULL;
973 }
974
975 static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
976                                    u8 key_index, bool pairwise,
977                                    const u8 *mac_addr,
978                                    struct key_params *params)
979 {
980         struct ath6kl *ar = ath6kl_priv(ndev);
981         struct ath6kl_vif *vif = netdev_priv(ndev);
982         struct ath6kl_key *key = NULL;
983         int seq_len;
984         u8 key_usage;
985         u8 key_type;
986
987         if (!ath6kl_cfg80211_ready(vif))
988                 return -EIO;
989
990         if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
991                 if (params->key_len != WMI_KRK_LEN)
992                         return -EINVAL;
993                 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
994                                               params->key);
995         }
996
997         if (key_index > WMI_MAX_KEY_INDEX) {
998                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
999                            "%s: key index %d out of bounds\n", __func__,
1000                            key_index);
1001                 return -ENOENT;
1002         }
1003
1004         key = &vif->keys[key_index];
1005         memset(key, 0, sizeof(struct ath6kl_key));
1006
1007         if (pairwise)
1008                 key_usage = PAIRWISE_USAGE;
1009         else
1010                 key_usage = GROUP_USAGE;
1011
1012         seq_len = params->seq_len;
1013         if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1014             seq_len > ATH6KL_KEY_SEQ_LEN) {
1015                 /* Only first half of the WPI PN is configured */
1016                 seq_len = ATH6KL_KEY_SEQ_LEN;
1017         }
1018         if (params->key_len > WLAN_MAX_KEY_LEN ||
1019             seq_len > sizeof(key->seq))
1020                 return -EINVAL;
1021
1022         key->key_len = params->key_len;
1023         memcpy(key->key, params->key, key->key_len);
1024         key->seq_len = seq_len;
1025         memcpy(key->seq, params->seq, key->seq_len);
1026         key->cipher = params->cipher;
1027
1028         switch (key->cipher) {
1029         case WLAN_CIPHER_SUITE_WEP40:
1030         case WLAN_CIPHER_SUITE_WEP104:
1031                 key_type = WEP_CRYPT;
1032                 break;
1033
1034         case WLAN_CIPHER_SUITE_TKIP:
1035                 key_type = TKIP_CRYPT;
1036                 break;
1037
1038         case WLAN_CIPHER_SUITE_CCMP:
1039                 key_type = AES_CRYPT;
1040                 break;
1041         case WLAN_CIPHER_SUITE_SMS4:
1042                 key_type = WAPI_CRYPT;
1043                 break;
1044
1045         default:
1046                 return -ENOTSUPP;
1047         }
1048
1049         if (((vif->auth_mode == WPA_PSK_AUTH)
1050              || (vif->auth_mode == WPA2_PSK_AUTH))
1051             && (key_usage & GROUP_USAGE))
1052                 del_timer(&vif->disconnect_timer);
1053
1054         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1055                    "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1056                    __func__, key_index, key->key_len, key_type,
1057                    key_usage, key->seq_len);
1058
1059         if (vif->nw_type == AP_NETWORK && !pairwise &&
1060             (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
1061              key_type == WAPI_CRYPT) && params) {
1062                 ar->ap_mode_bkey.valid = true;
1063                 ar->ap_mode_bkey.key_index = key_index;
1064                 ar->ap_mode_bkey.key_type = key_type;
1065                 ar->ap_mode_bkey.key_len = key->key_len;
1066                 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
1067                 if (!test_bit(CONNECTED, &vif->flags)) {
1068                         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
1069                                    "key configuration until AP mode has been "
1070                                    "started\n");
1071                         /*
1072                          * The key will be set in ath6kl_connect_ap_mode() once
1073                          * the connected event is received from the target.
1074                          */
1075                         return 0;
1076                 }
1077         }
1078
1079         if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
1080             !test_bit(CONNECTED, &vif->flags)) {
1081                 /*
1082                  * Store the key locally so that it can be re-configured after
1083                  * the AP mode has properly started
1084                  * (ath6kl_install_statioc_wep_keys).
1085                  */
1086                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
1087                            "until AP mode has been started\n");
1088                 vif->wep_key_list[key_index].key_len = key->key_len;
1089                 memcpy(vif->wep_key_list[key_index].key, key->key,
1090                        key->key_len);
1091                 return 0;
1092         }
1093
1094         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
1095                                      key_type, key_usage, key->key_len,
1096                                      key->seq, key->seq_len, key->key,
1097                                      KEY_OP_INIT_VAL,
1098                                      (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
1099 }
1100
1101 static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1102                                    u8 key_index, bool pairwise,
1103                                    const u8 *mac_addr)
1104 {
1105         struct ath6kl *ar = ath6kl_priv(ndev);
1106         struct ath6kl_vif *vif = netdev_priv(ndev);
1107
1108         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1109
1110         if (!ath6kl_cfg80211_ready(vif))
1111                 return -EIO;
1112
1113         if (key_index > WMI_MAX_KEY_INDEX) {
1114                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1115                            "%s: key index %d out of bounds\n", __func__,
1116                            key_index);
1117                 return -ENOENT;
1118         }
1119
1120         if (!vif->keys[key_index].key_len) {
1121                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1122                            "%s: index %d is empty\n", __func__, key_index);
1123                 return 0;
1124         }
1125
1126         vif->keys[key_index].key_len = 0;
1127
1128         return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
1129 }
1130
1131 static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1132                                    u8 key_index, bool pairwise,
1133                                    const u8 *mac_addr, void *cookie,
1134                                    void (*callback) (void *cookie,
1135                                                      struct key_params *))
1136 {
1137         struct ath6kl_vif *vif = netdev_priv(ndev);
1138         struct ath6kl_key *key = NULL;
1139         struct key_params params;
1140
1141         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1142
1143         if (!ath6kl_cfg80211_ready(vif))
1144                 return -EIO;
1145
1146         if (key_index > WMI_MAX_KEY_INDEX) {
1147                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1148                            "%s: key index %d out of bounds\n", __func__,
1149                            key_index);
1150                 return -ENOENT;
1151         }
1152
1153         key = &vif->keys[key_index];
1154         memset(&params, 0, sizeof(params));
1155         params.cipher = key->cipher;
1156         params.key_len = key->key_len;
1157         params.seq_len = key->seq_len;
1158         params.seq = key->seq;
1159         params.key = key->key;
1160
1161         callback(cookie, &params);
1162
1163         return key->key_len ? 0 : -ENOENT;
1164 }
1165
1166 static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1167                                            struct net_device *ndev,
1168                                            u8 key_index, bool unicast,
1169                                            bool multicast)
1170 {
1171         struct ath6kl *ar = ath6kl_priv(ndev);
1172         struct ath6kl_vif *vif = netdev_priv(ndev);
1173         struct ath6kl_key *key = NULL;
1174         u8 key_usage;
1175         enum crypto_type key_type = NONE_CRYPT;
1176
1177         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1178
1179         if (!ath6kl_cfg80211_ready(vif))
1180                 return -EIO;
1181
1182         if (key_index > WMI_MAX_KEY_INDEX) {
1183                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1184                            "%s: key index %d out of bounds\n",
1185                            __func__, key_index);
1186                 return -ENOENT;
1187         }
1188
1189         if (!vif->keys[key_index].key_len) {
1190                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1191                            __func__, key_index);
1192                 return -EINVAL;
1193         }
1194
1195         vif->def_txkey_index = key_index;
1196         key = &vif->keys[vif->def_txkey_index];
1197         key_usage = GROUP_USAGE;
1198         if (vif->prwise_crypto == WEP_CRYPT)
1199                 key_usage |= TX_USAGE;
1200         if (unicast)
1201                 key_type = vif->prwise_crypto;
1202         if (multicast)
1203                 key_type = vif->grp_crypto;
1204
1205         if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
1206                 return 0; /* Delay until AP mode has been started */
1207
1208         return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1209                                      vif->def_txkey_index,
1210                                      key_type, key_usage,
1211                                      key->key_len, key->seq, key->seq_len,
1212                                      key->key,
1213                                      KEY_OP_INIT_VAL, NULL,
1214                                      SYNC_BOTH_WMIFLAG);
1215 }
1216
1217 void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
1218                                        bool ismcast)
1219 {
1220         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1221                    "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1222
1223         cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
1224                                      (ismcast ? NL80211_KEYTYPE_GROUP :
1225                                       NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1226                                      GFP_KERNEL);
1227 }
1228
1229 static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1230 {
1231         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1232         struct ath6kl_vif *vif;
1233         int ret;
1234
1235         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1236                    changed);
1237
1238         vif = ath6kl_vif_first(ar);
1239         if (!vif)
1240                 return -EIO;
1241
1242         if (!ath6kl_cfg80211_ready(vif))
1243                 return -EIO;
1244
1245         if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1246                 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1247                 if (ret != 0) {
1248                         ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1249                         return -EIO;
1250                 }
1251         }
1252
1253         return 0;
1254 }
1255
1256 /*
1257  * The type nl80211_tx_power_setting replaces the following
1258  * data type from 2.6.36 onwards
1259 */
1260 static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1261                                        enum nl80211_tx_power_setting type,
1262                                        int mbm)
1263 {
1264         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1265         struct ath6kl_vif *vif;
1266         u8 ath6kl_dbm;
1267         int dbm = MBM_TO_DBM(mbm);
1268
1269         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1270                    type, dbm);
1271
1272         vif = ath6kl_vif_first(ar);
1273         if (!vif)
1274                 return -EIO;
1275
1276         if (!ath6kl_cfg80211_ready(vif))
1277                 return -EIO;
1278
1279         switch (type) {
1280         case NL80211_TX_POWER_AUTOMATIC:
1281                 return 0;
1282         case NL80211_TX_POWER_LIMITED:
1283                 ar->tx_pwr = ath6kl_dbm = dbm;
1284                 break;
1285         default:
1286                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1287                            __func__, type);
1288                 return -EOPNOTSUPP;
1289         }
1290
1291         ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, ath6kl_dbm);
1292
1293         return 0;
1294 }
1295
1296 static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1297 {
1298         struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1299         struct ath6kl_vif *vif;
1300
1301         vif = ath6kl_vif_first(ar);
1302         if (!vif)
1303                 return -EIO;
1304
1305         if (!ath6kl_cfg80211_ready(vif))
1306                 return -EIO;
1307
1308         if (test_bit(CONNECTED, &vif->flags)) {
1309                 ar->tx_pwr = 0;
1310
1311                 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
1312                         ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1313                         return -EIO;
1314                 }
1315
1316                 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1317                                                  5 * HZ);
1318
1319                 if (signal_pending(current)) {
1320                         ath6kl_err("target did not respond\n");
1321                         return -EINTR;
1322                 }
1323         }
1324
1325         *dbm = ar->tx_pwr;
1326         return 0;
1327 }
1328
1329 static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1330                                           struct net_device *dev,
1331                                           bool pmgmt, int timeout)
1332 {
1333         struct ath6kl *ar = ath6kl_priv(dev);
1334         struct wmi_power_mode_cmd mode;
1335         struct ath6kl_vif *vif = netdev_priv(dev);
1336
1337         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1338                    __func__, pmgmt, timeout);
1339
1340         if (!ath6kl_cfg80211_ready(vif))
1341                 return -EIO;
1342
1343         if (pmgmt) {
1344                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1345                 mode.pwr_mode = REC_POWER;
1346         } else {
1347                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1348                 mode.pwr_mode = MAX_PERF_POWER;
1349         }
1350
1351         if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
1352              mode.pwr_mode) != 0) {
1353                 ath6kl_err("wmi_powermode_cmd failed\n");
1354                 return -EIO;
1355         }
1356
1357         return 0;
1358 }
1359
1360 static struct net_device *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
1361                                                     char *name,
1362                                                     enum nl80211_iftype type,
1363                                                     u32 *flags,
1364                                                     struct vif_params *params)
1365 {
1366         struct ath6kl *ar = wiphy_priv(wiphy);
1367         struct net_device *ndev;
1368         u8 if_idx, nw_type;
1369
1370         if (ar->num_vif == ar->vif_max) {
1371                 ath6kl_err("Reached maximum number of supported vif\n");
1372                 return ERR_PTR(-EINVAL);
1373         }
1374
1375         if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1376                 ath6kl_err("Not a supported interface type\n");
1377                 return ERR_PTR(-EINVAL);
1378         }
1379
1380         ndev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1381         if (!ndev)
1382                 return ERR_PTR(-ENOMEM);
1383
1384         ar->num_vif++;
1385
1386         return ndev;
1387 }
1388
1389 static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
1390                                      struct net_device *ndev)
1391 {
1392         struct ath6kl *ar = wiphy_priv(wiphy);
1393         struct ath6kl_vif *vif = netdev_priv(ndev);
1394
1395         spin_lock_bh(&ar->list_lock);
1396         list_del(&vif->list);
1397         spin_unlock_bh(&ar->list_lock);
1398
1399         ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1400
1401         ath6kl_cfg80211_vif_cleanup(vif);
1402
1403         return 0;
1404 }
1405
1406 static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1407                                         struct net_device *ndev,
1408                                         enum nl80211_iftype type, u32 *flags,
1409                                         struct vif_params *params)
1410 {
1411         struct ath6kl_vif *vif = netdev_priv(ndev);
1412
1413         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1414
1415         switch (type) {
1416         case NL80211_IFTYPE_STATION:
1417                 vif->next_mode = INFRA_NETWORK;
1418                 break;
1419         case NL80211_IFTYPE_ADHOC:
1420                 vif->next_mode = ADHOC_NETWORK;
1421                 break;
1422         case NL80211_IFTYPE_AP:
1423                 vif->next_mode = AP_NETWORK;
1424                 break;
1425         case NL80211_IFTYPE_P2P_CLIENT:
1426                 vif->next_mode = INFRA_NETWORK;
1427                 break;
1428         case NL80211_IFTYPE_P2P_GO:
1429                 vif->next_mode = AP_NETWORK;
1430                 break;
1431         default:
1432                 ath6kl_err("invalid interface type %u\n", type);
1433                 return -EOPNOTSUPP;
1434         }
1435
1436         vif->wdev.iftype = type;
1437
1438         return 0;
1439 }
1440
1441 static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1442                                      struct net_device *dev,
1443                                      struct cfg80211_ibss_params *ibss_param)
1444 {
1445         struct ath6kl *ar = ath6kl_priv(dev);
1446         struct ath6kl_vif *vif = netdev_priv(dev);
1447         int status;
1448
1449         if (!ath6kl_cfg80211_ready(vif))
1450                 return -EIO;
1451
1452         vif->ssid_len = ibss_param->ssid_len;
1453         memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
1454
1455         if (ibss_param->channel)
1456                 vif->ch_hint = ibss_param->channel->center_freq;
1457
1458         if (ibss_param->channel_fixed) {
1459                 /*
1460                  * TODO: channel_fixed: The channel should be fixed, do not
1461                  * search for IBSSs to join on other channels. Target
1462                  * firmware does not support this feature, needs to be
1463                  * updated.
1464                  */
1465                 return -EOPNOTSUPP;
1466         }
1467
1468         memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
1469         if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1470                 memcpy(vif->req_bssid, ibss_param->bssid,
1471                        sizeof(vif->req_bssid));
1472
1473         ath6kl_set_wpa_version(vif, 0);
1474
1475         status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
1476         if (status)
1477                 return status;
1478
1479         if (ibss_param->privacy) {
1480                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1481                 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
1482         } else {
1483                 ath6kl_set_cipher(vif, 0, true);
1484                 ath6kl_set_cipher(vif, 0, false);
1485         }
1486
1487         vif->nw_type = vif->next_mode;
1488
1489         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1490                    "%s: connect called with authmode %d dot11 auth %d"
1491                    " PW crypto %d PW crypto len %d GRP crypto %d"
1492                    " GRP crypto len %d channel hint %u\n",
1493                    __func__,
1494                    vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1495                    vif->prwise_crypto_len, vif->grp_crypto,
1496                    vif->grp_crypto_len, vif->ch_hint);
1497
1498         status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
1499                                         vif->dot11_auth_mode, vif->auth_mode,
1500                                         vif->prwise_crypto,
1501                                         vif->prwise_crypto_len,
1502                                         vif->grp_crypto, vif->grp_crypto_len,
1503                                         vif->ssid_len, vif->ssid,
1504                                         vif->req_bssid, vif->ch_hint,
1505                                         ar->connect_ctrl_flags, SUBTYPE_NONE);
1506         set_bit(CONNECT_PEND, &vif->flags);
1507
1508         return 0;
1509 }
1510
1511 static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1512                                       struct net_device *dev)
1513 {
1514         struct ath6kl_vif *vif = netdev_priv(dev);
1515
1516         if (!ath6kl_cfg80211_ready(vif))
1517                 return -EIO;
1518
1519         ath6kl_disconnect(vif);
1520         memset(vif->ssid, 0, sizeof(vif->ssid));
1521         vif->ssid_len = 0;
1522
1523         return 0;
1524 }
1525
1526 static const u32 cipher_suites[] = {
1527         WLAN_CIPHER_SUITE_WEP40,
1528         WLAN_CIPHER_SUITE_WEP104,
1529         WLAN_CIPHER_SUITE_TKIP,
1530         WLAN_CIPHER_SUITE_CCMP,
1531         CCKM_KRK_CIPHER_SUITE,
1532         WLAN_CIPHER_SUITE_SMS4,
1533 };
1534
1535 static bool is_rate_legacy(s32 rate)
1536 {
1537         static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1538                 6000, 9000, 12000, 18000, 24000,
1539                 36000, 48000, 54000
1540         };
1541         u8 i;
1542
1543         for (i = 0; i < ARRAY_SIZE(legacy); i++)
1544                 if (rate == legacy[i])
1545                         return true;
1546
1547         return false;
1548 }
1549
1550 static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1551 {
1552         static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1553                 52000, 58500, 65000, 72200
1554         };
1555         u8 i;
1556
1557         for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1558                 if (rate == ht20[i]) {
1559                         if (i == ARRAY_SIZE(ht20) - 1)
1560                                 /* last rate uses sgi */
1561                                 *sgi = true;
1562                         else
1563                                 *sgi = false;
1564
1565                         *mcs = i;
1566                         return true;
1567                 }
1568         }
1569         return false;
1570 }
1571
1572 static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1573 {
1574         static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1575                 81000, 108000, 121500, 135000,
1576                 150000
1577         };
1578         u8 i;
1579
1580         for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1581                 if (rate == ht40[i]) {
1582                         if (i == ARRAY_SIZE(ht40) - 1)
1583                                 /* last rate uses sgi */
1584                                 *sgi = true;
1585                         else
1586                                 *sgi = false;
1587
1588                         *mcs = i;
1589                         return true;
1590                 }
1591         }
1592
1593         return false;
1594 }
1595
1596 static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1597                               u8 *mac, struct station_info *sinfo)
1598 {
1599         struct ath6kl *ar = ath6kl_priv(dev);
1600         struct ath6kl_vif *vif = netdev_priv(dev);
1601         long left;
1602         bool sgi;
1603         s32 rate;
1604         int ret;
1605         u8 mcs;
1606
1607         if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
1608                 return -ENOENT;
1609
1610         if (down_interruptible(&ar->sem))
1611                 return -EBUSY;
1612
1613         set_bit(STATS_UPDATE_PEND, &vif->flags);
1614
1615         ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
1616
1617         if (ret != 0) {
1618                 up(&ar->sem);
1619                 return -EIO;
1620         }
1621
1622         left = wait_event_interruptible_timeout(ar->event_wq,
1623                                                 !test_bit(STATS_UPDATE_PEND,
1624                                                           &vif->flags),
1625                                                 WMI_TIMEOUT);
1626
1627         up(&ar->sem);
1628
1629         if (left == 0)
1630                 return -ETIMEDOUT;
1631         else if (left < 0)
1632                 return left;
1633
1634         if (vif->target_stats.rx_byte) {
1635                 sinfo->rx_bytes = vif->target_stats.rx_byte;
1636                 sinfo->filled |= STATION_INFO_RX_BYTES;
1637                 sinfo->rx_packets = vif->target_stats.rx_pkt;
1638                 sinfo->filled |= STATION_INFO_RX_PACKETS;
1639         }
1640
1641         if (vif->target_stats.tx_byte) {
1642                 sinfo->tx_bytes = vif->target_stats.tx_byte;
1643                 sinfo->filled |= STATION_INFO_TX_BYTES;
1644                 sinfo->tx_packets = vif->target_stats.tx_pkt;
1645                 sinfo->filled |= STATION_INFO_TX_PACKETS;
1646         }
1647
1648         sinfo->signal = vif->target_stats.cs_rssi;
1649         sinfo->filled |= STATION_INFO_SIGNAL;
1650
1651         rate = vif->target_stats.tx_ucast_rate;
1652
1653         if (is_rate_legacy(rate)) {
1654                 sinfo->txrate.legacy = rate / 100;
1655         } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1656                 if (sgi) {
1657                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1658                         sinfo->txrate.mcs = mcs - 1;
1659                 } else {
1660                         sinfo->txrate.mcs = mcs;
1661                 }
1662
1663                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1664         } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1665                 if (sgi) {
1666                         sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1667                         sinfo->txrate.mcs = mcs - 1;
1668                 } else {
1669                         sinfo->txrate.mcs = mcs;
1670                 }
1671
1672                 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1673                 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1674         } else {
1675                 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1676                            "invalid rate from stats: %d\n", rate);
1677                 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
1678                 return 0;
1679         }
1680
1681         sinfo->filled |= STATION_INFO_TX_BITRATE;
1682
1683         if (test_bit(CONNECTED, &vif->flags) &&
1684             test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
1685             vif->nw_type == INFRA_NETWORK) {
1686                 sinfo->filled |= STATION_INFO_BSS_PARAM;
1687                 sinfo->bss_param.flags = 0;
1688                 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1689                 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
1690         }
1691
1692         return 0;
1693 }
1694
1695 static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1696                             struct cfg80211_pmksa *pmksa)
1697 {
1698         struct ath6kl *ar = ath6kl_priv(netdev);
1699         struct ath6kl_vif *vif = netdev_priv(netdev);
1700
1701         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1702                                        pmksa->pmkid, true);
1703 }
1704
1705 static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1706                             struct cfg80211_pmksa *pmksa)
1707 {
1708         struct ath6kl *ar = ath6kl_priv(netdev);
1709         struct ath6kl_vif *vif = netdev_priv(netdev);
1710
1711         return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
1712                                        pmksa->pmkid, false);
1713 }
1714
1715 static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1716 {
1717         struct ath6kl *ar = ath6kl_priv(netdev);
1718         struct ath6kl_vif *vif = netdev_priv(netdev);
1719
1720         if (test_bit(CONNECTED, &vif->flags))
1721                 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1722                                                vif->bssid, NULL, false);
1723         return 0;
1724 }
1725
1726 static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1727                           struct cfg80211_wowlan *wow, u32 *filter)
1728 {
1729         int ret, pos;
1730         u8 mask[WOW_MASK_SIZE];
1731         u16 i;
1732
1733         /* Configure the patterns that we received from the user. */
1734         for (i = 0; i < wow->n_patterns; i++) {
1735
1736                 /*
1737                  * Convert given nl80211 specific mask value to equivalent
1738                  * driver specific mask value and send it to the chip along
1739                  * with patterns. For example, If the mask value defined in
1740                  * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1741                  * then equivalent driver specific mask value is
1742                  * "0xFF 0x00 0xFF 0x00".
1743                  */
1744                 memset(&mask, 0, sizeof(mask));
1745                 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1746                         if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1747                                 mask[pos] = 0xFF;
1748                 }
1749                 /*
1750                  * Note: Pattern's offset is not passed as part of wowlan
1751                  * parameter from CFG layer. So it's always passed as ZERO
1752                  * to the firmware. It means, given WOW patterns are always
1753                  * matched from the first byte of received pkt in the firmware.
1754                  */
1755                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1756                                 vif->fw_vif_idx, WOW_LIST_ID,
1757                                 wow->patterns[i].pattern_len,
1758                                 0 /* pattern offset */,
1759                                 wow->patterns[i].pattern, mask);
1760                 if (ret)
1761                         return ret;
1762         }
1763
1764         if (wow->disconnect)
1765                 *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1766
1767         if (wow->magic_pkt)
1768                 *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1769
1770         if (wow->gtk_rekey_failure)
1771                 *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1772
1773         if (wow->eap_identity_req)
1774                 *filter |= WOW_FILTER_OPTION_EAP_REQ;
1775
1776         if (wow->four_way_handshake)
1777                 *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1778
1779         return 0;
1780 }
1781
1782 static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1783 {
1784         static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1785                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1786                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1787                 0x00, 0x08 };
1788         static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1789                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1790                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1791                 0x00, 0x7f };
1792         u8 unicst_offset = 0;
1793         static const u8 arp_pattern[] = { 0x08, 0x06 };
1794         static const u8 arp_mask[] = { 0xff, 0xff };
1795         u8 arp_offset = 20;
1796         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1797         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1798         u8 discvr_offset = 38;
1799         static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1800                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1801                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1802                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1803                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1804                 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1805         static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1806                 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1807                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1808                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1809                 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1810                 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1811         u8 dhcp_offset = 0;
1812         int ret;
1813
1814         /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1815         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1816                         vif->fw_vif_idx, WOW_LIST_ID,
1817                         sizeof(unicst_pattern), unicst_offset,
1818                         unicst_pattern, unicst_mask);
1819         if (ret) {
1820                 ath6kl_err("failed to add WOW unicast IP pattern\n");
1821                 return ret;
1822         }
1823
1824         /* Setup all ARP pkt pattern */
1825         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1826                         vif->fw_vif_idx, WOW_LIST_ID,
1827                         sizeof(arp_pattern), arp_offset,
1828                         arp_pattern, arp_mask);
1829         if (ret) {
1830                 ath6kl_err("failed to add WOW ARP pattern\n");
1831                 return ret;
1832         }
1833
1834         /*
1835          * Setup multicast pattern for mDNS 224.0.0.251,
1836          * SSDP 239.255.255.250 and LLMNR  224.0.0.252
1837          */
1838         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1839                         vif->fw_vif_idx, WOW_LIST_ID,
1840                         sizeof(discvr_pattern), discvr_offset,
1841                         discvr_pattern, discvr_mask);
1842         if (ret) {
1843                 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
1844                 return ret;
1845         }
1846
1847         /* Setup all DHCP broadcast pkt pattern */
1848         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1849                         vif->fw_vif_idx, WOW_LIST_ID,
1850                         sizeof(dhcp_pattern), dhcp_offset,
1851                         dhcp_pattern, dhcp_mask);
1852         if (ret) {
1853                 ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
1854                 return ret;
1855         }
1856
1857         return 0;
1858 }
1859
1860 static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
1861 {
1862         struct net_device *ndev = vif->ndev;
1863         static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1864         static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1865         u8 discvr_offset = 38;
1866         u8 mac_mask[ETH_ALEN];
1867         int ret;
1868
1869         /* Setup unicast pkt pattern */
1870         memset(mac_mask, 0xff, ETH_ALEN);
1871         ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1872                                 vif->fw_vif_idx, WOW_LIST_ID,
1873                                 ETH_ALEN, 0, ndev->dev_addr,
1874                                 mac_mask);
1875         if (ret) {
1876                 ath6kl_err("failed to add WOW unicast pattern\n");
1877                 return ret;
1878         }
1879
1880         /*
1881          * Setup multicast pattern for mDNS 224.0.0.251,
1882          * SSDP 239.255.255.250 and LLMNR 224.0.0.252
1883          */
1884         if ((ndev->flags & IFF_ALLMULTI) ||
1885             (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
1886                 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1887                                 vif->fw_vif_idx, WOW_LIST_ID,
1888                                 sizeof(discvr_pattern), discvr_offset,
1889                                 discvr_pattern, discvr_mask);
1890                 if (ret) {
1891                         ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR "
1892                                    "pattern\n");
1893                         return ret;
1894                 }
1895         }
1896
1897         return 0;
1898 }
1899
1900 static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
1901 {
1902         struct in_device *in_dev;
1903         struct in_ifaddr *ifa;
1904         struct ath6kl_vif *vif;
1905         int ret, left;
1906         u32 filter = 0;
1907         u16 i;
1908         u8 index = 0;
1909         __be32 ips[MAX_IP_ADDRS];
1910
1911         vif = ath6kl_vif_first(ar);
1912         if (!vif)
1913                 return -EIO;
1914
1915         if (!ath6kl_cfg80211_ready(vif))
1916                 return -EIO;
1917
1918         if (!test_bit(CONNECTED, &vif->flags))
1919                 return -ENOTCONN;
1920
1921         if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
1922                 return -EINVAL;
1923
1924         /* Clear existing WOW patterns */
1925         for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
1926                 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
1927                                                WOW_LIST_ID, i);
1928
1929         /*
1930          * Skip the default WOW pattern configuration
1931          * if the driver receives any WOW patterns from
1932          * the user.
1933          */
1934         if (wow)
1935                 ret = ath6kl_wow_usr(ar, vif, wow, &filter);
1936         else if (vif->nw_type == AP_NETWORK)
1937                 ret = ath6kl_wow_ap(ar, vif);
1938         else
1939                 ret = ath6kl_wow_sta(ar, vif);
1940
1941         if (ret)
1942                 return ret;
1943
1944         /* Setup own IP addr for ARP agent. */
1945         in_dev = __in_dev_get_rtnl(vif->ndev);
1946         if (!in_dev)
1947                 goto skip_arp;
1948
1949         ifa = in_dev->ifa_list;
1950         memset(&ips, 0, sizeof(ips));
1951
1952         /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
1953         while (index < MAX_IP_ADDRS && ifa) {
1954                 ips[index] = ifa->ifa_local;
1955                 ifa = ifa->ifa_next;
1956                 index++;
1957         }
1958
1959         if (ifa) {
1960                 ath6kl_err("total IP addr count is exceeding fw limit\n");
1961                 return -EINVAL;
1962         }
1963
1964         ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
1965         if (ret) {
1966                 ath6kl_err("fail to setup ip for arp agent\n");
1967                 return ret;
1968         }
1969
1970 skip_arp:
1971         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
1972                                           ATH6KL_WOW_MODE_ENABLE,
1973                                           filter,
1974                                           WOW_HOST_REQ_DELAY);
1975         if (ret)
1976                 return ret;
1977
1978         clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
1979
1980         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
1981                                                  ATH6KL_HOST_MODE_ASLEEP);
1982         if (ret)
1983                 return ret;
1984
1985         left = wait_event_interruptible_timeout(ar->event_wq,
1986                         test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags),
1987                         WMI_TIMEOUT);
1988         if (left == 0) {
1989                 ath6kl_warn("timeout, didn't get host sleep cmd "
1990                             "processed event\n");
1991                 ret = -ETIMEDOUT;
1992         } else if (left < 0) {
1993                 ath6kl_warn("error while waiting for host sleep cmd "
1994                             "processed event %d\n", left);
1995                 ret = left;
1996         }
1997
1998         if (ar->tx_pending[ar->ctrl_ep]) {
1999                 left = wait_event_interruptible_timeout(ar->event_wq,
2000                                 ar->tx_pending[ar->ctrl_ep] == 0, WMI_TIMEOUT);
2001                 if (left == 0) {
2002                         ath6kl_warn("clear wmi ctrl data timeout\n");
2003                         ret = -ETIMEDOUT;
2004                 } else if (left < 0) {
2005                         ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2006                         ret = left;
2007                 }
2008         }
2009
2010         return ret;
2011 }
2012
2013 static int ath6kl_wow_resume(struct ath6kl *ar)
2014 {
2015         struct ath6kl_vif *vif;
2016         int ret;
2017
2018         vif = ath6kl_vif_first(ar);
2019         if (!vif)
2020                 return -EIO;
2021
2022         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2023                                                  ATH6KL_HOST_MODE_AWAKE);
2024         return ret;
2025 }
2026
2027 int ath6kl_cfg80211_suspend(struct ath6kl *ar,
2028                             enum ath6kl_cfg_suspend_mode mode,
2029                             struct cfg80211_wowlan *wow)
2030 {
2031         int ret;
2032
2033         switch (mode) {
2034         case ATH6KL_CFG_SUSPEND_WOW:
2035
2036                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2037
2038                 /* Flush all non control pkts in TX path */
2039                 ath6kl_tx_data_cleanup(ar);
2040
2041                 ret = ath6kl_wow_suspend(ar, wow);
2042                 if (ret) {
2043                         ath6kl_err("wow suspend failed: %d\n", ret);
2044                         return ret;
2045                 }
2046                 ar->state = ATH6KL_STATE_WOW;
2047                 break;
2048
2049         case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
2050
2051                 ath6kl_cfg80211_stop_all(ar);
2052
2053                 /* save the current power mode before enabling power save */
2054                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2055
2056                 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2057                 if (ret) {
2058                         ath6kl_warn("wmi powermode command failed during suspend: %d\n",
2059                                     ret);
2060                 }
2061
2062                 ar->state = ATH6KL_STATE_DEEPSLEEP;
2063
2064                 break;
2065
2066         case ATH6KL_CFG_SUSPEND_CUTPOWER:
2067
2068                 ath6kl_cfg80211_stop_all(ar);
2069
2070                 if (ar->state == ATH6KL_STATE_OFF) {
2071                         ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2072                                    "suspend hw off, no action for cutpower\n");
2073                         break;
2074                 }
2075
2076                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2077
2078                 ret = ath6kl_init_hw_stop(ar);
2079                 if (ret) {
2080                         ath6kl_warn("failed to stop hw during suspend: %d\n",
2081                                     ret);
2082                 }
2083
2084                 ar->state = ATH6KL_STATE_CUTPOWER;
2085
2086                 break;
2087
2088         case ATH6KL_CFG_SUSPEND_SCHED_SCAN:
2089                 /*
2090                  * Nothing needed for schedule scan, firmware is already in
2091                  * wow mode and sleeping most of the time.
2092                  */
2093                 break;
2094
2095         default:
2096                 break;
2097         }
2098
2099         return 0;
2100 }
2101 EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
2102
2103 int ath6kl_cfg80211_resume(struct ath6kl *ar)
2104 {
2105         int ret;
2106
2107         switch (ar->state) {
2108         case  ATH6KL_STATE_WOW:
2109                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2110
2111                 ret = ath6kl_wow_resume(ar);
2112                 if (ret) {
2113                         ath6kl_warn("wow mode resume failed: %d\n", ret);
2114                         return ret;
2115                 }
2116
2117                 ar->state = ATH6KL_STATE_ON;
2118                 break;
2119
2120         case ATH6KL_STATE_DEEPSLEEP:
2121                 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2122                         ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2123                                                        ar->wmi->saved_pwr_mode);
2124                         if (ret) {
2125                                 ath6kl_warn("wmi powermode command failed during resume: %d\n",
2126                                             ret);
2127                         }
2128                 }
2129
2130                 ar->state = ATH6KL_STATE_ON;
2131
2132                 break;
2133
2134         case ATH6KL_STATE_CUTPOWER:
2135                 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2136
2137                 ret = ath6kl_init_hw_start(ar);
2138                 if (ret) {
2139                         ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2140                         return ret;
2141                 }
2142                 break;
2143
2144         case ATH6KL_STATE_SCHED_SCAN:
2145                 break;
2146
2147         default:
2148                 break;
2149         }
2150
2151         return 0;
2152 }
2153 EXPORT_SYMBOL(ath6kl_cfg80211_resume);
2154
2155 #ifdef CONFIG_PM
2156
2157 /* hif layer decides what suspend mode to use */
2158 static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
2159                                  struct cfg80211_wowlan *wow)
2160 {
2161         struct ath6kl *ar = wiphy_priv(wiphy);
2162
2163         return ath6kl_hif_suspend(ar, wow);
2164 }
2165
2166 static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
2167 {
2168         struct ath6kl *ar = wiphy_priv(wiphy);
2169
2170         return ath6kl_hif_resume(ar);
2171 }
2172
2173 /*
2174  * FIXME: WOW suspend mode is selected if the host sdio controller supports
2175  * both sdio irq wake up and keep power. The target pulls sdio data line to
2176  * wake up the host when WOW pattern matches. This causes sdio irq handler
2177  * is being called in the host side which internally hits ath6kl's RX path.
2178  *
2179  * Since sdio interrupt is not disabled, RX path executes even before
2180  * the host executes the actual resume operation from PM module.
2181  *
2182  * In the current scenario, WOW resume should happen before start processing
2183  * any data from the target. So It's required to perform WOW resume in RX path.
2184  * Ideally we should perform WOW resume only in the actual platform
2185  * resume path. This area needs bit rework to avoid WOW resume in RX path.
2186  *
2187  * ath6kl_check_wow_status() is called from ath6kl_rx().
2188  */
2189 void ath6kl_check_wow_status(struct ath6kl *ar)
2190 {
2191         if (ar->state == ATH6KL_STATE_WOW)
2192                 ath6kl_cfg80211_resume(ar);
2193 }
2194
2195 #else
2196
2197 void ath6kl_check_wow_status(struct ath6kl *ar)
2198 {
2199 }
2200 #endif
2201
2202 static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
2203                               struct ieee80211_channel *chan,
2204                               enum nl80211_channel_type channel_type)
2205 {
2206         struct ath6kl_vif *vif;
2207
2208         /*
2209          * 'dev' could be NULL if a channel change is required for the hardware
2210          * device itself, instead of a particular VIF.
2211          *
2212          * FIXME: To be handled properly when monitor mode is supported.
2213          */
2214         if (!dev)
2215                 return -EBUSY;
2216
2217         vif = netdev_priv(dev);
2218
2219         if (!ath6kl_cfg80211_ready(vif))
2220                 return -EIO;
2221
2222         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
2223                    __func__, chan->center_freq, chan->hw_value);
2224         vif->next_chan = chan->center_freq;
2225
2226         return 0;
2227 }
2228
2229 static bool ath6kl_is_p2p_ie(const u8 *pos)
2230 {
2231         return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2232                 pos[2] == 0x50 && pos[3] == 0x6f &&
2233                 pos[4] == 0x9a && pos[5] == 0x09;
2234 }
2235
2236 static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2237                                         const u8 *ies, size_t ies_len)
2238 {
2239         struct ath6kl *ar = vif->ar;
2240         const u8 *pos;
2241         u8 *buf = NULL;
2242         size_t len = 0;
2243         int ret;
2244
2245         /*
2246          * Filter out P2P IE(s) since they will be included depending on
2247          * the Probe Request frame in ath6kl_send_go_probe_resp().
2248          */
2249
2250         if (ies && ies_len) {
2251                 buf = kmalloc(ies_len, GFP_KERNEL);
2252                 if (buf == NULL)
2253                         return -ENOMEM;
2254                 pos = ies;
2255                 while (pos + 1 < ies + ies_len) {
2256                         if (pos + 2 + pos[1] > ies + ies_len)
2257                                 break;
2258                         if (!ath6kl_is_p2p_ie(pos)) {
2259                                 memcpy(buf + len, pos, 2 + pos[1]);
2260                                 len += 2 + pos[1];
2261                         }
2262                         pos += 2 + pos[1];
2263                 }
2264         }
2265
2266         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2267                                        WMI_FRAME_PROBE_RESP, buf, len);
2268         kfree(buf);
2269         return ret;
2270 }
2271
2272 static int ath6kl_set_ies(struct ath6kl_vif *vif,
2273                           struct cfg80211_beacon_data *info)
2274 {
2275         struct ath6kl *ar = vif->ar;
2276         int res;
2277
2278         if (info->beacon_ies) {
2279                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2280                                                WMI_FRAME_BEACON,
2281                                                info->beacon_ies,
2282                                                info->beacon_ies_len);
2283                 if (res)
2284                         return res;
2285         }
2286
2287         if (info->proberesp_ies) {
2288                 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2289                                                    info->proberesp_ies_len);
2290                 if (res)
2291                         return res;
2292         }
2293
2294         if (info->assocresp_ies) {
2295                 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2296                                                WMI_FRAME_ASSOC_RESP,
2297                                                info->assocresp_ies,
2298                                                info->assocresp_ies_len);
2299                 if (res)
2300                         return res;
2301         }
2302
2303         return 0;
2304 }
2305
2306 static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2307                            struct cfg80211_ap_settings *info)
2308 {
2309         struct ath6kl *ar = ath6kl_priv(dev);
2310         struct ath6kl_vif *vif = netdev_priv(dev);
2311         struct ieee80211_mgmt *mgmt;
2312         u8 *ies;
2313         int ies_len;
2314         struct wmi_connect_cmd p;
2315         int res;
2316         int i, ret;
2317
2318         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
2319
2320         if (!ath6kl_cfg80211_ready(vif))
2321                 return -EIO;
2322
2323         if (vif->next_mode != AP_NETWORK)
2324                 return -EOPNOTSUPP;
2325
2326         res = ath6kl_set_ies(vif, &info->beacon);
2327
2328         ar->ap_mode_bkey.valid = false;
2329
2330         /* TODO:
2331          * info->interval
2332          * info->dtim_period
2333          */
2334
2335         if (info->beacon.head == NULL)
2336                 return -EINVAL;
2337         mgmt = (struct ieee80211_mgmt *) info->beacon.head;
2338         ies = mgmt->u.beacon.variable;
2339         if (ies > info->beacon.head + info->beacon.head_len)
2340                 return -EINVAL;
2341         ies_len = info->beacon.head + info->beacon.head_len - ies;
2342
2343         if (info->ssid == NULL)
2344                 return -EINVAL;
2345         memcpy(vif->ssid, info->ssid, info->ssid_len);
2346         vif->ssid_len = info->ssid_len;
2347         if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
2348                 return -EOPNOTSUPP; /* TODO */
2349
2350         ret = ath6kl_set_auth_type(vif, info->auth_type);
2351         if (ret)
2352                 return ret;
2353
2354         memset(&p, 0, sizeof(p));
2355
2356         for (i = 0; i < info->crypto.n_akm_suites; i++) {
2357                 switch (info->crypto.akm_suites[i]) {
2358                 case WLAN_AKM_SUITE_8021X:
2359                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2360                                 p.auth_mode |= WPA_AUTH;
2361                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2362                                 p.auth_mode |= WPA2_AUTH;
2363                         break;
2364                 case WLAN_AKM_SUITE_PSK:
2365                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2366                                 p.auth_mode |= WPA_PSK_AUTH;
2367                         if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2368                                 p.auth_mode |= WPA2_PSK_AUTH;
2369                         break;
2370                 }
2371         }
2372         if (p.auth_mode == 0)
2373                 p.auth_mode = NONE_AUTH;
2374         vif->auth_mode = p.auth_mode;
2375
2376         for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2377                 switch (info->crypto.ciphers_pairwise[i]) {
2378                 case WLAN_CIPHER_SUITE_WEP40:
2379                 case WLAN_CIPHER_SUITE_WEP104:
2380                         p.prwise_crypto_type |= WEP_CRYPT;
2381                         break;
2382                 case WLAN_CIPHER_SUITE_TKIP:
2383                         p.prwise_crypto_type |= TKIP_CRYPT;
2384                         break;
2385                 case WLAN_CIPHER_SUITE_CCMP:
2386                         p.prwise_crypto_type |= AES_CRYPT;
2387                         break;
2388                 case WLAN_CIPHER_SUITE_SMS4:
2389                         p.prwise_crypto_type |= WAPI_CRYPT;
2390                         break;
2391                 }
2392         }
2393         if (p.prwise_crypto_type == 0) {
2394                 p.prwise_crypto_type = NONE_CRYPT;
2395                 ath6kl_set_cipher(vif, 0, true);
2396         } else if (info->crypto.n_ciphers_pairwise == 1)
2397                 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
2398
2399         switch (info->crypto.cipher_group) {
2400         case WLAN_CIPHER_SUITE_WEP40:
2401         case WLAN_CIPHER_SUITE_WEP104:
2402                 p.grp_crypto_type = WEP_CRYPT;
2403                 break;
2404         case WLAN_CIPHER_SUITE_TKIP:
2405                 p.grp_crypto_type = TKIP_CRYPT;
2406                 break;
2407         case WLAN_CIPHER_SUITE_CCMP:
2408                 p.grp_crypto_type = AES_CRYPT;
2409                 break;
2410         case WLAN_CIPHER_SUITE_SMS4:
2411                 p.grp_crypto_type = WAPI_CRYPT;
2412                 break;
2413         default:
2414                 p.grp_crypto_type = NONE_CRYPT;
2415                 break;
2416         }
2417         ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
2418
2419         p.nw_type = AP_NETWORK;
2420         vif->nw_type = vif->next_mode;
2421
2422         p.ssid_len = vif->ssid_len;
2423         memcpy(p.ssid, vif->ssid, vif->ssid_len);
2424         p.dot11_auth_mode = vif->dot11_auth_mode;
2425         p.ch = cpu_to_le16(vif->next_chan);
2426
2427         /* Enable uAPSD support by default */
2428         res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2429         if (res < 0)
2430                 return res;
2431
2432         if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2433                 p.nw_subtype = SUBTYPE_P2PGO;
2434         } else {
2435                 /*
2436                  * Due to firmware limitation, it is not possible to
2437                  * do P2P mgmt operations in AP mode
2438                  */
2439                 p.nw_subtype = SUBTYPE_NONE;
2440         }
2441
2442         res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
2443         if (res < 0)
2444                 return res;
2445
2446         return 0;
2447 }
2448
2449 static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2450                                 struct cfg80211_beacon_data *beacon)
2451 {
2452         struct ath6kl_vif *vif = netdev_priv(dev);
2453
2454         if (!ath6kl_cfg80211_ready(vif))
2455                 return -EIO;
2456
2457         if (vif->next_mode != AP_NETWORK)
2458                 return -EOPNOTSUPP;
2459
2460         return ath6kl_set_ies(vif, beacon);
2461 }
2462
2463 static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
2464 {
2465         struct ath6kl *ar = ath6kl_priv(dev);
2466         struct ath6kl_vif *vif = netdev_priv(dev);
2467
2468         if (vif->nw_type != AP_NETWORK)
2469                 return -EOPNOTSUPP;
2470         if (!test_bit(CONNECTED, &vif->flags))
2471                 return -ENOTCONN;
2472
2473         ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
2474         clear_bit(CONNECTED, &vif->flags);
2475
2476         return 0;
2477 }
2478
2479 static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2480
2481 static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2482                               u8 *mac)
2483 {
2484         struct ath6kl *ar = ath6kl_priv(dev);
2485         struct ath6kl_vif *vif = netdev_priv(dev);
2486         const u8 *addr = mac ? mac : bcast_addr;
2487
2488         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2489                                       addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2490 }
2491
2492 static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2493                                  u8 *mac, struct station_parameters *params)
2494 {
2495         struct ath6kl *ar = ath6kl_priv(dev);
2496         struct ath6kl_vif *vif = netdev_priv(dev);
2497
2498         if (vif->nw_type != AP_NETWORK)
2499                 return -EOPNOTSUPP;
2500
2501         /* Use this only for authorizing/unauthorizing a station */
2502         if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
2503                 return -EOPNOTSUPP;
2504
2505         if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
2506                 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2507                                               WMI_AP_MLME_AUTHORIZE, mac, 0);
2508         return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
2509                                       WMI_AP_MLME_UNAUTHORIZE, mac, 0);
2510 }
2511
2512 static int ath6kl_remain_on_channel(struct wiphy *wiphy,
2513                                     struct net_device *dev,
2514                                     struct ieee80211_channel *chan,
2515                                     enum nl80211_channel_type channel_type,
2516                                     unsigned int duration,
2517                                     u64 *cookie)
2518 {
2519         struct ath6kl *ar = ath6kl_priv(dev);
2520         struct ath6kl_vif *vif = netdev_priv(dev);
2521         u32 id;
2522
2523         /* TODO: if already pending or ongoing remain-on-channel,
2524          * return -EBUSY */
2525         id = ++vif->last_roc_id;
2526         if (id == 0) {
2527                 /* Do not use 0 as the cookie value */
2528                 id = ++vif->last_roc_id;
2529         }
2530         *cookie = id;
2531
2532         return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
2533                                              chan->center_freq, duration);
2534 }
2535
2536 static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
2537                                            struct net_device *dev,
2538                                            u64 cookie)
2539 {
2540         struct ath6kl *ar = ath6kl_priv(dev);
2541         struct ath6kl_vif *vif = netdev_priv(dev);
2542
2543         if (cookie != vif->last_roc_id)
2544                 return -ENOENT;
2545         vif->last_cancel_roc_id = cookie;
2546
2547         return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
2548 }
2549
2550 static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
2551                                      const u8 *buf, size_t len,
2552                                      unsigned int freq)
2553 {
2554         struct ath6kl *ar = vif->ar;
2555         const u8 *pos;
2556         u8 *p2p;
2557         int p2p_len;
2558         int ret;
2559         const struct ieee80211_mgmt *mgmt;
2560
2561         mgmt = (const struct ieee80211_mgmt *) buf;
2562
2563         /* Include P2P IE(s) from the frame generated in user space. */
2564
2565         p2p = kmalloc(len, GFP_KERNEL);
2566         if (p2p == NULL)
2567                 return -ENOMEM;
2568         p2p_len = 0;
2569
2570         pos = mgmt->u.probe_resp.variable;
2571         while (pos + 1 < buf + len) {
2572                 if (pos + 2 + pos[1] > buf + len)
2573                         break;
2574                 if (ath6kl_is_p2p_ie(pos)) {
2575                         memcpy(p2p + p2p_len, pos, 2 + pos[1]);
2576                         p2p_len += 2 + pos[1];
2577                 }
2578                 pos += 2 + pos[1];
2579         }
2580
2581         ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
2582                                                  mgmt->da, p2p, p2p_len);
2583         kfree(p2p);
2584         return ret;
2585 }
2586
2587 static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
2588                           struct ieee80211_channel *chan, bool offchan,
2589                           enum nl80211_channel_type channel_type,
2590                           bool channel_type_valid, unsigned int wait,
2591                           const u8 *buf, size_t len, bool no_cck,
2592                           bool dont_wait_for_ack, u64 *cookie)
2593 {
2594         struct ath6kl *ar = ath6kl_priv(dev);
2595         struct ath6kl_vif *vif = netdev_priv(dev);
2596         u32 id;
2597         const struct ieee80211_mgmt *mgmt;
2598
2599         mgmt = (const struct ieee80211_mgmt *) buf;
2600         if (buf + len >= mgmt->u.probe_resp.variable &&
2601             vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
2602             ieee80211_is_probe_resp(mgmt->frame_control)) {
2603                 /*
2604                  * Send Probe Response frame in AP mode using a separate WMI
2605                  * command to allow the target to fill in the generic IEs.
2606                  */
2607                 *cookie = 0; /* TX status not supported */
2608                 return ath6kl_send_go_probe_resp(vif, buf, len,
2609                                                  chan->center_freq);
2610         }
2611
2612         id = vif->send_action_id++;
2613         if (id == 0) {
2614                 /*
2615                  * 0 is a reserved value in the WMI command and shall not be
2616                  * used for the command.
2617                  */
2618                 id = vif->send_action_id++;
2619         }
2620
2621         *cookie = id;
2622
2623         if (test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
2624                     ar->fw_capabilities)) {
2625                 /*
2626                  * If capable of doing P2P mgmt operations using
2627                  * station interface, send additional information like
2628                  * supported rates to advertise and xmit rates for
2629                  * probe requests
2630                  */
2631                 return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
2632                                                 chan->center_freq, wait,
2633                                                 buf, len, no_cck);
2634         } else {
2635                 return ath6kl_wmi_send_action_cmd(ar->wmi, vif->fw_vif_idx, id,
2636                                                   chan->center_freq, wait,
2637                                                   buf, len);
2638         }
2639 }
2640
2641 static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
2642                                        struct net_device *dev,
2643                                        u16 frame_type, bool reg)
2644 {
2645         struct ath6kl_vif *vif = netdev_priv(dev);
2646
2647         ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
2648                    __func__, frame_type, reg);
2649         if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
2650                 /*
2651                  * Note: This notification callback is not allowed to sleep, so
2652                  * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
2653                  * hardcode target to report Probe Request frames all the time.
2654                  */
2655                 vif->probe_req_report = reg;
2656         }
2657 }
2658
2659 static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
2660                         struct net_device *dev,
2661                         struct cfg80211_sched_scan_request *request)
2662 {
2663         struct ath6kl *ar = ath6kl_priv(dev);
2664         struct ath6kl_vif *vif = netdev_priv(dev);
2665         u16 interval;
2666         int ret;
2667         u8 i;
2668
2669         if (ar->state != ATH6KL_STATE_ON)
2670                 return -EIO;
2671
2672         if (vif->sme_state != SME_DISCONNECTED)
2673                 return -EBUSY;
2674
2675         for (i = 0; i < ar->wiphy->max_sched_scan_ssids; i++) {
2676                 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
2677                                           i, DISABLE_SSID_FLAG,
2678                                           0, NULL);
2679         }
2680
2681         /* fw uses seconds, also make sure that it's >0 */
2682         interval = max_t(u16, 1, request->interval / 1000);
2683
2684         ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2685                                   interval, interval,
2686                                   10, 0, 0, 0, 3, 0, 0, 0);
2687
2688         if (request->n_ssids && request->ssids[0].ssid_len) {
2689                 for (i = 0; i < request->n_ssids; i++) {
2690                         ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
2691                                                   i, SPECIFIC_SSID_FLAG,
2692                                                   request->ssids[i].ssid_len,
2693                                                   request->ssids[i].ssid);
2694                 }
2695         }
2696
2697         ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2698                                           ATH6KL_WOW_MODE_ENABLE,
2699                                           WOW_FILTER_SSID,
2700                                           WOW_HOST_REQ_DELAY);
2701         if (ret) {
2702                 ath6kl_warn("Failed to enable wow with ssid filter: %d\n", ret);
2703                 return ret;
2704         }
2705
2706         /* this also clears IE in fw if it's not set */
2707         ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2708                                        WMI_FRAME_PROBE_REQ,
2709                                        request->ie, request->ie_len);
2710         if (ret) {
2711                 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d",
2712                             ret);
2713                 return ret;
2714         }
2715
2716         ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2717                                                  ATH6KL_HOST_MODE_ASLEEP);
2718         if (ret) {
2719                 ath6kl_warn("Failed to enable host sleep mode for sched scan: %d\n",
2720                             ret);
2721                 return ret;
2722         }
2723
2724         ar->state = ATH6KL_STATE_SCHED_SCAN;
2725
2726         return ret;
2727 }
2728
2729 static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
2730                                       struct net_device *dev)
2731 {
2732         struct ath6kl_vif *vif = netdev_priv(dev);
2733         bool stopped;
2734
2735         stopped = __ath6kl_cfg80211_sscan_stop(vif);
2736
2737         if (!stopped)
2738                 return -EIO;
2739
2740         return 0;
2741 }
2742
2743 static const struct ieee80211_txrx_stypes
2744 ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
2745         [NL80211_IFTYPE_STATION] = {
2746                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2747                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2748                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2749                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2750         },
2751         [NL80211_IFTYPE_AP] = {
2752                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2753                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2754                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2755                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2756         },
2757         [NL80211_IFTYPE_P2P_CLIENT] = {
2758                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2759                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2760                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2761                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2762         },
2763         [NL80211_IFTYPE_P2P_GO] = {
2764                 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2765                 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
2766                 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
2767                 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
2768         },
2769 };
2770
2771 static struct cfg80211_ops ath6kl_cfg80211_ops = {
2772         .add_virtual_intf = ath6kl_cfg80211_add_iface,
2773         .del_virtual_intf = ath6kl_cfg80211_del_iface,
2774         .change_virtual_intf = ath6kl_cfg80211_change_iface,
2775         .scan = ath6kl_cfg80211_scan,
2776         .connect = ath6kl_cfg80211_connect,
2777         .disconnect = ath6kl_cfg80211_disconnect,
2778         .add_key = ath6kl_cfg80211_add_key,
2779         .get_key = ath6kl_cfg80211_get_key,
2780         .del_key = ath6kl_cfg80211_del_key,
2781         .set_default_key = ath6kl_cfg80211_set_default_key,
2782         .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
2783         .set_tx_power = ath6kl_cfg80211_set_txpower,
2784         .get_tx_power = ath6kl_cfg80211_get_txpower,
2785         .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
2786         .join_ibss = ath6kl_cfg80211_join_ibss,
2787         .leave_ibss = ath6kl_cfg80211_leave_ibss,
2788         .get_station = ath6kl_get_station,
2789         .set_pmksa = ath6kl_set_pmksa,
2790         .del_pmksa = ath6kl_del_pmksa,
2791         .flush_pmksa = ath6kl_flush_pmksa,
2792         CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
2793 #ifdef CONFIG_PM
2794         .suspend = __ath6kl_cfg80211_suspend,
2795         .resume = __ath6kl_cfg80211_resume,
2796 #endif
2797         .set_channel = ath6kl_set_channel,
2798         .start_ap = ath6kl_start_ap,
2799         .change_beacon = ath6kl_change_beacon,
2800         .stop_ap = ath6kl_stop_ap,
2801         .del_station = ath6kl_del_station,
2802         .change_station = ath6kl_change_station,
2803         .remain_on_channel = ath6kl_remain_on_channel,
2804         .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
2805         .mgmt_tx = ath6kl_mgmt_tx,
2806         .mgmt_frame_register = ath6kl_mgmt_frame_register,
2807         .sched_scan_start = ath6kl_cfg80211_sscan_start,
2808         .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
2809 };
2810
2811 void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
2812 {
2813         ath6kl_cfg80211_sscan_disable(vif);
2814
2815         switch (vif->sme_state) {
2816         case SME_DISCONNECTED:
2817                 break;
2818         case SME_CONNECTING:
2819                 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
2820                                         NULL, 0,
2821                                         WLAN_STATUS_UNSPECIFIED_FAILURE,
2822                                         GFP_KERNEL);
2823                 break;
2824         case SME_CONNECTED:
2825                 cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
2826                 break;
2827         }
2828
2829         if (test_bit(CONNECTED, &vif->flags) ||
2830             test_bit(CONNECT_PEND, &vif->flags))
2831                 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
2832
2833         vif->sme_state = SME_DISCONNECTED;
2834         clear_bit(CONNECTED, &vif->flags);
2835         clear_bit(CONNECT_PEND, &vif->flags);
2836
2837         /* disable scanning */
2838         if (ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
2839                                       0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
2840                 ath6kl_warn("failed to disable scan during stop\n");
2841
2842         ath6kl_cfg80211_scan_complete_event(vif, true);
2843 }
2844
2845 void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
2846 {
2847         struct ath6kl_vif *vif;
2848
2849         vif = ath6kl_vif_first(ar);
2850         if (!vif) {
2851                 /* save the current power mode before enabling power save */
2852                 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2853
2854                 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
2855                         ath6kl_warn("ath6kl_deep_sleep_enable: "
2856                                     "wmi_powermode_cmd failed\n");
2857                 return;
2858         }
2859
2860         /*
2861          * FIXME: we should take ar->list_lock to protect changes in the
2862          * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
2863          * sleeps.
2864          */
2865         list_for_each_entry(vif, &ar->vif_list, list)
2866                 ath6kl_cfg80211_stop(vif);
2867 }
2868
2869 static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
2870 {
2871         vif->aggr_cntxt = aggr_init(vif);
2872         if (!vif->aggr_cntxt) {
2873                 ath6kl_err("failed to initialize aggr\n");
2874                 return -ENOMEM;
2875         }
2876
2877         setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
2878                     (unsigned long) vif->ndev);
2879         setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
2880                     (unsigned long) vif);
2881
2882         set_bit(WMM_ENABLED, &vif->flags);
2883         spin_lock_init(&vif->if_lock);
2884
2885         INIT_LIST_HEAD(&vif->mc_filter);
2886
2887         return 0;
2888 }
2889
2890 void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
2891 {
2892         struct ath6kl *ar = vif->ar;
2893         struct ath6kl_mc_filter *mc_filter, *tmp;
2894
2895         aggr_module_destroy(vif->aggr_cntxt);
2896
2897         ar->avail_idx_map |= BIT(vif->fw_vif_idx);
2898
2899         if (vif->nw_type == ADHOC_NETWORK)
2900                 ar->ibss_if_active = false;
2901
2902         list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
2903                 list_del(&mc_filter->list);
2904                 kfree(mc_filter);
2905         }
2906
2907         unregister_netdevice(vif->ndev);
2908
2909         ar->num_vif--;
2910 }
2911
2912 struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
2913                                         enum nl80211_iftype type, u8 fw_vif_idx,
2914                                         u8 nw_type)
2915 {
2916         struct net_device *ndev;
2917         struct ath6kl_vif *vif;
2918
2919         ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
2920         if (!ndev)
2921                 return NULL;
2922
2923         vif = netdev_priv(ndev);
2924         ndev->ieee80211_ptr = &vif->wdev;
2925         vif->wdev.wiphy = ar->wiphy;
2926         vif->ar = ar;
2927         vif->ndev = ndev;
2928         SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
2929         vif->wdev.netdev = ndev;
2930         vif->wdev.iftype = type;
2931         vif->fw_vif_idx = fw_vif_idx;
2932         vif->nw_type = vif->next_mode = nw_type;
2933
2934         memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
2935         if (fw_vif_idx != 0)
2936                 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
2937                                      0x2;
2938
2939         init_netdev(ndev);
2940
2941         ath6kl_init_control_info(vif);
2942
2943         if (ath6kl_cfg80211_vif_init(vif))
2944                 goto err;
2945
2946         if (register_netdevice(ndev))
2947                 goto err;
2948
2949         ar->avail_idx_map &= ~BIT(fw_vif_idx);
2950         vif->sme_state = SME_DISCONNECTED;
2951         set_bit(WLAN_ENABLED, &vif->flags);
2952         ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
2953         set_bit(NETDEV_REGISTERED, &vif->flags);
2954
2955         if (type == NL80211_IFTYPE_ADHOC)
2956                 ar->ibss_if_active = true;
2957
2958         spin_lock_bh(&ar->list_lock);
2959         list_add_tail(&vif->list, &ar->vif_list);
2960         spin_unlock_bh(&ar->list_lock);
2961
2962         return ndev;
2963
2964 err:
2965         aggr_module_destroy(vif->aggr_cntxt);
2966         free_netdev(ndev);
2967         return NULL;
2968 }
2969
2970 int ath6kl_cfg80211_init(struct ath6kl *ar)
2971 {
2972         struct wiphy *wiphy = ar->wiphy;
2973         int ret;
2974
2975         wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
2976
2977         wiphy->max_remain_on_channel_duration = 5000;
2978
2979         /* set device pointer for wiphy */
2980         set_wiphy_dev(wiphy, ar->dev);
2981
2982         wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
2983                                  BIT(NL80211_IFTYPE_ADHOC) |
2984                                  BIT(NL80211_IFTYPE_AP);
2985         if (ar->p2p) {
2986                 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
2987                                           BIT(NL80211_IFTYPE_P2P_CLIENT);
2988         }
2989
2990         /* max num of ssids that can be probed during scanning */
2991         wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2992         wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2993         wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2994         wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2995         wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
2996
2997         wiphy->cipher_suites = cipher_suites;
2998         wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
2999
3000         wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
3001                               WIPHY_WOWLAN_DISCONNECT |
3002                               WIPHY_WOWLAN_GTK_REKEY_FAILURE  |
3003                               WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3004                               WIPHY_WOWLAN_EAP_IDENTITY_REQ   |
3005                               WIPHY_WOWLAN_4WAY_HANDSHAKE;
3006         wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
3007         wiphy->wowlan.pattern_min_len = 1;
3008         wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
3009
3010         wiphy->max_sched_scan_ssids = 10;
3011
3012         ret = wiphy_register(wiphy);
3013         if (ret < 0) {
3014                 ath6kl_err("couldn't register wiphy device\n");
3015                 return ret;
3016         }
3017
3018         return 0;
3019 }
3020
3021 void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
3022 {
3023         wiphy_unregister(ar->wiphy);
3024 }
3025
3026 struct ath6kl *ath6kl_cfg80211_create(void)
3027 {
3028         struct ath6kl *ar;
3029         struct wiphy *wiphy;
3030
3031         /* create a new wiphy for use with cfg80211 */
3032         wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
3033
3034         if (!wiphy) {
3035                 ath6kl_err("couldn't allocate wiphy device\n");
3036                 return NULL;
3037         }
3038
3039         ar = wiphy_priv(wiphy);
3040         ar->wiphy = wiphy;
3041
3042         return ar;
3043 }
3044
3045 /* Note: ar variable must not be accessed after calling this! */
3046 void ath6kl_cfg80211_destroy(struct ath6kl *ar)
3047 {
3048         int i;
3049
3050         for (i = 0; i < AP_MAX_NUM_STA; i++)
3051                 kfree(ar->sta_list[i].aggr_conn);
3052
3053         wiphy_free(ar->wiphy);
3054 }
3055