ath6kl: Move aggregation information to vif structure
[deliverable/linux.git] / drivers / net / wireless / ath / ath6kl / cfg80211.c
CommitLineData
bdcd8170
KV
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"
abcb344b 20#include "hif-ops.h"
003353b0 21#include "testmode.h"
bdcd8170 22
6bbc7c35
JM
23static unsigned int ath6kl_p2p;
24
25module_param(ath6kl_p2p, uint, 0644);
26
bdcd8170
KV
27#define RATETAB_ENT(_rate, _rateid, _flags) { \
28 .bitrate = (_rate), \
29 .flags = (_flags), \
30 .hw_value = (_rateid), \
31}
32
33#define CHAN2G(_channel, _freq, _flags) { \
34 .band = IEEE80211_BAND_2GHZ, \
35 .hw_value = (_channel), \
36 .center_freq = (_freq), \
37 .flags = (_flags), \
38 .max_antenna_gain = 0, \
39 .max_power = 30, \
40}
41
42#define CHAN5G(_channel, _flags) { \
43 .band = IEEE80211_BAND_5GHZ, \
44 .hw_value = (_channel), \
45 .center_freq = 5000 + (5 * (_channel)), \
46 .flags = (_flags), \
47 .max_antenna_gain = 0, \
48 .max_power = 30, \
49}
50
51static struct ieee80211_rate ath6kl_rates[] = {
52 RATETAB_ENT(10, 0x1, 0),
53 RATETAB_ENT(20, 0x2, 0),
54 RATETAB_ENT(55, 0x4, 0),
55 RATETAB_ENT(110, 0x8, 0),
56 RATETAB_ENT(60, 0x10, 0),
57 RATETAB_ENT(90, 0x20, 0),
58 RATETAB_ENT(120, 0x40, 0),
59 RATETAB_ENT(180, 0x80, 0),
60 RATETAB_ENT(240, 0x100, 0),
61 RATETAB_ENT(360, 0x200, 0),
62 RATETAB_ENT(480, 0x400, 0),
63 RATETAB_ENT(540, 0x800, 0),
64};
65
66#define ath6kl_a_rates (ath6kl_rates + 4)
67#define ath6kl_a_rates_size 8
68#define ath6kl_g_rates (ath6kl_rates + 0)
69#define ath6kl_g_rates_size 12
70
71static struct ieee80211_channel ath6kl_2ghz_channels[] = {
72 CHAN2G(1, 2412, 0),
73 CHAN2G(2, 2417, 0),
74 CHAN2G(3, 2422, 0),
75 CHAN2G(4, 2427, 0),
76 CHAN2G(5, 2432, 0),
77 CHAN2G(6, 2437, 0),
78 CHAN2G(7, 2442, 0),
79 CHAN2G(8, 2447, 0),
80 CHAN2G(9, 2452, 0),
81 CHAN2G(10, 2457, 0),
82 CHAN2G(11, 2462, 0),
83 CHAN2G(12, 2467, 0),
84 CHAN2G(13, 2472, 0),
85 CHAN2G(14, 2484, 0),
86};
87
88static struct ieee80211_channel ath6kl_5ghz_a_channels[] = {
89 CHAN5G(34, 0), CHAN5G(36, 0),
90 CHAN5G(38, 0), CHAN5G(40, 0),
91 CHAN5G(42, 0), CHAN5G(44, 0),
92 CHAN5G(46, 0), CHAN5G(48, 0),
93 CHAN5G(52, 0), CHAN5G(56, 0),
94 CHAN5G(60, 0), CHAN5G(64, 0),
95 CHAN5G(100, 0), CHAN5G(104, 0),
96 CHAN5G(108, 0), CHAN5G(112, 0),
97 CHAN5G(116, 0), CHAN5G(120, 0),
98 CHAN5G(124, 0), CHAN5G(128, 0),
99 CHAN5G(132, 0), CHAN5G(136, 0),
100 CHAN5G(140, 0), CHAN5G(149, 0),
101 CHAN5G(153, 0), CHAN5G(157, 0),
102 CHAN5G(161, 0), CHAN5G(165, 0),
103 CHAN5G(184, 0), CHAN5G(188, 0),
104 CHAN5G(192, 0), CHAN5G(196, 0),
105 CHAN5G(200, 0), CHAN5G(204, 0),
106 CHAN5G(208, 0), CHAN5G(212, 0),
107 CHAN5G(216, 0),
108};
109
110static struct ieee80211_supported_band ath6kl_band_2ghz = {
111 .n_channels = ARRAY_SIZE(ath6kl_2ghz_channels),
112 .channels = ath6kl_2ghz_channels,
113 .n_bitrates = ath6kl_g_rates_size,
114 .bitrates = ath6kl_g_rates,
115};
116
117static struct ieee80211_supported_band ath6kl_band_5ghz = {
118 .n_channels = ARRAY_SIZE(ath6kl_5ghz_a_channels),
119 .channels = ath6kl_5ghz_a_channels,
120 .n_bitrates = ath6kl_a_rates_size,
121 .bitrates = ath6kl_a_rates,
122};
123
837cb97e
JM
124#define CCKM_KRK_CIPHER_SUITE 0x004096ff /* use for KRK */
125
bdcd8170
KV
126static int ath6kl_set_wpa_version(struct ath6kl *ar,
127 enum nl80211_wpa_versions wpa_version)
128{
3450334f
VT
129 /* TODO: Findout vif */
130 struct ath6kl_vif *vif = ar->vif;
131
bdcd8170
KV
132 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
133
134 if (!wpa_version) {
3450334f 135 vif->auth_mode = NONE_AUTH;
bdcd8170 136 } else if (wpa_version & NL80211_WPA_VERSION_2) {
3450334f 137 vif->auth_mode = WPA2_AUTH;
bdcd8170 138 } else if (wpa_version & NL80211_WPA_VERSION_1) {
3450334f 139 vif->auth_mode = WPA_AUTH;
bdcd8170
KV
140 } else {
141 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
142 return -ENOTSUPP;
143 }
144
145 return 0;
146}
147
148static int ath6kl_set_auth_type(struct ath6kl *ar,
149 enum nl80211_auth_type auth_type)
150{
3450334f
VT
151 /* TODO: Findout vif */
152 struct ath6kl_vif *vif = ar->vif;
bdcd8170
KV
153
154 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
155
156 switch (auth_type) {
157 case NL80211_AUTHTYPE_OPEN_SYSTEM:
3450334f 158 vif->dot11_auth_mode = OPEN_AUTH;
bdcd8170
KV
159 break;
160 case NL80211_AUTHTYPE_SHARED_KEY:
3450334f 161 vif->dot11_auth_mode = SHARED_AUTH;
bdcd8170
KV
162 break;
163 case NL80211_AUTHTYPE_NETWORK_EAP:
3450334f 164 vif->dot11_auth_mode = LEAP_AUTH;
bdcd8170
KV
165 break;
166
167 case NL80211_AUTHTYPE_AUTOMATIC:
3450334f 168 vif->dot11_auth_mode = OPEN_AUTH | SHARED_AUTH;
bdcd8170
KV
169 break;
170
171 default:
172 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
173 return -ENOTSUPP;
174 }
175
176 return 0;
177}
178
179static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
180{
3450334f
VT
181 /* TODO: Findout vif */
182 struct ath6kl_vif *vif = ar->vif;
183
184 u8 *ar_cipher = ucast ? &vif->prwise_crypto : &vif->grp_crypto;
185 u8 *ar_cipher_len = ucast ? &vif->prwise_crypto_len :
186 &vif->grp_crypto_len;
bdcd8170
KV
187
188 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
189 __func__, cipher, ucast);
190
191 switch (cipher) {
192 case 0:
193 /* our own hack to use value 0 as no crypto used */
194 *ar_cipher = NONE_CRYPT;
195 *ar_cipher_len = 0;
196 break;
197 case WLAN_CIPHER_SUITE_WEP40:
198 *ar_cipher = WEP_CRYPT;
199 *ar_cipher_len = 5;
200 break;
201 case WLAN_CIPHER_SUITE_WEP104:
202 *ar_cipher = WEP_CRYPT;
203 *ar_cipher_len = 13;
204 break;
205 case WLAN_CIPHER_SUITE_TKIP:
206 *ar_cipher = TKIP_CRYPT;
207 *ar_cipher_len = 0;
208 break;
209 case WLAN_CIPHER_SUITE_CCMP:
210 *ar_cipher = AES_CRYPT;
211 *ar_cipher_len = 0;
212 break;
213 default:
214 ath6kl_err("cipher 0x%x not supported\n", cipher);
215 return -ENOTSUPP;
216 }
217
218 return 0;
219}
220
221static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
222{
3450334f
VT
223 /* TODO: Findout vif */
224 struct ath6kl_vif *vif = ar->vif;
225
bdcd8170
KV
226 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
227
228 if (key_mgmt == WLAN_AKM_SUITE_PSK) {
3450334f
VT
229 if (vif->auth_mode == WPA_AUTH)
230 vif->auth_mode = WPA_PSK_AUTH;
231 else if (vif->auth_mode == WPA2_AUTH)
232 vif->auth_mode = WPA2_PSK_AUTH;
837cb97e 233 } else if (key_mgmt == 0x00409600) {
3450334f
VT
234 if (vif->auth_mode == WPA_AUTH)
235 vif->auth_mode = WPA_AUTH_CCKM;
236 else if (vif->auth_mode == WPA2_AUTH)
237 vif->auth_mode = WPA2_AUTH_CCKM;
bdcd8170 238 } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
3450334f 239 vif->auth_mode = NONE_AUTH;
bdcd8170
KV
240 }
241}
242
243static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
244{
59c98449
VT
245 struct ath6kl_vif *vif = ar->vif;
246
bdcd8170
KV
247 if (!test_bit(WMI_READY, &ar->flag)) {
248 ath6kl_err("wmi is not ready\n");
249 return false;
250 }
251
59c98449 252 if (!test_bit(WLAN_ENABLED, &vif->flags)) {
bdcd8170
KV
253 ath6kl_err("wlan disabled\n");
254 return false;
255 }
256
257 return true;
258}
259
6981ffdc
KF
260static bool ath6kl_is_wpa_ie(const u8 *pos)
261{
262 return pos[0] == WLAN_EID_WPA && pos[1] >= 4 &&
263 pos[2] == 0x00 && pos[3] == 0x50 &&
264 pos[4] == 0xf2 && pos[5] == 0x01;
265}
266
267static bool ath6kl_is_rsn_ie(const u8 *pos)
268{
269 return pos[0] == WLAN_EID_RSN;
270}
271
272static int ath6kl_set_assoc_req_ies(struct ath6kl *ar, const u8 *ies,
273 size_t ies_len)
274{
275 const u8 *pos;
276 u8 *buf = NULL;
277 size_t len = 0;
278 int ret;
279
280 /*
281 * Filter out RSN/WPA IE(s)
282 */
283
284 if (ies && ies_len) {
285 buf = kmalloc(ies_len, GFP_KERNEL);
286 if (buf == NULL)
287 return -ENOMEM;
288 pos = ies;
289
290 while (pos + 1 < ies + ies_len) {
291 if (pos + 2 + pos[1] > ies + ies_len)
292 break;
293 if (!(ath6kl_is_wpa_ie(pos) || ath6kl_is_rsn_ie(pos))) {
294 memcpy(buf + len, pos, 2 + pos[1]);
295 len += 2 + pos[1];
296 }
297 pos += 2 + pos[1];
298 }
299 }
300
301 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_REQ,
302 buf, len);
303 kfree(buf);
304 return ret;
305}
306
bdcd8170
KV
307static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
308 struct cfg80211_connect_params *sme)
309{
310 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 311 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
312 int status;
313
314 ar->sme_state = SME_CONNECTING;
315
316 if (!ath6kl_cfg80211_ready(ar))
317 return -EIO;
318
319 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
320 ath6kl_err("destroy in progress\n");
321 return -EBUSY;
322 }
323
324 if (test_bit(SKIP_SCAN, &ar->flag) &&
325 ((sme->channel && sme->channel->center_freq == 0) ||
326 (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
327 ath6kl_err("SkipScan: channel or bssid invalid\n");
328 return -EINVAL;
329 }
330
331 if (down_interruptible(&ar->sem)) {
332 ath6kl_err("busy, couldn't get access\n");
333 return -ERESTARTSYS;
334 }
335
336 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
337 ath6kl_err("busy, destroy in progress\n");
338 up(&ar->sem);
339 return -EBUSY;
340 }
341
342 if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
343 /*
344 * sleep until the command queue drains
345 */
346 wait_event_interruptible_timeout(ar->event_wq,
347 ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
348 WMI_TIMEOUT);
349 if (signal_pending(current)) {
350 ath6kl_err("cmd queue drain timeout\n");
351 up(&ar->sem);
352 return -EINTR;
353 }
354 }
355
6981ffdc
KF
356 if (sme->ie && (sme->ie_len > 0)) {
357 status = ath6kl_set_assoc_req_ies(ar, sme->ie, sme->ie_len);
358 if (status)
359 return status;
360 }
361
59c98449 362 if (test_bit(CONNECTED, &vif->flags) &&
3450334f
VT
363 vif->ssid_len == sme->ssid_len &&
364 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
bdcd8170 365 ar->reconnect_flag = true;
8c8b65e3 366 status = ath6kl_wmi_reconnect_cmd(ar->wmi, vif->req_bssid,
f74bac54 367 vif->ch_hint);
bdcd8170
KV
368
369 up(&ar->sem);
370 if (status) {
371 ath6kl_err("wmi_reconnect_cmd failed\n");
372 return -EIO;
373 }
374 return 0;
3450334f
VT
375 } else if (vif->ssid_len == sme->ssid_len &&
376 !memcmp(vif->ssid, sme->ssid, vif->ssid_len)) {
bdcd8170
KV
377 ath6kl_disconnect(ar);
378 }
379
3450334f
VT
380 memset(vif->ssid, 0, sizeof(vif->ssid));
381 vif->ssid_len = sme->ssid_len;
382 memcpy(vif->ssid, sme->ssid, sme->ssid_len);
bdcd8170
KV
383
384 if (sme->channel)
f74bac54 385 vif->ch_hint = sme->channel->center_freq;
bdcd8170 386
8c8b65e3 387 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170 388 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
8c8b65e3 389 memcpy(vif->req_bssid, sme->bssid, sizeof(vif->req_bssid));
bdcd8170
KV
390
391 ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
392
393 status = ath6kl_set_auth_type(ar, sme->auth_type);
394 if (status) {
395 up(&ar->sem);
396 return status;
397 }
398
399 if (sme->crypto.n_ciphers_pairwise)
400 ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
401 else
402 ath6kl_set_cipher(ar, 0, true);
403
404 ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
405
406 if (sme->crypto.n_akm_suites)
407 ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
408
409 if ((sme->key_len) &&
3450334f
VT
410 (vif->auth_mode == NONE_AUTH) &&
411 (vif->prwise_crypto == WEP_CRYPT)) {
bdcd8170
KV
412 struct ath6kl_key *key = NULL;
413
414 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
415 sme->key_idx > WMI_MAX_KEY_INDEX) {
416 ath6kl_err("key index %d out of bounds\n",
417 sme->key_idx);
418 up(&ar->sem);
419 return -ENOENT;
420 }
421
6f2a73f9 422 key = &vif->keys[sme->key_idx];
bdcd8170
KV
423 key->key_len = sme->key_len;
424 memcpy(key->key, sme->key, key->key_len);
3450334f
VT
425 key->cipher = vif->prwise_crypto;
426 vif->def_txkey_index = sme->key_idx;
bdcd8170
KV
427
428 ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
3450334f 429 vif->prwise_crypto,
bdcd8170
KV
430 GROUP_USAGE | TX_USAGE,
431 key->key_len,
432 NULL,
433 key->key, KEY_OP_INIT_VAL, NULL,
434 NO_SYNC_WMIFLAG);
435 }
436
437 if (!ar->usr_bss_filter) {
59c98449 438 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
bdcd8170
KV
439 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
440 ath6kl_err("couldn't set bss filtering\n");
441 up(&ar->sem);
442 return -EIO;
443 }
444 }
445
f5938f24 446 vif->nw_type = vif->next_mode;
bdcd8170
KV
447
448 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
449 "%s: connect called with authmode %d dot11 auth %d"
450 " PW crypto %d PW crypto len %d GRP crypto %d"
451 " GRP crypto len %d channel hint %u\n",
452 __func__,
3450334f
VT
453 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
454 vif->prwise_crypto_len, vif->grp_crypto,
f74bac54 455 vif->grp_crypto_len, vif->ch_hint);
bdcd8170
KV
456
457 ar->reconnect_flag = 0;
f5938f24 458 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
3450334f
VT
459 vif->dot11_auth_mode, vif->auth_mode,
460 vif->prwise_crypto,
461 vif->prwise_crypto_len,
462 vif->grp_crypto, vif->grp_crypto_len,
463 vif->ssid_len, vif->ssid,
f74bac54 464 vif->req_bssid, vif->ch_hint,
bdcd8170
KV
465 ar->connect_ctrl_flags);
466
467 up(&ar->sem);
468
469 if (status == -EINVAL) {
3450334f
VT
470 memset(vif->ssid, 0, sizeof(vif->ssid));
471 vif->ssid_len = 0;
bdcd8170
KV
472 ath6kl_err("invalid request\n");
473 return -ENOENT;
474 } else if (status) {
475 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
476 return -EIO;
477 }
478
479 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
3450334f
VT
480 ((vif->auth_mode == WPA_PSK_AUTH)
481 || (vif->auth_mode == WPA2_PSK_AUTH))) {
bdcd8170
KV
482 mod_timer(&ar->disconnect_timer,
483 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
484 }
485
486 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
59c98449 487 set_bit(CONNECT_PEND, &vif->flags);
bdcd8170
KV
488
489 return 0;
490}
491
01cac476
JM
492static int ath6kl_add_bss_if_needed(struct ath6kl *ar, const u8 *bssid,
493 struct ieee80211_channel *chan,
494 const u8 *beacon_ie, size_t beacon_ie_len)
495{
3450334f
VT
496 /* TODO: Findout vif */
497 struct ath6kl_vif *vif = ar->vif;
01cac476
JM
498 struct cfg80211_bss *bss;
499 u8 *ie;
500
be98e3a4 501 bss = cfg80211_get_bss(ar->wiphy, chan, bssid,
3450334f 502 vif->ssid, vif->ssid_len, WLAN_CAPABILITY_ESS,
01cac476
JM
503 WLAN_CAPABILITY_ESS);
504 if (bss == NULL) {
505 /*
506 * Since cfg80211 may not yet know about the BSS,
507 * generate a partial entry until the first BSS info
508 * event becomes available.
509 *
510 * Prepend SSID element since it is not included in the Beacon
511 * IEs from the target.
512 */
3450334f 513 ie = kmalloc(2 + vif->ssid_len + beacon_ie_len, GFP_KERNEL);
01cac476
JM
514 if (ie == NULL)
515 return -ENOMEM;
516 ie[0] = WLAN_EID_SSID;
3450334f
VT
517 ie[1] = vif->ssid_len;
518 memcpy(ie + 2, vif->ssid, vif->ssid_len);
519 memcpy(ie + 2 + vif->ssid_len, beacon_ie, beacon_ie_len);
be98e3a4 520 bss = cfg80211_inform_bss(ar->wiphy, chan,
01cac476 521 bssid, 0, WLAN_CAPABILITY_ESS, 100,
3450334f 522 ie, 2 + vif->ssid_len + beacon_ie_len,
01cac476
JM
523 0, GFP_KERNEL);
524 if (bss)
525 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "added dummy bss for "
526 "%pM prior to indicating connect/roamed "
527 "event\n", bssid);
528 kfree(ie);
529 } else
530 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "cfg80211 already has a bss "
531 "entry\n");
532
533 if (bss == NULL)
534 return -ENOMEM;
535
536 cfg80211_put_bss(bss);
537
538 return 0;
539}
540
bdcd8170
KV
541void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
542 u8 *bssid, u16 listen_intvl,
543 u16 beacon_intvl,
544 enum network_type nw_type,
545 u8 beacon_ie_len, u8 assoc_req_len,
546 u8 assoc_resp_len, u8 *assoc_info)
547{
01cac476 548 struct ieee80211_channel *chan;
59c98449
VT
549 /* TODO: Findout vif */
550 struct ath6kl_vif *vif = ar->vif;
bdcd8170
KV
551
552 /* capinfo + listen interval */
553 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
554
555 /* capinfo + status code + associd */
556 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
557
558 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
559 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
560 assoc_resp_ie_offset;
561
562 assoc_req_len -= assoc_req_ie_offset;
563 assoc_resp_len -= assoc_resp_ie_offset;
564
32c10874
JM
565 /*
566 * Store Beacon interval here; DTIM period will be available only once
567 * a Beacon frame from the AP is seen.
568 */
569 ar->assoc_bss_beacon_int = beacon_intvl;
59c98449 570 clear_bit(DTIM_PERIOD_AVAIL, &vif->flags);
32c10874 571
bdcd8170
KV
572 if (nw_type & ADHOC_NETWORK) {
573 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
574 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
575 "%s: ath6k not in ibss mode\n", __func__);
576 return;
577 }
578 }
579
580 if (nw_type & INFRA_NETWORK) {
6b5e5d25
JM
581 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
582 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
583 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
584 "%s: ath6k not in station mode\n", __func__);
585 return;
586 }
587 }
588
be98e3a4 589 chan = ieee80211_get_channel(ar->wiphy, (int) channel);
bdcd8170 590
bdcd8170 591
01cac476
JM
592 if (nw_type & ADHOC_NETWORK) {
593 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
bdcd8170
KV
594 return;
595 }
596
01cac476
JM
597 if (ath6kl_add_bss_if_needed(ar, bssid, chan, assoc_info,
598 beacon_ie_len) < 0) {
599 ath6kl_err("could not add cfg80211 bss entry for "
600 "connect/roamed notification\n");
bdcd8170
KV
601 return;
602 }
603
9aa60357 604 if (ar->sme_state == SME_CONNECTING) {
bdcd8170 605 /* inform connect result to cfg80211 */
9aa60357 606 ar->sme_state = SME_CONNECTED;
bdcd8170
KV
607 cfg80211_connect_result(ar->net_dev, bssid,
608 assoc_req_ie, assoc_req_len,
609 assoc_resp_ie, assoc_resp_len,
610 WLAN_STATUS_SUCCESS, GFP_KERNEL);
9aa60357 611 } else if (ar->sme_state == SME_CONNECTED) {
bdcd8170 612 /* inform roam event to cfg80211 */
01cac476 613 cfg80211_roamed(ar->net_dev, chan, bssid,
bdcd8170
KV
614 assoc_req_ie, assoc_req_len,
615 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
616 }
617}
618
619static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
620 struct net_device *dev, u16 reason_code)
621{
622 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
3450334f 623 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
624
625 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
626 reason_code);
627
628 if (!ath6kl_cfg80211_ready(ar))
629 return -EIO;
630
631 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
632 ath6kl_err("busy, destroy in progress\n");
633 return -EBUSY;
634 }
635
636 if (down_interruptible(&ar->sem)) {
637 ath6kl_err("busy, couldn't get access\n");
638 return -ERESTARTSYS;
639 }
640
641 ar->reconnect_flag = 0;
642 ath6kl_disconnect(ar);
3450334f
VT
643 memset(vif->ssid, 0, sizeof(vif->ssid));
644 vif->ssid_len = 0;
bdcd8170
KV
645
646 if (!test_bit(SKIP_SCAN, &ar->flag))
8c8b65e3 647 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170
KV
648
649 up(&ar->sem);
650
170826dd
VT
651 ar->sme_state = SME_DISCONNECTED;
652
bdcd8170
KV
653 return 0;
654}
655
656void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
657 u8 *bssid, u8 assoc_resp_len,
658 u8 *assoc_info, u16 proto_reason)
659{
59c98449
VT
660 /* TODO: Findout vif */
661 struct ath6kl_vif *vif = ar->vif;
662
bdcd8170
KV
663 if (ar->scan_req) {
664 cfg80211_scan_done(ar->scan_req, true);
665 ar->scan_req = NULL;
666 }
667
f5938f24 668 if (vif->nw_type & ADHOC_NETWORK) {
bdcd8170
KV
669 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
670 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
671 "%s: ath6k not in ibss mode\n", __func__);
672 return;
673 }
674 memset(bssid, 0, ETH_ALEN);
675 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
676 return;
677 }
678
f5938f24 679 if (vif->nw_type & INFRA_NETWORK) {
6b5e5d25
JM
680 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
681 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
682 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
683 "%s: ath6k not in station mode\n", __func__);
684 return;
685 }
686 }
687
1de547d6
VT
688 /*
689 * Send a disconnect command to target when a disconnect event is
690 * received with reason code other than 3 (DISCONNECT_CMD - disconnect
691 * request from host) to make the firmware stop trying to connect even
692 * after giving disconnect event. There will be one more disconnect
693 * event for this disconnect command with reason code DISCONNECT_CMD
694 * which will be notified to cfg80211.
695 */
bdcd8170 696
1de547d6 697 if (reason != DISCONNECT_CMD) {
bdcd8170
KV
698 ath6kl_wmi_disconnect_cmd(ar->wmi);
699 return;
700 }
701
59c98449 702 clear_bit(CONNECT_PEND, &vif->flags);
bdcd8170 703
ac59a2b2
VT
704 if (ar->sme_state == SME_CONNECTING) {
705 cfg80211_connect_result(ar->net_dev,
706 bssid, NULL, 0,
707 NULL, 0,
708 WLAN_STATUS_UNSPECIFIED_FAILURE,
709 GFP_KERNEL);
710 } else if (ar->sme_state == SME_CONNECTED) {
711 cfg80211_disconnected(ar->net_dev, reason,
712 NULL, 0, GFP_KERNEL);
bdcd8170
KV
713 }
714
ac59a2b2 715 ar->sme_state = SME_DISCONNECTED;
bdcd8170
KV
716}
717
bdcd8170
KV
718static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
719 struct cfg80211_scan_request *request)
720{
721 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
59c98449 722 struct ath6kl_vif *vif = netdev_priv(ndev);
1276c9ef
EL
723 s8 n_channels = 0;
724 u16 *channels = NULL;
bdcd8170 725 int ret = 0;
f1f92179 726 u32 force_fg_scan = 0;
bdcd8170
KV
727
728 if (!ath6kl_cfg80211_ready(ar))
729 return -EIO;
730
731 if (!ar->usr_bss_filter) {
59c98449 732 clear_bit(CLEAR_BSSFILTER_ON_BEACON, &vif->flags);
1b1e6ee3
JM
733 ret = ath6kl_wmi_bssfilter_cmd(
734 ar->wmi,
59c98449 735 (test_bit(CONNECTED, &vif->flags) ?
1b1e6ee3
JM
736 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
737 if (ret) {
bdcd8170 738 ath6kl_err("couldn't set bss filtering\n");
1b1e6ee3 739 return ret;
bdcd8170
KV
740 }
741 }
742
743 if (request->n_ssids && request->ssids[0].ssid_len) {
744 u8 i;
745
746 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
747 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
748
749 for (i = 0; i < request->n_ssids; i++)
750 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
751 SPECIFIC_SSID_FLAG,
752 request->ssids[i].ssid_len,
753 request->ssids[i].ssid);
754 }
755
b84da8c7
JM
756 if (request->ie) {
757 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
758 request->ie, request->ie_len);
759 if (ret) {
760 ath6kl_err("failed to set Probe Request appie for "
761 "scan");
762 return ret;
763 }
764 }
765
11869bef
JM
766 /*
767 * Scan only the requested channels if the request specifies a set of
768 * channels. If the list is longer than the target supports, do not
769 * configure the list and instead, scan all available channels.
770 */
771 if (request->n_channels > 0 &&
772 request->n_channels <= WMI_MAX_CHANNELS) {
1276c9ef
EL
773 u8 i;
774
11869bef 775 n_channels = request->n_channels;
1276c9ef
EL
776
777 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
778 if (channels == NULL) {
779 ath6kl_warn("failed to set scan channels, "
780 "scan all channels");
781 n_channels = 0;
782 }
783
784 for (i = 0; i < n_channels; i++)
785 channels[i] = request->channels[i]->center_freq;
786 }
787
59c98449 788 if (test_bit(CONNECTED, &vif->flags))
f1f92179
VT
789 force_fg_scan = 1;
790
791 ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, force_fg_scan,
1b1e6ee3
JM
792 false, 0, 0, n_channels, channels);
793 if (ret)
bdcd8170 794 ath6kl_err("wmi_startscan_cmd failed\n");
11869bef
JM
795 else
796 ar->scan_req = request;
bdcd8170 797
1276c9ef
EL
798 kfree(channels);
799
bdcd8170
KV
800 return ret;
801}
802
803void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
804{
6fd1eace 805 int i;
bdcd8170
KV
806
807 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
808
6fd1eace
KV
809 if (!ar->scan_req)
810 return;
811
812 if ((status == -ECANCELED) || (status == -EBUSY)) {
813 cfg80211_scan_done(ar->scan_req, true);
814 goto out;
815 }
6fd1eace
KV
816
817 cfg80211_scan_done(ar->scan_req, false);
818
819 if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
820 for (i = 0; i < ar->scan_req->n_ssids; i++) {
821 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
822 DISABLE_SSID_FLAG,
823 0, NULL);
bdcd8170 824 }
bdcd8170 825 }
6fd1eace
KV
826
827out:
828 ar->scan_req = NULL;
bdcd8170
KV
829}
830
831static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
832 u8 key_index, bool pairwise,
833 const u8 *mac_addr,
834 struct key_params *params)
835{
836 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
59c98449 837 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
838 struct ath6kl_key *key = NULL;
839 u8 key_usage;
840 u8 key_type;
841 int status = 0;
842
843 if (!ath6kl_cfg80211_ready(ar))
844 return -EIO;
845
837cb97e
JM
846 if (params->cipher == CCKM_KRK_CIPHER_SUITE) {
847 if (params->key_len != WMI_KRK_LEN)
848 return -EINVAL;
849 return ath6kl_wmi_add_krk_cmd(ar->wmi, params->key);
850 }
851
bdcd8170
KV
852 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
853 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
854 "%s: key index %d out of bounds\n", __func__,
855 key_index);
856 return -ENOENT;
857 }
858
6f2a73f9 859 key = &vif->keys[key_index];
bdcd8170
KV
860 memset(key, 0, sizeof(struct ath6kl_key));
861
862 if (pairwise)
863 key_usage = PAIRWISE_USAGE;
864 else
865 key_usage = GROUP_USAGE;
866
867 if (params) {
868 if (params->key_len > WLAN_MAX_KEY_LEN ||
869 params->seq_len > sizeof(key->seq))
870 return -EINVAL;
871
872 key->key_len = params->key_len;
873 memcpy(key->key, params->key, key->key_len);
874 key->seq_len = params->seq_len;
875 memcpy(key->seq, params->seq, key->seq_len);
876 key->cipher = params->cipher;
877 }
878
879 switch (key->cipher) {
880 case WLAN_CIPHER_SUITE_WEP40:
881 case WLAN_CIPHER_SUITE_WEP104:
882 key_type = WEP_CRYPT;
883 break;
884
885 case WLAN_CIPHER_SUITE_TKIP:
886 key_type = TKIP_CRYPT;
887 break;
888
889 case WLAN_CIPHER_SUITE_CCMP:
890 key_type = AES_CRYPT;
891 break;
892
893 default:
894 return -ENOTSUPP;
895 }
896
3450334f
VT
897 if (((vif->auth_mode == WPA_PSK_AUTH)
898 || (vif->auth_mode == WPA2_PSK_AUTH))
bdcd8170
KV
899 && (key_usage & GROUP_USAGE))
900 del_timer(&ar->disconnect_timer);
901
902 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
903 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
904 __func__, key_index, key->key_len, key_type,
905 key_usage, key->seq_len);
906
3450334f 907 vif->def_txkey_index = key_index;
9a5b1318 908
f5938f24 909 if (vif->nw_type == AP_NETWORK && !pairwise &&
9a5b1318
JM
910 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
911 ar->ap_mode_bkey.valid = true;
912 ar->ap_mode_bkey.key_index = key_index;
913 ar->ap_mode_bkey.key_type = key_type;
914 ar->ap_mode_bkey.key_len = key->key_len;
915 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
59c98449 916 if (!test_bit(CONNECTED, &vif->flags)) {
9a5b1318
JM
917 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
918 "key configuration until AP mode has been "
919 "started\n");
920 /*
921 * The key will be set in ath6kl_connect_ap_mode() once
922 * the connected event is received from the target.
923 */
924 return 0;
925 }
926 }
927
f5938f24 928 if (vif->next_mode == AP_NETWORK && key_type == WEP_CRYPT &&
59c98449 929 !test_bit(CONNECTED, &vif->flags)) {
151411e8
JM
930 /*
931 * Store the key locally so that it can be re-configured after
932 * the AP mode has properly started
933 * (ath6kl_install_statioc_wep_keys).
934 */
935 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay WEP key configuration "
936 "until AP mode has been started\n");
6f2a73f9
VT
937 vif->wep_key_list[key_index].key_len = key->key_len;
938 memcpy(vif->wep_key_list[key_index].key, key->key,
939 key->key_len);
151411e8
JM
940 return 0;
941 }
942
3450334f 943 status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
bdcd8170
KV
944 key_type, key_usage, key->key_len,
945 key->seq, key->key, KEY_OP_INIT_VAL,
946 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
947
948 if (status)
949 return -EIO;
950
951 return 0;
952}
953
954static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
955 u8 key_index, bool pairwise,
956 const u8 *mac_addr)
957{
958 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
6f2a73f9 959 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
960
961 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
962
963 if (!ath6kl_cfg80211_ready(ar))
964 return -EIO;
965
966 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
967 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
968 "%s: key index %d out of bounds\n", __func__,
969 key_index);
970 return -ENOENT;
971 }
972
6f2a73f9 973 if (!vif->keys[key_index].key_len) {
bdcd8170
KV
974 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
975 "%s: index %d is empty\n", __func__, key_index);
976 return 0;
977 }
978
6f2a73f9 979 vif->keys[key_index].key_len = 0;
bdcd8170
KV
980
981 return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
982}
983
984static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
985 u8 key_index, bool pairwise,
986 const u8 *mac_addr, void *cookie,
987 void (*callback) (void *cookie,
988 struct key_params *))
989{
990 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
6f2a73f9 991 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
992 struct ath6kl_key *key = NULL;
993 struct key_params params;
994
995 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
996
997 if (!ath6kl_cfg80211_ready(ar))
998 return -EIO;
999
1000 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1001 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1002 "%s: key index %d out of bounds\n", __func__,
1003 key_index);
1004 return -ENOENT;
1005 }
1006
6f2a73f9 1007 key = &vif->keys[key_index];
bdcd8170
KV
1008 memset(&params, 0, sizeof(params));
1009 params.cipher = key->cipher;
1010 params.key_len = key->key_len;
1011 params.seq_len = key->seq_len;
1012 params.seq = key->seq;
1013 params.key = key->key;
1014
1015 callback(cookie, &params);
1016
1017 return key->key_len ? 0 : -ENOENT;
1018}
1019
1020static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1021 struct net_device *ndev,
1022 u8 key_index, bool unicast,
1023 bool multicast)
1024{
1025 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
59c98449 1026 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
1027 struct ath6kl_key *key = NULL;
1028 int status = 0;
1029 u8 key_usage;
229ed6b5 1030 enum crypto_type key_type = NONE_CRYPT;
bdcd8170
KV
1031
1032 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1033
1034 if (!ath6kl_cfg80211_ready(ar))
1035 return -EIO;
1036
1037 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1038 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1039 "%s: key index %d out of bounds\n",
1040 __func__, key_index);
1041 return -ENOENT;
1042 }
1043
6f2a73f9 1044 if (!vif->keys[key_index].key_len) {
bdcd8170
KV
1045 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1046 __func__, key_index);
1047 return -EINVAL;
1048 }
1049
3450334f 1050 vif->def_txkey_index = key_index;
6f2a73f9 1051 key = &vif->keys[vif->def_txkey_index];
bdcd8170 1052 key_usage = GROUP_USAGE;
3450334f 1053 if (vif->prwise_crypto == WEP_CRYPT)
bdcd8170 1054 key_usage |= TX_USAGE;
229ed6b5 1055 if (unicast)
3450334f 1056 key_type = vif->prwise_crypto;
229ed6b5 1057 if (multicast)
3450334f 1058 key_type = vif->grp_crypto;
bdcd8170 1059
f5938f24 1060 if (vif->next_mode == AP_NETWORK && !test_bit(CONNECTED, &vif->flags))
9a5b1318
JM
1061 return 0; /* Delay until AP mode has been started */
1062
3450334f 1063 status = ath6kl_wmi_addkey_cmd(ar->wmi, vif->def_txkey_index,
229ed6b5 1064 key_type, key_usage,
bdcd8170
KV
1065 key->key_len, key->seq, key->key,
1066 KEY_OP_INIT_VAL, NULL,
1067 SYNC_BOTH_WMIFLAG);
1068 if (status)
1069 return -EIO;
1070
1071 return 0;
1072}
1073
1074void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
1075 bool ismcast)
1076{
8c8b65e3
VT
1077 /* TODO: Findout vif */
1078 struct ath6kl_vif *vif = ar->vif;
1079
bdcd8170
KV
1080 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1081 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1082
8c8b65e3 1083 cfg80211_michael_mic_failure(ar->net_dev, vif->bssid,
bdcd8170
KV
1084 (ismcast ? NL80211_KEYTYPE_GROUP :
1085 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1086 GFP_KERNEL);
1087}
1088
1089static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1090{
1091 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1092 int ret;
1093
1094 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1095 changed);
1096
1097 if (!ath6kl_cfg80211_ready(ar))
1098 return -EIO;
1099
1100 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1101 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1102 if (ret != 0) {
1103 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1104 return -EIO;
1105 }
1106 }
1107
1108 return 0;
1109}
1110
1111/*
1112 * The type nl80211_tx_power_setting replaces the following
1113 * data type from 2.6.36 onwards
1114*/
1115static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1116 enum nl80211_tx_power_setting type,
1117 int dbm)
1118{
1119 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1120 u8 ath6kl_dbm;
1121
1122 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1123 type, dbm);
1124
1125 if (!ath6kl_cfg80211_ready(ar))
1126 return -EIO;
1127
1128 switch (type) {
1129 case NL80211_TX_POWER_AUTOMATIC:
1130 return 0;
1131 case NL80211_TX_POWER_LIMITED:
1132 ar->tx_pwr = ath6kl_dbm = dbm;
1133 break;
1134 default:
1135 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1136 __func__, type);
1137 return -EOPNOTSUPP;
1138 }
1139
1140 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1141
1142 return 0;
1143}
1144
1145static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1146{
1147 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
59c98449 1148 struct ath6kl_vif *vif = ar->vif;
bdcd8170
KV
1149
1150 if (!ath6kl_cfg80211_ready(ar))
1151 return -EIO;
1152
59c98449 1153 if (test_bit(CONNECTED, &vif->flags)) {
bdcd8170
KV
1154 ar->tx_pwr = 0;
1155
1156 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1157 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1158 return -EIO;
1159 }
1160
1161 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1162 5 * HZ);
1163
1164 if (signal_pending(current)) {
1165 ath6kl_err("target did not respond\n");
1166 return -EINTR;
1167 }
1168 }
1169
1170 *dbm = ar->tx_pwr;
1171 return 0;
1172}
1173
1174static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1175 struct net_device *dev,
1176 bool pmgmt, int timeout)
1177{
1178 struct ath6kl *ar = ath6kl_priv(dev);
1179 struct wmi_power_mode_cmd mode;
1180
1181 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1182 __func__, pmgmt, timeout);
1183
1184 if (!ath6kl_cfg80211_ready(ar))
1185 return -EIO;
1186
1187 if (pmgmt) {
1188 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1189 mode.pwr_mode = REC_POWER;
1190 } else {
1191 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1192 mode.pwr_mode = MAX_PERF_POWER;
1193 }
1194
1195 if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1196 ath6kl_err("wmi_powermode_cmd failed\n");
1197 return -EIO;
1198 }
1199
1200 return 0;
1201}
1202
1203static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1204 struct net_device *ndev,
1205 enum nl80211_iftype type, u32 *flags,
1206 struct vif_params *params)
1207{
1208 struct ath6kl *ar = ath6kl_priv(ndev);
1209 struct wireless_dev *wdev = ar->wdev;
f5938f24 1210 struct ath6kl_vif *vif = netdev_priv(ndev);
bdcd8170
KV
1211
1212 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1213
1214 if (!ath6kl_cfg80211_ready(ar))
1215 return -EIO;
1216
1217 switch (type) {
1218 case NL80211_IFTYPE_STATION:
f5938f24 1219 vif->next_mode = INFRA_NETWORK;
bdcd8170
KV
1220 break;
1221 case NL80211_IFTYPE_ADHOC:
f5938f24 1222 vif->next_mode = ADHOC_NETWORK;
bdcd8170 1223 break;
6e4604c8 1224 case NL80211_IFTYPE_AP:
f5938f24 1225 vif->next_mode = AP_NETWORK;
6e4604c8 1226 break;
6b5e5d25 1227 case NL80211_IFTYPE_P2P_CLIENT:
f5938f24 1228 vif->next_mode = INFRA_NETWORK;
6b5e5d25
JM
1229 break;
1230 case NL80211_IFTYPE_P2P_GO:
f5938f24 1231 vif->next_mode = AP_NETWORK;
6b5e5d25 1232 break;
bdcd8170
KV
1233 default:
1234 ath6kl_err("invalid interface type %u\n", type);
1235 return -EOPNOTSUPP;
1236 }
1237
1238 wdev->iftype = type;
1239
1240 return 0;
1241}
1242
1243static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1244 struct net_device *dev,
1245 struct cfg80211_ibss_params *ibss_param)
1246{
1247 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1248 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1249 int status;
1250
1251 if (!ath6kl_cfg80211_ready(ar))
1252 return -EIO;
1253
3450334f
VT
1254 vif->ssid_len = ibss_param->ssid_len;
1255 memcpy(vif->ssid, ibss_param->ssid, vif->ssid_len);
bdcd8170
KV
1256
1257 if (ibss_param->channel)
f74bac54 1258 vif->ch_hint = ibss_param->channel->center_freq;
bdcd8170
KV
1259
1260 if (ibss_param->channel_fixed) {
1261 /*
1262 * TODO: channel_fixed: The channel should be fixed, do not
1263 * search for IBSSs to join on other channels. Target
1264 * firmware does not support this feature, needs to be
1265 * updated.
1266 */
1267 return -EOPNOTSUPP;
1268 }
1269
8c8b65e3 1270 memset(vif->req_bssid, 0, sizeof(vif->req_bssid));
bdcd8170 1271 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
8c8b65e3
VT
1272 memcpy(vif->req_bssid, ibss_param->bssid,
1273 sizeof(vif->req_bssid));
bdcd8170
KV
1274
1275 ath6kl_set_wpa_version(ar, 0);
1276
1277 status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1278 if (status)
1279 return status;
1280
1281 if (ibss_param->privacy) {
1282 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1283 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1284 } else {
1285 ath6kl_set_cipher(ar, 0, true);
1286 ath6kl_set_cipher(ar, 0, false);
1287 }
1288
f5938f24 1289 vif->nw_type = vif->next_mode;
bdcd8170
KV
1290
1291 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1292 "%s: connect called with authmode %d dot11 auth %d"
1293 " PW crypto %d PW crypto len %d GRP crypto %d"
1294 " GRP crypto len %d channel hint %u\n",
1295 __func__,
3450334f
VT
1296 vif->auth_mode, vif->dot11_auth_mode, vif->prwise_crypto,
1297 vif->prwise_crypto_len, vif->grp_crypto,
f74bac54 1298 vif->grp_crypto_len, vif->ch_hint);
bdcd8170 1299
f5938f24 1300 status = ath6kl_wmi_connect_cmd(ar->wmi, vif->nw_type,
3450334f
VT
1301 vif->dot11_auth_mode, vif->auth_mode,
1302 vif->prwise_crypto,
1303 vif->prwise_crypto_len,
1304 vif->grp_crypto, vif->grp_crypto_len,
1305 vif->ssid_len, vif->ssid,
f74bac54 1306 vif->req_bssid, vif->ch_hint,
bdcd8170 1307 ar->connect_ctrl_flags);
59c98449 1308 set_bit(CONNECT_PEND, &vif->flags);
bdcd8170
KV
1309
1310 return 0;
1311}
1312
1313static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1314 struct net_device *dev)
1315{
1316 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
3450334f 1317 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1318
1319 if (!ath6kl_cfg80211_ready(ar))
1320 return -EIO;
1321
1322 ath6kl_disconnect(ar);
3450334f
VT
1323 memset(vif->ssid, 0, sizeof(vif->ssid));
1324 vif->ssid_len = 0;
bdcd8170
KV
1325
1326 return 0;
1327}
1328
1329static const u32 cipher_suites[] = {
1330 WLAN_CIPHER_SUITE_WEP40,
1331 WLAN_CIPHER_SUITE_WEP104,
1332 WLAN_CIPHER_SUITE_TKIP,
1333 WLAN_CIPHER_SUITE_CCMP,
837cb97e 1334 CCKM_KRK_CIPHER_SUITE,
bdcd8170
KV
1335};
1336
1337static bool is_rate_legacy(s32 rate)
1338{
1339 static const s32 legacy[] = { 1000, 2000, 5500, 11000,
1340 6000, 9000, 12000, 18000, 24000,
1341 36000, 48000, 54000
1342 };
1343 u8 i;
1344
1345 for (i = 0; i < ARRAY_SIZE(legacy); i++)
1346 if (rate == legacy[i])
1347 return true;
1348
1349 return false;
1350}
1351
1352static bool is_rate_ht20(s32 rate, u8 *mcs, bool *sgi)
1353{
1354 static const s32 ht20[] = { 6500, 13000, 19500, 26000, 39000,
1355 52000, 58500, 65000, 72200
1356 };
1357 u8 i;
1358
1359 for (i = 0; i < ARRAY_SIZE(ht20); i++) {
1360 if (rate == ht20[i]) {
1361 if (i == ARRAY_SIZE(ht20) - 1)
1362 /* last rate uses sgi */
1363 *sgi = true;
1364 else
1365 *sgi = false;
1366
1367 *mcs = i;
1368 return true;
1369 }
1370 }
1371 return false;
1372}
1373
1374static bool is_rate_ht40(s32 rate, u8 *mcs, bool *sgi)
1375{
1376 static const s32 ht40[] = { 13500, 27000, 40500, 54000,
1377 81000, 108000, 121500, 135000,
1378 150000
1379 };
1380 u8 i;
1381
1382 for (i = 0; i < ARRAY_SIZE(ht40); i++) {
1383 if (rate == ht40[i]) {
1384 if (i == ARRAY_SIZE(ht40) - 1)
1385 /* last rate uses sgi */
1386 *sgi = true;
1387 else
1388 *sgi = false;
1389
1390 *mcs = i;
1391 return true;
1392 }
1393 }
1394
1395 return false;
1396}
1397
1398static int ath6kl_get_station(struct wiphy *wiphy, struct net_device *dev,
1399 u8 *mac, struct station_info *sinfo)
1400{
1401 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1402 struct ath6kl_vif *vif = netdev_priv(dev);
bdcd8170
KV
1403 long left;
1404 bool sgi;
1405 s32 rate;
1406 int ret;
1407 u8 mcs;
1408
8c8b65e3 1409 if (memcmp(mac, vif->bssid, ETH_ALEN) != 0)
bdcd8170
KV
1410 return -ENOENT;
1411
1412 if (down_interruptible(&ar->sem))
1413 return -EBUSY;
1414
1415 set_bit(STATS_UPDATE_PEND, &ar->flag);
1416
1417 ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1418
1419 if (ret != 0) {
1420 up(&ar->sem);
1421 return -EIO;
1422 }
1423
1424 left = wait_event_interruptible_timeout(ar->event_wq,
1425 !test_bit(STATS_UPDATE_PEND,
1426 &ar->flag),
1427 WMI_TIMEOUT);
1428
1429 up(&ar->sem);
1430
1431 if (left == 0)
1432 return -ETIMEDOUT;
1433 else if (left < 0)
1434 return left;
1435
1436 if (ar->target_stats.rx_byte) {
1437 sinfo->rx_bytes = ar->target_stats.rx_byte;
1438 sinfo->filled |= STATION_INFO_RX_BYTES;
1439 sinfo->rx_packets = ar->target_stats.rx_pkt;
1440 sinfo->filled |= STATION_INFO_RX_PACKETS;
1441 }
1442
1443 if (ar->target_stats.tx_byte) {
1444 sinfo->tx_bytes = ar->target_stats.tx_byte;
1445 sinfo->filled |= STATION_INFO_TX_BYTES;
1446 sinfo->tx_packets = ar->target_stats.tx_pkt;
1447 sinfo->filled |= STATION_INFO_TX_PACKETS;
1448 }
1449
1450 sinfo->signal = ar->target_stats.cs_rssi;
1451 sinfo->filled |= STATION_INFO_SIGNAL;
1452
1453 rate = ar->target_stats.tx_ucast_rate;
1454
1455 if (is_rate_legacy(rate)) {
1456 sinfo->txrate.legacy = rate / 100;
1457 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1458 if (sgi) {
1459 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1460 sinfo->txrate.mcs = mcs - 1;
1461 } else {
1462 sinfo->txrate.mcs = mcs;
1463 }
1464
1465 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1466 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1467 if (sgi) {
1468 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1469 sinfo->txrate.mcs = mcs - 1;
1470 } else {
1471 sinfo->txrate.mcs = mcs;
1472 }
1473
1474 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1475 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1476 } else {
9a730834
KV
1477 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1478 "invalid rate from stats: %d\n", rate);
1479 ath6kl_debug_war(ar, ATH6KL_WAR_INVALID_RATE);
bdcd8170
KV
1480 return 0;
1481 }
1482
1483 sinfo->filled |= STATION_INFO_TX_BITRATE;
1484
59c98449
VT
1485 if (test_bit(CONNECTED, &vif->flags) &&
1486 test_bit(DTIM_PERIOD_AVAIL, &vif->flags) &&
f5938f24 1487 vif->nw_type == INFRA_NETWORK) {
32c10874
JM
1488 sinfo->filled |= STATION_INFO_BSS_PARAM;
1489 sinfo->bss_param.flags = 0;
1490 sinfo->bss_param.dtim_period = ar->assoc_bss_dtim_period;
1491 sinfo->bss_param.beacon_interval = ar->assoc_bss_beacon_int;
1492 }
1493
bdcd8170
KV
1494 return 0;
1495}
1496
1497static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1498 struct cfg80211_pmksa *pmksa)
1499{
1500 struct ath6kl *ar = ath6kl_priv(netdev);
1501 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1502 pmksa->pmkid, true);
1503}
1504
1505static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1506 struct cfg80211_pmksa *pmksa)
1507{
1508 struct ath6kl *ar = ath6kl_priv(netdev);
1509 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1510 pmksa->pmkid, false);
1511}
1512
1513static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1514{
1515 struct ath6kl *ar = ath6kl_priv(netdev);
59c98449
VT
1516 struct ath6kl_vif *vif = netdev_priv(netdev);
1517
1518 if (test_bit(CONNECTED, &vif->flags))
8c8b65e3
VT
1519 return ath6kl_wmi_setpmkid_cmd(ar->wmi, vif->bssid,
1520 NULL, false);
bdcd8170
KV
1521 return 0;
1522}
1523
abcb344b
KV
1524#ifdef CONFIG_PM
1525static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1526 struct cfg80211_wowlan *wow)
1527{
1528 struct ath6kl *ar = wiphy_priv(wiphy);
1529
1530 return ath6kl_hif_suspend(ar);
1531}
aa6cffc1
CN
1532
1533static int ar6k_cfg80211_resume(struct wiphy *wiphy)
1534{
1535 struct ath6kl *ar = wiphy_priv(wiphy);
1536
1537 return ath6kl_hif_resume(ar);
1538}
abcb344b
KV
1539#endif
1540
6a7c9bad
JM
1541static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1542 struct ieee80211_channel *chan,
1543 enum nl80211_channel_type channel_type)
1544{
1545 struct ath6kl *ar = ath6kl_priv(dev);
1546
1547 if (!ath6kl_cfg80211_ready(ar))
1548 return -EIO;
1549
1550 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1551 __func__, chan->center_freq, chan->hw_value);
1552 ar->next_chan = chan->center_freq;
1553
1554 return 0;
1555}
1556
8bdfbf40
JM
1557static bool ath6kl_is_p2p_ie(const u8 *pos)
1558{
1559 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1560 pos[2] == 0x50 && pos[3] == 0x6f &&
1561 pos[4] == 0x9a && pos[5] == 0x09;
1562}
1563
1564static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1565 size_t ies_len)
1566{
1567 const u8 *pos;
1568 u8 *buf = NULL;
1569 size_t len = 0;
1570 int ret;
1571
1572 /*
1573 * Filter out P2P IE(s) since they will be included depending on
1574 * the Probe Request frame in ath6kl_send_go_probe_resp().
1575 */
1576
1577 if (ies && ies_len) {
1578 buf = kmalloc(ies_len, GFP_KERNEL);
1579 if (buf == NULL)
1580 return -ENOMEM;
1581 pos = ies;
1582 while (pos + 1 < ies + ies_len) {
1583 if (pos + 2 + pos[1] > ies + ies_len)
1584 break;
1585 if (!ath6kl_is_p2p_ie(pos)) {
1586 memcpy(buf + len, pos, 2 + pos[1]);
1587 len += 2 + pos[1];
1588 }
1589 pos += 2 + pos[1];
1590 }
1591 }
1592
1593 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1594 buf, len);
1595 kfree(buf);
1596 return ret;
1597}
1598
6a7c9bad
JM
1599static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1600 struct beacon_parameters *info, bool add)
1601{
1602 struct ath6kl *ar = ath6kl_priv(dev);
3450334f 1603 struct ath6kl_vif *vif = netdev_priv(dev);
6a7c9bad
JM
1604 struct ieee80211_mgmt *mgmt;
1605 u8 *ies;
1606 int ies_len;
1607 struct wmi_connect_cmd p;
1608 int res;
1609 int i;
1610
1611 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1612
1613 if (!ath6kl_cfg80211_ready(ar))
1614 return -EIO;
1615
f5938f24 1616 if (vif->next_mode != AP_NETWORK)
6a7c9bad
JM
1617 return -EOPNOTSUPP;
1618
1619 if (info->beacon_ies) {
1620 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1621 info->beacon_ies,
1622 info->beacon_ies_len);
1623 if (res)
1624 return res;
1625 }
1626 if (info->proberesp_ies) {
8bdfbf40
JM
1627 res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1628 info->proberesp_ies_len);
6a7c9bad
JM
1629 if (res)
1630 return res;
1631 }
1632 if (info->assocresp_ies) {
1633 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1634 info->assocresp_ies,
1635 info->assocresp_ies_len);
1636 if (res)
1637 return res;
1638 }
1639
1640 if (!add)
1641 return 0;
1642
9a5b1318
JM
1643 ar->ap_mode_bkey.valid = false;
1644
6a7c9bad
JM
1645 /* TODO:
1646 * info->interval
1647 * info->dtim_period
1648 */
1649
1650 if (info->head == NULL)
1651 return -EINVAL;
1652 mgmt = (struct ieee80211_mgmt *) info->head;
1653 ies = mgmt->u.beacon.variable;
1654 if (ies > info->head + info->head_len)
1655 return -EINVAL;
1656 ies_len = info->head + info->head_len - ies;
1657
1658 if (info->ssid == NULL)
1659 return -EINVAL;
3450334f
VT
1660 memcpy(vif->ssid, info->ssid, info->ssid_len);
1661 vif->ssid_len = info->ssid_len;
6a7c9bad
JM
1662 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1663 return -EOPNOTSUPP; /* TODO */
1664
3450334f 1665 vif->dot11_auth_mode = OPEN_AUTH;
6a7c9bad
JM
1666
1667 memset(&p, 0, sizeof(p));
1668
1669 for (i = 0; i < info->crypto.n_akm_suites; i++) {
1670 switch (info->crypto.akm_suites[i]) {
1671 case WLAN_AKM_SUITE_8021X:
1672 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1673 p.auth_mode |= WPA_AUTH;
1674 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1675 p.auth_mode |= WPA2_AUTH;
1676 break;
1677 case WLAN_AKM_SUITE_PSK:
1678 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1679 p.auth_mode |= WPA_PSK_AUTH;
1680 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1681 p.auth_mode |= WPA2_PSK_AUTH;
1682 break;
1683 }
1684 }
1685 if (p.auth_mode == 0)
1686 p.auth_mode = NONE_AUTH;
3450334f 1687 vif->auth_mode = p.auth_mode;
6a7c9bad
JM
1688
1689 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1690 switch (info->crypto.ciphers_pairwise[i]) {
1691 case WLAN_CIPHER_SUITE_WEP40:
1692 case WLAN_CIPHER_SUITE_WEP104:
1693 p.prwise_crypto_type |= WEP_CRYPT;
1694 break;
1695 case WLAN_CIPHER_SUITE_TKIP:
1696 p.prwise_crypto_type |= TKIP_CRYPT;
1697 break;
1698 case WLAN_CIPHER_SUITE_CCMP:
1699 p.prwise_crypto_type |= AES_CRYPT;
1700 break;
1701 }
1702 }
229ed6b5 1703 if (p.prwise_crypto_type == 0) {
6a7c9bad 1704 p.prwise_crypto_type = NONE_CRYPT;
229ed6b5
EL
1705 ath6kl_set_cipher(ar, 0, true);
1706 } else if (info->crypto.n_ciphers_pairwise == 1)
1707 ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
6a7c9bad
JM
1708
1709 switch (info->crypto.cipher_group) {
1710 case WLAN_CIPHER_SUITE_WEP40:
1711 case WLAN_CIPHER_SUITE_WEP104:
1712 p.grp_crypto_type = WEP_CRYPT;
1713 break;
1714 case WLAN_CIPHER_SUITE_TKIP:
1715 p.grp_crypto_type = TKIP_CRYPT;
1716 break;
1717 case WLAN_CIPHER_SUITE_CCMP:
1718 p.grp_crypto_type = AES_CRYPT;
1719 break;
1720 default:
1721 p.grp_crypto_type = NONE_CRYPT;
1722 break;
1723 }
229ed6b5 1724 ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
6a7c9bad
JM
1725
1726 p.nw_type = AP_NETWORK;
f5938f24 1727 vif->nw_type = vif->next_mode;
6a7c9bad 1728
3450334f
VT
1729 p.ssid_len = vif->ssid_len;
1730 memcpy(p.ssid, vif->ssid, vif->ssid_len);
1731 p.dot11_auth_mode = vif->dot11_auth_mode;
6a7c9bad
JM
1732 p.ch = cpu_to_le16(ar->next_chan);
1733
9a5b1318
JM
1734 res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1735 if (res < 0)
1736 return res;
1737
1738 return 0;
6a7c9bad
JM
1739}
1740
1741static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1742 struct beacon_parameters *info)
1743{
1744 return ath6kl_ap_beacon(wiphy, dev, info, true);
1745}
1746
1747static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1748 struct beacon_parameters *info)
1749{
1750 return ath6kl_ap_beacon(wiphy, dev, info, false);
1751}
1752
1753static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1754{
1755 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1756 struct ath6kl_vif *vif = netdev_priv(dev);
6a7c9bad 1757
f5938f24 1758 if (vif->nw_type != AP_NETWORK)
6a7c9bad 1759 return -EOPNOTSUPP;
59c98449 1760 if (!test_bit(CONNECTED, &vif->flags))
6a7c9bad
JM
1761 return -ENOTCONN;
1762
1763 ath6kl_wmi_disconnect_cmd(ar->wmi);
59c98449 1764 clear_bit(CONNECTED, &vif->flags);
6a7c9bad
JM
1765
1766 return 0;
1767}
1768
23875136
JM
1769static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1770 u8 *mac, struct station_parameters *params)
1771{
1772 struct ath6kl *ar = ath6kl_priv(dev);
f5938f24 1773 struct ath6kl_vif *vif = netdev_priv(dev);
23875136 1774
f5938f24 1775 if (vif->nw_type != AP_NETWORK)
23875136
JM
1776 return -EOPNOTSUPP;
1777
1778 /* Use this only for authorizing/unauthorizing a station */
1779 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1780 return -EOPNOTSUPP;
1781
1782 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1783 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1784 mac, 0);
1785 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1786 0);
1787}
1788
63fa1e0c
JM
1789static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1790 struct net_device *dev,
1791 struct ieee80211_channel *chan,
1792 enum nl80211_channel_type channel_type,
1793 unsigned int duration,
1794 u64 *cookie)
1795{
1796 struct ath6kl *ar = ath6kl_priv(dev);
1797
1798 /* TODO: if already pending or ongoing remain-on-channel,
1799 * return -EBUSY */
1800 *cookie = 1; /* only a single pending request is supported */
1801
1802 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1803 duration);
1804}
1805
1806static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1807 struct net_device *dev,
1808 u64 cookie)
1809{
1810 struct ath6kl *ar = ath6kl_priv(dev);
1811
1812 if (cookie != 1)
1813 return -ENOENT;
1814
1815 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1816}
1817
8bdfbf40
JM
1818static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1819 size_t len, unsigned int freq)
1820{
1821 const u8 *pos;
1822 u8 *p2p;
1823 int p2p_len;
1824 int ret;
1825 const struct ieee80211_mgmt *mgmt;
1826
1827 mgmt = (const struct ieee80211_mgmt *) buf;
1828
1829 /* Include P2P IE(s) from the frame generated in user space. */
1830
1831 p2p = kmalloc(len, GFP_KERNEL);
1832 if (p2p == NULL)
1833 return -ENOMEM;
1834 p2p_len = 0;
1835
1836 pos = mgmt->u.probe_resp.variable;
1837 while (pos + 1 < buf + len) {
1838 if (pos + 2 + pos[1] > buf + len)
1839 break;
1840 if (ath6kl_is_p2p_ie(pos)) {
1841 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1842 p2p_len += 2 + pos[1];
1843 }
1844 pos += 2 + pos[1];
1845 }
1846
1847 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1848 p2p, p2p_len);
1849 kfree(p2p);
1850 return ret;
1851}
1852
8a6c8060
JM
1853static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1854 struct ieee80211_channel *chan, bool offchan,
1855 enum nl80211_channel_type channel_type,
1856 bool channel_type_valid, unsigned int wait,
e247bd90
JB
1857 const u8 *buf, size_t len, bool no_cck,
1858 bool dont_wait_for_ack, u64 *cookie)
8a6c8060
JM
1859{
1860 struct ath6kl *ar = ath6kl_priv(dev);
59c98449 1861 struct ath6kl_vif *vif = netdev_priv(dev);
8a6c8060 1862 u32 id;
8bdfbf40
JM
1863 const struct ieee80211_mgmt *mgmt;
1864
1865 mgmt = (const struct ieee80211_mgmt *) buf;
1866 if (buf + len >= mgmt->u.probe_resp.variable &&
f5938f24 1867 vif->nw_type == AP_NETWORK && test_bit(CONNECTED, &vif->flags) &&
8bdfbf40
JM
1868 ieee80211_is_probe_resp(mgmt->frame_control)) {
1869 /*
1870 * Send Probe Response frame in AP mode using a separate WMI
1871 * command to allow the target to fill in the generic IEs.
1872 */
1873 *cookie = 0; /* TX status not supported */
1874 return ath6kl_send_go_probe_resp(ar, buf, len,
1875 chan->center_freq);
1876 }
8a6c8060
JM
1877
1878 id = ar->send_action_id++;
1879 if (id == 0) {
1880 /*
1881 * 0 is a reserved value in the WMI command and shall not be
1882 * used for the command.
1883 */
1884 id = ar->send_action_id++;
1885 }
1886
1887 *cookie = id;
1888 return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1889 buf, len);
1890}
1891
ae32c30a
JM
1892static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1893 struct net_device *dev,
1894 u16 frame_type, bool reg)
1895{
1896 struct ath6kl *ar = ath6kl_priv(dev);
1897
1898 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1899 __func__, frame_type, reg);
1900 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1901 /*
1902 * Note: This notification callback is not allowed to sleep, so
1903 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1904 * hardcode target to report Probe Request frames all the time.
1905 */
1906 ar->probe_req_report = reg;
1907 }
1908}
1909
f80574ae
JM
1910static const struct ieee80211_txrx_stypes
1911ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1912 [NL80211_IFTYPE_STATION] = {
1913 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1914 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1915 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1916 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1917 },
1918 [NL80211_IFTYPE_P2P_CLIENT] = {
1919 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1920 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1921 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1922 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1923 },
1924 [NL80211_IFTYPE_P2P_GO] = {
1925 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1926 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1927 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1928 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1929 },
1930};
1931
bdcd8170
KV
1932static struct cfg80211_ops ath6kl_cfg80211_ops = {
1933 .change_virtual_intf = ath6kl_cfg80211_change_iface,
1934 .scan = ath6kl_cfg80211_scan,
1935 .connect = ath6kl_cfg80211_connect,
1936 .disconnect = ath6kl_cfg80211_disconnect,
1937 .add_key = ath6kl_cfg80211_add_key,
1938 .get_key = ath6kl_cfg80211_get_key,
1939 .del_key = ath6kl_cfg80211_del_key,
1940 .set_default_key = ath6kl_cfg80211_set_default_key,
1941 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1942 .set_tx_power = ath6kl_cfg80211_set_txpower,
1943 .get_tx_power = ath6kl_cfg80211_get_txpower,
1944 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1945 .join_ibss = ath6kl_cfg80211_join_ibss,
1946 .leave_ibss = ath6kl_cfg80211_leave_ibss,
1947 .get_station = ath6kl_get_station,
1948 .set_pmksa = ath6kl_set_pmksa,
1949 .del_pmksa = ath6kl_del_pmksa,
1950 .flush_pmksa = ath6kl_flush_pmksa,
003353b0 1951 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
abcb344b
KV
1952#ifdef CONFIG_PM
1953 .suspend = ar6k_cfg80211_suspend,
aa6cffc1 1954 .resume = ar6k_cfg80211_resume,
abcb344b 1955#endif
6a7c9bad
JM
1956 .set_channel = ath6kl_set_channel,
1957 .add_beacon = ath6kl_add_beacon,
1958 .set_beacon = ath6kl_set_beacon,
1959 .del_beacon = ath6kl_del_beacon,
23875136 1960 .change_station = ath6kl_change_station,
63fa1e0c
JM
1961 .remain_on_channel = ath6kl_remain_on_channel,
1962 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
8a6c8060 1963 .mgmt_tx = ath6kl_mgmt_tx,
ae32c30a 1964 .mgmt_frame_register = ath6kl_mgmt_frame_register,
bdcd8170
KV
1965};
1966
8dafb70e 1967struct ath6kl *ath6kl_core_alloc(struct device *dev)
bdcd8170 1968{
6bbc7c35 1969 struct ath6kl *ar;
be98e3a4 1970 struct wiphy *wiphy;
8dafb70e 1971 u8 ctr;
bdcd8170
KV
1972
1973 /* create a new wiphy for use with cfg80211 */
be98e3a4 1974 wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
8dafb70e 1975
be98e3a4 1976 if (!wiphy) {
bdcd8170 1977 ath6kl_err("couldn't allocate wiphy device\n");
bdcd8170
KV
1978 return NULL;
1979 }
1980
be98e3a4 1981 ar = wiphy_priv(wiphy);
6bbc7c35 1982 ar->p2p = !!ath6kl_p2p;
be98e3a4 1983 ar->wiphy = wiphy;
8dafb70e
VT
1984 ar->dev = dev;
1985
1986 spin_lock_init(&ar->lock);
1987 spin_lock_init(&ar->mcastpsq_lock);
1988
1989 init_waitqueue_head(&ar->event_wq);
1990 sema_init(&ar->sem, 1);
1991
1992 INIT_LIST_HEAD(&ar->amsdu_rx_buffer_queue);
1993
1994 clear_bit(WMI_ENABLED, &ar->flag);
1995 clear_bit(SKIP_SCAN, &ar->flag);
1996 clear_bit(DESTROY_IN_PROGRESS, &ar->flag);
1997
1998 ar->listen_intvl_t = A_DEFAULT_LISTEN_INTERVAL;
1999 ar->listen_intvl_b = 0;
2000 ar->tx_pwr = 0;
2001
2002 ar->intra_bss = 1;
2003 memset(&ar->sc_params, 0, sizeof(ar->sc_params));
2004 ar->sc_params.short_scan_ratio = WMI_SHORTSCANRATIO_DEFAULT;
2005 ar->sc_params.scan_ctrl_flags = DEFAULT_SCAN_CTRL_FLAGS;
2006 ar->lrssi_roam_threshold = DEF_LRSSI_ROAM_THRESHOLD;
2007
2008 memset((u8 *)ar->sta_list, 0,
2009 AP_MAX_NUM_STA * sizeof(struct ath6kl_sta));
2010
2011 /* Init the PS queues */
2012 for (ctr = 0; ctr < AP_MAX_NUM_STA; ctr++) {
2013 spin_lock_init(&ar->sta_list[ctr].psq_lock);
2014 skb_queue_head_init(&ar->sta_list[ctr].psq);
2015 }
2016
2017 skb_queue_head_init(&ar->mcastpsq);
2018
2019 memcpy(ar->ap_country_code, DEF_AP_COUNTRY_CODE, 3);
2020
2021 return ar;
2022}
2023
2024int ath6kl_register_ieee80211_hw(struct ath6kl *ar)
2025{
2026 struct wiphy *wiphy = ar->wiphy;
2027 int ret;
6bbc7c35 2028
be98e3a4 2029 wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
f80574ae 2030
be98e3a4 2031 wiphy->max_remain_on_channel_duration = 5000;
63fa1e0c 2032
bdcd8170 2033 /* set device pointer for wiphy */
8dafb70e 2034 set_wiphy_dev(wiphy, ar->dev);
bdcd8170 2035
be98e3a4 2036 wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
8dafb70e
VT
2037 BIT(NL80211_IFTYPE_ADHOC) |
2038 BIT(NL80211_IFTYPE_AP);
6bbc7c35 2039 if (ar->p2p) {
be98e3a4 2040 wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
8dafb70e 2041 BIT(NL80211_IFTYPE_P2P_CLIENT);
6bbc7c35 2042 }
8dafb70e 2043
bdcd8170 2044 /* max num of ssids that can be probed during scanning */
be98e3a4
VT
2045 wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
2046 wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
2047 wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
2048 wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
2049 wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
bdcd8170 2050
be98e3a4
VT
2051 wiphy->cipher_suites = cipher_suites;
2052 wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
bdcd8170 2053
be98e3a4 2054 ret = wiphy_register(wiphy);
bdcd8170
KV
2055 if (ret < 0) {
2056 ath6kl_err("couldn't register wiphy device\n");
8dafb70e 2057 return ret;
bdcd8170
KV
2058 }
2059
8dafb70e 2060 return 0;
bdcd8170
KV
2061}
2062
108438bc 2063static int ath6kl_init_if_data(struct ath6kl_vif *vif)
bdcd8170 2064{
108438bc
VT
2065 struct ath6kl *ar = vif->ar;
2066
2132c69c
VT
2067 vif->aggr_cntxt = aggr_init(vif->ndev);
2068 if (!vif->aggr_cntxt) {
8dafb70e
VT
2069 ath6kl_err("failed to initialize aggr\n");
2070 return -ENOMEM;
2071 }
2072
2073 setup_timer(&ar->disconnect_timer, disconnect_timer_handler,
108438bc 2074 (unsigned long) vif->ndev);
bdcd8170 2075
8dafb70e
VT
2076 return 0;
2077}
2078
108438bc 2079void ath6kl_deinit_if_data(struct ath6kl_vif *vif)
8dafb70e 2080{
2132c69c 2081 aggr_module_destroy(vif->aggr_cntxt);
8dafb70e 2082
2132c69c 2083 vif->aggr_cntxt = NULL;
8dafb70e 2084
59c98449 2085 if (test_bit(NETDEV_REGISTERED, &vif->flags)) {
108438bc 2086 unregister_netdev(vif->ndev);
59c98449 2087 clear_bit(NETDEV_REGISTERED, &vif->flags);
8dafb70e
VT
2088 }
2089
108438bc 2090 free_netdev(vif->ndev);
8dafb70e
VT
2091}
2092
2093struct net_device *ath6kl_interface_add(struct ath6kl *ar, char *name,
2094 enum nl80211_iftype type)
2095{
2096 struct net_device *ndev;
108438bc 2097 struct ath6kl_vif *vif;
8dafb70e 2098
108438bc 2099 ndev = alloc_netdev(sizeof(*vif), "wlan%d", ether_setup);
8dafb70e
VT
2100 if (!ndev)
2101 return NULL;
2102
108438bc
VT
2103 vif = netdev_priv(ndev);
2104 ndev->ieee80211_ptr = &vif->wdev;
2105 vif->wdev.wiphy = ar->wiphy;
2106 vif->ar = ar;
2107 ar->vif = vif;
2108 vif->ndev = ndev;
2109 SET_NETDEV_DEV(ndev, wiphy_dev(vif->wdev.wiphy));
2110 vif->wdev.netdev = ndev;
2111 vif->wdev.iftype = type;
2112 ar->wdev = &vif->wdev;
8dafb70e
VT
2113 ar->net_dev = ndev;
2114
2115 init_netdev(ndev);
2116
2117 ath6kl_init_control_info(ar);
2118
2119 /* TODO: Pass interface specific pointer instead of ar */
108438bc 2120 if (ath6kl_init_if_data(vif))
8dafb70e
VT
2121 goto err;
2122
2123 if (register_netdev(ndev))
2124 goto err;
2125
2126 ar->sme_state = SME_DISCONNECTED;
59c98449 2127 set_bit(WLAN_ENABLED, &vif->flags);
8dafb70e 2128 ar->wlan_pwr_state = WLAN_POWER_STATE_ON;
59c98449 2129 set_bit(NETDEV_REGISTERED, &vif->flags);
8dafb70e
VT
2130
2131 return ndev;
2132
2133err:
108438bc 2134 ath6kl_deinit_if_data(vif);
8dafb70e
VT
2135
2136 return NULL;
2137}
2138
2139void ath6kl_deinit_ieee80211_hw(struct ath6kl *ar)
2140{
bdcd8170
KV
2141 if (ar->scan_req) {
2142 cfg80211_scan_done(ar->scan_req, true);
2143 ar->scan_req = NULL;
2144 }
2145
be98e3a4
VT
2146 wiphy_unregister(ar->wiphy);
2147 wiphy_free(ar->wiphy);
bdcd8170 2148}
This page took 0.229745 seconds and 5 git commands to generate.