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 */
67 static u8
get_bss_phy_capability(bss_t
*bss
)
70 struct ieee80211_common_ie
*cie
= &bss
->ni_cie
;
71 #define CHAN_IS_11A(x) (!((x >= 2412) && (x <= 2484)))
72 if (CHAN_IS_11A(cie
->ie_chan
)) {
74 capability
= WMI_11NA_CAPABILITY
;
76 capability
= WMI_11A_CAPABILITY
;
78 } else if ((cie
->ie_erp
) || (cie
->ie_xrates
)) {
80 capability
= WMI_11NG_CAPABILITY
;
82 capability
= WMI_11G_CAPABILITY
;
89 ar6000_scan_node(void *arg
, bss_t
*ni
)
95 struct ar_giwscan_param
*param
;
98 struct ieee80211_common_ie
*cie
;
101 u32 rate_len
, data_len
= 0;
103 param
= (struct ar_giwscan_param
*)arg
;
105 current_ev
= param
->current_ev
;
106 end_buf
= param
->end_buf
;
110 if ((end_buf
- current_ev
) > IW_EV_ADDR_LEN
)
112 A_MEMZERO(&iwe
, sizeof(iwe
));
114 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
115 A_MEMCPY(iwe
.u
.ap_addr
.sa_data
, ni
->ni_macaddr
, 6);
116 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
117 &iwe
, IW_EV_ADDR_LEN
);
119 param
->bytes_needed
+= IW_EV_ADDR_LEN
;
121 data_len
= cie
->ie_ssid
[1] + IW_EV_POINT_LEN
;
122 if ((end_buf
- current_ev
) > data_len
)
124 A_MEMZERO(&iwe
, sizeof(iwe
));
125 iwe
.cmd
= SIOCGIWESSID
;
126 iwe
.u
.data
.flags
= 1;
127 iwe
.u
.data
.length
= cie
->ie_ssid
[1];
128 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
129 &iwe
, (char*)&cie
->ie_ssid
[2]);
131 param
->bytes_needed
+= data_len
;
133 if (cie
->ie_capInfo
& (IEEE80211_CAPINFO_ESS
|IEEE80211_CAPINFO_IBSS
)) {
134 if ((end_buf
- current_ev
) > IW_EV_UINT_LEN
)
136 A_MEMZERO(&iwe
, sizeof(iwe
));
137 iwe
.cmd
= SIOCGIWMODE
;
138 iwe
.u
.mode
= cie
->ie_capInfo
& IEEE80211_CAPINFO_ESS
?
139 IW_MODE_MASTER
: IW_MODE_ADHOC
;
140 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
141 &iwe
, IW_EV_UINT_LEN
);
143 param
->bytes_needed
+= IW_EV_UINT_LEN
;
146 if ((end_buf
- current_ev
) > IW_EV_FREQ_LEN
)
148 A_MEMZERO(&iwe
, sizeof(iwe
));
149 iwe
.cmd
= SIOCGIWFREQ
;
150 iwe
.u
.freq
.m
= cie
->ie_chan
* 100000;
152 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
153 &iwe
, IW_EV_FREQ_LEN
);
155 param
->bytes_needed
+= IW_EV_FREQ_LEN
;
157 if ((end_buf
- current_ev
) > IW_EV_QUAL_LEN
)
159 A_MEMZERO(&iwe
, sizeof(iwe
));
161 ar6000_set_quality(&iwe
.u
.qual
, ni
->ni_snr
);
162 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
163 &iwe
, IW_EV_QUAL_LEN
);
165 param
->bytes_needed
+= IW_EV_QUAL_LEN
;
167 if ((end_buf
- current_ev
) > IW_EV_POINT_LEN
)
169 A_MEMZERO(&iwe
, sizeof(iwe
));
170 iwe
.cmd
= SIOCGIWENCODE
;
171 if (cie
->ie_capInfo
& IEEE80211_CAPINFO_PRIVACY
) {
172 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
174 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
176 iwe
.u
.data
.length
= 0;
177 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
180 param
->bytes_needed
+= IW_EV_POINT_LEN
;
182 /* supported bit rate */
183 A_MEMZERO(&iwe
, sizeof(iwe
));
184 iwe
.cmd
= SIOCGIWRATE
;
185 iwe
.u
.bitrate
.fixed
= 0;
186 iwe
.u
.bitrate
.disabled
= 0;
187 iwe
.u
.bitrate
.value
= 0;
188 current_val
= current_ev
+ IW_EV_LCP_LEN
;
189 param
->bytes_needed
+= IW_EV_LCP_LEN
;
191 if (cie
->ie_rates
!= NULL
) {
192 rate_len
= cie
->ie_rates
[1];
193 data_len
= (rate_len
* (IW_EV_PARAM_LEN
- IW_EV_LCP_LEN
));
194 if ((end_buf
- current_ev
) > data_len
)
196 for (j
= 0; j
< rate_len
; j
++) {
198 val
= cie
->ie_rates
[2 + j
];
199 iwe
.u
.bitrate
.value
=
200 (val
>= 0x80)? ((val
- 0x80) * 500000): (val
* 500000);
201 current_val
= IWE_STREAM_ADD_VALUE(param
->info
, current_ev
,
202 current_val
, end_buf
,
203 &iwe
, IW_EV_PARAM_LEN
);
206 param
->bytes_needed
+= data_len
;
209 if (cie
->ie_xrates
!= NULL
) {
210 rate_len
= cie
->ie_xrates
[1];
211 data_len
= (rate_len
* (IW_EV_PARAM_LEN
- IW_EV_LCP_LEN
));
212 if ((end_buf
- current_ev
) > data_len
)
214 for (j
= 0; j
< rate_len
; j
++) {
216 val
= cie
->ie_xrates
[2 + j
];
217 iwe
.u
.bitrate
.value
=
218 (val
>= 0x80)? ((val
- 0x80) * 500000): (val
* 500000);
219 current_val
= IWE_STREAM_ADD_VALUE(param
->info
, current_ev
,
220 current_val
, end_buf
,
221 &iwe
, IW_EV_PARAM_LEN
);
224 param
->bytes_needed
+= data_len
;
226 /* remove fixed header if no rates were added */
227 if ((current_val
- current_ev
) > IW_EV_LCP_LEN
)
228 current_ev
= current_val
;
230 #if WIRELESS_EXT >= 18
232 if (cie
->ie_wpa
!= NULL
) {
233 data_len
= cie
->ie_wpa
[1] + 2 + IW_EV_POINT_LEN
;
234 if ((end_buf
- current_ev
) > data_len
)
236 A_MEMZERO(&iwe
, sizeof(iwe
));
238 iwe
.u
.data
.length
= cie
->ie_wpa
[1] + 2;
239 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
240 &iwe
, (char*)cie
->ie_wpa
);
242 param
->bytes_needed
+= data_len
;
245 if (cie
->ie_rsn
!= NULL
&& cie
->ie_rsn
[0] == IEEE80211_ELEMID_RSN
) {
246 data_len
= cie
->ie_rsn
[1] + 2 + IW_EV_POINT_LEN
;
247 if ((end_buf
- current_ev
) > data_len
)
249 A_MEMZERO(&iwe
, sizeof(iwe
));
251 iwe
.u
.data
.length
= cie
->ie_rsn
[1] + 2;
252 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
253 &iwe
, (char*)cie
->ie_rsn
);
255 param
->bytes_needed
+= data_len
;
258 #endif /* WIRELESS_EXT >= 18 */
260 if ((end_buf
- current_ev
) > IW_EV_CHAR_LEN
)
263 A_MEMZERO(&iwe
, sizeof(iwe
));
264 iwe
.cmd
= SIOCGIWNAME
;
265 switch (get_bss_phy_capability(ni
)) {
266 case WMI_11A_CAPABILITY
:
267 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11a");
269 case WMI_11G_CAPABILITY
:
270 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11g");
272 case WMI_11NA_CAPABILITY
:
273 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11na");
275 case WMI_11NG_CAPABILITY
:
276 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11ng");
279 snprintf(iwe
.u
.name
, IFNAMSIZ
, "IEEE 802.11b");
282 current_ev
= IWE_STREAM_ADD_EVENT(param
->info
, current_ev
, end_buf
,
283 &iwe
, IW_EV_CHAR_LEN
);
285 param
->bytes_needed
+= IW_EV_CHAR_LEN
;
287 #if WIRELESS_EXT > 14
288 A_MEMZERO(&iwe
, sizeof(iwe
));
289 iwe
.cmd
= IWEVCUSTOM
;
290 iwe
.u
.data
.length
= snprintf(buf
, sizeof(buf
), "bcn_int=%d", cie
->ie_beaconInt
);
291 data_len
= iwe
.u
.data
.length
+ IW_EV_POINT_LEN
;
292 if ((end_buf
- current_ev
) > data_len
)
294 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
297 param
->bytes_needed
+= data_len
;
299 #if WIRELESS_EXT < 18
300 if (cie
->ie_wpa
!= NULL
) {
301 static const char wpa_leader
[] = "wpa_ie=";
302 data_len
= (sizeof(wpa_leader
) - 1) + ((cie
->ie_wpa
[1]+2) * 2) + IW_EV_POINT_LEN
;
303 if ((end_buf
- current_ev
) > data_len
)
305 A_MEMZERO(&iwe
, sizeof(iwe
));
306 iwe
.cmd
= IWEVCUSTOM
;
307 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wpa
,
309 wpa_leader
, sizeof(wpa_leader
)-1);
311 if (iwe
.u
.data
.length
!= 0) {
312 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
316 param
->bytes_needed
+= data_len
;
319 if (cie
->ie_rsn
!= NULL
&& cie
->ie_rsn
[0] == IEEE80211_ELEMID_RSN
) {
320 static const char rsn_leader
[] = "rsn_ie=";
321 data_len
= (sizeof(rsn_leader
) - 1) + ((cie
->ie_rsn
[1]+2) * 2) + IW_EV_POINT_LEN
;
322 if ((end_buf
- current_ev
) > data_len
)
324 A_MEMZERO(&iwe
, sizeof(iwe
));
325 iwe
.cmd
= IWEVCUSTOM
;
326 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_rsn
,
328 rsn_leader
, sizeof(rsn_leader
)-1);
330 if (iwe
.u
.data
.length
!= 0) {
331 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
335 param
->bytes_needed
+= data_len
;
337 #endif /* WIRELESS_EXT < 18 */
339 if (cie
->ie_wmm
!= NULL
) {
340 static const char wmm_leader
[] = "wmm_ie=";
341 data_len
= (sizeof(wmm_leader
) - 1) + ((cie
->ie_wmm
[1]+2) * 2) + IW_EV_POINT_LEN
;
342 if ((end_buf
- current_ev
) > data_len
)
344 A_MEMZERO(&iwe
, sizeof(iwe
));
345 iwe
.cmd
= IWEVCUSTOM
;
346 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wmm
,
348 wmm_leader
, sizeof(wmm_leader
)-1);
349 if (iwe
.u
.data
.length
!= 0) {
350 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
354 param
->bytes_needed
+= data_len
;
357 if (cie
->ie_ath
!= NULL
) {
358 static const char ath_leader
[] = "ath_ie=";
359 data_len
= (sizeof(ath_leader
) - 1) + ((cie
->ie_ath
[1]+2) * 2) + IW_EV_POINT_LEN
;
360 if ((end_buf
- current_ev
) > data_len
)
362 A_MEMZERO(&iwe
, sizeof(iwe
));
363 iwe
.cmd
= IWEVCUSTOM
;
364 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_ath
,
366 ath_leader
, sizeof(ath_leader
)-1);
367 if (iwe
.u
.data
.length
!= 0) {
368 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
372 param
->bytes_needed
+= data_len
;
376 if (cie
->ie_wapi
!= NULL
) {
377 static const char wapi_leader
[] = "wapi_ie=";
378 data_len
= (sizeof(wapi_leader
) - 1) + ((cie
->ie_wapi
[1] + 2) * 2) + IW_EV_POINT_LEN
;
379 if ((end_buf
- current_ev
) > data_len
) {
380 A_MEMZERO(&iwe
, sizeof(iwe
));
381 iwe
.cmd
= IWEVCUSTOM
;
382 iwe
.u
.data
.length
= encode_ie(buf
, sizeof(buf
), cie
->ie_wapi
,
384 wapi_leader
, sizeof(wapi_leader
) - 1);
385 if (iwe
.u
.data
.length
!= 0) {
386 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
,
390 param
->bytes_needed
+= data_len
;
392 #endif /* WAPI_ENABLE */
394 #endif /* WIRELESS_EXT > 14 */
396 #if WIRELESS_EXT >= 18
397 if (cie
->ie_wsc
!= NULL
) {
398 data_len
= (cie
->ie_wsc
[1] + 2) + IW_EV_POINT_LEN
;
399 if ((end_buf
- current_ev
) > data_len
)
401 A_MEMZERO(&iwe
, sizeof(iwe
));
403 iwe
.u
.data
.length
= cie
->ie_wsc
[1] + 2;
404 current_ev
= IWE_STREAM_ADD_POINT(param
->info
, current_ev
, end_buf
,
405 &iwe
, (char*)cie
->ie_wsc
);
407 param
->bytes_needed
+= data_len
;
409 #endif /* WIRELESS_EXT >= 18 */
411 param
->current_ev
= current_ev
;
415 ar6000_ioctl_giwscan(struct net_device
*dev
,
416 struct iw_request_info
*info
,
417 struct iw_point
*data
, char *extra
)
419 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
420 struct ar_giwscan_param param
;
422 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
423 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
427 if (ar
->arWlanState
== WLAN_DISABLED
) {
431 if (ar
->arWmiReady
== false) {
435 param
.current_ev
= extra
;
436 param
.end_buf
= extra
+ data
->length
;
437 param
.bytes_needed
= 0;
440 /* Translate data to WE format */
441 wmi_iterate_nodes(ar
->arWmi
, ar6000_scan_node
, ¶m
);
443 /* check if bytes needed is greater than bytes consumed */
444 if (param
.bytes_needed
> (param
.current_ev
- extra
))
446 /* Request one byte more than needed, because when "data->length" equals bytes_needed,
447 it is not possible to add the last event data as all iwe_stream_add_xxxxx() functions
448 checks whether (cur_ptr + ev_len) < end_ptr, due to this one more retry would happen*/
449 data
->length
= param
.bytes_needed
+ 1;
457 extern int reconnect_flag
;
460 ar6000_ioctl_siwessid(struct net_device
*dev
,
461 struct iw_request_info
*info
,
462 struct iw_point
*data
, char *ssid
)
464 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
467 u8 prevMode
= ar
->arNetworkType
;
469 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
470 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
474 if (ar
->bIsDestroyProgress
) {
478 if (ar
->arWlanState
== WLAN_DISABLED
) {
482 if (ar
->arWmiReady
== false) {
486 #if defined(WIRELESS_EXT)
487 if (WIRELESS_EXT
>= 20) {
493 * iwconfig passes a null terminated string with length including this
494 * so we need to account for this
496 if (data
->flags
&& (!data
->length
|| (data
->length
== 1) ||
497 ((data
->length
- 1) > sizeof(ar
->arSsid
))))
505 if (ar
->arNextMode
== AP_NETWORK
) {
506 /* SSID change for AP network - Will take effect on commit */
507 if(A_MEMCMP(ar
->arSsid
,ssid
,32) != 0) {
508 ar
->arSsidLen
= data
->length
- 1;
509 A_MEMCPY(ar
->arSsid
, ssid
, ar
->arSsidLen
);
510 ar
->ap_profile_flag
= 1; /* There is a change in profile */
513 } else if(ar
->arNetworkType
== AP_NETWORK
) {
517 /* We are switching from AP to STA | IBSS mode, cleanup the AP state */
518 for (ctr
=0; ctr
< AP_MAX_NUM_STA
; ctr
++) {
519 remove_sta(ar
, ar
->sta_list
[ctr
].mac
, 0);
521 A_MUTEX_LOCK(&ar
->mcastpsqLock
);
522 while (!A_NETBUF_QUEUE_EMPTY(&ar
->mcastpsq
)) {
523 skb
= A_NETBUF_DEQUEUE(&ar
->mcastpsq
);
526 A_MUTEX_UNLOCK(&ar
->mcastpsqLock
);
529 /* Added for bug 25178, return an IOCTL error instead of target returning
530 Illegal parameter error when either the BSSID or channel is missing
531 and we cannot scan during connect.
534 if (ar
->arSkipScan
== true &&
535 (ar
->arChannelHint
== 0 ||
536 (!ar
->arReqBssid
[0] && !ar
->arReqBssid
[1] && !ar
->arReqBssid
[2] &&
537 !ar
->arReqBssid
[3] && !ar
->arReqBssid
[4] && !ar
->arReqBssid
[5])))
543 if (down_interruptible(&ar
->arSem
)) {
547 if (ar
->bIsDestroyProgress
|| ar
->arWlanState
== WLAN_DISABLED
) {
552 if (ar
->arTxPending
[wmi_get_control_ep(ar
->arWmi
)]) {
554 * sleep until the command queue drains
556 wait_event_interruptible_timeout(arEvent
,
557 ar
->arTxPending
[wmi_get_control_ep(ar
->arWmi
)] == 0, wmitimeout
* HZ
);
558 if (signal_pending(current
)) {
564 arNetworkType
= ar
->arNetworkType
;
565 #ifdef ATH6K_CONFIG_CFG80211
566 if (ar
->arConnected
) {
567 #endif /* ATH6K_CONFIG_CFG80211 */
568 ar6000_init_profile_info(ar
);
569 #ifdef ATH6K_CONFIG_CFG80211
571 #endif /* ATH6K_CONFIG_CFG80211 */
572 ar
->arNetworkType
= arNetworkType
;
575 /* Update the arNetworkType */
576 ar
->arNetworkType
= ar
->arNextMode
;
579 if ((prevMode
!= AP_NETWORK
) &&
580 ((ar
->arSsidLen
) || ((ar
->arSsidLen
== 0) && ar
->arConnected
) || (!data
->flags
)))
582 if ((!data
->flags
) ||
583 (A_MEMCMP(ar
->arSsid
, ssid
, ar
->arSsidLen
) != 0) ||
584 (ar
->arSsidLen
!= (data
->length
- 1)))
587 * SSID set previously or essid off has been issued.
589 * Disconnect Command is issued in two cases after wmi is ready
590 * (1) ssid is different from the previous setting
591 * (2) essid off has been issued
594 if (ar
->arWmiReady
== true) {
596 status
= wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
597 status
= wmi_disconnect_cmd(ar
->arWmi
);
598 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
600 if (ar
->arSkipScan
== false) {
601 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
614 * SSID is same, so we assume profile hasn't changed.
615 * If the interface is up and wmi is ready, we issue
616 * a reconnect cmd. Issue a reconnect only we are already
619 if((ar
->arConnected
== true) && (ar
->arWmiReady
== true))
621 reconnect_flag
= true;
622 status
= wmi_reconnect_cmd(ar
->arWmi
,ar
->arReqBssid
,
625 if (status
!= A_OK
) {
632 * Dont return if connect is pending.
634 if(!(ar
->arConnectPending
)) {
642 ar
->arSsidLen
= data
->length
- 1;
643 A_MEMCPY(ar
->arSsid
, ssid
, ar
->arSsidLen
);
645 if (ar6000_connect_to_ap(ar
)!= A_OK
) {
656 ar6000_ioctl_giwessid(struct net_device
*dev
,
657 struct iw_request_info
*info
,
658 struct iw_point
*data
, char *essid
)
660 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
662 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
663 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
667 if (ar
->arWlanState
== WLAN_DISABLED
) {
671 if (!ar
->arSsidLen
) {
676 data
->length
= ar
->arSsidLen
;
677 A_MEMCPY(essid
, ar
->arSsid
, ar
->arSsidLen
);
683 void ar6000_install_static_wep_keys(AR_SOFTC_T
*ar
)
688 for (index
= WMI_MIN_KEY_INDEX
; index
<= WMI_MAX_KEY_INDEX
; index
++) {
689 if (ar
->arWepKeyList
[index
].arKeyLen
) {
690 keyUsage
= GROUP_USAGE
;
691 if (index
== ar
->arDefTxKeyIndex
) {
692 keyUsage
|= TX_USAGE
;
694 wmi_addKey_cmd(ar
->arWmi
,
698 ar
->arWepKeyList
[index
].arKeyLen
,
700 ar
->arWepKeyList
[index
].arKey
, KEY_OP_INIT_VAL
, NULL
,
710 ar6000_ioctl_siwrate(struct net_device
*dev
,
711 struct iw_request_info
*info
,
712 struct iw_param
*rrq
, char *extra
)
714 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
718 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
719 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
724 kbps
= rrq
->value
/ 1000; /* rrq->value is in bps */
726 kbps
= -1; /* -1 indicates auto rate */
728 if(kbps
!= -1 && wmi_validate_bitrate(ar
->arWmi
, kbps
, &rate_idx
) != A_OK
)
730 AR_DEBUG_PRINTF(ATH_DEBUG_ERR
,("BitRate is not Valid %d\n", kbps
));
733 ar
->arBitRate
= kbps
;
734 if(ar
->arWmiReady
== true)
736 if (wmi_set_bitrate_cmd(ar
->arWmi
, kbps
, -1, -1) != A_OK
) {
747 ar6000_ioctl_giwrate(struct net_device
*dev
,
748 struct iw_request_info
*info
,
749 struct iw_param
*rrq
, char *extra
)
751 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
754 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
755 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
759 if (ar
->bIsDestroyProgress
) {
763 if (ar
->arWlanState
== WLAN_DISABLED
) {
767 if ((ar
->arNextMode
!= AP_NETWORK
&& !ar
->arConnected
) || ar
->arWmiReady
== false) {
768 rrq
->value
= 1000 * 1000;
772 if (down_interruptible(&ar
->arSem
)) {
776 if (ar
->bIsDestroyProgress
|| ar
->arWlanState
== WLAN_DISABLED
) {
781 ar
->arBitRate
= 0xFFFF;
782 if (wmi_get_bitrate_cmd(ar
->arWmi
) != A_OK
) {
786 wait_event_interruptible_timeout(arEvent
, ar
->arBitRate
!= 0xFFFF, wmitimeout
* HZ
);
787 if (signal_pending(current
)) {
790 /* If the interface is down or wmi is not ready or the target is not
791 connected - return the value stored in the device structure */
793 if (ar
->arBitRate
== -1) {
797 rrq
->value
= ar
->arBitRate
* 1000;
810 ar6000_ioctl_siwtxpow(struct net_device
*dev
,
811 struct iw_request_info
*info
,
812 struct iw_param
*rrq
, char *extra
)
814 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
817 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
818 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
822 if (ar
->arWlanState
== WLAN_DISABLED
) {
831 if (rrq
->flags
!= IW_TXPOW_DBM
) {
834 ar
->arTxPwr
= dbM
= rrq
->value
;
835 ar
->arTxPwrSet
= true;
837 ar
->arTxPwr
= dbM
= 0;
838 ar
->arTxPwrSet
= false;
840 if(ar
->arWmiReady
== true)
842 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_TX
,("Set tx pwr cmd %d dbM\n", dbM
));
843 wmi_set_txPwr_cmd(ar
->arWmi
, dbM
);
852 ar6000_ioctl_giwtxpow(struct net_device
*dev
,
853 struct iw_request_info
*info
,
854 struct iw_param
*rrq
, char *extra
)
856 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
859 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
860 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
864 if (ar
->bIsDestroyProgress
) {
868 if (ar
->arWlanState
== WLAN_DISABLED
) {
872 if (down_interruptible(&ar
->arSem
)) {
876 if (ar
->bIsDestroyProgress
) {
881 if((ar
->arWmiReady
== true) && (ar
->arConnected
== true))
885 if (wmi_get_txPwr_cmd(ar
->arWmi
) != A_OK
) {
890 wait_event_interruptible_timeout(arEvent
, ar
->arTxPwr
!= 0, wmitimeout
* HZ
);
892 if (signal_pending(current
)) {
896 /* If the interace is down or wmi is not ready or target is not connected
897 then return value stored in the device structure */
900 if (ar
->arTxPwrSet
== true) {
903 rrq
->value
= ar
->arTxPwr
;
904 rrq
->flags
= IW_TXPOW_DBM
;
906 // IWLIST need this flag to get TxPower
918 * since iwconfig only provides us with one max retry value, we use it
919 * to apply to data frames of the BE traffic class.
922 ar6000_ioctl_siwretry(struct net_device
*dev
,
923 struct iw_request_info
*info
,
924 struct iw_param
*rrq
, char *extra
)
926 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
928 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
929 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
933 if (ar
->arWlanState
== WLAN_DISABLED
) {
941 if ((rrq
->flags
& IW_RETRY_TYPE
) != IW_RETRY_LIMIT
) {
945 if ( !(rrq
->value
>= WMI_MIN_RETRIES
) || !(rrq
->value
<= WMI_MAX_RETRIES
)) {
948 if(ar
->arWmiReady
== true)
950 if (wmi_set_retry_limits_cmd(ar
->arWmi
, DATA_FRAMETYPE
, WMM_AC_BE
,
951 rrq
->value
, 0) != A_OK
){
955 ar
->arMaxRetries
= rrq
->value
;
963 ar6000_ioctl_giwretry(struct net_device
*dev
,
964 struct iw_request_info
*info
,
965 struct iw_param
*rrq
, char *extra
)
967 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
969 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
970 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
974 if (ar
->arWlanState
== WLAN_DISABLED
) {
979 switch (rrq
->flags
& IW_RETRY_TYPE
) {
980 case IW_RETRY_LIFETIME
:
984 rrq
->flags
= IW_RETRY_LIMIT
;
985 switch (rrq
->flags
& IW_RETRY_MODIFIER
) {
987 rrq
->flags
|= IW_RETRY_MIN
;
988 rrq
->value
= WMI_MIN_RETRIES
;
991 rrq
->flags
|= IW_RETRY_MAX
;
992 rrq
->value
= ar
->arMaxRetries
;
1004 ar6000_ioctl_siwencode(struct net_device
*dev
,
1005 struct iw_request_info
*info
,
1006 struct iw_point
*erq
, char *keybuf
)
1008 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1012 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1013 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1017 if(ar
->arNextMode
!= AP_NETWORK
) {
1019 * Static WEP Keys should be configured before setting the SSID
1021 if (ar
->arSsid
[0] && erq
->length
) {
1026 if (ar
->arWlanState
== WLAN_DISABLED
) {
1030 index
= erq
->flags
& IW_ENCODE_INDEX
;
1032 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1033 ((index
- 1) > WMI_MAX_KEY_INDEX
)))
1038 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1040 * Encryption disabled
1044 * If key index was specified then clear the specified key
1047 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1048 sizeof(ar
->arWepKeyList
[index
].arKey
));
1049 ar
->arWepKeyList
[index
].arKeyLen
= 0;
1051 ar
->arDot11AuthMode
= OPEN_AUTH
;
1052 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1053 ar
->arGroupCrypto
= NONE_CRYPT
;
1054 ar
->arAuthMode
= NONE_AUTH
;
1057 * Enabling WEP encryption
1060 index
--; /* keyindex is off base 1 in iwconfig */
1063 if (erq
->flags
& IW_ENCODE_OPEN
) {
1065 ar
->arDefTxKeyIndex
= index
;
1067 if (erq
->flags
& IW_ENCODE_RESTRICTED
) {
1068 auth
|= SHARED_AUTH
;
1076 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(erq
->length
)) {
1080 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1081 sizeof(ar
->arWepKeyList
[index
].arKey
));
1082 A_MEMCPY(ar
->arWepKeyList
[index
].arKey
, keybuf
, erq
->length
);
1083 ar
->arWepKeyList
[index
].arKeyLen
= erq
->length
;
1084 ar
->arDot11AuthMode
= auth
;
1086 if (ar
->arWepKeyList
[index
].arKeyLen
== 0) {
1089 ar
->arDefTxKeyIndex
= index
;
1091 if(ar
->arSsidLen
&& ar
->arWepKeyList
[index
].arKeyLen
) {
1092 wmi_addKey_cmd(ar
->arWmi
,
1095 GROUP_USAGE
| TX_USAGE
,
1096 ar
->arWepKeyList
[index
].arKeyLen
,
1098 ar
->arWepKeyList
[index
].arKey
, KEY_OP_INIT_VAL
, NULL
,
1103 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1104 ar
->arGroupCrypto
= WEP_CRYPT
;
1105 ar
->arAuthMode
= NONE_AUTH
;
1108 if(ar
->arNextMode
!= AP_NETWORK
) {
1110 * profile has changed. Erase ssid to signal change
1112 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1115 ar
->ap_profile_flag
= 1; /* There is a change in profile */
1120 ar6000_ioctl_giwencode(struct net_device
*dev
,
1121 struct iw_request_info
*info
,
1122 struct iw_point
*erq
, char *key
)
1124 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1126 struct ar_wep_key
*wk
;
1128 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1129 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1133 if (ar
->arWlanState
== WLAN_DISABLED
) {
1137 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1139 erq
->flags
= IW_ENCODE_DISABLED
;
1141 if (ar
->arPairwiseCrypto
== WEP_CRYPT
) {
1142 /* get the keyIndex */
1143 keyIndex
= erq
->flags
& IW_ENCODE_INDEX
;
1144 if (0 == keyIndex
) {
1145 keyIndex
= ar
->arDefTxKeyIndex
;
1146 } else if ((keyIndex
- 1 < WMI_MIN_KEY_INDEX
) ||
1147 (keyIndex
- 1 > WMI_MAX_KEY_INDEX
))
1149 keyIndex
= WMI_MIN_KEY_INDEX
;
1153 erq
->flags
= keyIndex
+ 1;
1154 erq
->flags
&= ~IW_ENCODE_DISABLED
;
1155 wk
= &ar
->arWepKeyList
[keyIndex
];
1156 if (erq
->length
> wk
->arKeyLen
) {
1157 erq
->length
= wk
->arKeyLen
;
1160 A_MEMCPY(key
, wk
->arKey
, erq
->length
);
1163 erq
->flags
&= ~IW_ENCODE_DISABLED
;
1164 if (ar
->user_saved_keys
.keyOk
) {
1165 erq
->length
= ar
->user_saved_keys
.ucast_ik
.ik_keylen
;
1167 A_MEMCPY(key
, ar
->user_saved_keys
.ucast_ik
.ik_keydata
, erq
->length
);
1170 erq
->length
= 1; // not really printing any key but let iwconfig know enc is on
1174 if (ar
->arDot11AuthMode
& OPEN_AUTH
) {
1175 erq
->flags
|= IW_ENCODE_OPEN
;
1177 if (ar
->arDot11AuthMode
& SHARED_AUTH
) {
1178 erq
->flags
|= IW_ENCODE_RESTRICTED
;
1185 #if WIRELESS_EXT >= 18
1190 ar6000_ioctl_siwgenie(struct net_device
*dev
,
1191 struct iw_request_info
*info
,
1192 struct iw_point
*erq
, char *extra
)
1194 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1197 u8
*ie
= erq
->pointer
;
1199 u16 ie_length
= erq
->length
;
1203 if (ar
->arWmiReady
== false) {
1207 if (ie_type
== IEEE80211_ELEMID_WAPI
) {
1208 if (ie_length
> 0) {
1209 if (copy_from_user(wapi_ie
, ie
, ie_length
)) {
1213 wmi_set_appie_cmd(ar
->arWmi
, WMI_FRAME_ASSOC_REQ
, ie_length
, wapi_ie
);
1214 } else if (ie_length
== 0) {
1215 wmi_set_appie_cmd(ar
->arWmi
, WMI_FRAME_ASSOC_REQ
, ie_length
, wapi_ie
);
1226 ar6000_ioctl_giwgenie(struct net_device
*dev
,
1227 struct iw_request_info
*info
,
1228 struct iw_point
*erq
, char *extra
)
1230 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1232 if (ar
->arWmiReady
== false) {
1245 ar6000_ioctl_siwauth(struct net_device
*dev
,
1246 struct iw_request_info
*info
,
1247 struct iw_param
*data
, char *extra
)
1249 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1256 if (ar
->arWmiReady
== false) {
1260 if (ar
->arWlanState
== WLAN_DISABLED
) {
1264 param
= data
->flags
& IW_AUTH_INDEX
;
1265 value
= data
->value
;
1270 case IW_AUTH_WPA_VERSION
:
1271 if (value
& IW_AUTH_WPA_VERSION_DISABLED
) {
1272 ar
->arAuthMode
= NONE_AUTH
;
1273 } else if (value
& IW_AUTH_WPA_VERSION_WPA
) {
1274 ar
->arAuthMode
= WPA_AUTH
;
1275 } else if (value
& IW_AUTH_WPA_VERSION_WPA2
) {
1276 ar
->arAuthMode
= WPA2_AUTH
;
1279 profChanged
= false;
1282 case IW_AUTH_CIPHER_PAIRWISE
:
1283 if (value
& IW_AUTH_CIPHER_NONE
) {
1284 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1285 ar
->arPairwiseCryptoLen
= 0;
1286 } else if (value
& IW_AUTH_CIPHER_WEP40
) {
1287 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1288 ar
->arPairwiseCryptoLen
= 5;
1289 } else if (value
& IW_AUTH_CIPHER_TKIP
) {
1290 ar
->arPairwiseCrypto
= TKIP_CRYPT
;
1291 ar
->arPairwiseCryptoLen
= 0;
1292 } else if (value
& IW_AUTH_CIPHER_CCMP
) {
1293 ar
->arPairwiseCrypto
= AES_CRYPT
;
1294 ar
->arPairwiseCryptoLen
= 0;
1295 } else if (value
& IW_AUTH_CIPHER_WEP104
) {
1296 ar
->arPairwiseCrypto
= WEP_CRYPT
;
1297 ar
->arPairwiseCryptoLen
= 13;
1300 profChanged
= false;
1303 case IW_AUTH_CIPHER_GROUP
:
1304 if (value
& IW_AUTH_CIPHER_NONE
) {
1305 ar
->arGroupCrypto
= NONE_CRYPT
;
1306 ar
->arGroupCryptoLen
= 0;
1307 } else if (value
& IW_AUTH_CIPHER_WEP40
) {
1308 ar
->arGroupCrypto
= WEP_CRYPT
;
1309 ar
->arGroupCryptoLen
= 5;
1310 } else if (value
& IW_AUTH_CIPHER_TKIP
) {
1311 ar
->arGroupCrypto
= TKIP_CRYPT
;
1312 ar
->arGroupCryptoLen
= 0;
1313 } else if (value
& IW_AUTH_CIPHER_CCMP
) {
1314 ar
->arGroupCrypto
= AES_CRYPT
;
1315 ar
->arGroupCryptoLen
= 0;
1316 } else if (value
& IW_AUTH_CIPHER_WEP104
) {
1317 ar
->arGroupCrypto
= WEP_CRYPT
;
1318 ar
->arGroupCryptoLen
= 13;
1321 profChanged
= false;
1324 case IW_AUTH_KEY_MGMT
:
1325 if (value
& IW_AUTH_KEY_MGMT_PSK
) {
1326 if (WPA_AUTH
== ar
->arAuthMode
) {
1327 ar
->arAuthMode
= WPA_PSK_AUTH
;
1328 } else if (WPA2_AUTH
== ar
->arAuthMode
) {
1329 ar
->arAuthMode
= WPA2_PSK_AUTH
;
1333 } else if (!(value
& IW_AUTH_KEY_MGMT_802_1X
)) {
1334 ar
->arAuthMode
= NONE_AUTH
;
1337 case IW_AUTH_TKIP_COUNTERMEASURES
:
1338 wmi_set_tkip_countermeasures_cmd(ar
->arWmi
, value
);
1339 profChanged
= false;
1341 case IW_AUTH_DROP_UNENCRYPTED
:
1342 profChanged
= false;
1344 case IW_AUTH_80211_AUTH_ALG
:
1345 ar
->arDot11AuthMode
= 0;
1346 if (value
& IW_AUTH_ALG_OPEN_SYSTEM
) {
1347 ar
->arDot11AuthMode
|= OPEN_AUTH
;
1349 if (value
& IW_AUTH_ALG_SHARED_KEY
) {
1350 ar
->arDot11AuthMode
|= SHARED_AUTH
;
1352 if (value
& IW_AUTH_ALG_LEAP
) {
1353 ar
->arDot11AuthMode
= LEAP_AUTH
;
1355 if(ar
->arDot11AuthMode
== 0) {
1357 profChanged
= false;
1360 case IW_AUTH_WPA_ENABLED
:
1362 ar
->arAuthMode
= NONE_AUTH
;
1363 /* when the supplicant is stopped, it calls this
1364 * handler with value=0. The followings need to be
1365 * reset if the STA were to connect again
1368 ar
->arDot11AuthMode
= OPEN_AUTH
;
1369 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1370 ar
->arPairwiseCryptoLen
= 0;
1371 ar
->arGroupCrypto
= NONE_CRYPT
;
1372 ar
->arGroupCryptoLen
= 0;
1375 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1376 profChanged
= false;
1378 case IW_AUTH_ROAMING_CONTROL
:
1379 profChanged
= false;
1381 case IW_AUTH_PRIVACY_INVOKED
:
1383 ar
->arPairwiseCrypto
= NONE_CRYPT
;
1384 ar
->arPairwiseCryptoLen
= 0;
1385 ar
->arGroupCrypto
= NONE_CRYPT
;
1386 ar
->arGroupCryptoLen
= 0;
1390 case IW_AUTH_WAPI_ENABLED
:
1391 ar
->arWapiEnable
= value
;
1396 profChanged
= false;
1400 if (profChanged
== true) {
1402 * profile has changed. Erase ssid to signal change
1404 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
1416 ar6000_ioctl_giwauth(struct net_device
*dev
,
1417 struct iw_request_info
*info
,
1418 struct iw_param
*data
, char *extra
)
1420 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1424 if (ar
->arWmiReady
== false) {
1428 if (ar
->arWlanState
== WLAN_DISABLED
) {
1432 param
= data
->flags
& IW_AUTH_INDEX
;
1438 case IW_AUTH_WPA_VERSION
:
1439 if (ar
->arAuthMode
== NONE_AUTH
) {
1440 data
->value
|= IW_AUTH_WPA_VERSION_DISABLED
;
1441 } else if (ar
->arAuthMode
== WPA_AUTH
) {
1442 data
->value
|= IW_AUTH_WPA_VERSION_WPA
;
1443 } else if (ar
->arAuthMode
== WPA2_AUTH
) {
1444 data
->value
|= IW_AUTH_WPA_VERSION_WPA2
;
1449 case IW_AUTH_CIPHER_PAIRWISE
:
1450 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1451 data
->value
|= IW_AUTH_CIPHER_NONE
;
1452 } else if (ar
->arPairwiseCrypto
== WEP_CRYPT
) {
1453 if (ar
->arPairwiseCryptoLen
== 13) {
1454 data
->value
|= IW_AUTH_CIPHER_WEP104
;
1456 data
->value
|= IW_AUTH_CIPHER_WEP40
;
1458 } else if (ar
->arPairwiseCrypto
== TKIP_CRYPT
) {
1459 data
->value
|= IW_AUTH_CIPHER_TKIP
;
1460 } else if (ar
->arPairwiseCrypto
== AES_CRYPT
) {
1461 data
->value
|= IW_AUTH_CIPHER_CCMP
;
1466 case IW_AUTH_CIPHER_GROUP
:
1467 if (ar
->arGroupCrypto
== NONE_CRYPT
) {
1468 data
->value
|= IW_AUTH_CIPHER_NONE
;
1469 } else if (ar
->arGroupCrypto
== WEP_CRYPT
) {
1470 if (ar
->arGroupCryptoLen
== 13) {
1471 data
->value
|= IW_AUTH_CIPHER_WEP104
;
1473 data
->value
|= IW_AUTH_CIPHER_WEP40
;
1475 } else if (ar
->arGroupCrypto
== TKIP_CRYPT
) {
1476 data
->value
|= IW_AUTH_CIPHER_TKIP
;
1477 } else if (ar
->arGroupCrypto
== AES_CRYPT
) {
1478 data
->value
|= IW_AUTH_CIPHER_CCMP
;
1483 case IW_AUTH_KEY_MGMT
:
1484 if ((ar
->arAuthMode
== WPA_PSK_AUTH
) ||
1485 (ar
->arAuthMode
== WPA2_PSK_AUTH
)) {
1486 data
->value
|= IW_AUTH_KEY_MGMT_PSK
;
1487 } else if ((ar
->arAuthMode
== WPA_AUTH
) ||
1488 (ar
->arAuthMode
== WPA2_AUTH
)) {
1489 data
->value
|= IW_AUTH_KEY_MGMT_802_1X
;
1492 case IW_AUTH_TKIP_COUNTERMEASURES
:
1493 // TODO. Save countermeassure enable/disable
1496 case IW_AUTH_DROP_UNENCRYPTED
:
1498 case IW_AUTH_80211_AUTH_ALG
:
1499 if (ar
->arDot11AuthMode
== OPEN_AUTH
) {
1500 data
->value
|= IW_AUTH_ALG_OPEN_SYSTEM
;
1501 } else if (ar
->arDot11AuthMode
== SHARED_AUTH
) {
1502 data
->value
|= IW_AUTH_ALG_SHARED_KEY
;
1503 } else if (ar
->arDot11AuthMode
== LEAP_AUTH
) {
1504 data
->value
|= IW_AUTH_ALG_LEAP
;
1509 case IW_AUTH_WPA_ENABLED
:
1510 if (ar
->arAuthMode
== NONE_AUTH
) {
1516 case IW_AUTH_RX_UNENCRYPTED_EAPOL
:
1518 case IW_AUTH_ROAMING_CONTROL
:
1520 case IW_AUTH_PRIVACY_INVOKED
:
1521 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1528 case IW_AUTH_WAPI_ENABLED
:
1529 data
->value
= ar
->arWapiEnable
;
1544 ar6000_ioctl_siwpmksa(struct net_device
*dev
,
1545 struct iw_request_info
*info
,
1546 struct iw_point
*data
, char *extra
)
1548 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1551 struct iw_pmksa
*pmksa
;
1553 pmksa
= (struct iw_pmksa
*)extra
;
1555 if (ar
->arWmiReady
== false) {
1562 switch (pmksa
->cmd
) {
1564 status
= wmi_setPmkid_cmd(ar
->arWmi
, (u8
*)pmksa
->bssid
.sa_data
, pmksa
->pmkid
, true);
1566 case IW_PMKSA_REMOVE
:
1567 status
= wmi_setPmkid_cmd(ar
->arWmi
, (u8
*)pmksa
->bssid
.sa_data
, pmksa
->pmkid
, false);
1569 case IW_PMKSA_FLUSH
:
1570 if (ar
->arConnected
== true) {
1571 status
= wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
1578 if (status
!= A_OK
) {
1587 #define PN_INIT 0x5c365c36
1589 static int ar6000_set_wapi_key(struct net_device
*dev
,
1590 struct iw_request_info
*info
,
1591 struct iw_point
*erq
, char *extra
)
1593 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1594 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1595 KEY_USAGE keyUsage
= 0;
1603 CRYPTO_TYPE keyType
= WAPI_CRYPT
;
1604 const u8 broadcastMac
[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
1606 index
= erq
->flags
& IW_ENCODE_INDEX
;
1607 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1608 ((index
- 1) > WMI_MAX_KEY_INDEX
))) {
1613 if (index
< 0 || index
> 4) {
1616 keyData
= (u8
*)(ext
+ 1);
1617 keyLen
= erq
->length
- sizeof(struct iw_encode_ext
);
1618 A_MEMCPY(wapiKeyRsc
, ext
->tx_seq
, sizeof(wapiKeyRsc
));
1620 if (A_MEMCMP(ext
->addr
.sa_data
, broadcastMac
, sizeof(broadcastMac
)) == 0) {
1621 keyUsage
|= GROUP_USAGE
;
1622 PN
= (u32
*)wapiKeyRsc
;
1623 for (i
= 0; i
< 4; i
++) {
1627 keyUsage
|= PAIRWISE_USAGE
;
1629 status
= wmi_addKey_cmd(ar
->arWmi
,
1638 SYNC_BEFORE_WMIFLAG
);
1639 if (A_OK
!= status
) {
1651 ar6000_ioctl_siwencodeext(struct net_device
*dev
,
1652 struct iw_request_info
*info
,
1653 struct iw_point
*erq
, char *extra
)
1655 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1657 struct iw_encode_ext
*ext
;
1663 CRYPTO_TYPE keyType
;
1665 struct ieee80211req_key ik
;
1666 #endif /* USER_KEYS */
1668 if (ar
->arWlanState
== WLAN_DISABLED
) {
1673 ar
->user_saved_keys
.keyOk
= false;
1674 #endif /* USER_KEYS */
1676 index
= erq
->flags
& IW_ENCODE_INDEX
;
1678 if (index
&& (((index
- 1) < WMI_MIN_KEY_INDEX
) ||
1679 ((index
- 1) > WMI_MAX_KEY_INDEX
)))
1684 ext
= (struct iw_encode_ext
*)extra
;
1685 if (erq
->flags
& IW_ENCODE_DISABLED
) {
1687 * Encryption disabled
1691 * If key index was specified then clear the specified key
1694 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1695 sizeof(ar
->arWepKeyList
[index
].arKey
));
1696 ar
->arWepKeyList
[index
].arKeyLen
= 0;
1700 * Enabling WEP encryption
1703 index
--; /* keyindex is off base 1 in iwconfig */
1707 keyLen
= erq
->length
- sizeof(struct iw_encode_ext
);
1709 if (ext
->ext_flags
& IW_ENCODE_EXT_SET_TX_KEY
) {
1710 keyUsage
= TX_USAGE
;
1711 ar
->arDefTxKeyIndex
= index
;
1712 // Just setting the key index
1722 /* key follows iw_encode_ext */
1723 keyData
= (u8
*)(ext
+ 1);
1726 case IW_ENCODE_ALG_WEP
:
1727 keyType
= WEP_CRYPT
;
1729 ik
.ik_type
= IEEE80211_CIPHER_WEP
;
1730 #endif /* USER_KEYS */
1731 if (!IEEE80211_IS_VALID_WEP_CIPHER_LEN(keyLen
)) {
1735 /* Check whether it is static wep. */
1736 if (!ar
->arConnected
) {
1737 A_MEMZERO(ar
->arWepKeyList
[index
].arKey
,
1738 sizeof(ar
->arWepKeyList
[index
].arKey
));
1739 A_MEMCPY(ar
->arWepKeyList
[index
].arKey
, keyData
, keyLen
);
1740 ar
->arWepKeyList
[index
].arKeyLen
= keyLen
;
1745 case IW_ENCODE_ALG_TKIP
:
1746 keyType
= TKIP_CRYPT
;
1748 ik
.ik_type
= IEEE80211_CIPHER_TKIP
;
1749 #endif /* USER_KEYS */
1751 case IW_ENCODE_ALG_CCMP
:
1752 keyType
= AES_CRYPT
;
1754 ik
.ik_type
= IEEE80211_CIPHER_AES_CCM
;
1755 #endif /* USER_KEYS */
1758 case IW_ENCODE_ALG_SM4
:
1759 if (ar
->arWapiEnable
) {
1760 return ar6000_set_wapi_key(dev
, info
, erq
, extra
);
1765 case IW_ENCODE_ALG_PMK
:
1766 ar
->arConnectCtrlFlags
|= CONNECT_DO_WPA_OFFLOAD
;
1767 return wmi_set_pmk_cmd(ar
->arWmi
, keyData
);
1773 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1774 keyUsage
|= GROUP_USAGE
;
1776 keyUsage
|= PAIRWISE_USAGE
;
1779 if (ext
->ext_flags
& IW_ENCODE_EXT_RX_SEQ_VALID
) {
1780 A_MEMCPY(keyRsc
, ext
->rx_seq
, sizeof(keyRsc
));
1782 A_MEMZERO(keyRsc
, sizeof(keyRsc
));
1785 if (((WPA_PSK_AUTH
== ar
->arAuthMode
) || (WPA2_PSK_AUTH
== ar
->arAuthMode
)) &&
1786 (GROUP_USAGE
& keyUsage
))
1788 A_UNTIMEOUT(&ar
->disconnect_timer
);
1791 status
= wmi_addKey_cmd(ar
->arWmi
, index
, keyType
, keyUsage
,
1793 keyData
, KEY_OP_INIT_VAL
,
1794 (u8
*)ext
->addr
.sa_data
,
1796 if (status
!= A_OK
) {
1801 ik
.ik_keyix
= index
;
1802 ik
.ik_keylen
= keyLen
;
1803 memcpy(ik
.ik_keydata
, keyData
, keyLen
);
1804 memcpy(&ik
.ik_keyrsc
, keyRsc
, sizeof(keyRsc
));
1805 memcpy(ik
.ik_macaddr
, ext
->addr
.sa_data
, ETH_ALEN
);
1806 if (ext
->ext_flags
& IW_ENCODE_EXT_GROUP_KEY
) {
1807 memcpy(&ar
->user_saved_keys
.bcast_ik
, &ik
,
1808 sizeof(struct ieee80211req_key
));
1810 memcpy(&ar
->user_saved_keys
.ucast_ik
, &ik
,
1811 sizeof(struct ieee80211req_key
));
1813 ar
->user_saved_keys
.keyOk
= true;
1814 #endif /* USER_KEYS */
1825 ar6000_ioctl_giwencodeext(struct net_device
*dev
,
1826 struct iw_request_info
*info
,
1827 struct iw_point
*erq
, char *extra
)
1829 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1831 if (ar
->arWlanState
== WLAN_DISABLED
) {
1835 if (ar
->arPairwiseCrypto
== NONE_CRYPT
) {
1837 erq
->flags
= IW_ENCODE_DISABLED
;
1844 #endif // WIRELESS_EXT >= 18
1846 #if WIRELESS_EXT > 20
1847 static int ar6000_ioctl_siwpower(struct net_device
*dev
,
1848 struct iw_request_info
*info
,
1849 union iwreq_data
*wrqu
, char *extra
)
1851 #ifndef ATH6K_CONFIG_OTA_MODE
1852 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1853 WMI_POWER_MODE power_mode
;
1855 if (ar
->arWmiReady
== false) {
1859 if (ar
->arWlanState
== WLAN_DISABLED
) {
1863 if (wrqu
->power
.disabled
)
1864 power_mode
= MAX_PERF_POWER
;
1866 power_mode
= REC_POWER
;
1868 if (wmi_powermode_cmd(ar
->arWmi
, power_mode
) < 0)
1874 static int ar6000_ioctl_giwpower(struct net_device
*dev
,
1875 struct iw_request_info
*info
,
1876 union iwreq_data
*wrqu
, char *extra
)
1878 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1879 WMI_POWER_MODE power_mode
;
1881 if (ar
->arWmiReady
== false) {
1885 if (ar
->arWlanState
== WLAN_DISABLED
) {
1889 power_mode
= wmi_get_power_mode_cmd(ar
->arWmi
);
1891 if (power_mode
== MAX_PERF_POWER
)
1892 wrqu
->power
.disabled
= 1;
1894 wrqu
->power
.disabled
= 0;
1898 #endif // WIRELESS_EXT > 20
1904 ar6000_ioctl_giwname(struct net_device
*dev
,
1905 struct iw_request_info
*info
,
1906 char *name
, char *extra
)
1909 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1911 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1912 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1916 if (ar
->arWlanState
== WLAN_DISABLED
) {
1920 capability
= ar
->arPhyCapability
;
1921 if(ar
->arNetworkType
== INFRA_NETWORK
&& ar
->arConnected
) {
1922 bss_t
*bss
= wmi_find_node(ar
->arWmi
, ar
->arBssid
);
1924 capability
= get_bss_phy_capability(bss
);
1925 wmi_node_return(ar
->arWmi
, bss
);
1928 switch (capability
) {
1929 case (WMI_11A_CAPABILITY
):
1930 strncpy(name
, "AR6000 802.11a", IFNAMSIZ
);
1932 case (WMI_11G_CAPABILITY
):
1933 strncpy(name
, "AR6000 802.11g", IFNAMSIZ
);
1935 case (WMI_11AG_CAPABILITY
):
1936 strncpy(name
, "AR6000 802.11ag", IFNAMSIZ
);
1938 case (WMI_11NA_CAPABILITY
):
1939 strncpy(name
, "AR6000 802.11na", IFNAMSIZ
);
1941 case (WMI_11NG_CAPABILITY
):
1942 strncpy(name
, "AR6000 802.11ng", IFNAMSIZ
);
1944 case (WMI_11NAG_CAPABILITY
):
1945 strncpy(name
, "AR6000 802.11nag", IFNAMSIZ
);
1948 strncpy(name
, "AR6000 802.11b", IFNAMSIZ
);
1959 ar6000_ioctl_siwfreq(struct net_device
*dev
,
1960 struct iw_request_info
*info
,
1961 struct iw_freq
*freq
, char *extra
)
1963 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
1965 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
1966 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
1970 if (ar
->arWlanState
== WLAN_DISABLED
) {
1975 * We support limiting the channels via wmiconfig.
1977 * We use this command to configure the channel hint for the connect cmd
1978 * so it is possible the target will end up connecting to a different
1983 } else if (freq
->e
== 1) {
1984 ar
->arChannelHint
= freq
->m
/ 100000;
1987 ar
->arChannelHint
= wlan_ieee2freq(freq
->m
);
1989 /* Auto Channel Selection */
1990 ar
->arChannelHint
= 0;
1994 ar
->ap_profile_flag
= 1; /* There is a change in profile */
1996 A_PRINTF("channel hint set to %d\n", ar
->arChannelHint
);
2004 ar6000_ioctl_giwfreq(struct net_device
*dev
,
2005 struct iw_request_info
*info
,
2006 struct iw_freq
*freq
, char *extra
)
2008 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2010 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2011 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2015 if (ar
->arWlanState
== WLAN_DISABLED
) {
2019 if (ar
->arNetworkType
== AP_NETWORK
) {
2020 if(ar
->arChannelHint
) {
2021 freq
->m
= ar
->arChannelHint
* 100000;
2022 } else if(ar
->arACS
) {
2023 freq
->m
= ar
->arACS
* 100000;
2028 if (ar
->arConnected
!= true) {
2031 freq
->m
= ar
->arBssChannel
* 100000;
2044 ar6000_ioctl_siwmode(struct net_device
*dev
,
2045 struct iw_request_info
*info
,
2046 __u32
*mode
, char *extra
)
2048 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2050 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2051 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2055 if (ar
->arWlanState
== WLAN_DISABLED
) {
2060 * clear SSID during mode switch in connected state
2062 if(!(ar
->arNetworkType
== (((*mode
) == IW_MODE_INFRA
) ? INFRA_NETWORK
: ADHOC_NETWORK
)) && (ar
->arConnected
== true) ){
2063 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2069 ar
->arNextMode
= INFRA_NETWORK
;
2072 ar
->arNextMode
= ADHOC_NETWORK
;
2074 case IW_MODE_MASTER
:
2075 ar
->arNextMode
= AP_NETWORK
;
2081 /* clear all shared parameters between AP and STA|IBSS modes when we
2082 * switch between them. Switch between STA & IBSS modes does'nt clear
2083 * the shared profile. This is as per the original design for switching
2084 * between STA & IBSS.
2086 if (ar
->arNetworkType
== AP_NETWORK
|| ar
->arNextMode
== AP_NETWORK
) {
2087 ar
->arDot11AuthMode
= OPEN_AUTH
;
2088 ar
->arAuthMode
= NONE_AUTH
;
2089 ar
->arPairwiseCrypto
= NONE_CRYPT
;
2090 ar
->arPairwiseCryptoLen
= 0;
2091 ar
->arGroupCrypto
= NONE_CRYPT
;
2092 ar
->arGroupCryptoLen
= 0;
2093 ar
->arChannelHint
= 0;
2094 ar
->arBssChannel
= 0;
2095 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2096 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2100 /* SSID has to be cleared to trigger a profile change while switching
2101 * between STA & IBSS modes having the same SSID
2103 if (ar
->arNetworkType
!= ar
->arNextMode
) {
2104 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2115 ar6000_ioctl_giwmode(struct net_device
*dev
,
2116 struct iw_request_info
*info
,
2117 __u32
*mode
, char *extra
)
2119 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2121 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2122 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2126 if (ar
->arWlanState
== WLAN_DISABLED
) {
2130 switch (ar
->arNetworkType
) {
2132 *mode
= IW_MODE_INFRA
;
2135 *mode
= IW_MODE_ADHOC
;
2138 *mode
= IW_MODE_MASTER
;
2150 ar6000_ioctl_siwsens(struct net_device
*dev
,
2151 struct iw_request_info
*info
,
2152 struct iw_param
*sens
, char *extra
)
2161 ar6000_ioctl_giwsens(struct net_device
*dev
,
2162 struct iw_request_info
*info
,
2163 struct iw_param
*sens
, char *extra
)
2175 ar6000_ioctl_giwrange(struct net_device
*dev
,
2176 struct iw_request_info
*info
,
2177 struct iw_point
*data
, char *extra
)
2179 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2180 struct iw_range
*range
= (struct iw_range
*) extra
;
2183 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2184 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2188 if (ar
->bIsDestroyProgress
) {
2192 if (ar
->arWmiReady
== false) {
2196 if (down_interruptible(&ar
->arSem
)) {
2197 return -ERESTARTSYS
;
2200 if (ar
->bIsDestroyProgress
) {
2205 ar
->arNumChannels
= -1;
2206 A_MEMZERO(ar
->arChannelList
, sizeof (ar
->arChannelList
));
2208 if (wmi_get_channelList_cmd(ar
->arWmi
) != A_OK
) {
2213 wait_event_interruptible_timeout(arEvent
, ar
->arNumChannels
!= -1, wmitimeout
* HZ
);
2215 if (signal_pending(current
)) {
2220 data
->length
= sizeof(struct iw_range
);
2221 A_MEMZERO(range
, sizeof(struct iw_range
));
2223 range
->txpower_capa
= 0;
2225 range
->min_pmp
= 1 * 1024;
2226 range
->max_pmp
= 65535 * 1024;
2227 range
->min_pmt
= 1 * 1024;
2228 range
->max_pmt
= 1000 * 1024;
2229 range
->pmp_flags
= IW_POWER_PERIOD
;
2230 range
->pmt_flags
= IW_POWER_TIMEOUT
;
2233 range
->we_version_compiled
= WIRELESS_EXT
;
2234 range
->we_version_source
= 13;
2236 range
->retry_capa
= IW_RETRY_LIMIT
;
2237 range
->retry_flags
= IW_RETRY_LIMIT
;
2238 range
->min_retry
= 0;
2239 range
->max_retry
= 255;
2241 range
->num_frequency
= range
->num_channels
= ar
->arNumChannels
;
2242 for (i
= 0; i
< ar
->arNumChannels
; i
++) {
2243 range
->freq
[i
].i
= wlan_freq2ieee(ar
->arChannelList
[i
]);
2244 range
->freq
[i
].m
= ar
->arChannelList
[i
] * 100000;
2245 range
->freq
[i
].e
= 1;
2247 * Linux supports max of 32 channels, bail out once you
2250 if (i
== IW_MAX_FREQUENCIES
) {
2255 /* Max quality is max field value minus noise floor */
2256 range
->max_qual
.qual
= 0xff - 161;
2259 * In order to use dBm measurements, 'level' must be lower
2260 * than any possible measurement (see iw_print_stats() in
2261 * wireless tools). It's unclear how this is meant to be
2262 * done, but setting zero in these values forces dBm and
2263 * the actual numbers are not used.
2265 range
->max_qual
.level
= 0;
2266 range
->max_qual
.noise
= 0;
2268 range
->sensitivity
= 3;
2270 range
->max_encoding_tokens
= 4;
2271 /* XXX query driver to find out supported key sizes */
2272 range
->num_encoding_sizes
= 3;
2273 range
->encoding_size
[0] = 5; /* 40-bit */
2274 range
->encoding_size
[1] = 13; /* 104-bit */
2275 range
->encoding_size
[2] = 16; /* 128-bit */
2277 range
->num_bitrates
= 0;
2279 /* estimated maximum TCP throughput values (bps) */
2280 range
->throughput
= 22000000;
2283 range
->max_rts
= 2347;
2284 range
->min_frag
= 256;
2285 range
->max_frag
= 2346;
2295 * This ioctl is used to set the desired bssid for the connect command.
2298 ar6000_ioctl_siwap(struct net_device
*dev
,
2299 struct iw_request_info
*info
,
2300 struct sockaddr
*ap_addr
, char *extra
)
2302 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2304 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2305 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2309 if (ar
->arWlanState
== WLAN_DISABLED
) {
2313 if (ap_addr
->sa_family
!= ARPHRD_ETHER
) {
2317 if (A_MEMCMP(&ap_addr
->sa_data
, bcast_mac
, AR6000_ETH_ADDR_LEN
) == 0) {
2318 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
2320 A_MEMCPY(ar
->arReqBssid
, &ap_addr
->sa_data
, sizeof(ar
->arReqBssid
));
2330 ar6000_ioctl_giwap(struct net_device
*dev
,
2331 struct iw_request_info
*info
,
2332 struct sockaddr
*ap_addr
, char *extra
)
2334 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2336 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2337 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2341 if (ar
->arWlanState
== WLAN_DISABLED
) {
2345 if (ar
->arNetworkType
== AP_NETWORK
) {
2346 A_MEMCPY(&ap_addr
->sa_data
, dev
->dev_addr
, ATH_MAC_LEN
);
2347 ap_addr
->sa_family
= ARPHRD_ETHER
;
2351 if (ar
->arConnected
!= true) {
2355 A_MEMCPY(&ap_addr
->sa_data
, ar
->arBssid
, sizeof(ar
->arBssid
));
2356 ap_addr
->sa_family
= ARPHRD_ETHER
;
2361 #if (WIRELESS_EXT >= 18)
2366 ar6000_ioctl_siwmlme(struct net_device
*dev
,
2367 struct iw_request_info
*info
,
2368 struct iw_point
*data
, char *extra
)
2370 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2372 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2373 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2377 if (ar
->bIsDestroyProgress
) {
2381 if (ar
->arWlanState
== WLAN_DISABLED
) {
2385 if (ar
->arWmiReady
== false) {
2389 if (down_interruptible(&ar
->arSem
)) {
2390 return -ERESTARTSYS
;
2393 if (data
->pointer
&& data
->length
== sizeof(struct iw_mlme
)) {
2396 struct iw_mlme mlme
;
2398 if (copy_from_user(&mlme
, data
->pointer
, sizeof(struct iw_mlme
)))
2403 case IW_MLME_DEAUTH
:
2405 case IW_MLME_DISASSOC
:
2406 if ((ar
->arConnected
!= true) ||
2407 (memcmp(ar
->arBssid
, mlme
.addr
.sa_data
, 6) != 0)) {
2412 wmi_setPmkid_cmd(ar
->arWmi
, ar
->arBssid
, NULL
, 0);
2413 arNetworkType
= ar
->arNetworkType
;
2414 ar6000_init_profile_info(ar
);
2415 ar
->arNetworkType
= arNetworkType
;
2417 wmi_disconnect_cmd(ar
->arWmi
);
2418 A_MEMZERO(ar
->arSsid
, sizeof(ar
->arSsid
));
2420 if (ar
->arSkipScan
== false) {
2421 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
2438 #endif /* WIRELESS_EXT >= 18 */
2444 ar6000_ioctl_iwaplist(struct net_device
*dev
,
2445 struct iw_request_info
*info
,
2446 struct iw_point
*data
, char *extra
)
2448 return -EIO
; /* for now */
2455 ar6000_ioctl_siwscan(struct net_device
*dev
,
2456 struct iw_request_info
*info
,
2457 struct iw_point
*data
, char *extra
)
2459 #define ACT_DWELLTIME_DEFAULT 105
2460 #define HOME_TXDRAIN_TIME 100
2461 #define SCAN_INT HOME_TXDRAIN_TIME + ACT_DWELLTIME_DEFAULT
2462 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2465 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2466 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2470 if (ar
->arWmiReady
== false) {
2474 if (ar
->arWlanState
== WLAN_DISABLED
) {
2478 /* If scan is issued in the middle of ongoing scan or connect,
2479 dont issue another one */
2480 if ( ar
->scan_triggered
> 0 ) {
2481 ++ar
->scan_triggered
;
2482 if (ar
->scan_triggered
< 5) {
2485 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_SCAN
,("Scan request is triggered over 5 times. Not scan complete event\n"));
2489 if (!ar
->arUserBssFilter
) {
2490 if (wmi_bssfilter_cmd(ar
->arWmi
, ALL_BSS_FILTER
, 0) != A_OK
) {
2495 if (ar
->arConnected
) {
2496 if (wmi_get_stats_cmd(ar
->arWmi
) != A_OK
) {
2502 #if WIRELESS_EXT >= 18
2503 if (data
->pointer
&& (data
->length
== sizeof(struct iw_scan_req
)))
2505 if ((data
->flags
& IW_SCAN_THIS_ESSID
) == IW_SCAN_THIS_ESSID
)
2507 struct iw_scan_req req
;
2508 if (copy_from_user(&req
, data
->pointer
, sizeof(struct iw_scan_req
)))
2510 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, SPECIFIC_SSID_FLAG
, req
.essid_len
, req
.essid
) != A_OK
)
2512 ar
->scanSpecificSsid
= true;
2516 if (ar
->scanSpecificSsid
) {
2517 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != A_OK
)
2519 ar
->scanSpecificSsid
= false;
2525 if (ar
->scanSpecificSsid
) {
2526 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != A_OK
)
2528 ar
->scanSpecificSsid
= false;
2532 #endif /* ANDROID_ENV */
2534 if (wmi_startscan_cmd(ar
->arWmi
, WMI_LONG_SCAN
, false, false, \
2535 0, 0, 0, NULL
) != A_OK
) {
2540 ar
->scan_triggered
= 1;
2544 #undef ACT_DWELLTIME_DEFAULT
2545 #undef HOME_TXDRAIN_TIME
2551 * Units are in db above the noise floor. That means the
2552 * rssi values reported in the tx/rx descriptors in the
2553 * driver are the SNR expressed in db.
2555 * If you assume that the noise floor is -95, which is an
2556 * excellent assumption 99.5 % of the time, then you can
2557 * derive the absolute signal level (i.e. -95 + rssi).
2558 * There are some other slight factors to take into account
2559 * depending on whether the rssi measurement is from 11b,
2560 * 11g, or 11a. These differences are at most 2db and
2561 * can be documented.
2563 * NB: various calculations are based on the orinoco/wavelan
2564 * drivers for compatibility
2567 ar6000_set_quality(struct iw_quality
*iq
, A_INT8 rssi
)
2575 /* NB: max is 94 because noise is hardcoded to 161 */
2579 iq
->noise
= 161; /* -95dBm */
2580 iq
->level
= iq
->noise
+ iq
->qual
;
2586 ar6000_ioctl_siwcommit(struct net_device
*dev
,
2587 struct iw_request_info
*info
,
2588 struct iw_point
*data
, char *extra
)
2590 AR_SOFTC_T
*ar
= (AR_SOFTC_T
*)ar6k_priv(dev
);
2592 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != A_OK
) {
2593 A_PRINTF("wext_ioctl: cmd=0x%x not allowed in this mode\n", info
->cmd
);
2597 if (ar
->arWmiReady
== false) {
2601 if (ar
->arWlanState
== WLAN_DISABLED
) {
2605 AR_DEBUG_PRINTF(ATH_DEBUG_WLAN_CONNECT
,("AP: SSID %s freq %d authmode %d dot11 auth %d"\
2606 " PW crypto %d GRP crypto %d\n",
2607 ar
->arSsid
, ar
->arChannelHint
,
2608 ar
->arAuthMode
, ar
->arDot11AuthMode
,
2609 ar
->arPairwiseCrypto
, ar
->arGroupCrypto
));
2611 ar6000_ap_mode_profile_commit(ar
);
2613 /* if there is a profile switch from STA|IBSS mode to AP mode,
2614 * update the host driver association state for the STA|IBSS mode.
2616 if (ar
->arNetworkType
!= AP_NETWORK
&& ar
->arNextMode
== AP_NETWORK
) {
2617 ar
->arConnectPending
= false;
2618 ar
->arConnected
= false;
2619 /* Stop getting pkts from upper stack */
2620 netif_stop_queue(ar
->arNetDev
);
2621 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2622 ar
->arBssChannel
= 0;
2623 ar
->arBeaconInterval
= 0;
2625 /* Flush the Tx queues */
2626 ar6000_TxDataCleanup(ar
);
2628 /* Start getting pkts from upper stack */
2629 netif_wake_queue(ar
->arNetDev
);
2635 #define W_PROTO(_x) wait_ ## _x
2636 #define WAIT_HANDLER_IMPL(_x, type) \
2637 int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
2641 ret = _x(dev, info, wrqu, extra); \
2647 WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid
, struct iw_point
*)
2648 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate
, struct iw_param
*)
2649 WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow
, struct iw_param
*)
2650 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange
, struct iw_point
*)
2652 /* Structures to export the Wireless Handlers */
2653 static const iw_handler ath_handlers
[] = {
2654 (iw_handler
) ar6000_ioctl_siwcommit
, /* SIOCSIWCOMMIT */
2655 (iw_handler
) ar6000_ioctl_giwname
, /* SIOCGIWNAME */
2656 (iw_handler
) NULL
, /* SIOCSIWNWID */
2657 (iw_handler
) NULL
, /* SIOCGIWNWID */
2658 (iw_handler
) ar6000_ioctl_siwfreq
, /* SIOCSIWFREQ */
2659 (iw_handler
) ar6000_ioctl_giwfreq
, /* SIOCGIWFREQ */
2660 (iw_handler
) ar6000_ioctl_siwmode
, /* SIOCSIWMODE */
2661 (iw_handler
) ar6000_ioctl_giwmode
, /* SIOCGIWMODE */
2662 (iw_handler
) ar6000_ioctl_siwsens
, /* SIOCSIWSENS */
2663 (iw_handler
) ar6000_ioctl_giwsens
, /* SIOCGIWSENS */
2664 (iw_handler
) NULL
/* not _used */, /* SIOCSIWRANGE */
2665 (iw_handler
) W_PROTO(ar6000_ioctl_giwrange
),/* SIOCGIWRANGE */
2666 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
2667 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
2668 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
2669 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
2670 (iw_handler
) NULL
, /* SIOCSIWSPY */
2671 (iw_handler
) NULL
, /* SIOCGIWSPY */
2672 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
2673 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
2674 (iw_handler
) ar6000_ioctl_siwap
, /* SIOCSIWAP */
2675 (iw_handler
) ar6000_ioctl_giwap
, /* SIOCGIWAP */
2676 #if (WIRELESS_EXT >= 18)
2677 (iw_handler
) ar6000_ioctl_siwmlme
, /* SIOCSIWMLME */
2679 (iw_handler
) NULL
, /* -- hole -- */
2680 #endif /* WIRELESS_EXT >= 18 */
2681 (iw_handler
) ar6000_ioctl_iwaplist
, /* SIOCGIWAPLIST */
2682 (iw_handler
) ar6000_ioctl_siwscan
, /* SIOCSIWSCAN */
2683 (iw_handler
) ar6000_ioctl_giwscan
, /* SIOCGIWSCAN */
2684 (iw_handler
) W_PROTO(ar6000_ioctl_siwessid
),/* SIOCSIWESSID */
2685 (iw_handler
) ar6000_ioctl_giwessid
, /* SIOCGIWESSID */
2686 (iw_handler
) NULL
, /* SIOCSIWNICKN */
2687 (iw_handler
) NULL
, /* SIOCGIWNICKN */
2688 (iw_handler
) NULL
, /* -- hole -- */
2689 (iw_handler
) NULL
, /* -- hole -- */
2690 (iw_handler
) ar6000_ioctl_siwrate
, /* SIOCSIWRATE */
2691 (iw_handler
) W_PROTO(ar6000_ioctl_giwrate
), /* SIOCGIWRATE */
2692 (iw_handler
) NULL
, /* SIOCSIWRTS */
2693 (iw_handler
) NULL
, /* SIOCGIWRTS */
2694 (iw_handler
) NULL
, /* SIOCSIWFRAG */
2695 (iw_handler
) NULL
, /* SIOCGIWFRAG */
2696 (iw_handler
) ar6000_ioctl_siwtxpow
, /* SIOCSIWTXPOW */
2697 (iw_handler
) W_PROTO(ar6000_ioctl_giwtxpow
),/* SIOCGIWTXPOW */
2698 (iw_handler
) ar6000_ioctl_siwretry
, /* SIOCSIWRETRY */
2699 (iw_handler
) ar6000_ioctl_giwretry
, /* SIOCGIWRETRY */
2700 (iw_handler
) ar6000_ioctl_siwencode
, /* SIOCSIWENCODE */
2701 (iw_handler
) ar6000_ioctl_giwencode
, /* SIOCGIWENCODE */
2702 #if WIRELESS_EXT > 20
2703 (iw_handler
) ar6000_ioctl_siwpower
, /* SIOCSIWPOWER */
2704 (iw_handler
) ar6000_ioctl_giwpower
, /* SIOCGIWPOWER */
2705 #endif // WIRELESS_EXT > 20
2706 #if WIRELESS_EXT >= 18
2707 (iw_handler
) NULL
, /* -- hole -- */
2708 (iw_handler
) NULL
, /* -- hole -- */
2709 (iw_handler
) ar6000_ioctl_siwgenie
, /* SIOCSIWGENIE */
2710 (iw_handler
) ar6000_ioctl_giwgenie
, /* SIOCGIWGENIE */
2711 (iw_handler
) ar6000_ioctl_siwauth
, /* SIOCSIWAUTH */
2712 (iw_handler
) ar6000_ioctl_giwauth
, /* SIOCGIWAUTH */
2713 (iw_handler
) ar6000_ioctl_siwencodeext
, /* SIOCSIWENCODEEXT */
2714 (iw_handler
) ar6000_ioctl_giwencodeext
, /* SIOCGIWENCODEEXT */
2715 (iw_handler
) ar6000_ioctl_siwpmksa
, /* SIOCSIWPMKSA */
2716 #endif // WIRELESS_EXT >= 18
2719 struct iw_handler_def ath_iw_handler_def
= {
2720 .standard
= (iw_handler
*)ath_handlers
,
2721 .num_standard
= ARRAY_SIZE(ath_handlers
),