cfg80211: fix radar check for P2P_DEVICE
[linux-2.6-block.git] / drivers / net / wireless / ath / ath6kl / cfg80211.c
CommitLineData
bdcd8170
KV
1/*
2 * Copyright (c) 2004-2011 Atheros Communications Inc.
1b2df407 3 * Copyright (c) 2011-2012 Qualcomm Atheros, Inc.
bdcd8170
KV
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
516304b0
JP
18#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
19
6eb07caf 20#include <linux/moduleparam.h>
c08631c6 21#include <linux/inetdevice.h>
d6a434d6 22#include <linux/export.h>
6eb07caf 23
bdcd8170
KV
24#include "core.h"
25#include "cfg80211.h"
26#include "debug.h"
abcb344b 27#include "hif-ops.h"
003353b0 28#include "testmode.h"
bdcd8170
KV
29
30#define RATETAB_ENT(_rate, _rateid, _flags) { \
31 .bitrate = (_rate), \
32 .flags = (_flags), \
33 .hw_value = (_rateid), \
34}
35
36#define CHAN2G(_channel, _freq, _flags) { \
37 .band = IEEE80211_BAND_2GHZ, \
38 .hw_value = (_channel), \
39 .center_freq = (_freq), \
40 .flags = (_flags), \
41 .max_antenna_gain = 0, \
42 .max_power = 30, \
43}
44
45#define CHAN5G(_channel, _flags) { \
46 .band = IEEE80211_BAND_5GHZ, \
47 .hw_value = (_channel), \
48 .center_freq = 5000 + (5 * (_channel)), \
49 .flags = (_flags), \
50 .max_antenna_gain = 0, \
51 .max_power = 30, \
52}
53
f599359c
BS
54#define DEFAULT_BG_SCAN_PERIOD 60
55
dd45b759
NS
56struct ath6kl_cfg80211_match_probe_ssid {
57 struct cfg80211_ssid ssid;
58 u8 flag;
59};
60
bdcd8170
KV
61static struct ieee80211_rate ath6kl_rates[] = {
62 RATETAB_ENT(10, 0x1, 0),
63 RATETAB_ENT(20, 0x2, 0),
64 RATETAB_ENT(55, 0x4, 0),
65 RATETAB_ENT(110, 0x8, 0),
66 RATETAB_ENT(60, 0x10, 0),
67 RATETAB_ENT(90, 0x20, 0),
68 RATETAB_ENT(120, 0x40, 0),
69 RATETAB_ENT(180, 0x80, 0),
70 RATETAB_ENT(240, 0x100, 0),
71 RATETAB_ENT(360, 0x200, 0),
72 RATETAB_ENT(480, 0x400, 0),
73 RATETAB_ENT(540, 0x800, 0),
74};
75
76#define ath6kl_a_rates (ath6kl_rates + 4)
77#define ath6kl_a_rates_size 8
78#define ath6kl_g_rates (ath6kl_rates + 0)
79#define ath6kl_g_rates_size 12
80
bed56e31
VT
81#define ath6kl_g_htcap IEEE80211_HT_CAP_SGI_20
82#define ath6kl_a_htcap (IEEE80211_HT_CAP_SUP_WIDTH_20_40 | \
faaf1929
VT
83 IEEE80211_HT_CAP_SGI_20 | \
84 IEEE80211_HT_CAP_SGI_40)
85
bdcd8170
KV
86static struct ieee80211_channel ath6kl_2ghz_channels[] = {
87 CHAN2G(1, 2412, 0),
88 CHAN2G(2, 2417, 0),
89 CHAN2G(3, 2422, 0),
90 CHAN2G(4, 2427, 0),
91 CHAN2G(5, 2432, 0),
92 CHAN2G(6, 2437, 0),
93 CHAN2G(7, 2442, 0),
94 CHAN2G(8, 2447, 0),
95 CHAN2G(9, 2452, 0),
96 CHAN2G(10, 2457, 0),
97 CHAN2G(11, 2462, 0),
98 CHAN2G(12, 2467, 0),
99 CHAN2G(13, 2472, 0),
100 CHAN2G(14, 2484, 0),
101};
102
103static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
104 CHAN5G(34, 0), CHAN5G(36, 0),
105 CHAN5G(38, 0), CHAN5G(40, 0),
106 CHAN5G(42, 0), CHAN5G(44, 0),
107 CHAN5G(46, 0), CHAN5G(48, 0),
108 CHAN5G(52, 0), CHAN5G(56, 0),
109 CHAN5G(60, 0), CHAN5G(64, 0),
110 CHAN5G(100, 0), CHAN5G(104, 0),
111 CHAN5G(108, 0), CHAN5G(112, 0),
112 CHAN5G(116, 0), CHAN5G(120, 0),
113 CHAN5G(124, 0), CHAN5G(128, 0),
114 CHAN5G(132, 0), CHAN5G(136, 0),
115 CHAN5G(140, 0), CHAN5G(149, 0),
116 CHAN5G(153, 0), CHAN5G(157, 0),
117 CHAN5G(161, 0), CHAN5G(165, 0),
118 CHAN5G(184, 0), CHAN5G(188, 0),
119 CHAN5G(192, 0), CHAN5G(196, 0),
120 CHAN5G(200, 0), CHAN5G(204, 0),
121 CHAN5G(208, 0), CHAN5G(212, 0),
122 CHAN5G(216, 0),
123};
124
125static struct ieee80211_supported_band ath6kl_band_2ghz = {
126 .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
127 .channels = ath6kl_2ghz_channels,
128 .n_bitrates = ath6kl_g_rates_size,
129 .bitrates = ath6kl_g_rates,
faaf1929
VT
130 .ht_cap.cap = ath6kl_g_htcap,
131 .ht_cap.ht_supported = true,
bdcd8170
KV
132};
133
134static struct ieee80211_supported_band ath6kl_band_5ghz = {
135 .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
136 .channels = ath6kl_5ghz_a_channels,
137 .n_bitrates = ath6kl_a_rates_size,
138 .bitrates = ath6kl_a_rates,
bed56e31 139 .ht_cap.cap = ath6kl_a_htcap,
faaf1929 140 .ht_cap.ht_supported = true,
bdcd8170
KV
141};
142
837cb97e
JM
143#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
144
10509f90
KV
145/* returns true if scheduled scan was stopped */
146static bool __ath6kl_cfg80211_sscan_stop(struct ath6kl_vif *vif)
147{
148 struct ath6kl *ar = vif->ar;
149
b1f47e3a 150 if (!test_and_clear_bit(SCHED_SCANNING, &vif->flags))
10509f90
KV
151 return false;
152
153 del_timer_sync(&vif->sched_scan_timer);
154
58109df6
VT
155 if (ar->state == ATH6KL_STATE_RECOVERY)
156 return true;
10509f90 157
b1f47e3a 158 ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, false);
10509f90
KV
159
160 return true;
161}
162
163static void ath6kl_cfg80211_sscan_disable(struct ath6kl_vif *vif)
164{
165 struct ath6kl *ar = vif->ar;
166 bool stopped;
167
168 stopped = __ath6kl_cfg80211_sscan_stop(vif);
169
170 if (!stopped)
171 return;
172
173 cfg80211_sched_scan_stopped(ar->wiphy);
174}
175
240d2799 176static int ath6kl_set_wpa_version(struct ath6kl_vif *vif,
bdcd8170
KV
177 enum nl80211_wpa_versions wpa_version)
178{
179 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
180
181 if (!wpa_version) {
3450334f 182 vif->auth_mode = NONE_AUTH;
bdcd8170 183 } else if (wpa_version & NL80211_WPA_VERSION_2) {
3450334f 184 vif->auth_mode = WPA2_AUTH;
bdcd8170 185 } else if (wpa_version & NL80211_WPA_VERSION_1) {
3450334f 186 vif->auth_mode = WPA_AUTH;
bdcd8170
KV
187 } else {
188 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
189 return -ENOTSUPP;
190 }
191
192 return 0;
193}
194
240d2799 195static int ath6kl_set_auth_type(struct ath6kl_vif *vif,
bdcd8170
KV
196 enum nl80211_auth_type auth_type)
197{
bdcd8170
KV
198 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
199
200 switch (auth_type) {
201 case NL80211_AUTHTYPE_OPEN_SYSTEM:
3450334f 202 vif->dot11_auth_mode = OPEN_AUTH;
bdcd8170
KV
203 break;
204 case NL80211_AUTHTYPE_SHARED_KEY:
3450334f 205 vif->dot11_auth_mode = SHARED_AUTH;
bdcd8170
KV
206 break;
207 case NL80211_AUTHTYPE_NETWORK_EAP:
3450334f 208 vif->dot11_auth_mode = LEAP_AUTH;
bdcd8170
KV
209 break;
210
211 case NL80211_AUTHTYPE_AUTOMATIC:
3450334f 212 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
bdcd8170
KV
213 break;
214
215 default:
3c325fbd 216 ath6kl_err("%s: 0x%x not supported\n", __func__, auth_type);
bdcd8170
KV
217 return -ENOTSUPP;
218 }
219
220 return 0;
221}
222
240d2799 223static int ath6kl_set_cipher(struct ath6kl_vif *vif, u32 cipher, bool ucast)
bdcd8170 224{
3450334f
VT
225 u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
226 u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
227 &vif->grp_crypto_len;
bdcd8170
KV
228
229 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
230 __func__, cipher, ucast);
231
232 switch (cipher) {
233 case 0:
234 /* our own hack to use value 0 as no crypto used */
235 *ar_cipher = NONE_CRYPT;
236 *ar_cipher_len = 0;
237 break;
238 case WLAN_CIPHER_SUITE_WEP40:
239 *ar_cipher = WEP_CRYPT;
240 *ar_cipher_len = 5;
241 break;
242 case WLAN_CIPHER_SUITE_WEP104:
243 *ar_cipher = WEP_CRYPT;
244 *ar_cipher_len = 13;
245 break;
246 case WLAN_CIPHER_SUITE_TKIP:
247 *ar_cipher = TKIP_CRYPT;
248 *ar_cipher_len = 0;
249 break;
250 case WLAN_CIPHER_SUITE_CCMP:
251 *ar_cipher = AES_CRYPT;
252 *ar_cipher_len = 0;
253 break;
5e07021e
DS
254 case WLAN_CIPHER_SUITE_SMS4:
255 *ar_cipher = WAPI_CRYPT;
256 *ar_cipher_len = 0;
257 break;
bdcd8170
KV
258 default:
259 ath6kl_err("cipher 0x%x not supported\n", cipher);
260 return -ENOTSUPP;
261 }
262
263 return 0;
264}
265
240d2799 266static void ath6kl_set_key_mgmt(struct ath6kl_vif *vif, u32 key_mgmt)
bdcd8170
KV
267{
268 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
269
270 if (key_mgmt == WLAN_AKM_SUITE_PSK) {
3450334f
VT
271 if (vif->auth_mode == WPA_AUTH)
272 vif->auth_mode = WPA_PSK_AUTH;
273 else if (vif->auth_mode == WPA2_AUTH)
274 vif->auth_mode = WPA2_PSK_AUTH;
837cb97e 275 } else if (key_mgmt == 0x00409600) {
3450334f
VT
276 if (vif->auth_mode == WPA_AUTH)
277 vif->auth_mode = WPA_AUTH_CCKM;
278 else if (vif->auth_mode == WPA2_AUTH)
279 vif->auth_mode = WPA2_AUTH_CCKM;
bdcd8170 280 } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
3450334f 281 vif->auth_mode = NONE_AUTH;
bdcd8170
KV
282 }
283}
284
990bd915 285static bool ath6kl_cfg80211_ready(struct ath6kl_vif *vif)
bdcd8170 286{
990bd915 287 struct ath6kl *ar = vif->ar;
59c98449 288
bdcd8170
KV
289 if (!test_bit(WMI_READY, &ar->flag)) {
290 ath6kl_err("wmi is not ready\n");
291 return false;
292 }
293
59c98449 294 if (!test_bit(WLAN_ENABLED, &vif->flags)) {
bdcd8170
KV
295 ath6kl_err("wlan disabled\n");
296 return false;
297 }
298
299 return true;
300}
301
6981ffdc
KF
302static bool ath6kl_is_wpa_ie(const u8 *pos)
303{
04b2312a 304 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
6981ffdc
KF
305 pos[2] == 0x00 && pos[3] == 0x50 &&
306 pos[4] == 0xf2 && pos[5] == 0x01;
307}
308
309static bool ath6kl_is_rsn_ie(const u8 *pos)
310{
311 return pos[0] == WLAN_EID_RSN;
312}
313
63541212
AT
314static bool ath6kl_is_wps_ie(const u8 *pos)
315{
316 return (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
317 pos[1] >= 4 &&
318 pos[2] == 0x00 && pos[3] == 0x50 && pos[4] == 0xf2 &&
319 pos[5] == 0x04);
320}
321
334234b5
VT
322static int ath6kl_set_assoc_req_ies(struct ath6kl_vif *vif, const u8 *ies,
323 size_t ies_len)
6981ffdc 324{
334234b5 325 struct ath6kl *ar = vif->ar;
6981ffdc
KF
326 const u8 *pos;
327 u8 *buf = NULL;
328 size_t len = 0;
329 int ret;
330
63541212
AT
331 /*
332 * Clear previously set flag
333 */
334
335 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
336
6981ffdc
KF
337 /*
338 * Filter out RSN/WPA IE(s)
339 */
340
341 if (ies && ies_len) {
342 buf = kmalloc(ies_len, GFP_KERNEL);
343 if (buf == NULL)
344 return -ENOMEM;
345 pos = ies;
346
347 while (pos + 1 < ies + ies_len) {
348 if (pos + 2 + pos[1] > ies + ies_len)
349 break;
350 if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
351 memcpy(buf + len, pos, 2 + pos[1]);
352 len += 2 + pos[1];
353 }
63541212
AT
354
355 if (ath6kl_is_wps_ie(pos))
356 ar->connect_ctrl_flags |= CONNECT_WPS_FLAG;
357
6981ffdc
KF
358 pos += 2 + pos[1];
359 }
360 }
361
334234b5
VT
362 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
363 WMI_FRAME_ASSOC_REQ, buf, len);
6981ffdc
KF
364 kfree(buf);
365 return ret;
366}
367
55055976
VT
368static int ath6kl_nliftype_to_drv_iftype(enum nl80211_iftype type, u8 *nw_type)
369{
370 switch (type) {
371 case NL80211_IFTYPE_STATION:
38142644 372 case NL80211_IFTYPE_P2P_CLIENT:
55055976
VT
373 *nw_type = INFRA_NETWORK;
374 break;
375 case NL80211_IFTYPE_ADHOC:
376 *nw_type = ADHOC_NETWORK;
377 break;
378 case NL80211_IFTYPE_AP:
55055976
VT
379 case NL80211_IFTYPE_P2P_GO:
380 *nw_type = AP_NETWORK;
381 break;
382 default:
383 ath6kl_err("invalid interface type %u\n", type);
384 return -ENOTSUPP;
385 }
386
387 return 0;
388}
389
390static bool ath6kl_is_valid_iftype(struct ath6kl *ar, enum nl80211_iftype type,
391 u8 *if_idx, u8 *nw_type)
392{
393 int i;
394
395 if (ath6kl_nliftype_to_drv_iftype(type, nw_type))
396 return false;
397
398 if (ar->ibss_if_active || ((type == NL80211_IFTYPE_ADHOC) &&
96f1fadc 399 ar->num_vif))
55055976
VT
400 return false;
401
402 if (type == NL80211_IFTYPE_STATION ||
403 type == NL80211_IFTYPE_AP || type == NL80211_IFTYPE_ADHOC) {
71f96ee6 404 for (i = 0; i < ar->vif_max; i++) {
55055976
VT
405 if ((ar->avail_idx_map >> i) & BIT(0)) {
406 *if_idx = i;
407 return true;
408 }
409 }
410 }
411
3226f68a
VT
412 if (type == NL80211_IFTYPE_P2P_CLIENT ||
413 type == NL80211_IFTYPE_P2P_GO) {
71f96ee6 414 for (i = ar->max_norm_iface; i < ar->vif_max; i++) {
3226f68a
VT
415 if ((ar->avail_idx_map >> i) & BIT(0)) {
416 *if_idx = i;
417 return true;
418 }
419 }
420 }
421
55055976
VT
422 return false;
423}
424
8c9bb054
KV
425static bool ath6kl_is_tx_pending(struct ath6kl *ar)
426{
427 return ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0;
428}
429
430
bdcd8170
KV
431static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
432 struct cfg80211_connect_params *sme)
433{
434 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 435 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170 436 int status;
3ca9d1fc 437 u8 nw_subtype = (ar->p2p) ? SUBTYPE_P2PDEV : SUBTYPE_NONE;
ce0dc0cf 438 u16 interval;
bdcd8170 439
10509f90
KV
440 ath6kl_cfg80211_sscan_disable(vif);
441
14ee6f6b 442 vif->sme_state = SME_CONNECTING;
bdcd8170 443
990bd915 444 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
445 return -EIO;
446
447 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
448 ath6kl_err("destroy in progress\n");
449 return -EBUSY;
450 }
451
452 if (test_bit(SKIP_SCAN, &ar->flag) &&
453 ((sme->channel && sme->channel->center_freq == 0) ||
454 (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
455 ath6kl_err("SkipScan: channel or bssid invalid\n");
456 return -EINVAL;
457 }
458
459 if (down_interruptible(&ar->sem)) {
460 ath6kl_err("busy, couldn't get access\n");
461 return -ERESTARTSYS;
462 }
463
464 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
465 ath6kl_err("busy, destroy in progress\n");
466 up(&ar->sem);
467 return -EBUSY;
468 }
469
470 if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
471 /*
472 * sleep until the command queue drains
473 */
474 wait_event_interruptible_timeout(ar->event_wq,
8c9bb054
KV
475 ath6kl_is_tx_pending(ar),
476 WMI_TIMEOUT);
bdcd8170
KV
477 if (signal_pending(current)) {
478 ath6kl_err("cmd queue drain timeout\n");
479 up(&ar->sem);
480 return -EINTR;
481 }
482 }
483
6e786cb1
JM
484 status = ath6kl_set_assoc_req_ies(vif, sme->ie, sme->ie_len);
485 if (status) {
486 up(&ar->sem);
487 return status;
488 }
489
490 if (sme->ie == NULL || sme->ie_len == 0)
542c519a 491 ar->connect_ctrl_flags &= ~CONNECT_WPS_FLAG;
6981ffdc 492
59c98449 493 if (test_bit(CONNECTED, &vif->flags) &&
3450334f
VT
494 vif->ssid_len == sme->ssid_len &&
495 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
cf5333d7 496 vif->reconnect_flag = true;
334234b5
VT
497 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->fw_vif_idx,
498 vif->req_bssid,
f74bac54 499 vif->ch_hint);
bdcd8170
KV
500
501 up(&ar->sem);
502 if (status) {
503 ath6kl_err("wmi_reconnect_cmd failed\n");
504 return -EIO;
505 }
506 return 0;
3450334f
VT
507 } else if (vif->ssid_len == sme->ssid_len &&
508 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
240d2799 509 ath6kl_disconnect(vif);
bdcd8170
KV
510 }
511
3450334f
VT
512 memset(vif->ssid, 0, sizeof(vif->ssid));
513 vif->ssid_len = sme->ssid_len;
514 memcpy(vif->ssid, sme->ssid, sme->ssid_len);
bdcd8170
KV
515
516 if (sme->channel)
f74bac54 517 vif->ch_hint = sme->channel->center_freq;
bdcd8170 518
8c8b65e3 519 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170 520 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
8c8b65e3 521 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
bdcd8170 522
240d2799 523 ath6kl_set_wpa_version(vif, sme->crypto.wpa_versions);
bdcd8170 524
240d2799 525 status = ath6kl_set_auth_type(vif, sme->auth_type);
bdcd8170
KV
526 if (status) {
527 up(&ar->sem);
528 return status;
529 }
530
531 if (sme->crypto.n_ciphers_pairwise)
240d2799 532 ath6kl_set_cipher(vif, sme->crypto.ciphers_pairwise[0], true);
bdcd8170 533 else
240d2799 534 ath6kl_set_cipher(vif, 0, true);
bdcd8170 535
240d2799 536 ath6kl_set_cipher(vif, sme->crypto.cipher_group, false);
bdcd8170
KV
537
538 if (sme->crypto.n_akm_suites)
240d2799 539 ath6kl_set_key_mgmt(vif, sme->crypto.akm_suites[0]);
bdcd8170
KV
540
541 if ((sme->key_len) &&
3450334f
VT
542 (vif->auth_mode == NONE_AUTH) &&
543 (vif->prwise_crypto == WEP_CRYPT)) {
bdcd8170
KV
544 struct ath6kl_key *key = NULL;
545
792ecb33 546 if (sme->key_idx > WMI_MAX_KEY_INDEX) {
bdcd8170
KV
547 ath6kl_err("key index %d out of bounds\n",
548 sme->key_idx);
549 up(&ar->sem);
550 return -ENOENT;
551 }
552
6f2a73f9 553 key = &vif->keys[sme->key_idx];
bdcd8170
KV
554 key->key_len = sme->key_len;
555 memcpy(key->key, sme->key, key->key_len);
3450334f
VT
556 key->cipher = vif->prwise_crypto;
557 vif->def_txkey_index = sme->key_idx;
bdcd8170 558
334234b5 559 ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, sme->key_idx,
3450334f 560 vif->prwise_crypto,
bdcd8170
KV
561 GROUP_USAGE | TX_USAGE,
562 key->key_len,
f4bb9a6f 563 NULL, 0,
bdcd8170
KV
564 key->key, KEY_OP_INIT_VAL, NULL,
565 NO_SYNC_WMIFLAG);
566 }
567
568 if (!ar->usr_bss_filter) {
59c98449 569 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
240d2799 570 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
96f1fadc 571 ALL_BSS_FILTER, 0) != 0) {
bdcd8170
KV
572 ath6kl_err("couldn't set bss filtering\n");
573 up(&ar->sem);
574 return -EIO;
575 }
576 }
577
f5938f24 578 vif->nw_type = vif->next_mode;
bdcd8170 579
c422d52d
TP
580 /* enable enhanced bmiss detection if applicable */
581 ath6kl_cfg80211_sta_bmiss_enhance(vif, true);
582
3ca9d1fc
AT
583 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_CLIENT)
584 nw_subtype = SUBTYPE_P2PCLIENT;
585
bdcd8170
KV
586 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
587 "%s: connect called with authmode %d dot11 auth %d"
588 " PW crypto %d PW crypto len %d GRP crypto %d"
589 " GRP crypto len %d channel hint %u\n",
590 __func__,
3450334f
VT
591 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
592 vif->prwise_crypto_len, vif->grp_crypto,
f74bac54 593 vif->grp_crypto_len, vif->ch_hint);
bdcd8170 594
cf5333d7 595 vif->reconnect_flag = 0;
ce0dc0cf
RM
596
597 if (vif->nw_type == INFRA_NETWORK) {
b5283871
KV
598 interval = max_t(u16, vif->listen_intvl_t,
599 ATH6KL_MAX_WOW_LISTEN_INTL);
ce0dc0cf
RM
600 status = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
601 interval,
602 0);
603 if (status) {
604 ath6kl_err("couldn't set listen intervel\n");
605 up(&ar->sem);
606 return status;
607 }
608 }
609
334234b5 610 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
3450334f
VT
611 vif->dot11_auth_mode, vif->auth_mode,
612 vif->prwise_crypto,
613 vif->prwise_crypto_len,
614 vif->grp_crypto, vif->grp_crypto_len,
615 vif->ssid_len, vif->ssid,
f74bac54 616 vif->req_bssid, vif->ch_hint,
3ca9d1fc 617 ar->connect_ctrl_flags, nw_subtype);
bdcd8170 618
f599359c
BS
619 /* disable background scan if period is 0 */
620 if (sme->bg_scan_period == 0)
621 sme->bg_scan_period = 0xffff;
622
623 /* configure default value if not specified */
624 if (sme->bg_scan_period == -1)
625 sme->bg_scan_period = DEFAULT_BG_SCAN_PERIOD;
626
627 ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx, 0, 0,
628 sme->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
629
bdcd8170
KV
630 up(&ar->sem);
631
632 if (status == -EINVAL) {
3450334f
VT
633 memset(vif->ssid, 0, sizeof(vif->ssid));
634 vif->ssid_len = 0;
bdcd8170
KV
635 ath6kl_err("invalid request\n");
636 return -ENOENT;
637 } else if (status) {
638 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
639 return -EIO;
640 }
641
642 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
ddc3d77c
KV
643 ((vif->auth_mode == WPA_PSK_AUTH) ||
644 (vif->auth_mode == WPA2_PSK_AUTH))) {
de3ad713 645 mod_timer(&vif->disconnect_timer,
bdcd8170
KV
646 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
647 }
648
649 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
59c98449 650 set_bit(CONNECT_PEND, &vif->flags);
bdcd8170
KV
651
652 return 0;
653}
654
5e13fd35
VT
655static struct cfg80211_bss *
656ath6kl_add_bss_if_needed(struct ath6kl_vif *vif,
657 enum network_type nw_type,
658 const u8 *bssid,
659 struct ieee80211_channel *chan,
660 const u8 *beacon_ie,
661 size_t beacon_ie_len)
01cac476 662{
240d2799 663 struct ath6kl *ar = vif->ar;
01cac476 664 struct cfg80211_bss *bss;
4eab6f4f 665 u16 cap_mask, cap_val;
01cac476
JM
666 u8 *ie;
667
4eab6f4f
RM
668 if (nw_type & ADHOC_NETWORK) {
669 cap_mask = WLAN_CAPABILITY_IBSS;
670 cap_val = WLAN_CAPABILITY_IBSS;
671 } else {
672 cap_mask = WLAN_CAPABILITY_ESS;
673 cap_val = WLAN_CAPABILITY_ESS;
674 }
675
be98e3a4 676 bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
4eab6f4f
RM
677 vif->ssid, vif->ssid_len,
678 cap_mask, cap_val);
01cac476
JM
679 if (bss == NULL) {
680 /*
681 * Since cfg80211 may not yet know about the BSS,
682 * generate a partial entry until the first BSS info
683 * event becomes available.
684 *
685 * Prepend SSID element since it is not included in the Beacon
686 * IEs from the target.
687 */
3450334f 688 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
01cac476 689 if (ie == NULL)
5e13fd35 690 return NULL;
01cac476 691 ie[0] = WLAN_EID_SSID;
3450334f
VT
692 ie[1] = vif->ssid_len;
693 memcpy(ie + 2, vif->ssid, vif->ssid_len);
694 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
be98e3a4 695 bss = cfg80211_inform_bss(ar->wiphy, chan,
4eab6f4f 696 bssid, 0, cap_val, 100,
3450334f 697 ie, 2 + vif->ssid_len + beacon_ie_len,
01cac476
JM
698 0, GFP_KERNEL);
699 if (bss)
cdeb8602
KV
700 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
701 "added bss %pM to cfg80211\n", bssid);
01cac476
JM
702 kfree(ie);
703 } else
5e13fd35 704 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss\n");
01cac476 705
5e13fd35 706 return bss;
01cac476
JM
707}
708
240d2799 709void ath6kl_cfg80211_connect_event(struct ath6kl_vif *vif, u16 channel,
bdcd8170
KV
710 u8 *bssid, u16 listen_intvl,
711 u16 beacon_intvl,
712 enum network_type nw_type,
713 u8 beacon_ie_len, u8 assoc_req_len,
714 u8 assoc_resp_len, u8 *assoc_info)
715{
01cac476 716 struct ieee80211_channel *chan;
240d2799 717 struct ath6kl *ar = vif->ar;
5e13fd35 718 struct cfg80211_bss *bss;
bdcd8170
KV
719
720 /* capinfo + listen interval */
721 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
722
723 /* capinfo + status code + associd */
724 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
725
726 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
727 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
728 assoc_resp_ie_offset;
729
730 assoc_req_len -= assoc_req_ie_offset;
731 assoc_resp_len -= assoc_resp_ie_offset;
732
32c10874
JM
733 /*
734 * Store Beacon interval here; DTIM period will be available only once
735 * a Beacon frame from the AP is seen.
736 */
cf5333d7 737 vif->assoc_bss_beacon_int = beacon_intvl;
59c98449 738 clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
32c10874 739
bdcd8170 740 if (nw_type & ADHOC_NETWORK) {
551959d8 741 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
bdcd8170
KV
742 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
743 "%s: ath6k not in ibss mode\n", __func__);
744 return;
745 }
746 }
747
748 if (nw_type & INFRA_NETWORK) {
551959d8
VT
749 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
750 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
751 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
752 "%s: ath6k not in station mode\n", __func__);
753 return;
754 }
755 }
756
be98e3a4 757 chan = ieee80211_get_channel(ar->wiphy, (int) channel);
bdcd8170 758
5e13fd35
VT
759 bss = ath6kl_add_bss_if_needed(vif, nw_type, bssid, chan,
760 assoc_info, beacon_ie_len);
761 if (!bss) {
4eab6f4f 762 ath6kl_err("could not add cfg80211 bss entry\n");
bdcd8170
KV
763 return;
764 }
765
4eab6f4f
RM
766 if (nw_type & ADHOC_NETWORK) {
767 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "ad-hoc %s selected\n",
768 nw_type & ADHOC_CREATOR ? "creator" : "joiner");
769 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
5e13fd35 770 cfg80211_put_bss(bss);
bdcd8170
KV
771 return;
772 }
773
14ee6f6b 774 if (vif->sme_state == SME_CONNECTING) {
bdcd8170 775 /* inform connect result to cfg80211 */
14ee6f6b 776 vif->sme_state = SME_CONNECTED;
240d2799 777 cfg80211_connect_result(vif->ndev, bssid,
bdcd8170
KV
778 assoc_req_ie, assoc_req_len,
779 assoc_resp_ie, assoc_resp_len,
780 WLAN_STATUS_SUCCESS, GFP_KERNEL);
5e13fd35 781 cfg80211_put_bss(bss);
14ee6f6b 782 } else if (vif->sme_state == SME_CONNECTED) {
bdcd8170 783 /* inform roam event to cfg80211 */
5e13fd35
VT
784 cfg80211_roamed_bss(vif->ndev, bss, assoc_req_ie, assoc_req_len,
785 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
bdcd8170
KV
786 }
787}
788
789static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
790 struct net_device *dev, u16 reason_code)
791{
d6d5c06c 792 struct ath6kl *ar = ath6kl_priv(dev);
3450334f 793 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
794
795 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
796 reason_code);
797
10509f90
KV
798 ath6kl_cfg80211_sscan_disable(vif);
799
990bd915 800 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
801 return -EIO;
802
803 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
804 ath6kl_err("busy, destroy in progress\n");
805 return -EBUSY;
806 }
807
808 if (down_interruptible(&ar->sem)) {
809 ath6kl_err("busy, couldn't get access\n");
810 return -ERESTARTSYS;
811 }
812
cf5333d7 813 vif->reconnect_flag = 0;
240d2799 814 ath6kl_disconnect(vif);
3450334f
VT
815 memset(vif->ssid, 0, sizeof(vif->ssid));
816 vif->ssid_len = 0;
bdcd8170
KV
817
818 if (!test_bit(SKIP_SCAN, &ar->flag))
8c8b65e3 819 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170
KV
820
821 up(&ar->sem);
822
14ee6f6b 823 vif->sme_state = SME_DISCONNECTED;
170826dd 824
bdcd8170
KV
825 return 0;
826}
827
240d2799 828void ath6kl_cfg80211_disconnect_event(struct ath6kl_vif *vif, u8 reason,
bdcd8170
KV
829 u8 *bssid, u8 assoc_resp_len,
830 u8 *assoc_info, u16 proto_reason)
831{
240d2799 832 struct ath6kl *ar = vif->ar;
59c98449 833
14ee6f6b
VT
834 if (vif->scan_req) {
835 cfg80211_scan_done(vif->scan_req, true);
836 vif->scan_req = NULL;
bdcd8170
KV
837 }
838
f5938f24 839 if (vif->nw_type & ADHOC_NETWORK) {
551959d8 840 if (vif->wdev.iftype != NL80211_IFTYPE_ADHOC) {
bdcd8170
KV
841 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
842 "%s: ath6k not in ibss mode\n", __func__);
843 return;
844 }
845 memset(bssid, 0, ETH_ALEN);
240d2799 846 cfg80211_ibss_joined(vif->ndev, bssid, GFP_KERNEL);
bdcd8170
KV
847 return;
848 }
849
f5938f24 850 if (vif->nw_type & INFRA_NETWORK) {
551959d8
VT
851 if (vif->wdev.iftype != NL80211_IFTYPE_STATION &&
852 vif->wdev.iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
853 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
854 "%s: ath6k not in station mode\n", __func__);
855 return;
856 }
857 }
858
59c98449 859 clear_bit(CONNECT_PEND, &vif->flags);
bdcd8170 860
14ee6f6b 861 if (vif->sme_state == SME_CONNECTING) {
240d2799 862 cfg80211_connect_result(vif->ndev,
96f1fadc
KV
863 bssid, NULL, 0,
864 NULL, 0,
865 WLAN_STATUS_UNSPECIFIED_FAILURE,
866 GFP_KERNEL);
14ee6f6b 867 } else if (vif->sme_state == SME_CONNECTED) {
33a6664a 868 cfg80211_disconnected(vif->ndev, proto_reason,
96f1fadc 869 NULL, 0, GFP_KERNEL);
bdcd8170
KV
870 }
871
14ee6f6b 872 vif->sme_state = SME_DISCONNECTED;
33a6664a
TP
873
874 /*
875 * Send a disconnect command to target when a disconnect event is
876 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
877 * request from host) to make the firmware stop trying to connect even
878 * after giving disconnect event. There will be one more disconnect
879 * event for this disconnect command with reason code DISCONNECT_CMD
880 * which won't be notified to cfg80211.
881 */
882 if (reason != DISCONNECT_CMD)
883 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
bdcd8170
KV
884}
885
3b8ffc6a
JM
886static int ath6kl_set_probed_ssids(struct ath6kl *ar,
887 struct ath6kl_vif *vif,
dd45b759
NS
888 struct cfg80211_ssid *ssids, int n_ssids,
889 struct cfg80211_match_set *match_set,
890 int n_match_ssid)
3b8ffc6a 891{
dd45b759
NS
892 u8 i, j, index_to_add, ssid_found = false;
893 struct ath6kl_cfg80211_match_probe_ssid ssid_list[MAX_PROBED_SSIDS];
894
895 memset(ssid_list, 0, sizeof(ssid_list));
3b8ffc6a 896
dd45b759
NS
897 if (n_ssids > MAX_PROBED_SSIDS ||
898 n_match_ssid > MAX_PROBED_SSIDS)
3b8ffc6a
JM
899 return -EINVAL;
900
901 for (i = 0; i < n_ssids; i++) {
dd45b759
NS
902 memcpy(ssid_list[i].ssid.ssid,
903 ssids[i].ssid,
904 ssids[i].ssid_len);
905 ssid_list[i].ssid.ssid_len = ssids[i].ssid_len;
906
907 if (ssids[i].ssid_len)
908 ssid_list[i].flag = SPECIFIC_SSID_FLAG;
909 else
910 ssid_list[i].flag = ANY_SSID_FLAG;
911
912 if (n_match_ssid == 0)
913 ssid_list[i].flag |= MATCH_SSID_FLAG;
914 }
915
916 index_to_add = i;
917
918 for (i = 0; i < n_match_ssid; i++) {
919 ssid_found = false;
920
921 for (j = 0; j < n_ssids; j++) {
922 if ((match_set[i].ssid.ssid_len ==
923 ssid_list[j].ssid.ssid_len) &&
924 (!memcmp(ssid_list[j].ssid.ssid,
925 match_set[i].ssid.ssid,
926 match_set[i].ssid.ssid_len))) {
927 ssid_list[j].flag |= MATCH_SSID_FLAG;
928 ssid_found = true;
929 break;
930 }
931 }
932
933 if (ssid_found)
934 continue;
935
936 if (index_to_add >= MAX_PROBED_SSIDS)
937 continue;
938
939 ssid_list[index_to_add].ssid.ssid_len =
940 match_set[i].ssid.ssid_len;
941 memcpy(ssid_list[index_to_add].ssid.ssid,
942 match_set[i].ssid.ssid,
943 match_set[i].ssid.ssid_len);
944 ssid_list[index_to_add].flag |= MATCH_SSID_FLAG;
945 index_to_add++;
946 }
947
948 for (i = 0; i < index_to_add; i++) {
3b8ffc6a 949 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
dd45b759
NS
950 ssid_list[i].flag,
951 ssid_list[i].ssid.ssid_len,
952 ssid_list[i].ssid.ssid);
953
3b8ffc6a
JM
954 }
955
956 /* Make sure no old entries are left behind */
dd45b759 957 for (i = index_to_add; i < MAX_PROBED_SSIDS; i++) {
3b8ffc6a
JM
958 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx, i,
959 DISABLE_SSID_FLAG, 0, NULL);
960 }
961
962 return 0;
963}
964
fd014284 965static int ath6kl_cfg80211_scan(struct wiphy *wiphy,
bdcd8170
KV
966 struct cfg80211_scan_request *request)
967{
fd014284
JB
968 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(request->wdev);
969 struct ath6kl *ar = ath6kl_priv(vif->ndev);
1276c9ef
EL
970 s8 n_channels = 0;
971 u16 *channels = NULL;
bdcd8170 972 int ret = 0;
f1f92179 973 u32 force_fg_scan = 0;
bdcd8170 974
990bd915 975 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
976 return -EIO;
977
10509f90
KV
978 ath6kl_cfg80211_sscan_disable(vif);
979
bdcd8170 980 if (!ar->usr_bss_filter) {
59c98449 981 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
954e6ce5
VT
982 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
983 ALL_BSS_FILTER, 0);
1b1e6ee3 984 if (ret) {
bdcd8170 985 ath6kl_err("couldn't set bss filtering\n");
1b1e6ee3 986 return ret;
bdcd8170
KV
987 }
988 }
989
3b8ffc6a 990 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
dd45b759 991 request->n_ssids, NULL, 0);
3b8ffc6a
JM
992 if (ret < 0)
993 return ret;
bdcd8170 994
080eec4f
AT
995 /* this also clears IE in fw if it's not set */
996 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
997 WMI_FRAME_PROBE_REQ,
998 request->ie, request->ie_len);
999 if (ret) {
f1ff32e8 1000 ath6kl_err("failed to set Probe Request appie for scan\n");
080eec4f 1001 return ret;
b84da8c7
JM
1002 }
1003
11869bef
JM
1004 /*
1005 * Scan only the requested channels if the request specifies a set of
1006 * channels. If the list is longer than the target supports, do not
1007 * configure the list and instead, scan all available channels.
1008 */
1009 if (request->n_channels > 0 &&
1010 request->n_channels <= WMI_MAX_CHANNELS) {
1276c9ef
EL
1011 u8 i;
1012
11869bef 1013 n_channels = request->n_channels;
1276c9ef
EL
1014
1015 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
1016 if (channels == NULL) {
cdeb8602 1017 ath6kl_warn("failed to set scan channels, scan all channels");
1276c9ef
EL
1018 n_channels = 0;
1019 }
1020
1021 for (i = 0; i < n_channels; i++)
1022 channels[i] = request->channels[i]->center_freq;
1023 }
1024
59c98449 1025 if (test_bit(CONNECTED, &vif->flags))
f1f92179
VT
1026 force_fg_scan = 1;
1027
5b35dff0
RM
1028 vif->scan_req = request;
1029
11f0bfcf
KV
1030 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, vif->fw_vif_idx,
1031 WMI_LONG_SCAN, force_fg_scan,
1032 false, 0,
1033 ATH6KL_FG_SCAN_INTERVAL,
1034 n_channels, channels,
1035 request->no_cck,
1036 request->rates);
5b35dff0 1037 if (ret) {
11f0bfcf 1038 ath6kl_err("failed to start scan: %d\n", ret);
5b35dff0
RM
1039 vif->scan_req = NULL;
1040 }
bdcd8170 1041
1276c9ef
EL
1042 kfree(channels);
1043
bdcd8170
KV
1044 return ret;
1045}
1046
1c17d313 1047void ath6kl_cfg80211_scan_complete_event(struct ath6kl_vif *vif, bool aborted)
bdcd8170 1048{
240d2799 1049 struct ath6kl *ar = vif->ar;
6fd1eace 1050 int i;
bdcd8170 1051
1c17d313
KV
1052 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status%s\n", __func__,
1053 aborted ? " aborted" : "");
bdcd8170 1054
14ee6f6b 1055 if (!vif->scan_req)
6fd1eace
KV
1056 return;
1057
1c17d313 1058 if (aborted)
6fd1eace 1059 goto out;
6fd1eace 1060
14ee6f6b
VT
1061 if (vif->scan_req->n_ssids && vif->scan_req->ssids[0].ssid_len) {
1062 for (i = 0; i < vif->scan_req->n_ssids; i++) {
334234b5
VT
1063 ath6kl_wmi_probedssid_cmd(ar->wmi, vif->fw_vif_idx,
1064 i + 1, DISABLE_SSID_FLAG,
6fd1eace 1065 0, NULL);
bdcd8170 1066 }
bdcd8170 1067 }
6fd1eace
KV
1068
1069out:
cb93821a 1070 cfg80211_scan_done(vif->scan_req, aborted);
14ee6f6b 1071 vif->scan_req = NULL;
bdcd8170
KV
1072}
1073
c4f7863e
TP
1074void ath6kl_cfg80211_ch_switch_notify(struct ath6kl_vif *vif, int freq,
1075 enum wmi_phy_mode mode)
1076{
683b6d3b 1077 struct cfg80211_chan_def chandef;
c4f7863e
TP
1078
1079 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1080 "channel switch notify nw_type %d freq %d mode %d\n",
1081 vif->nw_type, freq, mode);
1082
3d9d1d66
JB
1083 cfg80211_chandef_create(&chandef,
1084 ieee80211_get_channel(vif->ar->wiphy, freq),
1085 (mode == WMI_11G_HT20) ?
1086 NL80211_CHAN_HT20 : NL80211_CHAN_NO_HT);
c4f7863e 1087
683b6d3b 1088 cfg80211_ch_switch_notify(vif->ndev, &chandef);
c4f7863e
TP
1089}
1090
bdcd8170
KV
1091static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
1092 u8 key_index, bool pairwise,
1093 const u8 *mac_addr,
1094 struct key_params *params)
1095{
d6d5c06c 1096 struct ath6kl *ar = ath6kl_priv(ndev);
59c98449 1097 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170 1098 struct ath6kl_key *key = NULL;
4a8ce2fd 1099 int seq_len;
bdcd8170
KV
1100 u8 key_usage;
1101 u8 key_type;
bdcd8170 1102
990bd915 1103 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1104 return -EIO;
1105
837cb97e
JM
1106 if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
1107 if (params->key_len != WMI_KRK_LEN)
1108 return -EINVAL;
240d2799
VT
1109 return ath6kl_wmi_add_krk_cmd(ar->wmi, vif->fw_vif_idx,
1110 params->key);
837cb97e
JM
1111 }
1112
792ecb33 1113 if (key_index > WMI_MAX_KEY_INDEX) {
bdcd8170
KV
1114 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1115 "%s: key index %d out of bounds\n", __func__,
1116 key_index);
1117 return -ENOENT;
1118 }
1119
6f2a73f9 1120 key = &vif->keys[key_index];
bdcd8170
KV
1121 memset(key, 0, sizeof(struct ath6kl_key));
1122
1123 if (pairwise)
1124 key_usage = PAIRWISE_USAGE;
1125 else
1126 key_usage = GROUP_USAGE;
1127
4a8ce2fd
SM
1128 seq_len = params->seq_len;
1129 if (params->cipher == WLAN_CIPHER_SUITE_SMS4 &&
1130 seq_len > ATH6KL_KEY_SEQ_LEN) {
1131 /* Only first half of the WPI PN is configured */
1132 seq_len = ATH6KL_KEY_SEQ_LEN;
bdcd8170 1133 }
4a8ce2fd
SM
1134 if (params->key_len > WLAN_MAX_KEY_LEN ||
1135 seq_len > sizeof(key->seq))
1136 return -EINVAL;
1137
1138 key->key_len = params->key_len;
1139 memcpy(key->key, params->key, key->key_len);
1140 key->seq_len = seq_len;
1141 memcpy(key->seq, params->seq, key->seq_len);
1142 key->cipher = params->cipher;
bdcd8170
KV
1143
1144 switch (key->cipher) {
1145 case WLAN_CIPHER_SUITE_WEP40:
1146 case WLAN_CIPHER_SUITE_WEP104:
1147 key_type = WEP_CRYPT;
1148 break;
1149
1150 case WLAN_CIPHER_SUITE_TKIP:
1151 key_type = TKIP_CRYPT;
1152 break;
1153
1154 case WLAN_CIPHER_SUITE_CCMP:
1155 key_type = AES_CRYPT;
1156 break;
5e07021e
DS
1157 case WLAN_CIPHER_SUITE_SMS4:
1158 key_type = WAPI_CRYPT;
1159 break;
bdcd8170
KV
1160
1161 default:
1162 return -ENOTSUPP;
1163 }
1164
ddc3d77c
KV
1165 if (((vif->auth_mode == WPA_PSK_AUTH) ||
1166 (vif->auth_mode == WPA2_PSK_AUTH)) &&
1167 (key_usage & GROUP_USAGE))
de3ad713 1168 del_timer(&vif->disconnect_timer);
bdcd8170
KV
1169
1170 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1171 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
1172 __func__, key_index, key->key_len, key_type,
1173 key_usage, key->seq_len);
1174
f5938f24 1175 if (vif->nw_type == AP_NETWORK && !pairwise &&
4703290a 1176 (key_type == TKIP_CRYPT || key_type == AES_CRYPT ||
cc4d623d 1177 key_type == WAPI_CRYPT)) {
9a5b1318
JM
1178 ar->ap_mode_bkey.valid = true;
1179 ar->ap_mode_bkey.key_index = key_index;
1180 ar->ap_mode_bkey.key_type = key_type;
1181 ar->ap_mode_bkey.key_len = key->key_len;
1182 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
59c98449 1183 if (!test_bit(CONNECTED, &vif->flags)) {
cdeb8602
KV
1184 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1185 "Delay initial group key configuration until AP mode has been started\n");
9a5b1318
JM
1186 /*
1187 * The key will be set in ath6kl_connect_ap_mode() once
1188 * the connected event is received from the target.
1189 */
1190 return 0;
1191 }
1192 }
1193
f5938f24 1194 if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
59c98449 1195 !test_bit(CONNECTED, &vif->flags)) {
151411e8
JM
1196 /*
1197 * Store the key locally so that it can be re-configured after
1198 * the AP mode has properly started
1199 * (ath6kl_install_statioc_wep_keys).
1200 */
cdeb8602
KV
1201 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1202 "Delay WEP key configuration until AP mode has been started\n");
6f2a73f9
VT
1203 vif->wep_key_list[key_index].key_len = key->key_len;
1204 memcpy(vif->wep_key_list[key_index].key, key->key,
1205 key->key_len);
151411e8
JM
1206 return 0;
1207 }
1208
7cefa44f 1209 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx, key_index,
f3e61ece
JM
1210 key_type, key_usage, key->key_len,
1211 key->seq, key->seq_len, key->key,
1212 KEY_OP_INIT_VAL,
1213 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
bdcd8170
KV
1214}
1215
1216static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
1217 u8 key_index, bool pairwise,
1218 const u8 *mac_addr)
1219{
d6d5c06c 1220 struct ath6kl *ar = ath6kl_priv(ndev);
6f2a73f9 1221 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
1222
1223 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1224
990bd915 1225 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1226 return -EIO;
1227
792ecb33 1228 if (key_index > WMI_MAX_KEY_INDEX) {
bdcd8170
KV
1229 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1230 "%s: key index %d out of bounds\n", __func__,
1231 key_index);
1232 return -ENOENT;
1233 }
1234
6f2a73f9 1235 if (!vif->keys[key_index].key_len) {
bdcd8170
KV
1236 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1237 "%s: index %d is empty\n", __func__, key_index);
1238 return 0;
1239 }
1240
6f2a73f9 1241 vif->keys[key_index].key_len = 0;
bdcd8170 1242
334234b5 1243 return ath6kl_wmi_deletekey_cmd(ar->wmi, vif->fw_vif_idx, key_index);
bdcd8170
KV
1244}
1245
1246static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
1247 u8 key_index, bool pairwise,
1248 const u8 *mac_addr, void *cookie,
1249 void (*callback) (void *cookie,
1250 struct key_params *))
1251{
6f2a73f9 1252 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
1253 struct ath6kl_key *key = NULL;
1254 struct key_params params;
1255
1256 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1257
990bd915 1258 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1259 return -EIO;
1260
792ecb33 1261 if (key_index > WMI_MAX_KEY_INDEX) {
bdcd8170
KV
1262 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1263 "%s: key index %d out of bounds\n", __func__,
1264 key_index);
1265 return -ENOENT;
1266 }
1267
6f2a73f9 1268 key = &vif->keys[key_index];
bdcd8170
KV
1269 memset(&params, 0, sizeof(params));
1270 params.cipher = key->cipher;
1271 params.key_len = key->key_len;
1272 params.seq_len = key->seq_len;
1273 params.seq = key->seq;
1274 params.key = key->key;
1275
1276 callback(cookie, &params);
1277
1278 return key->key_len ? 0 : -ENOENT;
1279}
1280
1281static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1282 struct net_device *ndev,
1283 u8 key_index, bool unicast,
1284 bool multicast)
1285{
d6d5c06c 1286 struct ath6kl *ar = ath6kl_priv(ndev);
59c98449 1287 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170 1288 struct ath6kl_key *key = NULL;
bdcd8170 1289 u8 key_usage;
229ed6b5 1290 enum crypto_type key_type = NONE_CRYPT;
bdcd8170
KV
1291
1292 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1293
990bd915 1294 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1295 return -EIO;
1296
792ecb33 1297 if (key_index > WMI_MAX_KEY_INDEX) {
bdcd8170
KV
1298 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1299 "%s: key index %d out of bounds\n",
1300 __func__, key_index);
1301 return -ENOENT;
1302 }
1303
6f2a73f9 1304 if (!vif->keys[key_index].key_len) {
bdcd8170
KV
1305 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1306 __func__, key_index);
1307 return -EINVAL;
1308 }
1309
3450334f 1310 vif->def_txkey_index = key_index;
6f2a73f9 1311 key = &vif->keys[vif->def_txkey_index];
bdcd8170 1312 key_usage = GROUP_USAGE;
3450334f 1313 if (vif->prwise_crypto == WEP_CRYPT)
bdcd8170 1314 key_usage |= TX_USAGE;
229ed6b5 1315 if (unicast)
3450334f 1316 key_type = vif->prwise_crypto;
229ed6b5 1317 if (multicast)
3450334f 1318 key_type = vif->grp_crypto;
bdcd8170 1319
f5938f24 1320 if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
9a5b1318
JM
1321 return 0; /* Delay until AP mode has been started */
1322
f3e61ece
JM
1323 return ath6kl_wmi_addkey_cmd(ar->wmi, vif->fw_vif_idx,
1324 vif->def_txkey_index,
1325 key_type, key_usage,
1326 key->key_len, key->seq, key->seq_len,
1327 key->key,
1328 KEY_OP_INIT_VAL, NULL,
1329 SYNC_BOTH_WMIFLAG);
bdcd8170
KV
1330}
1331
240d2799 1332void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl_vif *vif, u8 keyid,
bdcd8170
KV
1333 bool ismcast)
1334{
1335 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1336 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1337
240d2799 1338 cfg80211_michael_mic_failure(vif->ndev, vif->bssid,
bdcd8170
KV
1339 (ismcast ? NL80211_KEYTYPE_GROUP :
1340 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1341 GFP_KERNEL);
1342}
1343
1344static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1345{
1346 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
990bd915 1347 struct ath6kl_vif *vif;
bdcd8170
KV
1348 int ret;
1349
1350 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1351 changed);
1352
990bd915
VT
1353 vif = ath6kl_vif_first(ar);
1354 if (!vif)
1355 return -EIO;
1356
1357 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1358 return -EIO;
1359
1360 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1361 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1362 if (ret != 0) {
1363 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1364 return -EIO;
1365 }
1366 }
1367
1368 return 0;
1369}
1370
bdcd8170 1371static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
c8442118 1372 struct wireless_dev *wdev,
bdcd8170 1373 enum nl80211_tx_power_setting type,
b992a285 1374 int mbm)
bdcd8170
KV
1375{
1376 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
990bd915 1377 struct ath6kl_vif *vif;
b992a285 1378 int dbm = MBM_TO_DBM(mbm);
bdcd8170
KV
1379
1380 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1381 type, dbm);
1382
990bd915
VT
1383 vif = ath6kl_vif_first(ar);
1384 if (!vif)
1385 return -EIO;
1386
1387 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1388 return -EIO;
1389
1390 switch (type) {
1391 case NL80211_TX_POWER_AUTOMATIC:
1392 return 0;
1393 case NL80211_TX_POWER_LIMITED:
d0d670ab 1394 ar->tx_pwr = dbm;
bdcd8170
KV
1395 break;
1396 default:
1397 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1398 __func__, type);
1399 return -EOPNOTSUPP;
1400 }
1401
d0d670ab 1402 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx, dbm);
bdcd8170
KV
1403
1404 return 0;
1405}
1406
c8442118
JB
1407static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy,
1408 struct wireless_dev *wdev,
1409 int *dbm)
bdcd8170
KV
1410{
1411 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
990bd915
VT
1412 struct ath6kl_vif *vif;
1413
1414 vif = ath6kl_vif_first(ar);
1415 if (!vif)
1416 return -EIO;
bdcd8170 1417
990bd915 1418 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1419 return -EIO;
1420
59c98449 1421 if (test_bit(CONNECTED, &vif->flags)) {
bdcd8170
KV
1422 ar->tx_pwr = 0;
1423
990bd915 1424 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi, vif->fw_vif_idx) != 0) {
bdcd8170
KV
1425 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1426 return -EIO;
1427 }
1428
1429 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1430 5 * HZ);
1431
1432 if (signal_pending(current)) {
1433 ath6kl_err("target did not respond\n");
1434 return -EINTR;
1435 }
1436 }
1437
1438 *dbm = ar->tx_pwr;
1439 return 0;
1440}
1441
1442static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1443 struct net_device *dev,
1444 bool pmgmt, int timeout)
1445{
1446 struct ath6kl *ar = ath6kl_priv(dev);
1447 struct wmi_power_mode_cmd mode;
334234b5 1448 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1449
1450 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1451 __func__, pmgmt, timeout);
1452
990bd915 1453 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1454 return -EIO;
1455
1456 if (pmgmt) {
1457 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1458 mode.pwr_mode = REC_POWER;
1459 } else {
1460 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1461 mode.pwr_mode = MAX_PERF_POWER;
1462 }
1463
334234b5 1464 if (ath6kl_wmi_powermode_cmd(ar->wmi, vif->fw_vif_idx,
96f1fadc 1465 mode.pwr_mode) != 0) {
bdcd8170
KV
1466 ath6kl_err("wmi_powermode_cmd failed\n");
1467 return -EIO;
1468 }
1469
1470 return 0;
1471}
1472
84efbb84 1473static struct wireless_dev *ath6kl_cfg80211_add_iface(struct wiphy *wiphy,
552bff0c 1474 const char *name,
84efbb84
JB
1475 enum nl80211_iftype type,
1476 u32 *flags,
1477 struct vif_params *params)
55055976
VT
1478{
1479 struct ath6kl *ar = wiphy_priv(wiphy);
84efbb84 1480 struct wireless_dev *wdev;
55055976
VT
1481 u8 if_idx, nw_type;
1482
71f96ee6 1483 if (ar->num_vif == ar->vif_max) {
55055976
VT
1484 ath6kl_err("Reached maximum number of supported vif\n");
1485 return ERR_PTR(-EINVAL);
1486 }
1487
1488 if (!ath6kl_is_valid_iftype(ar, type, &if_idx, &nw_type)) {
1489 ath6kl_err("Not a supported interface type\n");
1490 return ERR_PTR(-EINVAL);
1491 }
1492
84efbb84
JB
1493 wdev = ath6kl_interface_add(ar, name, type, if_idx, nw_type);
1494 if (!wdev)
55055976
VT
1495 return ERR_PTR(-ENOMEM);
1496
1497 ar->num_vif++;
1498
84efbb84 1499 return wdev;
55055976
VT
1500}
1501
1502static int ath6kl_cfg80211_del_iface(struct wiphy *wiphy,
84efbb84 1503 struct wireless_dev *wdev)
55055976
VT
1504{
1505 struct ath6kl *ar = wiphy_priv(wiphy);
84efbb84 1506 struct ath6kl_vif *vif = netdev_priv(wdev->netdev);
55055976 1507
11f6e40d 1508 spin_lock_bh(&ar->list_lock);
55055976 1509 list_del(&vif->list);
11f6e40d 1510 spin_unlock_bh(&ar->list_lock);
55055976
VT
1511
1512 ath6kl_cleanup_vif(vif, test_bit(WMI_READY, &ar->flag));
1513
c25889e8 1514 ath6kl_cfg80211_vif_cleanup(vif);
55055976
VT
1515
1516 return 0;
1517}
1518
bdcd8170
KV
1519static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1520 struct net_device *ndev,
1521 enum nl80211_iftype type, u32 *flags,
1522 struct vif_params *params)
1523{
f5938f24 1524 struct ath6kl_vif *vif = netdev_priv(ndev);
1e8d13b0 1525 int i;
bdcd8170
KV
1526
1527 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1528
1e8d13b0
VT
1529 /*
1530 * Don't bring up p2p on an interface which is not initialized
1531 * for p2p operation where fw does not have capability to switch
1532 * dynamically between non-p2p and p2p type interface.
1533 */
1534 if (!test_bit(ATH6KL_FW_CAPABILITY_STA_P2PDEV_DUPLEX,
1535 vif->ar->fw_capabilities) &&
1536 (type == NL80211_IFTYPE_P2P_CLIENT ||
1537 type == NL80211_IFTYPE_P2P_GO)) {
1538 if (vif->ar->vif_max == 1) {
1539 if (vif->fw_vif_idx != 0)
1540 return -EINVAL;
1541 else
1542 goto set_iface_type;
1543 }
1544
1545 for (i = vif->ar->max_norm_iface; i < vif->ar->vif_max; i++) {
1546 if (i == vif->fw_vif_idx)
1547 break;
1548 }
1549
1550 if (i == vif->ar->vif_max) {
1551 ath6kl_err("Invalid interface to bring up P2P\n");
1552 return -EINVAL;
1553 }
1554 }
1555
c422d52d
TP
1556 /* need to clean up enhanced bmiss detection fw state */
1557 ath6kl_cfg80211_sta_bmiss_enhance(vif, false);
1558
1e8d13b0 1559set_iface_type:
bdcd8170
KV
1560 switch (type) {
1561 case NL80211_IFTYPE_STATION:
f5938f24 1562 vif->next_mode = INFRA_NETWORK;
bdcd8170
KV
1563 break;
1564 case NL80211_IFTYPE_ADHOC:
f5938f24 1565 vif->next_mode = ADHOC_NETWORK;
bdcd8170 1566 break;
6e4604c8 1567 case NL80211_IFTYPE_AP:
f5938f24 1568 vif->next_mode = AP_NETWORK;
6e4604c8 1569 break;
6b5e5d25 1570 case NL80211_IFTYPE_P2P_CLIENT:
f5938f24 1571 vif->next_mode = INFRA_NETWORK;
6b5e5d25
JM
1572 break;
1573 case NL80211_IFTYPE_P2P_GO:
f5938f24 1574 vif->next_mode = AP_NETWORK;
6b5e5d25 1575 break;
bdcd8170
KV
1576 default:
1577 ath6kl_err("invalid interface type %u\n", type);
1578 return -EOPNOTSUPP;
1579 }
1580
551959d8 1581 vif->wdev.iftype = type;
bdcd8170
KV
1582
1583 return 0;
1584}
1585
1586static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1587 struct net_device *dev,
1588 struct cfg80211_ibss_params *ibss_param)
1589{
1590 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1591 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1592 int status;
1593
990bd915 1594 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1595 return -EIO;
1596
3450334f
VT
1597 vif->ssid_len = ibss_param->ssid_len;
1598 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
bdcd8170 1599
683b6d3b
JB
1600 if (ibss_param->chandef.chan)
1601 vif->ch_hint = ibss_param->chandef.chan->center_freq;
bdcd8170
KV
1602
1603 if (ibss_param->channel_fixed) {
1604 /*
1605 * TODO: channel_fixed: The channel should be fixed, do not
1606 * search for IBSSs to join on other channels. Target
1607 * firmware does not support this feature, needs to be
1608 * updated.
1609 */
1610 return -EOPNOTSUPP;
1611 }
1612
8c8b65e3 1613 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170 1614 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
8c8b65e3
VT
1615 memcpy(vif->req_bssid, ibss_param->bssid,
1616 sizeof(vif->req_bssid));
bdcd8170 1617
240d2799 1618 ath6kl_set_wpa_version(vif, 0);
bdcd8170 1619
240d2799 1620 status = ath6kl_set_auth_type(vif, NL80211_AUTHTYPE_OPEN_SYSTEM);
bdcd8170
KV
1621 if (status)
1622 return status;
1623
1624 if (ibss_param->privacy) {
240d2799
VT
1625 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, true);
1626 ath6kl_set_cipher(vif, WLAN_CIPHER_SUITE_WEP40, false);
bdcd8170 1627 } else {
240d2799
VT
1628 ath6kl_set_cipher(vif, 0, true);
1629 ath6kl_set_cipher(vif, 0, false);
bdcd8170
KV
1630 }
1631
f5938f24 1632 vif->nw_type = vif->next_mode;
bdcd8170
KV
1633
1634 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1635 "%s: connect called with authmode %d dot11 auth %d"
1636 " PW crypto %d PW crypto len %d GRP crypto %d"
1637 " GRP crypto len %d channel hint %u\n",
1638 __func__,
3450334f
VT
1639 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1640 vif->prwise_crypto_len, vif->grp_crypto,
f74bac54 1641 vif->grp_crypto_len, vif->ch_hint);
bdcd8170 1642
334234b5 1643 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->fw_vif_idx, vif->nw_type,
3450334f
VT
1644 vif->dot11_auth_mode, vif->auth_mode,
1645 vif->prwise_crypto,
1646 vif->prwise_crypto_len,
1647 vif->grp_crypto, vif->grp_crypto_len,
1648 vif->ssid_len, vif->ssid,
f74bac54 1649 vif->req_bssid, vif->ch_hint,
3ca9d1fc 1650 ar->connect_ctrl_flags, SUBTYPE_NONE);
59c98449 1651 set_bit(CONNECT_PEND, &vif->flags);
bdcd8170
KV
1652
1653 return 0;
1654}
1655
1656static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1657 struct net_device *dev)
1658{
3450334f 1659 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170 1660
990bd915 1661 if (!ath6kl_cfg80211_ready(vif))
bdcd8170
KV
1662 return -EIO;
1663
240d2799 1664 ath6kl_disconnect(vif);
3450334f
VT
1665 memset(vif->ssid, 0, sizeof(vif->ssid));
1666 vif->ssid_len = 0;
bdcd8170
KV
1667
1668 return 0;
1669}
1670
1671static const u32 cipher_suites[] = {
1672 WLAN_CIPHER_SUITE_WEP40,
1673 WLAN_CIPHER_SUITE_WEP104,
1674 WLAN_CIPHER_SUITE_TKIP,
1675 WLAN_CIPHER_SUITE_CCMP,
837cb97e 1676 CCKM_KRK_CIPHER_SUITE,
5e07021e 1677 WLAN_CIPHER_SUITE_SMS4,
bdcd8170
KV
1678};
1679
1680static bool is_rate_legacy(s32 rate)
1681{
1682 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1683 6000, 9000, 12000, 18000, 24000,
1684 36000, 48000, 54000
1685 };
1686 u8 i;
1687
1688 for (i = 0; i < ARRAY_SIZE(legacy); i++)
1689 if (rate == legacy[i])
1690 return true;
1691
1692 return false;
1693}
1694
1695static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1696{
1697 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1698 52000, 58500, 65000, 72200
1699 };
1700 u8 i;
1701
1702 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1703 if (rate == ht20[i]) {
1704 if (i == ARRAY_SIZE(ht20) - 1)
1705 /* last rate uses sgi */
1706 *sgi = true;
1707 else
1708 *sgi = false;
1709
1710 *mcs = i;
1711 return true;
1712 }
1713 }
1714 return false;
1715}
1716
1717static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1718{
1719 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1720 81000, 108000, 121500, 135000,
1721 150000
1722 };
1723 u8 i;
1724
1725 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1726 if (rate == ht40[i]) {
1727 if (i == ARRAY_SIZE(ht40) - 1)
1728 /* last rate uses sgi */
1729 *sgi = true;
1730 else
1731 *sgi = false;
1732
1733 *mcs = i;
1734 return true;
1735 }
1736 }
1737
1738 return false;
1739}
1740
1741static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1742 u8 *mac, struct station_info *sinfo)
1743{
1744 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1745 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1746 long left;
1747 bool sgi;
1748 s32 rate;
1749 int ret;
1750 u8 mcs;
1751
8c8b65e3 1752 if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
bdcd8170
KV
1753 return -ENOENT;
1754
1755 if (down_interruptible(&ar->sem))
1756 return -EBUSY;
1757
b95907a7 1758 set_bit(STATS_UPDATE_PEND, &vif->flags);
bdcd8170 1759
334234b5 1760 ret = ath6kl_wmi_get_stats_cmd(ar->wmi, vif->fw_vif_idx);
bdcd8170
KV
1761
1762 if (ret != 0) {
1763 up(&ar->sem);
1764 return -EIO;
1765 }
1766
1767 left = wait_event_interruptible_timeout(ar->event_wq,
1768 !test_bit(STATS_UPDATE_PEND,
b95907a7 1769 &vif->flags),
bdcd8170
KV
1770 WMI_TIMEOUT);
1771
1772 up(&ar->sem);
1773
1774 if (left == 0)
1775 return -ETIMEDOUT;
1776 else if (left < 0)
1777 return left;
1778
b95907a7
VT
1779 if (vif->target_stats.rx_byte) {
1780 sinfo->rx_bytes = vif->target_stats.rx_byte;
bdcd8170 1781 sinfo->filled |= STATION_INFO_RX_BYTES;
b95907a7 1782 sinfo->rx_packets = vif->target_stats.rx_pkt;
bdcd8170
KV
1783 sinfo->filled |= STATION_INFO_RX_PACKETS;
1784 }
1785
b95907a7
VT
1786 if (vif->target_stats.tx_byte) {
1787 sinfo->tx_bytes = vif->target_stats.tx_byte;
bdcd8170 1788 sinfo->filled |= STATION_INFO_TX_BYTES;
b95907a7 1789 sinfo->tx_packets = vif->target_stats.tx_pkt;
bdcd8170
KV
1790 sinfo->filled |= STATION_INFO_TX_PACKETS;
1791 }
1792
b95907a7 1793 sinfo->signal = vif->target_stats.cs_rssi;
bdcd8170
KV
1794 sinfo->filled |= STATION_INFO_SIGNAL;
1795
b95907a7 1796 rate = vif->target_stats.tx_ucast_rate;
bdcd8170
KV
1797
1798 if (is_rate_legacy(rate)) {
1799 sinfo->txrate.legacy = rate / 100;
1800 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1801 if (sgi) {
1802 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1803 sinfo->txrate.mcs = mcs - 1;
1804 } else {
1805 sinfo->txrate.mcs = mcs;
1806 }
1807
1808 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1809 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1810 if (sgi) {
1811 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1812 sinfo->txrate.mcs = mcs - 1;
1813 } else {
1814 sinfo->txrate.mcs = mcs;
1815 }
1816
1817 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1818 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1819 } else {
9a730834
KV
1820 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1821 "invalid rate from stats: %d\n", rate);
1822 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
bdcd8170
KV
1823 return 0;
1824 }
1825
1826 sinfo->filled |= STATION_INFO_TX_BITRATE;
1827
59c98449
VT
1828 if (test_bit(CONNECTED, &vif->flags) &&
1829 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
f5938f24 1830 vif->nw_type == INFRA_NETWORK) {
32c10874
JM
1831 sinfo->filled |= STATION_INFO_BSS_PARAM;
1832 sinfo->bss_param.flags = 0;
cf5333d7
VT
1833 sinfo->bss_param.dtim_period = vif->assoc_bss_dtim_period;
1834 sinfo->bss_param.beacon_interval = vif->assoc_bss_beacon_int;
32c10874
JM
1835 }
1836
bdcd8170
KV
1837 return 0;
1838}
1839
1840static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1841 struct cfg80211_pmksa *pmksa)
1842{
1843 struct ath6kl *ar = ath6kl_priv(netdev);
334234b5
VT
1844 struct ath6kl_vif *vif = netdev_priv(netdev);
1845
1846 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
bdcd8170
KV
1847 pmksa->pmkid, true);
1848}
1849
1850static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1851 struct cfg80211_pmksa *pmksa)
1852{
1853 struct ath6kl *ar = ath6kl_priv(netdev);
334234b5
VT
1854 struct ath6kl_vif *vif = netdev_priv(netdev);
1855
1856 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx, pmksa->bssid,
bdcd8170
KV
1857 pmksa->pmkid, false);
1858}
1859
1860static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1861{
1862 struct ath6kl *ar = ath6kl_priv(netdev);
59c98449
VT
1863 struct ath6kl_vif *vif = netdev_priv(netdev);
1864
1865 if (test_bit(CONNECTED, &vif->flags))
334234b5
VT
1866 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->fw_vif_idx,
1867 vif->bssid, NULL, false);
bdcd8170
KV
1868 return 0;
1869}
1870
d91e8eee
RM
1871static int ath6kl_wow_usr(struct ath6kl *ar, struct ath6kl_vif *vif,
1872 struct cfg80211_wowlan *wow, u32 *filter)
6cb3c714 1873{
d91e8eee 1874 int ret, pos;
2c07cf44 1875 u8 mask[WOW_PATTERN_SIZE];
6cb3c714 1876 u16 i;
6cb3c714 1877
d91e8eee 1878 /* Configure the patterns that we received from the user. */
6cb3c714
RM
1879 for (i = 0; i < wow->n_patterns; i++) {
1880
1881 /*
1882 * Convert given nl80211 specific mask value to equivalent
1883 * driver specific mask value and send it to the chip along
1884 * with patterns. For example, If the mask value defined in
1885 * struct cfg80211_wowlan is 0xA (equivalent binary is 1010),
1886 * then equivalent driver specific mask value is
1887 * "0xFF 0x00 0xFF 0x00".
1888 */
1889 memset(&mask, 0, sizeof(mask));
1890 for (pos = 0; pos < wow->patterns[i].pattern_len; pos++) {
1891 if (wow->patterns[i].mask[pos / 8] & (0x1 << (pos % 8)))
1892 mask[pos] = 0xFF;
1893 }
1894 /*
1895 * Note: Pattern's offset is not passed as part of wowlan
1896 * parameter from CFG layer. So it's always passed as ZERO
1897 * to the firmware. It means, given WOW patterns are always
1898 * matched from the first byte of received pkt in the firmware.
1899 */
1900 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
d91e8eee
RM
1901 vif->fw_vif_idx, WOW_LIST_ID,
1902 wow->patterns[i].pattern_len,
1903 0 /* pattern offset */,
1904 wow->patterns[i].pattern, mask);
6cb3c714
RM
1905 if (ret)
1906 return ret;
1907 }
1908
d91e8eee
RM
1909 if (wow->disconnect)
1910 *filter |= WOW_FILTER_OPTION_NWK_DISASSOC;
1911
1912 if (wow->magic_pkt)
1913 *filter |= WOW_FILTER_OPTION_MAGIC_PACKET;
1914
1915 if (wow->gtk_rekey_failure)
1916 *filter |= WOW_FILTER_OPTION_GTK_ERROR;
1917
1918 if (wow->eap_identity_req)
1919 *filter |= WOW_FILTER_OPTION_EAP_REQ;
1920
1921 if (wow->four_way_handshake)
1922 *filter |= WOW_FILTER_OPTION_8021X_4WAYHS;
1923
1924 return 0;
1925}
1926
1927static int ath6kl_wow_ap(struct ath6kl *ar, struct ath6kl_vif *vif)
1928{
1929 static const u8 unicst_pattern[] = { 0x00, 0x00, 0x00,
1930 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1931 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1932 0x00, 0x08 };
1933 static const u8 unicst_mask[] = { 0x01, 0x00, 0x00,
1934 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1935 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1936 0x00, 0x7f };
1937 u8 unicst_offset = 0;
1938 static const u8 arp_pattern[] = { 0x08, 0x06 };
1939 static const u8 arp_mask[] = { 0xff, 0xff };
1940 u8 arp_offset = 20;
1941 static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
1942 static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
1943 u8 discvr_offset = 38;
1944 static const u8 dhcp_pattern[] = { 0xff, 0xff, 0xff, 0xff,
1945 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1946 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00,
1947 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1948 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1949 0x00, 0x00, 0x00, 0x00, 0x00, 0x43 /* port 67 */ };
1950 static const u8 dhcp_mask[] = { 0xff, 0xff, 0xff, 0xff,
1951 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1952 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
1953 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1954 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1955 0x00, 0x00, 0x00, 0x00, 0xff, 0xff /* port 67 */ };
1956 u8 dhcp_offset = 0;
1957 int ret;
1958
1959 /* Setup unicast IP, EAPOL-like and ARP pkt pattern */
1960 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1961 vif->fw_vif_idx, WOW_LIST_ID,
1962 sizeof(unicst_pattern), unicst_offset,
1963 unicst_pattern, unicst_mask);
1964 if (ret) {
1965 ath6kl_err("failed to add WOW unicast IP pattern\n");
1966 return ret;
1967 }
1968
1969 /* Setup all ARP pkt pattern */
1970 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1971 vif->fw_vif_idx, WOW_LIST_ID,
1972 sizeof(arp_pattern), arp_offset,
1973 arp_pattern, arp_mask);
1974 if (ret) {
1975 ath6kl_err("failed to add WOW ARP pattern\n");
1976 return ret;
1977 }
1978
1979 /*
1980 * Setup multicast pattern for mDNS 224.0.0.251,
1981 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
1982 */
1983 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1984 vif->fw_vif_idx, WOW_LIST_ID,
1985 sizeof(discvr_pattern), discvr_offset,
1986 discvr_pattern, discvr_mask);
1987 if (ret) {
1988 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
1989 return ret;
1990 }
1991
1992 /* Setup all DHCP broadcast pkt pattern */
1993 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
1994 vif->fw_vif_idx, WOW_LIST_ID,
1995 sizeof(dhcp_pattern), dhcp_offset,
1996 dhcp_pattern, dhcp_mask);
1997 if (ret) {
1998 ath6kl_err("failed to add WOW DHCP broadcast pattern\n");
1999 return ret;
2000 }
2001
2002 return 0;
2003}
2004
2005static int ath6kl_wow_sta(struct ath6kl *ar, struct ath6kl_vif *vif)
2006{
2007 struct net_device *ndev = vif->ndev;
2008 static const u8 discvr_pattern[] = { 0xe0, 0x00, 0x00, 0xf8 };
2009 static const u8 discvr_mask[] = { 0xf0, 0x00, 0x00, 0xf8 };
2010 u8 discvr_offset = 38;
2011 u8 mac_mask[ETH_ALEN];
2012 int ret;
2013
2014 /* Setup unicast pkt pattern */
2015 memset(mac_mask, 0xff, ETH_ALEN);
2016 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2017 vif->fw_vif_idx, WOW_LIST_ID,
2018 ETH_ALEN, 0, ndev->dev_addr,
2019 mac_mask);
2020 if (ret) {
2021 ath6kl_err("failed to add WOW unicast pattern\n");
2022 return ret;
2023 }
2024
2025 /*
2026 * Setup multicast pattern for mDNS 224.0.0.251,
2027 * SSDP 239.255.255.250 and LLMNR 224.0.0.252
2028 */
2029 if ((ndev->flags & IFF_ALLMULTI) ||
2030 (ndev->flags & IFF_MULTICAST && netdev_mc_count(ndev) > 0)) {
2031 ret = ath6kl_wmi_add_wow_pattern_cmd(ar->wmi,
2032 vif->fw_vif_idx, WOW_LIST_ID,
2033 sizeof(discvr_pattern), discvr_offset,
2034 discvr_pattern, discvr_mask);
2035 if (ret) {
cdeb8602 2036 ath6kl_err("failed to add WOW mDNS/SSDP/LLMNR pattern\n");
d91e8eee
RM
2037 return ret;
2038 }
2039 }
2040
2041 return 0;
2042}
2043
055bde49
RM
2044static int is_hsleep_mode_procsed(struct ath6kl_vif *vif)
2045{
2046 return test_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2047}
2048
2049static bool is_ctrl_ep_empty(struct ath6kl *ar)
2050{
2051 return !ar->tx_pending[ar->ctrl_ep];
2052}
2053
2054static int ath6kl_cfg80211_host_sleep(struct ath6kl *ar, struct ath6kl_vif *vif)
2055{
2056 int ret, left;
2057
2058 clear_bit(HOST_SLEEP_MODE_CMD_PROCESSED, &vif->flags);
2059
2060 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2061 ATH6KL_HOST_MODE_ASLEEP);
2062 if (ret)
2063 return ret;
2064
2065 left = wait_event_interruptible_timeout(ar->event_wq,
2066 is_hsleep_mode_procsed(vif),
2067 WMI_TIMEOUT);
2068 if (left == 0) {
2069 ath6kl_warn("timeout, didn't get host sleep cmd processed event\n");
2070 ret = -ETIMEDOUT;
2071 } else if (left < 0) {
2072 ath6kl_warn("error while waiting for host sleep cmd processed event %d\n",
2073 left);
2074 ret = left;
2075 }
2076
2077 if (ar->tx_pending[ar->ctrl_ep]) {
2078 left = wait_event_interruptible_timeout(ar->event_wq,
2079 is_ctrl_ep_empty(ar),
2080 WMI_TIMEOUT);
2081 if (left == 0) {
2082 ath6kl_warn("clear wmi ctrl data timeout\n");
2083 ret = -ETIMEDOUT;
2084 } else if (left < 0) {
2085 ath6kl_warn("clear wmi ctrl data failed: %d\n", left);
2086 ret = left;
2087 }
2088 }
2089
2090 return ret;
2091}
2092
fd4377b6
TP
2093static int ath6kl_wow_suspend_vif(struct ath6kl_vif *vif,
2094 struct cfg80211_wowlan *wow, u32 *filter)
d91e8eee 2095{
fd4377b6 2096 struct ath6kl *ar = vif->ar;
d91e8eee
RM
2097 struct in_device *in_dev;
2098 struct in_ifaddr *ifa;
055bde49 2099 int ret;
ce0dc0cf 2100 u16 i, bmiss_time;
d91e8eee 2101 __be32 ips[MAX_IP_ADDRS];
fd4377b6 2102 u8 index = 0;
d91e8eee 2103
6821d4f0
NG
2104 if (!test_bit(NETDEV_MCAST_ALL_ON, &vif->flags) &&
2105 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2106 ar->fw_capabilities)) {
6251d801
NG
2107 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
2108 vif->fw_vif_idx, false);
2109 if (ret)
2110 return ret;
2111 }
2112
d91e8eee
RM
2113 /* Clear existing WOW patterns */
2114 for (i = 0; i < WOW_MAX_FILTERS_PER_LIST; i++)
2115 ath6kl_wmi_del_wow_pattern_cmd(ar->wmi, vif->fw_vif_idx,
2116 WOW_LIST_ID, i);
2117
2118 /*
2119 * Skip the default WOW pattern configuration
2120 * if the driver receives any WOW patterns from
2121 * the user.
2122 */
2123 if (wow)
fd4377b6 2124 ret = ath6kl_wow_usr(ar, vif, wow, filter);
d91e8eee
RM
2125 else if (vif->nw_type == AP_NETWORK)
2126 ret = ath6kl_wow_ap(ar, vif);
2127 else
2128 ret = ath6kl_wow_sta(ar, vif);
2129
2130 if (ret)
2131 return ret;
2132
390a8c8f
RM
2133 netif_stop_queue(vif->ndev);
2134
ce0dc0cf
RM
2135 if (vif->nw_type != AP_NETWORK) {
2136 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2137 ATH6KL_MAX_WOW_LISTEN_INTL,
2138 0);
2139 if (ret)
2140 return ret;
2141
2142 /* Set listen interval x 15 times as bmiss time */
2143 bmiss_time = ATH6KL_MAX_WOW_LISTEN_INTL * 15;
2144 if (bmiss_time > ATH6KL_MAX_BMISS_TIME)
2145 bmiss_time = ATH6KL_MAX_BMISS_TIME;
2146
2147 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2148 bmiss_time, 0);
2149 if (ret)
2150 return ret;
2151
2152 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2153 0xFFFF, 0, 0xFFFF, 0, 0, 0,
2154 0, 0, 0, 0);
2155 if (ret)
2156 return ret;
2157 }
2158
c08631c6
RM
2159 /* Setup own IP addr for ARP agent. */
2160 in_dev = __in_dev_get_rtnl(vif->ndev);
2161 if (!in_dev)
fd4377b6 2162 return 0;
c08631c6
RM
2163
2164 ifa = in_dev->ifa_list;
2165 memset(&ips, 0, sizeof(ips));
2166
2167 /* Configure IP addr only if IP address count < MAX_IP_ADDRS */
2168 while (index < MAX_IP_ADDRS && ifa) {
2169 ips[index] = ifa->ifa_local;
2170 ifa = ifa->ifa_next;
2171 index++;
2172 }
2173
2174 if (ifa) {
2175 ath6kl_err("total IP addr count is exceeding fw limit\n");
2176 return -EINVAL;
2177 }
2178
2179 ret = ath6kl_wmi_set_ip_cmd(ar->wmi, vif->fw_vif_idx, ips[0], ips[1]);
2180 if (ret) {
2181 ath6kl_err("fail to setup ip for arp agent\n");
2182 return ret;
2183 }
2184
fd4377b6
TP
2185 return ret;
2186}
2187
2188static int ath6kl_wow_suspend(struct ath6kl *ar, struct cfg80211_wowlan *wow)
2189{
2190 struct ath6kl_vif *first_vif, *vif;
2191 int ret = 0;
2192 u32 filter = 0;
2193 bool connected = false;
2194
2195 /* enter / leave wow suspend on first vif always */
2196 first_vif = ath6kl_vif_first(ar);
2197 if (WARN_ON(unlikely(!first_vif)) ||
2198 !ath6kl_cfg80211_ready(first_vif))
2199 return -EIO;
2200
2201 if (wow && (wow->n_patterns > WOW_MAX_FILTERS_PER_LIST))
2202 return -EINVAL;
2203
2204 /* install filters for each connected vif */
2205 spin_lock_bh(&ar->list_lock);
2206 list_for_each_entry(vif, &ar->vif_list, list) {
2207 if (!test_bit(CONNECTED, &vif->flags) ||
2208 !ath6kl_cfg80211_ready(vif))
2209 continue;
2210 connected = true;
2211
2212 ret = ath6kl_wow_suspend_vif(vif, wow, &filter);
2213 if (ret)
2214 break;
2215 }
2216 spin_unlock_bh(&ar->list_lock);
2217
2218 if (!connected)
2219 return -ENOTCONN;
2220 else if (ret)
2221 return ret;
2222
2223 ar->state = ATH6KL_STATE_SUSPENDING;
2224
2225 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, first_vif->fw_vif_idx,
6cb3c714
RM
2226 ATH6KL_WOW_MODE_ENABLE,
2227 filter,
2228 WOW_HOST_REQ_DELAY);
2229 if (ret)
2230 return ret;
2231
fd4377b6 2232 return ath6kl_cfg80211_host_sleep(ar, first_vif);
6cb3c714
RM
2233}
2234
fd4377b6 2235static int ath6kl_wow_resume_vif(struct ath6kl_vif *vif)
6cb3c714 2236{
fd4377b6 2237 struct ath6kl *ar = vif->ar;
6cb3c714
RM
2238 int ret;
2239
ce0dc0cf
RM
2240 if (vif->nw_type != AP_NETWORK) {
2241 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2242 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2243 if (ret)
2244 return ret;
2245
2246 ret = ath6kl_wmi_listeninterval_cmd(ar->wmi, vif->fw_vif_idx,
2247 vif->listen_intvl_t, 0);
2248 if (ret)
2249 return ret;
2250
2251 ret = ath6kl_wmi_bmisstime_cmd(ar->wmi, vif->fw_vif_idx,
2252 vif->bmiss_time_t, 0);
2253 if (ret)
2254 return ret;
2255 }
2256
6821d4f0
NG
2257 if (!test_bit(NETDEV_MCAST_ALL_OFF, &vif->flags) &&
2258 test_bit(ATH6KL_FW_CAPABILITY_WOW_MULTICAST_FILTER,
2259 ar->fw_capabilities)) {
6251d801 2260 ret = ath6kl_wmi_mcast_filter_cmd(vif->ar->wmi,
fd4377b6 2261 vif->fw_vif_idx, true);
6251d801
NG
2262 if (ret)
2263 return ret;
2264 }
2265
390a8c8f
RM
2266 netif_wake_queue(vif->ndev);
2267
2268 return 0;
6cb3c714
RM
2269}
2270
fd4377b6
TP
2271static int ath6kl_wow_resume(struct ath6kl *ar)
2272{
2273 struct ath6kl_vif *vif;
2274 int ret;
2275
2276 vif = ath6kl_vif_first(ar);
2277 if (WARN_ON(unlikely(!vif)) ||
2278 !ath6kl_cfg80211_ready(vif))
2279 return -EIO;
2280
2281 ar->state = ATH6KL_STATE_RESUMING;
2282
2283 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2284 ATH6KL_HOST_MODE_AWAKE);
2285 if (ret) {
2286 ath6kl_warn("Failed to configure host sleep mode for wow resume: %d\n",
2287 ret);
2288 goto cleanup;
2289 }
2290
2291 spin_lock_bh(&ar->list_lock);
2292 list_for_each_entry(vif, &ar->vif_list, list) {
2293 if (!test_bit(CONNECTED, &vif->flags) ||
2294 !ath6kl_cfg80211_ready(vif))
2295 continue;
2296 ret = ath6kl_wow_resume_vif(vif);
2297 if (ret)
2298 break;
2299 }
2300 spin_unlock_bh(&ar->list_lock);
2301
2302 if (ret)
2303 goto cleanup;
2304
2305 ar->state = ATH6KL_STATE_ON;
2306 return 0;
2307
2308cleanup:
2309 ar->state = ATH6KL_STATE_WOW;
2310 return ret;
2311}
2312
40abc2de
RM
2313static int ath6kl_cfg80211_deepsleep_suspend(struct ath6kl *ar)
2314{
2315 struct ath6kl_vif *vif;
2316 int ret;
2317
2318 vif = ath6kl_vif_first(ar);
2319 if (!vif)
2320 return -EIO;
2321
48f27587
MJ
2322 if (!test_bit(WMI_READY, &ar->flag)) {
2323 ath6kl_err("deepsleep failed as wmi is not ready\n");
40abc2de 2324 return -EIO;
48f27587 2325 }
40abc2de
RM
2326
2327 ath6kl_cfg80211_stop_all(ar);
2328
2329 /* Save the current power mode before enabling power save */
2330 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
2331
2332 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER);
2333 if (ret)
2334 return ret;
2335
2336 /* Disable WOW mode */
2337 ret = ath6kl_wmi_set_wow_mode_cmd(ar->wmi, vif->fw_vif_idx,
2338 ATH6KL_WOW_MODE_DISABLE,
2339 0, 0);
2340 if (ret)
2341 return ret;
2342
2343 /* Flush all non control pkts in TX path */
2344 ath6kl_tx_data_cleanup(ar);
2345
2346 ret = ath6kl_cfg80211_host_sleep(ar, vif);
2347 if (ret)
2348 return ret;
2349
2350 return 0;
2351}
2352
2353static int ath6kl_cfg80211_deepsleep_resume(struct ath6kl *ar)
2354{
2355 struct ath6kl_vif *vif;
2356 int ret;
2357
2358 vif = ath6kl_vif_first(ar);
2359
2360 if (!vif)
2361 return -EIO;
2362
2363 if (ar->wmi->pwr_mode != ar->wmi->saved_pwr_mode) {
2364 ret = ath6kl_wmi_powermode_cmd(ar->wmi, 0,
2365 ar->wmi->saved_pwr_mode);
2366 if (ret)
2367 return ret;
2368 }
2369
2370 ret = ath6kl_wmi_set_host_sleep_mode_cmd(ar->wmi, vif->fw_vif_idx,
2371 ATH6KL_HOST_MODE_AWAKE);
2372 if (ret)
2373 return ret;
2374
2375 ar->state = ATH6KL_STATE_ON;
2376
2377 /* Reset scan parameter to default values */
2378 ret = ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
2379 0, 0, 0, 0, 0, 0, 3, 0, 0, 0);
2380 if (ret)
2381 return ret;
2382
2383 return 0;
2384}
2385
52d81a68 2386int ath6kl_cfg80211_suspend(struct ath6kl *ar,
0f60e9f4
RM
2387 enum ath6kl_cfg_suspend_mode mode,
2388 struct cfg80211_wowlan *wow)
52d81a68 2389{
3d79499c 2390 struct ath6kl_vif *vif;
390a8c8f 2391 enum ath6kl_state prev_state;
52d81a68
KV
2392 int ret;
2393
52d81a68 2394 switch (mode) {
d7c44e0b
RM
2395 case ATH6KL_CFG_SUSPEND_WOW:
2396
2397 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode suspend\n");
2398
2399 /* Flush all non control pkts in TX path */
2400 ath6kl_tx_data_cleanup(ar);
2401
390a8c8f
RM
2402 prev_state = ar->state;
2403
d7c44e0b 2404 ret = ath6kl_wow_suspend(ar, wow);
390a8c8f
RM
2405 if (ret) {
2406 ar->state = prev_state;
d7c44e0b 2407 return ret;
390a8c8f 2408 }
1e9a905d 2409
d7c44e0b
RM
2410 ar->state = ATH6KL_STATE_WOW;
2411 break;
2412
52d81a68 2413 case ATH6KL_CFG_SUSPEND_DEEPSLEEP:
524441e3 2414
40abc2de 2415 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep suspend\n");
52d81a68 2416
40abc2de 2417 ret = ath6kl_cfg80211_deepsleep_suspend(ar);
52d81a68 2418 if (ret) {
40abc2de
RM
2419 ath6kl_err("deepsleep suspend failed: %d\n", ret);
2420 return ret;
52d81a68
KV
2421 }
2422
76a9fbe2
KV
2423 ar->state = ATH6KL_STATE_DEEPSLEEP;
2424
52d81a68 2425 break;
b4b2a0b1
KV
2426
2427 case ATH6KL_CFG_SUSPEND_CUTPOWER:
524441e3 2428
7125f01d 2429 ath6kl_cfg80211_stop_all(ar);
524441e3 2430
b4b2a0b1
KV
2431 if (ar->state == ATH6KL_STATE_OFF) {
2432 ath6kl_dbg(ATH6KL_DBG_SUSPEND,
2433 "suspend hw off, no action for cutpower\n");
2434 break;
2435 }
2436
2437 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "suspend cutting power\n");
2438
2439 ret = ath6kl_init_hw_stop(ar);
2440 if (ret) {
2441 ath6kl_warn("failed to stop hw during suspend: %d\n",
2442 ret);
2443 }
2444
2445 ar->state = ATH6KL_STATE_CUTPOWER;
2446
2447 break;
2448
2449 default:
2450 break;
52d81a68
KV
2451 }
2452
3d79499c
VN
2453 list_for_each_entry(vif, &ar->vif_list, list)
2454 ath6kl_cfg80211_scan_complete_event(vif, true);
2455
52d81a68
KV
2456 return 0;
2457}
d6a434d6 2458EXPORT_SYMBOL(ath6kl_cfg80211_suspend);
52d81a68
KV
2459
2460int ath6kl_cfg80211_resume(struct ath6kl *ar)
2461{
76a9fbe2
KV
2462 int ret;
2463
2464 switch (ar->state) {
d7c44e0b
RM
2465 case ATH6KL_STATE_WOW:
2466 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "wow mode resume\n");
2467
2468 ret = ath6kl_wow_resume(ar);
2469 if (ret) {
2470 ath6kl_warn("wow mode resume failed: %d\n", ret);
2471 return ret;
2472 }
2473
d7c44e0b
RM
2474 break;
2475
76a9fbe2 2476 case ATH6KL_STATE_DEEPSLEEP:
40abc2de 2477 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "deep sleep resume\n");
76a9fbe2 2478
40abc2de
RM
2479 ret = ath6kl_cfg80211_deepsleep_resume(ar);
2480 if (ret) {
2481 ath6kl_warn("deep sleep resume failed: %d\n", ret);
2482 return ret;
2483 }
76a9fbe2
KV
2484 break;
2485
b4b2a0b1
KV
2486 case ATH6KL_STATE_CUTPOWER:
2487 ath6kl_dbg(ATH6KL_DBG_SUSPEND, "resume restoring power\n");
2488
2489 ret = ath6kl_init_hw_start(ar);
2490 if (ret) {
2491 ath6kl_warn("Failed to boot hw in resume: %d\n", ret);
2492 return ret;
2493 }
d7c44e0b 2494 break;
b4b2a0b1 2495
76a9fbe2
KV
2496 default:
2497 break;
52d81a68
KV
2498 }
2499
2500 return 0;
2501}
d6a434d6 2502EXPORT_SYMBOL(ath6kl_cfg80211_resume);
52d81a68 2503
abcb344b 2504#ifdef CONFIG_PM
52d81a68
KV
2505
2506/* hif layer decides what suspend mode to use */
2507static int __ath6kl_cfg80211_suspend(struct wiphy *wiphy,
abcb344b
KV
2508 struct cfg80211_wowlan *wow)
2509{
2510 struct ath6kl *ar = wiphy_priv(wiphy);
2511
84caf800
VT
2512 ath6kl_recovery_suspend(ar);
2513
0f60e9f4 2514 return ath6kl_hif_suspend(ar, wow);
abcb344b 2515}
aa6cffc1 2516
52d81a68 2517static int __ath6kl_cfg80211_resume(struct wiphy *wiphy)
aa6cffc1
CN
2518{
2519 struct ath6kl *ar = wiphy_priv(wiphy);
84caf800
VT
2520 int err;
2521
2522 err = ath6kl_hif_resume(ar);
2523 if (err)
2524 return err;
aa6cffc1 2525
92332993 2526 ath6kl_recovery_resume(ar);
aa6cffc1 2527
84caf800 2528 return 0;
aa6cffc1 2529}
a918fb3c
RM
2530
2531/*
2532 * FIXME: WOW suspend mode is selected if the host sdio controller supports
2533 * both sdio irq wake up and keep power. The target pulls sdio data line to
2534 * wake up the host when WOW pattern matches. This causes sdio irq handler
2535 * is being called in the host side which internally hits ath6kl's RX path.
2536 *
2537 * Since sdio interrupt is not disabled, RX path executes even before
2538 * the host executes the actual resume operation from PM module.
2539 *
2540 * In the current scenario, WOW resume should happen before start processing
2541 * any data from the target. So It's required to perform WOW resume in RX path.
2542 * Ideally we should perform WOW resume only in the actual platform
2543 * resume path. This area needs bit rework to avoid WOW resume in RX path.
2544 *
2545 * ath6kl_check_wow_status() is called from ath6kl_rx().
2546 */
2547void ath6kl_check_wow_status(struct ath6kl *ar)
2548{
390a8c8f
RM
2549 if (ar->state == ATH6KL_STATE_SUSPENDING)
2550 return;
2551
a918fb3c
RM
2552 if (ar->state == ATH6KL_STATE_WOW)
2553 ath6kl_cfg80211_resume(ar);
2554}
2555
2556#else
2557
2558void ath6kl_check_wow_status(struct ath6kl *ar)
2559{
2560}
abcb344b
KV
2561#endif
2562
df90b369
VT
2563static int ath6kl_set_htcap(struct ath6kl_vif *vif, enum ieee80211_band band,
2564 bool ht_enable)
6a7c9bad 2565{
67b3f129 2566 struct ath6kl_htcap *htcap = &vif->htcap[band];
6a7c9bad 2567
df90b369
VT
2568 if (htcap->ht_enable == ht_enable)
2569 return 0;
6a7c9bad 2570
df90b369
VT
2571 if (ht_enable) {
2572 /* Set default ht capabilities */
2573 htcap->ht_enable = true;
2574 htcap->cap_info = (band == IEEE80211_BAND_2GHZ) ?
2575 ath6kl_g_htcap : ath6kl_a_htcap;
2576 htcap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_16K;
2577 } else /* Disable ht */
2578 memset(htcap, 0, sizeof(*htcap));
6a7c9bad 2579
df90b369
VT
2580 return ath6kl_wmi_set_htcap_cmd(vif->ar->wmi, vif->fw_vif_idx,
2581 band, htcap);
6a7c9bad
JM
2582}
2583
37a2f950
TP
2584static int ath6kl_restore_htcap(struct ath6kl_vif *vif)
2585{
2586 struct wiphy *wiphy = vif->ar->wiphy;
2587 int band, ret = 0;
2588
2589 for (band = 0; band < IEEE80211_NUM_BANDS; band++) {
2590 if (!wiphy->bands[band])
2591 continue;
2592
2593 ret = ath6kl_set_htcap(vif, band,
2594 wiphy->bands[band]->ht_cap.ht_supported);
2595 if (ret)
2596 return ret;
2597 }
2598
2599 return ret;
2600}
2601
8bdfbf40
JM
2602static bool ath6kl_is_p2p_ie(const u8 *pos)
2603{
2604 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
2605 pos[2] == 0x50 && pos[3] == 0x6f &&
2606 pos[4] == 0x9a && pos[5] == 0x09;
2607}
2608
334234b5
VT
2609static int ath6kl_set_ap_probe_resp_ies(struct ath6kl_vif *vif,
2610 const u8 *ies, size_t ies_len)
8bdfbf40 2611{
334234b5 2612 struct ath6kl *ar = vif->ar;
8bdfbf40
JM
2613 const u8 *pos;
2614 u8 *buf = NULL;
2615 size_t len = 0;
2616 int ret;
2617
2618 /*
2619 * Filter out P2P IE(s) since they will be included depending on
2620 * the Probe Request frame in ath6kl_send_go_probe_resp().
2621 */
2622
2623 if (ies && ies_len) {
2624 buf = kmalloc(ies_len, GFP_KERNEL);
2625 if (buf == NULL)
2626 return -ENOMEM;
2627 pos = ies;
2628 while (pos + 1 < ies + ies_len) {
2629 if (pos + 2 + pos[1] > ies + ies_len)
2630 break;
2631 if (!ath6kl_is_p2p_ie(pos)) {
2632 memcpy(buf + len, pos, 2 + pos[1]);
2633 len += 2 + pos[1];
2634 }
2635 pos += 2 + pos[1];
2636 }
2637 }
2638
334234b5
VT
2639 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2640 WMI_FRAME_PROBE_RESP, buf, len);
8bdfbf40
JM
2641 kfree(buf);
2642 return ret;
2643}
2644
8860020e
JB
2645static int ath6kl_set_ies(struct ath6kl_vif *vif,
2646 struct cfg80211_beacon_data *info)
6a7c9bad 2647{
8860020e 2648 struct ath6kl *ar = vif->ar;
6a7c9bad 2649 int res;
6a7c9bad 2650
17a7b16d
AT
2651 /* this also clears IE in fw if it's not set */
2652 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2653 WMI_FRAME_BEACON,
2654 info->beacon_ies,
2655 info->beacon_ies_len);
2656 if (res)
2657 return res;
2658
2659 /* this also clears IE in fw if it's not set */
2660 res = ath6kl_set_ap_probe_resp_ies(vif, info->proberesp_ies,
2661 info->proberesp_ies_len);
2662 if (res)
2663 return res;
2664
2665 /* this also clears IE in fw if it's not set */
2666 res = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
2667 WMI_FRAME_ASSOC_RESP,
2668 info->assocresp_ies,
2669 info->assocresp_ies_len);
2670 if (res)
2671 return res;
6a7c9bad 2672
8860020e
JB
2673 return 0;
2674}
2675
c422d52d
TP
2676void ath6kl_cfg80211_sta_bmiss_enhance(struct ath6kl_vif *vif, bool enable)
2677{
2678 int err;
2679
2680 if (WARN_ON(!test_bit(WMI_READY, &vif->ar->flag)))
2681 return;
2682
2683 if (vif->nw_type != INFRA_NETWORK)
2684 return;
2685
2686 if (!test_bit(ATH6KL_FW_CAPABILITY_BMISS_ENHANCE,
2687 vif->ar->fw_capabilities))
2688 return;
2689
2690 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s fw bmiss enhance\n",
2691 enable ? "enable" : "disable");
2692
2693 err = ath6kl_wmi_sta_bmiss_enhance_cmd(vif->ar->wmi,
2694 vif->fw_vif_idx, enable);
2695 if (err)
2696 ath6kl_err("failed to %s enhanced bmiss detection: %d\n",
2697 enable ? "enable" : "disable", err);
2698}
2699
d97c121b
VT
2700static int ath6kl_get_rsn_capab(struct cfg80211_beacon_data *beacon,
2701 u8 *rsn_capab)
2702{
2703 const u8 *rsn_ie;
2704 size_t rsn_ie_len;
2705 u16 cnt;
2706
2707 if (!beacon->tail)
2708 return -EINVAL;
2709
2710 rsn_ie = cfg80211_find_ie(WLAN_EID_RSN, beacon->tail, beacon->tail_len);
2711 if (!rsn_ie)
2712 return -EINVAL;
2713
2714 rsn_ie_len = *(rsn_ie + 1);
2715 /* skip element id and length */
2716 rsn_ie += 2;
2717
9e8b16db
VT
2718 /* skip version */
2719 if (rsn_ie_len < 2)
d97c121b 2720 return -EINVAL;
9e8b16db
VT
2721 rsn_ie += 2;
2722 rsn_ie_len -= 2;
2723
2724 /* skip group cipher suite */
2725 if (rsn_ie_len < 4)
2726 return 0;
2727 rsn_ie += 4;
2728 rsn_ie_len -= 4;
d97c121b
VT
2729
2730 /* skip pairwise cipher suite */
2731 if (rsn_ie_len < 2)
9e8b16db 2732 return 0;
798985c6 2733 cnt = get_unaligned_le16(rsn_ie);
d97c121b
VT
2734 rsn_ie += (2 + cnt * 4);
2735 rsn_ie_len -= (2 + cnt * 4);
2736
2737 /* skip akm suite */
2738 if (rsn_ie_len < 2)
9e8b16db 2739 return 0;
798985c6 2740 cnt = get_unaligned_le16(rsn_ie);
d97c121b
VT
2741 rsn_ie += (2 + cnt * 4);
2742 rsn_ie_len -= (2 + cnt * 4);
2743
2744 if (rsn_ie_len < 2)
9e8b16db 2745 return 0;
d97c121b
VT
2746
2747 memcpy(rsn_capab, rsn_ie, 2);
2748
2749 return 0;
2750}
2751
8860020e
JB
2752static int ath6kl_start_ap(struct wiphy *wiphy, struct net_device *dev,
2753 struct cfg80211_ap_settings *info)
6a7c9bad
JM
2754{
2755 struct ath6kl *ar = ath6kl_priv(dev);
3450334f 2756 struct ath6kl_vif *vif = netdev_priv(dev);
6a7c9bad 2757 struct ieee80211_mgmt *mgmt;
67cd22e4 2758 bool hidden = false;
6a7c9bad
JM
2759 u8 *ies;
2760 int ies_len;
2761 struct wmi_connect_cmd p;
2762 int res;
be5abaaf 2763 int i, ret;
d97c121b 2764 u16 rsn_capab = 0;
7ac25eac 2765 int inactivity_timeout = 0;
6a7c9bad 2766
8860020e 2767 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s:\n", __func__);
6a7c9bad 2768
990bd915 2769 if (!ath6kl_cfg80211_ready(vif))
6a7c9bad
JM
2770 return -EIO;
2771
f5938f24 2772 if (vif->next_mode != AP_NETWORK)
6a7c9bad
JM
2773 return -EOPNOTSUPP;
2774
8860020e 2775 res = ath6kl_set_ies(vif, &info->beacon);
6a7c9bad 2776
9a5b1318
JM
2777 ar->ap_mode_bkey.valid = false;
2778
6a7c9bad
JM
2779 /* TODO:
2780 * info->interval
6a7c9bad
JM
2781 */
2782
d154f32e
EL
2783 ret = ath6kl_wmi_ap_set_dtim_cmd(ar->wmi, vif->fw_vif_idx,
2784 info->dtim_period);
2785
2786 /* ignore error, just print a warning and continue normally */
2787 if (ret)
2788 ath6kl_warn("Failed to set dtim_period in beacon: %d\n", ret);
2789
8860020e 2790 if (info->beacon.head == NULL)
6a7c9bad 2791 return -EINVAL;
8860020e 2792 mgmt = (struct ieee80211_mgmt *) info->beacon.head;
6a7c9bad 2793 ies = mgmt->u.beacon.variable;
8860020e 2794 if (ies > info->beacon.head + info->beacon.head_len)
6a7c9bad 2795 return -EINVAL;
8860020e 2796 ies_len = info->beacon.head + info->beacon.head_len - ies;
6a7c9bad
JM
2797
2798 if (info->ssid == NULL)
2799 return -EINVAL;
3450334f
VT
2800 memcpy(vif->ssid, info->ssid, info->ssid_len);
2801 vif->ssid_len = info->ssid_len;
6a7c9bad 2802 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
67cd22e4
TP
2803 hidden = true;
2804
2805 res = ath6kl_wmi_ap_hidden_ssid(ar->wmi, vif->fw_vif_idx, hidden);
2806 if (res)
2807 return res;
6a7c9bad 2808
be5abaaf
VT
2809 ret = ath6kl_set_auth_type(vif, info->auth_type);
2810 if (ret)
2811 return ret;
6a7c9bad
JM
2812
2813 memset(&p, 0, sizeof(p));
2814
2815 for (i = 0; i < info->crypto.n_akm_suites; i++) {
2816 switch (info->crypto.akm_suites[i]) {
2817 case WLAN_AKM_SUITE_8021X:
2818 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2819 p.auth_mode |= WPA_AUTH;
2820 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2821 p.auth_mode |= WPA2_AUTH;
2822 break;
2823 case WLAN_AKM_SUITE_PSK:
2824 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
2825 p.auth_mode |= WPA_PSK_AUTH;
2826 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
2827 p.auth_mode |= WPA2_PSK_AUTH;
2828 break;
2829 }
2830 }
2831 if (p.auth_mode == 0)
2832 p.auth_mode = NONE_AUTH;
3450334f 2833 vif->auth_mode = p.auth_mode;
6a7c9bad
JM
2834
2835 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
2836 switch (info->crypto.ciphers_pairwise[i]) {
2837 case WLAN_CIPHER_SUITE_WEP40:
2838 case WLAN_CIPHER_SUITE_WEP104:
2839 p.prwise_crypto_type |= WEP_CRYPT;
2840 break;
2841 case WLAN_CIPHER_SUITE_TKIP:
2842 p.prwise_crypto_type |= TKIP_CRYPT;
2843 break;
2844 case WLAN_CIPHER_SUITE_CCMP:
2845 p.prwise_crypto_type |= AES_CRYPT;
2846 break;
b8214df1
DS
2847 case WLAN_CIPHER_SUITE_SMS4:
2848 p.prwise_crypto_type |= WAPI_CRYPT;
2849 break;
6a7c9bad
JM
2850 }
2851 }
229ed6b5 2852 if (p.prwise_crypto_type == 0) {
6a7c9bad 2853 p.prwise_crypto_type = NONE_CRYPT;
240d2799 2854 ath6kl_set_cipher(vif, 0, true);
229ed6b5 2855 } else if (info->crypto.n_ciphers_pairwise == 1)
240d2799 2856 ath6kl_set_cipher(vif, info->crypto.ciphers_pairwise[0], true);
6a7c9bad
JM
2857
2858 switch (info->crypto.cipher_group) {
2859 case WLAN_CIPHER_SUITE_WEP40:
2860 case WLAN_CIPHER_SUITE_WEP104:
2861 p.grp_crypto_type = WEP_CRYPT;
2862 break;
2863 case WLAN_CIPHER_SUITE_TKIP:
2864 p.grp_crypto_type = TKIP_CRYPT;
2865 break;
2866 case WLAN_CIPHER_SUITE_CCMP:
2867 p.grp_crypto_type = AES_CRYPT;
2868 break;
b8214df1
DS
2869 case WLAN_CIPHER_SUITE_SMS4:
2870 p.grp_crypto_type = WAPI_CRYPT;
2871 break;
6a7c9bad
JM
2872 default:
2873 p.grp_crypto_type = NONE_CRYPT;
2874 break;
2875 }
240d2799 2876 ath6kl_set_cipher(vif, info->crypto.cipher_group, false);
6a7c9bad
JM
2877
2878 p.nw_type = AP_NETWORK;
f5938f24 2879 vif->nw_type = vif->next_mode;
6a7c9bad 2880
3450334f
VT
2881 p.ssid_len = vif->ssid_len;
2882 memcpy(p.ssid, vif->ssid, vif->ssid_len);
2883 p.dot11_auth_mode = vif->dot11_auth_mode;
683b6d3b 2884 p.ch = cpu_to_le16(info->chandef.chan->center_freq);
6a7c9bad 2885
c1762a3f
TP
2886 /* Enable uAPSD support by default */
2887 res = ath6kl_wmi_ap_set_apsd(ar->wmi, vif->fw_vif_idx, true);
2888 if (res < 0)
2889 return res;
2890
3ca9d1fc
AT
2891 if (vif->wdev.iftype == NL80211_IFTYPE_P2P_GO) {
2892 p.nw_subtype = SUBTYPE_P2PGO;
2893 } else {
2894 /*
2895 * Due to firmware limitation, it is not possible to
2896 * do P2P mgmt operations in AP mode
2897 */
2898 p.nw_subtype = SUBTYPE_NONE;
2899 }
2900
03bdeb0d 2901 if (info->inactivity_timeout) {
7ac25eac
MSS
2902
2903 inactivity_timeout = info->inactivity_timeout;
2904
2905 if (ar->hw.flags & ATH6KL_HW_AP_INACTIVITY_MINS)
2906 inactivity_timeout = DIV_ROUND_UP(inactivity_timeout,
2907 60);
2908
03bdeb0d 2909 res = ath6kl_wmi_set_inact_period(ar->wmi, vif->fw_vif_idx,
7ac25eac 2910 inactivity_timeout);
03bdeb0d
VT
2911 if (res < 0)
2912 return res;
2913 }
2914
683b6d3b
JB
2915 if (ath6kl_set_htcap(vif, info->chandef.chan->band,
2916 cfg80211_get_chandef_type(&info->chandef)
2917 != NL80211_CHAN_NO_HT))
df90b369
VT
2918 return -EIO;
2919
d97c121b
VT
2920 /*
2921 * Get the PTKSA replay counter in the RSN IE. Supplicant
2922 * will use the RSN IE in M3 message and firmware has to
2923 * advertise the same in beacon/probe response. Send
2924 * the complete RSN IE capability field to firmware
2925 */
2926 if (!ath6kl_get_rsn_capab(&info->beacon, (u8 *) &rsn_capab) &&
2927 test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
2928 ar->fw_capabilities)) {
2929 res = ath6kl_wmi_set_ie_cmd(ar->wmi, vif->fw_vif_idx,
2930 WLAN_EID_RSN, WMI_RSN_IE_CAPB,
2931 (const u8 *) &rsn_capab,
2932 sizeof(rsn_capab));
f21243a8 2933 vif->rsn_capab = rsn_capab;
d97c121b
VT
2934 if (res < 0)
2935 return res;
2936 }
2937
c4f7863e 2938 memcpy(&vif->profile, &p, sizeof(p));
334234b5 2939 res = ath6kl_wmi_ap_profile_commit(ar->wmi, vif->fw_vif_idx, &p);
9a5b1318
JM
2940 if (res < 0)
2941 return res;
2942
2943 return 0;
6a7c9bad
JM
2944}
2945
8860020e
JB
2946static int ath6kl_change_beacon(struct wiphy *wiphy, struct net_device *dev,
2947 struct cfg80211_beacon_data *beacon)
6a7c9bad 2948{
8860020e 2949 struct ath6kl_vif *vif = netdev_priv(dev);
6a7c9bad 2950
8860020e
JB
2951 if (!ath6kl_cfg80211_ready(vif))
2952 return -EIO;
2953
2954 if (vif->next_mode != AP_NETWORK)
2955 return -EOPNOTSUPP;
2956
2957 return ath6kl_set_ies(vif, beacon);
6a7c9bad
JM
2958}
2959
8860020e 2960static int ath6kl_stop_ap(struct wiphy *wiphy, struct net_device *dev)
6a7c9bad
JM
2961{
2962 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 2963 struct ath6kl_vif *vif = netdev_priv(dev);
6a7c9bad 2964
f5938f24 2965 if (vif->nw_type != AP_NETWORK)
6a7c9bad 2966 return -EOPNOTSUPP;
59c98449 2967 if (!test_bit(CONNECTED, &vif->flags))
6a7c9bad
JM
2968 return -ENOTCONN;
2969
334234b5 2970 ath6kl_wmi_disconnect_cmd(ar->wmi, vif->fw_vif_idx);
59c98449 2971 clear_bit(CONNECTED, &vif->flags);
6a7c9bad 2972
df90b369 2973 /* Restore ht setting in firmware */
37a2f950 2974 return ath6kl_restore_htcap(vif);
6a7c9bad
JM
2975}
2976
33e5308d
JM
2977static const u8 bcast_addr[ETH_ALEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
2978
2979static int ath6kl_del_station(struct wiphy *wiphy, struct net_device *dev,
2980 u8 *mac)
2981{
2982 struct ath6kl *ar = ath6kl_priv(dev);
2983 struct ath6kl_vif *vif = netdev_priv(dev);
2984 const u8 *addr = mac ? mac : bcast_addr;
2985
2986 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx, WMI_AP_DEAUTH,
2987 addr, WLAN_REASON_PREV_AUTH_NOT_VALID);
2988}
2989
23875136
JM
2990static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
2991 u8 *mac, struct station_parameters *params)
2992{
2993 struct ath6kl *ar = ath6kl_priv(dev);
f5938f24 2994 struct ath6kl_vif *vif = netdev_priv(dev);
23875136 2995
f5938f24 2996 if (vif->nw_type != AP_NETWORK)
23875136
JM
2997 return -EOPNOTSUPP;
2998
2999 /* Use this only for authorizing/unauthorizing a station */
3000 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
3001 return -EOPNOTSUPP;
3002
3003 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
334234b5
VT
3004 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3005 WMI_AP_MLME_AUTHORIZE, mac, 0);
3006 return ath6kl_wmi_ap_set_mlme(ar->wmi, vif->fw_vif_idx,
3007 WMI_AP_MLME_UNAUTHORIZE, mac, 0);
23875136
JM
3008}
3009
63fa1e0c 3010static int ath6kl_remain_on_channel(struct wiphy *wiphy,
71bbc994 3011 struct wireless_dev *wdev,
63fa1e0c 3012 struct ieee80211_channel *chan,
63fa1e0c
JM
3013 unsigned int duration,
3014 u64 *cookie)
3015{
71bbc994
JB
3016 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3017 struct ath6kl *ar = ath6kl_priv(vif->ndev);
1052261e 3018 u32 id;
63fa1e0c
JM
3019
3020 /* TODO: if already pending or ongoing remain-on-channel,
3021 * return -EBUSY */
1052261e
JM
3022 id = ++vif->last_roc_id;
3023 if (id == 0) {
3024 /* Do not use 0 as the cookie value */
3025 id = ++vif->last_roc_id;
3026 }
3027 *cookie = id;
63fa1e0c 3028
334234b5
VT
3029 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx,
3030 chan->center_freq, duration);
63fa1e0c
JM
3031}
3032
3033static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
71bbc994 3034 struct wireless_dev *wdev,
63fa1e0c
JM
3035 u64 cookie)
3036{
71bbc994
JB
3037 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3038 struct ath6kl *ar = ath6kl_priv(vif->ndev);
63fa1e0c 3039
1052261e 3040 if (cookie != vif->last_roc_id)
63fa1e0c 3041 return -ENOENT;
1052261e 3042 vif->last_cancel_roc_id = cookie;
63fa1e0c 3043
334234b5 3044 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi, vif->fw_vif_idx);
63fa1e0c
JM
3045}
3046
334234b5
VT
3047static int ath6kl_send_go_probe_resp(struct ath6kl_vif *vif,
3048 const u8 *buf, size_t len,
3049 unsigned int freq)
8bdfbf40 3050{
334234b5 3051 struct ath6kl *ar = vif->ar;
8bdfbf40
JM
3052 const u8 *pos;
3053 u8 *p2p;
3054 int p2p_len;
3055 int ret;
3056 const struct ieee80211_mgmt *mgmt;
3057
3058 mgmt = (const struct ieee80211_mgmt *) buf;
3059
3060 /* Include P2P IE(s) from the frame generated in user space. */
3061
3062 p2p = kmalloc(len, GFP_KERNEL);
3063 if (p2p == NULL)
3064 return -ENOMEM;
3065 p2p_len = 0;
3066
3067 pos = mgmt->u.probe_resp.variable;
3068 while (pos + 1 < buf + len) {
3069 if (pos + 2 + pos[1] > buf + len)
3070 break;
3071 if (ath6kl_is_p2p_ie(pos)) {
3072 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
3073 p2p_len += 2 + pos[1];
3074 }
3075 pos += 2 + pos[1];
3076 }
3077
334234b5
VT
3078 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, vif->fw_vif_idx, freq,
3079 mgmt->da, p2p, p2p_len);
8bdfbf40
JM
3080 kfree(p2p);
3081 return ret;
3082}
3083
d0ff7383
NG
3084static bool ath6kl_mgmt_powersave_ap(struct ath6kl_vif *vif,
3085 u32 id,
3086 u32 freq,
3087 u32 wait,
3088 const u8 *buf,
3089 size_t len,
3090 bool *more_data,
3091 bool no_cck)
3092{
3093 struct ieee80211_mgmt *mgmt;
3094 struct ath6kl_sta *conn;
3095 bool is_psq_empty = false;
3096 struct ath6kl_mgmt_buff *mgmt_buf;
3097 size_t mgmt_buf_size;
3098 struct ath6kl *ar = vif->ar;
3099
3100 mgmt = (struct ieee80211_mgmt *) buf;
3101 if (is_multicast_ether_addr(mgmt->da))
3102 return false;
3103
3104 conn = ath6kl_find_sta(vif, mgmt->da);
3105 if (!conn)
3106 return false;
3107
3108 if (conn->sta_flags & STA_PS_SLEEP) {
3109 if (!(conn->sta_flags & STA_PS_POLLED)) {
3110 /* Queue the frames if the STA is sleeping */
3111 mgmt_buf_size = len + sizeof(struct ath6kl_mgmt_buff);
3112 mgmt_buf = kmalloc(mgmt_buf_size, GFP_KERNEL);
3113 if (!mgmt_buf)
3114 return false;
3115
3116 INIT_LIST_HEAD(&mgmt_buf->list);
3117 mgmt_buf->id = id;
3118 mgmt_buf->freq = freq;
3119 mgmt_buf->wait = wait;
3120 mgmt_buf->len = len;
3121 mgmt_buf->no_cck = no_cck;
3122 memcpy(mgmt_buf->buf, buf, len);
3123 spin_lock_bh(&conn->psq_lock);
3124 is_psq_empty = skb_queue_empty(&conn->psq) &&
3125 (conn->mgmt_psq_len == 0);
3126 list_add_tail(&mgmt_buf->list, &conn->mgmt_psq);
3127 conn->mgmt_psq_len++;
3128 spin_unlock_bh(&conn->psq_lock);
3129
3130 /*
3131 * If this is the first pkt getting queued
3132 * for this STA, update the PVB for this
3133 * STA.
3134 */
3135 if (is_psq_empty)
3136 ath6kl_wmi_set_pvb_cmd(ar->wmi, vif->fw_vif_idx,
3137 conn->aid, 1);
3138 return true;
3139 }
3140
3141 /*
3142 * This tx is because of a PsPoll.
3143 * Determine if MoreData bit has to be set.
3144 */
3145 spin_lock_bh(&conn->psq_lock);
3146 if (!skb_queue_empty(&conn->psq) || (conn->mgmt_psq_len != 0))
3147 *more_data = true;
3148 spin_unlock_bh(&conn->psq_lock);
3149 }
3150
3151 return false;
3152}
3153
c86e4f44
AT
3154/* Check if SSID length is greater than DIRECT- */
3155static bool ath6kl_is_p2p_go_ssid(const u8 *buf, size_t len)
3156{
3157 const struct ieee80211_mgmt *mgmt;
3158 mgmt = (const struct ieee80211_mgmt *) buf;
3159
3160 /* variable[1] contains the SSID tag length */
3161 if (buf + len >= &mgmt->u.probe_resp.variable[1] &&
3162 (mgmt->u.probe_resp.variable[1] > P2P_WILDCARD_SSID_LEN)) {
3163 return true;
3164 }
3165
3166 return false;
3167}
3168
71bbc994 3169static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev,
8a6c8060 3170 struct ieee80211_channel *chan, bool offchan,
42d97a59
JB
3171 unsigned int wait, const u8 *buf, size_t len,
3172 bool no_cck, bool dont_wait_for_ack, u64 *cookie)
8a6c8060 3173{
71bbc994
JB
3174 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
3175 struct ath6kl *ar = ath6kl_priv(vif->ndev);
8a6c8060 3176 u32 id;
8bdfbf40 3177 const struct ieee80211_mgmt *mgmt;
d0ff7383 3178 bool more_data, queued;
8bdfbf40
JM
3179
3180 mgmt = (const struct ieee80211_mgmt *) buf;
c86e4f44
AT
3181 if (vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
3182 ieee80211_is_probe_resp(mgmt->frame_control) &&
3183 ath6kl_is_p2p_go_ssid(buf, len)) {
8bdfbf40 3184 /*
c86e4f44 3185 * Send Probe Response frame in GO mode using a separate WMI
8bdfbf40
JM
3186 * command to allow the target to fill in the generic IEs.
3187 */
3188 *cookie = 0; /* TX status not supported */
334234b5 3189 return ath6kl_send_go_probe_resp(vif, buf, len,
8bdfbf40
JM
3190 chan->center_freq);
3191 }
8a6c8060 3192
cf5333d7 3193 id = vif->send_action_id++;
8a6c8060
JM
3194 if (id == 0) {
3195 /*
3196 * 0 is a reserved value in the WMI command and shall not be
3197 * used for the command.
3198 */
cf5333d7 3199 id = vif->send_action_id++;
8a6c8060
JM
3200 }
3201
3202 *cookie = id;
3ca9d1fc 3203
d0ff7383
NG
3204 /* AP mode Power saving processing */
3205 if (vif->nw_type == AP_NETWORK) {
3206 queued = ath6kl_mgmt_powersave_ap(vif,
3207 id, chan->center_freq,
3208 wait, buf,
3209 len, &more_data, no_cck);
3210 if (queued)
3211 return 0;
3ca9d1fc 3212 }
d0ff7383
NG
3213
3214 return ath6kl_wmi_send_mgmt_cmd(ar->wmi, vif->fw_vif_idx, id,
3215 chan->center_freq, wait,
3216 buf, len, no_cck);
8a6c8060
JM
3217}
3218
ae32c30a 3219static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
71bbc994 3220 struct wireless_dev *wdev,
ae32c30a
JM
3221 u16 frame_type, bool reg)
3222{
71bbc994 3223 struct ath6kl_vif *vif = ath6kl_vif_from_wdev(wdev);
ae32c30a
JM
3224
3225 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
3226 __func__, frame_type, reg);
3227 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
3228 /*
3229 * Note: This notification callback is not allowed to sleep, so
3230 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
3231 * hardcode target to report Probe Request frames all the time.
3232 */
cf5333d7 3233 vif->probe_req_report = reg;
ae32c30a
JM
3234 }
3235}
3236
10509f90
KV
3237static int ath6kl_cfg80211_sscan_start(struct wiphy *wiphy,
3238 struct net_device *dev,
3239 struct cfg80211_sched_scan_request *request)
3240{
3241 struct ath6kl *ar = ath6kl_priv(dev);
3242 struct ath6kl_vif *vif = netdev_priv(dev);
3243 u16 interval;
85b20fc2 3244 int ret, rssi_thold;
10509f90
KV
3245
3246 if (ar->state != ATH6KL_STATE_ON)
3247 return -EIO;
3248
3249 if (vif->sme_state != SME_DISCONNECTED)
3250 return -EBUSY;
3251
b4d13d3b
KV
3252 ath6kl_cfg80211_scan_complete_event(vif, true);
3253
3b8ffc6a 3254 ret = ath6kl_set_probed_ssids(ar, vif, request->ssids,
dd45b759
NS
3255 request->n_ssids,
3256 request->match_sets,
3257 request->n_match_sets);
3b8ffc6a
JM
3258 if (ret < 0)
3259 return ret;
10509f90 3260
dd45b759
NS
3261 if (!request->n_match_sets) {
3262 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3263 ALL_BSS_FILTER, 0);
3264 if (ret < 0)
3265 return ret;
3266 } else {
3267 ret = ath6kl_wmi_bssfilter_cmd(ar->wmi, vif->fw_vif_idx,
3268 MATCHED_SSID_FILTER, 0);
3269 if (ret < 0)
3270 return ret;
3271 }
3272
85b20fc2
TP
3273 if (test_bit(ATH6KL_FW_CAPABILITY_RSSI_SCAN_THOLD,
3274 ar->fw_capabilities)) {
3275 if (request->rssi_thold <= NL80211_SCAN_RSSI_THOLD_OFF)
3276 rssi_thold = 0;
3277 else if (request->rssi_thold < -127)
3278 rssi_thold = -127;
3279 else
3280 rssi_thold = request->rssi_thold;
3281
3282 ret = ath6kl_wmi_set_rssi_filter_cmd(ar->wmi, vif->fw_vif_idx,
3283 rssi_thold);
3284 if (ret) {
3285 ath6kl_err("failed to set RSSI threshold for scan\n");
3286 return ret;
3287 }
3288 }
3289
10509f90
KV
3290 /* fw uses seconds, also make sure that it's >0 */
3291 interval = max_t(u16, 1, request->interval / 1000);
3292
3293 ath6kl_wmi_scanparams_cmd(ar->wmi, vif->fw_vif_idx,
3294 interval, interval,
d472b5e4 3295 vif->bg_scan_period, 0, 0, 0, 3, 0, 0, 0);
10509f90 3296
10509f90
KV
3297 /* this also clears IE in fw if it's not set */
3298 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, vif->fw_vif_idx,
3299 WMI_FRAME_PROBE_REQ,
3300 request->ie, request->ie_len);
3301 if (ret) {
f1ff32e8 3302 ath6kl_warn("Failed to set probe request IE for scheduled scan: %d\n",
10509f90
KV
3303 ret);
3304 return ret;
3305 }
3306
b1f47e3a
TP
3307 ret = ath6kl_wmi_enable_sched_scan_cmd(ar->wmi, vif->fw_vif_idx, true);
3308 if (ret)
10509f90 3309 return ret;
10509f90 3310
b1f47e3a 3311 set_bit(SCHED_SCANNING, &vif->flags);
10509f90 3312
b1f47e3a 3313 return 0;
10509f90
KV
3314}
3315
3316static int ath6kl_cfg80211_sscan_stop(struct wiphy *wiphy,
3317 struct net_device *dev)
3318{
3319 struct ath6kl_vif *vif = netdev_priv(dev);
3320 bool stopped;
3321
3322 stopped = __ath6kl_cfg80211_sscan_stop(vif);
3323
3324 if (!stopped)
3325 return -EIO;
3326
3327 return 0;
3328}
3329
06e360ac
BS
3330static int ath6kl_cfg80211_set_bitrate(struct wiphy *wiphy,
3331 struct net_device *dev,
3332 const u8 *addr,
3333 const struct cfg80211_bitrate_mask *mask)
3334{
3335 struct ath6kl *ar = ath6kl_priv(dev);
3336 struct ath6kl_vif *vif = netdev_priv(dev);
3337
3338 return ath6kl_wmi_set_bitrate_mask(ar->wmi, vif->fw_vif_idx,
3339 mask);
3340}
3341
279b2862
TP
3342static int ath6kl_cfg80211_set_txe_config(struct wiphy *wiphy,
3343 struct net_device *dev,
3344 u32 rate, u32 pkts, u32 intvl)
3345{
3346 struct ath6kl *ar = ath6kl_priv(dev);
3347 struct ath6kl_vif *vif = netdev_priv(dev);
3348
3349 if (vif->nw_type != INFRA_NETWORK ||
3350 !test_bit(ATH6KL_FW_CAPABILITY_TX_ERR_NOTIFY, ar->fw_capabilities))
3351 return -EOPNOTSUPP;
3352
3353 if (vif->sme_state != SME_CONNECTED)
3354 return -ENOTCONN;
3355
3356 /* save this since the firmware won't report the interval */
3357 vif->txe_intvl = intvl;
3358
3359 return ath6kl_wmi_set_txe_notify(ar->wmi, vif->fw_vif_idx,
3360 rate, pkts, intvl);
3361}
3362
f80574ae
JM
3363static const struct ieee80211_txrx_stypes
3364ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
3365 [NL80211_IFTYPE_STATION] = {
3366 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3367 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3368 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3369 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3370 },
ba1f6fe3
JM
3371 [NL80211_IFTYPE_AP] = {
3372 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3373 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3374 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3375 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3376 },
f80574ae
JM
3377 [NL80211_IFTYPE_P2P_CLIENT] = {
3378 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3379 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3380 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3381 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3382 },
3383 [NL80211_IFTYPE_P2P_GO] = {
3384 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3385 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
3386 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
3387 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
3388 },
3389};
3390
bdcd8170 3391static struct cfg80211_ops ath6kl_cfg80211_ops = {
55055976
VT
3392 .add_virtual_intf = ath6kl_cfg80211_add_iface,
3393 .del_virtual_intf = ath6kl_cfg80211_del_iface,
bdcd8170
KV
3394 .change_virtual_intf = ath6kl_cfg80211_change_iface,
3395 .scan = ath6kl_cfg80211_scan,
3396 .connect = ath6kl_cfg80211_connect,
3397 .disconnect = ath6kl_cfg80211_disconnect,
3398 .add_key = ath6kl_cfg80211_add_key,
3399 .get_key = ath6kl_cfg80211_get_key,
3400 .del_key = ath6kl_cfg80211_del_key,
3401 .set_default_key = ath6kl_cfg80211_set_default_key,
3402 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
3403 .set_tx_power = ath6kl_cfg80211_set_txpower,
3404 .get_tx_power = ath6kl_cfg80211_get_txpower,
3405 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
3406 .join_ibss = ath6kl_cfg80211_join_ibss,
3407 .leave_ibss = ath6kl_cfg80211_leave_ibss,
3408 .get_station = ath6kl_get_station,
3409 .set_pmksa = ath6kl_set_pmksa,
3410 .del_pmksa = ath6kl_del_pmksa,
3411 .flush_pmksa = ath6kl_flush_pmksa,
003353b0 3412 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
abcb344b 3413#ifdef CONFIG_PM
52d81a68
KV
3414 .suspend = __ath6kl_cfg80211_suspend,
3415 .resume = __ath6kl_cfg80211_resume,
abcb344b 3416#endif
8860020e
JB
3417 .start_ap = ath6kl_start_ap,
3418 .change_beacon = ath6kl_change_beacon,
3419 .stop_ap = ath6kl_stop_ap,
33e5308d 3420 .del_station = ath6kl_del_station,
23875136 3421 .change_station = ath6kl_change_station,
63fa1e0c
JM
3422 .remain_on_channel = ath6kl_remain_on_channel,
3423 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
8a6c8060 3424 .mgmt_tx = ath6kl_mgmt_tx,
ae32c30a 3425 .mgmt_frame_register = ath6kl_mgmt_frame_register,
10509f90
KV
3426 .sched_scan_start = ath6kl_cfg80211_sscan_start,
3427 .sched_scan_stop = ath6kl_cfg80211_sscan_stop,
06e360ac 3428 .set_bitrate_mask = ath6kl_cfg80211_set_bitrate,
279b2862 3429 .set_cqm_txe_config = ath6kl_cfg80211_set_txe_config,
bdcd8170
KV
3430};
3431
7125f01d 3432void ath6kl_cfg80211_stop(struct ath6kl_vif *vif)
ec4b7f60 3433{
10509f90
KV
3434 ath6kl_cfg80211_sscan_disable(vif);
3435
ec4b7f60 3436 switch (vif->sme_state) {
c97a31b0
KV
3437 case SME_DISCONNECTED:
3438 break;
ec4b7f60
KV
3439 case SME_CONNECTING:
3440 cfg80211_connect_result(vif->ndev, vif->bssid, NULL, 0,
3441 NULL, 0,
3442 WLAN_STATUS_UNSPECIFIED_FAILURE,
3443 GFP_KERNEL);
3444 break;
3445 case SME_CONNECTED:
ec4b7f60
KV
3446 cfg80211_disconnected(vif->ndev, 0, NULL, 0, GFP_KERNEL);
3447 break;
3448 }
3449
58109df6
VT
3450 if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3451 (test_bit(CONNECTED, &vif->flags) ||
3452 test_bit(CONNECT_PEND, &vif->flags)))
7125f01d 3453 ath6kl_wmi_disconnect_cmd(vif->ar->wmi, vif->fw_vif_idx);
ec4b7f60
KV
3454
3455 vif->sme_state = SME_DISCONNECTED;
1f405255
KV
3456 clear_bit(CONNECTED, &vif->flags);
3457 clear_bit(CONNECT_PEND, &vif->flags);
ec4b7f60 3458
84caf800
VT
3459 /* Stop netdev queues, needed during recovery */
3460 netif_stop_queue(vif->ndev);
3461 netif_carrier_off(vif->ndev);
3462
ec4b7f60 3463 /* disable scanning */
58109df6
VT
3464 if (vif->ar->state != ATH6KL_STATE_RECOVERY &&
3465 ath6kl_wmi_scanparams_cmd(vif->ar->wmi, vif->fw_vif_idx, 0xFFFF,
7125f01d
KV
3466 0, 0, 0, 0, 0, 0, 0, 0, 0) != 0)
3467 ath6kl_warn("failed to disable scan during stop\n");
ec4b7f60
KV
3468
3469 ath6kl_cfg80211_scan_complete_event(vif, true);
3470}
3471
7125f01d
KV
3472void ath6kl_cfg80211_stop_all(struct ath6kl *ar)
3473{
3474 struct ath6kl_vif *vif;
3475
3476 vif = ath6kl_vif_first(ar);
84caf800 3477 if (!vif && ar->state != ATH6KL_STATE_RECOVERY) {
7125f01d
KV
3478 /* save the current power mode before enabling power save */
3479 ar->wmi->saved_pwr_mode = ar->wmi->pwr_mode;
3480
3481 if (ath6kl_wmi_powermode_cmd(ar->wmi, 0, REC_POWER) != 0)
cdeb8602 3482 ath6kl_warn("ath6kl_deep_sleep_enable: wmi_powermode_cmd failed\n");
7125f01d
KV
3483 return;
3484 }
3485
3486 /*
3487 * FIXME: we should take ar->list_lock to protect changes in the
3488 * vif_list, but that's not trivial to do as ath6kl_cfg80211_stop()
3489 * sleeps.
3490 */
3491 list_for_each_entry(vif, &ar->vif_list, list)
3492 ath6kl_cfg80211_stop(vif);
3493}
3494
0c0280bd
LR
3495static void ath6kl_cfg80211_reg_notify(struct wiphy *wiphy,
3496 struct regulatory_request *request)
84841ba2
KV
3497{
3498 struct ath6kl *ar = wiphy_priv(wiphy);
3499 u32 rates[IEEE80211_NUM_BANDS];
3500 int ret, i;
3501
3502 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
ff7e6867 3503 "cfg reg_notify %c%c%s%s initiator %d hint_type %d\n",
84841ba2
KV
3504 request->alpha2[0], request->alpha2[1],
3505 request->intersect ? " intersect" : "",
3506 request->processed ? " processed" : "",
ff7e6867
KV
3507 request->initiator, request->user_reg_hint_type);
3508
ff7e6867 3509 if (request->user_reg_hint_type != NL80211_USER_REG_HINT_CELL_BASE)
0c0280bd 3510 return;
84841ba2
KV
3511
3512 ret = ath6kl_wmi_set_regdomain_cmd(ar->wmi, request->alpha2);
3513 if (ret) {
3514 ath6kl_err("failed to set regdomain: %d\n", ret);
0c0280bd 3515 return;
84841ba2
KV
3516 }
3517
3518 /*
3519 * Firmware will apply the regdomain change only after a scan is
3520 * issued and it will send a WMI_REGDOMAIN_EVENTID when it has been
3521 * changed.
3522 */
3523
3524 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
3525 if (wiphy->bands[i])
3526 rates[i] = (1 << wiphy->bands[i]->n_bitrates) - 1;
3527
3528
3529 ret = ath6kl_wmi_beginscan_cmd(ar->wmi, 0, WMI_LONG_SCAN, false,
3530 false, 0, ATH6KL_FG_SCAN_INTERVAL,
3531 0, NULL, false, rates);
3532 if (ret) {
3533 ath6kl_err("failed to start scan for a regdomain change: %d\n",
3534 ret);
0c0280bd 3535 return;
84841ba2 3536 }
84841ba2
KV
3537}
3538
c25889e8 3539static int ath6kl_cfg80211_vif_init(struct ath6kl_vif *vif)
bdcd8170 3540{
7baef812 3541 vif->aggr_cntxt = aggr_init(vif);
2132c69c 3542 if (!vif->aggr_cntxt) {
8dafb70e
VT
3543 ath6kl_err("failed to initialize aggr\n");
3544 return -ENOMEM;
3545 }
3546
de3ad713 3547 setup_timer(&vif->disconnect_timer, disconnect_timer_handler,
108438bc 3548 (unsigned long) vif->ndev);
10509f90
KV
3549 setup_timer(&vif->sched_scan_timer, ath6kl_wmi_sscan_timer,
3550 (unsigned long) vif);
3551
de3ad713 3552 set_bit(WMM_ENABLED, &vif->flags);
478ac027 3553 spin_lock_init(&vif->if_lock);
bdcd8170 3554
80abaf9b
VT
3555 INIT_LIST_HEAD(&vif->mc_filter);
3556
8dafb70e
VT
3557 return 0;
3558}
3559
c25889e8 3560void ath6kl_cfg80211_vif_cleanup(struct ath6kl_vif *vif)
8dafb70e 3561{
55055976 3562 struct ath6kl *ar = vif->ar;
80abaf9b 3563 struct ath6kl_mc_filter *mc_filter, *tmp;
55055976 3564
2132c69c 3565 aggr_module_destroy(vif->aggr_cntxt);
8dafb70e 3566
55055976
VT
3567 ar->avail_idx_map |= BIT(vif->fw_vif_idx);
3568
3569 if (vif->nw_type == ADHOC_NETWORK)
3570 ar->ibss_if_active = false;
3571
80abaf9b
VT
3572 list_for_each_entry_safe(mc_filter, tmp, &vif->mc_filter, list) {
3573 list_del(&mc_filter->list);
3574 kfree(mc_filter);
3575 }
3576
27929723 3577 unregister_netdevice(vif->ndev);
55055976
VT
3578
3579 ar->num_vif--;
8dafb70e
VT
3580}
3581
552bff0c 3582struct wireless_dev *ath6kl_interface_add(struct ath6kl *ar, const char *name,
84efbb84
JB
3583 enum nl80211_iftype type,
3584 u8 fw_vif_idx, u8 nw_type)
8dafb70e
VT
3585{
3586 struct net_device *ndev;
108438bc 3587 struct ath6kl_vif *vif;
8dafb70e 3588
55055976 3589 ndev = alloc_netdev(sizeof(*vif), name, ether_setup);
8dafb70e
VT
3590 if (!ndev)
3591 return NULL;
3592
108438bc
VT
3593 vif = netdev_priv(ndev);
3594 ndev->ieee80211_ptr = &vif->wdev;
3595 vif->wdev.wiphy = ar->wiphy;
3596 vif->ar = ar;
108438bc
VT
3597 vif->ndev = ndev;
3598 SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
3599 vif->wdev.netdev = ndev;
3600 vif->wdev.iftype = type;
334234b5 3601 vif->fw_vif_idx = fw_vif_idx;
d0d670ab
KV
3602 vif->nw_type = nw_type;
3603 vif->next_mode = nw_type;
8f46fccd 3604 vif->listen_intvl_t = ATH6KL_DEFAULT_LISTEN_INTVAL;
ce0dc0cf 3605 vif->bmiss_time_t = ATH6KL_DEFAULT_BMISS_TIME;
eb38987e 3606 vif->bg_scan_period = 0;
67b3f129
KR
3607 vif->htcap[IEEE80211_BAND_2GHZ].ht_enable = true;
3608 vif->htcap[IEEE80211_BAND_5GHZ].ht_enable = true;
8dafb70e 3609
55055976 3610 memcpy(ndev->dev_addr, ar->mac_addr, ETH_ALEN);
c95dcb59 3611 if (fw_vif_idx != 0) {
55055976
VT
3612 ndev->dev_addr[0] = (ndev->dev_addr[0] ^ (1 << fw_vif_idx)) |
3613 0x2;
c95dcb59
AT
3614 if (test_bit(ATH6KL_FW_CAPABILITY_CUSTOM_MAC_ADDR,
3615 ar->fw_capabilities))
3616 ndev->dev_addr[4] ^= 0x80;
3617 }
55055976 3618
8dafb70e
VT
3619 init_netdev(ndev);
3620
e29f25f5 3621 ath6kl_init_control_info(vif);
8dafb70e 3622
c25889e8 3623 if (ath6kl_cfg80211_vif_init(vif))
8dafb70e
VT
3624 goto err;
3625
27929723 3626 if (register_netdevice(ndev))
8dafb70e
VT
3627 goto err;
3628
55055976 3629 ar->avail_idx_map &= ~BIT(fw_vif_idx);
14ee6f6b 3630 vif->sme_state = SME_DISCONNECTED;
59c98449 3631 set_bit(WLAN_ENABLED, &vif->flags);
8dafb70e 3632 ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
59c98449 3633 set_bit(NETDEV_REGISTERED, &vif->flags);
8dafb70e 3634
55055976
VT
3635 if (type == NL80211_IFTYPE_ADHOC)
3636 ar->ibss_if_active = true;
3637
11f6e40d 3638 spin_lock_bh(&ar->list_lock);
990bd915 3639 list_add_tail(&vif->list, &ar->vif_list);
11f6e40d 3640 spin_unlock_bh(&ar->list_lock);
990bd915 3641
84efbb84 3642 return &vif->wdev;
8dafb70e
VT
3643
3644err:
27929723
VT
3645 aggr_module_destroy(vif->aggr_cntxt);
3646 free_netdev(ndev);
8dafb70e
VT
3647 return NULL;
3648}
3649
46d33a21
KV
3650int ath6kl_cfg80211_init(struct ath6kl *ar)
3651{
3652 struct wiphy *wiphy = ar->wiphy;
d92917e4 3653 bool band_2gig = false, band_5gig = false, ht = false;
46d33a21
KV
3654 int ret;
3655
3656 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
3657
3658 wiphy->max_remain_on_channel_duration = 5000;
3659
3660 /* set device pointer for wiphy */
3661 set_wiphy_dev(wiphy, ar->dev);
3662
3663 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
3664 BIT(NL80211_IFTYPE_ADHOC) |
3665 BIT(NL80211_IFTYPE_AP);
3666 if (ar->p2p) {
3667 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
3668 BIT(NL80211_IFTYPE_P2P_CLIENT);
3669 }
3670
84841ba2 3671 if (config_enabled(CONFIG_ATH6KL_REGDOMAIN) &&
ff7e6867 3672 test_bit(ATH6KL_FW_CAPABILITY_REGDOMAIN, ar->fw_capabilities)) {
84841ba2 3673 wiphy->reg_notifier = ath6kl_cfg80211_reg_notify;
ff7e6867
KV
3674 ar->wiphy->features |= NL80211_FEATURE_CELL_BASE_REG_HINTS;
3675 }
84841ba2 3676
46d33a21 3677 /* max num of ssids that can be probed during scanning */
8ab5415d 3678 wiphy->max_scan_ssids = MAX_PROBED_SSIDS;
dd45b759
NS
3679
3680 /* max num of ssids that can be matched after scan */
3681 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_MATCH_LIST,
3682 ar->fw_capabilities))
3683 wiphy->max_match_sets = MAX_PROBED_SSIDS;
3684
46d33a21 3685 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
d92917e4
TP
3686 switch (ar->hw.cap) {
3687 case WMI_11AN_CAP:
3688 ht = true;
3689 case WMI_11A_CAP:
3690 band_5gig = true;
3691 break;
3692 case WMI_11GN_CAP:
3693 ht = true;
3694 case WMI_11G_CAP:
3695 band_2gig = true;
3696 break;
3697 case WMI_11AGN_CAP:
3698 ht = true;
3699 case WMI_11AG_CAP:
3700 band_2gig = true;
3701 band_5gig = true;
3702 break;
3703 default:
3704 ath6kl_err("invalid phy capability!\n");
3705 return -EINVAL;
3706 }
3707
7fd1ce7e
VT
3708 /*
3709 * Even if the fw has HT support, advertise HT cap only when
3710 * the firmware has support to override RSN capability, otherwise
3711 * 4-way handshake would fail.
3712 */
3713 if (!(ht &&
3714 test_bit(ATH6KL_FW_CAPABILITY_RSN_CAP_OVERRIDE,
3715 ar->fw_capabilities))) {
d92917e4
TP
3716 ath6kl_band_2ghz.ht_cap.cap = 0;
3717 ath6kl_band_2ghz.ht_cap.ht_supported = false;
3718 ath6kl_band_5ghz.ht_cap.cap = 0;
3719 ath6kl_band_5ghz.ht_cap.ht_supported = false;
3720 }
06e360ac 3721
c0b34e2b 3722 if (ar->hw.flags & ATH6KL_HW_64BIT_RATES) {
06e360ac
BS
3723 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3724 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3725 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3726 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[1] = 0xff;
3727 } else {
3728 ath6kl_band_2ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3729 ath6kl_band_5ghz.ht_cap.mcs.rx_mask[0] = 0xff;
3730 }
3731
d92917e4
TP
3732 if (band_2gig)
3733 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
3734 if (band_5gig)
3735 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
3736
46d33a21
KV
3737 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
3738
3739 wiphy->cipher_suites = cipher_suites;
3740 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
3741
dfb89c56 3742#ifdef CONFIG_PM
46d33a21
KV
3743 wiphy->wowlan.flags = WIPHY_WOWLAN_MAGIC_PKT |
3744 WIPHY_WOWLAN_DISCONNECT |
3745 WIPHY_WOWLAN_GTK_REKEY_FAILURE |
3746 WIPHY_WOWLAN_SUPPORTS_GTK_REKEY |
3747 WIPHY_WOWLAN_EAP_IDENTITY_REQ |
3748 WIPHY_WOWLAN_4WAY_HANDSHAKE;
3749 wiphy->wowlan.n_patterns = WOW_MAX_FILTERS_PER_LIST;
3750 wiphy->wowlan.pattern_min_len = 1;
3751 wiphy->wowlan.pattern_max_len = WOW_PATTERN_SIZE;
dfb89c56 3752#endif
46d33a21 3753
8ab5415d 3754 wiphy->max_sched_scan_ssids = MAX_PROBED_SSIDS;
46d33a21 3755
f2afdac7
VT
3756 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_FW_ROAM |
3757 WIPHY_FLAG_HAVE_AP_SME |
3758 WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL |
3759 WIPHY_FLAG_AP_PROBE_RESP_OFFLOAD;
3760
b1f47e3a 3761 if (test_bit(ATH6KL_FW_CAPABILITY_SCHED_SCAN_V2, ar->fw_capabilities))
f2afdac7
VT
3762 ar->wiphy->flags |= WIPHY_FLAG_SUPPORTS_SCHED_SCAN;
3763
03bdeb0d
VT
3764 if (test_bit(ATH6KL_FW_CAPABILITY_INACTIVITY_TIMEOUT,
3765 ar->fw_capabilities))
b292219f 3766 ar->wiphy->features |= NL80211_FEATURE_INACTIVITY_TIMER;
03bdeb0d 3767
f2afdac7
VT
3768 ar->wiphy->probe_resp_offload =
3769 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS |
3770 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_WPS2 |
a432e7cc 3771 NL80211_PROBE_RESP_OFFLOAD_SUPPORT_P2P;
f2afdac7 3772
46d33a21
KV
3773 ret = wiphy_register(wiphy);
3774 if (ret < 0) {
3775 ath6kl_err("couldn't register wiphy device\n");
3776 return ret;
3777 }
3778
e5348a1e
VT
3779 ar->wiphy_registered = true;
3780
46d33a21
KV
3781 return 0;
3782}
3783
3784void ath6kl_cfg80211_cleanup(struct ath6kl *ar)
8dafb70e 3785{
be98e3a4 3786 wiphy_unregister(ar->wiphy);
e5348a1e
VT
3787
3788 ar->wiphy_registered = false;
45eaa78f 3789}
46d33a21 3790
45eaa78f
KV
3791struct ath6kl *ath6kl_cfg80211_create(void)
3792{
3793 struct ath6kl *ar;
3794 struct wiphy *wiphy;
3795
3796 /* create a new wiphy for use with cfg80211 */
3797 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
3798
3799 if (!wiphy) {
3800 ath6kl_err("couldn't allocate wiphy device\n");
3801 return NULL;
3802 }
3803
3804 ar = wiphy_priv(wiphy);
3805 ar->wiphy = wiphy;
3806
3807 return ar;
3808}
3809
3810/* Note: ar variable must not be accessed after calling this! */
3811void ath6kl_cfg80211_destroy(struct ath6kl *ar)
3812{
1d2a4456
VT
3813 int i;
3814
3815 for (i = 0; i < AP_MAX_NUM_STA; i++)
3816 kfree(ar->sta_list[i].aggr_conn);
3817
be98e3a4 3818 wiphy_free(ar->wiphy);
bdcd8170 3819}
45eaa78f 3820