ath6kl: add firmware capabilities support
[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
124static int ath6kl_set_wpa_version(struct ath6kl *ar,
125 enum nl80211_wpa_versions wpa_version)
126{
127 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: %u\n", __func__, wpa_version);
128
129 if (!wpa_version) {
130 ar->auth_mode = NONE_AUTH;
131 } else if (wpa_version & NL80211_WPA_VERSION_2) {
132 ar->auth_mode = WPA2_AUTH;
133 } else if (wpa_version & NL80211_WPA_VERSION_1) {
134 ar->auth_mode = WPA_AUTH;
135 } else {
136 ath6kl_err("%s: %u not supported\n", __func__, wpa_version);
137 return -ENOTSUPP;
138 }
139
140 return 0;
141}
142
143static int ath6kl_set_auth_type(struct ath6kl *ar,
144 enum nl80211_auth_type auth_type)
145{
146
147 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, auth_type);
148
149 switch (auth_type) {
150 case NL80211_AUTHTYPE_OPEN_SYSTEM:
151 ar->dot11_auth_mode = OPEN_AUTH;
152 break;
153 case NL80211_AUTHTYPE_SHARED_KEY:
154 ar->dot11_auth_mode = SHARED_AUTH;
155 break;
156 case NL80211_AUTHTYPE_NETWORK_EAP:
157 ar->dot11_auth_mode = LEAP_AUTH;
158 break;
159
160 case NL80211_AUTHTYPE_AUTOMATIC:
161 ar->dot11_auth_mode = OPEN_AUTH;
162 ar->auto_auth_stage = AUTH_OPEN_IN_PROGRESS;
163 break;
164
165 default:
166 ath6kl_err("%s: 0x%x not spported\n", __func__, auth_type);
167 return -ENOTSUPP;
168 }
169
170 return 0;
171}
172
173static int ath6kl_set_cipher(struct ath6kl *ar, u32 cipher, bool ucast)
174{
175 u8 *ar_cipher = ucast ? &ar->prwise_crypto : &ar->grp_crypto;
38acde3c
EL
176 u8 *ar_cipher_len = ucast ? &ar->prwise_crypto_len :
177 &ar->grp_crypto_len;
bdcd8170
KV
178
179 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: cipher 0x%x, ucast %u\n",
180 __func__, cipher, ucast);
181
182 switch (cipher) {
183 case 0:
184 /* our own hack to use value 0 as no crypto used */
185 *ar_cipher = NONE_CRYPT;
186 *ar_cipher_len = 0;
187 break;
188 case WLAN_CIPHER_SUITE_WEP40:
189 *ar_cipher = WEP_CRYPT;
190 *ar_cipher_len = 5;
191 break;
192 case WLAN_CIPHER_SUITE_WEP104:
193 *ar_cipher = WEP_CRYPT;
194 *ar_cipher_len = 13;
195 break;
196 case WLAN_CIPHER_SUITE_TKIP:
197 *ar_cipher = TKIP_CRYPT;
198 *ar_cipher_len = 0;
199 break;
200 case WLAN_CIPHER_SUITE_CCMP:
201 *ar_cipher = AES_CRYPT;
202 *ar_cipher_len = 0;
203 break;
204 default:
205 ath6kl_err("cipher 0x%x not supported\n", cipher);
206 return -ENOTSUPP;
207 }
208
209 return 0;
210}
211
212static void ath6kl_set_key_mgmt(struct ath6kl *ar, u32 key_mgmt)
213{
214 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: 0x%x\n", __func__, key_mgmt);
215
216 if (key_mgmt == WLAN_AKM_SUITE_PSK) {
217 if (ar->auth_mode == WPA_AUTH)
218 ar->auth_mode = WPA_PSK_AUTH;
219 else if (ar->auth_mode == WPA2_AUTH)
220 ar->auth_mode = WPA2_PSK_AUTH;
221 } else if (key_mgmt != WLAN_AKM_SUITE_8021X) {
222 ar->auth_mode = NONE_AUTH;
223 }
224}
225
226static bool ath6kl_cfg80211_ready(struct ath6kl *ar)
227{
228 if (!test_bit(WMI_READY, &ar->flag)) {
229 ath6kl_err("wmi is not ready\n");
230 return false;
231 }
232
575b5f34 233 if (!test_bit(WLAN_ENABLED, &ar->flag)) {
bdcd8170
KV
234 ath6kl_err("wlan disabled\n");
235 return false;
236 }
237
238 return true;
239}
240
241static int ath6kl_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
242 struct cfg80211_connect_params *sme)
243{
244 struct ath6kl *ar = ath6kl_priv(dev);
245 int status;
246
247 ar->sme_state = SME_CONNECTING;
248
249 if (!ath6kl_cfg80211_ready(ar))
250 return -EIO;
251
252 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
253 ath6kl_err("destroy in progress\n");
254 return -EBUSY;
255 }
256
257 if (test_bit(SKIP_SCAN, &ar->flag) &&
258 ((sme->channel && sme->channel->center_freq == 0) ||
259 (sme->bssid && is_zero_ether_addr(sme->bssid)))) {
260 ath6kl_err("SkipScan: channel or bssid invalid\n");
261 return -EINVAL;
262 }
263
264 if (down_interruptible(&ar->sem)) {
265 ath6kl_err("busy, couldn't get access\n");
266 return -ERESTARTSYS;
267 }
268
269 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
270 ath6kl_err("busy, destroy in progress\n");
271 up(&ar->sem);
272 return -EBUSY;
273 }
274
275 if (ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)]) {
276 /*
277 * sleep until the command queue drains
278 */
279 wait_event_interruptible_timeout(ar->event_wq,
280 ar->tx_pending[ath6kl_wmi_get_control_ep(ar->wmi)] == 0,
281 WMI_TIMEOUT);
282 if (signal_pending(current)) {
283 ath6kl_err("cmd queue drain timeout\n");
284 up(&ar->sem);
285 return -EINTR;
286 }
287 }
288
289 if (test_bit(CONNECTED, &ar->flag) &&
290 ar->ssid_len == sme->ssid_len &&
291 !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
292 ar->reconnect_flag = true;
293 status = ath6kl_wmi_reconnect_cmd(ar->wmi, ar->req_bssid,
294 ar->ch_hint);
295
296 up(&ar->sem);
297 if (status) {
298 ath6kl_err("wmi_reconnect_cmd failed\n");
299 return -EIO;
300 }
301 return 0;
302 } else if (ar->ssid_len == sme->ssid_len &&
303 !memcmp(ar->ssid, sme->ssid, ar->ssid_len)) {
304 ath6kl_disconnect(ar);
305 }
306
307 memset(ar->ssid, 0, sizeof(ar->ssid));
308 ar->ssid_len = sme->ssid_len;
309 memcpy(ar->ssid, sme->ssid, sme->ssid_len);
310
311 if (sme->channel)
312 ar->ch_hint = sme->channel->center_freq;
313
314 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
315 if (sme->bssid && !is_broadcast_ether_addr(sme->bssid))
316 memcpy(ar->req_bssid, sme->bssid, sizeof(ar->req_bssid));
317
318 ath6kl_set_wpa_version(ar, sme->crypto.wpa_versions);
319
320 status = ath6kl_set_auth_type(ar, sme->auth_type);
321 if (status) {
322 up(&ar->sem);
323 return status;
324 }
325
326 if (sme->crypto.n_ciphers_pairwise)
327 ath6kl_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
328 else
329 ath6kl_set_cipher(ar, 0, true);
330
331 ath6kl_set_cipher(ar, sme->crypto.cipher_group, false);
332
333 if (sme->crypto.n_akm_suites)
334 ath6kl_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
335
336 if ((sme->key_len) &&
337 (ar->auth_mode == NONE_AUTH) && (ar->prwise_crypto == WEP_CRYPT)) {
338 struct ath6kl_key *key = NULL;
339
340 if (sme->key_idx < WMI_MIN_KEY_INDEX ||
341 sme->key_idx > WMI_MAX_KEY_INDEX) {
342 ath6kl_err("key index %d out of bounds\n",
343 sme->key_idx);
344 up(&ar->sem);
345 return -ENOENT;
346 }
347
348 key = &ar->keys[sme->key_idx];
349 key->key_len = sme->key_len;
350 memcpy(key->key, sme->key, key->key_len);
351 key->cipher = ar->prwise_crypto;
352 ar->def_txkey_index = sme->key_idx;
353
354 ath6kl_wmi_addkey_cmd(ar->wmi, sme->key_idx,
355 ar->prwise_crypto,
356 GROUP_USAGE | TX_USAGE,
357 key->key_len,
358 NULL,
359 key->key, KEY_OP_INIT_VAL, NULL,
360 NO_SYNC_WMIFLAG);
361 }
362
363 if (!ar->usr_bss_filter) {
364 if (ath6kl_wmi_bssfilter_cmd(ar->wmi, ALL_BSS_FILTER, 0) != 0) {
365 ath6kl_err("couldn't set bss filtering\n");
366 up(&ar->sem);
367 return -EIO;
368 }
369 }
370
371 ar->nw_type = ar->next_mode;
372
373 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
374 "%s: connect called with authmode %d dot11 auth %d"
375 " PW crypto %d PW crypto len %d GRP crypto %d"
376 " GRP crypto len %d channel hint %u\n",
377 __func__,
378 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
379 ar->prwise_crypto_len, ar->grp_crypto,
38acde3c 380 ar->grp_crypto_len, ar->ch_hint);
bdcd8170
KV
381
382 ar->reconnect_flag = 0;
383 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
384 ar->dot11_auth_mode, ar->auth_mode,
385 ar->prwise_crypto,
386 ar->prwise_crypto_len,
38acde3c 387 ar->grp_crypto, ar->grp_crypto_len,
bdcd8170
KV
388 ar->ssid_len, ar->ssid,
389 ar->req_bssid, ar->ch_hint,
390 ar->connect_ctrl_flags);
391
392 up(&ar->sem);
393
394 if (status == -EINVAL) {
395 memset(ar->ssid, 0, sizeof(ar->ssid));
396 ar->ssid_len = 0;
397 ath6kl_err("invalid request\n");
398 return -ENOENT;
399 } else if (status) {
400 ath6kl_err("ath6kl_wmi_connect_cmd failed\n");
401 return -EIO;
402 }
403
404 if ((!(ar->connect_ctrl_flags & CONNECT_DO_WPA_OFFLOAD)) &&
405 ((ar->auth_mode == WPA_PSK_AUTH)
406 || (ar->auth_mode == WPA2_PSK_AUTH))) {
407 mod_timer(&ar->disconnect_timer,
408 jiffies + msecs_to_jiffies(DISCON_TIMER_INTVAL));
409 }
410
411 ar->connect_ctrl_flags &= ~CONNECT_DO_WPA_OFFLOAD;
412 set_bit(CONNECT_PEND, &ar->flag);
413
414 return 0;
415}
416
417void ath6kl_cfg80211_connect_event(struct ath6kl *ar, u16 channel,
418 u8 *bssid, u16 listen_intvl,
419 u16 beacon_intvl,
420 enum network_type nw_type,
421 u8 beacon_ie_len, u8 assoc_req_len,
422 u8 assoc_resp_len, u8 *assoc_info)
423{
424 u16 size = 0;
425 u16 capability = 0;
426 struct cfg80211_bss *bss = NULL;
427 struct ieee80211_mgmt *mgmt = NULL;
428 struct ieee80211_channel *ibss_ch = NULL;
429 s32 signal = 50 * 100;
430 u8 ie_buf_len = 0;
431 unsigned char ie_buf[256];
432 unsigned char *ptr_ie_buf = ie_buf;
433 unsigned char *ieeemgmtbuf = NULL;
434 u8 source_mac[ETH_ALEN];
bdcd8170
KV
435
436 /* capinfo + listen interval */
437 u8 assoc_req_ie_offset = sizeof(u16) + sizeof(u16);
438
439 /* capinfo + status code + associd */
440 u8 assoc_resp_ie_offset = sizeof(u16) + sizeof(u16) + sizeof(u16);
441
442 u8 *assoc_req_ie = assoc_info + beacon_ie_len + assoc_req_ie_offset;
443 u8 *assoc_resp_ie = assoc_info + beacon_ie_len + assoc_req_len +
444 assoc_resp_ie_offset;
445
446 assoc_req_len -= assoc_req_ie_offset;
447 assoc_resp_len -= assoc_resp_ie_offset;
448
449 ar->auto_auth_stage = AUTH_IDLE;
450
451 if (nw_type & ADHOC_NETWORK) {
452 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
453 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
454 "%s: ath6k not in ibss mode\n", __func__);
455 return;
456 }
457 }
458
459 if (nw_type & INFRA_NETWORK) {
6b5e5d25
JM
460 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
461 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
462 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
463 "%s: ath6k not in station mode\n", __func__);
464 return;
465 }
466 }
467
bdcd8170
KV
468 /*
469 * Earlier we were updating the cfg about bss by making a beacon frame
470 * only if the entry for bss is not there. This can have some issue if
471 * ROAM event is generated and a heavy traffic is ongoing. The ROAM
472 * event is handled through a work queue and by the time it really gets
473 * handled, BSS would have been aged out. So it is better to update the
474 * cfg about BSS irrespective of its entry being present right now or
475 * not.
476 */
477
478 if (nw_type & ADHOC_NETWORK) {
479 /* construct 802.11 mgmt beacon */
480 if (ptr_ie_buf) {
481 *ptr_ie_buf++ = WLAN_EID_SSID;
482 *ptr_ie_buf++ = ar->ssid_len;
483 memcpy(ptr_ie_buf, ar->ssid, ar->ssid_len);
484 ptr_ie_buf += ar->ssid_len;
485
486 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
487 *ptr_ie_buf++ = 2; /* length */
488 *ptr_ie_buf++ = 0; /* ATIM window */
489 *ptr_ie_buf++ = 0; /* ATIM window */
490
491 /* TODO: update ibss params and include supported rates,
492 * DS param set, extened support rates, wmm. */
493
494 ie_buf_len = ptr_ie_buf - ie_buf;
495 }
496
497 capability |= WLAN_CAPABILITY_IBSS;
498
499 if (ar->prwise_crypto == WEP_CRYPT)
500 capability |= WLAN_CAPABILITY_PRIVACY;
501
502 memcpy(source_mac, ar->net_dev->dev_addr, ETH_ALEN);
503 ptr_ie_buf = ie_buf;
504 } else {
505 capability = *(u16 *) (&assoc_info[beacon_ie_len]);
506 memcpy(source_mac, bssid, ETH_ALEN);
507 ptr_ie_buf = assoc_req_ie;
508 ie_buf_len = assoc_req_len;
509 }
510
511 size = offsetof(struct ieee80211_mgmt, u)
512 + sizeof(mgmt->u.beacon)
513 + ie_buf_len;
514
515 ieeemgmtbuf = kzalloc(size, GFP_ATOMIC);
516 if (!ieeemgmtbuf) {
517 ath6kl_err("ieee mgmt buf alloc error\n");
bdcd8170
KV
518 return;
519 }
520
521 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
522 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
523 IEEE80211_STYPE_BEACON);
524 memset(mgmt->da, 0xff, ETH_ALEN); /* broadcast addr */
525 memcpy(mgmt->sa, source_mac, ETH_ALEN);
526 memcpy(mgmt->bssid, bssid, ETH_ALEN);
527 mgmt->u.beacon.beacon_int = cpu_to_le16(beacon_intvl);
528 mgmt->u.beacon.capab_info = cpu_to_le16(capability);
529 memcpy(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
530
531 ibss_ch = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
532
533 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
534 "%s: inform bss with bssid %pM channel %d beacon_intvl %d capability 0x%x\n",
535 __func__, mgmt->bssid, ibss_ch->hw_value,
536 beacon_intvl, capability);
537
538 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
539 ibss_ch, mgmt,
540 size, signal, GFP_KERNEL);
541 kfree(ieeemgmtbuf);
542 cfg80211_put_bss(bss);
543
544 if (nw_type & ADHOC_NETWORK) {
545 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
546 return;
547 }
548
9aa60357 549 if (ar->sme_state == SME_CONNECTING) {
bdcd8170 550 /* inform connect result to cfg80211 */
9aa60357 551 ar->sme_state = SME_CONNECTED;
bdcd8170
KV
552 cfg80211_connect_result(ar->net_dev, bssid,
553 assoc_req_ie, assoc_req_len,
554 assoc_resp_ie, assoc_resp_len,
555 WLAN_STATUS_SUCCESS, GFP_KERNEL);
9aa60357 556 } else if (ar->sme_state == SME_CONNECTED) {
bdcd8170
KV
557 /* inform roam event to cfg80211 */
558 cfg80211_roamed(ar->net_dev, ibss_ch, bssid,
559 assoc_req_ie, assoc_req_len,
560 assoc_resp_ie, assoc_resp_len, GFP_KERNEL);
561 }
562}
563
564static int ath6kl_cfg80211_disconnect(struct wiphy *wiphy,
565 struct net_device *dev, u16 reason_code)
566{
567 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
568
569 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: reason=%u\n", __func__,
570 reason_code);
571
572 if (!ath6kl_cfg80211_ready(ar))
573 return -EIO;
574
575 if (test_bit(DESTROY_IN_PROGRESS, &ar->flag)) {
576 ath6kl_err("busy, destroy in progress\n");
577 return -EBUSY;
578 }
579
580 if (down_interruptible(&ar->sem)) {
581 ath6kl_err("busy, couldn't get access\n");
582 return -ERESTARTSYS;
583 }
584
585 ar->reconnect_flag = 0;
586 ath6kl_disconnect(ar);
587 memset(ar->ssid, 0, sizeof(ar->ssid));
588 ar->ssid_len = 0;
589
590 if (!test_bit(SKIP_SCAN, &ar->flag))
591 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
592
593 up(&ar->sem);
594
595 return 0;
596}
597
598void ath6kl_cfg80211_disconnect_event(struct ath6kl *ar, u8 reason,
599 u8 *bssid, u8 assoc_resp_len,
600 u8 *assoc_info, u16 proto_reason)
601{
602 struct ath6kl_key *key = NULL;
603 u16 status;
604
605 if (ar->scan_req) {
606 cfg80211_scan_done(ar->scan_req, true);
607 ar->scan_req = NULL;
608 }
609
610 if (ar->nw_type & ADHOC_NETWORK) {
611 if (ar->wdev->iftype != NL80211_IFTYPE_ADHOC) {
612 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
613 "%s: ath6k not in ibss mode\n", __func__);
614 return;
615 }
616 memset(bssid, 0, ETH_ALEN);
617 cfg80211_ibss_joined(ar->net_dev, bssid, GFP_KERNEL);
618 return;
619 }
620
621 if (ar->nw_type & INFRA_NETWORK) {
6b5e5d25
JM
622 if (ar->wdev->iftype != NL80211_IFTYPE_STATION &&
623 ar->wdev->iftype != NL80211_IFTYPE_P2P_CLIENT) {
bdcd8170
KV
624 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
625 "%s: ath6k not in station mode\n", __func__);
626 return;
627 }
628 }
629
630 if (!test_bit(CONNECT_PEND, &ar->flag)) {
631 if (reason != DISCONNECT_CMD)
632 ath6kl_wmi_disconnect_cmd(ar->wmi);
633
634 return;
635 }
636
637 if (reason == NO_NETWORK_AVAIL) {
638 /* connect cmd failed */
639 ath6kl_wmi_disconnect_cmd(ar->wmi);
640 return;
641 }
642
643 if (reason != DISCONNECT_CMD)
644 return;
645
646 if (!ar->auto_auth_stage) {
647 clear_bit(CONNECT_PEND, &ar->flag);
648
649 if (ar->sme_state == SME_CONNECTING) {
650 cfg80211_connect_result(ar->net_dev,
651 bssid, NULL, 0,
652 NULL, 0,
653 WLAN_STATUS_UNSPECIFIED_FAILURE,
654 GFP_KERNEL);
0e5cc8e6 655 } else if (ar->sme_state == SME_CONNECTED) {
bdcd8170
KV
656 cfg80211_disconnected(ar->net_dev, reason,
657 NULL, 0, GFP_KERNEL);
658 }
659
660 ar->sme_state = SME_DISCONNECTED;
661 return;
662 }
663
664 if (ar->dot11_auth_mode != OPEN_AUTH)
665 return;
666
667 /*
668 * If the current auth algorithm is open, try shared and
669 * make autoAuthStage idle. We do not make it leap for now
670 * being.
671 */
672 key = &ar->keys[ar->def_txkey_index];
673 if (down_interruptible(&ar->sem)) {
674 ath6kl_err("busy, couldn't get access\n");
675 return;
676 }
677
678 ar->dot11_auth_mode = SHARED_AUTH;
679 ar->auto_auth_stage = AUTH_IDLE;
680
681 ath6kl_wmi_addkey_cmd(ar->wmi,
682 ar->def_txkey_index,
683 ar->prwise_crypto,
684 GROUP_USAGE | TX_USAGE,
685 key->key_len, NULL,
686 key->key,
687 KEY_OP_INIT_VAL, NULL,
688 NO_SYNC_WMIFLAG);
689
690 status = ath6kl_wmi_connect_cmd(ar->wmi,
691 ar->nw_type,
692 ar->dot11_auth_mode,
693 ar->auth_mode,
694 ar->prwise_crypto,
695 ar->prwise_crypto_len,
696 ar->grp_crypto,
38acde3c 697 ar->grp_crypto_len,
bdcd8170
KV
698 ar->ssid_len,
699 ar->ssid,
700 ar->req_bssid,
701 ar->ch_hint,
702 ar->connect_ctrl_flags);
703 up(&ar->sem);
704}
705
706static inline bool is_ch_11a(u16 ch)
707{
708 return (!((ch >= 2412) && (ch <= 2484)));
709}
710
cf104c2a 711/* struct ath6kl_node_table::nt_nodelock is locked when calling this */
91db35da 712void ath6kl_cfg80211_scan_node(struct wiphy *wiphy, struct bss *ni)
bdcd8170 713{
bdcd8170
KV
714 struct ieee80211_mgmt *mgmt;
715 struct ieee80211_channel *channel;
716 struct ieee80211_supported_band *band;
717 struct ath6kl_common_ie *cie;
718 s32 signal;
719 int freq;
720
721 cie = &ni->ni_cie;
722
723 if (is_ch_11a(cie->ie_chan))
724 band = wiphy->bands[IEEE80211_BAND_5GHZ]; /* 11a */
725 else if ((cie->ie_erp) || (cie->ie_xrates))
726 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11g */
727 else
728 band = wiphy->bands[IEEE80211_BAND_2GHZ]; /* 11b */
729
bdcd8170
KV
730 freq = cie->ie_chan;
731 channel = ieee80211_get_channel(wiphy, freq);
732 signal = ni->ni_snr * 100;
733
734 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
735 "%s: bssid %pM ch %d freq %d size %d\n", __func__,
0ce77920
JM
736 ni->ni_macaddr, channel->hw_value, freq, ni->ni_framelen);
737 /*
738 * Both Beacon and Probe Response frames have same payload structure,
739 * so it is fine to share the parser for both.
740 */
741 if (ni->ni_framelen < 8 + 2 + 2)
742 return;
743 mgmt = (struct ieee80211_mgmt *) (ni->ni_buf -
744 offsetof(struct ieee80211_mgmt, u));
745 cfg80211_inform_bss(wiphy, channel, ni->ni_macaddr,
746 le64_to_cpu(mgmt->u.beacon.timestamp),
747 le16_to_cpu(mgmt->u.beacon.capab_info),
748 le16_to_cpu(mgmt->u.beacon.beacon_int),
749 mgmt->u.beacon.variable,
750 ni->ni_buf + ni->ni_framelen -
751 mgmt->u.beacon.variable,
752 signal, GFP_ATOMIC);
bdcd8170
KV
753}
754
755static int ath6kl_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
756 struct cfg80211_scan_request *request)
757{
758 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1276c9ef
EL
759 s8 n_channels = 0;
760 u16 *channels = NULL;
bdcd8170 761 int ret = 0;
bdcd8170
KV
762
763 if (!ath6kl_cfg80211_ready(ar))
764 return -EIO;
765
766 if (!ar->usr_bss_filter) {
1b1e6ee3
JM
767 ret = ath6kl_wmi_bssfilter_cmd(
768 ar->wmi,
769 (test_bit(CONNECTED, &ar->flag) ?
770 ALL_BUT_BSS_FILTER : ALL_BSS_FILTER), 0);
771 if (ret) {
bdcd8170 772 ath6kl_err("couldn't set bss filtering\n");
1b1e6ee3 773 return ret;
bdcd8170
KV
774 }
775 }
776
777 if (request->n_ssids && request->ssids[0].ssid_len) {
778 u8 i;
779
780 if (request->n_ssids > (MAX_PROBED_SSID_INDEX - 1))
781 request->n_ssids = MAX_PROBED_SSID_INDEX - 1;
782
783 for (i = 0; i < request->n_ssids; i++)
784 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
785 SPECIFIC_SSID_FLAG,
786 request->ssids[i].ssid_len,
787 request->ssids[i].ssid);
788 }
789
b84da8c7
JM
790 if (request->ie) {
791 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_REQ,
792 request->ie, request->ie_len);
793 if (ret) {
794 ath6kl_err("failed to set Probe Request appie for "
795 "scan");
796 return ret;
797 }
798 }
799
11869bef
JM
800 /*
801 * Scan only the requested channels if the request specifies a set of
802 * channels. If the list is longer than the target supports, do not
803 * configure the list and instead, scan all available channels.
804 */
805 if (request->n_channels > 0 &&
806 request->n_channels <= WMI_MAX_CHANNELS) {
1276c9ef
EL
807 u8 i;
808
11869bef 809 n_channels = request->n_channels;
1276c9ef
EL
810
811 channels = kzalloc(n_channels * sizeof(u16), GFP_KERNEL);
812 if (channels == NULL) {
813 ath6kl_warn("failed to set scan channels, "
814 "scan all channels");
815 n_channels = 0;
816 }
817
818 for (i = 0; i < n_channels; i++)
819 channels[i] = request->channels[i]->center_freq;
820 }
821
1b1e6ee3
JM
822 ret = ath6kl_wmi_startscan_cmd(ar->wmi, WMI_LONG_SCAN, 0,
823 false, 0, 0, n_channels, channels);
824 if (ret)
bdcd8170 825 ath6kl_err("wmi_startscan_cmd failed\n");
11869bef
JM
826 else
827 ar->scan_req = request;
bdcd8170 828
1276c9ef
EL
829 kfree(channels);
830
bdcd8170
KV
831 return ret;
832}
833
834void ath6kl_cfg80211_scan_complete_event(struct ath6kl *ar, int status)
835{
6fd1eace 836 int i;
bdcd8170
KV
837
838 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: status %d\n", __func__, status);
839
6fd1eace
KV
840 if (!ar->scan_req)
841 return;
842
843 if ((status == -ECANCELED) || (status == -EBUSY)) {
844 cfg80211_scan_done(ar->scan_req, true);
845 goto out;
846 }
847
848 /* Translate data to cfg80211 mgmt format */
8a8bc5a4 849 wlan_iterate_nodes(&ar->scan_table, ar->wdev->wiphy);
6fd1eace
KV
850
851 cfg80211_scan_done(ar->scan_req, false);
852
853 if (ar->scan_req->n_ssids && ar->scan_req->ssids[0].ssid_len) {
854 for (i = 0; i < ar->scan_req->n_ssids; i++) {
855 ath6kl_wmi_probedssid_cmd(ar->wmi, i + 1,
856 DISABLE_SSID_FLAG,
857 0, NULL);
bdcd8170 858 }
bdcd8170 859 }
6fd1eace
KV
860
861out:
862 ar->scan_req = NULL;
bdcd8170
KV
863}
864
865static int ath6kl_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
866 u8 key_index, bool pairwise,
867 const u8 *mac_addr,
868 struct key_params *params)
869{
870 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
871 struct ath6kl_key *key = NULL;
872 u8 key_usage;
873 u8 key_type;
874 int status = 0;
875
876 if (!ath6kl_cfg80211_ready(ar))
877 return -EIO;
878
879 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
880 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
881 "%s: key index %d out of bounds\n", __func__,
882 key_index);
883 return -ENOENT;
884 }
885
886 key = &ar->keys[key_index];
887 memset(key, 0, sizeof(struct ath6kl_key));
888
889 if (pairwise)
890 key_usage = PAIRWISE_USAGE;
891 else
892 key_usage = GROUP_USAGE;
893
894 if (params) {
895 if (params->key_len > WLAN_MAX_KEY_LEN ||
896 params->seq_len > sizeof(key->seq))
897 return -EINVAL;
898
899 key->key_len = params->key_len;
900 memcpy(key->key, params->key, key->key_len);
901 key->seq_len = params->seq_len;
902 memcpy(key->seq, params->seq, key->seq_len);
903 key->cipher = params->cipher;
904 }
905
906 switch (key->cipher) {
907 case WLAN_CIPHER_SUITE_WEP40:
908 case WLAN_CIPHER_SUITE_WEP104:
909 key_type = WEP_CRYPT;
910 break;
911
912 case WLAN_CIPHER_SUITE_TKIP:
913 key_type = TKIP_CRYPT;
914 break;
915
916 case WLAN_CIPHER_SUITE_CCMP:
917 key_type = AES_CRYPT;
918 break;
919
920 default:
921 return -ENOTSUPP;
922 }
923
924 if (((ar->auth_mode == WPA_PSK_AUTH)
925 || (ar->auth_mode == WPA2_PSK_AUTH))
926 && (key_usage & GROUP_USAGE))
927 del_timer(&ar->disconnect_timer);
928
929 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
930 "%s: index %d, key_len %d, key_type 0x%x, key_usage 0x%x, seq_len %d\n",
931 __func__, key_index, key->key_len, key_type,
932 key_usage, key->seq_len);
933
934 ar->def_txkey_index = key_index;
9a5b1318
JM
935
936 if (ar->nw_type == AP_NETWORK && !pairwise &&
937 (key_type == TKIP_CRYPT || key_type == AES_CRYPT) && params) {
938 ar->ap_mode_bkey.valid = true;
939 ar->ap_mode_bkey.key_index = key_index;
940 ar->ap_mode_bkey.key_type = key_type;
941 ar->ap_mode_bkey.key_len = key->key_len;
942 memcpy(ar->ap_mode_bkey.key, key->key, key->key_len);
943 if (!test_bit(CONNECTED, &ar->flag)) {
944 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "Delay initial group "
945 "key configuration until AP mode has been "
946 "started\n");
947 /*
948 * The key will be set in ath6kl_connect_ap_mode() once
949 * the connected event is received from the target.
950 */
951 return 0;
952 }
953 }
954
bdcd8170
KV
955 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
956 key_type, key_usage, key->key_len,
957 key->seq, key->key, KEY_OP_INIT_VAL,
958 (u8 *) mac_addr, SYNC_BOTH_WMIFLAG);
959
960 if (status)
961 return -EIO;
962
963 return 0;
964}
965
966static int ath6kl_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
967 u8 key_index, bool pairwise,
968 const u8 *mac_addr)
969{
970 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
971
972 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
973
974 if (!ath6kl_cfg80211_ready(ar))
975 return -EIO;
976
977 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
978 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
979 "%s: key index %d out of bounds\n", __func__,
980 key_index);
981 return -ENOENT;
982 }
983
984 if (!ar->keys[key_index].key_len) {
985 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
986 "%s: index %d is empty\n", __func__, key_index);
987 return 0;
988 }
989
990 ar->keys[key_index].key_len = 0;
991
992 return ath6kl_wmi_deletekey_cmd(ar->wmi, key_index);
993}
994
995static int ath6kl_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
996 u8 key_index, bool pairwise,
997 const u8 *mac_addr, void *cookie,
998 void (*callback) (void *cookie,
999 struct key_params *))
1000{
1001 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1002 struct ath6kl_key *key = NULL;
1003 struct key_params params;
1004
1005 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1006
1007 if (!ath6kl_cfg80211_ready(ar))
1008 return -EIO;
1009
1010 if (key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1011 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1012 "%s: key index %d out of bounds\n", __func__,
1013 key_index);
1014 return -ENOENT;
1015 }
1016
1017 key = &ar->keys[key_index];
1018 memset(&params, 0, sizeof(params));
1019 params.cipher = key->cipher;
1020 params.key_len = key->key_len;
1021 params.seq_len = key->seq_len;
1022 params.seq = key->seq;
1023 params.key = key->key;
1024
1025 callback(cookie, &params);
1026
1027 return key->key_len ? 0 : -ENOENT;
1028}
1029
1030static int ath6kl_cfg80211_set_default_key(struct wiphy *wiphy,
1031 struct net_device *ndev,
1032 u8 key_index, bool unicast,
1033 bool multicast)
1034{
1035 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(ndev);
1036 struct ath6kl_key *key = NULL;
1037 int status = 0;
1038 u8 key_usage;
229ed6b5 1039 enum crypto_type key_type = NONE_CRYPT;
bdcd8170
KV
1040
1041 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: index %d\n", __func__, key_index);
1042
1043 if (!ath6kl_cfg80211_ready(ar))
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",
1049 __func__, key_index);
1050 return -ENOENT;
1051 }
1052
1053 if (!ar->keys[key_index].key_len) {
1054 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: invalid key index %d\n",
1055 __func__, key_index);
1056 return -EINVAL;
1057 }
1058
1059 ar->def_txkey_index = key_index;
1060 key = &ar->keys[ar->def_txkey_index];
1061 key_usage = GROUP_USAGE;
1062 if (ar->prwise_crypto == WEP_CRYPT)
1063 key_usage |= TX_USAGE;
229ed6b5
EL
1064 if (unicast)
1065 key_type = ar->prwise_crypto;
1066 if (multicast)
1067 key_type = ar->grp_crypto;
bdcd8170 1068
9a5b1318
JM
1069 if (ar->nw_type == AP_NETWORK && !test_bit(CONNECTED, &ar->flag))
1070 return 0; /* Delay until AP mode has been started */
1071
bdcd8170 1072 status = ath6kl_wmi_addkey_cmd(ar->wmi, ar->def_txkey_index,
229ed6b5 1073 key_type, key_usage,
bdcd8170
KV
1074 key->key_len, key->seq, key->key,
1075 KEY_OP_INIT_VAL, NULL,
1076 SYNC_BOTH_WMIFLAG);
1077 if (status)
1078 return -EIO;
1079
1080 return 0;
1081}
1082
1083void ath6kl_cfg80211_tkip_micerr_event(struct ath6kl *ar, u8 keyid,
1084 bool ismcast)
1085{
1086 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1087 "%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast);
1088
1089 cfg80211_michael_mic_failure(ar->net_dev, ar->bssid,
1090 (ismcast ? NL80211_KEYTYPE_GROUP :
1091 NL80211_KEYTYPE_PAIRWISE), keyid, NULL,
1092 GFP_KERNEL);
1093}
1094
1095static int ath6kl_cfg80211_set_wiphy_params(struct wiphy *wiphy, u32 changed)
1096{
1097 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1098 int ret;
1099
1100 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: changed 0x%x\n", __func__,
1101 changed);
1102
1103 if (!ath6kl_cfg80211_ready(ar))
1104 return -EIO;
1105
1106 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1107 ret = ath6kl_wmi_set_rts_cmd(ar->wmi, wiphy->rts_threshold);
1108 if (ret != 0) {
1109 ath6kl_err("ath6kl_wmi_set_rts_cmd failed\n");
1110 return -EIO;
1111 }
1112 }
1113
1114 return 0;
1115}
1116
1117/*
1118 * The type nl80211_tx_power_setting replaces the following
1119 * data type from 2.6.36 onwards
1120*/
1121static int ath6kl_cfg80211_set_txpower(struct wiphy *wiphy,
1122 enum nl80211_tx_power_setting type,
1123 int dbm)
1124{
1125 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1126 u8 ath6kl_dbm;
1127
1128 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x, dbm %d\n", __func__,
1129 type, dbm);
1130
1131 if (!ath6kl_cfg80211_ready(ar))
1132 return -EIO;
1133
1134 switch (type) {
1135 case NL80211_TX_POWER_AUTOMATIC:
1136 return 0;
1137 case NL80211_TX_POWER_LIMITED:
1138 ar->tx_pwr = ath6kl_dbm = dbm;
1139 break;
1140 default:
1141 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type 0x%x not supported\n",
1142 __func__, type);
1143 return -EOPNOTSUPP;
1144 }
1145
1146 ath6kl_wmi_set_tx_pwr_cmd(ar->wmi, ath6kl_dbm);
1147
1148 return 0;
1149}
1150
1151static int ath6kl_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1152{
1153 struct ath6kl *ar = (struct ath6kl *)wiphy_priv(wiphy);
1154
1155 if (!ath6kl_cfg80211_ready(ar))
1156 return -EIO;
1157
1158 if (test_bit(CONNECTED, &ar->flag)) {
1159 ar->tx_pwr = 0;
1160
1161 if (ath6kl_wmi_get_tx_pwr_cmd(ar->wmi) != 0) {
1162 ath6kl_err("ath6kl_wmi_get_tx_pwr_cmd failed\n");
1163 return -EIO;
1164 }
1165
1166 wait_event_interruptible_timeout(ar->event_wq, ar->tx_pwr != 0,
1167 5 * HZ);
1168
1169 if (signal_pending(current)) {
1170 ath6kl_err("target did not respond\n");
1171 return -EINTR;
1172 }
1173 }
1174
1175 *dbm = ar->tx_pwr;
1176 return 0;
1177}
1178
1179static int ath6kl_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1180 struct net_device *dev,
1181 bool pmgmt, int timeout)
1182{
1183 struct ath6kl *ar = ath6kl_priv(dev);
1184 struct wmi_power_mode_cmd mode;
1185
1186 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: pmgmt %d, timeout %d\n",
1187 __func__, pmgmt, timeout);
1188
1189 if (!ath6kl_cfg80211_ready(ar))
1190 return -EIO;
1191
1192 if (pmgmt) {
1193 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: max perf\n", __func__);
1194 mode.pwr_mode = REC_POWER;
1195 } else {
1196 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: rec power\n", __func__);
1197 mode.pwr_mode = MAX_PERF_POWER;
1198 }
1199
1200 if (ath6kl_wmi_powermode_cmd(ar->wmi, mode.pwr_mode) != 0) {
1201 ath6kl_err("wmi_powermode_cmd failed\n");
1202 return -EIO;
1203 }
1204
1205 return 0;
1206}
1207
1208static int ath6kl_cfg80211_change_iface(struct wiphy *wiphy,
1209 struct net_device *ndev,
1210 enum nl80211_iftype type, u32 *flags,
1211 struct vif_params *params)
1212{
1213 struct ath6kl *ar = ath6kl_priv(ndev);
1214 struct wireless_dev *wdev = ar->wdev;
1215
1216 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: type %u\n", __func__, type);
1217
1218 if (!ath6kl_cfg80211_ready(ar))
1219 return -EIO;
1220
1221 switch (type) {
1222 case NL80211_IFTYPE_STATION:
1223 ar->next_mode = INFRA_NETWORK;
1224 break;
1225 case NL80211_IFTYPE_ADHOC:
1226 ar->next_mode = ADHOC_NETWORK;
1227 break;
6e4604c8
JM
1228 case NL80211_IFTYPE_AP:
1229 ar->next_mode = AP_NETWORK;
1230 break;
6b5e5d25
JM
1231 case NL80211_IFTYPE_P2P_CLIENT:
1232 ar->next_mode = INFRA_NETWORK;
1233 break;
1234 case NL80211_IFTYPE_P2P_GO:
1235 ar->next_mode = AP_NETWORK;
1236 break;
bdcd8170
KV
1237 default:
1238 ath6kl_err("invalid interface type %u\n", type);
1239 return -EOPNOTSUPP;
1240 }
1241
1242 wdev->iftype = type;
1243
1244 return 0;
1245}
1246
1247static int ath6kl_cfg80211_join_ibss(struct wiphy *wiphy,
1248 struct net_device *dev,
1249 struct cfg80211_ibss_params *ibss_param)
1250{
1251 struct ath6kl *ar = ath6kl_priv(dev);
1252 int status;
1253
1254 if (!ath6kl_cfg80211_ready(ar))
1255 return -EIO;
1256
1257 ar->ssid_len = ibss_param->ssid_len;
1258 memcpy(ar->ssid, ibss_param->ssid, ar->ssid_len);
1259
1260 if (ibss_param->channel)
1261 ar->ch_hint = ibss_param->channel->center_freq;
1262
1263 if (ibss_param->channel_fixed) {
1264 /*
1265 * TODO: channel_fixed: The channel should be fixed, do not
1266 * search for IBSSs to join on other channels. Target
1267 * firmware does not support this feature, needs to be
1268 * updated.
1269 */
1270 return -EOPNOTSUPP;
1271 }
1272
1273 memset(ar->req_bssid, 0, sizeof(ar->req_bssid));
1274 if (ibss_param->bssid && !is_broadcast_ether_addr(ibss_param->bssid))
1275 memcpy(ar->req_bssid, ibss_param->bssid, sizeof(ar->req_bssid));
1276
1277 ath6kl_set_wpa_version(ar, 0);
1278
1279 status = ath6kl_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1280 if (status)
1281 return status;
1282
1283 if (ibss_param->privacy) {
1284 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1285 ath6kl_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1286 } else {
1287 ath6kl_set_cipher(ar, 0, true);
1288 ath6kl_set_cipher(ar, 0, false);
1289 }
1290
1291 ar->nw_type = ar->next_mode;
1292
1293 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG,
1294 "%s: connect called with authmode %d dot11 auth %d"
1295 " PW crypto %d PW crypto len %d GRP crypto %d"
1296 " GRP crypto len %d channel hint %u\n",
1297 __func__,
1298 ar->auth_mode, ar->dot11_auth_mode, ar->prwise_crypto,
1299 ar->prwise_crypto_len, ar->grp_crypto,
38acde3c 1300 ar->grp_crypto_len, ar->ch_hint);
bdcd8170
KV
1301
1302 status = ath6kl_wmi_connect_cmd(ar->wmi, ar->nw_type,
1303 ar->dot11_auth_mode, ar->auth_mode,
1304 ar->prwise_crypto,
1305 ar->prwise_crypto_len,
38acde3c 1306 ar->grp_crypto, ar->grp_crypto_len,
bdcd8170
KV
1307 ar->ssid_len, ar->ssid,
1308 ar->req_bssid, ar->ch_hint,
1309 ar->connect_ctrl_flags);
1310 set_bit(CONNECT_PEND, &ar->flag);
1311
1312 return 0;
1313}
1314
1315static int ath6kl_cfg80211_leave_ibss(struct wiphy *wiphy,
1316 struct net_device *dev)
1317{
1318 struct ath6kl *ar = (struct ath6kl *)ath6kl_priv(dev);
1319
1320 if (!ath6kl_cfg80211_ready(ar))
1321 return -EIO;
1322
1323 ath6kl_disconnect(ar);
1324 memset(ar->ssid, 0, sizeof(ar->ssid));
1325 ar->ssid_len = 0;
1326
1327 return 0;
1328}
1329
1330static const u32 cipher_suites[] = {
1331 WLAN_CIPHER_SUITE_WEP40,
1332 WLAN_CIPHER_SUITE_WEP104,
1333 WLAN_CIPHER_SUITE_TKIP,
1334 WLAN_CIPHER_SUITE_CCMP,
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);
1402 long left;
1403 bool sgi;
1404 s32 rate;
1405 int ret;
1406 u8 mcs;
1407
1408 if (memcmp(mac, ar->bssid, ETH_ALEN) != 0)
1409 return -ENOENT;
1410
1411 if (down_interruptible(&ar->sem))
1412 return -EBUSY;
1413
1414 set_bit(STATS_UPDATE_PEND, &ar->flag);
1415
1416 ret = ath6kl_wmi_get_stats_cmd(ar->wmi);
1417
1418 if (ret != 0) {
1419 up(&ar->sem);
1420 return -EIO;
1421 }
1422
1423 left = wait_event_interruptible_timeout(ar->event_wq,
1424 !test_bit(STATS_UPDATE_PEND,
1425 &ar->flag),
1426 WMI_TIMEOUT);
1427
1428 up(&ar->sem);
1429
1430 if (left == 0)
1431 return -ETIMEDOUT;
1432 else if (left < 0)
1433 return left;
1434
1435 if (ar->target_stats.rx_byte) {
1436 sinfo->rx_bytes = ar->target_stats.rx_byte;
1437 sinfo->filled |= STATION_INFO_RX_BYTES;
1438 sinfo->rx_packets = ar->target_stats.rx_pkt;
1439 sinfo->filled |= STATION_INFO_RX_PACKETS;
1440 }
1441
1442 if (ar->target_stats.tx_byte) {
1443 sinfo->tx_bytes = ar->target_stats.tx_byte;
1444 sinfo->filled |= STATION_INFO_TX_BYTES;
1445 sinfo->tx_packets = ar->target_stats.tx_pkt;
1446 sinfo->filled |= STATION_INFO_TX_PACKETS;
1447 }
1448
1449 sinfo->signal = ar->target_stats.cs_rssi;
1450 sinfo->filled |= STATION_INFO_SIGNAL;
1451
1452 rate = ar->target_stats.tx_ucast_rate;
1453
1454 if (is_rate_legacy(rate)) {
1455 sinfo->txrate.legacy = rate / 100;
1456 } else if (is_rate_ht20(rate, &mcs, &sgi)) {
1457 if (sgi) {
1458 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1459 sinfo->txrate.mcs = mcs - 1;
1460 } else {
1461 sinfo->txrate.mcs = mcs;
1462 }
1463
1464 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1465 } else if (is_rate_ht40(rate, &mcs, &sgi)) {
1466 if (sgi) {
1467 sinfo->txrate.flags |= RATE_INFO_FLAGS_SHORT_GI;
1468 sinfo->txrate.mcs = mcs - 1;
1469 } else {
1470 sinfo->txrate.mcs = mcs;
1471 }
1472
1473 sinfo->txrate.flags |= RATE_INFO_FLAGS_40_MHZ_WIDTH;
1474 sinfo->txrate.flags |= RATE_INFO_FLAGS_MCS;
1475 } else {
1476 ath6kl_warn("invalid rate: %d\n", rate);
1477 return 0;
1478 }
1479
1480 sinfo->filled |= STATION_INFO_TX_BITRATE;
1481
1482 return 0;
1483}
1484
1485static int ath6kl_set_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1486 struct cfg80211_pmksa *pmksa)
1487{
1488 struct ath6kl *ar = ath6kl_priv(netdev);
1489 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1490 pmksa->pmkid, true);
1491}
1492
1493static int ath6kl_del_pmksa(struct wiphy *wiphy, struct net_device *netdev,
1494 struct cfg80211_pmksa *pmksa)
1495{
1496 struct ath6kl *ar = ath6kl_priv(netdev);
1497 return ath6kl_wmi_setpmkid_cmd(ar->wmi, pmksa->bssid,
1498 pmksa->pmkid, false);
1499}
1500
1501static int ath6kl_flush_pmksa(struct wiphy *wiphy, struct net_device *netdev)
1502{
1503 struct ath6kl *ar = ath6kl_priv(netdev);
1504 if (test_bit(CONNECTED, &ar->flag))
1505 return ath6kl_wmi_setpmkid_cmd(ar->wmi, ar->bssid, NULL, false);
1506 return 0;
1507}
1508
abcb344b
KV
1509#ifdef CONFIG_PM
1510static int ar6k_cfg80211_suspend(struct wiphy *wiphy,
1511 struct cfg80211_wowlan *wow)
1512{
1513 struct ath6kl *ar = wiphy_priv(wiphy);
1514
1515 return ath6kl_hif_suspend(ar);
1516}
1517#endif
1518
6a7c9bad
JM
1519static int ath6kl_set_channel(struct wiphy *wiphy, struct net_device *dev,
1520 struct ieee80211_channel *chan,
1521 enum nl80211_channel_type channel_type)
1522{
1523 struct ath6kl *ar = ath6kl_priv(dev);
1524
1525 if (!ath6kl_cfg80211_ready(ar))
1526 return -EIO;
1527
1528 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: center_freq=%u hw_value=%u\n",
1529 __func__, chan->center_freq, chan->hw_value);
1530 ar->next_chan = chan->center_freq;
1531
1532 return 0;
1533}
1534
8bdfbf40
JM
1535static bool ath6kl_is_p2p_ie(const u8 *pos)
1536{
1537 return pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
1538 pos[2] == 0x50 && pos[3] == 0x6f &&
1539 pos[4] == 0x9a && pos[5] == 0x09;
1540}
1541
1542static int ath6kl_set_ap_probe_resp_ies(struct ath6kl *ar, const u8 *ies,
1543 size_t ies_len)
1544{
1545 const u8 *pos;
1546 u8 *buf = NULL;
1547 size_t len = 0;
1548 int ret;
1549
1550 /*
1551 * Filter out P2P IE(s) since they will be included depending on
1552 * the Probe Request frame in ath6kl_send_go_probe_resp().
1553 */
1554
1555 if (ies && ies_len) {
1556 buf = kmalloc(ies_len, GFP_KERNEL);
1557 if (buf == NULL)
1558 return -ENOMEM;
1559 pos = ies;
1560 while (pos + 1 < ies + ies_len) {
1561 if (pos + 2 + pos[1] > ies + ies_len)
1562 break;
1563 if (!ath6kl_is_p2p_ie(pos)) {
1564 memcpy(buf + len, pos, 2 + pos[1]);
1565 len += 2 + pos[1];
1566 }
1567 pos += 2 + pos[1];
1568 }
1569 }
1570
1571 ret = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_PROBE_RESP,
1572 buf, len);
1573 kfree(buf);
1574 return ret;
1575}
1576
6a7c9bad
JM
1577static int ath6kl_ap_beacon(struct wiphy *wiphy, struct net_device *dev,
1578 struct beacon_parameters *info, bool add)
1579{
1580 struct ath6kl *ar = ath6kl_priv(dev);
1581 struct ieee80211_mgmt *mgmt;
1582 u8 *ies;
1583 int ies_len;
1584 struct wmi_connect_cmd p;
1585 int res;
1586 int i;
1587
1588 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: add=%d\n", __func__, add);
1589
1590 if (!ath6kl_cfg80211_ready(ar))
1591 return -EIO;
1592
1593 if (ar->next_mode != AP_NETWORK)
1594 return -EOPNOTSUPP;
1595
1596 if (info->beacon_ies) {
1597 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_BEACON,
1598 info->beacon_ies,
1599 info->beacon_ies_len);
1600 if (res)
1601 return res;
1602 }
1603 if (info->proberesp_ies) {
8bdfbf40
JM
1604 res = ath6kl_set_ap_probe_resp_ies(ar, info->proberesp_ies,
1605 info->proberesp_ies_len);
6a7c9bad
JM
1606 if (res)
1607 return res;
1608 }
1609 if (info->assocresp_ies) {
1610 res = ath6kl_wmi_set_appie_cmd(ar->wmi, WMI_FRAME_ASSOC_RESP,
1611 info->assocresp_ies,
1612 info->assocresp_ies_len);
1613 if (res)
1614 return res;
1615 }
1616
1617 if (!add)
1618 return 0;
1619
9a5b1318
JM
1620 ar->ap_mode_bkey.valid = false;
1621
6a7c9bad
JM
1622 /* TODO:
1623 * info->interval
1624 * info->dtim_period
1625 */
1626
1627 if (info->head == NULL)
1628 return -EINVAL;
1629 mgmt = (struct ieee80211_mgmt *) info->head;
1630 ies = mgmt->u.beacon.variable;
1631 if (ies > info->head + info->head_len)
1632 return -EINVAL;
1633 ies_len = info->head + info->head_len - ies;
1634
1635 if (info->ssid == NULL)
1636 return -EINVAL;
1637 memcpy(ar->ssid, info->ssid, info->ssid_len);
1638 ar->ssid_len = info->ssid_len;
1639 if (info->hidden_ssid != NL80211_HIDDEN_SSID_NOT_IN_USE)
1640 return -EOPNOTSUPP; /* TODO */
1641
1642 ar->dot11_auth_mode = OPEN_AUTH;
1643
1644 memset(&p, 0, sizeof(p));
1645
1646 for (i = 0; i < info->crypto.n_akm_suites; i++) {
1647 switch (info->crypto.akm_suites[i]) {
1648 case WLAN_AKM_SUITE_8021X:
1649 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1650 p.auth_mode |= WPA_AUTH;
1651 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1652 p.auth_mode |= WPA2_AUTH;
1653 break;
1654 case WLAN_AKM_SUITE_PSK:
1655 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_1)
1656 p.auth_mode |= WPA_PSK_AUTH;
1657 if (info->crypto.wpa_versions & NL80211_WPA_VERSION_2)
1658 p.auth_mode |= WPA2_PSK_AUTH;
1659 break;
1660 }
1661 }
1662 if (p.auth_mode == 0)
1663 p.auth_mode = NONE_AUTH;
1664 ar->auth_mode = p.auth_mode;
1665
1666 for (i = 0; i < info->crypto.n_ciphers_pairwise; i++) {
1667 switch (info->crypto.ciphers_pairwise[i]) {
1668 case WLAN_CIPHER_SUITE_WEP40:
1669 case WLAN_CIPHER_SUITE_WEP104:
1670 p.prwise_crypto_type |= WEP_CRYPT;
1671 break;
1672 case WLAN_CIPHER_SUITE_TKIP:
1673 p.prwise_crypto_type |= TKIP_CRYPT;
1674 break;
1675 case WLAN_CIPHER_SUITE_CCMP:
1676 p.prwise_crypto_type |= AES_CRYPT;
1677 break;
1678 }
1679 }
229ed6b5 1680 if (p.prwise_crypto_type == 0) {
6a7c9bad 1681 p.prwise_crypto_type = NONE_CRYPT;
229ed6b5
EL
1682 ath6kl_set_cipher(ar, 0, true);
1683 } else if (info->crypto.n_ciphers_pairwise == 1)
1684 ath6kl_set_cipher(ar, info->crypto.ciphers_pairwise[0], true);
6a7c9bad
JM
1685
1686 switch (info->crypto.cipher_group) {
1687 case WLAN_CIPHER_SUITE_WEP40:
1688 case WLAN_CIPHER_SUITE_WEP104:
1689 p.grp_crypto_type = WEP_CRYPT;
1690 break;
1691 case WLAN_CIPHER_SUITE_TKIP:
1692 p.grp_crypto_type = TKIP_CRYPT;
1693 break;
1694 case WLAN_CIPHER_SUITE_CCMP:
1695 p.grp_crypto_type = AES_CRYPT;
1696 break;
1697 default:
1698 p.grp_crypto_type = NONE_CRYPT;
1699 break;
1700 }
229ed6b5 1701 ath6kl_set_cipher(ar, info->crypto.cipher_group, false);
6a7c9bad
JM
1702
1703 p.nw_type = AP_NETWORK;
1704 ar->nw_type = ar->next_mode;
1705
1706 p.ssid_len = ar->ssid_len;
1707 memcpy(p.ssid, ar->ssid, ar->ssid_len);
1708 p.dot11_auth_mode = ar->dot11_auth_mode;
1709 p.ch = cpu_to_le16(ar->next_chan);
1710
9a5b1318
JM
1711 res = ath6kl_wmi_ap_profile_commit(ar->wmi, &p);
1712 if (res < 0)
1713 return res;
1714
1715 return 0;
6a7c9bad
JM
1716}
1717
1718static int ath6kl_add_beacon(struct wiphy *wiphy, struct net_device *dev,
1719 struct beacon_parameters *info)
1720{
1721 return ath6kl_ap_beacon(wiphy, dev, info, true);
1722}
1723
1724static int ath6kl_set_beacon(struct wiphy *wiphy, struct net_device *dev,
1725 struct beacon_parameters *info)
1726{
1727 return ath6kl_ap_beacon(wiphy, dev, info, false);
1728}
1729
1730static int ath6kl_del_beacon(struct wiphy *wiphy, struct net_device *dev)
1731{
1732 struct ath6kl *ar = ath6kl_priv(dev);
1733
1734 if (ar->nw_type != AP_NETWORK)
1735 return -EOPNOTSUPP;
1736 if (!test_bit(CONNECTED, &ar->flag))
1737 return -ENOTCONN;
1738
1739 ath6kl_wmi_disconnect_cmd(ar->wmi);
1740 clear_bit(CONNECTED, &ar->flag);
1741
1742 return 0;
1743}
1744
23875136
JM
1745static int ath6kl_change_station(struct wiphy *wiphy, struct net_device *dev,
1746 u8 *mac, struct station_parameters *params)
1747{
1748 struct ath6kl *ar = ath6kl_priv(dev);
1749
1750 if (ar->nw_type != AP_NETWORK)
1751 return -EOPNOTSUPP;
1752
1753 /* Use this only for authorizing/unauthorizing a station */
1754 if (!(params->sta_flags_mask & BIT(NL80211_STA_FLAG_AUTHORIZED)))
1755 return -EOPNOTSUPP;
1756
1757 if (params->sta_flags_set & BIT(NL80211_STA_FLAG_AUTHORIZED))
1758 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_AUTHORIZE,
1759 mac, 0);
1760 return ath6kl_wmi_ap_set_mlme(ar->wmi, WMI_AP_MLME_UNAUTHORIZE, mac,
1761 0);
1762}
1763
63fa1e0c
JM
1764static int ath6kl_remain_on_channel(struct wiphy *wiphy,
1765 struct net_device *dev,
1766 struct ieee80211_channel *chan,
1767 enum nl80211_channel_type channel_type,
1768 unsigned int duration,
1769 u64 *cookie)
1770{
1771 struct ath6kl *ar = ath6kl_priv(dev);
1772
1773 /* TODO: if already pending or ongoing remain-on-channel,
1774 * return -EBUSY */
1775 *cookie = 1; /* only a single pending request is supported */
1776
1777 return ath6kl_wmi_remain_on_chnl_cmd(ar->wmi, chan->center_freq,
1778 duration);
1779}
1780
1781static int ath6kl_cancel_remain_on_channel(struct wiphy *wiphy,
1782 struct net_device *dev,
1783 u64 cookie)
1784{
1785 struct ath6kl *ar = ath6kl_priv(dev);
1786
1787 if (cookie != 1)
1788 return -ENOENT;
1789
1790 return ath6kl_wmi_cancel_remain_on_chnl_cmd(ar->wmi);
1791}
1792
8bdfbf40
JM
1793static int ath6kl_send_go_probe_resp(struct ath6kl *ar, const u8 *buf,
1794 size_t len, unsigned int freq)
1795{
1796 const u8 *pos;
1797 u8 *p2p;
1798 int p2p_len;
1799 int ret;
1800 const struct ieee80211_mgmt *mgmt;
1801
1802 mgmt = (const struct ieee80211_mgmt *) buf;
1803
1804 /* Include P2P IE(s) from the frame generated in user space. */
1805
1806 p2p = kmalloc(len, GFP_KERNEL);
1807 if (p2p == NULL)
1808 return -ENOMEM;
1809 p2p_len = 0;
1810
1811 pos = mgmt->u.probe_resp.variable;
1812 while (pos + 1 < buf + len) {
1813 if (pos + 2 + pos[1] > buf + len)
1814 break;
1815 if (ath6kl_is_p2p_ie(pos)) {
1816 memcpy(p2p + p2p_len, pos, 2 + pos[1]);
1817 p2p_len += 2 + pos[1];
1818 }
1819 pos += 2 + pos[1];
1820 }
1821
1822 ret = ath6kl_wmi_send_probe_response_cmd(ar->wmi, freq, mgmt->da,
1823 p2p, p2p_len);
1824 kfree(p2p);
1825 return ret;
1826}
1827
8a6c8060
JM
1828static int ath6kl_mgmt_tx(struct wiphy *wiphy, struct net_device *dev,
1829 struct ieee80211_channel *chan, bool offchan,
1830 enum nl80211_channel_type channel_type,
1831 bool channel_type_valid, unsigned int wait,
1832 const u8 *buf, size_t len, u64 *cookie)
1833{
1834 struct ath6kl *ar = ath6kl_priv(dev);
1835 u32 id;
8bdfbf40
JM
1836 const struct ieee80211_mgmt *mgmt;
1837
1838 mgmt = (const struct ieee80211_mgmt *) buf;
1839 if (buf + len >= mgmt->u.probe_resp.variable &&
1840 ar->nw_type == AP_NETWORK && test_bit(CONNECTED, &ar->flag) &&
1841 ieee80211_is_probe_resp(mgmt->frame_control)) {
1842 /*
1843 * Send Probe Response frame in AP mode using a separate WMI
1844 * command to allow the target to fill in the generic IEs.
1845 */
1846 *cookie = 0; /* TX status not supported */
1847 return ath6kl_send_go_probe_resp(ar, buf, len,
1848 chan->center_freq);
1849 }
8a6c8060
JM
1850
1851 id = ar->send_action_id++;
1852 if (id == 0) {
1853 /*
1854 * 0 is a reserved value in the WMI command and shall not be
1855 * used for the command.
1856 */
1857 id = ar->send_action_id++;
1858 }
1859
1860 *cookie = id;
1861 return ath6kl_wmi_send_action_cmd(ar->wmi, id, chan->center_freq, wait,
1862 buf, len);
1863}
1864
ae32c30a
JM
1865static void ath6kl_mgmt_frame_register(struct wiphy *wiphy,
1866 struct net_device *dev,
1867 u16 frame_type, bool reg)
1868{
1869 struct ath6kl *ar = ath6kl_priv(dev);
1870
1871 ath6kl_dbg(ATH6KL_DBG_WLAN_CFG, "%s: frame_type=0x%x reg=%d\n",
1872 __func__, frame_type, reg);
1873 if (frame_type == IEEE80211_STYPE_PROBE_REQ) {
1874 /*
1875 * Note: This notification callback is not allowed to sleep, so
1876 * we cannot send WMI_PROBE_REQ_REPORT_CMD here. Instead, we
1877 * hardcode target to report Probe Request frames all the time.
1878 */
1879 ar->probe_req_report = reg;
1880 }
1881}
1882
f80574ae
JM
1883static const struct ieee80211_txrx_stypes
1884ath6kl_mgmt_stypes[NUM_NL80211_IFTYPES] = {
1885 [NL80211_IFTYPE_STATION] = {
1886 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1887 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1888 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1889 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1890 },
1891 [NL80211_IFTYPE_P2P_CLIENT] = {
1892 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1893 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1894 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1895 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1896 },
1897 [NL80211_IFTYPE_P2P_GO] = {
1898 .tx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1899 BIT(IEEE80211_STYPE_PROBE_RESP >> 4),
1900 .rx = BIT(IEEE80211_STYPE_ACTION >> 4) |
1901 BIT(IEEE80211_STYPE_PROBE_REQ >> 4)
1902 },
1903};
1904
bdcd8170
KV
1905static struct cfg80211_ops ath6kl_cfg80211_ops = {
1906 .change_virtual_intf = ath6kl_cfg80211_change_iface,
1907 .scan = ath6kl_cfg80211_scan,
1908 .connect = ath6kl_cfg80211_connect,
1909 .disconnect = ath6kl_cfg80211_disconnect,
1910 .add_key = ath6kl_cfg80211_add_key,
1911 .get_key = ath6kl_cfg80211_get_key,
1912 .del_key = ath6kl_cfg80211_del_key,
1913 .set_default_key = ath6kl_cfg80211_set_default_key,
1914 .set_wiphy_params = ath6kl_cfg80211_set_wiphy_params,
1915 .set_tx_power = ath6kl_cfg80211_set_txpower,
1916 .get_tx_power = ath6kl_cfg80211_get_txpower,
1917 .set_power_mgmt = ath6kl_cfg80211_set_power_mgmt,
1918 .join_ibss = ath6kl_cfg80211_join_ibss,
1919 .leave_ibss = ath6kl_cfg80211_leave_ibss,
1920 .get_station = ath6kl_get_station,
1921 .set_pmksa = ath6kl_set_pmksa,
1922 .del_pmksa = ath6kl_del_pmksa,
1923 .flush_pmksa = ath6kl_flush_pmksa,
003353b0 1924 CFG80211_TESTMODE_CMD(ath6kl_tm_cmd)
abcb344b
KV
1925#ifdef CONFIG_PM
1926 .suspend = ar6k_cfg80211_suspend,
1927#endif
6a7c9bad
JM
1928 .set_channel = ath6kl_set_channel,
1929 .add_beacon = ath6kl_add_beacon,
1930 .set_beacon = ath6kl_set_beacon,
1931 .del_beacon = ath6kl_del_beacon,
23875136 1932 .change_station = ath6kl_change_station,
63fa1e0c
JM
1933 .remain_on_channel = ath6kl_remain_on_channel,
1934 .cancel_remain_on_channel = ath6kl_cancel_remain_on_channel,
8a6c8060 1935 .mgmt_tx = ath6kl_mgmt_tx,
ae32c30a 1936 .mgmt_frame_register = ath6kl_mgmt_frame_register,
bdcd8170
KV
1937};
1938
1939struct wireless_dev *ath6kl_cfg80211_init(struct device *dev)
1940{
1941 int ret = 0;
1942 struct wireless_dev *wdev;
6bbc7c35 1943 struct ath6kl *ar;
bdcd8170
KV
1944
1945 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1946 if (!wdev) {
1947 ath6kl_err("couldn't allocate wireless device\n");
1948 return NULL;
1949 }
1950
1951 /* create a new wiphy for use with cfg80211 */
1952 wdev->wiphy = wiphy_new(&ath6kl_cfg80211_ops, sizeof(struct ath6kl));
1953 if (!wdev->wiphy) {
1954 ath6kl_err("couldn't allocate wiphy device\n");
1955 kfree(wdev);
1956 return NULL;
1957 }
1958
6bbc7c35
JM
1959 ar = wiphy_priv(wdev->wiphy);
1960 ar->p2p = !!ath6kl_p2p;
1961
f80574ae
JM
1962 wdev->wiphy->mgmt_stypes = ath6kl_mgmt_stypes;
1963
63fa1e0c
JM
1964 wdev->wiphy->max_remain_on_channel_duration = 5000;
1965
bdcd8170
KV
1966 /* set device pointer for wiphy */
1967 set_wiphy_dev(wdev->wiphy, dev);
1968
1969 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
6e4604c8 1970 BIT(NL80211_IFTYPE_ADHOC) | BIT(NL80211_IFTYPE_AP);
6bbc7c35
JM
1971 if (ar->p2p) {
1972 wdev->wiphy->interface_modes |= BIT(NL80211_IFTYPE_P2P_GO) |
1973 BIT(NL80211_IFTYPE_P2P_CLIENT);
1974 }
bdcd8170
KV
1975 /* max num of ssids that can be probed during scanning */
1976 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
b84da8c7 1977 wdev->wiphy->max_scan_ie_len = 1000; /* FIX: what is correct limit? */
bdcd8170
KV
1978 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ath6kl_band_2ghz;
1979 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ath6kl_band_5ghz;
1980 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1981
1982 wdev->wiphy->cipher_suites = cipher_suites;
1983 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1984
1985 ret = wiphy_register(wdev->wiphy);
1986 if (ret < 0) {
1987 ath6kl_err("couldn't register wiphy device\n");
1988 wiphy_free(wdev->wiphy);
1989 kfree(wdev);
1990 return NULL;
1991 }
1992
1993 return wdev;
1994}
1995
1996void ath6kl_cfg80211_deinit(struct ath6kl *ar)
1997{
1998 struct wireless_dev *wdev = ar->wdev;
1999
2000 if (ar->scan_req) {
2001 cfg80211_scan_done(ar->scan_req, true);
2002 ar->scan_req = NULL;
2003 }
2004
2005 if (!wdev)
2006 return;
2007
2008 wiphy_unregister(wdev->wiphy);
2009 wiphy_free(wdev->wiphy);
2010 kfree(wdev);
2011}
This page took 0.372228 seconds and 5 git commands to generate.