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