]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/ath6kl/os/linux/cfg80211.c
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/linville/wirel...
[net-next-2.6.git] / drivers / staging / ath6kl / os / linux / cfg80211.c
CommitLineData
30295c89
VM
1//------------------------------------------------------------------------------
2// Copyright (c) 2004-2010 Atheros Communications Inc.
3// All rights reserved.
4//
5//
6//
7// Permission to use, copy, modify, and/or distribute this software for any
8// purpose with or without fee is hereby granted, provided that the above
9// copyright notice and this permission notice appear in all copies.
10//
11// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18//
19//
20//
21// Author(s): ="Atheros"
22//------------------------------------------------------------------------------
23
30295c89
VM
24#include <linux/wireless.h>
25#include <linux/ieee80211.h>
26#include <net/cfg80211.h>
27
28#include "ar6000_drv.h"
29
30
31extern A_WAITQUEUE_HEAD arEvent;
32extern unsigned int wmitimeout;
33extern int reconnect_flag;
34
35
36#define RATETAB_ENT(_rate, _rateid, _flags) { \
37 .bitrate = (_rate), \
38 .flags = (_flags), \
39 .hw_value = (_rateid), \
40}
41
42#define CHAN2G(_channel, _freq, _flags) { \
43 .band = IEEE80211_BAND_2GHZ, \
44 .hw_value = (_channel), \
45 .center_freq = (_freq), \
46 .flags = (_flags), \
47 .max_antenna_gain = 0, \
48 .max_power = 30, \
49}
50
51#define CHAN5G(_channel, _flags) { \
52 .band = IEEE80211_BAND_5GHZ, \
53 .hw_value = (_channel), \
54 .center_freq = 5000 + (5 * (_channel)), \
55 .flags = (_flags), \
56 .max_antenna_gain = 0, \
57 .max_power = 30, \
58}
59
60static struct
61ieee80211_rate ar6k_rates[] = {
62 RATETAB_ENT(10, 0x1, 0),
63 RATETAB_ENT(20, 0x2, 0),
64 RATETAB_ENT(55, 0x4, 0),
65 RATETAB_ENT(110, 0x8, 0),
66 RATETAB_ENT(60, 0x10, 0),
67 RATETAB_ENT(90, 0x20, 0),
68 RATETAB_ENT(120, 0x40, 0),
69 RATETAB_ENT(180, 0x80, 0),
70 RATETAB_ENT(240, 0x100, 0),
71 RATETAB_ENT(360, 0x200, 0),
72 RATETAB_ENT(480, 0x400, 0),
73 RATETAB_ENT(540, 0x800, 0),
74};
75
76#define ar6k_a_rates (ar6k_rates + 4)
77#define ar6k_a_rates_size 8
78#define ar6k_g_rates (ar6k_rates + 0)
79#define ar6k_g_rates_size 12
80
81static struct
82ieee80211_channel ar6k_2ghz_channels[] = {
83 CHAN2G(1, 2412, 0),
84 CHAN2G(2, 2417, 0),
85 CHAN2G(3, 2422, 0),
86 CHAN2G(4, 2427, 0),
87 CHAN2G(5, 2432, 0),
88 CHAN2G(6, 2437, 0),
89 CHAN2G(7, 2442, 0),
90 CHAN2G(8, 2447, 0),
91 CHAN2G(9, 2452, 0),
92 CHAN2G(10, 2457, 0),
93 CHAN2G(11, 2462, 0),
94 CHAN2G(12, 2467, 0),
95 CHAN2G(13, 2472, 0),
96 CHAN2G(14, 2484, 0),
97};
98
99static struct
100ieee80211_channel ar6k_5ghz_a_channels[] = {
101 CHAN5G(34, 0), CHAN5G(36, 0),
102 CHAN5G(38, 0), CHAN5G(40, 0),
103 CHAN5G(42, 0), CHAN5G(44, 0),
104 CHAN5G(46, 0), CHAN5G(48, 0),
105 CHAN5G(52, 0), CHAN5G(56, 0),
106 CHAN5G(60, 0), CHAN5G(64, 0),
107 CHAN5G(100, 0), CHAN5G(104, 0),
108 CHAN5G(108, 0), CHAN5G(112, 0),
109 CHAN5G(116, 0), CHAN5G(120, 0),
110 CHAN5G(124, 0), CHAN5G(128, 0),
111 CHAN5G(132, 0), CHAN5G(136, 0),
112 CHAN5G(140, 0), CHAN5G(149, 0),
113 CHAN5G(153, 0), CHAN5G(157, 0),
114 CHAN5G(161, 0), CHAN5G(165, 0),
115 CHAN5G(184, 0), CHAN5G(188, 0),
116 CHAN5G(192, 0), CHAN5G(196, 0),
117 CHAN5G(200, 0), CHAN5G(204, 0),
118 CHAN5G(208, 0), CHAN5G(212, 0),
119 CHAN5G(216, 0),
120};
121
122static struct
123ieee80211_supported_band ar6k_band_2ghz = {
124 .n_channels = ARRAY_SIZE(ar6k_2ghz_channels),
125 .channels = ar6k_2ghz_channels,
126 .n_bitrates = ar6k_g_rates_size,
127 .bitrates = ar6k_g_rates,
128};
129
130static struct
131ieee80211_supported_band ar6k_band_5ghz = {
132 .n_channels = ARRAY_SIZE(ar6k_5ghz_a_channels),
133 .channels = ar6k_5ghz_a_channels,
134 .n_bitrates = ar6k_a_rates_size,
135 .bitrates = ar6k_a_rates,
136};
137
138static int
139ar6k_set_wpa_version(AR_SOFTC_T *ar, enum nl80211_wpa_versions wpa_version)
140{
141
142 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: %u\n", __func__, wpa_version));
143
144 if (!wpa_version) {
145 ar->arAuthMode = NONE_AUTH;
146 } else if (wpa_version & NL80211_WPA_VERSION_1) {
147 ar->arAuthMode = WPA_AUTH;
148 } else if (wpa_version & NL80211_WPA_VERSION_2) {
149 ar->arAuthMode = WPA2_AUTH;
150 } else {
151 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
152 ("%s: %u not spported\n", __func__, wpa_version));
153 return -ENOTSUPP;
154 }
155
156 return A_OK;
157}
158
159static int
160ar6k_set_auth_type(AR_SOFTC_T *ar, enum nl80211_auth_type auth_type)
161{
162
163 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, auth_type));
164
165 switch (auth_type) {
166 case NL80211_AUTHTYPE_OPEN_SYSTEM:
167 ar->arDot11AuthMode = OPEN_AUTH;
168 break;
169 case NL80211_AUTHTYPE_SHARED_KEY:
170 ar->arDot11AuthMode = SHARED_AUTH;
171 break;
172 case NL80211_AUTHTYPE_NETWORK_EAP:
173 ar->arDot11AuthMode = LEAP_AUTH;
174 break;
175 default:
176 ar->arDot11AuthMode = OPEN_AUTH;
177 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
178 ("%s: 0x%x not spported\n", __func__, auth_type));
179 return -ENOTSUPP;
180 }
181
182 return A_OK;
183}
184
185static int
186ar6k_set_cipher(AR_SOFTC_T *ar, A_UINT32 cipher, A_BOOL ucast)
187{
188 A_UINT8 *ar_cipher = ucast ? &ar->arPairwiseCrypto :
189 &ar->arGroupCrypto;
190 A_UINT8 *ar_cipher_len = ucast ? &ar->arPairwiseCryptoLen :
191 &ar->arGroupCryptoLen;
192
193 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
194 ("%s: cipher 0x%x, ucast %u\n", __func__, cipher, ucast));
195
196 switch (cipher) {
197 case 0:
198 case IW_AUTH_CIPHER_NONE:
199 *ar_cipher = NONE_CRYPT;
200 *ar_cipher_len = 0;
201 break;
202 case WLAN_CIPHER_SUITE_WEP40:
203 *ar_cipher = WEP_CRYPT;
204 *ar_cipher_len = 5;
205 break;
206 case WLAN_CIPHER_SUITE_WEP104:
207 *ar_cipher = WEP_CRYPT;
208 *ar_cipher_len = 13;
209 break;
210 case WLAN_CIPHER_SUITE_TKIP:
211 *ar_cipher = TKIP_CRYPT;
212 *ar_cipher_len = 0;
213 break;
214 case WLAN_CIPHER_SUITE_CCMP:
215 *ar_cipher = AES_CRYPT;
216 *ar_cipher_len = 0;
217 break;
218 default:
219 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
220 ("%s: cipher 0x%x not supported\n", __func__, cipher));
221 return -ENOTSUPP;
222 }
223
224 return A_OK;
225}
226
227static void
228ar6k_set_key_mgmt(AR_SOFTC_T *ar, A_UINT32 key_mgmt)
229{
230 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: 0x%x\n", __func__, key_mgmt));
231
232 if (WLAN_AKM_SUITE_PSK == key_mgmt) {
233 if (WPA_AUTH == ar->arAuthMode) {
234 ar->arAuthMode = WPA_PSK_AUTH;
235 } else if (WPA2_AUTH == ar->arAuthMode) {
236 ar->arAuthMode = WPA2_PSK_AUTH;
237 }
238 } else if (WLAN_AKM_SUITE_8021X != key_mgmt) {
239 ar->arAuthMode = NONE_AUTH;
240 }
241}
242
243static int
244ar6k_cfg80211_connect(struct wiphy *wiphy, struct net_device *dev,
245 struct cfg80211_connect_params *sme)
246{
247 AR_SOFTC_T *ar = ar6k_priv(dev);
248 A_STATUS status;
249
250 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
251
252 if(ar->arWmiReady == FALSE) {
253 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready yet\n", __func__));
254 return -EIO;
255 }
256
257 if(ar->arWlanState == WLAN_DISABLED) {
258 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
259 return -EIO;
260 }
261
262 if(ar->bIsDestroyProgress) {
263 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: destroy in progress\n", __func__));
264 return -EBUSY;
265 }
266
267 if(!sme->ssid_len || IEEE80211_MAX_SSID_LEN < sme->ssid_len) {
268 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
269 return -EINVAL;
270 }
271
272 if(ar->arSkipScan == TRUE &&
273 ((sme->channel && sme->channel->center_freq == 0) ||
274 (sme->bssid && !sme->bssid[0] && !sme->bssid[1] && !sme->bssid[2] &&
275 !sme->bssid[3] && !sme->bssid[4] && !sme->bssid[5])))
276 {
277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s:SkipScan: channel or bssid invalid\n", __func__));
278 return -EINVAL;
279 }
280
281 if(down_interruptible(&ar->arSem)) {
282 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
283 return -ERESTARTSYS;
284 }
285
286 if(ar->bIsDestroyProgress) {
287 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
288 up(&ar->arSem);
289 return -EBUSY;
290 }
291
292 if(ar->arTxPending[wmi_get_control_ep(ar->arWmi)]) {
293 /*
294 * sleep until the command queue drains
295 */
296 wait_event_interruptible_timeout(arEvent,
297 ar->arTxPending[wmi_get_control_ep(ar->arWmi)] == 0, wmitimeout * HZ);
298 if (signal_pending(current)) {
299 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: cmd queue drain timeout\n", __func__));
300 up(&ar->arSem);
301 return -EINTR;
302 }
303 }
304
305 if(ar->arConnected == TRUE &&
306 ar->arSsidLen == sme->ssid_len &&
307 !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
308 reconnect_flag = TRUE;
309 status = wmi_reconnect_cmd(ar->arWmi,
310 ar->arReqBssid,
311 ar->arChannelHint);
312
313 up(&ar->arSem);
314 if (status != A_OK) {
315 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_reconnect_cmd failed\n", __func__));
316 return -EIO;
317 }
318 return 0;
319 } else if(ar->arSsidLen == sme->ssid_len &&
320 !A_MEMCMP(ar->arSsid, sme->ssid, ar->arSsidLen)) {
321 wmi_disconnect_cmd(ar->arWmi);
322 }
323
324 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
325 ar->arSsidLen = sme->ssid_len;
326 A_MEMCPY(ar->arSsid, sme->ssid, sme->ssid_len);
327
328 if(sme->channel){
329 ar->arChannelHint = sme->channel->center_freq;
330 }
331
332 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
333 if(sme->bssid){
334 if(A_MEMCMP(&sme->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
335 A_MEMCPY(ar->arReqBssid, sme->bssid, sizeof(ar->arReqBssid));
336 }
337 }
338
339 ar6k_set_wpa_version(ar, sme->crypto.wpa_versions);
340 ar6k_set_auth_type(ar, sme->auth_type);
341
342 if(sme->crypto.n_ciphers_pairwise) {
343 ar6k_set_cipher(ar, sme->crypto.ciphers_pairwise[0], true);
344 } else {
345 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
346 }
347 ar6k_set_cipher(ar, sme->crypto.cipher_group, false);
348
349 if(sme->crypto.n_akm_suites) {
350 ar6k_set_key_mgmt(ar, sme->crypto.akm_suites[0]);
351 }
352
353 if((sme->key_len) &&
354 (NONE_AUTH == ar->arAuthMode) &&
355 (WEP_CRYPT == ar->arPairwiseCrypto)) {
356 struct ar_key *key = NULL;
357
358 if(sme->key_idx < WMI_MIN_KEY_INDEX || sme->key_idx > WMI_MAX_KEY_INDEX) {
359 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
360 ("%s: key index %d out of bounds\n", __func__, sme->key_idx));
361 up(&ar->arSem);
362 return -ENOENT;
363 }
364
365 key = &ar->keys[sme->key_idx];
366 key->key_len = sme->key_len;
367 A_MEMCPY(key->key, sme->key, key->key_len);
368 key->cipher = ar->arPairwiseCrypto;
369 ar->arDefTxKeyIndex = sme->key_idx;
370
371 wmi_addKey_cmd(ar->arWmi, sme->key_idx,
372 ar->arPairwiseCrypto,
373 GROUP_USAGE | TX_USAGE,
374 key->key_len,
375 NULL,
376 key->key, KEY_OP_INIT_VAL, NULL,
377 NO_SYNC_WMIFLAG);
378 }
379
380 if (!ar->arUserBssFilter) {
381 if (wmi_bssfilter_cmd(ar->arWmi, ALL_BSS_FILTER, 0) != A_OK) {
382 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
383 up(&ar->arSem);
384 return -EIO;
385 }
386 }
387
388 ar->arNetworkType = ar->arNextMode;
389
390 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
391 " PW crypto %d PW crypto Len %d GRP crypto %d"\
392 " GRP crypto Len %d channel hint %u\n",
393 __func__, ar->arAuthMode, ar->arDot11AuthMode,
394 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
395 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
396
397 reconnect_flag = 0;
398 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
399 ar->arDot11AuthMode, ar->arAuthMode,
400 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
401 ar->arGroupCrypto,ar->arGroupCryptoLen,
402 ar->arSsidLen, ar->arSsid,
403 ar->arReqBssid, ar->arChannelHint,
404 ar->arConnectCtrlFlags);
405
406 up(&ar->arSem);
407
408 if (A_EINVAL == status) {
409 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
410 ar->arSsidLen = 0;
411 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Invalid request\n", __func__));
412 return -ENOENT;
413 } else if (status != A_OK) {
414 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_connect_cmd failed\n", __func__));
415 return -EIO;
416 }
417
418 if ((!(ar->arConnectCtrlFlags & CONNECT_DO_WPA_OFFLOAD)) &&
419 ((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)))
420 {
421 A_TIMEOUT_MS(&ar->disconnect_timer, A_DISCONNECT_TIMER_INTERVAL, 0);
422 }
423
424 ar->arConnectCtrlFlags &= ~CONNECT_DO_WPA_OFFLOAD;
425 ar->arConnectPending = TRUE;
426
427 return 0;
428}
429
430void
431ar6k_cfg80211_connect_event(AR_SOFTC_T *ar, A_UINT16 channel,
432 A_UINT8 *bssid, A_UINT16 listenInterval,
433 A_UINT16 beaconInterval,NETWORK_TYPE networkType,
434 A_UINT8 beaconIeLen, A_UINT8 assocReqLen,
435 A_UINT8 assocRespLen, A_UINT8 *assocInfo)
436{
437 A_UINT16 size = 0;
438 A_UINT16 capability = 0;
439 struct cfg80211_bss *bss = NULL;
440 struct ieee80211_mgmt *mgmt = NULL;
441 struct ieee80211_channel *ibss_channel = NULL;
442 s32 signal = 50 * 100;
443 A_UINT8 ie_buf_len = 0;
444 unsigned char ie_buf[256];
445 unsigned char *ptr_ie_buf = ie_buf;
446 unsigned char *ieeemgmtbuf = NULL;
447 A_UINT8 source_mac[ATH_MAC_LEN];
448
449 A_UINT8 assocReqIeOffset = sizeof(A_UINT16) + /* capinfo*/
450 sizeof(A_UINT16); /* listen interval */
451 A_UINT8 assocRespIeOffset = sizeof(A_UINT16) + /* capinfo*/
452 sizeof(A_UINT16) + /* status Code */
453 sizeof(A_UINT16); /* associd */
454 A_UINT8 *assocReqIe = assocInfo + beaconIeLen + assocReqIeOffset;
455 A_UINT8 *assocRespIe = assocInfo + beaconIeLen + assocReqLen + assocRespIeOffset;
456
457 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
458
459 assocReqLen -= assocReqIeOffset;
460 assocRespLen -= assocRespIeOffset;
461
462 if((ADHOC_NETWORK & networkType)) {
463 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
464 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
465 ("%s: ath6k not in ibss mode\n", __func__));
466 return;
467 }
468 }
469
470 if((INFRA_NETWORK & networkType)) {
471 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
472 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
473 ("%s: ath6k not in station mode\n", __func__));
474 return;
475 }
476 }
477
478 /* Before informing the join/connect event, make sure that
479 * bss entry is present in scan list, if it not present
480 * construct and insert into scan list, otherwise that
481 * event will be dropped on the way by cfg80211, due to
482 * this keys will not be plumbed in case of WEP and
483 * application will not be aware of join/connect status. */
484 bss = cfg80211_get_bss(ar->wdev->wiphy, NULL, bssid,
485 ar->wdev->ssid, ar->wdev->ssid_len,
486 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS),
487 ((ADHOC_NETWORK & networkType) ? WLAN_CAPABILITY_IBSS : WLAN_CAPABILITY_ESS));
488
489 if(!bss) {
490 if (ADHOC_NETWORK & networkType) {
491 /* construct 802.11 mgmt beacon */
492 if(ptr_ie_buf) {
493 *ptr_ie_buf++ = WLAN_EID_SSID;
494 *ptr_ie_buf++ = ar->arSsidLen;
495 A_MEMCPY(ptr_ie_buf, ar->arSsid, ar->arSsidLen);
496 ptr_ie_buf +=ar->arSsidLen;
497
498 *ptr_ie_buf++ = WLAN_EID_IBSS_PARAMS;
499 *ptr_ie_buf++ = 2; /* length */
500 *ptr_ie_buf++ = 0; /* ATIM window */
501 *ptr_ie_buf++ = 0; /* ATIM window */
502
503 /* TODO: update ibss params and include supported rates,
504 * DS param set, extened support rates, wmm. */
505
506 ie_buf_len = ptr_ie_buf - ie_buf;
507 }
508
509 capability |= IEEE80211_CAPINFO_IBSS;
510 if(WEP_CRYPT == ar->arPairwiseCrypto) {
511 capability |= IEEE80211_CAPINFO_PRIVACY;
512 }
513 A_MEMCPY(source_mac, ar->arNetDev->dev_addr, ATH_MAC_LEN);
514 ptr_ie_buf = ie_buf;
515 } else {
516 capability = *(A_UINT16 *)(&assocInfo[beaconIeLen]);
517 A_MEMCPY(source_mac, bssid, ATH_MAC_LEN);
518 ptr_ie_buf = assocReqIe;
519 ie_buf_len = assocReqLen;
520 }
521
522 size = offsetof(struct ieee80211_mgmt, u)
523 + sizeof(mgmt->u.beacon)
524 + ie_buf_len;
525
526 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
527 if(!ieeemgmtbuf) {
528 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
529 ("%s: ieeeMgmtbuf alloc error\n", __func__));
530 return;
531 }
532
533 A_MEMZERO(ieeemgmtbuf, size);
534 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
535 mgmt->frame_control = (IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_BEACON);
536 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
537 A_MEMCPY(mgmt->sa, source_mac, ATH_MAC_LEN);
538 A_MEMCPY(mgmt->bssid, bssid, ATH_MAC_LEN);
539 mgmt->u.beacon.beacon_int = beaconInterval;
540 mgmt->u.beacon.capab_info = capability;
541 A_MEMCPY(mgmt->u.beacon.variable, ptr_ie_buf, ie_buf_len);
542
543 ibss_channel = ieee80211_get_channel(ar->wdev->wiphy, (int)channel);
544
fa1ae16c
AS
545 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
546 ("%s: inform bss with bssid %pM channel %d beaconInterval %d "
97d23545 547 "capability 0x%x\n", __func__, mgmt->bssid,
fa1ae16c 548 ibss_channel->hw_value, beaconInterval, capability));
30295c89
VM
549
550 bss = cfg80211_inform_bss_frame(ar->wdev->wiphy,
551 ibss_channel, mgmt,
552 le16_to_cpu(size),
553 signal, GFP_KERNEL);
554 A_FREE(ieeemgmtbuf);
555 cfg80211_put_bss(bss);
556 }
557
558 if((ADHOC_NETWORK & networkType)) {
559 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
560 return;
561 }
562
563 if (FALSE == ar->arConnected) {
564 /* inform connect result to cfg80211 */
565 cfg80211_connect_result(ar->arNetDev, bssid,
566 assocReqIe, assocReqLen,
567 assocRespIe, assocRespLen,
568 WLAN_STATUS_SUCCESS, GFP_KERNEL);
569 } else {
570 /* inform roam event to cfg80211 */
571 cfg80211_roamed(ar->arNetDev, bssid,
572 assocReqIe, assocReqLen,
573 assocRespIe, assocRespLen,
574 GFP_KERNEL);
575 }
576}
577
578static int
579ar6k_cfg80211_disconnect(struct wiphy *wiphy, struct net_device *dev,
580 A_UINT16 reason_code)
581{
582 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
583
584 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason_code));
585
586 if(ar->arWmiReady == FALSE) {
587 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
588 return -EIO;
589 }
590
591 if(ar->arWlanState == WLAN_DISABLED) {
592 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
593 return -EIO;
594 }
595
596 if(ar->bIsDestroyProgress) {
597 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, destroy in progress\n", __func__));
598 return -EBUSY;
599 }
600
601 if(down_interruptible(&ar->arSem)) {
602 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: busy, couldn't get access\n", __func__));
603 return -ERESTARTSYS;
604 }
605
606 reconnect_flag = 0;
607 wmi_disconnect_cmd(ar->arWmi);
608 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
609 ar->arSsidLen = 0;
610
611 if (ar->arSkipScan == FALSE) {
612 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
613 }
614
615 up(&ar->arSem);
616
617 return 0;
618}
619
620void
621ar6k_cfg80211_disconnect_event(AR_SOFTC_T *ar, A_UINT8 reason,
622 A_UINT8 *bssid, A_UINT8 assocRespLen,
623 A_UINT8 *assocInfo, A_UINT16 protocolReasonStatus)
624{
625
626 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: reason=%u\n", __func__, reason));
627
628 if((ADHOC_NETWORK & ar->arNetworkType)) {
629 if(NL80211_IFTYPE_ADHOC != ar->wdev->iftype) {
630 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
631 ("%s: ath6k not in ibss mode\n", __func__));
632 return;
633 }
634 A_MEMZERO(bssid, ETH_ALEN);
635 cfg80211_ibss_joined(ar->arNetDev, bssid, GFP_KERNEL);
636 return;
637 }
638
639 if((INFRA_NETWORK & ar->arNetworkType)) {
640 if(NL80211_IFTYPE_STATION != ar->wdev->iftype) {
641 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
642 ("%s: ath6k not in station mode\n", __func__));
643 return;
644 }
645 }
646
647 if(FALSE == ar->arConnected) {
648 if(NO_NETWORK_AVAIL == reason) {
649 /* connect cmd failed */
650 cfg80211_connect_result(ar->arNetDev, bssid,
651 NULL, 0,
652 NULL, 0,
653 WLAN_STATUS_UNSPECIFIED_FAILURE,
654 GFP_KERNEL);
655 }
656 } else {
657 /* connection loss due to disconnect cmd or low rssi */
658 cfg80211_disconnected(ar->arNetDev, reason, NULL, 0, GFP_KERNEL);
659 }
660}
661
662void
663ar6k_cfg80211_scan_node(void *arg, bss_t *ni)
664{
665 struct wiphy *wiphy = (struct wiphy *)arg;
666 A_UINT16 size;
667 unsigned char *ieeemgmtbuf = NULL;
668 struct ieee80211_mgmt *mgmt;
669 struct ieee80211_channel *channel;
670 struct ieee80211_supported_band *band;
671 struct ieee80211_common_ie *cie;
672 s32 signal;
673 int freq;
674
675 cie = &ni->ni_cie;
676
677#define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
678 if(CHAN_IS_11A(cie->ie_chan)) {
679 /* 11a */
680 band = wiphy->bands[IEEE80211_BAND_5GHZ];
681 } else if((cie->ie_erp) || (cie->ie_xrates)) {
682 /* 11g */
683 band = wiphy->bands[IEEE80211_BAND_2GHZ];
684 } else {
685 /* 11b */
686 band = wiphy->bands[IEEE80211_BAND_2GHZ];
687 }
688
689 size = ni->ni_framelen + offsetof(struct ieee80211_mgmt, u);
690 ieeemgmtbuf = A_MALLOC_NOWAIT(size);
691 if(!ieeemgmtbuf)
692 {
693 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ieeeMgmtbuf alloc error\n", __func__));
694 return;
695 }
696
697 /* Note:
698 TODO: Update target to include 802.11 mac header while sending bss info.
699 Target removes 802.11 mac header while sending the bss info to host,
700 cfg80211 needs it, for time being just filling the da, sa and bssid fields alone.
701 */
702 mgmt = (struct ieee80211_mgmt *)ieeemgmtbuf;
703 A_MEMCPY(mgmt->da, bcast_mac, ATH_MAC_LEN);
704 A_MEMCPY(mgmt->sa, ni->ni_macaddr, ATH_MAC_LEN);
705 A_MEMCPY(mgmt->bssid, ni->ni_macaddr, ATH_MAC_LEN);
706 A_MEMCPY(ieeemgmtbuf + offsetof(struct ieee80211_mgmt, u),
707 ni->ni_buf, ni->ni_framelen);
708
709 freq = cie->ie_chan;
710 channel = ieee80211_get_channel(wiphy, freq);
711 signal = ni->ni_snr * 100;
712
fa1ae16c
AS
713 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
714 ("%s: bssid %pM channel %d freq %d size %d\n", __func__,
97d23545 715 mgmt->bssid, channel->hw_value, freq, size));
30295c89
VM
716 cfg80211_inform_bss_frame(wiphy, channel, mgmt,
717 le16_to_cpu(size),
718 signal, GFP_KERNEL);
719
720 A_FREE (ieeemgmtbuf);
721}
722
723static int
724ar6k_cfg80211_scan(struct wiphy *wiphy, struct net_device *ndev,
725 struct cfg80211_scan_request *request)
726{
727 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
728 int ret = 0;
729 A_BOOL forceFgScan = FALSE;
730
731 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
732
733 if(ar->arWmiReady == FALSE) {
734 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
735 return -EIO;
736 }
737
738 if(ar->arWlanState == WLAN_DISABLED) {
739 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
740 return -EIO;
741 }
742
743 if (!ar->arUserBssFilter) {
744 if (wmi_bssfilter_cmd(ar->arWmi,
745 (ar->arConnected ? ALL_BUT_BSS_FILTER : ALL_BSS_FILTER),
746 0) != A_OK) {
747 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Couldn't set bss filtering\n", __func__));
748 return -EIO;
749 }
750 }
751
752 if(request->n_ssids &&
753 request->ssids[0].ssid_len) {
754 A_UINT8 i;
755
756 if(request->n_ssids > MAX_PROBED_SSID_INDEX) {
757 request->n_ssids = MAX_PROBED_SSID_INDEX;
758 }
759
760 for (i = 0; i < request->n_ssids; i++) {
761 wmi_probedSsid_cmd(ar->arWmi, i, SPECIFIC_SSID_FLAG,
762 request->ssids[i].ssid_len,
763 request->ssids[i].ssid);
764 }
765 }
766
767 if(ar->arConnected) {
768 forceFgScan = TRUE;
769 }
770
771 if(wmi_startscan_cmd(ar->arWmi, WMI_LONG_SCAN, forceFgScan, FALSE, \
772 0, 0, 0, NULL) != A_OK) {
773 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_startscan_cmd failed\n", __func__));
774 ret = -EIO;
775 }
776
777 ar->scan_request = request;
778
779 return ret;
780}
781
782void
783ar6k_cfg80211_scanComplete_event(AR_SOFTC_T *ar, A_STATUS status)
784{
785
786 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: status %d\n", __func__, status));
787
788 if(ar->scan_request)
789 {
790 /* Translate data to cfg80211 mgmt format */
791 wmi_iterate_nodes(ar->arWmi, ar6k_cfg80211_scan_node, ar->wdev->wiphy);
792
793 cfg80211_scan_done(ar->scan_request,
794 (status & A_ECANCELED) ? true : false);
795
796 if(ar->scan_request->n_ssids &&
797 ar->scan_request->ssids[0].ssid_len) {
798 A_UINT8 i;
799
800 for (i = 0; i < ar->scan_request->n_ssids; i++) {
801 wmi_probedSsid_cmd(ar->arWmi, i, DISABLE_SSID_FLAG,
802 0, NULL);
803 }
804 }
805 ar->scan_request = NULL;
806 }
807}
808
809static int
810ar6k_cfg80211_add_key(struct wiphy *wiphy, struct net_device *ndev,
22b4dc59 811 A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
30295c89
VM
812 struct key_params *params)
813{
814 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
815 struct ar_key *key = NULL;
816 A_UINT8 key_usage;
817 A_UINT8 key_type;
818 A_STATUS status = 0;
819
820 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s:\n", __func__));
821
822 if(ar->arWmiReady == FALSE) {
823 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
824 return -EIO;
825 }
826
827 if(ar->arWlanState == WLAN_DISABLED) {
828 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
829 return -EIO;
830 }
831
832 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
833 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
834 ("%s: key index %d out of bounds\n", __func__, key_index));
835 return -ENOENT;
836 }
837
838 key = &ar->keys[key_index];
839 A_MEMZERO(key, sizeof(struct ar_key));
840
841 if(!mac_addr || is_broadcast_ether_addr(mac_addr)) {
842 key_usage = GROUP_USAGE;
843 } else {
844 key_usage = PAIRWISE_USAGE;
845 }
846
847 if(params) {
848 if(params->key_len > WLAN_MAX_KEY_LEN ||
849 params->seq_len > IW_ENCODE_SEQ_MAX_SIZE)
850 return -EINVAL;
851
852 key->key_len = params->key_len;
853 A_MEMCPY(key->key, params->key, key->key_len);
854 key->seq_len = params->seq_len;
855 A_MEMCPY(key->seq, params->seq, key->seq_len);
856 key->cipher = params->cipher;
857 }
858
859 switch (key->cipher) {
860 case WLAN_CIPHER_SUITE_WEP40:
861 case WLAN_CIPHER_SUITE_WEP104:
862 key_type = WEP_CRYPT;
863 break;
864
865 case WLAN_CIPHER_SUITE_TKIP:
866 key_type = TKIP_CRYPT;
867 break;
868
869 case WLAN_CIPHER_SUITE_CCMP:
870 key_type = AES_CRYPT;
871 break;
872
873 default:
874 return -ENOTSUPP;
875 }
876
877 if (((WPA_PSK_AUTH == ar->arAuthMode) || (WPA2_PSK_AUTH == ar->arAuthMode)) &&
878 (GROUP_USAGE & key_usage))
879 {
880 A_UNTIMEOUT(&ar->disconnect_timer);
881 }
882
883 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
884 ("%s: index %d, key_len %d, key_type 0x%x,"\
885 " key_usage 0x%x, seq_len %d\n",
886 __func__, key_index, key->key_len, key_type,
887 key_usage, key->seq_len));
888
889 ar->arDefTxKeyIndex = key_index;
890 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex, key_type, key_usage,
891 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
892 (A_UINT8*)mac_addr, SYNC_BOTH_WMIFLAG);
893
894
895 if(status != A_OK) {
896 return -EIO;
897 }
898
899 return 0;
900}
901
902static int
903ar6k_cfg80211_del_key(struct wiphy *wiphy, struct net_device *ndev,
22b4dc59 904 A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr)
30295c89
VM
905{
906 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
907
908 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
909
910 if(ar->arWmiReady == FALSE) {
911 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
912 return -EIO;
913 }
914
915 if(ar->arWlanState == WLAN_DISABLED) {
916 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
917 return -EIO;
918 }
919
920 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
921 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
922 ("%s: key index %d out of bounds\n", __func__, key_index));
923 return -ENOENT;
924 }
925
926 if(!ar->keys[key_index].key_len) {
927 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d is empty\n", __func__, key_index));
928 return 0;
929 }
930
931 ar->keys[key_index].key_len = 0;
932
933 return wmi_deleteKey_cmd(ar->arWmi, key_index);
934}
935
936
937static int
938ar6k_cfg80211_get_key(struct wiphy *wiphy, struct net_device *ndev,
22b4dc59
HM
939 A_UINT8 key_index, bool pairwise, const A_UINT8 *mac_addr,
940 void *cookie,
30295c89
VM
941 void (*callback)(void *cookie, struct key_params*))
942{
943 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
944 struct ar_key *key = NULL;
945 struct key_params params;
946
947 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
948
949 if(ar->arWmiReady == FALSE) {
950 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
951 return -EIO;
952 }
953
954 if(ar->arWlanState == WLAN_DISABLED) {
955 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
956 return -EIO;
957 }
958
959 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
960 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
961 ("%s: key index %d out of bounds\n", __func__, key_index));
962 return -ENOENT;
963 }
964
965 key = &ar->keys[key_index];
966 A_MEMZERO(&params, sizeof(params));
967 params.cipher = key->cipher;
968 params.key_len = key->key_len;
969 params.seq_len = key->seq_len;
970 params.seq = key->seq;
971 params.key = key->key;
972
973 callback(cookie, &params);
974
975 return key->key_len ? 0 : -ENOENT;
976}
977
978
979static int
980ar6k_cfg80211_set_default_key(struct wiphy *wiphy, struct net_device *ndev,
981 A_UINT8 key_index)
982{
983 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
984 struct ar_key *key = NULL;
985 A_STATUS status = A_OK;
986
987 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
988
989 if(ar->arWmiReady == FALSE) {
990 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
991 return -EIO;
992 }
993
994 if(ar->arWlanState == WLAN_DISABLED) {
995 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
996 return -EIO;
997 }
998
999 if(key_index < WMI_MIN_KEY_INDEX || key_index > WMI_MAX_KEY_INDEX) {
1000 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1001 ("%s: key index %d out of bounds\n",
1002 __func__, key_index));
1003 return -ENOENT;
1004 }
1005
1006 if(!ar->keys[key_index].key_len) {
1007 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: invalid key index %d\n",
1008 __func__, key_index));
1009 return -EINVAL;
1010 }
1011
1012 ar->arDefTxKeyIndex = key_index;
1013 key = &ar->keys[ar->arDefTxKeyIndex];
1014 status = wmi_addKey_cmd(ar->arWmi, ar->arDefTxKeyIndex,
1015 ar->arPairwiseCrypto, GROUP_USAGE | TX_USAGE,
1016 key->key_len, key->seq, key->key, KEY_OP_INIT_VAL,
1017 NULL, SYNC_BOTH_WMIFLAG);
1018 if (status != A_OK) {
1019 return -EIO;
1020 }
1021
1022 return 0;
1023}
1024
1025static int
1026ar6k_cfg80211_set_default_mgmt_key(struct wiphy *wiphy, struct net_device *ndev,
1027 A_UINT8 key_index)
1028{
1029 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(ndev);
1030
1031 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: index %d\n", __func__, key_index));
1032
1033 if(ar->arWmiReady == FALSE) {
1034 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1035 return -EIO;
1036 }
1037
1038 if(ar->arWlanState == WLAN_DISABLED) {
1039 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1040 return -EIO;
1041 }
1042
1043 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1044 return -ENOTSUPP;
1045}
1046
1047void
1048ar6k_cfg80211_tkip_micerr_event(AR_SOFTC_T *ar, A_UINT8 keyid, A_BOOL ismcast)
1049{
1050 AR_DEBUG_PRINTF(ATH_DEBUG_INFO,
1051 ("%s: keyid %d, ismcast %d\n", __func__, keyid, ismcast));
1052
1053 cfg80211_michael_mic_failure(ar->arNetDev, ar->arBssid,
1054 (ismcast ? NL80211_KEYTYPE_GROUP : NL80211_KEYTYPE_PAIRWISE),
1055 keyid, NULL, GFP_KERNEL);
1056}
1057
1058static int
1059ar6k_cfg80211_set_wiphy_params(struct wiphy *wiphy, A_UINT32 changed)
1060{
1061 AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1062
1063 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: changed 0x%x\n", __func__, changed));
1064
1065 if(ar->arWmiReady == FALSE) {
1066 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1067 return -EIO;
1068 }
1069
1070 if(ar->arWlanState == WLAN_DISABLED) {
1071 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1072 return -EIO;
1073 }
1074
1075 if (changed & WIPHY_PARAM_RTS_THRESHOLD) {
1076 if (wmi_set_rts_cmd(ar->arWmi,wiphy->rts_threshold) != A_OK){
1077 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_set_rts_cmd failed\n", __func__));
1078 return -EIO;
1079 }
1080 }
1081
1082 return 0;
1083}
1084
1085static int
1086ar6k_cfg80211_set_bitrate_mask(struct wiphy *wiphy, struct net_device *dev,
1087 const A_UINT8 *peer,
1088 const struct cfg80211_bitrate_mask *mask)
1089{
1090 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("Setting rates: Not supported\n"));
1091 return -EIO;
1092}
1093
1094/* The type nl80211_tx_power_setting replaces the following data type from 2.6.36 onwards */
1095static int
1096ar6k_cfg80211_set_txpower(struct wiphy *wiphy, enum nl80211_tx_power_setting type, int dbm)
1097{
1098 AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1099 A_UINT8 ar_dbm;
1100
1101 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x, dbm %d\n", __func__, type, dbm));
1102
1103 if(ar->arWmiReady == FALSE) {
1104 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1105 return -EIO;
1106 }
1107
1108 if(ar->arWlanState == WLAN_DISABLED) {
1109 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1110 return -EIO;
1111 }
1112
1113 ar->arTxPwrSet = FALSE;
1114 switch(type) {
1115 case NL80211_TX_POWER_AUTOMATIC:
1116 return 0;
1117 case NL80211_TX_POWER_LIMITED:
1118 ar->arTxPwr = ar_dbm = dbm;
1119 ar->arTxPwrSet = TRUE;
1120 break;
1121 default:
1122 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type 0x%x not supported\n", __func__, type));
1123 return -EOPNOTSUPP;
1124 }
1125
1126 wmi_set_txPwr_cmd(ar->arWmi, ar_dbm);
1127
1128 return 0;
1129}
1130
1131static int
1132ar6k_cfg80211_get_txpower(struct wiphy *wiphy, int *dbm)
1133{
1134 AR_SOFTC_T *ar = (AR_SOFTC_T *)wiphy_priv(wiphy);
1135
1136 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1137
1138 if(ar->arWmiReady == FALSE) {
1139 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1140 return -EIO;
1141 }
1142
1143 if(ar->arWlanState == WLAN_DISABLED) {
1144 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1145 return -EIO;
1146 }
1147
1148 if((ar->arConnected == TRUE)) {
1149 ar->arTxPwr = 0;
1150
1151 if(wmi_get_txPwr_cmd(ar->arWmi) != A_OK) {
1152 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_get_txPwr_cmd failed\n", __func__));
1153 return -EIO;
1154 }
1155
1156 wait_event_interruptible_timeout(arEvent, ar->arTxPwr != 0, 5 * HZ);
1157
1158 if(signal_pending(current)) {
1159 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Target did not respond\n", __func__));
1160 return -EINTR;
1161 }
1162 }
1163
1164 *dbm = ar->arTxPwr;
1165 return 0;
1166}
1167
1168static int
1169ar6k_cfg80211_set_power_mgmt(struct wiphy *wiphy,
1170 struct net_device *dev,
1171 bool pmgmt, int timeout)
1172{
1173 AR_SOFTC_T *ar = ar6k_priv(dev);
1174 WMI_POWER_MODE_CMD pwrMode;
1175
1176 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: pmgmt %d, timeout %d\n", __func__, pmgmt, timeout));
1177
1178 if(ar->arWmiReady == FALSE) {
1179 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1180 return -EIO;
1181 }
1182
1183 if(ar->arWlanState == WLAN_DISABLED) {
1184 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1185 return -EIO;
1186 }
1187
1188 if(pmgmt) {
1189 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Max Perf\n", __func__));
1190 pwrMode.powerMode = MAX_PERF_POWER;
1191 } else {
1192 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Rec Power\n", __func__));
1193 pwrMode.powerMode = REC_POWER;
1194 }
1195
1196 if(wmi_powermode_cmd(ar->arWmi, pwrMode.powerMode) != A_OK) {
1197 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: wmi_powermode_cmd failed\n", __func__));
1198 return -EIO;
1199 }
1200
1201 return 0;
1202}
1203
1204static int
1205ar6k_cfg80211_add_virtual_intf(struct wiphy *wiphy, char *name,
1206 enum nl80211_iftype type, u32 *flags,
1207 struct vif_params *params)
1208{
1209
1210 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1211
1212 /* Multiple virtual interface is not supported.
1213 * The default interface supports STA and IBSS type
1214 */
1215 return -EOPNOTSUPP;
1216}
1217
1218static int
1219ar6k_cfg80211_del_virtual_intf(struct wiphy *wiphy, struct net_device *dev)
1220{
1221
1222 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: not supported\n", __func__));
1223
1224 /* Multiple virtual interface is not supported.
1225 * The default interface supports STA and IBSS type
1226 */
1227 return -EOPNOTSUPP;
1228}
1229
1230static int
1231ar6k_cfg80211_change_iface(struct wiphy *wiphy, struct net_device *ndev,
1232 enum nl80211_iftype type, u32 *flags,
1233 struct vif_params *params)
1234{
1235 AR_SOFTC_T *ar = ar6k_priv(ndev);
1236 struct wireless_dev *wdev = ar->wdev;
1237
1238 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: type %u\n", __func__, type));
1239
1240 if(ar->arWmiReady == FALSE) {
1241 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1242 return -EIO;
1243 }
1244
1245 if(ar->arWlanState == WLAN_DISABLED) {
1246 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1247 return -EIO;
1248 }
1249
1250 switch (type) {
1251 case NL80211_IFTYPE_STATION:
1252 ar->arNextMode = INFRA_NETWORK;
1253 break;
1254 case NL80211_IFTYPE_ADHOC:
1255 ar->arNextMode = ADHOC_NETWORK;
1256 break;
1257 default:
1258 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: type %u\n", __func__, type));
1259 return -EOPNOTSUPP;
1260 }
1261
1262 wdev->iftype = type;
1263
1264 return 0;
1265}
1266
1267static int
1268ar6k_cfg80211_join_ibss(struct wiphy *wiphy, struct net_device *dev,
1269 struct cfg80211_ibss_params *ibss_param)
1270{
1271 AR_SOFTC_T *ar = ar6k_priv(dev);
1272 A_STATUS status;
1273
1274 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1275
1276 if(ar->arWmiReady == FALSE) {
1277 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1278 return -EIO;
1279 }
1280
1281 if(ar->arWlanState == WLAN_DISABLED) {
1282 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1283 return -EIO;
1284 }
1285
1286 if(!ibss_param->ssid_len || IEEE80211_MAX_SSID_LEN < ibss_param->ssid_len) {
1287 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: ssid invalid\n", __func__));
1288 return -EINVAL;
1289 }
1290
1291 ar->arSsidLen = ibss_param->ssid_len;
1292 A_MEMCPY(ar->arSsid, ibss_param->ssid, ar->arSsidLen);
1293
1294 if(ibss_param->channel) {
1295 ar->arChannelHint = ibss_param->channel->center_freq;
1296 }
1297
1298 if(ibss_param->channel_fixed) {
1299 /* TODO: channel_fixed: The channel should be fixed, do not search for
1300 * IBSSs to join on other channels. Target firmware does not support this
1301 * feature, needs to be updated.*/
1302 }
1303
1304 A_MEMZERO(ar->arReqBssid, sizeof(ar->arReqBssid));
1305 if(ibss_param->bssid) {
1306 if(A_MEMCMP(&ibss_param->bssid, bcast_mac, AR6000_ETH_ADDR_LEN)) {
1307 A_MEMCPY(ar->arReqBssid, ibss_param->bssid, sizeof(ar->arReqBssid));
1308 }
1309 }
1310
1311 ar6k_set_wpa_version(ar, 0);
1312 ar6k_set_auth_type(ar, NL80211_AUTHTYPE_OPEN_SYSTEM);
1313
1314 if(ibss_param->privacy) {
1315 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, true);
1316 ar6k_set_cipher(ar, WLAN_CIPHER_SUITE_WEP40, false);
1317 } else {
1318 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, true);
1319 ar6k_set_cipher(ar, IW_AUTH_CIPHER_NONE, false);
1320 }
1321
1322 ar->arNetworkType = ar->arNextMode;
1323
1324 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: Connect called with authmode %d dot11 auth %d"\
1325 " PW crypto %d PW crypto Len %d GRP crypto %d"\
1326 " GRP crypto Len %d channel hint %u\n",
1327 __func__, ar->arAuthMode, ar->arDot11AuthMode,
1328 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1329 ar->arGroupCrypto, ar->arGroupCryptoLen, ar->arChannelHint));
1330
1331 status = wmi_connect_cmd(ar->arWmi, ar->arNetworkType,
1332 ar->arDot11AuthMode, ar->arAuthMode,
1333 ar->arPairwiseCrypto, ar->arPairwiseCryptoLen,
1334 ar->arGroupCrypto,ar->arGroupCryptoLen,
1335 ar->arSsidLen, ar->arSsid,
1336 ar->arReqBssid, ar->arChannelHint,
1337 ar->arConnectCtrlFlags);
1338
1339 return 0;
1340}
1341
1342static int
1343ar6k_cfg80211_leave_ibss(struct wiphy *wiphy, struct net_device *dev)
1344{
1345 AR_SOFTC_T *ar = (AR_SOFTC_T *)ar6k_priv(dev);
1346
1347 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1348
1349 if(ar->arWmiReady == FALSE) {
1350 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wmi not ready\n", __func__));
1351 return -EIO;
1352 }
1353
1354 if(ar->arWlanState == WLAN_DISABLED) {
1355 AR_DEBUG_PRINTF(ATH_DEBUG_ERR, ("%s: Wlan disabled\n", __func__));
1356 return -EIO;
1357 }
1358
1359 wmi_disconnect_cmd(ar->arWmi);
1360 A_MEMZERO(ar->arSsid, sizeof(ar->arSsid));
1361 ar->arSsidLen = 0;
1362
1363 return 0;
1364}
1365
1366
1367static const
1368A_UINT32 cipher_suites[] = {
1369 WLAN_CIPHER_SUITE_WEP40,
1370 WLAN_CIPHER_SUITE_WEP104,
1371 WLAN_CIPHER_SUITE_TKIP,
1372 WLAN_CIPHER_SUITE_CCMP,
1373};
1374
1375static struct
1376cfg80211_ops ar6k_cfg80211_ops = {
1377 .change_virtual_intf = ar6k_cfg80211_change_iface,
1378 .add_virtual_intf = ar6k_cfg80211_add_virtual_intf,
1379 .del_virtual_intf = ar6k_cfg80211_del_virtual_intf,
1380 .scan = ar6k_cfg80211_scan,
1381 .connect = ar6k_cfg80211_connect,
1382 .disconnect = ar6k_cfg80211_disconnect,
1383 .add_key = ar6k_cfg80211_add_key,
1384 .get_key = ar6k_cfg80211_get_key,
1385 .del_key = ar6k_cfg80211_del_key,
1386 .set_default_key = ar6k_cfg80211_set_default_key,
1387 .set_default_mgmt_key = ar6k_cfg80211_set_default_mgmt_key,
1388 .set_wiphy_params = ar6k_cfg80211_set_wiphy_params,
1389 .set_bitrate_mask = ar6k_cfg80211_set_bitrate_mask,
1390 .set_tx_power = ar6k_cfg80211_set_txpower,
1391 .get_tx_power = ar6k_cfg80211_get_txpower,
1392 .set_power_mgmt = ar6k_cfg80211_set_power_mgmt,
1393 .join_ibss = ar6k_cfg80211_join_ibss,
1394 .leave_ibss = ar6k_cfg80211_leave_ibss,
1395};
1396
1397struct wireless_dev *
1398ar6k_cfg80211_init(struct device *dev)
1399{
1400 int ret = 0;
1401 struct wireless_dev *wdev;
1402
1403 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1404
1405 wdev = kzalloc(sizeof(struct wireless_dev), GFP_KERNEL);
1406 if(!wdev) {
1407 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1408 ("%s: Couldn't allocate wireless device\n", __func__));
1409 return ERR_PTR(-ENOMEM);
1410 }
1411
1412 /* create a new wiphy for use with cfg80211 */
1413 wdev->wiphy = wiphy_new(&ar6k_cfg80211_ops, sizeof(AR_SOFTC_T));
1414 if(!wdev->wiphy) {
1415 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1416 ("%s: Couldn't allocate wiphy device\n", __func__));
1417 kfree(wdev);
1418 return ERR_PTR(-ENOMEM);
1419 }
1420
1421 /* set device pointer for wiphy */
1422 set_wiphy_dev(wdev->wiphy, dev);
1423
1424 wdev->wiphy->interface_modes = BIT(NL80211_IFTYPE_STATION) |
1425 BIT(NL80211_IFTYPE_ADHOC);
1426 /* max num of ssids that can be probed during scanning */
1427 wdev->wiphy->max_scan_ssids = MAX_PROBED_SSID_INDEX;
1428 wdev->wiphy->bands[IEEE80211_BAND_2GHZ] = &ar6k_band_2ghz;
1429 wdev->wiphy->bands[IEEE80211_BAND_5GHZ] = &ar6k_band_5ghz;
1430 wdev->wiphy->signal_type = CFG80211_SIGNAL_TYPE_MBM;
1431
1432 wdev->wiphy->cipher_suites = cipher_suites;
1433 wdev->wiphy->n_cipher_suites = ARRAY_SIZE(cipher_suites);
1434
1435 ret = wiphy_register(wdev->wiphy);
1436 if(ret < 0) {
1437 AR_DEBUG_PRINTF(ATH_DEBUG_ERR,
1438 ("%s: Couldn't register wiphy device\n", __func__));
1439 wiphy_free(wdev->wiphy);
1440 return ERR_PTR(ret);
1441 }
1442
1443 return wdev;
1444}
1445
1446void
1447ar6k_cfg80211_deinit(AR_SOFTC_T *ar)
1448{
1449 struct wireless_dev *wdev = ar->wdev;
1450
1451 AR_DEBUG_PRINTF(ATH_DEBUG_INFO, ("%s: \n", __func__));
1452
1453 if(ar->scan_request) {
1454 cfg80211_scan_done(ar->scan_request, true);
1455 ar->scan_request = NULL;
1456 }
1457
1458 if(!wdev)
1459 return;
1460
1461 wiphy_unregister(wdev->wiphy);
1462 wiphy_free(wdev->wiphy);
1463 kfree(wdev);
1464}
1465
1466
1467
1468
1469
1470
1471