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