Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(138)

Side by Side Diff: chromeos/drivers/ath6kl/os/linux/cfg80211.c

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

Powered by Google App Engine
This is Rietveld 408576698