3 * Copyright (c) 2004-2007 Atheros Communications Inc.
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;
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.
20 #include "ar6000_drv.h"
22 static A_UINT8 bcast_mac
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
23 static void ar6000_set_quality(struct iw_quality
*iq
, A_INT8 rssi
);
24 extern unsigned int wmitimeout
;
25 extern A_WAITQUEUE_HEAD arEvent
;
26 extern wait_queue_head_t ar6000_scan_queue
;
29 * Encode a WPA or RSN information element as a custom
30 * element using the hostap format.
33 encode_ie(void *buf
, size_t bufsize
,
34 const u_int8_t
*ie
, size_t ielen
,
35 const char *leader
, size_t leader_len
)
40 if (bufsize
< leader_len
)
43 memcpy(p
, leader
, leader_len
);
44 bufsize
-= leader_len
;
46 for (i
= 0; i
< ielen
&& bufsize
> 2; i
++)
47 p
+= sprintf(p
, "%02x", ie
[i
]);
48 return (i
== ielen
? p
- (u_int8_t
*)buf
: 0);
52 ar6000_scan_node(void *arg
, bss_t
*ni
)
58 struct ar_giwscan_param
*param
;
61 struct ieee80211_common_ie
*cie
;
62 struct iw_request_info info
;
67 param
= (struct ar_giwscan_param
*)arg
;
69 if (param
->current_ev
>= param
->end_buf
) {
72 if ((param
->firstPass
== TRUE
) &&
73 ((ni
->ni_cie
.ie_wpa
== NULL
) && (ni
->ni_cie
.ie_rsn
== NULL
))) {
75 * Only forward wpa bss's in first pass
80 if ((param
->firstPass
== FALSE
) &&
81 ((ni
->ni_cie
.ie_wpa
!= NULL
) || (ni
->ni_cie
.ie_rsn
!= NULL
))) {
83 * Only forward non-wpa bss's in 2nd pass
88 current_ev
= param
->current_ev
;
89 end_buf
= param
->end_buf
;
93 A_MEMZERO(&iwe
, sizeof(iwe
));
95 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
96 A_MEMCPY(iwe
.u
.ap_addr
.sa_data
, ni
->ni_macaddr
, 6);
97 current_ev
= iwe_stream_add_event(&info
, current_ev
, end_buf
, &iwe
,
100 A_MEMZERO(&iwe
, sizeof(iwe
));
101 iwe
.cmd
= SIOCGIWESSID
;
102 iwe
.u
.data
.flags
= 1;
103 iwe
.u
.data
.length
= cie
->ie_ssid
[1];
104 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
,
107 if (cie
->ie_capInfo
& (IEEE80211_CAPINFO_ESS
|IEEE80211_CAPINFO_IBSS
)) {
108 A_MEMZERO(&iwe
, sizeof(iwe
));
109 iwe
.cmd
= SIOCGIWMODE
;
110 iwe
.u
.mode
= cie
->ie_capInfo
& IEEE80211_CAPINFO_ESS
?
111 IW_MODE_MASTER
: IW_MODE_ADHOC
;
112 current_ev
= iwe_stream_add_event(&info
, current_ev
, end_buf
, &iwe
,
116 A_MEMZERO(&iwe
, sizeof(iwe
));
117 iwe
.cmd
= SIOCGIWFREQ
;
118 iwe
.u
.freq
.m
= cie
->ie_chan
* 100000;
120 current_ev
= iwe_stream_add_event(&info
, current_ev
, end_buf
, &iwe
,
123 A_MEMZERO(&iwe
, sizeof(iwe
));
125 ar6000_set_quality(&iwe
.u
.qual
, ni
->ni_snr
);
126 current_ev
= iwe_stream_add_event(&info
, current_ev
, end_buf
, &iwe
,
129 A_MEMZERO(&iwe
, sizeof(iwe
));
130 iwe
.cmd
= SIOCGIWENCODE
;
131 if (cie
->ie_capInfo
& IEEE80211_CAPINFO_PRIVACY
) {
132 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
134 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
136 iwe
.u
.data
.length
= 0;
137 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
, "");
139 A_MEMZERO(&iwe
, sizeof(iwe
));
140 iwe
.cmd
= IWEVCUSTOM
;
141 snprintf(buf
, sizeof(buf
), "bcn_int=%d", cie
->ie_beaconInt
);
142 iwe
.u
.data
.length
= strlen(buf
);
143 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
, buf
);
145 if (cie
->ie_wpa
!= NULL
) {
146 static const char wpa_leader
[] = "wpa_ie=";
148 A_MEMZERO(&iwe
, sizeof(iwe
));
149 iwe
.cmd
= IWEVCUSTOM
;
150 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wpa
,
152 wpa_leader
, sizeof(wpa_leader
)-1);
154 if (iwe
.u
.data
.length
!= 0) {
155 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
,
160 if (cie
->ie_rsn
!= NULL
&& cie
->ie_rsn
[0] == IEEE80211_ELEMID_RSN
) {
161 static const char rsn_leader
[] = "rsn_ie=";
163 A_MEMZERO(&iwe
, sizeof(iwe
));
164 iwe
.cmd
= IWEVCUSTOM
;
165 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_rsn
,
167 rsn_leader
, sizeof(rsn_leader
)-1);
169 if (iwe
.u
.data
.length
!= 0) {
170 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
,
175 if (cie
->ie_wmm
!= NULL
) {
176 static const char wmm_leader
[] = "wmm_ie=";
178 A_MEMZERO(&iwe
, sizeof(iwe
));
179 iwe
.cmd
= IWEVCUSTOM
;
180 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wmm
,
182 wmm_leader
, sizeof(wmm_leader
)-1);
183 if (iwe
.u
.data
.length
!= 0) {
184 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
,
189 if (cie
->ie_ath
!= NULL
) {
190 static const char ath_leader
[] = "ath_ie=";
192 A_MEMZERO(&iwe
, sizeof(iwe
));
193 iwe
.cmd
= IWEVCUSTOM
;
194 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_ath
,
196 ath_leader
, sizeof(ath_leader
)-1);
197 if (iwe
.u
.data
.length
!= 0) {
198 current_ev
= iwe_stream_add_point(&info
, current_ev
, end_buf
, &iwe
,
203 param
->current_ev
= current_ev
;
207 ar6000_ioctl_giwscan(struct net_device
*dev
,
208 struct iw_request_info
*info
,
209 struct iw_point
*data
, char *extra
)
211 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
212 struct ar_giwscan_param param
;
215 if (ar
->arWlanState
== WLAN_DISABLED
) {
219 if (ar
->arWmiReady
== FALSE
) {
223 param
.current_ev
= extra
;
224 param
.end_buf
= extra
+ IW_SCAN_MAX_DATA
;
225 param
.firstPass
= TRUE
;
228 * Do two passes to insure WPA scan candidates
229 * are sorted to the front. This is a hack to deal with
230 * the wireless extensions capping scan results at
231 * IW_SCAN_MAX_DATA bytes. In densely populated environments
232 * it's easy to overflow this buffer (especially with WPA/RSN
233 * information elements). Note this sorting hack does not
234 * guarantee we won't overflow anyway.
236 for (i
= 0; i
< 2; i
++) {
238 * Translate data to WE format.
240 wmi_iterate_nodes(ar
->arWmi
, ar6000_scan_node
, ¶m
);
241 param
.firstPass
= FALSE
;
242 if (param
.current_ev
>= param
.end_buf
) {
243 data
->length
= param
.current_ev
- extra
;
248 data
->length
= param
.current_ev
- extra
;
252 extern int reconnect_flag
;
255 ar6000_ioctl_siwessid(struct net_device
*dev
,
256 struct iw_request_info
*info
,
257 struct iw_point
*data
, char *ssid
)
259 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
261 A_UINT8 arNetworkType
;
263 if (ar
->arWlanState
== WLAN_DISABLED
) {
267 if (ar
->arWmiReady
== FALSE
) {
272 * iwconfig passes a string with length excluding any trailing NUL.
273 * FIXME: we should be able to set an ESSID of 32 bytes, yet things fall
274 * over badly if we do. So we limit the ESSID to 31 bytes.
276 if (data
->flags
&& (!data
->length
|| data
->length
>= sizeof(ar
->arSsid
))) {
282 /* Added for bug 25178, return an IOCTL error instead of target returning
283 Illegal parameter error when either the BSSID or channel is missing
284 and we cannot scan during connect.
287 if (ar
->arSkipScan
== TRUE
&&
288 (ar
->arChannelHint
== 0 ||
289 (!ar
->arReqBssid
[0] && !ar
->arReqBssid
[1] && !ar
->arReqBssid
[2] &&
290 !ar
->arReqBssid
[3] && !ar
->arReqBssid
[4] && !ar
->arReqBssid
[5])))
296 if (down_interruptible(&ar
->arSem
)) {
300 if (ar
->arTxPending
[WMI_CONTROL_PRI
]) {
302 * sleep until the command queue drains
304 wait_event_interruptible_timeout(arEvent
,
305 ar
->arTxPending
[WMI_CONTROL_PRI
] == 0, wmitimeout
* HZ
);
306 if (signal_pending(current
)) {
312 arNetworkType
= ar
->arNetworkType
;
313 ar6000_init_profile_info(ar
);
314 ar
->arNetworkType
= arNetworkType
;
318 * The original logic here prevented a disconnect if issuing an "essid off"
319 * if no ESSID was set, presumably to prevent sending multiple disconnects
322 * Unfortunately, this also meant that no disconnect was sent when we were
323 * already connected, but the profile has been changed since (which also
324 * clears the ESSID as a reminder that the WMI needs updating.)
326 * The "1 ||" makes sure we always disconnect or reconnect. The WMI doesn't
327 * seem to mind being sent multiple disconnects.
329 if (1 || (ar
->arSsidLen
) || (!data
->flags
))
331 if ((!data
->flags
) ||
332 (A_MEMCMP(ar
->arSsid
, ssid
, ar
->arSsidLen
) != 0) ||
333 (ar
->arSsidLen
!= (data
->length
)))
336 * SSID set previously or essid off has been issued.
338 * Disconnect Command is issued in two cases after wmi is ready
339 * (1) ssid is different from the previous setting
340 * (2) essid off has been issued
343 if (ar
->arWmiReady
== TRUE
) {
345 status
= wmi_disconnect_cmd(ar
->arWmi
);
346 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
348 if (ar
->arSkipScan
== FALSE
) {
349 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
362 * SSID is same, so we assume profile hasn't changed.
363 * If the interface is up and wmi is ready, we issue
364 * a reconnect cmd. Issue a reconnect only we are already
367 if((ar
->arConnected
== TRUE
) && (ar
->arWmiReady
== TRUE
))
369 reconnect_flag
= TRUE
;
370 status
= wmi_reconnect_cmd(ar
->arWmi
,ar
->arReqBssid
,
373 if (status
!= A_OK
) {
380 * Dont return if connect is pending.
382 if(!(ar
->arConnectPending
)) {
390 ar
->arSsidLen
= data
->length
;
391 A_MEMCPY(ar
->arSsid
, ssid
, ar
->arSsidLen
);
393 /* The ssid length check prevents second "essid off" from the user,
394 to be treated as a connect cmd. The second "essid off" is ignored.
396 if((ar
->arWmiReady
== TRUE
) && (ar
->arSsidLen
> 0) )
398 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
399 if (SHARED_AUTH
== ar
->arDot11AuthMode
) {
400 ar6000_install_static_wep_keys(ar
);
402 AR_DEBUG_PRINTF("Connect called with authmode %d dot11 auth %d"\
403 " PW crypto %d PW crypto Len %d GRP crypto %d"\
404 " GRP crypto Len %d\n",
405 ar
->arAuthMode
, ar
->arDot11AuthMode
,
406 ar
->arPairwiseCrypto
, ar
->arPairwiseCryptoLen
,
407 ar
->arGroupCrypto
, ar
->arGroupCryptoLen
);
409 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
410 status
= wmi_connect_cmd(ar
->arWmi
, ar
->arNetworkType
,
411 ar
->arDot11AuthMode
, ar
->arAuthMode
,
412 ar
->arPairwiseCrypto
, ar
->arPairwiseCryptoLen
,
413 ar
->arGroupCrypto
,ar
->arGroupCryptoLen
,
414 ar
->arSsidLen
, ar
->arSsid
,
415 ar
->arReqBssid
, ar
->arChannelHint
,
416 ar
->arConnectCtrlFlags
);
421 if (status
!= A_OK
) {
424 ar
->arConnectPending
= TRUE
;
433 ar6000_ioctl_giwessid(struct net_device
*dev
,
434 struct iw_request_info
*info
,
435 struct iw_point
*data
, char *essid
)
437 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
439 if (ar
->arWlanState
== WLAN_DISABLED
) {
444 data
->length
= ar
->arSsidLen
;
445 A_MEMCPY(essid
, ar
->arSsid
, ar
->arSsidLen
);
451 void ar6000_install_static_wep_keys(AR_SOFTC_T
*ar
)
456 for (index
= WMI_MIN_KEY_INDEX
; index
<= WMI_MAX_KEY_INDEX
; index
++) {
457 if (ar
->arWepKeyList
[index
].arKeyLen
) {
458 keyUsage
= GROUP_USAGE
;
459 if (index
== ar
->arDefTxKeyIndex
) {
460 keyUsage
|= TX_USAGE
;
462 wmi_addKey_cmd(ar
->arWmi
,
466 ar
->arWepKeyList
[index
].arKeyLen
,
468 ar
->arWepKeyList
[index
].arKey
, KEY_OP_INIT_VAL
,
475 ar6000_ioctl_delkey(struct net_device
*dev
, struct iw_request_info
*info
,
476 void *w
, char *extra
)
482 ar6000_ioctl_setmlme(struct net_device
*dev
, struct iw_request_info
*info
,
483 void *w
, char *extra
)
485 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
486 struct ieee80211req_mlme
*mlme
= (struct ieee80211req_mlme
*)extra
;
488 if ((ar
->arWmiReady
== FALSE
) || (ar
->arConnected
!= TRUE
))
491 switch (mlme
->im_op
) {
492 case IEEE80211_MLME_DISASSOC
:
493 case IEEE80211_MLME_DEAUTH
:
504 ar6000_ioctl_setwmmparams(struct net_device
*dev
, struct iw_request_info
*info
,
505 void *w
, char *extra
)
507 return -EIO
; /* for now */
511 ar6000_ioctl_getwmmparams(struct net_device
*dev
, struct iw_request_info
*info
,
512 void *w
, char *extra
)
514 return -EIO
; /* for now */
517 int ar6000_ioctl_setoptie(struct net_device
*dev
, struct iw_request_info
*info
,
518 struct iw_point
*data
, char *extra
)
520 /* The target generates the WPA/RSN IE */
525 ar6000_ioctl_setauthalg(struct net_device
*dev
, struct iw_request_info
*info
,
526 void *w
, char *extra
)
528 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
529 struct ieee80211req_authalg
*req
= (struct ieee80211req_authalg
*)extra
;
533 AR6000_SPIN_LOCK(&ar
->arLock
, 0);
535 if (req
->auth_alg
== AUTH_ALG_OPEN_SYSTEM
) {
536 ar
->arDot11AuthMode
= OPEN_AUTH
;
537 } else if (req
->auth_alg
== AUTH_ALG_LEAP
) {
538 ar
->arDot11AuthMode
= LEAP_AUTH
;
539 ar
->arPairwiseCrypto
= WEP_CRYPT
;
540 ar
->arGroupCrypto
= WEP_CRYPT
;
545 AR6000_SPIN_UNLOCK(&ar
->arLock
, 0);
550 ar6000_ioctl_addpmkid(struct net_device
*dev
, struct iw_request_info
*info
,
551 void *w
, char *extra
)
553 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
554 struct ieee80211req_addpmkid
*req
= (struct ieee80211req_addpmkid
*)extra
;
557 if (ar
->arWlanState
== WLAN_DISABLED
) {
561 AR_DEBUG_PRINTF("Add pmkid for %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x en=%d\n",
562 req
->pi_bssid
[0], req
->pi_bssid
[1], req
->pi_bssid
[2],
563 req
->pi_bssid
[3], req
->pi_bssid
[4], req
->pi_bssid
[5],
566 status
= wmi_setPmkid_cmd(ar
->arWmi
, req
->pi_bssid
, req
->pi_pmkid
,
569 if (status
!= A_OK
) {
580 ar6000_ioctl_siwrate(struct net_device
*dev
,
581 struct iw_request_info
*info
,
582 struct iw_param
*rrq
, char *extra
)
584 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
588 kbps
= rrq
->value
/ 1000; /* rrq->value is in bps */
590 kbps
= -1; /* -1 indicates auto rate */
592 if(kbps
!= -1 && wmi_validate_bitrate(ar
->arWmi
, kbps
) == A_EINVAL
)
594 AR_DEBUG_PRINTF("BitRate is not Valid %d\n", kbps
);
597 ar
->arBitRate
= kbps
;
598 if(ar
->arWmiReady
== TRUE
)
600 if (wmi_set_bitrate_cmd(ar
->arWmi
, kbps
) != A_OK
) {
611 ar6000_ioctl_giwrate(struct net_device
*dev
,
612 struct iw_request_info
*info
,
613 struct iw_param
*rrq
, char *extra
)
615 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
618 if (down_interruptible(&ar
->arSem
)) {
621 if(ar
->arWmiReady
== TRUE
)
623 ar
->arBitRate
= 0xFFFF;
624 if (wmi_get_bitrate_cmd(ar
->arWmi
) != A_OK
) {
628 wait_event_interruptible_timeout(arEvent
, ar
->arBitRate
!= 0xFFFF, wmitimeout
* HZ
);
629 if (signal_pending(current
)) {
633 /* If the interface is down or wmi is not ready or the target is not
634 connected - return the value stored in the device structure */
636 if (ar
->arBitRate
== -1) {
640 rrq
->value
= ar
->arBitRate
* 1000;
653 ar6000_ioctl_siwtxpow(struct net_device
*dev
,
654 struct iw_request_info
*info
,
655 struct iw_param
*rrq
, char *extra
)
657 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
660 if (ar
->arWlanState
== WLAN_DISABLED
) {
664 if (ar
->arRadioSwitch
== WLAN_ENABLED
666 if (wmi_switch_radio(ar
->arWmi
, WLAN_DISABLED
) < 0)
668 ar
->arRadioSwitch
= WLAN_DISABLED
;
669 } else if (ar
->arRadioSwitch
== WLAN_DISABLED
671 if (wmi_switch_radio(ar
->arWmi
, WLAN_ENABLED
) < 0)
673 ar
->arRadioSwitch
= WLAN_ENABLED
;
677 if (rrq
->flags
!= IW_TXPOW_DBM
) {
680 ar
->arTxPwr
= dbM
= rrq
->value
;
681 ar
->arTxPwrSet
= TRUE
;
683 ar
->arTxPwr
= dbM
= 0;
684 ar
->arTxPwrSet
= FALSE
;
686 if(ar
->arWmiReady
== TRUE
)
688 AR_DEBUG_PRINTF("Set tx pwr cmd %d dbM\n", dbM
);
689 wmi_set_txPwr_cmd(ar
->arWmi
, dbM
);
698 ar6000_ioctl_giwtxpow(struct net_device
*dev
,
699 struct iw_request_info
*info
,
700 struct iw_param
*rrq
, char *extra
)
702 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
705 if (ar
->arWlanState
== WLAN_DISABLED
) {
709 if (ar
->arRadioSwitch
== WLAN_DISABLED
) {
714 if (down_interruptible(&ar
->arSem
)) {
717 if((ar
->arWmiReady
== TRUE
) && (ar
->arConnected
== TRUE
))
721 if (wmi_get_txPwr_cmd(ar
->arWmi
) != A_OK
) {
726 wait_event_interruptible_timeout(arEvent
, ar
->arTxPwr
!= 0, wmitimeout
* HZ
);
728 if (signal_pending(current
)) {
732 /* If the interace is down or wmi is not ready or target is not connected
733 then return value stored in the device structure */
736 if (ar
->arTxPwrSet
== TRUE
) {
739 rrq
->value
= ar
->arTxPwr
;
740 rrq
->flags
= IW_TXPOW_DBM
;
750 * since iwconfig only provides us with one max retry value, we use it
751 * to apply to data frames of the BE traffic class.
754 ar6000_ioctl_siwretry(struct net_device
*dev
,
755 struct iw_request_info
*info
,
756 struct iw_param
*rrq
, char *extra
)
758 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
760 if (ar
->arWlanState
== WLAN_DISABLED
) {
768 if ((rrq
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
) {
772 if ( !(rrq
->value
>= WMI_MIN_RETRIES
) || !(rrq
->value
<= WMI_MAX_RETRIES
)) {
775 if(ar
->arWmiReady
== TRUE
)
777 if (wmi_set_retry_limits_cmd(ar
->arWmi
, DATA_FRAMETYPE
, WMM_AC_BE
,
778 rrq
->value
, 0) != A_OK
){
782 ar
->arMaxRetries
= rrq
->value
;
790 ar6000_ioctl_giwretry(struct net_device
*dev
,
791 struct iw_request_info
*info
,
792 struct iw_param
*rrq
, char *extra
)
794 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
796 if (ar
->arWlanState
== WLAN_DISABLED
) {
801 switch (rrq
->flags
& IW_RETRY_TYPE
) {
802 case IW_RETRY_LIFETIME
:
806 rrq
->flags
= IW_RETRY_LIMIT
;
807 switch (rrq
->flags
& IW_RETRY_MODIFIER
) {
809 rrq
->flags
|= IW_RETRY_MIN
;
810 rrq
->value
= WMI_MIN_RETRIES
;
813 rrq
->flags
|= IW_RETRY_MAX
;
814 rrq
->value
= ar
->arMaxRetries
;
826 ar6000_ioctl_siwencode(struct net_device
*dev
,
827 struct iw_request_info
*info
,
828 struct iw_point
*erq
, char *keybuf
)
830 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
832 A_INT32 auth
= ar
->arDot11AuthMode
;
834 if (ar
->arWlanState
== WLAN_DISABLED
) {
838 index
= erq
->flags
& IW_ENCODE_INDEX
;
840 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
841 ((index
- 1) > WMI_MAX_KEY_INDEX
)))
846 if (erq
->flags
& IW_ENCODE_DISABLED
) {
848 * Encryption disabled
852 * If key index was specified then clear the specified key
855 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
856 sizeof(ar
->arWepKeyList
[index
].arKey
));
857 ar
->arWepKeyList
[index
].arKeyLen
= 0;
859 ar
->arDot11AuthMode
= OPEN_AUTH
;
860 ar
->arPairwiseCrypto
= NONE_CRYPT
;
861 ar
->arGroupCrypto
= NONE_CRYPT
;
862 ar
->arAuthMode
= NONE_AUTH
;
865 * Enabling WEP encryption
868 index
--; /* keyindex is off base 1 in iwconfig */
871 if (erq
->flags
& IW_ENCODE_OPEN
) {
873 } else if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
878 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq
->length
)) {
882 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
883 sizeof(ar
->arWepKeyList
[index
].arKey
));
884 A_MEMCPY(ar
->arWepKeyList
[index
].arKey
, keybuf
, erq
->length
);
885 ar
->arWepKeyList
[index
].arKeyLen
= erq
->length
;
887 if (ar
->arWepKeyList
[index
].arKeyLen
== 0) {
890 ar
->arDefTxKeyIndex
= index
;
893 ar
->arPairwiseCrypto
= WEP_CRYPT
;
894 ar
->arGroupCrypto
= WEP_CRYPT
;
895 ar
->arDot11AuthMode
= auth
;
896 ar
->arAuthMode
= NONE_AUTH
;
900 * profile has changed. Erase ssid to signal change
902 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
909 ar6000_ioctl_giwencode(struct net_device
*dev
,
910 struct iw_request_info
*info
,
911 struct iw_point
*erq
, char *key
)
913 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
915 struct ar_wep_key
*wk
;
917 if (ar
->arWlanState
== WLAN_DISABLED
) {
921 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
923 erq
->flags
= IW_ENCODE_DISABLED
;
925 /* get the keyIndex */
926 keyIndex
= erq
->flags
& IW_ENCODE_INDEX
;
928 keyIndex
= ar
->arDefTxKeyIndex
;
929 } else if ((keyIndex
- 1 < WMI_MIN_KEY_INDEX
) ||
930 (keyIndex
- 1 > WMI_MAX_KEY_INDEX
))
932 keyIndex
= WMI_MIN_KEY_INDEX
;
936 erq
->flags
= keyIndex
+ 1;
937 erq
->flags
|= IW_ENCODE_ENABLED
;
938 wk
= &ar
->arWepKeyList
[keyIndex
];
939 if (erq
->length
> wk
->arKeyLen
) {
940 erq
->length
= wk
->arKeyLen
;
943 A_MEMCPY(key
, wk
->arKey
, erq
->length
);
945 if (ar
->arDot11AuthMode
== OPEN_AUTH
) {
946 erq
->flags
|= IW_ENCODE_OPEN
;
947 } else if (ar
->arDot11AuthMode
== SHARED_AUTH
) {
948 erq
->flags
|= IW_ENCODE_RESTRICTED
;
955 static int ar6000_ioctl_siwpower(struct net_device
*dev
,
956 struct iw_request_info
*info
,
957 union iwreq_data
*wrqu
, char *extra
)
959 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
960 WMI_POWER_MODE power_mode
;
962 if (wrqu
->power
.disabled
)
963 power_mode
= MAX_PERF_POWER
;
965 power_mode
= REC_POWER
;
967 if (wmi_powermode_cmd(ar
->arWmi
, power_mode
) < 0)
973 static int ar6000_ioctl_giwpower(struct net_device
*dev
,
974 struct iw_request_info
*info
,
975 union iwreq_data
*wrqu
, char *extra
)
977 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
981 * https://docs.openmoko.org/trac/ticket/2267
982 * When starting wpa_supplicant the kernel oopses.
983 * The following condition avoids the oops.
984 * Remove this comment to bless this solution.
986 if (ar
->arWlanState
== WLAN_DISABLED
|| ar
->arWmiReady
== FALSE
)
989 return wmi_get_power_mode_cmd(ar
->arWmi
);
992 static int ar6000_ioctl_siwgenie(struct net_device
*dev
,
993 struct iw_request_info
*info
,
994 struct iw_point
*dwrq
,
997 /* The target does that for us */
1001 static int ar6000_ioctl_giwgenie(struct net_device
*dev
,
1002 struct iw_request_info
*info
,
1003 struct iw_point
*dwrq
,
1009 static int ar6000_ioctl_siwauth(struct net_device
*dev
,
1010 struct iw_request_info
*info
,
1011 struct iw_param
*param
,
1014 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1017 switch (param
->flags
& IW_AUTH_INDEX
) {
1018 case IW_AUTH_WPA_VERSION
:
1019 if (param
->value
& IW_AUTH_WPA_VERSION_DISABLED
) {
1020 ar
->arAuthMode
= NONE_AUTH
;
1022 if (param
->value
& IW_AUTH_WPA_VERSION_WPA
) {
1023 ar
->arAuthMode
= WPA_AUTH
;
1025 if (param
->value
& IW_AUTH_WPA_VERSION_WPA2
) {
1026 ar
->arAuthMode
= WPA2_AUTH
;
1031 case IW_AUTH_CIPHER_PAIRWISE
:
1032 if (param
->value
& IW_AUTH_CIPHER_NONE
) {
1033 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1035 if (param
->value
& IW_AUTH_CIPHER_WEP40
) {
1036 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1038 if (param
->value
& IW_AUTH_CIPHER_TKIP
) {
1039 ar
->arPairwiseCrypto
= TKIP_CRYPT
;
1041 if (param
->value
& IW_AUTH_CIPHER_CCMP
) {
1042 ar
->arPairwiseCrypto
= AES_CRYPT
;
1047 case IW_AUTH_CIPHER_GROUP
:
1048 if (param
->value
& IW_AUTH_CIPHER_NONE
) {
1049 ar
->arGroupCrypto
= NONE_CRYPT
;
1051 if (param
->value
& IW_AUTH_CIPHER_WEP40
) {
1052 ar
->arGroupCrypto
= WEP_CRYPT
;
1054 if (param
->value
& IW_AUTH_CIPHER_TKIP
) {
1055 ar
->arGroupCrypto
= TKIP_CRYPT
;
1057 if (param
->value
& IW_AUTH_CIPHER_CCMP
) {
1058 ar
->arGroupCrypto
= AES_CRYPT
;
1063 case IW_AUTH_KEY_MGMT
:
1064 if (param
->value
& IW_AUTH_KEY_MGMT_PSK
) {
1065 if (ar
->arAuthMode
== WPA_AUTH
) {
1066 ar
->arAuthMode
= WPA_PSK_AUTH
;
1067 } else if (ar
->arAuthMode
== WPA2_AUTH
) {
1068 ar
->arAuthMode
= WPA2_PSK_AUTH
;
1075 case IW_AUTH_TKIP_COUNTERMEASURES
:
1076 if (ar
->arWmiReady
== FALSE
) {
1079 wmi_set_tkip_countermeasures_cmd(ar
->arWmi
, param
->value
);
1082 case IW_AUTH_DROP_UNENCRYPTED
:
1085 case IW_AUTH_80211_AUTH_ALG
:
1086 if (param
->value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
1087 ar
->arDot11AuthMode
= OPEN_AUTH
;
1089 if (param
->value
& IW_AUTH_ALG_SHARED_KEY
) {
1090 ar
->arDot11AuthMode
= SHARED_AUTH
;
1092 if (param
->value
& IW_AUTH_ALG_LEAP
) {
1093 ar
->arDot11AuthMode
= LEAP_AUTH
;
1094 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1095 ar
->arGroupCrypto
= WEP_CRYPT
;
1101 case IW_AUTH_WPA_ENABLED
:
1105 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1108 case IW_AUTH_PRIVACY_INVOKED
:
1112 printk("%s(): Unknown flag 0x%x\n", __FUNCTION__
, param
->flags
);
1117 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1124 static int ar6000_ioctl_giwauth(struct net_device
*dev
,
1125 struct iw_request_info
*info
,
1126 struct iw_param
*dwrq
,
1132 static int ar6000_ioctl_siwencodeext(struct net_device
*dev
,
1133 struct iw_request_info
*info
,
1134 union iwreq_data
*wrqu
,
1137 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1138 struct iw_point
*encoding
= &wrqu
->encoding
;
1139 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1140 int alg
= ext
->alg
, idx
;
1142 if (ar
->arWlanState
== WLAN_DISABLED
) {
1146 /* Determine and validate the key index */
1147 idx
= (encoding
->flags
& IW_ENCODE_INDEX
) - 1;
1149 if (idx
< 0 || idx
> 3)
1153 if ((alg
== IW_ENCODE_ALG_TKIP
) || (alg
== IW_ENCODE_ALG_CCMP
)) {
1154 struct ieee80211req_key ik
;
1155 KEY_USAGE key_usage
;
1156 CRYPTO_TYPE key_type
= NONE_CRYPT
;
1159 ar
->user_saved_keys
.keyOk
= FALSE
;
1161 if (alg
== IW_ENCODE_ALG_TKIP
) {
1162 key_type
= TKIP_CRYPT
;
1163 ik
.ik_type
= IEEE80211_CIPHER_TKIP
;
1165 key_type
= AES_CRYPT
;
1166 ik
.ik_type
= IEEE80211_CIPHER_AES_CCM
;
1170 ik
.ik_keylen
= ext
->key_len
;
1171 ik
.ik_flags
= IEEE80211_KEY_RECV
;
1172 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
1173 ik
.ik_flags
|= IEEE80211_KEY_XMIT
1174 | IEEE80211_KEY_DEFAULT
;
1177 if (ext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
1178 memcpy(&ik
.ik_keyrsc
, ext
->rx_seq
, 8);
1181 memcpy(ik
.ik_keydata
, ext
->key
, ext
->key_len
);
1183 ar
->user_saved_keys
.keyType
= key_type
;
1184 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1185 key_usage
= GROUP_USAGE
;
1186 memset(ik
.ik_macaddr
, 0, ETH_ALEN
);
1187 memcpy(&ar
->user_saved_keys
.bcast_ik
, &ik
,
1188 sizeof(struct ieee80211req_key
));
1190 key_usage
= PAIRWISE_USAGE
;
1191 memcpy(ik
.ik_macaddr
, ext
->addr
.sa_data
, ETH_ALEN
);
1192 memcpy(&ar
->user_saved_keys
.ucast_ik
, &ik
,
1193 sizeof(struct ieee80211req_key
));
1196 status
= wmi_addKey_cmd(ar
->arWmi
, ik
.ik_keyix
, key_type
,
1197 key_usage
, ik
.ik_keylen
,
1198 (A_UINT8
*)&ik
.ik_keyrsc
,
1200 KEY_OP_INIT_VAL
, SYNC_BEFORE_WMIFLAG
);
1205 ar
->user_saved_keys
.keyOk
= TRUE
;
1210 /* WEP falls back to SIWENCODE */
1218 static int ar6000_ioctl_giwencodeext(struct net_device
*dev
,
1219 struct iw_request_info
*info
,
1220 struct iw_point
*dwrq
,
1228 ar6000_ioctl_setparam(struct net_device
*dev
,
1229 struct iw_request_info
*info
,
1230 void *erq
, char *extra
)
1232 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1233 int *i
= (int *)extra
;
1237 A_BOOL profChanged
= FALSE
;
1239 if (ar
->arWlanState
== WLAN_DISABLED
) {
1244 case IEEE80211_PARAM_WPA
:
1247 ar
->arAuthMode
= WPA_AUTH
;
1251 ar
->arAuthMode
= WPA2_AUTH
;
1255 ar
->arAuthMode
= NONE_AUTH
;
1259 printk("IEEE80211_PARAM_WPA: Unknown value %d\n", value
);
1262 case IEEE80211_PARAM_AUTHMODE
:
1264 case IEEE80211_AUTH_WPA_PSK
:
1265 if (WPA_AUTH
== ar
->arAuthMode
) {
1266 ar
->arAuthMode
= WPA_PSK_AUTH
;
1268 } else if (WPA2_AUTH
== ar
->arAuthMode
) {
1269 ar
->arAuthMode
= WPA2_PSK_AUTH
;
1272 AR_DEBUG_PRINTF("Error - Setting PSK mode when WPA "\
1273 "param was set to %d\n",
1278 case IEEE80211_AUTH_WPA_CCKM
:
1279 if (WPA2_AUTH
== ar
->arAuthMode
) {
1280 ar
->arAuthMode
= WPA2_AUTH_CCKM
;
1282 ar
->arAuthMode
= WPA_AUTH_CCKM
;
1289 case IEEE80211_PARAM_UCASTCIPHER
:
1291 case IEEE80211_CIPHER_AES_CCM
:
1292 ar
->arPairwiseCrypto
= AES_CRYPT
;
1295 case IEEE80211_CIPHER_TKIP
:
1296 ar
->arPairwiseCrypto
= TKIP_CRYPT
;
1299 case IEEE80211_CIPHER_WEP
:
1300 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1303 case IEEE80211_CIPHER_NONE
:
1304 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1309 case IEEE80211_PARAM_UCASTKEYLEN
:
1310 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value
)) {
1313 ar
->arPairwiseCryptoLen
= value
;
1316 case IEEE80211_PARAM_MCASTCIPHER
:
1318 case IEEE80211_CIPHER_AES_CCM
:
1319 ar
->arGroupCrypto
= AES_CRYPT
;
1322 case IEEE80211_CIPHER_TKIP
:
1323 ar
->arGroupCrypto
= TKIP_CRYPT
;
1326 case IEEE80211_CIPHER_WEP
:
1327 ar
->arGroupCrypto
= WEP_CRYPT
;
1330 case IEEE80211_CIPHER_NONE
:
1331 ar
->arGroupCrypto
= NONE_CRYPT
;
1336 case IEEE80211_PARAM_MCASTKEYLEN
:
1337 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(value
)) {
1340 ar
->arGroupCryptoLen
= value
;
1343 case IEEE80211_PARAM_COUNTERMEASURES
:
1344 if (ar
->arWmiReady
== FALSE
) {
1347 wmi_set_tkip_countermeasures_cmd(ar
->arWmi
, value
);
1353 if (profChanged
== TRUE
) {
1355 * profile has changed. Erase ssid to signal change
1357 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1365 ar6000_ioctl_getparam(struct net_device
*dev
, struct iw_request_info
*info
,
1366 void *w
, char *extra
)
1368 return -EIO
; /* for now */
1372 ar6000_ioctl_setkey(struct net_device
*dev
, struct iw_request_info
*info
,
1373 void *w
, char *extra
)
1375 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1376 struct ieee80211req_key
*ik
= (struct ieee80211req_key
*)extra
;
1379 CRYPTO_TYPE keyType
= NONE_CRYPT
;
1381 if (ar
->arWlanState
== WLAN_DISABLED
) {
1385 ar
->user_saved_keys
.keyOk
= FALSE
;
1387 if ( 0 == memcmp(ik
->ik_macaddr
, "\x00\x00\x00\x00\x00\x00",
1388 IEEE80211_ADDR_LEN
)) {
1389 keyUsage
= GROUP_USAGE
;
1390 A_MEMCPY(&ar
->user_saved_keys
.bcast_ik
, ik
,
1391 sizeof(struct ieee80211req_key
));
1393 keyUsage
= PAIRWISE_USAGE
;
1394 A_MEMCPY(&ar
->user_saved_keys
.ucast_ik
, ik
,
1395 sizeof(struct ieee80211req_key
));
1398 switch (ik
->ik_type
) {
1399 case IEEE80211_CIPHER_WEP
:
1400 keyType
= WEP_CRYPT
;
1402 case IEEE80211_CIPHER_TKIP
:
1403 keyType
= TKIP_CRYPT
;
1405 case IEEE80211_CIPHER_AES_CCM
:
1406 keyType
= AES_CRYPT
;
1411 ar
->user_saved_keys
.keyType
= keyType
;
1413 if (IEEE80211_CIPHER_CCKM_KRK
!= ik
->ik_type
) {
1414 if (NONE_CRYPT
== keyType
) {
1418 status
= wmi_addKey_cmd(ar
->arWmi
, ik
->ik_keyix
, keyType
, keyUsage
,
1419 ik
->ik_keylen
, (A_UINT8
*)&ik
->ik_keyrsc
,
1420 ik
->ik_keydata
, KEY_OP_INIT_VAL
,
1421 SYNC_BEFORE_WMIFLAG
);
1423 if (status
!= A_OK
) {
1427 status
= wmi_add_krk_cmd(ar
->arWmi
, ik
->ik_keydata
);
1430 ar
->user_saved_keys
.keyOk
= TRUE
;
1440 ar6000_ioctl_giwname(struct net_device
*dev
,
1441 struct iw_request_info
*info
,
1442 char *name
, char *extra
)
1444 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1446 if (ar
->arWlanState
== WLAN_DISABLED
) {
1450 switch (ar
->arPhyCapability
) {
1451 case (WMI_11A_CAPABILITY
):
1452 strncpy(name
, "AR6000 802.11a", IFNAMSIZ
);
1454 case (WMI_11G_CAPABILITY
):
1455 strncpy(name
, "AR6000 802.11g", IFNAMSIZ
);
1457 case (WMI_11AG_CAPABILITY
):
1458 strncpy(name
, "AR6000 802.11ag", IFNAMSIZ
);
1461 strncpy(name
, "AR6000 802.11", IFNAMSIZ
);
1472 ar6000_ioctl_siwfreq(struct net_device
*dev
,
1473 struct iw_request_info
*info
,
1474 struct iw_freq
*freq
, char *extra
)
1476 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1478 if (ar
->arWlanState
== WLAN_DISABLED
) {
1483 * We support limiting the channels via wmiconfig.
1485 * We use this command to configure the channel hint for the connect cmd
1486 * so it is possible the target will end up connecting to a different
1491 } else if (freq
->e
== 1) {
1492 ar
->arChannelHint
= freq
->m
/ 100000;
1494 ar
->arChannelHint
= wlan_ieee2freq(freq
->m
);
1497 A_PRINTF("channel hint set to %d\n", ar
->arChannelHint
);
1505 ar6000_ioctl_giwfreq(struct net_device
*dev
,
1506 struct iw_request_info
*info
,
1507 struct iw_freq
*freq
, char *extra
)
1509 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1511 if (ar
->arWlanState
== WLAN_DISABLED
) {
1515 if (ar
->arConnected
!= TRUE
) {
1519 freq
->m
= ar
->arBssChannel
* 100000;
1529 ar6000_ioctl_siwmode(struct net_device
*dev
,
1530 struct iw_request_info
*info
,
1531 __u32
*mode
, char *extra
)
1533 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1535 if (ar
->arWlanState
== WLAN_DISABLED
) {
1541 ar
->arNetworkType
= INFRA_NETWORK
;
1544 ar
->arNetworkType
= ADHOC_NETWORK
;
1557 ar6000_ioctl_giwmode(struct net_device
*dev
,
1558 struct iw_request_info
*info
,
1559 __u32
*mode
, char *extra
)
1561 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1563 if (ar
->arWlanState
== WLAN_DISABLED
) {
1567 switch (ar
->arNetworkType
) {
1569 *mode
= IW_MODE_INFRA
;
1572 *mode
= IW_MODE_ADHOC
;
1584 ar6000_ioctl_siwsens(struct net_device
*dev
,
1585 struct iw_request_info
*info
,
1586 struct iw_param
*sens
, char *extra
)
1595 ar6000_ioctl_giwsens(struct net_device
*dev
,
1596 struct iw_request_info
*info
,
1597 struct iw_param
*sens
, char *extra
)
1609 ar6000_ioctl_giwrange(struct net_device
*dev
,
1610 struct iw_request_info
*info
,
1611 struct iw_point
*data
, char *extra
)
1613 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1614 struct iw_range
*range
= (struct iw_range
*) extra
;
1617 if (ar
->arWmiReady
== FALSE
) {
1621 if (ar
->arWlanState
== WLAN_DISABLED
) {
1625 if (down_interruptible(&ar
->arSem
)) {
1626 return -ERESTARTSYS
;
1628 ar
->arNumChannels
= -1;
1629 A_MEMZERO(ar
->arChannelList
, sizeof (ar
->arChannelList
));
1631 if (wmi_get_channelList_cmd(ar
->arWmi
) != A_OK
) {
1636 wait_event_interruptible_timeout(arEvent
, ar
->arNumChannels
!= -1, wmitimeout
* HZ
);
1638 if (signal_pending(current
)) {
1643 data
->length
= sizeof(struct iw_range
);
1644 A_MEMZERO(range
, sizeof(struct iw_range
));
1646 range
->txpower_capa
= IW_TXPOW_DBM
;
1648 range
->min_pmp
= 1 * 1024;
1649 range
->max_pmp
= 65535 * 1024;
1650 range
->min_pmt
= 1 * 1024;
1651 range
->max_pmt
= 1000 * 1024;
1652 range
->pmp_flags
= IW_POWER_PERIOD
;
1653 range
->pmt_flags
= IW_POWER_TIMEOUT
;
1656 range
->we_version_compiled
= WIRELESS_EXT
;
1657 range
->we_version_source
= 13;
1659 range
->retry_capa
= IW_RETRY_LIMIT
;
1660 range
->retry_flags
= IW_RETRY_LIMIT
;
1661 range
->min_retry
= 0;
1662 range
->max_retry
= 255;
1664 range
->num_frequency
= range
->num_channels
= ar
->arNumChannels
;
1665 for (i
= 0; i
< ar
->arNumChannels
; i
++) {
1666 range
->freq
[i
].i
= wlan_freq2ieee(ar
->arChannelList
[i
]);
1667 range
->freq
[i
].m
= ar
->arChannelList
[i
] * 100000;
1668 range
->freq
[i
].e
= 1;
1670 * Linux supports max of 32 channels, bail out once you
1673 if (i
== IW_MAX_FREQUENCIES
) {
1678 /* Max quality is max field value minus noise floor */
1679 range
->max_qual
.qual
= 0xff - 161;
1682 * In order to use dBm measurements, 'level' must be lower
1683 * than any possible measurement (see iw_print_stats() in
1684 * wireless tools). It's unclear how this is meant to be
1685 * done, but setting zero in these values forces dBm and
1686 * the actual numbers are not used.
1688 range
->max_qual
.level
= 0;
1689 range
->max_qual
.noise
= 0;
1691 range
->sensitivity
= 3;
1693 range
->max_encoding_tokens
= 4;
1694 /* XXX query driver to find out supported key sizes */
1695 range
->num_encoding_sizes
= 3;
1696 range
->encoding_size
[0] = 5; /* 40-bit */
1697 range
->encoding_size
[1] = 13; /* 104-bit */
1698 range
->encoding_size
[2] = 16; /* 128-bit */
1700 range
->num_bitrates
= 0;
1702 /* estimated maximum TCP throughput values (bps) */
1703 range
->throughput
= 22000000;
1706 range
->max_rts
= 2347;
1707 range
->min_frag
= 256;
1708 range
->max_frag
= 2346;
1718 * This ioctl is used to set the desired bssid for the connect command.
1721 ar6000_ioctl_siwap(struct net_device
*dev
,
1722 struct iw_request_info
*info
,
1723 struct sockaddr
*ap_addr
, char *extra
)
1725 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1727 if (ar
->arWlanState
== WLAN_DISABLED
) {
1731 if (ap_addr
->sa_family
!= ARPHRD_ETHER
) {
1735 if (A_MEMCMP(&ap_addr
->sa_data
, bcast_mac
, AR6000_ETH_ADDR_LEN
) == 0) {
1736 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
1738 A_MEMCPY(ar
->arReqBssid
, &ap_addr
->sa_data
, sizeof(ar
->arReqBssid
));
1748 ar6000_ioctl_giwap(struct net_device
*dev
,
1749 struct iw_request_info
*info
,
1750 struct sockaddr
*ap_addr
, char *extra
)
1752 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1754 if (ar
->arWlanState
== WLAN_DISABLED
) {
1758 if (ar
->arConnected
!= TRUE
) {
1762 A_MEMCPY(&ap_addr
->sa_data
, ar
->arBssid
, sizeof(ar
->arBssid
));
1763 ap_addr
->sa_family
= ARPHRD_ETHER
;
1772 ar6000_ioctl_iwaplist(struct net_device
*dev
,
1773 struct iw_request_info
*info
,
1774 struct iw_point
*data
, char *extra
)
1776 return -EIO
; /* for now */
1783 ar6000_ioctl_siwscan(struct net_device
*dev
,
1784 struct iw_request_info
*info
,
1785 struct iw_point
*data
, char *extra
)
1787 #define ACT_DWELLTIME_DEFAULT 105
1788 #define HOME_TXDRAIN_TIME 100
1789 #define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
1790 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)netdev_priv(dev
);
1793 if (ar
->arWmiReady
== FALSE
) {
1797 if (ar
->arWlanState
== WLAN_DISABLED
) {
1801 /* We ask for everything from the target */
1802 if (wmi_bssfilter_cmd(ar
->arWmi
, ALL_BSS_FILTER
, 0) != A_OK
) {
1803 printk("Couldn't set filtering\n");
1807 if (wmi_startscan_cmd(ar
->arWmi
, WMI_LONG_SCAN
, FALSE
, FALSE
, \
1808 HOME_TXDRAIN_TIME
, SCAN_INT
) != A_OK
) {
1812 ar
->scan_complete
= 0;
1813 wait_event_interruptible_timeout(ar6000_scan_queue
, ar
->scan_complete
,
1816 if (wmi_bssfilter_cmd(ar
->arWmi
, NONE_BSS_FILTER
, 0) != A_OK
) {
1817 printk("Couldn't set filtering\n");
1822 #undef ACT_DWELLTIME_DEFAULT
1823 #undef HOME_TXDRAIN_TIME
1829 * Units are in db above the noise floor. That means the
1830 * rssi values reported in the tx/rx descriptors in the
1831 * driver are the SNR expressed in db.
1833 * If you assume that the noise floor is -95, which is an
1834 * excellent assumption 99.5 % of the time, then you can
1835 * derive the absolute signal level (i.e. -95 + rssi).
1836 * There are some other slight factors to take into account
1837 * depending on whether the rssi measurement is from 11b,
1838 * 11g, or 11a. These differences are at most 2db and
1839 * can be documented.
1841 * NB: various calculations are based on the orinoco/wavelan
1842 * drivers for compatibility
1845 ar6000_set_quality(struct iw_quality
*iq
, A_INT8 rssi
)
1853 /* NB: max is 94 because noise is hardcoded to 161 */
1857 iq
->noise
= 161; /* -95dBm */
1858 iq
->level
= iq
->noise
+ iq
->qual
;
1863 /* Structures to export the Wireless Handlers */
1864 static const iw_handler ath_handlers
[] = {
1865 (iw_handler
) NULL
, /* SIOCSIWCOMMIT */
1866 (iw_handler
) ar6000_ioctl_giwname
, /* SIOCGIWNAME */
1867 (iw_handler
) NULL
, /* SIOCSIWNWID */
1868 (iw_handler
) NULL
, /* SIOCGIWNWID */
1869 (iw_handler
) ar6000_ioctl_siwfreq
, /* SIOCSIWFREQ */
1870 (iw_handler
) ar6000_ioctl_giwfreq
, /* SIOCGIWFREQ */
1871 (iw_handler
) ar6000_ioctl_siwmode
, /* SIOCSIWMODE */
1872 (iw_handler
) ar6000_ioctl_giwmode
, /* SIOCGIWMODE */
1873 (iw_handler
) ar6000_ioctl_siwsens
, /* SIOCSIWSENS */
1874 (iw_handler
) ar6000_ioctl_giwsens
, /* SIOCGIWSENS */
1875 (iw_handler
) NULL
/* not _used */, /* SIOCSIWRANGE */
1876 (iw_handler
) ar6000_ioctl_giwrange
, /* SIOCGIWRANGE */
1877 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
1878 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
1879 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
1880 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
1881 (iw_handler
) NULL
, /* SIOCSIWSPY */
1882 (iw_handler
) NULL
, /* SIOCGIWSPY */
1883 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
1884 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
1885 (iw_handler
) ar6000_ioctl_siwap
, /* SIOCSIWAP */
1886 (iw_handler
) ar6000_ioctl_giwap
, /* SIOCGIWAP */
1887 (iw_handler
) NULL
, /* -- hole -- */
1888 (iw_handler
) ar6000_ioctl_iwaplist
, /* SIOCGIWAPLIST */
1889 (iw_handler
) ar6000_ioctl_siwscan
, /* SIOCSIWSCAN */
1890 (iw_handler
) ar6000_ioctl_giwscan
, /* SIOCGIWSCAN */
1891 (iw_handler
) ar6000_ioctl_siwessid
, /* SIOCSIWESSID */
1892 (iw_handler
) ar6000_ioctl_giwessid
, /* SIOCGIWESSID */
1893 (iw_handler
) NULL
, /* SIOCSIWNICKN */
1894 (iw_handler
) NULL
, /* SIOCGIWNICKN */
1895 (iw_handler
) NULL
, /* -- hole -- */
1896 (iw_handler
) NULL
, /* -- hole -- */
1897 (iw_handler
) ar6000_ioctl_siwrate
, /* SIOCSIWRATE */
1898 (iw_handler
) ar6000_ioctl_giwrate
, /* SIOCGIWRATE */
1899 (iw_handler
) NULL
, /* SIOCSIWRTS */
1900 (iw_handler
) NULL
, /* SIOCGIWRTS */
1901 (iw_handler
) NULL
, /* SIOCSIWFRAG */
1902 (iw_handler
) NULL
, /* SIOCGIWFRAG */
1903 (iw_handler
) ar6000_ioctl_siwtxpow
, /* SIOCSIWTXPOW */
1904 (iw_handler
) ar6000_ioctl_giwtxpow
, /* SIOCGIWTXPOW */
1905 (iw_handler
) ar6000_ioctl_siwretry
, /* SIOCSIWRETRY */
1906 (iw_handler
) ar6000_ioctl_giwretry
, /* SIOCGIWRETRY */
1907 (iw_handler
) ar6000_ioctl_siwencode
, /* SIOCSIWENCODE */
1908 (iw_handler
) ar6000_ioctl_giwencode
, /* SIOCGIWENCODE */
1909 (iw_handler
) ar6000_ioctl_siwpower
, /* SIOCSIWPOWER */
1910 (iw_handler
) ar6000_ioctl_giwpower
, /* SIOCGIWPOWER */
1911 (iw_handler
) NULL
, /* -- hole -- */
1912 (iw_handler
) NULL
, /* -- hole -- */
1913 (iw_handler
) ar6000_ioctl_siwgenie
, /* SIOCSIWGENIE */
1914 (iw_handler
) ar6000_ioctl_giwgenie
, /* SIOCGIWGENIE */
1915 (iw_handler
) ar6000_ioctl_siwauth
, /* SIOCSIWAUTH */
1916 (iw_handler
) ar6000_ioctl_giwauth
, /* SIOCGIWAUTH */
1917 (iw_handler
) ar6000_ioctl_siwencodeext
,/* SIOCSIWENCODEEXT */
1918 (iw_handler
) ar6000_ioctl_giwencodeext
,/* SIOCGIWENCODEEXT */
1919 (iw_handler
) NULL
, /* SIOCSIWPMKSA */
1922 static const iw_handler ath_priv_handlers
[] = {
1923 (iw_handler
) ar6000_ioctl_setparam
, /* SIOCWFIRSTPRIV+0 */
1924 (iw_handler
) ar6000_ioctl_getparam
, /* SIOCWFIRSTPRIV+1 */
1925 (iw_handler
) ar6000_ioctl_setkey
, /* SIOCWFIRSTPRIV+2 */
1926 (iw_handler
) ar6000_ioctl_setwmmparams
, /* SIOCWFIRSTPRIV+3 */
1927 (iw_handler
) ar6000_ioctl_delkey
, /* SIOCWFIRSTPRIV+4 */
1928 (iw_handler
) ar6000_ioctl_getwmmparams
, /* SIOCWFIRSTPRIV+5 */
1929 (iw_handler
) ar6000_ioctl_setoptie
, /* SIOCWFIRSTPRIV+6 */
1930 (iw_handler
) ar6000_ioctl_setmlme
, /* SIOCWFIRSTPRIV+7 */
1931 (iw_handler
) ar6000_ioctl_addpmkid
, /* SIOCWFIRSTPRIV+8 */
1934 #define IW_PRIV_TYPE_KEY \
1935 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_key))
1936 #define IW_PRIV_TYPE_DELKEY \
1937 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_del_key))
1938 #define IW_PRIV_TYPE_MLME \
1939 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_mlme))
1940 #define IW_PRIV_TYPE_ADDPMKID \
1941 (IW_PRIV_TYPE_BYTE | sizeof(struct ieee80211req_addpmkid))
1943 static const struct iw_priv_args ar6000_priv_args
[] = {
1944 { IEEE80211_IOCTL_SETKEY
,
1945 IW_PRIV_TYPE_KEY
| IW_PRIV_SIZE_FIXED
, 0, "setkey"},
1946 { IEEE80211_IOCTL_DELKEY
,
1947 IW_PRIV_TYPE_DELKEY
| IW_PRIV_SIZE_FIXED
, 0, "delkey"},
1948 { IEEE80211_IOCTL_SETPARAM
,
1949 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2, 0, "setparam"},
1950 { IEEE80211_IOCTL_GETPARAM
,
1951 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
1952 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getparam"},
1953 { IEEE80211_IOCTL_SETWMMPARAMS
,
1954 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 4, 0, "setwmmparams"},
1955 { IEEE80211_IOCTL_GETWMMPARAMS
,
1956 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3,
1957 IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1, "getwmmparams"},
1958 { IEEE80211_IOCTL_SETOPTIE
,
1959 IW_PRIV_TYPE_BYTE
, 0, "setie"},
1960 { IEEE80211_IOCTL_SETMLME
,
1961 IW_PRIV_TYPE_MLME
, 0, "setmlme"},
1962 { IEEE80211_IOCTL_ADDPMKID
,
1963 IW_PRIV_TYPE_ADDPMKID
| IW_PRIV_SIZE_FIXED
, 0, "addpmkid"},
1966 void ar6000_ioctl_iwsetup(struct iw_handler_def
*def
)
1968 def
->private_args
= (struct iw_priv_args
*)ar6000_priv_args
;
1969 def
->num_private_args
= ARRAY_SIZE(ar6000_priv_args
);
1972 struct iw_handler_def ath_iw_handler_def
= {
1973 .standard
= (iw_handler
*)ath_handlers
,
1974 .num_standard
= ARRAY_SIZE(ath_handlers
),
1975 .private = (iw_handler
*)ath_priv_handlers
,
1976 .num_private
= ARRAY_SIZE(ath_priv_handlers
),