1 /***********************************************************************
2 ** Copyright (C) 2003 ACX100 Open Source Project
4 ** The contents of this file are subject to the Mozilla Public
5 ** License Version 1.1 (the "License"); you may not use this file
6 ** except in compliance with the License. You may obtain a copy of
7 ** the License at http://www.mozilla.org/MPL/
9 ** Software distributed under the License is distributed on an "AS
10 ** IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
11 ** implied. See the License for the specific language governing
12 ** rights and limitations under the License.
14 ** Alternatively, the contents of this file may be used under the
15 ** terms of the GNU Public License version 2 (the "GPL"), in which
16 ** case the provisions of the GPL are applicable instead of the
17 ** above. If you wish to allow the use of your version of this file
18 ** only under the terms of the GPL and not to allow others to use
19 ** your version of this file under the MPL, indicate your decision
20 ** by deleting the provisions above and replace them with the notice
21 ** and other provisions required by the GPL. If you do not delete
22 ** the provisions above, a recipient may use your version of this
23 ** file under either the MPL or the GPL.
24 ** ---------------------------------------------------------------------
25 ** Inquiries regarding the ACX100 Open Source Project can be
28 ** acx100-users@lists.sf.net
29 ** http://acx100.sf.net
30 ** ---------------------------------------------------------------------
33 #include <linux/version.h>
34 #include <linux/kernel.h>
35 #include <linux/types.h>
37 //#include <asm/uaccess.h> /* required for 2.4.x kernels; verify_write() */
38 #include <linux/if_arp.h>
39 #include <linux/wireless.h>
40 #include <net/iw_handler.h>
45 /***********************************************************************
48 /* channel frequencies
49 * TODO: Currently, every other 802.11 driver keeps its own copy of this. In
50 * the long run this should be integrated into ieee802_11.h or wireless.h or
51 * whatever IEEE802.11x framework evolves */
52 static const u16 acx_channel_freq
[] = {
53 2412, 2417, 2422, 2427, 2432, 2437, 2442,
54 2447, 2452, 2457, 2462, 2467, 2472, 2484,
58 /***********************************************************************
62 acx_ioctl_commit(struct net_device
*ndev
,
63 struct iw_request_info
*info
,
64 union iwreq_data
*wrqu
,
67 acx_device_t
*adev
= ndev2adev(ndev
);
72 if (ACX_STATE_IFACE_UP
& adev
->dev_state_mask
)
73 acx_s_update_card_settings(adev
);
81 /***********************************************************************
85 struct net_device
*ndev
,
86 struct iw_request_info
*info
,
87 union iwreq_data
*wrqu
,
90 acx_device_t
*adev
= ndev2adev(ndev
);
91 static const char * const names
[] = { "IEEE 802.11b+/g+", "IEEE 802.11b+" };
93 strcpy(wrqu
->name
, names
[IS_ACX111(adev
) ? 0 : 1]);
99 /***********************************************************************
100 ** acx_ioctl_set_freq
104 struct net_device
*ndev
,
105 struct iw_request_info
*info
,
106 union iwreq_data
*wrqu
,
109 acx_device_t
*adev
= ndev2adev(ndev
);
111 unsigned int mult
= 1;
116 if (wrqu
->freq
.e
== 0 && wrqu
->freq
.m
<= 1000) {
117 /* Setting by channel number */
118 channel
= wrqu
->freq
.m
;
120 /* If setting by frequency, convert to a channel */
123 for (i
= 0; i
< (6 - wrqu
->freq
.e
); i
++)
126 for (i
= 1; i
<= 14; i
++)
127 if (wrqu
->freq
.m
== acx_channel_freq
[i
- 1] * mult
)
138 adev
->channel
= channel
;
139 /* hmm, the following code part is strange, but this is how
140 * it was being done before... */
141 log(L_IOCTL
, "Changing to channel %d\n", channel
);
142 SET_BIT(adev
->set_mask
, GETSET_CHANNEL
);
144 result
= -EINPROGRESS
; /* need to call commit handler */
146 acx_sem_unlock(adev
);
153 /***********************************************************************
157 struct net_device
*ndev
,
158 struct iw_request_info
*info
,
159 union iwreq_data
*wrqu
,
162 acx_device_t
*adev
= ndev2adev(ndev
);
164 wrqu
->freq
.m
= adev
->channel
;
169 /***********************************************************************
170 ** acx_ioctl_set_mode
174 struct net_device
*ndev
,
175 struct iw_request_info
*info
,
176 union iwreq_data
*wrqu
,
179 acx_device_t
*adev
= ndev2adev(ndev
);
186 switch (wrqu
->mode
) {
188 adev
->mode
= ACX_MODE_OFF
;
190 case IW_MODE_MONITOR
:
191 adev
->mode
= ACX_MODE_MONITOR
;
194 adev
->mode
= ACX_MODE_0_ADHOC
;
197 adev
->mode
= ACX_MODE_2_STA
;
200 printk("acx: master mode (HostAP) is very, very "
201 "experimental! It might work partially, but "
202 "better get prepared for nasty surprises "
204 adev
->mode
= ACX_MODE_3_AP
;
209 result
= -EOPNOTSUPP
;
213 log(L_ASSOC
, "new adev->mode=%d\n", adev
->mode
);
214 SET_BIT(adev
->set_mask
, GETSET_MODE
);
215 result
= -EINPROGRESS
;
218 acx_sem_unlock(adev
);
225 /***********************************************************************
229 struct net_device
*ndev
,
230 struct iw_request_info
*info
,
231 union iwreq_data
*wrqu
,
234 acx_device_t
*adev
= ndev2adev(ndev
);
237 switch (adev
->mode
) {
239 wrqu
->mode
= IW_MODE_AUTO
; break;
240 case ACX_MODE_MONITOR
:
241 wrqu
->mode
= IW_MODE_MONITOR
; break;
242 case ACX_MODE_0_ADHOC
:
243 wrqu
->mode
= IW_MODE_ADHOC
; break;
245 wrqu
->mode
= IW_MODE_INFRA
; break;
247 wrqu
->mode
= IW_MODE_MASTER
; break;
249 result
= -EOPNOTSUPP
;
255 /***********************************************************************
259 struct net_device
*ndev
,
260 struct iw_request_info
*info
,
261 union iwreq_data
*wrqu
,
264 struct iw_param
*vwrq
= &wrqu
->sens
;
265 acx_device_t
*adev
= ndev2adev(ndev
);
269 adev
->sensitivity
= (1 == vwrq
->disabled
) ? 0 : vwrq
->value
;
270 SET_BIT(adev
->set_mask
, GETSET_SENSITIVITY
);
272 acx_sem_unlock(adev
);
278 /***********************************************************************
282 struct net_device
*ndev
,
283 struct iw_request_info
*info
,
284 union iwreq_data
*wrqu
,
287 struct iw_param
*vwrq
= &wrqu
->sens
;
288 acx_device_t
*adev
= ndev2adev(ndev
);
291 /* setting the PHY reg via fw cmd doesn't work yet */
294 /* acx_sem_lock(adev); */
296 vwrq
->value
= adev
->sensitivity
;
297 vwrq
->disabled
= (vwrq
->value
== 0);
300 /* acx_sem_unlock(adev); */
306 /***********************************************************************
309 ** Sets the MAC address of the AP to associate with
313 struct net_device
*ndev
,
314 struct iw_request_info
*info
,
315 union iwreq_data
*wrqu
,
318 struct sockaddr
*awrq
= &wrqu
->ap_addr
;
319 acx_device_t
*adev
= ndev2adev(ndev
);
328 if (ARPHRD_ETHER
!= awrq
->sa_family
) {
334 acxlog_mac(L_IOCTL
, "set AP=", ap
, "\n");
336 MAC_COPY(adev
->ap
, ap
);
338 /* We want to start rescan in managed or ad-hoc mode,
339 ** otherwise just set adev->ap.
340 ** "iwconfig <if> ap <mac> mode managed": we must be able
341 ** to set ap _first_ and _then_ set mode */
342 switch (adev
->mode
) {
343 case ACX_MODE_0_ADHOC
:
345 /* FIXME: if there is a convention on what zero AP means,
346 ** please add a comment about that. I don't know of any --vda */
347 if (mac_is_zero(ap
)) {
348 /* "off" == 00:00:00:00:00:00 */
350 log(L_IOCTL
, "Not reassociating\n");
352 log(L_IOCTL
, "Forcing reassociation\n");
353 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
357 result
= -EINPROGRESS
;
364 /***********************************************************************
368 struct net_device
*ndev
,
369 struct iw_request_info
*info
,
370 union iwreq_data
*wrqu
,
373 struct sockaddr
*awrq
= &wrqu
->ap_addr
;
374 acx_device_t
*adev
= ndev2adev(ndev
);
376 if (ACX_STATUS_4_ASSOCIATED
== adev
->status
) {
377 /* as seen in Aironet driver, airo.c */
378 MAC_COPY(awrq
->sa_data
, adev
->bssid
);
380 MAC_ZERO(awrq
->sa_data
);
382 awrq
->sa_family
= ARPHRD_ETHER
;
387 /***********************************************************************
388 ** acx_ioctl_get_aplist
390 ** Deprecated in favor of iwscan.
391 ** We simply return the list of currently available stations in range,
392 ** don't do a new scan.
395 acx_ioctl_get_aplist(
396 struct net_device
*ndev
,
397 struct iw_request_info
*info
,
398 union iwreq_data
*wrqu
,
401 struct iw_point
*dwrq
= &wrqu
->data
;
402 acx_device_t
*adev
= ndev2adev(ndev
);
403 struct sockaddr
*address
= (struct sockaddr
*) extra
;
404 struct iw_quality qual
[IW_MAX_AP
];
410 /* we have AP list only in STA mode */
411 if (ACX_MODE_2_STA
!= adev
->mode
) {
412 result
= -EOPNOTSUPP
;
417 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
418 struct client
*bss
= &adev
->sta_list
[i
];
419 if (!bss
->used
) continue;
420 MAC_COPY(address
[cur
].sa_data
, bss
->bssid
);
421 address
[cur
].sa_family
= ARPHRD_ETHER
;
422 qual
[cur
].level
= bss
->sir
;
423 qual
[cur
].noise
= bss
->snr
;
425 qual
[cur
].qual
= acx_signal_determine_quality(qual
[cur
].level
,
428 qual
[cur
].qual
= (qual
[cur
].noise
<= 100) ?
429 100 - qual
[cur
].noise
: 0;
431 /* no scan: level/noise/qual not updated: */
432 qual
[cur
].updated
= 0;
437 memcpy(extra
+ sizeof(struct sockaddr
)*cur
, &qual
,
438 sizeof(struct iw_quality
)*cur
);
447 /***********************************************************************
451 struct net_device
*ndev
,
452 struct iw_request_info
*info
,
453 union iwreq_data
*wrqu
,
456 acx_device_t
*adev
= ndev2adev(ndev
);
463 /* don't start scan if device is not up yet */
464 if (!(adev
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
469 /* This is NOT a rescan for new AP!
470 ** Do not use SET_BIT(GETSET_RESCAN); */
471 acx_s_cmd_start_scan(adev
);
475 acx_sem_unlock(adev
);
482 /***********************************************************************
483 ** acx_s_scan_add_station
485 /* helper. not sure whether it's really a _s_leeping fn */
487 acx_s_scan_add_station(
498 /* MAC address has to be added first */
500 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
501 MAC_COPY(iwe
.u
.ap_addr
.sa_data
, bss
->bssid
);
502 acxlog_mac(L_IOCTL
, "scan, station address: ", bss
->bssid
, "\n");
503 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_ADDR_LEN
);
506 iwe
.cmd
= SIOCGIWESSID
;
507 iwe
.u
.data
.length
= bss
->essid_len
;
508 iwe
.u
.data
.flags
= 1;
509 log(L_IOCTL
, "scan, essid: %s\n", bss
->essid
);
510 ptr
= iwe_stream_add_point(ptr
, end_buf
, &iwe
, bss
->essid
);
513 iwe
.cmd
= SIOCGIWMODE
;
514 if (bss
->cap_info
& (WF_MGMT_CAP_ESS
| WF_MGMT_CAP_IBSS
)) {
515 if (bss
->cap_info
& WF_MGMT_CAP_ESS
)
516 iwe
.u
.mode
= IW_MODE_MASTER
;
518 iwe
.u
.mode
= IW_MODE_ADHOC
;
519 log(L_IOCTL
, "scan, mode: %d\n", iwe
.u
.mode
);
520 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_UINT_LEN
);
524 iwe
.cmd
= SIOCGIWFREQ
;
525 iwe
.u
.freq
.m
= acx_channel_freq
[bss
->channel
- 1] * 100000;
527 log(L_IOCTL
, "scan, frequency: %d\n", iwe
.u
.freq
.m
);
528 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_FREQ_LEN
);
530 /* Add link quality */
532 /* FIXME: these values should be expressed in dBm, but we don't know
533 * how to calibrate it yet */
534 iwe
.u
.qual
.level
= bss
->sir
;
535 iwe
.u
.qual
.noise
= bss
->snr
;
537 iwe
.u
.qual
.qual
= acx_signal_determine_quality(iwe
.u
.qual
.level
,
540 iwe
.u
.qual
.qual
= (iwe
.u
.qual
.noise
<= 100) ?
541 100 - iwe
.u
.qual
.noise
: 0;
543 iwe
.u
.qual
.updated
= 7;
544 log(L_IOCTL
, "scan, link quality: %d/%d/%d\n",
545 iwe
.u
.qual
.level
, iwe
.u
.qual
.noise
, iwe
.u
.qual
.qual
);
546 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_QUAL_LEN
);
549 iwe
.cmd
= SIOCGIWENCODE
;
550 if (bss
->cap_info
& WF_MGMT_CAP_PRIVACY
)
551 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
553 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
554 iwe
.u
.data
.length
= 0;
555 log(L_IOCTL
, "scan, encryption flags: %X\n", iwe
.u
.data
.flags
);
556 ptr
= iwe_stream_add_point(ptr
, end_buf
, &iwe
, bss
->essid
);
559 iwe
.cmd
= SIOCGIWRATE
;
560 iwe
.u
.bitrate
.fixed
= iwe
.u
.bitrate
.disabled
= 0;
561 ptr_rate
= ptr
+ IW_EV_LCP_LEN
;
564 u16 rate
= bss
->rate_cap
;
565 const u8
* p
= acx_bitpos2ratebyte
;
568 iwe
.u
.bitrate
.value
= *p
* 500000; /* units of 500kb/s */
569 log(L_IOCTL
, "scan, rate: %d\n", iwe
.u
.bitrate
.value
);
570 ptr
= iwe_stream_add_value(ptr
, ptr_rate
, end_buf
,
571 &iwe
, IW_EV_PARAM_LEN
);
577 if ((ptr_rate
- ptr
) > (ptrdiff_t)IW_EV_LCP_LEN
)
580 /* drop remaining station data items for now */
587 /***********************************************************************
592 struct net_device
*ndev
,
593 struct iw_request_info
*info
,
594 union iwreq_data
*wrqu
,
597 struct iw_point
*dwrq
= &wrqu
->data
;
598 acx_device_t
*adev
= ndev2adev(ndev
);
607 /* no scan available if device is not up yet */
608 if (!(adev
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
609 log(L_IOCTL
, "iface not up yet\n");
614 #ifdef ENODATA_TO_BE_USED_AFTER_SCAN_ERROR_ONLY
615 if (adev
->bss_table_count
== 0) {
616 /* no stations found */
622 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
623 struct client
*bss
= &adev
->sta_list
[i
];
624 if (!bss
->used
) continue;
625 ptr
= acx_s_scan_add_station(adev
, ptr
,
626 extra
+ IW_SCAN_MAX_DATA
, bss
);
628 dwrq
->length
= ptr
- extra
;
632 acx_sem_unlock(adev
);
639 /***********************************************************************
640 ** acx_ioctl_set_essid
644 struct net_device
*ndev
,
645 struct iw_request_info
*info
,
646 union iwreq_data
*wrqu
,
649 struct iw_point
*dwrq
= &wrqu
->essid
;
650 acx_device_t
*adev
= ndev2adev(ndev
);
651 int len
= dwrq
->length
;
661 log(L_IOCTL
, "set ESSID '%*s', length %d, flags 0x%04X\n",
662 len
, extra
, len
, dwrq
->flags
);
666 /* ESSID disabled? */
667 if (0 == dwrq
->flags
) {
668 adev
->essid_active
= 0;
671 if (dwrq
->length
> IW_ESSID_MAX_SIZE
+1) {
676 if (len
> sizeof(adev
->essid
))
677 len
= sizeof(adev
->essid
);
678 memcpy(adev
->essid
, extra
, len
-1);
679 adev
->essid
[len
-1] = '\0';
680 /* Paranoia: just in case there is a '\0'... */
681 adev
->essid_len
= strlen(adev
->essid
);
682 adev
->essid_active
= 1;
685 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
687 result
= -EINPROGRESS
;
690 acx_sem_unlock(adev
);
697 /***********************************************************************
701 struct net_device
*ndev
,
702 struct iw_request_info
*info
,
703 union iwreq_data
*wrqu
,
706 struct iw_point
*dwrq
= &wrqu
->essid
;
707 acx_device_t
*adev
= ndev2adev(ndev
);
709 dwrq
->flags
= adev
->essid_active
;
710 if (adev
->essid_active
) {
711 memcpy(extra
, adev
->essid
, adev
->essid_len
);
712 extra
[adev
->essid_len
] = '\0';
713 dwrq
->length
= adev
->essid_len
+ 1;
720 /***********************************************************************
721 ** acx_l_update_client_rates
724 acx_l_update_client_rates(acx_device_t
*adev
, u16 rate
)
727 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
728 client_t
*clt
= &adev
->sta_list
[i
];
729 if (!clt
->used
) continue;
730 clt
->rate_cfg
= (clt
->rate_cap
& rate
);
731 if (!clt
->rate_cfg
) {
732 /* no compatible rates left: kick client */
733 acxlog_mac(L_ASSOC
, "client ",clt
->address
," kicked: "
734 "rates are not compatible anymore\n");
735 acx_l_sta_list_del(adev
, clt
);
738 clt
->rate_cur
&= clt
->rate_cfg
;
739 if (!clt
->rate_cur
) {
740 /* current rate become invalid, choose a valid one */
741 clt
->rate_cur
= 1 << lowest_bit(clt
->rate_cfg
);
744 clt
->rate_100
= acx_bitpos2rate100
[highest_bit(clt
->rate_cur
)];
745 clt
->fallback_count
= clt
->stepup_count
= 0;
746 clt
->ignore_count
= 16;
748 switch (adev
->mode
) {
750 if (adev
->ap_client
&& !adev
->ap_client
->used
) {
751 /* Owwww... we kicked our AP!! :) */
752 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
758 /***********************************************************************
760 /* maps bits from acx111 rate to rate in Mbits */
761 static const unsigned int
762 acx111_rate_tbl
[] = {
776 500000, /* 13, should not happen */
777 500000, /* 14, should not happen */
778 500000, /* 15, should not happen */
781 /***********************************************************************
786 struct net_device
*ndev
,
787 struct iw_request_info
*info
,
788 union iwreq_data
*wrqu
,
791 struct iw_param
*vwrq
= &wrqu
->param
;
792 acx_device_t
*adev
= ndev2adev(ndev
);
796 int result
= -EINVAL
;
799 log(L_IOCTL
, "rate %d fixed 0x%X disabled 0x%X flags 0x%X\n",
800 vwrq
->value
, vwrq
->fixed
, vwrq
->disabled
, vwrq
->flags
);
802 if ((0 == vwrq
->fixed
) || (1 == vwrq
->fixed
)) {
803 int i
= VEC_SIZE(acx111_rate_tbl
)-1;
804 if (vwrq
->value
== -1)
805 /* "iwconfig rate auto" --> choose highest */
806 vwrq
->value
= IS_ACX100(adev
) ? 22000000 : 54000000;
808 if (vwrq
->value
== acx111_rate_tbl
[i
]) {
815 if (i
== -1) { /* no matching rate */
819 } else { /* rate N, N<1000 (driver specific): we don't use this */
820 result
= -EOPNOTSUPP
;
823 /* now: only one bit is set in txrate_cfg, corresponding to
826 autorate
= (vwrq
->fixed
== 0) && (RATE111_1
!= txrate_cfg
);
828 /* convert 00100000 -> 00111111 */
829 txrate_cfg
= (txrate_cfg
<<1)-1;
832 if (IS_ACX100(adev
)) {
833 txrate_cfg
&= RATE111_ACX100_COMPAT
;
835 result
= -ENOTSUPP
; /* rate is not supported by acx100 */
841 acx_lock(adev
, flags
);
843 adev
->rate_auto
= autorate
;
844 adev
->rate_oper
= txrate_cfg
;
845 adev
->rate_basic
= txrate_cfg
;
846 /* only do that in auto mode, non-auto will be able to use
847 * one specific Tx rate only anyway */
849 /* only use 802.11b base rates, for standard 802.11b H/W
851 adev
->rate_basic
&= RATE111_80211B_COMPAT
;
853 adev
->rate_bcast
= 1 << lowest_bit(txrate_cfg
);
855 adev
->rate_bcast100
= acx_rate111to100(adev
->rate_bcast
);
856 acx_l_update_ratevector(adev
);
857 acx_l_update_client_rates(adev
, txrate_cfg
);
859 /* Do/don't do tx rate fallback; beacon contents and rate */
860 SET_BIT(adev
->set_mask
, SET_RATE_FALLBACK
|SET_TEMPLATES
);
861 result
= -EINPROGRESS
;
863 acx_unlock(adev
, flags
);
864 acx_sem_unlock(adev
);
871 /***********************************************************************
872 ** acx_ioctl_get_rate
876 struct net_device
*ndev
,
877 struct iw_request_info
*info
,
878 union iwreq_data
*wrqu
,
881 struct iw_param
*vwrq
= &wrqu
->param
;
882 acx_device_t
*adev
= ndev2adev(ndev
);
886 acx_lock(adev
, flags
);
887 rate
= adev
->rate_oper
;
889 rate
= adev
->ap_client
->rate_cur
;
890 vwrq
->value
= acx111_rate_tbl
[highest_bit(rate
)];
891 vwrq
->fixed
= !adev
->rate_auto
;
893 acx_unlock(adev
, flags
);
900 struct net_device
*ndev
,
901 struct iw_request_info
*info
,
902 union iwreq_data
*wrqu
,
905 struct iw_param
*vwrq
= &wrqu
->rts
;
906 acx_device_t
*adev
= ndev2adev(ndev
);
907 int val
= vwrq
->value
;
911 if ((val
< 0) || (val
> 2312))
914 adev
->rts_threshold
= val
;
920 struct net_device
*ndev
,
921 struct iw_request_info
*info
,
922 union iwreq_data
*wrqu
,
925 struct iw_param
*vwrq
= &wrqu
->rts
;
926 acx_device_t
*adev
= ndev2adev(ndev
);
928 vwrq
->value
= adev
->rts_threshold
;
929 vwrq
->disabled
= (vwrq
->value
>= 2312);
935 #if ACX_FRAGMENTATION
938 struct net_device
*ndev
,
939 struct iw_request_info
*info
,
940 struct iw_param
*vwrq
,
943 acx_device_t
*adev
= ndev2adev(ndev
);
944 int val
= vwrq
->value
;
949 if ((val
< 256) || (val
> 2347))
952 adev
->frag_threshold
= val
;
958 struct net_device
*ndev
,
959 struct iw_request_info
*info
,
960 union iwreq_data
*wrqu
,
963 struct iw_param
*vwrq
= &wrqu
->frag
;
964 acx_device_t
*adev
= ndev2adev(ndev
);
966 vwrq
->value
= adev
->frag_threshold
;
967 vwrq
->disabled
= (vwrq
->value
>= 2347);
974 /***********************************************************************
975 ** acx_ioctl_set_encode
978 acx_ioctl_set_encode(
979 struct net_device
*ndev
,
980 struct iw_request_info
*info
,
981 union iwreq_data
*wrqu
,
984 struct iw_point
*dwrq
= &wrqu
->encoding
;
985 acx_device_t
*adev
= ndev2adev(ndev
);
991 log(L_IOCTL
, "set encoding flags=0x%04X, size=%d, key: %s\n",
992 dwrq
->flags
, dwrq
->length
, extra
? "set" : "No key");
996 index
= (dwrq
->flags
& IW_ENCODE_INDEX
) - 1;
998 if (dwrq
->length
> 0) {
999 /* if index is 0 or invalid, use default key */
1000 if ((index
< 0) || (index
> 3))
1001 index
= (int)adev
->wep_current_index
;
1003 if (0 == (dwrq
->flags
& IW_ENCODE_NOKEY
)) {
1004 if (dwrq
->length
> 29)
1005 dwrq
->length
= 29; /* restrict it */
1007 if (dwrq
->length
> 13) {
1008 /* 29*8 == 232, WEP256 */
1009 adev
->wep_keys
[index
].size
= 29;
1010 } else if (dwrq
->length
> 5) {
1011 /* 13*8 == 104bit, WEP128 */
1012 adev
->wep_keys
[index
].size
= 13;
1013 } else if (dwrq
->length
> 0) {
1014 /* 5*8 == 40bit, WEP64 */
1015 adev
->wep_keys
[index
].size
= 5;
1018 adev
->wep_keys
[index
].size
= 0;
1021 memset(adev
->wep_keys
[index
].key
, 0,
1022 sizeof(adev
->wep_keys
[index
].key
));
1023 memcpy(adev
->wep_keys
[index
].key
, extra
, dwrq
->length
);
1026 /* set transmit key */
1027 if ((index
>= 0) && (index
<= 3))
1028 adev
->wep_current_index
= index
;
1029 else if (0 == (dwrq
->flags
& IW_ENCODE_MODE
)) {
1030 /* complain if we were not just setting
1037 adev
->wep_enabled
= !(dwrq
->flags
& IW_ENCODE_DISABLED
);
1039 if (dwrq
->flags
& IW_ENCODE_OPEN
) {
1040 adev
->auth_alg
= WLAN_AUTH_ALG_OPENSYSTEM
;
1041 adev
->wep_restricted
= 0;
1043 } else if (dwrq
->flags
& IW_ENCODE_RESTRICTED
) {
1044 adev
->auth_alg
= WLAN_AUTH_ALG_SHAREDKEY
;
1045 adev
->wep_restricted
= 1;
1048 /* set flag to make sure the card WEP settings get updated */
1049 SET_BIT(adev
->set_mask
, GETSET_WEP
);
1051 log(L_IOCTL
, "len=%d, key at 0x%p, flags=0x%X\n",
1052 dwrq
->length
, extra
, dwrq
->flags
);
1054 for (index
= 0; index
<= 3; index
++) {
1055 if (adev
->wep_keys
[index
].size
) {
1056 log(L_IOCTL
, "index=%d, size=%d, key at 0x%p\n",
1057 adev
->wep_keys
[index
].index
,
1058 (int) adev
->wep_keys
[index
].size
,
1059 adev
->wep_keys
[index
].key
);
1062 result
= -EINPROGRESS
;
1065 acx_sem_unlock(adev
);
1072 /***********************************************************************
1073 ** acx_ioctl_get_encode
1076 acx_ioctl_get_encode(
1077 struct net_device
*ndev
,
1078 struct iw_request_info
*info
,
1079 union iwreq_data
*wrqu
,
1082 struct iw_point
*dwrq
= &wrqu
->encoding
;
1083 acx_device_t
*adev
= ndev2adev(ndev
);
1084 int index
= (dwrq
->flags
& IW_ENCODE_INDEX
) - 1;
1088 if (adev
->wep_enabled
== 0) {
1089 dwrq
->flags
= IW_ENCODE_DISABLED
;
1091 if ((index
< 0) || (index
> 3))
1092 index
= (int)adev
->wep_current_index
;
1094 dwrq
->flags
= (adev
->wep_restricted
== 1) ?
1095 IW_ENCODE_RESTRICTED
: IW_ENCODE_OPEN
;
1096 dwrq
->length
= adev
->wep_keys
[index
].size
;
1098 memcpy(extra
, adev
->wep_keys
[index
].key
,
1099 adev
->wep_keys
[index
].size
);
1102 /* set the current index */
1103 SET_BIT(dwrq
->flags
, index
+ 1);
1105 log(L_IOCTL
, "len=%d, key=%p, flags=0x%X\n",
1106 dwrq
->length
, dwrq
->pointer
,
1114 /***********************************************************************
1117 acx_ioctl_set_power(
1118 struct net_device
*ndev
,
1119 struct iw_request_info
*info
,
1120 union iwreq_data
*wrqu
,
1123 struct iw_param
*vwrq
= &wrqu
->power
;
1124 acx_device_t
*adev
= ndev2adev(ndev
);
1125 int result
= -EINPROGRESS
;
1129 log(L_IOCTL
, "set 802.11 powersave flags=0x%04X\n", vwrq
->flags
);
1133 if (vwrq
->disabled
) {
1134 CLEAR_BIT(adev
->ps_wakeup_cfg
, PS_CFG_ENABLE
);
1135 SET_BIT(adev
->set_mask
, GETSET_POWER_80211
);
1138 if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_TIMEOUT
) {
1139 u16 ps_timeout
= (vwrq
->value
* 1024) / 1000;
1141 if (ps_timeout
> 255)
1143 log(L_IOCTL
, "setting PS timeout value to %d time units "
1144 "due to %dus\n", ps_timeout
, vwrq
->value
);
1145 adev
->ps_hangover_period
= ps_timeout
;
1146 } else if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_PERIOD
) {
1147 u16 ps_periods
= vwrq
->value
/ 1000000;
1149 if (ps_periods
> 255)
1151 log(L_IOCTL
, "setting PS period value to %d periods "
1152 "due to %dus\n", ps_periods
, vwrq
->value
);
1153 adev
->ps_listen_interval
= ps_periods
;
1154 CLEAR_BIT(adev
->ps_wakeup_cfg
, PS_CFG_WAKEUP_MODE_MASK
);
1155 SET_BIT(adev
->ps_wakeup_cfg
, PS_CFG_WAKEUP_EACH_ITVL
);
1158 switch (vwrq
->flags
& IW_POWER_MODE
) {
1159 /* FIXME: are we doing the right thing here? */
1160 case IW_POWER_UNICAST_R
:
1161 CLEAR_BIT(adev
->ps_options
, PS_OPT_STILL_RCV_BCASTS
);
1163 case IW_POWER_MULTICAST_R
:
1164 SET_BIT(adev
->ps_options
, PS_OPT_STILL_RCV_BCASTS
);
1166 case IW_POWER_ALL_R
:
1167 SET_BIT(adev
->ps_options
, PS_OPT_STILL_RCV_BCASTS
);
1172 log(L_IOCTL
, "unknown PS mode\n");
1177 SET_BIT(adev
->ps_wakeup_cfg
, PS_CFG_ENABLE
);
1178 SET_BIT(adev
->set_mask
, GETSET_POWER_80211
);
1180 acx_sem_unlock(adev
);
1187 /***********************************************************************
1190 acx_ioctl_get_power(
1191 struct net_device
*ndev
,
1192 struct iw_request_info
*info
,
1193 union iwreq_data
*wrqu
,
1196 struct iw_param
*vwrq
= &wrqu
->power
;
1197 acx_device_t
*adev
= ndev2adev(ndev
);
1201 log(L_IOCTL
, "Get 802.11 Power Save flags = 0x%04X\n", vwrq
->flags
);
1202 vwrq
->disabled
= ((adev
->ps_wakeup_cfg
& PS_CFG_ENABLE
) == 0);
1206 if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_TIMEOUT
) {
1207 vwrq
->value
= adev
->ps_hangover_period
* 1000 / 1024;
1208 vwrq
->flags
= IW_POWER_TIMEOUT
;
1210 vwrq
->value
= adev
->ps_listen_interval
* 1000000;
1211 vwrq
->flags
= IW_POWER_PERIOD
|IW_POWER_RELATIVE
;
1213 if (adev
->ps_options
& PS_OPT_STILL_RCV_BCASTS
)
1214 SET_BIT(vwrq
->flags
, IW_POWER_ALL_R
);
1216 SET_BIT(vwrq
->flags
, IW_POWER_UNICAST_R
);
1223 /***********************************************************************
1224 ** acx_ioctl_get_txpow
1227 acx_ioctl_get_txpow(
1228 struct net_device
*ndev
,
1229 struct iw_request_info
*info
,
1230 union iwreq_data
*wrqu
,
1233 struct iw_param
*vwrq
= &wrqu
->power
;
1234 acx_device_t
*adev
= ndev2adev(ndev
);
1238 vwrq
->flags
= IW_TXPOW_DBM
;
1241 vwrq
->value
= adev
->tx_level_dbm
;
1243 log(L_IOCTL
, "get txpower:%d dBm\n", adev
->tx_level_dbm
);
1250 /***********************************************************************
1251 ** acx_ioctl_set_txpow
1254 acx_ioctl_set_txpow(
1255 struct net_device
*ndev
,
1256 struct iw_request_info
*info
,
1257 union iwreq_data
*wrqu
,
1260 struct iw_param
*vwrq
= &wrqu
->power
;
1261 acx_device_t
*adev
= ndev2adev(ndev
);
1266 log(L_IOCTL
, "set txpower:%d, disabled:%d, flags:0x%04X\n",
1267 vwrq
->value
, vwrq
->disabled
, vwrq
->flags
);
1271 if (vwrq
->disabled
!= adev
->tx_disabled
) {
1272 SET_BIT(adev
->set_mask
, GETSET_TX
);
1275 adev
->tx_disabled
= vwrq
->disabled
;
1276 if (vwrq
->value
== -1) {
1277 if (vwrq
->disabled
) {
1278 adev
->tx_level_dbm
= 0;
1279 log(L_IOCTL
, "disable radio tx\n");
1281 /* adev->tx_level_auto = 1; */
1282 log(L_IOCTL
, "set tx power auto (NIY)\n");
1285 adev
->tx_level_dbm
= vwrq
->value
<= 20 ? vwrq
->value
: 20;
1286 /* adev->tx_level_auto = 0; */
1287 log(L_IOCTL
, "set txpower=%d dBm\n", adev
->tx_level_dbm
);
1289 SET_BIT(adev
->set_mask
, GETSET_TXPOWER
);
1291 result
= -EINPROGRESS
;
1293 acx_sem_unlock(adev
);
1300 /***********************************************************************
1301 ** acx_ioctl_get_range
1304 acx_ioctl_get_range(
1305 struct net_device
*ndev
,
1306 struct iw_request_info
*info
,
1307 union iwreq_data
*wrqu
,
1310 struct iw_point
*dwrq
= &wrqu
->data
;
1311 struct iw_range
*range
= (struct iw_range
*)extra
;
1312 acx_device_t
*adev
= ndev2adev(ndev
);
1320 dwrq
->length
= sizeof(struct iw_range
);
1321 memset(range
, 0, sizeof(struct iw_range
));
1323 for (i
= 1; i
<= 14; i
++) {
1324 if (adev
->reg_dom_chanmask
& (1 << (i
- 1))) {
1325 range
->freq
[n
].i
= i
;
1326 range
->freq
[n
].m
= acx_channel_freq
[i
- 1] * 100000;
1327 range
->freq
[n
].e
= 1; /* units are MHz */
1331 range
->num_channels
= n
;
1332 range
->num_frequency
= n
;
1335 range
->max_rts
= 2312;
1337 #if ACX_FRAGMENTATION
1338 range
->min_frag
= 256;
1339 range
->max_frag
= 2312;
1342 range
->encoding_size
[0] = 5;
1343 range
->encoding_size
[1] = 13;
1344 range
->encoding_size
[2] = 29;
1345 range
->num_encoding_sizes
= 3;
1346 range
->max_encoding_tokens
= 4;
1349 range
->max_pmp
= 5000000;
1351 range
->max_pmt
= 65535 * 1000;
1352 range
->pmp_flags
= IW_POWER_PERIOD
;
1353 range
->pmt_flags
= IW_POWER_TIMEOUT
;
1354 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
1356 if (IS_ACX100(adev
)) { /* ACX100 has direct radio programming - arbitrary levels, so offer a lot */
1357 for (i
= 0; i
<= IW_MAX_TXPOWER
- 1; i
++)
1358 range
->txpower
[i
] = 20 * i
/ (IW_MAX_TXPOWER
- 1);
1359 range
->num_txpower
= IW_MAX_TXPOWER
;
1360 range
->txpower_capa
= IW_TXPOW_DBM
;
1363 int count
= min(IW_MAX_TXPOWER
, (int)adev
->cfgopt_power_levels
.len
);
1364 for (i
= 0; i
<= count
; i
++)
1365 range
->txpower
[i
] = adev
->cfgopt_power_levels
.list
[i
];
1366 range
->num_txpower
= count
;
1367 /* this list is given in mW */
1368 range
->txpower_capa
= IW_TXPOW_MWATT
;
1371 range
->we_version_compiled
= WIRELESS_EXT
;
1372 range
->we_version_source
= 0x9;
1374 range
->retry_capa
= IW_RETRY_LIMIT
;
1375 range
->retry_flags
= IW_RETRY_LIMIT
;
1376 range
->min_retry
= 1;
1377 range
->max_retry
= 255;
1379 range
->r_time_flags
= IW_RETRY_LIFETIME
;
1380 range
->min_r_time
= 0;
1381 /* FIXME: lifetime ranges and orders of magnitude are strange?? */
1382 range
->max_r_time
= 65535;
1385 range
->sensitivity
= 0;
1386 else if (IS_ACX111(adev
))
1387 range
->sensitivity
= 3;
1389 range
->sensitivity
= 255;
1391 for (i
=0; i
< adev
->rate_supported_len
; i
++) {
1392 range
->bitrate
[i
] = (adev
->rate_supported
[i
] & ~0x80) * 500000;
1393 /* never happens, but keep it, to be safe: */
1394 if (range
->bitrate
[i
] == 0)
1397 range
->num_bitrates
= i
;
1399 range
->max_qual
.qual
= 100;
1400 range
->max_qual
.level
= 100;
1401 range
->max_qual
.noise
= 100;
1402 /* TODO: better values */
1403 range
->avg_qual
.qual
= 90;
1404 range
->avg_qual
.level
= 80;
1405 range
->avg_qual
.noise
= 2;
1413 /***********************************************************************
1414 ** Private functions
1417 /***********************************************************************
1418 ** acx_ioctl_get_nick
1422 struct net_device
*ndev
,
1423 struct iw_request_info
*info
,
1424 union iwreq_data
*wrqu
,
1427 struct iw_point
*dwrq
= &wrqu
->data
;
1428 acx_device_t
*adev
= ndev2adev(ndev
);
1430 strcpy(extra
, adev
->nick
);
1431 dwrq
->length
= strlen(extra
) + 1;
1437 /***********************************************************************
1438 ** acx_ioctl_set_nick
1442 struct net_device
*ndev
,
1443 struct iw_request_info
*info
,
1444 union iwreq_data
*wrqu
,
1447 struct iw_point
*dwrq
= &wrqu
->data
;
1448 acx_device_t
*adev
= ndev2adev(ndev
);
1455 if (dwrq
->length
> IW_ESSID_MAX_SIZE
+ 1) {
1460 /* extra includes trailing \0, so it's ok */
1461 strcpy(adev
->nick
, extra
);
1465 acx_sem_unlock(adev
);
1472 /***********************************************************************
1473 ** acx_ioctl_get_retry
1476 acx_ioctl_get_retry(
1477 struct net_device
*ndev
,
1478 struct iw_request_info
*info
,
1479 union iwreq_data
*wrqu
,
1482 struct iw_param
*vwrq
= &wrqu
->retry
;
1483 acx_device_t
*adev
= ndev2adev(ndev
);
1484 unsigned int type
= vwrq
->flags
& IW_RETRY_TYPE
;
1485 unsigned int modifier
= vwrq
->flags
& IW_RETRY_MODIFIER
;
1492 /* return the short retry number by default */
1493 if (type
== IW_RETRY_LIFETIME
) {
1494 vwrq
->flags
= IW_RETRY_LIFETIME
;
1495 vwrq
->value
= adev
->msdu_lifetime
;
1496 } else if (modifier
== IW_RETRY_MAX
) {
1497 vwrq
->flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
1498 vwrq
->value
= adev
->long_retry
;
1500 vwrq
->flags
= IW_RETRY_LIMIT
;
1501 if (adev
->long_retry
!= adev
->short_retry
)
1502 SET_BIT(vwrq
->flags
, IW_RETRY_MIN
);
1503 vwrq
->value
= adev
->short_retry
;
1506 /* can't be disabled */
1507 vwrq
->disabled
= (u8
)0;
1510 acx_sem_unlock(adev
);
1517 /***********************************************************************
1518 ** acx_ioctl_set_retry
1521 acx_ioctl_set_retry(
1522 struct net_device
*ndev
,
1523 struct iw_request_info
*info
,
1524 union iwreq_data
*wrqu
,
1527 struct iw_param
*vwrq
= &wrqu
->retry
;
1528 acx_device_t
*adev
= ndev2adev(ndev
);
1537 if (vwrq
->disabled
) {
1545 if (IW_RETRY_LIMIT
== (vwrq
->flags
& IW_RETRY_TYPE
)) {
1546 printk("old retry limits: short %d long %d\n",
1547 adev
->short_retry
, adev
->long_retry
);
1548 if (vwrq
->flags
& IW_RETRY_MAX
) {
1549 adev
->long_retry
= vwrq
->value
;
1550 } else if (vwrq
->flags
& IW_RETRY_MIN
) {
1551 adev
->short_retry
= vwrq
->value
;
1553 /* no modifier: set both */
1554 adev
->long_retry
= vwrq
->value
;
1555 adev
->short_retry
= vwrq
->value
;
1557 printk("new retry limits: short %d long %d\n",
1558 adev
->short_retry
, adev
->long_retry
);
1559 SET_BIT(adev
->set_mask
, GETSET_RETRY
);
1560 result
= -EINPROGRESS
;
1562 else if (vwrq
->flags
& IW_RETRY_LIFETIME
) {
1563 adev
->msdu_lifetime
= vwrq
->value
;
1564 printk("new MSDU lifetime: %d\n", adev
->msdu_lifetime
);
1565 SET_BIT(adev
->set_mask
, SET_MSDU_LIFETIME
);
1566 result
= -EINPROGRESS
;
1569 acx_sem_unlock(adev
);
1576 /************************ private ioctls ******************************/
1579 /***********************************************************************
1580 ** acx_ioctl_set_debug
1584 acx_ioctl_set_debug(
1585 struct net_device
*ndev
,
1586 struct iw_request_info
*info
,
1587 union iwreq_data
*wrqu
,
1590 unsigned int debug_new
= *((unsigned int *)extra
);
1591 int result
= -EINVAL
;
1593 log(L_ANY
, "setting debug from %04X to %04X\n", acx_debug
, debug_new
);
1594 acx_debug
= debug_new
;
1603 /***********************************************************************
1604 ** acx_ioctl_list_reg_domain
1607 acx_ioctl_list_reg_domain(
1608 struct net_device
*ndev
,
1609 struct iw_request_info
*info
,
1610 union iwreq_data
*wrqu
,
1614 const char * const *entry
= acx_reg_domain_strings
;
1616 printk("dom# chan# domain/country\n");
1618 printk("%4d %s\n", i
++, *entry
++);
1623 /***********************************************************************
1624 ** acx_ioctl_set_reg_domain
1627 acx_ioctl_set_reg_domain(
1628 struct net_device
*ndev
,
1629 struct iw_request_info
*info
,
1630 union iwreq_data
*wrqu
,
1633 acx_device_t
*adev
= ndev2adev(ndev
);
1638 if ((*extra
< 1) || ((size_t)*extra
> acx_reg_domain_ids_len
)) {
1645 adev
->reg_dom_id
= acx_reg_domain_ids
[*extra
- 1];
1646 SET_BIT(adev
->set_mask
, GETSET_REG_DOMAIN
);
1648 result
= -EINPROGRESS
;
1650 acx_sem_unlock(adev
);
1657 /***********************************************************************
1658 ** acx_ioctl_get_reg_domain
1661 acx_ioctl_get_reg_domain(
1662 struct net_device
*ndev
,
1663 struct iw_request_info
*info
,
1664 union iwreq_data
*wrqu
,
1667 acx_device_t
*adev
= ndev2adev(ndev
);
1671 dom
= adev
->reg_dom_id
;
1673 for (i
= 1; i
<= acx_reg_domain_ids_len
; i
++) {
1674 if (acx_reg_domain_ids
[i
-1] == dom
) {
1675 log(L_IOCTL
, "regulatory domain is currently set "
1676 "to %d (0x%X): %s\n", i
, dom
,
1677 acx_reg_domain_strings
[i
-1]);
1687 /***********************************************************************
1688 ** acx_ioctl_set_short_preamble
1690 static const char * const
1691 preamble_modes
[] = {
1694 "auto (peer capability dependent)",
1695 "unknown mode, error"
1699 acx_ioctl_set_short_preamble(
1700 struct net_device
*ndev
,
1701 struct iw_request_info
*info
,
1702 union iwreq_data
*wrqu
,
1705 acx_device_t
*adev
= ndev2adev(ndev
);
1711 if ((unsigned char)*extra
> 2) {
1718 adev
->preamble_mode
= (u8
)*extra
;
1719 switch (adev
->preamble_mode
) {
1721 adev
->preamble_cur
= 0;
1724 /* short, kick incapable peers */
1725 adev
->preamble_cur
= 1;
1726 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
1727 client_t
*clt
= &adev
->sta_list
[i
];
1728 if (!clt
->used
) continue;
1729 if (!(clt
->cap_info
& WF_MGMT_CAP_SHORT
)) {
1730 clt
->used
= CLIENT_EMPTY_SLOT_0
;
1733 switch (adev
->mode
) {
1734 case ACX_MODE_2_STA
:
1735 if (adev
->ap_client
&& !adev
->ap_client
->used
) {
1736 /* We kicked our AP :) */
1737 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
1741 case 2: /* auto. short only if all peers are short-capable */
1742 adev
->preamble_cur
= 1;
1743 for (i
= 0; i
< VEC_SIZE(adev
->sta_list
); i
++) {
1744 client_t
*clt
= &adev
->sta_list
[i
];
1745 if (!clt
->used
) continue;
1746 if (!(clt
->cap_info
& WF_MGMT_CAP_SHORT
)) {
1747 adev
->preamble_cur
= 0;
1753 printk("new short preamble setting: configured %s, active %s\n",
1754 preamble_modes
[adev
->preamble_mode
],
1755 preamble_modes
[adev
->preamble_cur
]);
1758 acx_sem_unlock(adev
);
1765 /***********************************************************************
1766 ** acx_ioctl_get_short_preamble
1769 acx_ioctl_get_short_preamble(
1770 struct net_device
*ndev
,
1771 struct iw_request_info
*info
,
1772 union iwreq_data
*wrqu
,
1775 acx_device_t
*adev
= ndev2adev(ndev
);
1779 printk("current short preamble setting: configured %s, active %s\n",
1780 preamble_modes
[adev
->preamble_mode
],
1781 preamble_modes
[adev
->preamble_cur
]);
1783 *extra
= (char)adev
->preamble_mode
;
1785 acx_sem_unlock(adev
);
1791 /***********************************************************************
1792 ** acx_ioctl_set_antenna
1794 ** TX and RX antenna can be set separately but this function good
1795 ** for testing 0-4 bits
1798 acx_ioctl_set_antenna(
1799 struct net_device
*ndev
,
1800 struct iw_request_info
*info
,
1801 union iwreq_data
*wrqu
,
1804 acx_device_t
*adev
= ndev2adev(ndev
);
1808 printk("old antenna value: 0x%02X (COMBINED bit mask)\n"
1809 "Rx antenna selection:\n"
1812 "0x80 full diversity\n"
1813 "0xc0 partial diversity\n"
1814 "0x0f dwell time mask (in units of us)\n"
1815 "Tx antenna selection:\n"
1816 "0x00 ant. 2\n" /* yep, those ARE reversed! */
1818 "new antenna value: 0x%02X\n",
1819 adev
->antenna
, (u8
)*extra
);
1821 adev
->antenna
= (u8
)*extra
;
1822 SET_BIT(adev
->set_mask
, GETSET_ANTENNA
);
1824 acx_sem_unlock(adev
);
1826 return -EINPROGRESS
;
1830 /***********************************************************************
1831 ** acx_ioctl_get_antenna
1834 acx_ioctl_get_antenna(
1835 struct net_device
*ndev
,
1836 struct iw_request_info
*info
,
1837 union iwreq_data
*wrqu
,
1840 acx_device_t
*adev
= ndev2adev(ndev
);
1842 /* no locking. it's pointless to lock a single load */
1843 printk("current antenna value: 0x%02X (COMBINED bit mask)\n"
1844 "Rx antenna selection:\n"
1847 "0x80 full diversity\n"
1848 "0xc0 partial diversity\n"
1849 "Tx antenna selection:\n"
1850 "0x00 ant. 2\n" /* yep, those ARE reversed! */
1851 "0x20 ant. 1\n", adev
->antenna
);
1857 /***********************************************************************
1858 ** acx_ioctl_set_rx_antenna
1860 ** 0 = antenna1; 1 = antenna2; 2 = full diversity; 3 = partial diversity
1861 ** Could anybody test which antenna is the external one?
1864 acx_ioctl_set_rx_antenna(
1865 struct net_device
*ndev
,
1866 struct iw_request_info
*info
,
1867 union iwreq_data
*wrqu
,
1870 acx_device_t
*adev
= ndev2adev(ndev
);
1880 printk("old antenna value: 0x%02X\n", adev
->antenna
);
1884 adev
->antenna
&= 0x3f;
1885 SET_BIT(adev
->antenna
, (*extra
<< 6));
1886 SET_BIT(adev
->set_mask
, GETSET_ANTENNA
);
1887 printk("new antenna value: 0x%02X\n", adev
->antenna
);
1888 result
= -EINPROGRESS
;
1890 acx_sem_unlock(adev
);
1897 /***********************************************************************
1898 ** acx_ioctl_set_tx_antenna
1900 ** Arguments: 0 == antenna2; 1 == antenna1;
1901 ** Could anybody test which antenna is the external one?
1904 acx_ioctl_set_tx_antenna(
1905 struct net_device
*ndev
,
1906 struct iw_request_info
*info
,
1907 union iwreq_data
*wrqu
,
1910 acx_device_t
*adev
= ndev2adev(ndev
);
1920 printk("old antenna value: 0x%02X\n", adev
->antenna
);
1924 adev
->antenna
&= ~0x30;
1925 SET_BIT(adev
->antenna
, ((*extra
& 0x01) << 5));
1926 SET_BIT(adev
->set_mask
, GETSET_ANTENNA
);
1927 printk("new antenna value: 0x%02X\n", adev
->antenna
);
1928 result
= -EINPROGRESS
;
1930 acx_sem_unlock(adev
);
1937 /***********************************************************************
1938 ** acx_ioctl_wlansniff
1940 ** can we just remove this in favor of monitor mode? --vda
1943 acx_ioctl_wlansniff(
1944 struct net_device
*ndev
,
1945 struct iw_request_info
*info
,
1946 union iwreq_data
*wrqu
,
1949 acx_device_t
*adev
= ndev2adev(ndev
);
1950 unsigned int *params
= (unsigned int*)extra
;
1951 unsigned int enable
= (unsigned int)(params
[0] > 0);
1958 /* not using printk() here, since it distorts kismet display
1959 * when printk messages activated */
1960 log(L_IOCTL
, "setting monitor to: 0x%02X\n", params
[0]);
1962 switch (params
[0]) {
1964 /* no monitor mode. hmm, should we simply ignore it
1965 * or go back to enabling adev->netdev->type ARPHRD_ETHER? */
1968 adev
->monitor_type
= ARPHRD_IEEE80211_PRISM
;
1971 adev
->monitor_type
= ARPHRD_IEEE80211
;
1976 adev
->mode
= ACX_MODE_MONITOR
;
1977 SET_BIT(adev
->set_mask
, GETSET_MODE
);
1981 adev
->channel
= params
[1];
1982 SET_BIT(adev
->set_mask
, GETSET_RX
);
1984 result
= -EINPROGRESS
;
1986 acx_sem_unlock(adev
);
1993 /***********************************************************************
1994 ** acx_ioctl_unknown11
1995 ** FIXME: looks like some sort of "iwpriv kick_sta MAC" but it's broken
1998 acx_ioctl_unknown11(
1999 struct net_device
*ndev
,
2000 struct iw_request_info
*info
,
2001 union iwreq_data
*wrqu
,
2005 struct iw_param
*vwrq
= &wrqu
->param
;
2006 acx_device_t
*adev
= ndev2adev(ndev
);
2007 unsigned long flags
;
2012 acx_lock(adev
, flags
);
2014 acx_l_transmit_disassoc(adev
, &client
);
2017 acx_unlock(adev
, flags
);
2018 acx_sem_unlock(adev
);
2026 /***********************************************************************
2027 ** debug helper function to be able to debug various issues relatively easily
2030 acx_ioctl_dbg_set_masks(
2031 struct net_device
*ndev
,
2032 struct iw_request_info
*info
,
2033 union iwreq_data
*wrqu
,
2036 acx_device_t
*adev
= ndev2adev(ndev
);
2037 const unsigned int *params
= (unsigned int*)extra
;
2042 log(L_IOCTL
, "setting flags in settings mask: "
2043 "get_mask %08X set_mask %08X\n"
2044 "before: get_mask %08X set_mask %08X\n",
2045 params
[0], params
[1],
2046 adev
->get_mask
, adev
->set_mask
);
2047 SET_BIT(adev
->get_mask
, params
[0]);
2048 SET_BIT(adev
->set_mask
, params
[1]);
2049 log(L_IOCTL
, "after: get_mask %08X set_mask %08X\n",
2050 adev
->get_mask
, adev
->set_mask
);
2051 result
= -EINPROGRESS
; /* immediately call commit handler */
2053 acx_sem_unlock(adev
);
2059 /***********************************************************************
2060 * acx_ioctl_set_rates
2062 * This ioctl takes string parameter. Examples:
2063 * iwpriv wlan0 SetRates "1,2"
2064 * use 1 and 2 Mbit rates, both are in basic rate set
2065 * iwpriv wlan0 SetRates "1,2 5,11"
2066 * use 1,2,5.5,11 Mbit rates. 1 and 2 are basic
2067 * iwpriv wlan0 SetRates "1,2 5c,11c"
2068 * same ('c' means 'CCK modulation' and it is a default for 5 and 11)
2069 * iwpriv wlan0 SetRates "1,2 5p,11p"
2070 * use 1,2,5.5,11 Mbit, 1,2 are basic. 5 and 11 are using PBCC
2071 * iwpriv wlan0 SetRates "1,2,5,11 22p"
2072 * use 1,2,5.5,11,22 Mbit. 1,2,5.5 and 11 are basic. 22 is using PBCC
2073 * (this is the maximum acx100 can do (modulo x4 mode))
2074 * iwpriv wlan0 SetRates "1,2,5,11 22"
2075 * same. 802.11 defines only PBCC modulation
2076 * for 22 and 33 Mbit rates, so there is no ambiguity
2077 * iwpriv wlan0 SetRates "1,2,5,11 6o,9o,12o,18o,24o,36o,48o,54o"
2078 * 1,2,5.5 and 11 are basic. 11g OFDM rates are enabled but
2079 * they are not in basic rate set. 22 Mbit is disabled.
2080 * iwpriv wlan0 SetRates "1,2,5,11 6,9,12,18,24,36,48,54"
2081 * same. OFDM is default for 11g rates except 22 and 33 Mbit,
2082 * thus 'o' is optional
2083 * iwpriv wlan0 SetRates "1,2,5,11 6d,9d,12d,18d,24d,36d,48d,54d"
2084 * 1,2,5.5 and 11 are basic. 11g CCK-OFDM rates are enabled
2085 * (acx111 does not support CCK-OFDM, driver will reject this cmd)
2086 * iwpriv wlan0 SetRates "6,9,12 18,24,36,48,54"
2087 * 6,9,12 are basic, rest of 11g rates is enabled. Using OFDM
2089 #include "setrate.c"
2091 /* disallow: 33Mbit (unsupported by hw) */
2092 /* disallow: CCKOFDM (unsupported by hw) */
2094 acx111_supported(int mbit
, int modulation
, void *opaque
)
2096 if (mbit
==33) return -ENOTSUPP
;
2097 if (modulation
==DOT11_MOD_CCKOFDM
) return -ENOTSUPP
;
2103 [DOT11_RATE_1
] = RATE111_1
,
2104 [DOT11_RATE_2
] = RATE111_2
,
2105 [DOT11_RATE_5
] = RATE111_5
,
2106 [DOT11_RATE_11
] = RATE111_11
,
2107 [DOT11_RATE_22
] = RATE111_22
,
2108 /* [DOT11_RATE_33] = */
2109 [DOT11_RATE_6
] = RATE111_6
,
2110 [DOT11_RATE_9
] = RATE111_9
,
2111 [DOT11_RATE_12
] = RATE111_12
,
2112 [DOT11_RATE_18
] = RATE111_18
,
2113 [DOT11_RATE_24
] = RATE111_24
,
2114 [DOT11_RATE_36
] = RATE111_36
,
2115 [DOT11_RATE_48
] = RATE111_48
,
2116 [DOT11_RATE_54
] = RATE111_54
,
2120 acx111_gen_mask(int mbit
, int modulation
, void *opaque
)
2122 /* lower 16 bits show selected 1, 2, CCK and OFDM rates */
2123 /* upper 16 bits show selected PBCC rates */
2124 u32 m
= acx111mask
[rate_mbit2enum(mbit
)];
2125 if (modulation
==DOT11_MOD_PBCC
)
2131 verify_rate(u32 rate
, int chip_type
)
2133 /* never happens. be paranoid */
2134 if (!rate
) return -EINVAL
;
2136 /* disallow: mixing PBCC and CCK at 5 and 11Mbit
2137 ** (can be supported, but needs complicated handling in tx code) */
2138 if (( rate
& ((RATE111_11
+RATE111_5
)<<16) )
2139 && ( rate
& (RATE111_11
+RATE111_5
) )
2143 if (CHIPTYPE_ACX100
== chip_type
) {
2144 if ( rate
& ~(RATE111_ACX100_COMPAT
+(RATE111_ACX100_COMPAT
<<16)) )
2151 acx_ioctl_set_rates(struct net_device
*ndev
,
2152 struct iw_request_info
*info
,
2153 union iwreq_data
*wrqu
,
2156 acx_device_t
*adev
= ndev2adev(ndev
);
2157 unsigned long flags
;
2159 u32 brate
= 0, orate
= 0; /* basic, operational rate set */
2163 log(L_IOCTL
, "set_rates %s\n", extra
);
2164 result
= fill_ratemasks(extra
, &brate
, &orate
,
2165 acx111_supported
, acx111_gen_mask
, 0);
2166 if (result
) goto end
;
2167 SET_BIT(orate
, brate
);
2168 log(L_IOCTL
, "brate %08X orate %08X\n", brate
, orate
);
2170 result
= verify_rate(brate
, adev
->chip_type
);
2171 if (result
) goto end
;
2172 result
= verify_rate(orate
, adev
->chip_type
);
2173 if (result
) goto end
;
2176 acx_lock(adev
, flags
);
2178 adev
->rate_basic
= brate
;
2179 adev
->rate_oper
= orate
;
2180 /* TODO: ideally, we shall monitor highest basic rate
2181 ** which was successfully sent to every peer
2182 ** (say, last we checked, everybody could hear 5.5 Mbits)
2183 ** and use that for bcasts when we want to reach all peers.
2184 ** For beacons, we probably shall use lowest basic rate
2185 ** because we want to reach all *potential* new peers too */
2186 adev
->rate_bcast
= 1 << lowest_bit(brate
);
2187 if (IS_ACX100(adev
))
2188 adev
->rate_bcast100
= acx_rate111to100(adev
->rate_bcast
);
2189 adev
->rate_auto
= !has_only_one_bit(orate
);
2190 acx_l_update_client_rates(adev
, orate
);
2191 /* TODO: get rid of ratevector, build it only when needed */
2192 acx_l_update_ratevector(adev
);
2194 /* Do/don't do tx rate fallback; beacon contents and rate */
2195 SET_BIT(adev
->set_mask
, SET_RATE_FALLBACK
|SET_TEMPLATES
);
2196 result
= -EINPROGRESS
;
2198 acx_unlock(adev
, flags
);
2199 acx_sem_unlock(adev
);
2206 /***********************************************************************
2207 ** acx_ioctl_get_phy_chan_busy_percentage
2210 acx_ioctl_get_phy_chan_busy_percentage(
2211 struct net_device
*ndev
,
2212 struct iw_request_info
*info
,
2213 union iwreq_data
*wrqu
,
2216 acx_device_t
*adev
= ndev2adev(ndev
);
2227 if (OK
!= acx_s_interrogate(adev
, &usage
, ACX1xx_IE_MEDIUM_USAGE
)) {
2232 usage
.busytime
= le32_to_cpu(usage
.busytime
);
2233 usage
.totaltime
= le32_to_cpu(usage
.totaltime
);
2234 printk("%s: average busy percentage since last invocation: %d%% "
2235 "(%u of %u microseconds)\n",
2237 usage
.busytime
/ ((usage
.totaltime
/ 100) + 1),
2238 usage
.busytime
, usage
.totaltime
);
2243 acx_sem_unlock(adev
);
2249 /***********************************************************************
2250 ** acx_ioctl_set_ed_threshold
2253 acx_ioctl_set_ed_threshold(
2254 struct net_device
*ndev
,
2255 struct iw_request_info
*info
,
2256 union iwreq_data
*wrqu
,
2259 acx_device_t
*adev
= ndev2adev(ndev
);
2263 printk("old ED threshold value: %d\n", adev
->ed_threshold
);
2264 adev
->ed_threshold
= (unsigned char)*extra
;
2265 printk("new ED threshold value: %d\n", (unsigned char)*extra
);
2266 SET_BIT(adev
->set_mask
, GETSET_ED_THRESH
);
2268 acx_sem_unlock(adev
);
2270 return -EINPROGRESS
;
2274 /***********************************************************************
2275 ** acx_ioctl_set_cca
2279 struct net_device
*ndev
,
2280 struct iw_request_info
*info
,
2281 union iwreq_data
*wrqu
,
2284 acx_device_t
*adev
= ndev2adev(ndev
);
2289 printk("old CCA value: 0x%02X\n", adev
->cca
);
2290 adev
->cca
= (unsigned char)*extra
;
2291 printk("new CCA value: 0x%02X\n", (unsigned char)*extra
);
2292 SET_BIT(adev
->set_mask
, GETSET_CCA
);
2293 result
= -EINPROGRESS
;
2295 acx_sem_unlock(adev
);
2301 /***********************************************************************
2303 static const char * const
2304 scan_modes
[] = { "active", "passive", "background" };
2307 acx_print_scan_params(acx_device_t
*adev
, const char* head
)
2309 printk("%s: %smode %d (%s), min chan time %dTU, "
2310 "max chan time %dTU, max scan rate byte: %d\n",
2311 adev
->ndev
->name
, head
,
2312 adev
->scan_mode
, scan_modes
[adev
->scan_mode
],
2313 adev
->scan_probe_delay
, adev
->scan_duration
, adev
->scan_rate
);
2317 acx_ioctl_set_scan_params(
2318 struct net_device
*ndev
,
2319 struct iw_request_info
*info
,
2320 union iwreq_data
*wrqu
,
2323 acx_device_t
*adev
= ndev2adev(ndev
);
2325 const int *params
= (int *)extra
;
2329 acx_print_scan_params(adev
, "old scan parameters: ");
2330 if ((params
[0] != -1) && (params
[0] >= 0) && (params
[0] <= 2))
2331 adev
->scan_mode
= params
[0];
2332 if (params
[1] != -1)
2333 adev
->scan_probe_delay
= params
[1];
2334 if (params
[2] != -1)
2335 adev
->scan_duration
= params
[2];
2336 if ((params
[3] != -1) && (params
[3] <= 255))
2337 adev
->scan_rate
= params
[3];
2338 acx_print_scan_params(adev
, "new scan parameters: ");
2339 SET_BIT(adev
->set_mask
, GETSET_RESCAN
);
2340 result
= -EINPROGRESS
;
2342 acx_sem_unlock(adev
);
2348 acx_ioctl_get_scan_params(
2349 struct net_device
*ndev
,
2350 struct iw_request_info
*info
,
2351 union iwreq_data
*wrqu
,
2354 acx_device_t
*adev
= ndev2adev(ndev
);
2356 int *params
= (int *)extra
;
2360 acx_print_scan_params(adev
, "current scan parameters: ");
2361 params
[0] = adev
->scan_mode
;
2362 params
[1] = adev
->scan_probe_delay
;
2363 params
[2] = adev
->scan_duration
;
2364 params
[3] = adev
->scan_rate
;
2367 acx_sem_unlock(adev
);
2373 /***********************************************************************
2376 acx100_ioctl_set_led_power(
2377 struct net_device
*ndev
,
2378 struct iw_request_info
*info
,
2379 union iwreq_data
*wrqu
,
2382 static const char * const led_modes
[] = { "off", "on", "LinkQuality" };
2384 acx_device_t
*adev
= ndev2adev(ndev
);
2389 printk("%s: power LED status: old %d (%s), ",
2392 led_modes
[adev
->led_power
]);
2393 adev
->led_power
= extra
[0];
2394 if (adev
->led_power
> 2) adev
->led_power
= 2;
2395 printk("new %d (%s)\n",
2397 led_modes
[adev
->led_power
]);
2399 if (adev
->led_power
== 2) {
2400 printk("%s: max link quality setting: old %d, ",
2401 ndev
->name
, adev
->brange_max_quality
);
2403 adev
->brange_max_quality
= extra
[1];
2404 printk("new %d\n", adev
->brange_max_quality
);
2407 SET_BIT(adev
->set_mask
, GETSET_LED_POWER
);
2409 result
= -EINPROGRESS
;
2411 acx_sem_unlock(adev
);
2417 /***********************************************************************
2420 acx100_ioctl_get_led_power(
2421 struct net_device
*ndev
,
2422 struct iw_request_info
*info
,
2423 union iwreq_data
*wrqu
,
2426 acx_device_t
*adev
= ndev2adev(ndev
);
2430 extra
[0] = adev
->led_power
;
2431 if (adev
->led_power
== 2)
2432 extra
[1] = adev
->brange_max_quality
;
2436 acx_sem_unlock(adev
);
2442 /***********************************************************************
2446 struct net_device
*ndev
,
2447 struct iw_request_info
*info
,
2448 union iwreq_data
*wrqu
,
2451 struct iw_param
*vwrq
= &wrqu
->param
;
2452 if (!IS_PCI(ndev2adev(ndev
)))
2454 return acx111pci_ioctl_info(ndev
, info
, vwrq
, extra
);
2458 /***********************************************************************
2461 acx100_ioctl_set_phy_amp_bias(
2462 struct net_device
*ndev
,
2463 struct iw_request_info
*info
,
2464 union iwreq_data
*wrqu
,
2467 struct iw_param
*vwrq
= &wrqu
->param
;
2468 if (IS_USB(ndev2adev(ndev
))) {
2469 printk("acx: set_phy_amp_bias() is not supported on USB\n");
2472 #ifdef CONFIG_ACX_MEM
2473 return acx100mem_ioctl_set_phy_amp_bias(ndev
, info
, vwrq
, extra
);
2475 return acx100pci_ioctl_set_phy_amp_bias(ndev
, info
, vwrq
, extra
);
2480 /***********************************************************************
2482 static const iw_handler acx_ioctl_handler
[] =
2484 acx_ioctl_commit
, /* SIOCSIWCOMMIT */
2485 acx_ioctl_get_name
, /* SIOCGIWNAME */
2486 NULL
, /* SIOCSIWNWID */
2487 NULL
, /* SIOCGIWNWID */
2488 acx_ioctl_set_freq
, /* SIOCSIWFREQ */
2489 acx_ioctl_get_freq
, /* SIOCGIWFREQ */
2490 acx_ioctl_set_mode
, /* SIOCSIWMODE */
2491 acx_ioctl_get_mode
, /* SIOCGIWMODE */
2492 acx_ioctl_set_sens
, /* SIOCSIWSENS */
2493 acx_ioctl_get_sens
, /* SIOCGIWSENS */
2494 NULL
, /* SIOCSIWRANGE */
2495 acx_ioctl_get_range
, /* SIOCGIWRANGE */
2496 NULL
, /* SIOCSIWPRIV */
2497 NULL
, /* SIOCGIWPRIV */
2498 NULL
, /* SIOCSIWSTATS */
2499 NULL
, /* SIOCGIWSTATS */
2500 #if IW_HANDLER_VERSION > 4
2501 iw_handler_set_spy
, /* SIOCSIWSPY */
2502 iw_handler_get_spy
, /* SIOCGIWSPY */
2503 iw_handler_set_thrspy
, /* SIOCSIWTHRSPY */
2504 iw_handler_get_thrspy
, /* SIOCGIWTHRSPY */
2505 #else /* IW_HANDLER_VERSION > 4 */
2507 NULL
/* acx_ioctl_set_spy FIXME */, /* SIOCSIWSPY */
2508 NULL
/* acx_ioctl_get_spy */, /* SIOCGIWSPY */
2510 NULL
, /* SIOCSIWSPY */
2511 NULL
, /* SIOCGIWSPY */
2513 NULL
, /* [nothing] */
2514 NULL
, /* [nothing] */
2515 #endif /* IW_HANDLER_VERSION > 4 */
2516 acx_ioctl_set_ap
, /* SIOCSIWAP */
2517 acx_ioctl_get_ap
, /* SIOCGIWAP */
2518 NULL
, /* [nothing] */
2519 acx_ioctl_get_aplist
, /* SIOCGIWAPLIST */
2520 acx_ioctl_set_scan
, /* SIOCSIWSCAN */
2521 acx_ioctl_get_scan
, /* SIOCGIWSCAN */
2522 acx_ioctl_set_essid
, /* SIOCSIWESSID */
2523 acx_ioctl_get_essid
, /* SIOCGIWESSID */
2524 acx_ioctl_set_nick
, /* SIOCSIWNICKN */
2525 acx_ioctl_get_nick
, /* SIOCGIWNICKN */
2526 NULL
, /* [nothing] */
2527 NULL
, /* [nothing] */
2528 acx_ioctl_set_rate
, /* SIOCSIWRATE */
2529 acx_ioctl_get_rate
, /* SIOCGIWRATE */
2530 acx_ioctl_set_rts
, /* SIOCSIWRTS */
2531 acx_ioctl_get_rts
, /* SIOCGIWRTS */
2532 #if ACX_FRAGMENTATION
2533 acx_ioctl_set_frag
, /* SIOCSIWFRAG */
2534 acx_ioctl_get_frag
, /* SIOCGIWFRAG */
2536 NULL
, /* SIOCSIWFRAG */
2537 NULL
, /* SIOCGIWFRAG */
2539 acx_ioctl_set_txpow
, /* SIOCSIWTXPOW */
2540 acx_ioctl_get_txpow
, /* SIOCGIWTXPOW */
2541 acx_ioctl_set_retry
, /* SIOCSIWRETRY */
2542 acx_ioctl_get_retry
, /* SIOCGIWRETRY */
2543 acx_ioctl_set_encode
, /* SIOCSIWENCODE */
2544 acx_ioctl_get_encode
, /* SIOCGIWENCODE */
2545 acx_ioctl_set_power
, /* SIOCSIWPOWER */
2546 acx_ioctl_get_power
, /* SIOCGIWPOWER */
2550 /***********************************************************************
2553 /* if you plan to reorder something, make sure to reorder all other places
2555 /* SET/GET convention: SETs must have even position, GETs odd */
2556 #define ACX100_IOCTL SIOCIWFIRSTPRIV
2558 ACX100_IOCTL_DEBUG
= ACX100_IOCTL
,
2559 ACX100_IOCTL_GET__________UNUSED1
,
2560 ACX100_IOCTL_SET_PLED
,
2561 ACX100_IOCTL_GET_PLED
,
2562 ACX100_IOCTL_SET_RATES
,
2563 ACX100_IOCTL_LIST_DOM
,
2564 ACX100_IOCTL_SET_DOM
,
2565 ACX100_IOCTL_GET_DOM
,
2566 ACX100_IOCTL_SET_SCAN_PARAMS
,
2567 ACX100_IOCTL_GET_SCAN_PARAMS
,
2568 ACX100_IOCTL_SET_PREAMB
,
2569 ACX100_IOCTL_GET_PREAMB
,
2570 ACX100_IOCTL_SET_ANT
,
2571 ACX100_IOCTL_GET_ANT
,
2572 ACX100_IOCTL_RX_ANT
,
2573 ACX100_IOCTL_TX_ANT
,
2574 ACX100_IOCTL_SET_PHY_AMP_BIAS
,
2575 ACX100_IOCTL_GET_PHY_CHAN_BUSY
,
2576 ACX100_IOCTL_SET_ED
,
2577 ACX100_IOCTL_GET__________UNUSED3
,
2578 ACX100_IOCTL_SET_CCA
,
2579 ACX100_IOCTL_GET__________UNUSED4
,
2580 ACX100_IOCTL_MONITOR
,
2582 ACX100_IOCTL_DBG_SET_MASKS
,
2584 ACX100_IOCTL_DBG_SET_IO
,
2585 ACX100_IOCTL_DBG_GET_IO
2589 static const iw_handler acx_ioctl_private_handler
[] =
2592 [ACX100_IOCTL_DEBUG
- ACX100_IOCTL
] = acx_ioctl_set_debug
,
2594 [ACX100_IOCTL_SET_PLED
- ACX100_IOCTL
] = acx100_ioctl_set_led_power
,
2595 [ACX100_IOCTL_GET_PLED
- ACX100_IOCTL
] = acx100_ioctl_get_led_power
,
2596 [ACX100_IOCTL_SET_RATES
- ACX100_IOCTL
] = acx_ioctl_set_rates
,
2597 [ACX100_IOCTL_LIST_DOM
- ACX100_IOCTL
] = acx_ioctl_list_reg_domain
,
2598 [ACX100_IOCTL_SET_DOM
- ACX100_IOCTL
] = acx_ioctl_set_reg_domain
,
2599 [ACX100_IOCTL_GET_DOM
- ACX100_IOCTL
] = acx_ioctl_get_reg_domain
,
2600 [ACX100_IOCTL_SET_SCAN_PARAMS
- ACX100_IOCTL
] = acx_ioctl_set_scan_params
,
2601 [ACX100_IOCTL_GET_SCAN_PARAMS
- ACX100_IOCTL
] = acx_ioctl_get_scan_params
,
2602 [ACX100_IOCTL_SET_PREAMB
- ACX100_IOCTL
] = acx_ioctl_set_short_preamble
,
2603 [ACX100_IOCTL_GET_PREAMB
- ACX100_IOCTL
] = acx_ioctl_get_short_preamble
,
2604 [ACX100_IOCTL_SET_ANT
- ACX100_IOCTL
] = acx_ioctl_set_antenna
,
2605 [ACX100_IOCTL_GET_ANT
- ACX100_IOCTL
] = acx_ioctl_get_antenna
,
2606 [ACX100_IOCTL_RX_ANT
- ACX100_IOCTL
] = acx_ioctl_set_rx_antenna
,
2607 [ACX100_IOCTL_TX_ANT
- ACX100_IOCTL
] = acx_ioctl_set_tx_antenna
,
2608 [ACX100_IOCTL_SET_PHY_AMP_BIAS
- ACX100_IOCTL
] = acx100_ioctl_set_phy_amp_bias
,
2609 [ACX100_IOCTL_GET_PHY_CHAN_BUSY
- ACX100_IOCTL
] = acx_ioctl_get_phy_chan_busy_percentage
,
2610 [ACX100_IOCTL_SET_ED
- ACX100_IOCTL
] = acx_ioctl_set_ed_threshold
,
2611 [ACX100_IOCTL_SET_CCA
- ACX100_IOCTL
] = acx_ioctl_set_cca
,
2612 [ACX100_IOCTL_MONITOR
- ACX100_IOCTL
] = acx_ioctl_wlansniff
,
2613 [ACX100_IOCTL_TEST
- ACX100_IOCTL
] = acx_ioctl_unknown11
,
2614 [ACX100_IOCTL_DBG_SET_MASKS
- ACX100_IOCTL
] = acx_ioctl_dbg_set_masks
,
2615 [ACX111_IOCTL_INFO
- ACX100_IOCTL
] = acx111_ioctl_info
,
2619 static const struct iw_priv_args acx_ioctl_private_args
[] = {
2621 { cmd
: ACX100_IOCTL_DEBUG
,
2622 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
2624 name
: "SetDebug" },
2626 { cmd
: ACX100_IOCTL_SET_PLED
,
2627 set_args
: IW_PRIV_TYPE_BYTE
| 2,
2629 name
: "SetLEDPower" },
2630 { cmd
: ACX100_IOCTL_GET_PLED
,
2632 get_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 2,
2633 name
: "GetLEDPower" },
2634 { cmd
: ACX100_IOCTL_SET_RATES
,
2635 set_args
: IW_PRIV_TYPE_CHAR
| 256,
2637 name
: "SetRates" },
2638 { cmd
: ACX100_IOCTL_LIST_DOM
,
2641 name
: "ListRegDomain" },
2642 { cmd
: ACX100_IOCTL_SET_DOM
,
2643 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2645 name
: "SetRegDomain" },
2646 { cmd
: ACX100_IOCTL_GET_DOM
,
2648 get_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2649 name
: "GetRegDomain" },
2650 { cmd
: ACX100_IOCTL_SET_SCAN_PARAMS
,
2651 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 4,
2653 name
: "SetScanParams" },
2654 { cmd
: ACX100_IOCTL_GET_SCAN_PARAMS
,
2656 get_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 4,
2657 name
: "GetScanParams" },
2658 { cmd
: ACX100_IOCTL_SET_PREAMB
,
2659 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2661 name
: "SetSPreamble" },
2662 { cmd
: ACX100_IOCTL_GET_PREAMB
,
2664 get_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2665 name
: "GetSPreamble" },
2666 { cmd
: ACX100_IOCTL_SET_ANT
,
2667 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2669 name
: "SetAntenna" },
2670 { cmd
: ACX100_IOCTL_GET_ANT
,
2673 name
: "GetAntenna" },
2674 { cmd
: ACX100_IOCTL_RX_ANT
,
2675 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2677 name
: "SetRxAnt" },
2678 { cmd
: ACX100_IOCTL_TX_ANT
,
2679 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2681 name
: "SetTxAnt" },
2682 { cmd
: ACX100_IOCTL_SET_PHY_AMP_BIAS
,
2683 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2685 name
: "SetPhyAmpBias"},
2686 { cmd
: ACX100_IOCTL_GET_PHY_CHAN_BUSY
,
2689 name
: "GetPhyChanBusy" },
2690 { cmd
: ACX100_IOCTL_SET_ED
,
2691 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
2694 { cmd
: ACX100_IOCTL_SET_CCA
,
2695 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
2698 { cmd
: ACX100_IOCTL_MONITOR
,
2699 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
2702 { cmd
: ACX100_IOCTL_TEST
,
2706 { cmd
: ACX100_IOCTL_DBG_SET_MASKS
,
2707 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
2709 name
: "DbgSetMasks" },
2710 { cmd
: ACX111_IOCTL_INFO
,
2713 name
: "GetAcx111Info" },
2714 { cmd
: ACX100_IOCTL_DBG_SET_IO
,
2715 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 4,
2717 name
: "DbgSetIO" },
2718 { cmd
: ACX100_IOCTL_DBG_GET_IO
,
2719 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 3,
2721 name
: "DbgGetIO" },
2725 const struct iw_handler_def acx_ioctl_handler_def
=
2727 .num_standard
= VEC_SIZE(acx_ioctl_handler
),
2728 .num_private
= VEC_SIZE(acx_ioctl_private_handler
),
2729 .num_private_args
= VEC_SIZE(acx_ioctl_private_args
),
2730 .standard
= (iw_handler
*) acx_ioctl_handler
,
2731 .private = (iw_handler
*) acx_ioctl_private_handler
,
2732 .private_args
= (struct iw_priv_args
*) acx_ioctl_private_args
,
2733 #if IW_HANDLER_VERSION > 5
2734 .get_wireless_stats
= acx_e_get_wireless_stats