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