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