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