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