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
, s8 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 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
420 struct ar_giwscan_param param
;
422 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
467 u8 prevMode
= ar
->arNetworkType
;
469 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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(memcmp(ar
->arSsid
,ssid
,32) != 0) {
508 ar
->arSsidLen
= data
->length
- 1;
509 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
;
578 if ((prevMode
!= AP_NETWORK
) &&
580 ((ar
->arSsidLen
== 0) && (ar
->arConnected
|| ar
->arConnectPending
)) ||
583 if ((!data
->flags
) ||
584 (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 ar6000_disconnect(ar
);
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
,
633 * Dont return if connect is pending.
635 if(!(ar
->arConnectPending
)) {
643 ar
->arSsidLen
= data
->length
- 1;
644 memcpy(ar
->arSsid
, ssid
, ar
->arSsidLen
);
646 if (ar6000_connect_to_ap(ar
)!= 0) {
657 ar6000_ioctl_giwessid(struct net_device
*dev
,
658 struct iw_request_info
*info
,
659 struct iw_point
*data
, char *essid
)
661 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
663 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 memcpy(essid
, ar
->arSsid
, ar
->arSsidLen
);
684 void ar6000_install_static_wep_keys(struct ar6_softc
*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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
719 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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
) != 0)
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) != 0) {
748 ar6000_ioctl_giwrate(struct net_device
*dev
,
749 struct iw_request_info
*info
,
750 struct iw_param
*rrq
, char *extra
)
752 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
755 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
818 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
860 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
929 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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) != 0){
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
970 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1013 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1127 struct ar_wep_key
*wk
;
1129 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 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 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1198 u8
*ie
= erq
->pointer
;
1200 u16 ie_length
= erq
->length
;
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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)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
, (u8
*)pmksa
->bssid
.sa_data
, pmksa
->pmkid
, true);
1567 case IW_PMKSA_REMOVE
:
1568 status
= wmi_setPmkid_cmd(ar
->arWmi
, (u8
*)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);
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1595 struct iw_encode_ext
*ext
= (struct iw_encode_ext
*)extra
;
1596 KEY_USAGE keyUsage
= 0;
1604 CRYPTO_TYPE keyType
= WAPI_CRYPT
;
1605 const u8 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
= (u8
*)(ext
+ 1);
1618 keyLen
= erq
->length
- sizeof(struct iw_encode_ext
);
1619 memcpy(wapiKeyRsc
, ext
->tx_seq
, sizeof(wapiKeyRsc
));
1621 if (memcmp(ext
->addr
.sa_data
, broadcastMac
, sizeof(broadcastMac
)) == 0) {
1622 keyUsage
|= GROUP_USAGE
;
1623 PN
= (u32
*)wapiKeyRsc
;
1624 for (i
= 0; i
< 4; i
++) {
1628 keyUsage
|= PAIRWISE_USAGE
;
1630 status
= wmi_addKey_cmd(ar
->arWmi
,
1639 SYNC_BEFORE_WMIFLAG
);
1652 ar6000_ioctl_siwencodeext(struct net_device
*dev
,
1653 struct iw_request_info
*info
,
1654 struct iw_point
*erq
, char *extra
)
1656 struct ar6_softc
*ar
= (struct ar6_softc
*)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
= (u8
*)(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 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 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 (u8
*)ext
->addr
.sa_data
,
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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1912 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
1966 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2011 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2051 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2122 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2181 struct iw_range
*range
= (struct iw_range
*) extra
;
2184 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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
) != 0) {
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2305 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 (memcmp(&ap_addr
->sa_data
, bcast_mac
, AR6000_ETH_ADDR_LEN
) == 0) {
2319 A_MEMZERO(ar
->arReqBssid
, sizeof(ar
->arReqBssid
));
2321 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2337 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 memcpy(&ap_addr
->sa_data
, dev
->dev_addr
, ATH_MAC_LEN
);
2348 ap_addr
->sa_family
= ARPHRD_ETHER
;
2352 if (ar
->arConnected
!= true) {
2356 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2373 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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
)) {
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 ar6000_disconnect(ar
);
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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2466 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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) != 0) {
2496 if (ar
->arConnected
) {
2497 if (wmi_get_stats_cmd(ar
->arWmi
) != 0) {
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
) != 0)
2513 ar
->scanSpecificSsid
= true;
2517 if (ar
->scanSpecificSsid
) {
2518 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != 0)
2520 ar
->scanSpecificSsid
= false;
2526 if (ar
->scanSpecificSsid
) {
2527 if (wmi_probedSsid_cmd(ar
->arWmi
, 1, DISABLE_SSID_FLAG
, 0, NULL
) != 0)
2529 ar
->scanSpecificSsid
= false;
2533 #endif /* ANDROID_ENV */
2535 if (wmi_startscan_cmd(ar
->arWmi
, WMI_LONG_SCAN
, false, false, \
2536 0, 0, 0, NULL
) != 0) {
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
, s8 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 struct ar6_softc
*ar
= (struct ar6_softc
*)ar6k_priv(dev
);
2593 if (is_iwioctl_allowed(ar
->arNextMode
, info
->cmd
) != 0) {
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 /* Stop getting pkts from upper stack */
2619 netif_stop_queue(ar
->arNetDev
);
2620 A_MEMZERO(ar
->arBssid
, sizeof(ar
->arBssid
));
2621 ar
->arBssChannel
= 0;
2622 ar
->arBeaconInterval
= 0;
2624 /* Flush the Tx queues */
2625 ar6000_TxDataCleanup(ar
);
2627 /* Start getting pkts from upper stack */
2628 netif_wake_queue(ar
->arNetDev
);
2634 #define W_PROTO(_x) wait_ ## _x
2635 #define WAIT_HANDLER_IMPL(_x, type) \
2636 int wait_ ## _x (struct net_device *dev, struct iw_request_info *info, type wrqu, char *extra) {\
2640 ret = _x(dev, info, wrqu, extra); \
2646 WAIT_HANDLER_IMPL(ar6000_ioctl_siwessid
, struct iw_point
*)
2647 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrate
, struct iw_param
*)
2648 WAIT_HANDLER_IMPL(ar6000_ioctl_giwtxpow
, struct iw_param
*)
2649 WAIT_HANDLER_IMPL(ar6000_ioctl_giwrange
, struct iw_point
*)
2651 /* Structures to export the Wireless Handlers */
2652 static const iw_handler ath_handlers
[] = {
2653 (iw_handler
) ar6000_ioctl_siwcommit
, /* SIOCSIWCOMMIT */
2654 (iw_handler
) ar6000_ioctl_giwname
, /* SIOCGIWNAME */
2655 (iw_handler
) NULL
, /* SIOCSIWNWID */
2656 (iw_handler
) NULL
, /* SIOCGIWNWID */
2657 (iw_handler
) ar6000_ioctl_siwfreq
, /* SIOCSIWFREQ */
2658 (iw_handler
) ar6000_ioctl_giwfreq
, /* SIOCGIWFREQ */
2659 (iw_handler
) ar6000_ioctl_siwmode
, /* SIOCSIWMODE */
2660 (iw_handler
) ar6000_ioctl_giwmode
, /* SIOCGIWMODE */
2661 (iw_handler
) ar6000_ioctl_siwsens
, /* SIOCSIWSENS */
2662 (iw_handler
) ar6000_ioctl_giwsens
, /* SIOCGIWSENS */
2663 (iw_handler
) NULL
/* not _used */, /* SIOCSIWRANGE */
2664 (iw_handler
) W_PROTO(ar6000_ioctl_giwrange
),/* SIOCGIWRANGE */
2665 (iw_handler
) NULL
/* not used */, /* SIOCSIWPRIV */
2666 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWPRIV */
2667 (iw_handler
) NULL
/* not used */, /* SIOCSIWSTATS */
2668 (iw_handler
) NULL
/* kernel code */, /* SIOCGIWSTATS */
2669 (iw_handler
) NULL
, /* SIOCSIWSPY */
2670 (iw_handler
) NULL
, /* SIOCGIWSPY */
2671 (iw_handler
) NULL
, /* SIOCSIWTHRSPY */
2672 (iw_handler
) NULL
, /* SIOCGIWTHRSPY */
2673 (iw_handler
) ar6000_ioctl_siwap
, /* SIOCSIWAP */
2674 (iw_handler
) ar6000_ioctl_giwap
, /* SIOCGIWAP */
2675 #if (WIRELESS_EXT >= 18)
2676 (iw_handler
) ar6000_ioctl_siwmlme
, /* SIOCSIWMLME */
2678 (iw_handler
) NULL
, /* -- hole -- */
2679 #endif /* WIRELESS_EXT >= 18 */
2680 (iw_handler
) ar6000_ioctl_iwaplist
, /* SIOCGIWAPLIST */
2681 (iw_handler
) ar6000_ioctl_siwscan
, /* SIOCSIWSCAN */
2682 (iw_handler
) ar6000_ioctl_giwscan
, /* SIOCGIWSCAN */
2683 (iw_handler
) W_PROTO(ar6000_ioctl_siwessid
),/* SIOCSIWESSID */
2684 (iw_handler
) ar6000_ioctl_giwessid
, /* SIOCGIWESSID */
2685 (iw_handler
) NULL
, /* SIOCSIWNICKN */
2686 (iw_handler
) NULL
, /* SIOCGIWNICKN */
2687 (iw_handler
) NULL
, /* -- hole -- */
2688 (iw_handler
) NULL
, /* -- hole -- */
2689 (iw_handler
) ar6000_ioctl_siwrate
, /* SIOCSIWRATE */
2690 (iw_handler
) W_PROTO(ar6000_ioctl_giwrate
), /* SIOCGIWRATE */
2691 (iw_handler
) NULL
, /* SIOCSIWRTS */
2692 (iw_handler
) NULL
, /* SIOCGIWRTS */
2693 (iw_handler
) NULL
, /* SIOCSIWFRAG */
2694 (iw_handler
) NULL
, /* SIOCGIWFRAG */
2695 (iw_handler
) ar6000_ioctl_siwtxpow
, /* SIOCSIWTXPOW */
2696 (iw_handler
) W_PROTO(ar6000_ioctl_giwtxpow
),/* SIOCGIWTXPOW */
2697 (iw_handler
) ar6000_ioctl_siwretry
, /* SIOCSIWRETRY */
2698 (iw_handler
) ar6000_ioctl_giwretry
, /* SIOCGIWRETRY */
2699 (iw_handler
) ar6000_ioctl_siwencode
, /* SIOCSIWENCODE */
2700 (iw_handler
) ar6000_ioctl_giwencode
, /* SIOCGIWENCODE */
2701 #if WIRELESS_EXT > 20
2702 (iw_handler
) ar6000_ioctl_siwpower
, /* SIOCSIWPOWER */
2703 (iw_handler
) ar6000_ioctl_giwpower
, /* SIOCGIWPOWER */
2704 #endif // WIRELESS_EXT > 20
2705 #if WIRELESS_EXT >= 18
2706 (iw_handler
) NULL
, /* -- hole -- */
2707 (iw_handler
) NULL
, /* -- hole -- */
2708 (iw_handler
) ar6000_ioctl_siwgenie
, /* SIOCSIWGENIE */
2709 (iw_handler
) ar6000_ioctl_giwgenie
, /* SIOCGIWGENIE */
2710 (iw_handler
) ar6000_ioctl_siwauth
, /* SIOCSIWAUTH */
2711 (iw_handler
) ar6000_ioctl_giwauth
, /* SIOCGIWAUTH */
2712 (iw_handler
) ar6000_ioctl_siwencodeext
, /* SIOCSIWENCODEEXT */
2713 (iw_handler
) ar6000_ioctl_giwencodeext
, /* SIOCGIWENCODEEXT */
2714 (iw_handler
) ar6000_ioctl_siwpmksa
, /* SIOCSIWPMKSA */
2715 #endif // WIRELESS_EXT >= 18
2718 struct iw_handler_def ath_iw_handler_def
= {
2719 .standard
= (iw_handler
*)ath_handlers
,
2720 .num_standard
= ARRAY_SIZE(ath_handlers
),