1 //------------------------------------------------------------------------------
2 // Copyright (c) 2004-2010 Atheros Communications Inc.
3 // All rights reserved.
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.
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.
21 // Author(s): ="Atheros"
22 //------------------------------------------------------------------------------
24 #include "ar6000_drv.h"
26 #define IWE_STREAM_ADD_EVENT(p1, p2, p3, p4, p5) \
27 iwe_stream_add_event((p1), (p2), (p3), (p4), (p5))
29 #define IWE_STREAM_ADD_POINT(p1, p2, p3, p4, p5) \
30 iwe_stream_add_point((p1), (p2), (p3), (p4), (p5))
32 #define IWE_STREAM_ADD_VALUE(p1, p2, p3, p4, p5, p6) \
33 iwe_stream_add_value((p1), (p2), (p3), (p4), (p5), (p6))
35 static void ar6000_set_quality(struct iw_quality
*iq
, A_INT8 rssi
);
36 extern unsigned int wmitimeout
;
37 extern A_WAITQUEUE_HEAD arEvent
;
41 * Encode a WPA or RSN information element as a custom
42 * element using the hostap format.
45 encode_ie(void *buf
, size_t bufsize
,
46 const u_int8_t
*ie
, size_t ielen
,
47 const char *leader
, size_t leader_len
)
52 if (bufsize
< leader_len
)
55 memcpy(p
, leader
, leader_len
);
56 bufsize
-= leader_len
;
58 for (i
= 0; i
< ielen
&& bufsize
> 2; i
++)
60 p
+= sprintf((char*)p
, "%02x", ie
[i
]);
63 return (i
== ielen
? p
- (u_int8_t
*)buf
: 0);
65 #endif /* WIRELESS_EXT > 14 */
68 get_bss_phy_capability(bss_t
*bss
)
70 A_UINT8 capability
= 0;
71 struct ieee80211_common_ie
*cie
= &bss
->ni_cie
;
72 #define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
73 if (CHAN_IS_11A(cie
->ie_chan
)) {
75 capability
= WMI_11NA_CAPABILITY
;
77 capability
= WMI_11A_CAPABILITY
;
79 } else if ((cie
->ie_erp
) || (cie
->ie_xrates
)) {
81 capability
= WMI_11NG_CAPABILITY
;
83 capability
= WMI_11G_CAPABILITY
;
90 ar6000_scan_node(void *arg
, bss_t
*ni
)
96 struct ar_giwscan_param
*param
;
99 struct ieee80211_common_ie
*cie
;
102 A_UINT32 rate_len
, data_len
= 0;
104 param
= (struct ar_giwscan_param
*)arg
;
106 current_ev
= param
->current_ev
;
107 end_buf
= param
->end_buf
;
111 if ((end_buf
- current_ev
) > IW_EV_ADDR_LEN
)
113 A_MEMZERO(&iwe
, sizeof(iwe
));
115 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
116 A_MEMCPY(iwe
.u
.ap_addr
.sa_data
, ni
->ni_macaddr
, 6);
117 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
118 &iwe
, IW_EV_ADDR_LEN
);
120 param
->bytes_needed
+= IW_EV_ADDR_LEN
;
122 data_len
= cie
->ie_ssid
[1] + IW_EV_POINT_LEN
;
123 if ((end_buf
- current_ev
) > data_len
)
125 A_MEMZERO(&iwe
, sizeof(iwe
));
126 iwe
.cmd
= SIOCGIWESSID
;
127 iwe
.u
.data
.flags
= 1;
128 iwe
.u
.data
.length
= cie
->ie_ssid
[1];
129 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
130 &iwe
, (char*)&cie
->ie_ssid
[2]);
132 param
->bytes_needed
+= data_len
;
134 if (cie
->ie_capInfo
& (IEEE80211_CAPINFO_ESS
|IEEE80211_CAPINFO_IBSS
)) {
135 if ((end_buf
- current_ev
) > IW_EV_UINT_LEN
)
137 A_MEMZERO(&iwe
, sizeof(iwe
));
138 iwe
.cmd
= SIOCGIWMODE
;
139 iwe
.u
.mode
= cie
->ie_capInfo
& IEEE80211_CAPINFO_ESS
?
140 IW_MODE_MASTER
: IW_MODE_ADHOC
;
141 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
142 &iwe
, IW_EV_UINT_LEN
);
144 param
->bytes_needed
+= IW_EV_UINT_LEN
;
147 if ((end_buf
- current_ev
) > IW_EV_FREQ_LEN
)
149 A_MEMZERO(&iwe
, sizeof(iwe
));
150 iwe
.cmd
= SIOCGIWFREQ
;
151 iwe
.u
.freq
.m
= cie
->ie_chan
* 100000;
153 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
154 &iwe
, IW_EV_FREQ_LEN
);
156 param
->bytes_needed
+= IW_EV_FREQ_LEN
;
158 if ((end_buf
- current_ev
) > IW_EV_QUAL_LEN
)
160 A_MEMZERO(&iwe
, sizeof(iwe
));
162 ar6000_set_quality(&iwe
.u
.qual
, ni
->ni_snr
);
163 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
164 &iwe
, IW_EV_QUAL_LEN
);
166 param
->bytes_needed
+= IW_EV_QUAL_LEN
;
168 if ((end_buf
- current_ev
) > IW_EV_POINT_LEN
)
170 A_MEMZERO(&iwe
, sizeof(iwe
));
171 iwe
.cmd
= SIOCGIWENCODE
;
172 if (cie
->ie_capInfo
& IEEE80211_CAPINFO_PRIVACY
) {
173 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
175 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
177 iwe
.u
.data
.length
= 0;
178 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
181 param
->bytes_needed
+= IW_EV_POINT_LEN
;
183 /* supported bit rate */
184 A_MEMZERO(&iwe
, sizeof(iwe
));
185 iwe
.cmd
= SIOCGIWRATE
;
186 iwe
.u
.bitrate
.fixed
= 0;
187 iwe
.u
.bitrate
.disabled
= 0;
188 iwe
.u
.bitrate
.value
= 0;
189 current_val
= current_ev
+ IW_EV_LCP_LEN
;
190 param
->bytes_needed
+= IW_EV_LCP_LEN
;
192 if (cie
->ie_rates
!= NULL
) {
193 rate_len
= cie
->ie_rates
[1];
194 data_len
= (rate_len
* (IW_EV_PARAM_LEN
- IW_EV_LCP_LEN
));
195 if ((end_buf
- current_ev
) > data_len
)
197 for (j
= 0; j
< rate_len
; j
++) {
199 val
= cie
->ie_rates
[2 + j
];
200 iwe
.u
.bitrate
.value
=
201 (val
>= 0x80)? ((val
- 0x80) * 500000): (val
* 500000);
202 current_val
= IWE_STREAM_ADD_VALUE(param
->info
, current_ev
,
203 current_val
, end_buf
,
204 &iwe
, IW_EV_PARAM_LEN
);
207 param
->bytes_needed
+= data_len
;
210 if (cie
->ie_xrates
!= NULL
) {
211 rate_len
= cie
->ie_xrates
[1];
212 data_len
= (rate_len
* (IW_EV_PARAM_LEN
- IW_EV_LCP_LEN
));
213 if ((end_buf
- current_ev
) > data_len
)
215 for (j
= 0; j
< rate_len
; j
++) {
217 val
= cie
->ie_xrates
[2 + j
];
218 iwe
.u
.bitrate
.value
=
219 (val
>= 0x80)? ((val
- 0x80) * 500000): (val
* 500000);
220 current_val
= IWE_STREAM_ADD_VALUE(param
->info
, current_ev
,
221 current_val
, end_buf
,
222 &iwe
, IW_EV_PARAM_LEN
);
225 param
->bytes_needed
+= data_len
;
227 /* remove fixed header if no rates were added */
228 if ((current_val
- current_ev
) > IW_EV_LCP_LEN
)
229 current_ev
= current_val
;
231 #if WIRELESS_EXT >= 18
233 if (cie
->ie_wpa
!= NULL
) {
234 data_len
= cie
->ie_wpa
[1] + 2 + IW_EV_POINT_LEN
;
235 if ((end_buf
- current_ev
) > data_len
)
237 A_MEMZERO(&iwe
, sizeof(iwe
));
239 iwe
.u
.data
.length
= cie
->ie_wpa
[1] + 2;
240 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
241 &iwe
, (char*)cie
->ie_wpa
);
243 param
->bytes_needed
+= data_len
;
246 if (cie
->ie_rsn
!= NULL
&& cie
->ie_rsn
[0] == IEEE80211_ELEMID_RSN
) {
247 data_len
= cie
->ie_rsn
[1] + 2 + IW_EV_POINT_LEN
;
248 if ((end_buf
- current_ev
) > data_len
)
250 A_MEMZERO(&iwe
, sizeof(iwe
));
252 iwe
.u
.data
.length
= cie
->ie_rsn
[1] + 2;
253 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
254 &iwe
, (char*)cie
->ie_rsn
);
256 param
->bytes_needed
+= data_len
;
259 #endif /* WIRELESS_EXT >= 18 */
261 if ((end_buf
- current_ev
) > IW_EV_CHAR_LEN
)
264 A_MEMZERO(&iwe
, sizeof(iwe
));
265 iwe
.cmd
= SIOCGIWNAME
;
266 switch (get_bss_phy_capability(ni
)) {
267 case WMI_11A_CAPABILITY
:
268 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11a");
270 case WMI_11G_CAPABILITY
:
271 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11g");
273 case WMI_11NA_CAPABILITY
:
274 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11na");
276 case WMI_11NG_CAPABILITY
:
277 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11ng");
280 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11b");
283 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
284 &iwe
, IW_EV_CHAR_LEN
);
286 param
->bytes_needed
+= IW_EV_CHAR_LEN
;
288 #if WIRELESS_EXT > 14
289 A_MEMZERO(&iwe
, sizeof(iwe
));
290 iwe
.cmd
= IWEVCUSTOM
;
291 iwe
.u
.data
.length
= snprintf(buf
, sizeof(buf
), "bcn_int=%d", cie
->ie_beaconInt
);
292 data_len
= iwe
.u
.data
.length
+ IW_EV_POINT_LEN
;
293 if ((end_buf
- current_ev
) > data_len
)
295 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
298 param
->bytes_needed
+= data_len
;
300 #if WIRELESS_EXT < 18
301 if (cie
->ie_wpa
!= NULL
) {
302 static const char wpa_leader
[] = "wpa_ie=";
303 data_len
= (sizeof(wpa_leader
) - 1) + ((cie
->ie_wpa
[1]+2) * 2) + IW_EV_POINT_LEN
;
304 if ((end_buf
- current_ev
) > data_len
)
306 A_MEMZERO(&iwe
, sizeof(iwe
));
307 iwe
.cmd
= IWEVCUSTOM
;
308 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wpa
,
310 wpa_leader
, sizeof(wpa_leader
)-1);
312 if (iwe
.u
.data
.length
!= 0) {
313 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
317 param
->bytes_needed
+= data_len
;
320 if (cie
->ie_rsn
!= NULL
&& cie
->ie_rsn
[0] == IEEE80211_ELEMID_RSN
) {
321 static const char rsn_leader
[] = "rsn_ie=";
322 data_len
= (sizeof(rsn_leader
) - 1) + ((cie
->ie_rsn
[1]+2) * 2) + IW_EV_POINT_LEN
;
323 if ((end_buf
- current_ev
) > data_len
)
325 A_MEMZERO(&iwe
, sizeof(iwe
));
326 iwe
.cmd
= IWEVCUSTOM
;
327 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_rsn
,
329 rsn_leader
, sizeof(rsn_leader
)-1);
331 if (iwe
.u
.data
.length
!= 0) {
332 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
336 param
->bytes_needed
+= data_len
;
338 #endif /* WIRELESS_EXT < 18 */
340 if (cie
->ie_wmm
!= NULL
) {
341 static const char wmm_leader
[] = "wmm_ie=";
342 data_len
= (sizeof(wmm_leader
) - 1) + ((cie
->ie_wmm
[1]+2) * 2) + IW_EV_POINT_LEN
;
343 if ((end_buf
- current_ev
) > data_len
)
345 A_MEMZERO(&iwe
, sizeof(iwe
));
346 iwe
.cmd
= IWEVCUSTOM
;
347 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wmm
,
349 wmm_leader
, sizeof(wmm_leader
)-1);
350 if (iwe
.u
.data
.length
!= 0) {
351 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
355 param
->bytes_needed
+= data_len
;
358 if (cie
->ie_ath
!= NULL
) {
359 static const char ath_leader
[] = "ath_ie=";
360 data_len
= (sizeof(ath_leader
) - 1) + ((cie
->ie_ath
[1]+2) * 2) + IW_EV_POINT_LEN
;
361 if ((end_buf
- current_ev
) > data_len
)
363 A_MEMZERO(&iwe
, sizeof(iwe
));
364 iwe
.cmd
= IWEVCUSTOM
;
365 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_ath
,
367 ath_leader
, sizeof(ath_leader
)-1);
368 if (iwe
.u
.data
.length
!= 0) {
369 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
373 param
->bytes_needed
+= data_len
;
377 if (cie
->ie_wapi
!= NULL
) {
378 static const char wapi_leader
[] = "wapi_ie=";
379 data_len
= (sizeof(wapi_leader
) - 1) + ((cie
->ie_wapi
[1] + 2) * 2) + IW_EV_POINT_LEN
;
380 if ((end_buf
- current_ev
) > data_len
) {
381 A_MEMZERO(&iwe
, sizeof(iwe
));
382 iwe
.cmd
= IWEVCUSTOM
;
383 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wapi
,
385 wapi_leader
, sizeof(wapi_leader
) - 1);
386 if (iwe
.u
.data
.length
!= 0) {
387 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
391 param
->bytes_needed
+= data_len
;
393 #endif /* WAPI_ENABLE */
395 #endif /* WIRELESS_EXT > 14 */
397 #if WIRELESS_EXT >= 18
398 if (cie
->ie_wsc
!= NULL
) {
399 data_len
= (cie
->ie_wsc
[1] + 2) + IW_EV_POINT_LEN
;
400 if ((end_buf
- current_ev
) > data_len
)
402 A_MEMZERO(&iwe
, sizeof(iwe
));
404 iwe
.u
.data
.length
= cie
->ie_wsc
[1] + 2;
405 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
406 &iwe
, (char*)cie
->ie_wsc
);
408 param
->bytes_needed
+= data_len
;
410 #endif /* WIRELESS_EXT >= 18 */
412 param
->current_ev
= current_ev
;
416 ar6000_ioctl_giwscan(struct net_device
*dev
,
417 struct iw_request_info
*info
,
418 struct iw_point
*data
, char *extra
)
420 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
421 struct ar_giwscan_param param
;
423 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
424 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
428 if (ar
->arWlanState
== WLAN_DISABLED
) {
432 if (ar
->arWmiReady
== FALSE
) {
436 param
.current_ev
= extra
;
437 param
.end_buf
= extra
+ data
->length
;
438 param
.bytes_needed
= 0;
441 /* Translate data to WE format */
442 wmi_iterate_nodes(ar
->arWmi
, ar6000_scan_node
, ¶m
);
444 /* check if bytes needed is greater than bytes consumed */
445 if (param
.bytes_needed
> (param
.current_ev
- extra
))
447 /* Request one byte more than needed, because when "data->length" equals bytes_needed,
448 it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
449 checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
450 data
->length
= param
.bytes_needed
+ 1;
458 extern int reconnect_flag
;
461 ar6000_ioctl_siwessid(struct net_device
*dev
,
462 struct iw_request_info
*info
,
463 struct iw_point
*data
, char *ssid
)
465 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
467 A_UINT8 arNetworkType
;
468 A_UINT8 prevMode
= ar
->arNetworkType
;
470 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
471 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
475 if (ar
->bIsDestroyProgress
) {
479 if (ar
->arWlanState
== WLAN_DISABLED
) {
483 if (ar
->arWmiReady
== FALSE
) {
487 #if defined(WIRELESS_EXT)
488 if (WIRELESS_EXT
>= 20) {
494 * iwconfig passes a null terminated string with length including this
495 * so we need to account for this
497 if (data
->flags
&& (!data
->length
|| (data
->length
== 1) ||
498 ((data
->length
- 1) > sizeof(ar
->arSsid
))))
506 if (ar
->arNextMode
== AP_NETWORK
) {
507 /* SSID change for AP network - Will take effect on commit */
508 if(A_MEMCMP(ar
->arSsid
,ssid
,32) != 0) {
509 ar
->arSsidLen
= data
->length
- 1;
510 A_MEMCPY(ar
->arSsid
, ssid
, ar
->arSsidLen
);
511 ar
->ap_profile_flag
= 1; /* There is a change in profile */
514 } else if(ar
->arNetworkType
== AP_NETWORK
) {
518 /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
519 for (ctr
=0; ctr
< AP_MAX_NUM_STA
; ctr
++) {
520 remove_sta(ar
, ar
->sta_list
[ctr
].mac
, 0);
522 A_MUTEX_LOCK(&ar
->mcastpsqLock
);
523 while (!A_NETBUF_QUEUE_EMPTY(&ar
->mcastpsq
)) {
524 skb
= A_NETBUF_DEQUEUE(&ar
->mcastpsq
);
527 A_MUTEX_UNLOCK(&ar
->mcastpsqLock
);
530 /* Added for bug 25178, return an IOCTL error instead of target returning
531 Illegal parameter error when either the BSSID or channel is missing
532 and we cannot scan during connect.
535 if (ar
->arSkipScan
== TRUE
&&
536 (ar
->arChannelHint
== 0 ||
537 (!ar
->arReqBssid
[0] && !ar
->arReqBssid
[1] && !ar
->arReqBssid
[2] &&
538 !ar
->arReqBssid
[3] && !ar
->arReqBssid
[4] && !ar
->arReqBssid
[5])))
544 if (down_interruptible(&ar
->arSem
)) {
548 if (ar
->bIsDestroyProgress
|| ar
->arWlanState
== WLAN_DISABLED
) {
553 if (ar
->arTxPending
[wmi_get_control_ep(ar
->arWmi
)]) {
555 * sleep until the command queue drains
557 wait_event_interruptible_timeout(arEvent
,
558 ar
->arTxPending
[wmi_get_control_ep(ar
->arWmi
)] == 0, wmitimeout
* HZ
);
559 if (signal_pending(current
)) {
565 arNetworkType
= ar
->arNetworkType
;
566 #ifdef ATH6K_CONFIG_CFG80211
567 if (ar
->arConnected
) {
568 #endif /* ATH6K_CONFIG_CFG80211 */
569 ar6000_init_profile_info(ar
);
570 #ifdef ATH6K_CONFIG_CFG80211
572 #endif /* ATH6K_CONFIG_CFG80211 */
573 ar
->arNetworkType
= arNetworkType
;
576 /* Update the arNetworkType */
577 ar
->arNetworkType
= ar
->arNextMode
;
580 if ((prevMode
!= AP_NETWORK
) &&
581 ((ar
->arSsidLen
) || ((ar
->arSsidLen
== 0) && ar
->arConnected
) || (!data
->flags
)))
583 if ((!data
->flags
) ||
584 (A_MEMCMP(ar
->arSsid
, ssid
, ar
->arSsidLen
) != 0) ||
585 (ar
->arSsidLen
!= (data
->length
- 1)))
588 * SSID set previously or essid off has been issued.
590 * Disconnect Command is issued in two cases after wmi is ready
591 * (1) ssid is different from the previous setting
592 * (2) essid off has been issued
595 if (ar
->arWmiReady
== TRUE
) {
597 status
= wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
598 status
= wmi_disconnect_cmd(ar
->arWmi
);
599 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
601 if (ar
->arSkipScan
== FALSE
) {
602 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
615 * SSID is same, so we assume profile hasn't changed.
616 * If the interface is up and wmi is ready, we issue
617 * a reconnect cmd. Issue a reconnect only we are already
620 if((ar
->arConnected
== TRUE
) && (ar
->arWmiReady
== TRUE
))
622 reconnect_flag
= TRUE
;
623 status
= wmi_reconnect_cmd(ar
->arWmi
,ar
->arReqBssid
,
626 if (status
!= A_OK
) {
633 * Dont return if connect is pending.
635 if(!(ar
->arConnectPending
)) {
643 ar
->arSsidLen
= data
->length
- 1;
644 A_MEMCPY(ar
->arSsid
, ssid
, ar
->arSsidLen
);
646 if (ar6000_connect_to_ap(ar
)!= A_OK
) {
657 ar6000_ioctl_giwessid(struct net_device
*dev
,
658 struct iw_request_info
*info
,
659 struct iw_point
*data
, char *essid
)
661 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
663 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
664 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
668 if (ar
->arWlanState
== WLAN_DISABLED
) {
672 if (!ar
->arSsidLen
) {
677 data
->length
= ar
->arSsidLen
;
678 A_MEMCPY(essid
, ar
->arSsid
, ar
->arSsidLen
);
684 void ar6000_install_static_wep_keys(AR_SOFTC_T
*ar
)
689 for (index
= WMI_MIN_KEY_INDEX
; index
<= WMI_MAX_KEY_INDEX
; index
++) {
690 if (ar
->arWepKeyList
[index
].arKeyLen
) {
691 keyUsage
= GROUP_USAGE
;
692 if (index
== ar
->arDefTxKeyIndex
) {
693 keyUsage
|= TX_USAGE
;
695 wmi_addKey_cmd(ar
->arWmi
,
699 ar
->arWepKeyList
[index
].arKeyLen
,
701 ar
->arWepKeyList
[index
].arKey
, KEY_OP_INIT_VAL
, NULL
,
711 ar6000_ioctl_siwrate(struct net_device
*dev
,
712 struct iw_request_info
*info
,
713 struct iw_param
*rrq
, char *extra
)
715 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
719 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
720 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
725 kbps
= rrq
->value
/ 1000; /* rrq->value is in bps */
727 kbps
= -1; /* -1 indicates auto rate */
729 if(kbps
!= -1 && wmi_validate_bitrate(ar
->arWmi
, kbps
, &rate_idx
) != A_OK
)
731 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("BitRate is not Valid %d\n", kbps
));
734 ar
->arBitRate
= kbps
;
735 if(ar
->arWmiReady
== TRUE
)
737 if (wmi_set_bitrate_cmd(ar
->arWmi
, kbps
, -1, -1) != A_OK
) {
748 ar6000_ioctl_giwrate(struct net_device
*dev
,
749 struct iw_request_info
*info
,
750 struct iw_param
*rrq
, char *extra
)
752 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
755 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
756 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
760 if (ar
->bIsDestroyProgress
) {
764 if (ar
->arWlanState
== WLAN_DISABLED
) {
768 if ((ar
->arNextMode
!= AP_NETWORK
&& !ar
->arConnected
) || ar
->arWmiReady
== FALSE
) {
769 rrq
->value
= 1000 * 1000;
773 if (down_interruptible(&ar
->arSem
)) {
777 if (ar
->bIsDestroyProgress
|| ar
->arWlanState
== WLAN_DISABLED
) {
782 ar
->arBitRate
= 0xFFFF;
783 if (wmi_get_bitrate_cmd(ar
->arWmi
) != A_OK
) {
787 wait_event_interruptible_timeout(arEvent
, ar
->arBitRate
!= 0xFFFF, wmitimeout
* HZ
);
788 if (signal_pending(current
)) {
791 /* If the interface is down or wmi is not ready or the target is not
792 connected - return the value stored in the device structure */
794 if (ar
->arBitRate
== -1) {
798 rrq
->value
= ar
->arBitRate
* 1000;
811 ar6000_ioctl_siwtxpow(struct net_device
*dev
,
812 struct iw_request_info
*info
,
813 struct iw_param
*rrq
, char *extra
)
815 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
818 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
819 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
823 if (ar
->arWlanState
== WLAN_DISABLED
) {
832 if (rrq
->flags
!= IW_TXPOW_DBM
) {
835 ar
->arTxPwr
= dbM
= rrq
->value
;
836 ar
->arTxPwrSet
= TRUE
;
838 ar
->arTxPwr
= dbM
= 0;
839 ar
->arTxPwrSet
= FALSE
;
841 if(ar
->arWmiReady
== TRUE
)
843 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX
,("Set tx pwr cmd %d dbM\n", dbM
));
844 wmi_set_txPwr_cmd(ar
->arWmi
, dbM
);
853 ar6000_ioctl_giwtxpow(struct net_device
*dev
,
854 struct iw_request_info
*info
,
855 struct iw_param
*rrq
, char *extra
)
857 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
860 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
861 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
865 if (ar
->bIsDestroyProgress
) {
869 if (ar
->arWlanState
== WLAN_DISABLED
) {
873 if (down_interruptible(&ar
->arSem
)) {
877 if (ar
->bIsDestroyProgress
) {
882 if((ar
->arWmiReady
== TRUE
) && (ar
->arConnected
== TRUE
))
886 if (wmi_get_txPwr_cmd(ar
->arWmi
) != A_OK
) {
891 wait_event_interruptible_timeout(arEvent
, ar
->arTxPwr
!= 0, wmitimeout
* HZ
);
893 if (signal_pending(current
)) {
897 /* If the interace is down or wmi is not ready or target is not connected
898 then return value stored in the device structure */
901 if (ar
->arTxPwrSet
== TRUE
) {
904 rrq
->value
= ar
->arTxPwr
;
905 rrq
->flags
= IW_TXPOW_DBM
;
907 // IWLIST need this flag to get TxPower
919 * since iwconfig only provides us with one max retry value, we use it
920 * to apply to data frames of the BE traffic class.
923 ar6000_ioctl_siwretry(struct net_device
*dev
,
924 struct iw_request_info
*info
,
925 struct iw_param
*rrq
, char *extra
)
927 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
929 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
930 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
934 if (ar
->arWlanState
== WLAN_DISABLED
) {
942 if ((rrq
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
) {
946 if ( !(rrq
->value
>= WMI_MIN_RETRIES
) || !(rrq
->value
<= WMI_MAX_RETRIES
)) {
949 if(ar
->arWmiReady
== TRUE
)
951 if (wmi_set_retry_limits_cmd(ar
->arWmi
, DATA_FRAMETYPE
, WMM_AC_BE
,
952 rrq
->value
, 0) != A_OK
){
956 ar
->arMaxRetries
= rrq
->value
;
964 ar6000_ioctl_giwretry(struct net_device
*dev
,
965 struct iw_request_info
*info
,
966 struct iw_param
*rrq
, char *extra
)
968 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
970 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
971 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
975 if (ar
->arWlanState
== WLAN_DISABLED
) {
980 switch (rrq
->flags
& IW_RETRY_TYPE
) {
981 case IW_RETRY_LIFETIME
:
985 rrq
->flags
= IW_RETRY_LIMIT
;
986 switch (rrq
->flags
& IW_RETRY_MODIFIER
) {
988 rrq
->flags
|= IW_RETRY_MIN
;
989 rrq
->value
= WMI_MIN_RETRIES
;
992 rrq
->flags
|= IW_RETRY_MAX
;
993 rrq
->value
= ar
->arMaxRetries
;
1005 ar6000_ioctl_siwencode(struct net_device
*dev
,
1006 struct iw_request_info
*info
,
1007 struct iw_point
*erq
, char *keybuf
)
1009 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1013 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1014 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1018 if(ar
->arNextMode
!= AP_NETWORK
) {
1020 * Static WEP Keys should be configured before setting the SSID
1022 if (ar
->arSsid
[0] && erq
->length
) {
1027 if (ar
->arWlanState
== WLAN_DISABLED
) {
1031 index
= erq
->flags
& IW_ENCODE_INDEX
;
1033 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1034 ((index
- 1) > WMI_MAX_KEY_INDEX
)))
1039 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1041 * Encryption disabled
1045 * If key index was specified then clear the specified key
1048 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1049 sizeof(ar
->arWepKeyList
[index
].arKey
));
1050 ar
->arWepKeyList
[index
].arKeyLen
= 0;
1052 ar
->arDot11AuthMode
= OPEN_AUTH
;
1053 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1054 ar
->arGroupCrypto
= NONE_CRYPT
;
1055 ar
->arAuthMode
= NONE_AUTH
;
1058 * Enabling WEP encryption
1061 index
--; /* keyindex is off base 1 in iwconfig */
1064 if (erq
->flags
& IW_ENCODE_OPEN
) {
1066 ar
->arDefTxKeyIndex
= index
;
1068 if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
1069 auth
|= SHARED_AUTH
;
1077 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq
->length
)) {
1081 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1082 sizeof(ar
->arWepKeyList
[index
].arKey
));
1083 A_MEMCPY(ar
->arWepKeyList
[index
].arKey
, keybuf
, erq
->length
);
1084 ar
->arWepKeyList
[index
].arKeyLen
= erq
->length
;
1085 ar
->arDot11AuthMode
= auth
;
1087 if (ar
->arWepKeyList
[index
].arKeyLen
== 0) {
1090 ar
->arDefTxKeyIndex
= index
;
1092 if(ar
->arSsidLen
&& ar
->arWepKeyList
[index
].arKeyLen
) {
1093 wmi_addKey_cmd(ar
->arWmi
,
1096 GROUP_USAGE
| TX_USAGE
,
1097 ar
->arWepKeyList
[index
].arKeyLen
,
1099 ar
->arWepKeyList
[index
].arKey
, KEY_OP_INIT_VAL
, NULL
,
1104 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1105 ar
->arGroupCrypto
= WEP_CRYPT
;
1106 ar
->arAuthMode
= NONE_AUTH
;
1109 if(ar
->arNextMode
!= AP_NETWORK
) {
1111 * profile has changed. Erase ssid to signal change
1113 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1116 ar
->ap_profile_flag
= 1; /* There is a change in profile */
1121 ar6000_ioctl_giwencode(struct net_device
*dev
,
1122 struct iw_request_info
*info
,
1123 struct iw_point
*erq
, char *key
)
1125 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1127 struct ar_wep_key
*wk
;
1129 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1130 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1134 if (ar
->arWlanState
== WLAN_DISABLED
) {
1138 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1140 erq
->flags
= IW_ENCODE_DISABLED
;
1142 if (ar
->arPairwiseCrypto
== WEP_CRYPT
) {
1143 /* get the keyIndex */
1144 keyIndex
= erq
->flags
& IW_ENCODE_INDEX
;
1145 if (0 == keyIndex
) {
1146 keyIndex
= ar
->arDefTxKeyIndex
;
1147 } else if ((keyIndex
- 1 < WMI_MIN_KEY_INDEX
) ||
1148 (keyIndex
- 1 > WMI_MAX_KEY_INDEX
))
1150 keyIndex
= WMI_MIN_KEY_INDEX
;
1154 erq
->flags
= keyIndex
+ 1;
1155 erq
->flags
&= ~IW_ENCODE_DISABLED
;
1156 wk
= &ar
->arWepKeyList
[keyIndex
];
1157 if (erq
->length
> wk
->arKeyLen
) {
1158 erq
->length
= wk
->arKeyLen
;
1161 A_MEMCPY(key
, wk
->arKey
, erq
->length
);
1164 erq
->flags
&= ~IW_ENCODE_DISABLED
;
1165 if (ar
->user_saved_keys
.keyOk
) {
1166 erq
->length
= ar
->user_saved_keys
.ucast_ik
.ik_keylen
;
1168 A_MEMCPY(key
, ar
->user_saved_keys
.ucast_ik
.ik_keydata
, erq
->length
);
1171 erq
->length
= 1; // not really printing any key but let iwconfig know enc is on
1175 if (ar
->arDot11AuthMode
& OPEN_AUTH
) {
1176 erq
->flags
|= IW_ENCODE_OPEN
;
1178 if (ar
->arDot11AuthMode
& SHARED_AUTH
) {
1179 erq
->flags
|= IW_ENCODE_RESTRICTED
;
1186 #if WIRELESS_EXT >= 18
1191 ar6000_ioctl_siwgenie(struct net_device
*dev
,
1192 struct iw_request_info
*info
,
1193 struct iw_point
*erq
, char *extra
)
1195 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1198 A_UINT8
*ie
= erq
->pointer
;
1199 A_UINT8 ie_type
= ie
[0];
1200 A_UINT16 ie_length
= erq
->length
;
1201 A_UINT8 wapi_ie
[128];
1204 if (ar
->arWmiReady
== FALSE
) {
1208 if (ie_type
== IEEE80211_ELEMID_WAPI
) {
1209 if (ie_length
> 0) {
1210 if (copy_from_user(wapi_ie
, ie
, ie_length
)) {
1214 wmi_set_appie_cmd(ar
->arWmi
, WMI_FRAME_ASSOC_REQ
, ie_length
, wapi_ie
);
1215 } else if (ie_length
== 0) {
1216 wmi_set_appie_cmd(ar
->arWmi
, WMI_FRAME_ASSOC_REQ
, ie_length
, wapi_ie
);
1227 ar6000_ioctl_giwgenie(struct net_device
*dev
,
1228 struct iw_request_info
*info
,
1229 struct iw_point
*erq
, char *extra
)
1231 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1233 if (ar
->arWmiReady
== FALSE
) {
1246 ar6000_ioctl_siwauth(struct net_device
*dev
,
1247 struct iw_request_info
*info
,
1248 struct iw_param
*data
, char *extra
)
1250 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1257 if (ar
->arWmiReady
== FALSE
) {
1261 if (ar
->arWlanState
== WLAN_DISABLED
) {
1265 param
= data
->flags
& IW_AUTH_INDEX
;
1266 value
= data
->value
;
1271 case IW_AUTH_WPA_VERSION
:
1272 if (value
& IW_AUTH_WPA_VERSION_DISABLED
) {
1273 ar
->arAuthMode
= NONE_AUTH
;
1274 } else if (value
& IW_AUTH_WPA_VERSION_WPA
) {
1275 ar
->arAuthMode
= WPA_AUTH
;
1276 } else if (value
& IW_AUTH_WPA_VERSION_WPA2
) {
1277 ar
->arAuthMode
= WPA2_AUTH
;
1280 profChanged
= FALSE
;
1283 case IW_AUTH_CIPHER_PAIRWISE
:
1284 if (value
& IW_AUTH_CIPHER_NONE
) {
1285 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1286 ar
->arPairwiseCryptoLen
= 0;
1287 } else if (value
& IW_AUTH_CIPHER_WEP40
) {
1288 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1289 ar
->arPairwiseCryptoLen
= 5;
1290 } else if (value
& IW_AUTH_CIPHER_TKIP
) {
1291 ar
->arPairwiseCrypto
= TKIP_CRYPT
;
1292 ar
->arPairwiseCryptoLen
= 0;
1293 } else if (value
& IW_AUTH_CIPHER_CCMP
) {
1294 ar
->arPairwiseCrypto
= AES_CRYPT
;
1295 ar
->arPairwiseCryptoLen
= 0;
1296 } else if (value
& IW_AUTH_CIPHER_WEP104
) {
1297 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1298 ar
->arPairwiseCryptoLen
= 13;
1301 profChanged
= FALSE
;
1304 case IW_AUTH_CIPHER_GROUP
:
1305 if (value
& IW_AUTH_CIPHER_NONE
) {
1306 ar
->arGroupCrypto
= NONE_CRYPT
;
1307 ar
->arGroupCryptoLen
= 0;
1308 } else if (value
& IW_AUTH_CIPHER_WEP40
) {
1309 ar
->arGroupCrypto
= WEP_CRYPT
;
1310 ar
->arGroupCryptoLen
= 5;
1311 } else if (value
& IW_AUTH_CIPHER_TKIP
) {
1312 ar
->arGroupCrypto
= TKIP_CRYPT
;
1313 ar
->arGroupCryptoLen
= 0;
1314 } else if (value
& IW_AUTH_CIPHER_CCMP
) {
1315 ar
->arGroupCrypto
= AES_CRYPT
;
1316 ar
->arGroupCryptoLen
= 0;
1317 } else if (value
& IW_AUTH_CIPHER_WEP104
) {
1318 ar
->arGroupCrypto
= WEP_CRYPT
;
1319 ar
->arGroupCryptoLen
= 13;
1322 profChanged
= FALSE
;
1325 case IW_AUTH_KEY_MGMT
:
1326 if (value
& IW_AUTH_KEY_MGMT_PSK
) {
1327 if (WPA_AUTH
== ar
->arAuthMode
) {
1328 ar
->arAuthMode
= WPA_PSK_AUTH
;
1329 } else if (WPA2_AUTH
== ar
->arAuthMode
) {
1330 ar
->arAuthMode
= WPA2_PSK_AUTH
;
1334 } else if (!(value
& IW_AUTH_KEY_MGMT_802_1X
)) {
1335 ar
->arAuthMode
= NONE_AUTH
;
1338 case IW_AUTH_TKIP_COUNTERMEASURES
:
1339 wmi_set_tkip_countermeasures_cmd(ar
->arWmi
, value
);
1340 profChanged
= FALSE
;
1342 case IW_AUTH_DROP_UNENCRYPTED
:
1343 profChanged
= FALSE
;
1345 case IW_AUTH_80211_AUTH_ALG
:
1346 ar
->arDot11AuthMode
= 0;
1347 if (value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
1348 ar
->arDot11AuthMode
|= OPEN_AUTH
;
1350 if (value
& IW_AUTH_ALG_SHARED_KEY
) {
1351 ar
->arDot11AuthMode
|= SHARED_AUTH
;
1353 if (value
& IW_AUTH_ALG_LEAP
) {
1354 ar
->arDot11AuthMode
= LEAP_AUTH
;
1356 if(ar
->arDot11AuthMode
== 0) {
1358 profChanged
= FALSE
;
1361 case IW_AUTH_WPA_ENABLED
:
1363 ar
->arAuthMode
= NONE_AUTH
;
1364 /* when the supplicant is stopped, it calls this
1365 * handler with value=0. The followings need to be
1366 * reset if the STA were to connect again
1369 ar
->arDot11AuthMode
= OPEN_AUTH
;
1370 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1371 ar
->arPairwiseCryptoLen
= 0;
1372 ar
->arGroupCrypto
= NONE_CRYPT
;
1373 ar
->arGroupCryptoLen
= 0;
1376 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1377 profChanged
= FALSE
;
1379 case IW_AUTH_ROAMING_CONTROL
:
1380 profChanged
= FALSE
;
1382 case IW_AUTH_PRIVACY_INVOKED
:
1384 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1385 ar
->arPairwiseCryptoLen
= 0;
1386 ar
->arGroupCrypto
= NONE_CRYPT
;
1387 ar
->arGroupCryptoLen
= 0;
1391 case IW_AUTH_WAPI_ENABLED
:
1392 ar
->arWapiEnable
= value
;
1397 profChanged
= FALSE
;
1401 if (profChanged
== TRUE
) {
1403 * profile has changed. Erase ssid to signal change
1405 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1417 ar6000_ioctl_giwauth(struct net_device
*dev
,
1418 struct iw_request_info
*info
,
1419 struct iw_param
*data
, char *extra
)
1421 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1425 if (ar
->arWmiReady
== FALSE
) {
1429 if (ar
->arWlanState
== WLAN_DISABLED
) {
1433 param
= data
->flags
& IW_AUTH_INDEX
;
1439 case IW_AUTH_WPA_VERSION
:
1440 if (ar
->arAuthMode
== NONE_AUTH
) {
1441 data
->value
|= IW_AUTH_WPA_VERSION_DISABLED
;
1442 } else if (ar
->arAuthMode
== WPA_AUTH
) {
1443 data
->value
|= IW_AUTH_WPA_VERSION_WPA
;
1444 } else if (ar
->arAuthMode
== WPA2_AUTH
) {
1445 data
->value
|= IW_AUTH_WPA_VERSION_WPA2
;
1450 case IW_AUTH_CIPHER_PAIRWISE
:
1451 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1452 data
->value
|= IW_AUTH_CIPHER_NONE
;
1453 } else if (ar
->arPairwiseCrypto
== WEP_CRYPT
) {
1454 if (ar
->arPairwiseCryptoLen
== 13) {
1455 data
->value
|= IW_AUTH_CIPHER_WEP104
;
1457 data
->value
|= IW_AUTH_CIPHER_WEP40
;
1459 } else if (ar
->arPairwiseCrypto
== TKIP_CRYPT
) {
1460 data
->value
|= IW_AUTH_CIPHER_TKIP
;
1461 } else if (ar
->arPairwiseCrypto
== AES_CRYPT
) {
1462 data
->value
|= IW_AUTH_CIPHER_CCMP
;
1467 case IW_AUTH_CIPHER_GROUP
:
1468 if (ar
->arGroupCrypto
== NONE_CRYPT
) {
1469 data
->value
|= IW_AUTH_CIPHER_NONE
;
1470 } else if (ar
->arGroupCrypto
== WEP_CRYPT
) {
1471 if (ar
->arGroupCryptoLen
== 13) {
1472 data
->value
|= IW_AUTH_CIPHER_WEP104
;
1474 data
->value
|= IW_AUTH_CIPHER_WEP40
;
1476 } else if (ar
->arGroupCrypto
== TKIP_CRYPT
) {
1477 data
->value
|= IW_AUTH_CIPHER_TKIP
;
1478 } else if (ar
->arGroupCrypto
== AES_CRYPT
) {
1479 data
->value
|= IW_AUTH_CIPHER_CCMP
;
1484 case IW_AUTH_KEY_MGMT
:
1485 if ((ar
->arAuthMode
== WPA_PSK_AUTH
) ||
1486 (ar
->arAuthMode
== WPA2_PSK_AUTH
)) {
1487 data
->value
|= IW_AUTH_KEY_MGMT_PSK
;
1488 } else if ((ar
->arAuthMode
== WPA_AUTH
) ||
1489 (ar
->arAuthMode
== WPA2_AUTH
)) {
1490 data
->value
|= IW_AUTH_KEY_MGMT_802_1X
;
1493 case IW_AUTH_TKIP_COUNTERMEASURES
:
1494 // TODO. Save countermeassure enable/disable
1497 case IW_AUTH_DROP_UNENCRYPTED
:
1499 case IW_AUTH_80211_AUTH_ALG
:
1500 if (ar
->arDot11AuthMode
== OPEN_AUTH
) {
1501 data
->value
|= IW_AUTH_ALG_OPEN_SYSTEM
;
1502 } else if (ar
->arDot11AuthMode
== SHARED_AUTH
) {
1503 data
->value
|= IW_AUTH_ALG_SHARED_KEY
;
1504 } else if (ar
->arDot11AuthMode
== LEAP_AUTH
) {
1505 data
->value
|= IW_AUTH_ALG_LEAP
;
1510 case IW_AUTH_WPA_ENABLED
:
1511 if (ar
->arAuthMode
== NONE_AUTH
) {
1517 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1519 case IW_AUTH_ROAMING_CONTROL
:
1521 case IW_AUTH_PRIVACY_INVOKED
:
1522 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1529 case IW_AUTH_WAPI_ENABLED
:
1530 data
->value
= ar
->arWapiEnable
;
1545 ar6000_ioctl_siwpmksa(struct net_device
*dev
,
1546 struct iw_request_info
*info
,
1547 struct iw_point
*data
, char *extra
)
1549 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1552 struct iw_pmksa
*pmksa
;
1554 pmksa
= (struct iw_pmksa
*)extra
;
1556 if (ar
->arWmiReady
== FALSE
) {
1563 switch (pmksa
->cmd
) {
1565 status
= wmi_setPmkid_cmd(ar
->arWmi
, (A_UINT8
*)pmksa
->bssid
.sa_data
, pmksa
->pmkid
, TRUE
);
1567 case IW_PMKSA_REMOVE
:
1568 status
= wmi_setPmkid_cmd(ar
->arWmi
, (A_UINT8
*)pmksa
->bssid
.sa_data
, pmksa
->pmkid
, FALSE
);
1570 case IW_PMKSA_FLUSH
:
1571 if (ar
->arConnected
== TRUE
) {
1572 status
= wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
1579 if (status
!= A_OK
) {
1588 #define PN_INIT 0x5c365c36
1590 static int ar6000_set_wapi_key(struct net_device
*dev
,
1591 struct iw_request_info
*info
,
1592 struct iw_point
*erq
, char *extra
)
1594 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1595 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1596 KEY_USAGE keyUsage
= 0;
1603 A_UINT8 wapiKeyRsc
[16];
1604 CRYPTO_TYPE keyType
= WAPI_CRYPT
;
1605 const A_UINT8 broadcastMac
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1607 index
= erq
->flags
& IW_ENCODE_INDEX
;
1608 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1609 ((index
- 1) > WMI_MAX_KEY_INDEX
))) {
1614 if (index
< 0 || index
> 4) {
1617 keyData
= (A_UINT8
*)(ext
+ 1);
1618 keyLen
= erq
->length
- sizeof(struct iw_encode_ext
);
1619 A_MEMCPY(wapiKeyRsc
, ext
->tx_seq
, sizeof(wapiKeyRsc
));
1621 if (A_MEMCMP(ext
->addr
.sa_data
, broadcastMac
, sizeof(broadcastMac
)) == 0) {
1622 keyUsage
|= GROUP_USAGE
;
1623 PN
= (A_UINT32
*)wapiKeyRsc
;
1624 for (i
= 0; i
< 4; i
++) {
1628 keyUsage
|= PAIRWISE_USAGE
;
1630 status
= wmi_addKey_cmd(ar
->arWmi
,
1639 SYNC_BEFORE_WMIFLAG
);
1640 if (A_OK
!= status
) {
1652 ar6000_ioctl_siwencodeext(struct net_device
*dev
,
1653 struct iw_request_info
*info
,
1654 struct iw_point
*erq
, char *extra
)
1656 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1658 struct iw_encode_ext
*ext
;
1664 CRYPTO_TYPE keyType
;
1666 struct ieee80211req_key ik
;
1667 #endif /* USER_KEYS */
1669 if (ar
->arWlanState
== WLAN_DISABLED
) {
1674 ar
->user_saved_keys
.keyOk
= FALSE
;
1675 #endif /* USER_KEYS */
1677 index
= erq
->flags
& IW_ENCODE_INDEX
;
1679 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1680 ((index
- 1) > WMI_MAX_KEY_INDEX
)))
1685 ext
= (struct iw_encode_ext
*)extra
;
1686 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1688 * Encryption disabled
1692 * If key index was specified then clear the specified key
1695 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1696 sizeof(ar
->arWepKeyList
[index
].arKey
));
1697 ar
->arWepKeyList
[index
].arKeyLen
= 0;
1701 * Enabling WEP encryption
1704 index
--; /* keyindex is off base 1 in iwconfig */
1708 keyLen
= erq
->length
- sizeof(struct iw_encode_ext
);
1710 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
1711 keyUsage
= TX_USAGE
;
1712 ar
->arDefTxKeyIndex
= index
;
1713 // Just setting the key index
1723 /* key follows iw_encode_ext */
1724 keyData
= (A_UINT8
*)(ext
+ 1);
1727 case IW_ENCODE_ALG_WEP
:
1728 keyType
= WEP_CRYPT
;
1730 ik
.ik_type
= IEEE80211_CIPHER_WEP
;
1731 #endif /* USER_KEYS */
1732 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen
)) {
1736 /* Check whether it is static wep. */
1737 if (!ar
->arConnected
) {
1738 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1739 sizeof(ar
->arWepKeyList
[index
].arKey
));
1740 A_MEMCPY(ar
->arWepKeyList
[index
].arKey
, keyData
, keyLen
);
1741 ar
->arWepKeyList
[index
].arKeyLen
= keyLen
;
1746 case IW_ENCODE_ALG_TKIP
:
1747 keyType
= TKIP_CRYPT
;
1749 ik
.ik_type
= IEEE80211_CIPHER_TKIP
;
1750 #endif /* USER_KEYS */
1752 case IW_ENCODE_ALG_CCMP
:
1753 keyType
= AES_CRYPT
;
1755 ik
.ik_type
= IEEE80211_CIPHER_AES_CCM
;
1756 #endif /* USER_KEYS */
1759 case IW_ENCODE_ALG_SM4
:
1760 if (ar
->arWapiEnable
) {
1761 return ar6000_set_wapi_key(dev
, info
, erq
, extra
);
1766 case IW_ENCODE_ALG_PMK
:
1767 ar
->arConnectCtrlFlags
|= CONNECT_DO_WPA_OFFLOAD
;
1768 return wmi_set_pmk_cmd(ar
->arWmi
, keyData
);
1774 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1775 keyUsage
|= GROUP_USAGE
;
1777 keyUsage
|= PAIRWISE_USAGE
;
1780 if (ext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
1781 A_MEMCPY(keyRsc
, ext
->rx_seq
, sizeof(keyRsc
));
1783 A_MEMZERO(keyRsc
, sizeof(keyRsc
));
1786 if (((WPA_PSK_AUTH
== ar
->arAuthMode
) || (WPA2_PSK_AUTH
== ar
->arAuthMode
)) &&
1787 (GROUP_USAGE
& keyUsage
))
1789 A_UNTIMEOUT(&ar
->disconnect_timer
);
1792 status
= wmi_addKey_cmd(ar
->arWmi
, index
, keyType
, keyUsage
,
1794 keyData
, KEY_OP_INIT_VAL
,
1795 (A_UINT8
*)ext
->addr
.sa_data
,
1797 if (status
!= A_OK
) {
1802 ik
.ik_keyix
= index
;
1803 ik
.ik_keylen
= keyLen
;
1804 memcpy(ik
.ik_keydata
, keyData
, keyLen
);
1805 memcpy(&ik
.ik_keyrsc
, keyRsc
, sizeof(keyRsc
));
1806 memcpy(ik
.ik_macaddr
, ext
->addr
.sa_data
, ETH_ALEN
);
1807 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1808 memcpy(&ar
->user_saved_keys
.bcast_ik
, &ik
,
1809 sizeof(struct ieee80211req_key
));
1811 memcpy(&ar
->user_saved_keys
.ucast_ik
, &ik
,
1812 sizeof(struct ieee80211req_key
));
1814 ar
->user_saved_keys
.keyOk
= TRUE
;
1815 #endif /* USER_KEYS */
1826 ar6000_ioctl_giwencodeext(struct net_device
*dev
,
1827 struct iw_request_info
*info
,
1828 struct iw_point
*erq
, char *extra
)
1830 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1832 if (ar
->arWlanState
== WLAN_DISABLED
) {
1836 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1838 erq
->flags
= IW_ENCODE_DISABLED
;
1845 #endif // WIRELESS_EXT >= 18
1847 #if WIRELESS_EXT > 20
1848 static int ar6000_ioctl_siwpower(struct net_device
*dev
,
1849 struct iw_request_info
*info
,
1850 union iwreq_data
*wrqu
, char *extra
)
1852 #ifndef ATH6K_CONFIG_OTA_MODE
1853 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1854 WMI_POWER_MODE power_mode
;
1856 if (ar
->arWmiReady
== FALSE
) {
1860 if (ar
->arWlanState
== WLAN_DISABLED
) {
1864 if (wrqu
->power
.disabled
)
1865 power_mode
= MAX_PERF_POWER
;
1867 power_mode
= REC_POWER
;
1869 if (wmi_powermode_cmd(ar
->arWmi
, power_mode
) < 0)
1875 static int ar6000_ioctl_giwpower(struct net_device
*dev
,
1876 struct iw_request_info
*info
,
1877 union iwreq_data
*wrqu
, char *extra
)
1879 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1880 WMI_POWER_MODE power_mode
;
1882 if (ar
->arWmiReady
== FALSE
) {
1886 if (ar
->arWlanState
== WLAN_DISABLED
) {
1890 power_mode
= wmi_get_power_mode_cmd(ar
->arWmi
);
1892 if (power_mode
== MAX_PERF_POWER
)
1893 wrqu
->power
.disabled
= 1;
1895 wrqu
->power
.disabled
= 0;
1899 #endif // WIRELESS_EXT > 20
1905 ar6000_ioctl_giwname(struct net_device
*dev
,
1906 struct iw_request_info
*info
,
1907 char *name
, char *extra
)
1910 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1912 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1913 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1917 if (ar
->arWlanState
== WLAN_DISABLED
) {
1921 capability
= ar
->arPhyCapability
;
1922 if(ar
->arNetworkType
== INFRA_NETWORK
&& ar
->arConnected
) {
1923 bss_t
*bss
= wmi_find_node(ar
->arWmi
, ar
->arBssid
);
1925 capability
= get_bss_phy_capability(bss
);
1926 wmi_node_return(ar
->arWmi
, bss
);
1929 switch (capability
) {
1930 case (WMI_11A_CAPABILITY
):
1931 strncpy(name
, "AR6000 802.11a", IFNAMSIZ
);
1933 case (WMI_11G_CAPABILITY
):
1934 strncpy(name
, "AR6000 802.11g", IFNAMSIZ
);
1936 case (WMI_11AG_CAPABILITY
):
1937 strncpy(name
, "AR6000 802.11ag", IFNAMSIZ
);
1939 case (WMI_11NA_CAPABILITY
):
1940 strncpy(name
, "AR6000 802.11na", IFNAMSIZ
);
1942 case (WMI_11NG_CAPABILITY
):
1943 strncpy(name
, "AR6000 802.11ng", IFNAMSIZ
);
1945 case (WMI_11NAG_CAPABILITY
):
1946 strncpy(name
, "AR6000 802.11nag", IFNAMSIZ
);
1949 strncpy(name
, "AR6000 802.11b", IFNAMSIZ
);
1960 ar6000_ioctl_siwfreq(struct net_device
*dev
,
1961 struct iw_request_info
*info
,
1962 struct iw_freq
*freq
, char *extra
)
1964 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1966 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1967 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1971 if (ar
->arWlanState
== WLAN_DISABLED
) {
1976 * We support limiting the channels via wmiconfig.
1978 * We use this command to configure the channel hint for the connect cmd
1979 * so it is possible the target will end up connecting to a different
1984 } else if (freq
->e
== 1) {
1985 ar
->arChannelHint
= freq
->m
/ 100000;
1988 ar
->arChannelHint
= wlan_ieee2freq(freq
->m
);
1990 /* Auto Channel Selection */
1991 ar
->arChannelHint
= 0;
1995 ar
->ap_profile_flag
= 1; /* There is a change in profile */
1997 A_PRINTF("channel hint set to %d\n", ar
->arChannelHint
);
2005 ar6000_ioctl_giwfreq(struct net_device
*dev
,
2006 struct iw_request_info
*info
,
2007 struct iw_freq
*freq
, char *extra
)
2009 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2011 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2012 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2016 if (ar
->arWlanState
== WLAN_DISABLED
) {
2020 if (ar
->arNetworkType
== AP_NETWORK
) {
2021 if(ar
->arChannelHint
) {
2022 freq
->m
= ar
->arChannelHint
* 100000;
2023 } else if(ar
->arACS
) {
2024 freq
->m
= ar
->arACS
* 100000;
2029 if (ar
->arConnected
!= TRUE
) {
2032 freq
->m
= ar
->arBssChannel
* 100000;
2045 ar6000_ioctl_siwmode(struct net_device
*dev
,
2046 struct iw_request_info
*info
,
2047 __u32
*mode
, char *extra
)
2049 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2051 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2052 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2056 if (ar
->arWlanState
== WLAN_DISABLED
) {
2061 * clear SSID during mode switch in connected state
2063 if(!(ar
->arNetworkType
== (((*mode
) == IW_MODE_INFRA
) ? INFRA_NETWORK
: ADHOC_NETWORK
)) && (ar
->arConnected
== TRUE
) ){
2064 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2070 ar
->arNextMode
= INFRA_NETWORK
;
2073 ar
->arNextMode
= ADHOC_NETWORK
;
2075 case IW_MODE_MASTER
:
2076 ar
->arNextMode
= AP_NETWORK
;
2082 /* clear all shared parameters between AP and STA|IBSS modes when we
2083 * switch between them. Switch between STA & IBSS modes does'nt clear
2084 * the shared profile. This is as per the original design for switching
2085 * between STA & IBSS.
2087 if (ar
->arNetworkType
== AP_NETWORK
|| ar
->arNextMode
== AP_NETWORK
) {
2088 ar
->arDot11AuthMode
= OPEN_AUTH
;
2089 ar
->arAuthMode
= NONE_AUTH
;
2090 ar
->arPairwiseCrypto
= NONE_CRYPT
;
2091 ar
->arPairwiseCryptoLen
= 0;
2092 ar
->arGroupCrypto
= NONE_CRYPT
;
2093 ar
->arGroupCryptoLen
= 0;
2094 ar
->arChannelHint
= 0;
2095 ar
->arBssChannel
= 0;
2096 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2097 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2101 /* SSID has to be cleared to trigger a profile change while switching
2102 * between STA & IBSS modes having the same SSID
2104 if (ar
->arNetworkType
!= ar
->arNextMode
) {
2105 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2116 ar6000_ioctl_giwmode(struct net_device
*dev
,
2117 struct iw_request_info
*info
,
2118 __u32
*mode
, char *extra
)
2120 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2122 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2123 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2127 if (ar
->arWlanState
== WLAN_DISABLED
) {
2131 switch (ar
->arNetworkType
) {
2133 *mode
= IW_MODE_INFRA
;
2136 *mode
= IW_MODE_ADHOC
;
2139 *mode
= IW_MODE_MASTER
;
2151 ar6000_ioctl_siwsens(struct net_device
*dev
,
2152 struct iw_request_info
*info
,
2153 struct iw_param
*sens
, char *extra
)
2162 ar6000_ioctl_giwsens(struct net_device
*dev
,
2163 struct iw_request_info
*info
,
2164 struct iw_param
*sens
, char *extra
)
2176 ar6000_ioctl_giwrange(struct net_device
*dev
,
2177 struct iw_request_info
*info
,
2178 struct iw_point
*data
, char *extra
)
2180 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2181 struct iw_range
*range
= (struct iw_range
*) extra
;
2184 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2185 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2189 if (ar
->bIsDestroyProgress
) {
2193 if (ar
->arWmiReady
== FALSE
) {
2197 if (down_interruptible(&ar
->arSem
)) {
2198 return -ERESTARTSYS
;
2201 if (ar
->bIsDestroyProgress
) {
2206 ar
->arNumChannels
= -1;
2207 A_MEMZERO(ar
->arChannelList
, sizeof (ar
->arChannelList
));
2209 if (wmi_get_channelList_cmd(ar
->arWmi
) != A_OK
) {
2214 wait_event_interruptible_timeout(arEvent
, ar
->arNumChannels
!= -1, wmitimeout
* HZ
);
2216 if (signal_pending(current
)) {
2221 data
->length
= sizeof(struct iw_range
);
2222 A_MEMZERO(range
, sizeof(struct iw_range
));
2224 range
->txpower_capa
= 0;
2226 range
->min_pmp
= 1 * 1024;
2227 range
->max_pmp
= 65535 * 1024;
2228 range
->min_pmt
= 1 * 1024;
2229 range
->max_pmt
= 1000 * 1024;
2230 range
->pmp_flags
= IW_POWER_PERIOD
;
2231 range
->pmt_flags
= IW_POWER_TIMEOUT
;
2234 range
->we_version_compiled
= WIRELESS_EXT
;
2235 range
->we_version_source
= 13;
2237 range
->retry_capa
= IW_RETRY_LIMIT
;
2238 range
->retry_flags
= IW_RETRY_LIMIT
;
2239 range
->min_retry
= 0;
2240 range
->max_retry
= 255;
2242 range
->num_frequency
= range
->num_channels
= ar
->arNumChannels
;
2243 for (i
= 0; i
< ar
->arNumChannels
; i
++) {
2244 range
->freq
[i
].i
= wlan_freq2ieee(ar
->arChannelList
[i
]);
2245 range
->freq
[i
].m
= ar
->arChannelList
[i
] * 100000;
2246 range
->freq
[i
].e
= 1;
2248 * Linux supports max of 32 channels, bail out once you
2251 if (i
== IW_MAX_FREQUENCIES
) {
2256 /* Max quality is max field value minus noise floor */
2257 range
->max_qual
.qual
= 0xff - 161;
2260 * In order to use dBm measurements, 'level' must be lower
2261 * than any possible measurement (see iw_print_stats() in
2262 * wireless tools). It's unclear how this is meant to be
2263 * done, but setting zero in these values forces dBm and
2264 * the actual numbers are not used.
2266 range
->max_qual
.level
= 0;
2267 range
->max_qual
.noise
= 0;
2269 range
->sensitivity
= 3;
2271 range
->max_encoding_tokens
= 4;
2272 /* XXX query driver to find out supported key sizes */
2273 range
->num_encoding_sizes
= 3;
2274 range
->encoding_size
[0] = 5; /* 40-bit */
2275 range
->encoding_size
[1] = 13; /* 104-bit */
2276 range
->encoding_size
[2] = 16; /* 128-bit */
2278 range
->num_bitrates
= 0;
2280 /* estimated maximum TCP throughput values (bps) */
2281 range
->throughput
= 22000000;
2284 range
->max_rts
= 2347;
2285 range
->min_frag
= 256;
2286 range
->max_frag
= 2346;
2296 * This ioctl is used to set the desired bssid for the connect command.
2299 ar6000_ioctl_siwap(struct net_device
*dev
,
2300 struct iw_request_info
*info
,
2301 struct sockaddr
*ap_addr
, char *extra
)
2303 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2305 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2306 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2310 if (ar
->arWlanState
== WLAN_DISABLED
) {
2314 if (ap_addr
->sa_family
!= ARPHRD_ETHER
) {
2318 if (A_MEMCMP(&ap_addr
->sa_data
, bcast_mac
, AR6000_ETH_ADDR_LEN
) == 0) {
2319 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
2321 A_MEMCPY(ar
->arReqBssid
, &ap_addr
->sa_data
, sizeof(ar
->arReqBssid
));
2331 ar6000_ioctl_giwap(struct net_device
*dev
,
2332 struct iw_request_info
*info
,
2333 struct sockaddr
*ap_addr
, char *extra
)
2335 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2337 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2338 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2342 if (ar
->arWlanState
== WLAN_DISABLED
) {
2346 if (ar
->arNetworkType
== AP_NETWORK
) {
2347 A_MEMCPY(&ap_addr
->sa_data
, dev
->dev_addr
, ATH_MAC_LEN
);
2348 ap_addr
->sa_family
= ARPHRD_ETHER
;
2352 if (ar
->arConnected
!= TRUE
) {
2356 A_MEMCPY(&ap_addr
->sa_data
, ar
->arBssid
, sizeof(ar
->arBssid
));
2357 ap_addr
->sa_family
= ARPHRD_ETHER
;
2362 #if (WIRELESS_EXT >= 18)
2367 ar6000_ioctl_siwmlme(struct net_device
*dev
,
2368 struct iw_request_info
*info
,
2369 struct iw_point
*data
, char *extra
)
2371 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2373 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2374 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2378 if (ar
->bIsDestroyProgress
) {
2382 if (ar
->arWlanState
== WLAN_DISABLED
) {
2386 if (ar
->arWmiReady
== FALSE
) {
2390 if (down_interruptible(&ar
->arSem
)) {
2391 return -ERESTARTSYS
;
2394 if (data
->pointer
&& data
->length
== sizeof(struct iw_mlme
)) {
2396 A_UINT8 arNetworkType
;
2397 struct iw_mlme mlme
;
2399 if (copy_from_user(&mlme
, data
->pointer
, sizeof(struct iw_mlme
)))
2404 case IW_MLME_DEAUTH
:
2406 case IW_MLME_DISASSOC
:
2407 if ((ar
->arConnected
!= TRUE
) ||
2408 (memcmp(ar
->arBssid
, mlme
.addr
.sa_data
, 6) != 0)) {
2413 wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
2414 arNetworkType
= ar
->arNetworkType
;
2415 ar6000_init_profile_info(ar
);
2416 ar
->arNetworkType
= arNetworkType
;
2418 wmi_disconnect_cmd(ar
->arWmi
);
2419 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2421 if (ar
->arSkipScan
== FALSE
) {
2422 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
2439 #endif /* WIRELESS_EXT >= 18 */
2445 ar6000_ioctl_iwaplist(struct net_device
*dev
,
2446 struct iw_request_info
*info
,
2447 struct iw_point
*data
, char *extra
)
2449 return -EIO
; /* for now */
2456 ar6000_ioctl_siwscan(struct net_device
*dev
,
2457 struct iw_request_info
*info
,
2458 struct iw_point
*data
, char *extra
)
2460 #define ACT_DWELLTIME_DEFAULT 105
2461 #define HOME_TXDRAIN_TIME 100
2462 #define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
2463 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2466 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2467 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2471 if (ar
->arWmiReady
== FALSE
) {
2475 if (ar
->arWlanState
== WLAN_DISABLED
) {
2479 /* If scan is issued in the middle of ongoing scan or connect,
2480 dont issue another one */
2481 if ( ar
->scan_triggered
> 0 ) {
2482 ++ar
->scan_triggered
;
2483 if (ar
->scan_triggered
< 5) {
2486 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN
,("Scan request is triggered over 5 times. Not scan complete event\n"));
2490 if (!ar
->arUserBssFilter
) {
2491 if (wmi_bssfilter_cmd(ar
->arWmi
, ALL_BSS_FILTER
, 0) != A_OK
) {
2496 if (ar
->arConnected
) {
2497 if (wmi_get_stats_cmd(ar
->arWmi
) != A_OK
) {
2503 #if WIRELESS_EXT >= 18
2504 if (data
->pointer
&& (data
->length
== sizeof(struct iw_scan_req
)))
2506 if ((data
->flags
& IW_SCAN_THIS_ESSID
) == IW_SCAN_THIS_ESSID
)
2508 struct iw_scan_req req
;
2509 if (copy_from_user(&req
, data
->pointer
, sizeof(struct iw_scan_req
)))
2511 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, SPECIFIC_SSID_FLAG
, req
.essid_len
, req
.essid
) != A_OK
)
2513 ar
->scanSpecificSsid
= 1;
2517 if (ar
->scanSpecificSsid
) {
2518 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != A_OK
)
2520 ar
->scanSpecificSsid
= 0;
2526 if (ar
->scanSpecificSsid
) {
2527 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != A_OK
)
2529 ar
->scanSpecificSsid
= 0;
2533 #endif /* ANDROID_ENV */
2535 if (wmi_startscan_cmd(ar
->arWmi
, WMI_LONG_SCAN
, FALSE
, FALSE
, \
2536 0, 0, 0, NULL
) != A_OK
) {
2541 ar
->scan_triggered
= 1;
2545 #undef ACT_DWELLTIME_DEFAULT
2546 #undef HOME_TXDRAIN_TIME
2552 * Units are in db above the noise floor. That means the
2553 * rssi values reported in the tx/rx descriptors in the
2554 * driver are the SNR expressed in db.
2556 * If you assume that the noise floor is -95, which is an
2557 * excellent assumption 99.5 % of the time, then you can
2558 * derive the absolute signal level (i.e. -95 + rssi).
2559 * There are some other slight factors to take into account
2560 * depending on whether the rssi measurement is from 11b,
2561 * 11g, or 11a. These differences are at most 2db and
2562 * can be documented.
2564 * NB: various calculations are based on the orinoco/wavelan
2565 * drivers for compatibility
2568 ar6000_set_quality(struct iw_quality
*iq
, A_INT8 rssi
)
2576 /* NB: max is 94 because noise is hardcoded to 161 */
2580 iq
->noise
= 161; /* -95dBm */
2581 iq
->level
= iq
->noise
+ iq
->qual
;
2587 ar6000_ioctl_siwcommit(struct net_device
*dev
,
2588 struct iw_request_info
*info
,
2589 struct iw_point
*data
, char *extra
)
2591 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2593 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2594 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2598 if (ar
->arWmiReady
== FALSE
) {
2602 if (ar
->arWlanState
== WLAN_DISABLED
) {
2606 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT
,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
2607 " PW crypto %d GRP crypto %d\n",
2608 ar
->arSsid
, ar
->arChannelHint
,
2609 ar
->arAuthMode
, ar
->arDot11AuthMode
,
2610 ar
->arPairwiseCrypto
, ar
->arGroupCrypto
));
2612 ar6000_ap_mode_profile_commit(ar
);
2614 /* if there is a profile switch from STA|IBSS mode to AP mode,
2615 * update the host driver association state for the STA|IBSS mode.
2617 if (ar
->arNetworkType
!= AP_NETWORK
&& ar
->arNextMode
== AP_NETWORK
) {
2618 ar
->arConnectPending
= FALSE
;
2619 ar
->arConnected
= FALSE
;
2620 /* Stop getting pkts from upper stack */
2621 netif_stop_queue(ar
->arNetDev
);
2622 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2623 ar
->arBssChannel
= 0;
2624 ar
->arBeaconInterval
= 0;
2626 /* Flush the Tx queues */
2627 ar6000_TxDataCleanup(ar
);
2629 /* Start getting pkts from upper stack */
2630 netif_wake_queue(ar
->arNetDev
);
2636 #define W_PROTO(_x) wait_ ## _x
2637 #define WAIT_HANDLER_IMPL(_x, type) \
2638 int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
2642 ret = _x(dev, info, wrqu, extra); \
2648 WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid
, struct iw_point
*)
2649 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate
, struct iw_param
*)
2650 WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow
, struct iw_param
*)
2651 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange
, struct iw_point
*)
2653 /* Structures to export the Wireless Handlers */
2654 static const iw_handler ath_handlers
[] = {
2655 (iw_handler
) ar6000_ioctl_siwcommit
, /* SIOCSIWCOMMIT */
2656 (iw_handler
) ar6000_ioctl_giwname
, /* SIOCGIWNAME */
2657 (iw_handler
) NULL
, /* SIOCSIWNWID */
2658 (iw_handler
) NULL
, /* SIOCGIWNWID */
2659 (iw_handler
) ar6000_ioctl_siwfreq
, /* SIOCSIWFREQ */
2660 (iw_handler
) ar6000_ioctl_giwfreq
, /* SIOCGIWFREQ */
2661 (iw_handler
) ar6000_ioctl_siwmode
, /* SIOCSIWMODE */
2662 (iw_handler
) ar6000_ioctl_giwmode
, /* SIOCGIWMODE */
2663 (iw_handler
) ar6000_ioctl_siwsens
, /* SIOCSIWSENS */
2664 (iw_handler
) ar6000_ioctl_giwsens
, /* SIOCGIWSENS */
2665 (iw_handler
) NULL
/* not _used */, /* SIOCSIWRANGE */
2666 (iw_handler
) W_PROTO(ar6000_ioctl_giwrange
),/* SIOCGIWRANGE */
2667 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
2668 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
2669 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
2670 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
2671 (iw_handler
) NULL
, /* SIOCSIWSPY */
2672 (iw_handler
) NULL
, /* SIOCGIWSPY */
2673 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
2674 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
2675 (iw_handler
) ar6000_ioctl_siwap
, /* SIOCSIWAP */
2676 (iw_handler
) ar6000_ioctl_giwap
, /* SIOCGIWAP */
2677 #if (WIRELESS_EXT >= 18)
2678 (iw_handler
) ar6000_ioctl_siwmlme
, /* SIOCSIWMLME */
2680 (iw_handler
) NULL
, /* -- hole -- */
2681 #endif /* WIRELESS_EXT >= 18 */
2682 (iw_handler
) ar6000_ioctl_iwaplist
, /* SIOCGIWAPLIST */
2683 (iw_handler
) ar6000_ioctl_siwscan
, /* SIOCSIWSCAN */
2684 (iw_handler
) ar6000_ioctl_giwscan
, /* SIOCGIWSCAN */
2685 (iw_handler
) W_PROTO(ar6000_ioctl_siwessid
),/* SIOCSIWESSID */
2686 (iw_handler
) ar6000_ioctl_giwessid
, /* SIOCGIWESSID */
2687 (iw_handler
) NULL
, /* SIOCSIWNICKN */
2688 (iw_handler
) NULL
, /* SIOCGIWNICKN */
2689 (iw_handler
) NULL
, /* -- hole -- */
2690 (iw_handler
) NULL
, /* -- hole -- */
2691 (iw_handler
) ar6000_ioctl_siwrate
, /* SIOCSIWRATE */
2692 (iw_handler
) W_PROTO(ar6000_ioctl_giwrate
), /* SIOCGIWRATE */
2693 (iw_handler
) NULL
, /* SIOCSIWRTS */
2694 (iw_handler
) NULL
, /* SIOCGIWRTS */
2695 (iw_handler
) NULL
, /* SIOCSIWFRAG */
2696 (iw_handler
) NULL
, /* SIOCGIWFRAG */
2697 (iw_handler
) ar6000_ioctl_siwtxpow
, /* SIOCSIWTXPOW */
2698 (iw_handler
) W_PROTO(ar6000_ioctl_giwtxpow
),/* SIOCGIWTXPOW */
2699 (iw_handler
) ar6000_ioctl_siwretry
, /* SIOCSIWRETRY */
2700 (iw_handler
) ar6000_ioctl_giwretry
, /* SIOCGIWRETRY */
2701 (iw_handler
) ar6000_ioctl_siwencode
, /* SIOCSIWENCODE */
2702 (iw_handler
) ar6000_ioctl_giwencode
, /* SIOCGIWENCODE */
2703 #if WIRELESS_EXT > 20
2704 (iw_handler
) ar6000_ioctl_siwpower
, /* SIOCSIWPOWER */
2705 (iw_handler
) ar6000_ioctl_giwpower
, /* SIOCGIWPOWER */
2706 #endif // WIRELESS_EXT > 20
2707 #if WIRELESS_EXT >= 18
2708 (iw_handler
) NULL
, /* -- hole -- */
2709 (iw_handler
) NULL
, /* -- hole -- */
2710 (iw_handler
) ar6000_ioctl_siwgenie
, /* SIOCSIWGENIE */
2711 (iw_handler
) ar6000_ioctl_giwgenie
, /* SIOCGIWGENIE */
2712 (iw_handler
) ar6000_ioctl_siwauth
, /* SIOCSIWAUTH */
2713 (iw_handler
) ar6000_ioctl_giwauth
, /* SIOCGIWAUTH */
2714 (iw_handler
) ar6000_ioctl_siwencodeext
, /* SIOCSIWENCODEEXT */
2715 (iw_handler
) ar6000_ioctl_giwencodeext
, /* SIOCGIWENCODEEXT */
2716 (iw_handler
) ar6000_ioctl_siwpmksa
, /* SIOCSIWPMKSA */
2717 #endif // WIRELESS_EXT >= 18
2720 struct iw_handler_def ath_iw_handler_def
= {
2721 .standard
= (iw_handler
*)ath_handlers
,
2722 .num_standard
= ARRAY_SIZE(ath_handlers
),