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