1 /* src/acx100_ioctl.c - all the ioctl calls
3 * --------------------------------------------------------------------
5 * Copyright (C) 2003 ACX100 Open Source Project
7 * The contents of this file are subject to the Mozilla Public
8 * License Version 1.1 (the "License"); you may not use this file
9 * except in compliance with the License. You may obtain a copy of
10 * the License at http://www.mozilla.org/MPL/
12 * Software distributed under the License is distributed on an "AS
13 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
14 * implied. See the License for the specific language governing
15 * rights and limitations under the License.
17 * Alternatively, the contents of this file may be used under the
18 * terms of the GNU Public License version 2 (the "GPL"), in which
19 * case the provisions of the GPL are applicable instead of the
20 * above. If you wish to allow the use of your version of this file
21 * only under the terms of the GPL and not to allow others to use
22 * your version of this file under the MPL, indicate your decision
23 * by deleting the provisions above and replace them with the notice
24 * and other provisions required by the GPL. If you do not delete
25 * the provisions above, a recipient may use your version of this
26 * file under either the MPL or the GPL.
28 * --------------------------------------------------------------------
30 * Inquiries regarding the ACX100 Open Source Project can be
33 * acx100-users@lists.sf.net
34 * http://acx100.sf.net
36 * --------------------------------------------------------------------
39 #ifdef S_SPLINT_S /* some crap that splint needs to not crap out */
40 #define __signed__ signed
41 #define __u64 unsigned long long
42 #define u64 unsigned long long
43 #define loff_t unsigned long
44 #define sigval_t unsigned long
45 #define siginfo_t unsigned long
46 #define stack_t unsigned long
47 #define __s64 signed long long
49 #include <linux/config.h>
50 #include <linux/version.h>
51 #include <linux/kernel.h>
52 #include <linux/types.h>
54 #include <linux/if_arp.h>
55 #include <linux/wireless.h>
57 #include <net/iw_handler.h>
59 #include <asm/uaccess.h>
61 /*================================================================*/
62 /* Project Includes */
64 #include <p80211mgmt.h>
66 #include <acx100_helper.h>
67 #include <acx100_helper2.h>
72 * I only locked the device whenever calls to the hardware are made or
73 * parts of the wlandevice struct are modified, otherwise no locking is
74 * performed. I don't now if this is safe, we'll see.
77 extern UINT8
acx_signal_determine_quality(UINT8 signal
, UINT8 noise
);
80 /* if you plan to reorder something, make sure to reorder all other places
82 #define ACX100_IOCTL SIOCIWFIRSTPRIV
83 #define ACX100_IOCTL_DEBUG ACX100_IOCTL + 0x00
84 #define ACX100_IOCTL_LIST_DOM ACX100_IOCTL + 0x01
85 #define ACX100_IOCTL_SET_DOM ACX100_IOCTL + 0x02
86 #define ACX100_IOCTL_GET_DOM ACX100_IOCTL + 0x03
87 #define ACX100_IOCTL_SET_PREAMB ACX100_IOCTL + 0x04
88 #define ACX100_IOCTL_GET_PREAMB ACX100_IOCTL + 0x05
89 #define ACX100_IOCTL_SET_ANT ACX100_IOCTL + 0x06
90 #define ACX100_IOCTL_GET_ANT ACX100_IOCTL + 0x07
91 #define ACX100_IOCTL_RX_ANT ACX100_IOCTL + 0x08
92 #define ACX100_IOCTL_TX_ANT ACX100_IOCTL + 0x09
93 #define ACX100_IOCTL_SET_ED ACX100_IOCTL + 0x0a
94 #define ACX100_IOCTL_SET_CCA ACX100_IOCTL + 0x0b
95 #define ACX100_IOCTL_SET_PLED ACX100_IOCTL + 0x0c
96 #define ACX100_IOCTL_MONITOR ACX100_IOCTL + 0x0d
97 #define ACX100_IOCTL_TEST ACX100_IOCTL + 0x0e
98 #define ACX100_IOCTL_DBG_SET_MASKS ACX100_IOCTL + 0x0f
99 #define ACX100_IOCTL_ACX111_INFO ACX100_IOCTL + 0x10
102 /* channel frequencies
103 * TODO: Currently, every other 802.11 driver keeps its own copy of this. In
104 * the long run this should be integrated into ieee802_11.h or wireless.h or
105 * whatever IEEE802.11x framework evolves */
106 static const long acx100_channel_freq
[] = {
107 2412, 2417, 2422, 2427, 2432, 2437, 2442,
108 2447, 2452, 2457, 2462, 2467, 2472, 2484,
111 static const struct iw_priv_args acx100_ioctl_private_args
[] = {
113 { cmd
: ACX100_IOCTL_DEBUG
,
114 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
116 name
: "set_debug" },
118 { cmd
: ACX100_IOCTL_LIST_DOM
,
121 name
: "list_reg_domain" },
122 { cmd
: ACX100_IOCTL_SET_DOM
,
123 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
125 name
: "set_reg_domain" },
126 { cmd
: ACX100_IOCTL_GET_DOM
,
128 get_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
129 name
: "get_reg_domain" },
130 { cmd
: ACX100_IOCTL_SET_PREAMB
,
131 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
133 name
: "set_s_preamble" },
134 { cmd
: ACX100_IOCTL_GET_PREAMB
,
136 get_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
137 name
: "get_s_preamble" },
138 { cmd
: ACX100_IOCTL_SET_ANT
,
139 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
141 name
: "set_antenna" },
142 { cmd
: ACX100_IOCTL_GET_ANT
,
145 name
: "get_antenna" },
146 { cmd
: ACX100_IOCTL_RX_ANT
,
147 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
149 name
: "set_rx_ant" },
150 { cmd
: ACX100_IOCTL_TX_ANT
,
151 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
153 name
: "set_tx_ant" },
154 { cmd
: ACX100_IOCTL_SET_ED
,
155 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 1,
158 { cmd
: ACX100_IOCTL_SET_CCA
,
159 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
162 { cmd
: ACX100_IOCTL_SET_PLED
,
163 set_args
: IW_PRIV_TYPE_BYTE
| IW_PRIV_SIZE_FIXED
| 1,
165 name
: "set_led_power" },
166 { cmd
: ACX100_IOCTL_MONITOR
,
167 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
170 { cmd
: ACX100_IOCTL_TEST
,
174 { cmd
: ACX100_IOCTL_DBG_SET_MASKS
,
175 set_args
: IW_PRIV_TYPE_INT
| IW_PRIV_SIZE_FIXED
| 2,
177 name
: "DbgSetMasks" },
178 { cmd
: ACX100_IOCTL_ACX111_INFO
,
181 name
: "Acx111Info" }
184 /*------------------------------------------------------------------------------
185 * acx100_ioctl_commit
198 *----------------------------------------------------------------------------*/
199 static inline int acx100_ioctl_commit(struct net_device
*dev
,
200 struct iw_request_info
*info
,
201 void *zwrq
, char *extra
)
203 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
206 acx100_update_card_settings(priv
, 0, 0, 0);
211 static inline int acx100_ioctl_get_name(struct net_device
*dev
, struct iw_request_info
*info
, char *cwrq
, char *extra
)
213 const char * const protocol_name
= "IEEE 802.11b+";
214 acxlog(L_IOCTL
, "Get Name ==> %s\n", protocol_name
);
215 strcpy(cwrq
, protocol_name
);
219 /*----------------------------------------------------------------
220 * acx100_ioctl_set_freq
235 *----------------------------------------------------------------*/
236 static inline int acx100_ioctl_set_freq(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_freq
*fwrq
, char *extra
)
238 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
243 int result
= -EINVAL
;
246 acxlog(L_IOCTL
, "Set Frequency <== %i (%i)\n", fwrq
->m
, fwrq
->e
);
248 if (fwrq
->e
== 0 && fwrq
->m
<= 1000) {
249 /* Setting by channel number */
252 /* If setting by frequency, convert to a channel */
255 for (i
= 0; i
< (6 - fwrq
->e
); i
++)
258 for (i
= 1; i
<= 14; i
++)
259 if (fwrq
->m
== acx100_channel_freq
[i
- 1] * mult
)
268 if (0 != (err
= acx100_lock(priv
, &flags
))) {
273 priv
->channel
= (UINT16
)channel
;
274 /* hmm, the following code part is strange, but this is how
275 * it was being done before... */
276 if (ACX_MODE_3_MANAGED_AP
== priv
->macmode_wanted
) {
277 /* hmm, AP mode? So simply set channel... */
278 acxlog(L_IOCTL
, "Changing to channel %d\n", priv
->channel
);
279 priv
->set_mask
|= GETSET_TX
|GETSET_RX
;
282 if ((ACX_MODE_2_MANAGED_STA
== priv
->macmode_wanted
)
283 || (ACX_MODE_0_IBSS_ADHOC
== priv
->macmode_wanted
)) {
284 /* trigger scanning... */
285 priv
->set_mask
|= GETSET_CHANNEL
;
287 acx100_unlock(priv
, &flags
);
288 result
= -EINPROGRESS
; /* need to call commit handler */
294 static inline int acx100_ioctl_get_freq(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_freq
*fwrq
, char *extra
)
296 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
298 fwrq
->m
= priv
->channel
;
302 /*----------------------------------------------------------------
303 * acx100_ioctl_set_mode
318 *----------------------------------------------------------------*/
319 static inline int acx100_ioctl_set_mode(struct net_device
*dev
, struct iw_request_info
*info
, __u32
*uwrq
, char *extra
)
321 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
324 int result
= -EINVAL
;
327 acxlog(L_IOCTL
, "Set Mode <== %i\n", *uwrq
);
329 if (0 != (err
= acx100_lock(priv
, &flags
))) {
336 priv
->macmode_wanted
= ACX_MODE_FF_AUTO
;
339 priv
->macmode_wanted
= ACX_MODE_0_IBSS_ADHOC
;
342 priv
->macmode_wanted
= ACX_MODE_2_MANAGED_STA
;
345 priv
->macmode_wanted
= ACX_MODE_3_MANAGED_AP
;
348 result
= -EOPNOTSUPP
;
352 priv
->set_mask
|= GETSET_MODE
;
353 result
= -EINPROGRESS
;
356 acx100_unlock(priv
, &flags
);
362 static inline int acx100_ioctl_get_mode(struct net_device
*dev
, struct iw_request_info
*info
, __u32
*uwrq
, char *extra
)
364 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
367 #if SHOW_SPECIFIC_MACMODE_JOINED
368 if (priv
->status
!= ISTATUS_4_ASSOCIATED
)
370 { /* connection not up yet, so for now indicate the mode we want,
371 not the one we are in */
372 switch (priv
->macmode_wanted
) {
373 case ACX_MODE_FF_AUTO
:
374 *uwrq
= IW_MODE_AUTO
;
376 case ACX_MODE_0_IBSS_ADHOC
:
377 *uwrq
= IW_MODE_ADHOC
;
379 case ACX_MODE_2_MANAGED_STA
:
380 *uwrq
= IW_MODE_INFRA
;
382 case ACX_MODE_3_MANAGED_AP
:
383 *uwrq
= IW_MODE_MASTER
;
386 result
= -EOPNOTSUPP
;
390 #if SHOW_SPECIFIC_MACMODE_JOINED
393 switch (priv
->macmode_joined
) {
394 case ACX_MODE_0_IBSS_ADHOC
:
395 *uwrq
= IW_MODE_ADHOC
;
397 case ACX_MODE_2_MANAGED_STA
:
398 *uwrq
= IW_MODE_INFRA
;
400 case ACX_MODE_3_MANAGED_AP
:
401 *uwrq
= IW_MODE_MASTER
;
404 result
= -EOPNOTSUPP
;
411 acxlog(L_IOCTL
, "Get Mode ==> %d\n", *uwrq
);
416 static inline int acx100_ioctl_set_sens(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
418 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
420 acxlog(L_IOCTL
, "Set Sensitivity <== %d\n", vwrq
->value
);
422 if ((RADIO_RFMD_11
== priv
->radio_type
) || (RADIO_MAXIM_0D
== priv
->radio_type
)) {
423 priv
->sensitivity
= (1 == vwrq
->disabled
) ? 0 : vwrq
->value
;
424 priv
->set_mask
|= GETSET_SENSITIVITY
;
427 printk("ERROR: don't know how to set sensitivity for this radio type, please try to add that!\n");
432 static inline int acx100_ioctl_get_sens(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
434 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
436 if ((RADIO_RFMD_11
== priv
->radio_type
) || (RADIO_MAXIM_0D
== priv
->radio_type
)) {
437 acxlog(L_IOCTL
, "Get Sensitivity ==> %d\n", priv
->sensitivity
);
439 vwrq
->value
= priv
->sensitivity
;
440 vwrq
->disabled
= (vwrq
->value
== 0);
444 printk("ERROR: don't know how to get sensitivity for this radio type, please try to add that!\n");
449 /*------------------------------------------------------------------------------
452 * Sets the MAC address of the AP to associate with
460 * Call context: Process
464 *----------------------------------------------------------------------------*/
465 static inline int acx100_ioctl_set_ap(struct net_device
*dev
,
466 struct iw_request_info
*info
,
467 struct sockaddr
*awrq
, char *extra
)
469 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
470 static const unsigned char off
[ETH_ALEN
] = { 0, 0, 0, 0, 0, 0 };
480 if (ARPHRD_ETHER
!= awrq
->sa_family
) {
486 acxlog(L_IOCTL
, "Set AP <== %02x:%02x:%02x:%02x:%02x:%02x\n",
487 ap
[0], ap
[1], ap
[2], ap
[3], ap
[4], ap
[5]);
489 if (ACX_MODE_2_MANAGED_STA
!= priv
->macmode_wanted
) {
494 if (0 != acx100_is_mac_address_broadcast(ap
)) {
495 /* "any" == "auto" == FF:FF:FF:FF:FF:FF */
497 acxlog(L_IOCTL
, "Forcing reassociation\n");
498 acx100_scan_chan(priv
);
499 result
= -EINPROGRESS
;
500 } else if (!memcmp(off
, ap
, ETH_ALEN
)) {
501 /* "off" == 00:00:00:00:00:00 */
503 acxlog(L_IOCTL
, "Not reassociating\n");
505 /* AB:CD:EF:01:23:45 */
506 for (i
= 0; i
< priv
->bss_table_count
; i
++) {
507 struct bss_info
*bss
= &priv
->bss_table
[i
];
508 if (!memcmp(bss
->bssid
, ap
, ETH_ALEN
)) {
509 if ((!!priv
->wep_enabled
) != !!(bss
->caps
& IEEE802_11_MGMT_CAP_WEP
)) {
513 MAC_COPY(priv
->ap
, ap
);
514 acxlog(L_IOCTL
, "Forcing reassociation\n");
515 acx100_scan_chan(priv
);
516 result
= -EINPROGRESS
;
528 static inline int acx100_ioctl_get_ap(struct net_device
*dev
, struct iw_request_info
*info
, struct sockaddr
*awrq
, char *extra
)
530 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
532 acxlog(L_IOCTL
, "Get BSSID\n");
533 if (ISTATUS_4_ASSOCIATED
== priv
->status
) {
534 /* as seen in Aironet driver, airo.c */
535 MAC_COPY(awrq
->sa_data
, priv
->bssid
);
537 MAC_FILL(awrq
->sa_data
, 0x0);
539 awrq
->sa_family
= ARPHRD_ETHER
;
543 /*----------------------------------------------------------------
544 * acx100_ioctl_get_aplist
557 * Comment: deprecated in favour of iwscan.
558 * We simply return the list of currently available stations in range,
559 * don't do a new scan.
561 *----------------------------------------------------------------*/
562 static inline int acx100_ioctl_get_aplist(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
564 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
565 struct sockaddr
*address
= (struct sockaddr
*) extra
;
566 struct iw_quality qual
[IW_MAX_AP
];
572 /* in Master mode of course we don't have an AP list... */
573 if (ACX_MODE_3_MANAGED_AP
== priv
->macmode_joined
)
575 result
= -EOPNOTSUPP
;
579 for (i
= 0; i
< priv
->bss_table_count
; i
++) {
580 MAC_COPY(address
[i
].sa_data
, priv
->bss_table
[i
].bssid
);
581 address
[i
].sa_family
= ARPHRD_ETHER
;
582 qual
[i
].level
= priv
->bss_table
[i
].sir
;
583 qual
[i
].noise
= priv
->bss_table
[i
].snr
;
585 qual
[i
].qual
= acx_signal_determine_quality(qual
[i
].level
, qual
[i
].noise
);
587 qual
[i
].qual
= (qual
[i
].noise
<= 100) ?
588 100 - qual
[i
].noise
: 0;;
590 qual
[i
].updated
= 0; /* no scan: level/noise/qual not updated */
595 memcpy(extra
+ sizeof(struct sockaddr
)*i
, &qual
,
596 sizeof(struct iw_quality
)*i
);
599 dwrq
->length
= priv
->bss_table_count
;
606 static inline int acx100_ioctl_set_scan(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
608 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
609 int result
= -EINVAL
;
613 /* don't start scan if device is not up yet */
614 if (0 == (priv
->dev_state_mask
& ACX_STATE_IFACE_UP
)) {
619 acx100_scan_chan(priv
);
620 priv
->scan_start
= jiffies
;
621 priv
->scan_running
= 1;
629 #if WIRELESS_EXT > 13
630 static char *acx100_ioctl_scan_add_station(wlandevice_t
*priv
, char *ptr
, char *end_buf
, struct bss_info
*bss
)
638 /* MAC address has to be added first */
640 iwe
.u
.ap_addr
.sa_family
= ARPHRD_ETHER
;
641 MAC_COPY(iwe
.u
.ap_addr
.sa_data
, bss
->bssid
);
642 acxlog(L_IOCTL
, "scan, station address:\n");
643 acx100_log_mac_address(L_IOCTL
, bss
->bssid
);
644 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_ADDR_LEN
);
647 iwe
.cmd
= SIOCGIWESSID
;
648 iwe
.u
.data
.length
= bss
->essid_len
;
649 iwe
.u
.data
.flags
= 1;
650 acxlog(L_IOCTL
, "scan, essid: %s\n", bss
->essid
);
651 ptr
= iwe_stream_add_point(ptr
, end_buf
, &iwe
, bss
->essid
);
654 iwe
.cmd
= SIOCGIWMODE
;
655 if (0 != (bss
->caps
& (IEEE802_11_MGMT_CAP_ESS
| IEEE802_11_MGMT_CAP_IBSS
))) {
656 if (0 != (bss
->caps
& IEEE802_11_MGMT_CAP_ESS
))
657 iwe
.u
.mode
= IW_MODE_MASTER
;
659 iwe
.u
.mode
= IW_MODE_ADHOC
;
660 acxlog(L_IOCTL
, "scan, mode: %d\n", iwe
.u
.mode
);
661 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_UINT_LEN
);
665 iwe
.cmd
= SIOCGIWFREQ
;
666 iwe
.u
.freq
.m
= acx100_channel_freq
[bss
->channel
- 1] * 100000;
668 acxlog(L_IOCTL
, "scan, frequency: %d\n", iwe
.u
.freq
.m
);
669 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_FREQ_LEN
);
671 /* Add link quality */
673 /* FIXME: these values should be expressed in dBm, but we don't know
674 * how to calibrate it yet */
675 iwe
.u
.qual
.level
= bss
->sir
;
676 iwe
.u
.qual
.noise
= bss
->snr
;
678 iwe
.u
.qual
.qual
= acx_signal_determine_quality(iwe
.u
.qual
.level
, iwe
.u
.qual
.noise
);
680 iwe
.u
.qual
.qual
= (iwe
.u
.qual
.noise
<= 100) ?
681 100 - iwe
.u
.qual
.noise
: 0;
683 iwe
.u
.qual
.updated
= 7;
684 acxlog(L_IOCTL
, "scan, link quality: %d/%d/%d\n", iwe
.u
.qual
.level
, iwe
.u
.qual
.noise
, iwe
.u
.qual
.qual
);
685 ptr
= iwe_stream_add_event(ptr
, end_buf
, &iwe
, IW_EV_QUAL_LEN
);
688 iwe
.cmd
= SIOCGIWENCODE
;
689 if (0 != (bss
->caps
& IEEE802_11_MGMT_CAP_WEP
))
690 iwe
.u
.data
.flags
= IW_ENCODE_ENABLED
| IW_ENCODE_NOKEY
;
692 iwe
.u
.data
.flags
= IW_ENCODE_DISABLED
;
693 iwe
.u
.data
.length
= 0;
694 acxlog(L_IOCTL
, "scan, encryption flags: %x\n", iwe
.u
.data
.flags
);
695 ptr
= iwe_stream_add_point(ptr
, end_buf
, &iwe
, bss
->essid
);
698 iwe
.cmd
= SIOCGIWRATE
;
699 iwe
.u
.bitrate
.fixed
= iwe
.u
.bitrate
.disabled
= 0;
700 ptr_rate
= ptr
+ IW_EV_LCP_LEN
;
701 for (i
= 0; 0 != bss
->supp_rates
[i
]; i
++)
703 iwe
.u
.bitrate
.value
= (bss
->supp_rates
[i
] & ~0x80) * 500000; /* units of 500kb/s */
704 acxlog(L_IOCTL
, "scan, rate: %d [%02x]\n", iwe
.u
.bitrate
.value
, bss
->supp_rates
[i
]);
705 ptr
= iwe_stream_add_value(ptr
, ptr_rate
, end_buf
, &iwe
, IW_EV_PARAM_LEN
);
707 if ((ptr_rate
- ptr
) > (ptrdiff_t)IW_EV_LCP_LEN
)
710 /* drop remaining station data items for now */
712 FN_EXIT(1, (int)ptr
);
716 static inline int acx100_ioctl_get_scan(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
718 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
725 /* no scan available if device is not up yet */
726 if (0 == (priv
->dev_state_mask
& ACX_STATE_IFACE_UP
))
732 if (priv
->scan_start
&& time_before(jiffies
, priv
->scan_start
+ 3*HZ
))
734 /* scan still in progress, so no results yet, sorry */
738 priv
->scan_start
= 0;
740 if (priv
->bss_table_count
== 0)
742 /* no stations found */
747 for (i
= 0; i
< priv
->bss_table_count
; i
++)
749 struct bss_info
*bss
= &priv
->bss_table
[i
];
751 ptr
= acx100_ioctl_scan_add_station(priv
, ptr
, extra
+ IW_SCAN_MAX_DATA
, bss
);
753 dwrq
->length
= ptr
- extra
;
760 #endif /* WIRELESS_EXT > 13 */
762 /*----------------------------------------------------------------
763 * acx100_ioctl_set_essid
778 *----------------------------------------------------------------*/
779 static inline int acx100_ioctl_set_essid(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
781 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
782 int len
= dwrq
->length
;
785 int result
= -EINVAL
;
788 acxlog(L_IOCTL
, "Set ESSID <== %s, length %d, flags 0x%04x\n", extra
, len
, dwrq
->flags
);
795 if (0 != (err
= acx100_lock(priv
, &flags
))) {
800 /* ESSID disabled? */
801 if (0 == dwrq
->flags
)
803 priv
->essid_active
= (UINT8
)0;
807 if (dwrq
->length
> IW_ESSID_MAX_SIZE
+1)
813 priv
->essid_len
= (UINT8
)(len
- 1);
814 memcpy(priv
->essid
, extra
, priv
->essid_len
);
815 priv
->essid
[priv
->essid_len
] = '\0';
816 priv
->essid_active
= (UINT8
)1;
819 priv
->set_mask
|= GETSET_ESSID
;
822 acx100_unlock(priv
, &flags
);
823 result
= -EINPROGRESS
;
829 static inline int acx100_ioctl_get_essid(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
831 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
833 acxlog(L_IOCTL
, "Get ESSID ==> %s\n", priv
->essid
);
835 dwrq
->flags
= priv
->essid_active
;
836 if ((UINT8
)0 != priv
->essid_active
)
838 memcpy(extra
, priv
->essid
, priv
->essid_len
);
839 extra
[priv
->essid_len
] = '\0';
840 dwrq
->length
= priv
->essid_len
+ 1;
846 /*----------------------------------------------------------------
847 * acx100_ioctl_set_rate
862 *----------------------------------------------------------------*/
863 static inline int acx100_ioctl_set_rate(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
865 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
868 UINT8 txrate_cfg
, txrate_auto_idx_max
;
869 int result
= -EINVAL
;
873 "rate = %d, fixed = 0x%x, disabled = 0x%x, flags = 0x%x\n",
874 vwrq
->value
, vwrq
->fixed
, vwrq
->disabled
, vwrq
->flags
);
876 #define BITRATE_AUTO 1
878 if ((0 == vwrq
->fixed
) || (1 == vwrq
->fixed
)) {
880 if (1 == vwrq
->fixed
) {
883 switch (vwrq
->value
) {
885 case 1000000: /* 1Mbps */
886 txrate_cfg
= ACX_TXRATE_1
;
887 txrate_auto_idx_max
= 0;
890 case 2000000: /* 2Mbps */
891 txrate_cfg
= ACX_TXRATE_2
;
892 txrate_auto_idx_max
= 1;
895 case 5500000: /* 5.5Mbps */
896 txrate_cfg
= ACX_TXRATE_5_5
;
897 txrate_auto_idx_max
= 2;
900 case 11000000: /* 11Mbps */
901 txrate_cfg
= ACX_TXRATE_11
;
902 txrate_auto_idx_max
= 3;
905 case 22000000: /* 22Mbps */
906 txrate_cfg
= ACX_TXRATE_22PBCC
;
907 txrate_auto_idx_max
= 4;
911 case -1: /* highest available */
912 /* -1 is used to set highest available rate in
913 * case of iwconfig calls without rate given
914 * (iwconfig wlan0 rate auto etc.) */
915 txrate_cfg
= ACX_TXRATE_22PBCC
; /* 22Mbps is not supported by many APs, thus fallback needs to work properly to be able to safely go back to 11! */
916 txrate_auto_idx_max
= 4;
924 } else if (2 == vwrq
->fixed
) {
926 switch (vwrq
->value
) {
929 txrate_cfg
= ACX_TXRATE_1
;
930 txrate_auto_idx_max
= 0;
934 txrate_cfg
= ACX_TXRATE_2
;
935 txrate_auto_idx_max
= 1;
939 txrate_cfg
= ACX_TXRATE_5_5
;
940 txrate_auto_idx_max
= 2;
944 txrate_cfg
= ACX_TXRATE_5_5PBCC
;
945 txrate_auto_idx_max
= 2;
949 txrate_cfg
= ACX_TXRATE_11
;
950 txrate_auto_idx_max
= 3;
954 txrate_cfg
= ACX_TXRATE_11PBCC
;
955 txrate_auto_idx_max
= 3;
959 txrate_cfg
= ACX_TXRATE_22PBCC
;
960 txrate_auto_idx_max
= 4;
969 result
= -EOPNOTSUPP
;
973 if (0 != (err
= acx100_lock(priv
, &flags
))) {
978 priv
->txrate_cfg
= txrate_cfg
;
980 priv
->txrate_auto
= (UINT8
)(vwrq
->fixed
== (__u8
)0);
981 if (1 == priv
->txrate_auto
)
983 if (ACX_TXRATE_1
== txrate_cfg
) { /* auto rate with 1Mbps max. useless */
984 priv
->txrate_auto
= (UINT8
)0;
985 priv
->txrate_curr
= priv
->txrate_cfg
;
987 priv
->txrate_auto_idx_max
= txrate_auto_idx_max
;
988 priv
->txrate_auto_idx
= 1; /* 2Mbps */
989 priv
->txrate_curr
= ACX_TXRATE_2
; /* 2Mbps, play it safe at the beginning */
990 priv
->txrate_fallback_count
= 0;
991 priv
->txrate_stepup_count
= 0;
996 priv
->txrate_curr
= priv
->txrate_cfg
;
998 acx100_unlock(priv
, &flags
);
1001 acxlog(L_IOCTL
, "Tx rate = %d, auto rate %d, current rate %d\n", priv
->txrate_cfg
, priv
->txrate_auto
, priv
->txrate_curr
);
1002 priv
->set_mask
|= SET_RATE_FALLBACK
;
1003 result
= -EINPROGRESS
;
1005 acxlog(L_IOCTL
, "Tx rate = %d\n", priv
->txrate_cfg
);
1013 /*----------------------------------------------------------------
1014 * acx100_ioctl_get_rate
1029 *----------------------------------------------------------------*/
1030 static inline int acx100_ioctl_get_rate(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1032 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1034 vwrq
->value
= priv
->txrate_curr
* 100000;
1036 vwrq
->fixed
= (__u8
)(priv
->txrate_auto
== (UINT8
)0);
1040 vwrq
->disabled
= (__u8
)0;
1044 static inline int acx100_ioctl_set_rts(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1046 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1047 int val
= vwrq
->value
;
1049 if ((__u8
)0 != vwrq
->disabled
)
1051 if ((val
< 0) || (val
> 2312))
1054 priv
->rts_threshold
= val
;
1059 static inline int acx100_ioctl_get_rts(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1061 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1063 vwrq
->value
= priv
->rts_threshold
;
1064 vwrq
->disabled
= (__u8
)(vwrq
->value
>= 2312);
1065 vwrq
->fixed
= (__u8
)1;
1069 /*----------------------------------------------------------------
1070 * acx100_ioctl_set_encode
1085 *----------------------------------------------------------------*/
1086 static inline int acx100_ioctl_set_encode(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
1088 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1090 unsigned long flags
;
1092 int result
= -EINVAL
;
1096 "Set Encoding flags = 0x%04x, size = %i, key: %s\n",
1097 dwrq
->flags
, dwrq
->length
, extra
? "set" : "No key");
1099 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1104 index
= dwrq
->flags
& IW_ENCODE_INDEX
;
1106 if (dwrq
->length
> 0) {
1108 /* if index is 0 or invalid, use default key */
1109 if ((index
== 0) || (index
> 4))
1110 index
= (int)priv
->wep_current_index
;
1114 if (0 == (dwrq
->flags
& IW_ENCODE_NOKEY
)) {
1115 if (dwrq
->length
> 29)
1116 dwrq
->length
= 29; /* restrict it */
1118 if (dwrq
->length
> 13)
1119 priv
->wep_keys
[index
].size
= 29; /* 29*8 == 232, WEP256 */
1121 if (dwrq
->length
> 5)
1122 priv
->wep_keys
[index
].size
= 13; /* 13*8 == 104bit, WEP128 */
1124 if (dwrq
->length
> 0)
1125 priv
->wep_keys
[index
].size
= 5; /* 5*8 == 40bit, WEP64 */
1128 priv
->wep_keys
[index
].size
= 0;
1130 memset(priv
->wep_keys
[index
].key
, 0, sizeof(priv
->wep_keys
[index
].key
));
1131 memcpy(priv
->wep_keys
[index
].key
, extra
, dwrq
->length
);
1135 /* set transmit key */
1136 if ((index
>= 1) && (index
<= 4))
1137 priv
->wep_current_index
= (UINT8
)(index
- 1);
1139 if (0 == (dwrq
->flags
& IW_ENCODE_MODE
))
1141 /* complain if we were not just setting
1148 priv
->wep_enabled
= (UINT8
)(0 == (dwrq
->flags
& IW_ENCODE_DISABLED
));
1150 if (0 != (dwrq
->flags
& IW_ENCODE_OPEN
)) {
1151 priv
->auth_alg
= WLAN_AUTH_ALG_OPENSYSTEM
;
1152 priv
->wep_restricted
= (UINT8
)0;
1153 } else if (0 != (dwrq
->flags
& IW_ENCODE_RESTRICTED
)) {
1154 priv
->auth_alg
= WLAN_AUTH_ALG_SHAREDKEY
;
1155 priv
->wep_restricted
= (UINT8
)1;
1158 /* set flag to make sure the card WEP settings get updated */
1159 priv
->set_mask
|= GETSET_WEP
;
1161 acxlog(L_IOCTL
, "len = %d, key at 0x%p, flags = 0x%x\n",
1162 dwrq
->length
, extra
,
1165 for (index
= 0; index
<= 3; index
++) {
1166 if (0 != priv
->wep_keys
[index
].size
) {
1168 "index = %d, size = %d, key at 0x%p\n",
1169 priv
->wep_keys
[index
].index
,
1170 priv
->wep_keys
[index
].size
,
1171 priv
->wep_keys
[index
].key
);
1174 result
= -EINPROGRESS
;
1177 acx100_unlock(priv
, &flags
);
1183 /*----------------------------------------------------------------
1184 * acx100_ioctl_get_encode
1199 *----------------------------------------------------------------*/
1200 static inline int acx100_ioctl_get_encode(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
1202 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1204 if (ACX_MODE_0_IBSS_ADHOC
== priv
->macmode_wanted
) {
1205 /* ok, let's assume it's supported, but print a
1207 * FIXME: should be removed once it's definitely working. */
1208 acxlog(L_STD
, "Warning: WEP support might not be supported in Ad-Hoc mode yet!\n");
1209 /* return -EOPNOTSUPP; */
1212 if (priv
->wep_enabled
== (UINT8
)0)
1214 dwrq
->flags
= IW_ENCODE_DISABLED
;
1219 (priv
->wep_restricted
== (UINT8
)1) ? IW_ENCODE_RESTRICTED
: IW_ENCODE_OPEN
;
1222 priv
->wep_keys
[priv
->wep_current_index
].size
;
1225 priv
->wep_keys
[priv
->wep_current_index
].key
,
1226 priv
->wep_keys
[priv
->wep_current_index
].size
);
1229 /* set the current index */
1231 priv
->wep_keys
[priv
->wep_current_index
].index
+ 1;
1233 acxlog(L_IOCTL
, "len = %d, key = %p, flags = 0x%x\n",
1234 dwrq
->length
, dwrq
->pointer
,
1240 static inline int acx100_ioctl_set_power(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1242 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1244 acxlog(L_IOCTL
, "Set 802.11 Power Save flags = 0x%04x\n", vwrq
->flags
);
1245 if ((__u8
)0 != vwrq
->disabled
) {
1246 priv
->ps_wakeup_cfg
&= ~PS_CFG_ENABLE
;
1247 priv
->set_mask
|= GETSET_POWER_80211
;
1248 return -EINPROGRESS
;
1250 if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_TIMEOUT
) {
1251 UINT16 ps_timeout
= (vwrq
->value
* 1024) / 1000;
1253 if (ps_timeout
> 255)
1255 acxlog(L_IOCTL
, "setting PS timeout value to %d time units due to %dus\n", ps_timeout
, vwrq
->value
);
1256 priv
->ps_hangover_period
= ps_timeout
;
1257 } else if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_PERIOD
) {
1258 UINT16 ps_periods
= vwrq
->value
/ 1000000;
1260 if (ps_periods
> 255)
1262 acxlog(L_IOCTL
, "setting PS period value to %d periods due to %dus\n", ps_periods
, vwrq
->value
);
1263 priv
->ps_listen_interval
= ps_periods
;
1264 priv
->ps_wakeup_cfg
&= ~PS_CFG_WAKEUP_MODE_MASK
;
1265 priv
->ps_wakeup_cfg
|= PS_CFG_WAKEUP_EACH_ITVL
;
1267 switch (vwrq
->flags
& IW_POWER_MODE
) {
1268 /* FIXME: are we doing the right thing here? */
1269 case IW_POWER_UNICAST_R
:
1270 priv
->ps_options
&= ~PS_OPT_STILL_RCV_BCASTS
;
1272 case IW_POWER_MULTICAST_R
:
1273 priv
->ps_options
|= PS_OPT_STILL_RCV_BCASTS
;
1275 case IW_POWER_ALL_R
:
1276 priv
->ps_options
|= PS_OPT_STILL_RCV_BCASTS
;
1281 acxlog(L_IOCTL
, "unknown PS mode\n");
1284 priv
->ps_wakeup_cfg
|= PS_CFG_ENABLE
;
1285 priv
->set_mask
|= GETSET_POWER_80211
;
1286 return -EINPROGRESS
;
1290 static inline int acx100_ioctl_get_power(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1292 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1294 acxlog(L_IOCTL
, "Get 802.11 Power Save flags = 0x%04x\n", vwrq
->flags
);
1295 vwrq
->disabled
= ((priv
->ps_wakeup_cfg
& PS_CFG_ENABLE
) == (UINT8
)0);
1296 if (0 != vwrq
->disabled
)
1298 if ((vwrq
->flags
& IW_POWER_TYPE
) == IW_POWER_TIMEOUT
) {
1299 vwrq
->value
= priv
->ps_hangover_period
* 1000 / 1024;
1300 vwrq
->flags
= IW_POWER_TIMEOUT
;
1302 vwrq
->value
= priv
->ps_listen_interval
* 1000000;
1303 vwrq
->flags
= IW_POWER_PERIOD
|IW_POWER_RELATIVE
;
1305 if (0 != (priv
->ps_options
& PS_OPT_STILL_RCV_BCASTS
))
1306 vwrq
->flags
|= IW_POWER_ALL_R
;
1308 vwrq
->flags
|= IW_POWER_UNICAST_R
;
1313 /*----------------------------------------------------------------
1314 * acx100_ioctl_get_txpow
1329 *----------------------------------------------------------------*/
1330 static inline int acx100_ioctl_get_txpow(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1332 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1334 vwrq
->flags
= IW_TXPOW_DBM
;
1335 vwrq
->disabled
= (__u8
)0;
1336 vwrq
->fixed
= (__u8
)0;
1337 vwrq
->value
= priv
->tx_level_dbm
;
1339 acxlog(L_IOCTL
, "Get Tx power ==> %d dBm\n", priv
->tx_level_dbm
);
1344 /*----------------------------------------------------------------
1345 * acx100_ioctl_set_txpow
1360 *----------------------------------------------------------------*/
1361 static inline int acx100_ioctl_set_txpow(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1363 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1364 unsigned long flags
;
1366 int result
= -EINVAL
;
1369 acxlog(L_IOCTL
, "Set Tx power <== %d, disabled %d, flags 0x%04x\n", vwrq
->value
, vwrq
->disabled
, vwrq
->flags
);
1370 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1374 if (vwrq
->disabled
!= priv
->tx_disabled
) {
1375 priv
->set_mask
|= GETSET_TX
; /* Tx status needs update later */
1378 priv
->tx_disabled
= vwrq
->disabled
;
1379 if (vwrq
->value
== -1) {
1380 if (0 != vwrq
->disabled
) {
1381 priv
->tx_level_dbm
= (UINT8
)0;
1382 acxlog(L_IOCTL
, "Disable radio Tx\n");
1384 priv
->tx_level_auto
= (UINT8
)1;
1385 acxlog(L_IOCTL
, "Set Tx power auto (NIY)\n");
1388 priv
->tx_level_dbm
= vwrq
->value
<= 20 ? vwrq
->value
: 20;
1389 priv
->tx_level_auto
= (UINT8
)0;
1390 acxlog(L_IOCTL
, "Set Tx power = %d dBm\n", priv
->tx_level_dbm
);
1392 priv
->set_mask
|= GETSET_TXPOWER
;
1393 acx100_unlock(priv
, &flags
);
1394 result
= -EINPROGRESS
;
1400 /*----------------------------------------------------------------
1401 * acx100_ioctl_get_range
1416 *----------------------------------------------------------------*/
1417 static inline int acx100_ioctl_get_range(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
1419 if (dwrq
->pointer
!= NULL
) {
1420 struct iw_range
*range
= (struct iw_range
*)extra
;
1421 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1424 dwrq
->length
= sizeof(struct iw_range
);
1425 memset(range
, 0, sizeof(struct iw_range
));
1426 range
->num_channels
= 0;
1427 for (i
= 1; i
<= 14; i
++)
1428 if (0 != (priv
->reg_dom_chanmask
& (1 << (i
- 1))))
1430 range
->freq
[range
->num_channels
].i
= i
;
1431 range
->freq
[range
->num_channels
].m
= acx100_channel_freq
[i
- 1] * 100000;
1432 range
->freq
[range
->num_channels
++].e
= 1; /* MHz values */
1434 range
->num_frequency
= (__u8
)range
->num_channels
;
1437 range
->max_rts
= 2312;
1438 /* range->min_frag = 256;
1439 * range->max_frag = 2312;
1442 range
->encoding_size
[0] = 5;
1443 range
->encoding_size
[1] = 13;
1444 range
->encoding_size
[2] = 29;
1445 range
->num_encoding_sizes
= (__u8
)3;
1446 range
->max_encoding_tokens
= (__u8
)4;
1449 range
->max_pmp
= 5000000;
1451 range
->max_pmt
= 65535 * 1000;
1452 range
->pmp_flags
= IW_POWER_PERIOD
;
1453 range
->pmt_flags
= IW_POWER_TIMEOUT
;
1454 range
->pm_capa
= IW_POWER_PERIOD
| IW_POWER_TIMEOUT
| IW_POWER_ALL_R
;
1456 for (i
= 0; i
<= IW_MAX_TXPOWER
- 1; i
++)
1457 range
->txpower
[i
] = 20 * i
/ (IW_MAX_TXPOWER
- 1);
1458 range
->num_txpower
= (__u8
)IW_MAX_TXPOWER
;
1459 range
->txpower_capa
= IW_TXPOW_DBM
;
1461 range
->we_version_compiled
= (__u8
)WIRELESS_EXT
;
1462 range
->we_version_source
= (__u8
)0x9;
1464 range
->retry_capa
= IW_RETRY_LIMIT
;
1465 range
->retry_flags
= IW_RETRY_LIMIT
;
1466 range
->min_retry
= 1;
1467 range
->max_retry
= 255;
1469 range
->r_time_flags
= IW_RETRY_LIFETIME
;
1470 range
->min_r_time
= 0;
1471 range
->max_r_time
= 65535; /* FIXME: lifetime ranges and orders of magnitude are strange?? */
1473 range
->sensitivity
= 0xff;
1475 for (i
=0; i
< (UINT16
)priv
->rate_spt_len
; i
++) {
1476 range
->bitrate
[i
] = (priv
->rate_support1
[i
] & ~0x80) * 500000;
1477 if (range
->bitrate
[i
] == 0)
1480 range
->num_bitrates
= (__u8
)i
;
1482 range
->max_qual
.qual
= (__u8
)100;
1483 range
->max_qual
.level
= (__u8
)100;
1484 range
->max_qual
.noise
= (__u8
)100;
1485 /* FIXME: better values */
1486 range
->avg_qual
.qual
= (__u8
)90;
1487 range
->avg_qual
.level
= (__u8
)80;
1488 range
->avg_qual
.noise
= (__u8
)2;
1495 /*================================================================*/
1496 /* Private functions */
1497 /*================================================================*/
1499 /*----------------------------------------------------------------
1500 * acx100_ioctl_get_iw_priv
1513 * Comment: I added the monitor mode and changed the stuff below to look more like the orinoco driver
1515 *----------------------------------------------------------------*/
1516 static inline int acx100_ioctl_get_iw_priv(struct iwreq
*iwr
)
1518 int result
= -EINVAL
;
1520 if (iwr
->u
.data
.pointer
!= 0) {
1522 verify_area(VERIFY_WRITE
, iwr
->u
.data
.pointer
,
1523 sizeof(acx100_ioctl_private_args
));
1527 iwr
->u
.data
.length
= sizeof(acx100_ioctl_private_args
) / sizeof(acx100_ioctl_private_args
[0]);
1528 if (copy_to_user(iwr
->u
.data
.pointer
, acx100_ioctl_private_args
, sizeof(acx100_ioctl_private_args
)) !=
1535 /*----------------------------------------------------------------
1536 * acx100_ioctl_get_nick
1551 *----------------------------------------------------------------*/
1552 static inline int acx100_ioctl_get_nick(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
1554 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1556 /* FIXME : consider spinlock here */
1557 strcpy(extra
, priv
->nick
);
1558 /* FIXME : consider spinlock here */
1560 dwrq
->length
= strlen(extra
)+1;
1565 /*----------------------------------------------------------------
1566 * acx100_ioctl_set_nick
1579 * Comment: copied from orinoco.c
1581 *----------------------------------------------------------------*/
1582 static inline int acx100_ioctl_set_nick(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_point
*dwrq
, char *extra
)
1584 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1585 unsigned long flags
;
1587 int result
= -EINVAL
;
1591 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1596 if(dwrq
->length
> IW_ESSID_MAX_SIZE
+ 1) {
1601 /* extra includes trailing \0, so it's ok */
1602 strcpy(priv
->nick
, extra
);
1606 acx100_unlock(priv
, &flags
);
1612 /*------------------------------------------------------------------------------
1613 * acx100_ioctl_get_retry
1627 *----------------------------------------------------------------------------*/
1628 static inline int acx100_ioctl_get_retry(struct net_device
*dev
,
1629 struct iw_request_info
*info
,
1630 struct iw_param
*vwrq
, char *extra
)
1632 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
1633 __u16 type
= vwrq
->flags
& IW_RETRY_TYPE
;
1634 __u16 modifier
= vwrq
->flags
& IW_RETRY_MODIFIER
;
1635 unsigned long flags
;
1637 int result
= -EINVAL
;
1639 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1643 /* return the short retry number by default */
1644 if (type
== IW_RETRY_LIFETIME
) {
1645 vwrq
->flags
= IW_RETRY_LIFETIME
;
1646 vwrq
->value
= priv
->msdu_lifetime
;
1647 } else if (modifier
== IW_RETRY_MAX
) {
1648 vwrq
->flags
= IW_RETRY_LIMIT
| IW_RETRY_MAX
;
1649 vwrq
->value
= priv
->long_retry
;
1651 vwrq
->flags
= IW_RETRY_LIMIT
;
1652 if (priv
->long_retry
!= priv
->short_retry
)
1653 vwrq
->flags
|= IW_RETRY_MIN
;
1654 vwrq
->value
= priv
->short_retry
;
1656 acx100_unlock(priv
, &flags
);
1657 /* can't be disabled */
1658 vwrq
->disabled
= (__u8
)0;
1665 /*----------------------------------------------------------------
1666 * acx100_ioctl_set_retry
1681 *----------------------------------------------------------------*/
1682 static inline int acx100_ioctl_set_retry(struct net_device
*dev
,
1683 struct iw_request_info
*info
,
1684 struct iw_param
*vwrq
, char *extra
)
1686 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
1687 unsigned long flags
;
1689 int result
= -EINVAL
;
1696 if ((__u8
)0 != vwrq
->disabled
) {
1700 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1704 if (IW_RETRY_LIMIT
== (vwrq
->flags
& IW_RETRY_TYPE
)) {
1705 (void)printk("current retry limits: short %d long %d\n", priv
->short_retry
, priv
->long_retry
);
1706 if (0 != (vwrq
->flags
& IW_RETRY_MAX
)) {
1707 priv
->long_retry
= vwrq
->value
;
1708 } else if (0 != (vwrq
->flags
& IW_RETRY_MIN
)) {
1709 priv
->short_retry
= vwrq
->value
;
1711 /* no modifier: set both */
1712 priv
->long_retry
= vwrq
->value
;
1713 priv
->short_retry
= vwrq
->value
;
1715 (void)printk("new retry limits: short %d long %d\n", priv
->short_retry
, priv
->long_retry
);
1716 priv
->set_mask
|= GETSET_RETRY
;
1717 result
= -EINPROGRESS
;
1720 if (0 != (vwrq
->flags
& IW_RETRY_LIFETIME
)) {
1721 priv
->msdu_lifetime
= vwrq
->value
;
1722 (void)printk("new MSDU lifetime: %d\n", priv
->msdu_lifetime
);
1723 priv
->set_mask
|= SET_MSDU_LIFETIME
;
1724 result
= -EINPROGRESS
;
1726 acx100_unlock(priv
, &flags
);
1733 /******************************* private ioctls ******************************/
1736 /*----------------------------------------------------------------
1737 * acx100_ioctl_set_debug
1752 *----------------------------------------------------------------*/
1754 static inline int acx100_ioctl_set_debug(struct net_device
*dev
,
1755 struct iw_request_info
*info
,
1756 struct iw_param
*vwrq
, char *extra
)
1758 int debug_new
= *((int *)extra
);
1759 int result
= -EINVAL
;
1761 acxlog(L_STD
, "%s: setting debug from 0x%04X to 0x%04X\n", __func__
,
1771 extern const UINT8 reg_domain_ids
[];
1772 extern const UINT8 reg_domain_ids_len
;
1774 const char *reg_domain_strings
[] =
1775 { "FCC (USA) (1-11)",
1776 "DOC/IC (Canada) (1-11)",
1777 /* BTW: WLAN use in ETSI is regulated by
1778 * ETSI standard EN 300 328-2 V1.1.2 */
1779 "ETSI (Europe) (1-13)",
1784 "Israel? (new!) (4?-8?) (not all firmware versions)",
1785 NULL
/* needs to remain as last entry */
1788 /*----------------------------------------------------------------
1789 * acx100_ioctl_list_reg_domain
1804 *----------------------------------------------------------------*/
1805 static inline int acx100_ioctl_list_reg_domain(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1810 (void)printk("Domain/Country Channels Setting\n");
1811 for (i
= 0, entry
= reg_domain_strings
; *entry
; i
++, entry
++)
1812 (void)printk("%s %d\n", *entry
, i
+1);
1816 /*----------------------------------------------------------------
1817 * acx100_ioctl_set_reg_domain
1832 *----------------------------------------------------------------*/
1833 static inline int acx100_ioctl_set_reg_domain(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1835 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1836 unsigned long flags
;
1838 int result
= -EINVAL
;
1841 if (0 != (err
= acx100_lock(priv
, &flags
))) {
1846 if ((*extra
< 1) || ((size_t)*extra
> reg_domain_ids_len
)) {
1850 priv
->reg_dom_id
= reg_domain_ids
[*extra
- 1];
1851 priv
->set_mask
|= GETSET_REG_DOMAIN
;
1852 result
= -EINPROGRESS
;
1855 acx100_unlock(priv
, &flags
);
1861 /*----------------------------------------------------------------
1862 * acx100_ioctl_get_reg_domain
1877 *----------------------------------------------------------------*/
1878 static inline int acx100_ioctl_get_reg_domain(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1880 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
1883 for (i
=1; i
<= 7; i
++)
1884 if (reg_domain_ids
[i
-1] == priv
->reg_dom_id
)
1886 acxlog(L_STD
, "regulatory domain is currently set to %d (0x%x): %s\n", i
, priv
->reg_dom_id
, reg_domain_strings
[i
-1]);
1894 /*----------------------------------------------------------------
1895 * acx100_ioctl_set_short_preamble
1910 *----------------------------------------------------------------*/
1911 static inline int acx100_ioctl_set_short_preamble(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1913 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
1916 if ((*extra
< (char)0) || (*extra
> (char)2))
1919 priv
->preamble_mode
= (UINT8
)*extra
;
1923 priv
->preamble_flag
= (UINT8
)0;
1927 priv
->preamble_flag
= (UINT8
)1;
1930 descr
= "auto (peer capability dependent)";
1932 /* associated to a station? */
1933 if ((UINT8
)0x0 != priv
->station_assoc
.bssid
[0])
1934 priv
->preamble_flag
= (UINT8
)((priv
->station_assoc
.caps
& IEEE802_11_MGMT_CAP_SHORT_PRE
) == IEEE802_11_MGMT_CAP_SHORT_PRE
);
1937 descr
= "unknown mode, error";
1940 (void)printk("new Short Preamble setting: %s\n", descr
);
1945 /*----------------------------------------------------------------
1946 * acx100_ioctl_get_short_preamble
1961 *----------------------------------------------------------------*/
1962 static inline int acx100_ioctl_get_short_preamble(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
1964 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
1967 switch(priv
->preamble_mode
) {
1975 descr
= "auto (peer capability dependent)";
1978 descr
= "unknown mode, error";
1981 (void)printk("current Short Preamble setting: %s\n", descr
);
1983 *extra
= (char)priv
->preamble_mode
;
1988 /*----------------------------------------------------------------
1989 * acx100_ioctl_set_antenna
2002 * Comment: TX and RX antenna can be set separately but this function good
2003 * for testing 0-4 bits
2004 *----------------------------------------------------------------*/
2005 static inline int acx100_ioctl_set_antenna(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2007 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2009 (void)printk("current antenna value: 0x%02X\n", priv
->antenna
);
2010 (void)printk("Rx antenna selection seems to be bit 6 (0x40)\n");
2011 (void)printk("Tx antenna selection seems to be bit 5 (0x20)\n");
2012 priv
->antenna
= (UINT8
)*extra
;
2013 (void)printk("new antenna value: 0x%02X\n", priv
->antenna
);
2014 priv
->set_mask
|= GETSET_ANTENNA
;
2016 return -EINPROGRESS
;
2019 /*----------------------------------------------------------------
2020 * acx100_ioctl_get_antenna
2035 *----------------------------------------------------------------*/
2036 static inline int acx100_ioctl_get_antenna(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2038 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2040 (void)printk("current antenna value: 0x%02X\n", priv
->antenna
);
2041 (void)printk("Rx antenna selection seems to be bit 6 (0x40)\n");
2042 (void)printk("Tx antenna selection seems to be bit 5 (0x20)\n");
2047 /*----------------------------------------------------------------
2048 * acx100_ioctl_set_rx_antenna
2051 * Arguments: 0 = antenna1; 1 = antenna2;
2052 * / 2 and 3 = diversity? - need test /
2061 * Comment: Could anybody test which antenna is the external one
2063 *----------------------------------------------------------------*/
2064 static inline int acx100_ioctl_set_rx_antenna(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2066 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2067 unsigned long flags
;
2069 int result
= -EINVAL
;
2072 (void)printk("current antenna value: 0x%02X\n", priv
->antenna
);
2073 /* better keep the separate operations atomic */
2074 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2078 priv
->antenna
&= 0x3f;
2079 priv
->antenna
|= (*extra
<< 6);
2080 priv
->set_mask
|= GETSET_ANTENNA
;
2081 acx100_unlock(priv
, &flags
);
2082 (void)printk("new antenna value: 0x%02X\n", priv
->antenna
);
2083 result
= -EINPROGRESS
;
2090 /*----------------------------------------------------------------
2091 * acx100_ioctl_set_tx_antenna
2094 * Arguments: 0 = antenna1; 1 = antenna2;
2104 * Comment: Could anybody test which antenna is the external one
2106 *----------------------------------------------------------------*/
2107 static inline int acx100_ioctl_set_tx_antenna(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2109 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2110 unsigned long flags
;
2112 int result
= -EINVAL
;
2115 (void)printk("current antenna value: 0x%02X\n", priv
->antenna
);
2116 /* better keep the separate operations atomic */
2117 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2121 priv
->antenna
&= 0xdf;
2122 priv
->antenna
|= ((*extra
&= 0x01) << 5);
2123 priv
->set_mask
|= GETSET_ANTENNA
;
2124 acx100_unlock(priv
, &flags
);
2125 (void)printk("new antenna value: 0x%02X\n", priv
->antenna
);
2126 result
= -EINPROGRESS
;
2133 /*----------------------------------------------------------------
2134 * acx100_ioctl_wlansniff
2149 *----------------------------------------------------------------*/
2150 static inline int acx100_ioctl_wlansniff(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2152 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2153 int *parms
= (int*)extra
;
2154 int enable
= (int)(parms
[0] > 0);
2155 unsigned long flags
;
2157 int result
= -EINVAL
;
2161 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2166 priv
->monitor
= parms
[0];
2167 /* not using printk() here, since it distorts kismet display
2168 * when printk messages activated */
2169 acxlog(L_IOCTL
, "setting monitor to: 0x%02X\n", priv
->monitor
);
2174 priv
->netdev
->type
= ARPHRD_ETHER
;
2177 priv
->netdev
->type
= ARPHRD_IEEE80211_PRISM
;
2180 priv
->netdev
->type
= ARPHRD_IEEE80211
;
2184 if (0 != priv
->monitor
)
2185 priv
->monitor_setting
= 0x02; /* don't decrypt default key only, override decryption mechanism */
2187 priv
->monitor_setting
= 0x00; /* don't decrypt default key only, don't override decryption */
2189 priv
->set_mask
|= SET_RXCONFIG
| SET_WEP_OPTIONS
;
2193 priv
->channel
= parms
[1];
2194 priv
->set_mask
|= GETSET_RX
;
2196 acx100_unlock(priv
, &flags
);
2197 result
= -EINPROGRESS
;
2204 /*----------------------------------------------------------------
2205 * acx100_ioctl_unknown11
2220 *----------------------------------------------------------------*/
2221 static inline int acx100_ioctl_unknown11(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2223 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2224 unsigned long flags
;
2227 int result
= -EINVAL
;
2229 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2233 acx100_transmit_disassoc(&client
, priv
);
2234 acx100_unlock(priv
, &flags
);
2241 /* debug helper function to be able to debug various issues relatively easily */
2242 static inline int acx100_ioctl_dbg_set_masks(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2244 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2245 int *parms
= (int*)extra
;
2246 int result
= -EINVAL
;
2248 acxlog(L_IOCTL
, "setting flags in settings mask: get_mask %08x set_mask %08x\n", (UINT32
)parms
[0], (UINT32
)parms
[1]);
2249 acxlog(L_IOCTL
, "before: get_mask %08x set_mask %08x\n", priv
->get_mask
, priv
->set_mask
);
2250 priv
->get_mask
|= (UINT32
)parms
[0];
2251 priv
->set_mask
|= (UINT32
)parms
[1];
2252 acxlog(L_IOCTL
, "after: get_mask %08x set_mask %08x\n", priv
->get_mask
, priv
->set_mask
);
2253 result
= -EINPROGRESS
; /* immediately call commit handler */
2258 /*----------------------------------------------------------------
2259 * acx100_ioctl_acx111_info
2274 *----------------------------------------------------------------*/
2275 static inline int acx100_ioctl_acx111_info(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2277 wlandevice_t
*priv
= (wlandevice_t
*) dev
->priv
;
2278 TIWLAN_DC
*pDc
= &priv
->dc
;
2279 struct rxdescriptor
*rx_desc
= (struct rxdescriptor
*) pDc
->pRxDescQPool
;
2281 int result
= -EINVAL
;
2282 struct ACX111MemoryConfig memconf
;
2283 struct ACX111QueueConfig queueconf
;
2287 char ratefallback
[0x5];
2288 struct rxhostdescriptor
*rx_host_desc
;
2289 struct txdescriptor
*tx_desc
;
2290 struct txhostdescriptor
*tx_host_desc
;
2293 if ((err = acx100_lock(priv, &flags))) {
2298 if (CHIPTYPE_ACX111
!= priv
->chip_type
) {
2299 acxlog(L_STD
| L_IOCTL
, "ACX111-specific function called with non-ACX111 chip, aborting!\n");
2303 /* get Acx111 Memory Configuration */
2304 memset(&memconf
, 0x00, sizeof(memconf
));
2306 if (!acx100_interrogate(priv
, &memconf
, 0x03)) {
2307 acxlog(L_BINSTD
, "read memconf returns error\n");
2310 /* get Acx111 Queue Configuration */
2311 memset(&queueconf
, 0x00, sizeof(queueconf
));
2313 if (!acx100_interrogate(priv
, &queueconf
, 0x05)) {
2314 acxlog(L_BINSTD
, "read queuehead returns error\n");
2317 /* get Acx111 Memory Map */
2318 memset(memmap
, 0x00, sizeof(memmap
));
2320 if (!acx100_interrogate(priv
, &memmap
, 0x08)) {
2321 acxlog(L_BINSTD
, "read mem map returns error\n");
2324 /* get Acx111 Rx Config */
2325 memset(rxconfig
, 0x00, sizeof(rxconfig
));
2327 if (!acx100_interrogate(priv
, &rxconfig
, 0x10)) {
2328 acxlog(L_BINSTD
, "read rxconfig returns error\n");
2331 /* get Acx111 fcs error count */
2332 memset(fcserror
, 0x00, sizeof(fcserror
));
2334 if (!acx100_interrogate(priv
, &fcserror
, 0x0e)) {
2335 acxlog(L_BINSTD
, "read fcserror returns error\n");
2338 /* get Acx111 rate fallback */
2339 memset(ratefallback
, 0x00, sizeof(ratefallback
));
2341 if (!acx100_interrogate(priv
, &ratefallback
, 0x06)) {
2342 acxlog(L_BINSTD
, "read ratefallback returns error\n");
2345 #if (WLAN_HOSTIF!=WLAN_USB)
2346 /* force occurrence of a beacon interrupt */
2347 acx100_write_reg16(priv
, priv
->io
[IO_ACX_HINT_TRIG
], 0x20);
2350 /* dump Acx111 Mem Configuration */
2351 acxlog(L_STD
, "dump mem config:\n");
2352 acxlog(L_STD
, "data read: %d, struct size: %d\n", memconf
.length
, sizeof(memconf
));
2353 acxlog(L_STD
, "Number of stations: %1X\n", memconf
.no_of_stations
);
2354 acxlog(L_STD
, "Memory block size: %1X\n", memconf
.memory_block_size
);
2355 acxlog(L_STD
, "tx/rx memory block allocation: %1X\n", memconf
.tx_rx_memory_block_allocation
);
2356 acxlog(L_STD
, "count rx: %X / tx: %X queues\n", memconf
.count_rx_queues
, memconf
.count_tx_queues
);
2357 acxlog(L_STD
, "options %1X\n", memconf
.options
);
2358 acxlog(L_STD
, "fragmentation %1X\n", memconf
.fragmentation
);
2360 acxlog(L_STD
, "Rx Queue 1 Count Descriptors: %X\n", memconf
.rx_queue1_count_descs
);
2361 acxlog(L_STD
, "Rx Queue 1 Host Memory Start: %X\n", memconf
.rx_queue1_host_rx_start
);
2363 acxlog(L_STD
, "Tx Queue 1 Count Descriptors: %X\n", memconf
.tx_queue1_count_descs
);
2364 acxlog(L_STD
, "Tx Queue 1 Attributes: %X\n", memconf
.tx_queue1_attributes
);
2367 /* dump Acx111 Queue Configuration */
2368 acxlog(L_STD
, "dump queue head:\n");
2369 acxlog(L_STD
, "data read: %d, struct size: %d\n", queueconf
.length
, sizeof(queueconf
));
2370 acxlog(L_STD
, "tx_memory_block_address (from card): %X\n", queueconf
.tx_memory_block_address
);
2371 acxlog(L_STD
, "rx_memory_block_address (from card): %X\n", queueconf
.rx_memory_block_address
);
2373 acxlog(L_STD
, "rx1_queue address (from card): %X\n", queueconf
.rx1_queue_address
);
2374 acxlog(L_STD
, "tx1_queue address (from card): %X\n", queueconf
.tx1_queue_address
);
2375 acxlog(L_STD
, "tx1_queue attributes (from card): %X\n", queueconf
.tx1_attributes
);
2377 /* dump Acx111 Mem Map */
2378 acxlog(L_STD
, "dump mem map:\n");
2379 acxlog(L_STD
, "data read: %d, struct size: %d\n", *((UINT16
*)&memmap
[0x02]), sizeof(memmap
));
2380 acxlog(L_STD
, "Code start: %X\n", *((UINT32
*)&memmap
[0x04]));
2381 acxlog(L_STD
, "Code end: %X\n", *((UINT32
*)&memmap
[0x08]));
2382 acxlog(L_STD
, "WEP default key start: %X\n", *((UINT32
*)&memmap
[0x0C]));
2383 acxlog(L_STD
, "WEP default key end: %X\n", *((UINT32
*)&memmap
[0x10]));
2384 acxlog(L_STD
, "STA table start: %X\n", *((UINT32
*)&memmap
[0x14]));
2385 acxlog(L_STD
, "STA table end: %X\n", *((UINT32
*)&memmap
[0x18]));
2386 acxlog(L_STD
, "Packet template start: %X\n", *((UINT32
*)&memmap
[0x1C]));
2387 acxlog(L_STD
, "Packet template end: %X\n", *((UINT32
*)&memmap
[0x20]));
2388 acxlog(L_STD
, "Queue memory start: %X\n", *((UINT32
*)&memmap
[0x24]));
2389 acxlog(L_STD
, "Queue memory end: %X\n", *((UINT32
*)&memmap
[0x28]));
2390 acxlog(L_STD
, "Packet memory pool start: %X\n", *((UINT32
*)&memmap
[0x2C]));
2391 acxlog(L_STD
, "Packet memory pool end: %X\n", *((UINT32
*)&memmap
[0x30]));
2393 acxlog(L_STD
, "iobase: %p\n", priv
->iobase
);
2394 acxlog(L_STD
, "iobase2: %p\n", priv
->iobase2
);
2396 /* dump Acx111 Rx Config */
2397 acxlog(L_STD
, "dump rx config:\n");
2398 acxlog(L_STD
, "data read: %d, struct size: %d\n", *((UINT16
*)&rxconfig
[0x02]), sizeof(rxconfig
));
2399 acxlog(L_STD
, "rx config: %X\n", *((UINT16
*)&rxconfig
[0x04]));
2400 acxlog(L_STD
, "rx filter config: %X\n", *((UINT16
*)&rxconfig
[0x06]));
2402 /* dump Acx111 fcs error */
2403 acxlog(L_STD
, "dump fcserror:\n");
2404 acxlog(L_STD
, "data read: %d, struct size: %d\n", *((UINT16
*)&fcserror
[0x02]), sizeof(fcserror
));
2405 acxlog(L_STD
, "fcserrors: %X\n", *((UINT32
*)&fcserror
[0x04]));
2407 /* dump Acx111 rate fallback */
2408 acxlog(L_STD
, "dump rate fallback:\n");
2409 acxlog(L_STD
, "data read: %d, struct size: %d\n", *((UINT16
*)&ratefallback
[0x02]), sizeof(ratefallback
));
2410 acxlog(L_STD
, "ratefallback: %X\n", *((UINT8
*)&ratefallback
[0x04]));
2412 /* dump acx111 internal rx descriptor ring buffer */
2414 /* loop over complete receive pool */
2415 for (i
= 0; i
< pDc
->rx_pool_count
; i
++) {
2417 acxlog(L_STD
, "\ndump internal rxdescriptor %d:\n", i
);
2418 acxlog(L_STD
, "mem pos %p\n", rx_desc
);
2419 acxlog(L_STD
, "next 0x%X\n", rx_desc
->pNextDesc
);
2420 acxlog(L_STD
, "acx mem pointer (dynamic) 0x%X\n", rx_desc
->ACXMemPtr
);
2421 acxlog(L_STD
, "CTL (dynamic) 0x%X\n", rx_desc
->Ctl
);
2422 acxlog(L_STD
, "Rate (dynamic) 0x%X\n", rx_desc
->rate
);
2423 acxlog(L_STD
, "RxStatus (dynamic) 0x%X\n", rx_desc
->error
);
2424 acxlog(L_STD
, "Mod/Pre (dynamic) 0x%X\n", rx_desc
->SNR
);
2429 /* dump host rx descriptor ring buffer */
2431 rx_host_desc
= (struct rxhostdescriptor
*) pDc
->pRxHostDescQPool
;
2433 /* loop over complete receive pool */
2434 for (i
= 0; i
< pDc
->rx_pool_count
; i
++) {
2436 acxlog(L_STD
, "\ndump host rxdescriptor %d:\n", i
);
2437 acxlog(L_STD
, "mem pos 0x%X\n", (UINT32
)rx_host_desc
);
2438 acxlog(L_STD
, "buffer mem pos 0x%X\n", (UINT32
)rx_host_desc
->data_phy
);
2439 acxlog(L_STD
, "buffer mem offset 0x%X\n", rx_host_desc
->data_offset
);
2440 acxlog(L_STD
, "CTL 0x%X\n", rx_host_desc
->Ctl
);
2441 acxlog(L_STD
, "Length 0x%X\n", rx_host_desc
->length
);
2442 acxlog(L_STD
, "next 0x%X\n", (UINT32
)rx_host_desc
->desc_phy_next
);
2443 acxlog(L_STD
, "Status 0x%X\n", rx_host_desc
->Status
);
2449 /* dump acx111 internal tx descriptor ring buffer */
2450 tx_desc
= (struct txdescriptor
*) pDc
->pTxDescQPool
;
2452 /* loop over complete transmit pool */
2453 for (i
= 0; i
< pDc
->tx_pool_count
; i
++) {
2455 acxlog(L_STD
, "\ndump internal txdescriptor %d:\n", i
);
2456 acxlog(L_STD
, "size 0x%X\n", sizeof(struct txdescriptor
));
2457 acxlog(L_STD
, "mem pos 0x%X\n", (UINT32
)tx_desc
);
2458 acxlog(L_STD
, "next 0x%X\n", tx_desc
->pNextDesc
);
2459 acxlog(L_STD
, "acx mem pointer (dynamic) 0x%X\n", tx_desc
->AcxMemPtr
);
2460 acxlog(L_STD
, "host mem pointer (dynamic) 0x%X\n", tx_desc
->HostMemPtr
);
2461 acxlog(L_STD
, "length (dynamic) 0x%X\n", tx_desc
->total_length
);
2462 acxlog(L_STD
, "CTL (dynamic) 0x%X\n", tx_desc
->Ctl
);
2463 acxlog(L_STD
, "CTL2 (dynamic) 0x%X\n", tx_desc
->Ctl2
);
2464 acxlog(L_STD
, "Status (dynamic) 0x%X\n", tx_desc
->error
);
2465 acxlog(L_STD
, "Rate (dynamic) 0x%X\n", tx_desc
->rate
);
2468 if(priv
->chip_type
== CHIPTYPE_ACX111
) {
2469 /* the acx111 txdescriptor is 4 byte larger = 0x34 */
2470 tx_desc
= (struct txdescriptor
*) (((UINT32
)tx_desc
) + 4);
2475 /* dump host tx descriptor ring buffer */
2477 tx_host_desc
= (struct txhostdescriptor
*) pDc
->pTxHostDescQPool
;
2479 /* loop over complete host send pool */
2480 for (i
= 0; i
< pDc
->tx_pool_count
* 2; i
++) {
2482 acxlog(L_STD
, "\ndump host txdescriptor %d:\n", i
);
2483 acxlog(L_STD
, "mem pos 0x%X\n", (UINT32
)tx_host_desc
);
2484 acxlog(L_STD
, "buffer mem pos 0x%X\n", (UINT32
)tx_host_desc
->data_phy
);
2485 acxlog(L_STD
, "buffer mem offset 0x%X\n", tx_host_desc
->data_offset
);
2486 acxlog(L_STD
, "CTL 0x%X\n", tx_host_desc
->Ctl
);
2487 acxlog(L_STD
, "Length 0x%X\n", tx_host_desc
->length
);
2488 acxlog(L_STD
, "next 0x%X\n", (UINT32
)tx_host_desc
->desc_phy_next
);
2489 acxlog(L_STD
, "Status 0x%X\n", tx_host_desc
->Status
);
2495 /* acx100_write_reg16(priv, 0xb4, 0x4); */
2497 /* acx100_unlock(priv, &flags); */
2504 /*----------------------------------------------------------------
2505 * acx100_ioctl_set_ed_threshold
2520 *----------------------------------------------------------------*/
2521 static inline int acx100_ioctl_set_ed_threshold(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2523 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
2525 (void)printk("current ED threshold value: %d\n", priv
->ed_threshold
);
2526 priv
->ed_threshold
= (unsigned char)*extra
;
2527 (void)printk("new ED threshold value: %d\n", (unsigned char)*extra
);
2528 priv
->set_mask
|= GETSET_ED_THRESH
;
2530 return -EINPROGRESS
;
2533 /*----------------------------------------------------------------
2534 * acx100_ioctl_set_cca
2549 *----------------------------------------------------------------*/
2550 static inline int acx100_ioctl_set_cca(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2552 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
2553 unsigned long flags
;
2555 int result
= -EINVAL
;
2557 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2562 (void)printk("current CCA value: 0x%02X\n", priv
->cca
);
2563 priv
->cca
= (unsigned char)*extra
;
2564 (void)printk("new CCA value: 0x%02X\n", (unsigned char)*extra
);
2565 priv
->set_mask
|= GETSET_CCA
;
2566 acx100_unlock(priv
, &flags
);
2567 result
= -EINPROGRESS
;
2573 static inline int acx100_ioctl_set_led_power(struct net_device
*dev
, struct iw_request_info
*info
, struct iw_param
*vwrq
, char *extra
)
2575 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
2576 unsigned long flags
;
2578 int result
= -EINVAL
;
2580 if (0 != (err
= acx100_lock(priv
, &flags
))) {
2584 (void)printk("current power LED status: %d\n", priv
->led_power
);
2585 priv
->led_power
= (unsigned char)*extra
;
2586 (void)printk("new power LED status: %d\n", (unsigned char)*extra
);
2587 priv
->set_mask
|= GETSET_LED_POWER
;
2589 acx100_unlock(priv
, &flags
);
2590 result
= -EINPROGRESS
;
2596 #if WIRELESS_EXT >= 13
2597 static const iw_handler acx100_ioctl_handler
[] =
2599 (iw_handler
) acx100_ioctl_commit
, /* SIOCSIWCOMMIT */
2600 (iw_handler
) acx100_ioctl_get_name
, /* SIOCGIWNAME */
2601 (iw_handler
) NULL
, /* SIOCSIWNWID */
2602 (iw_handler
) NULL
, /* SIOCGIWNWID */
2603 (iw_handler
) acx100_ioctl_set_freq
, /* SIOCSIWFREQ */
2604 (iw_handler
) acx100_ioctl_get_freq
, /* SIOCGIWFREQ */
2605 (iw_handler
) acx100_ioctl_set_mode
, /* SIOCSIWMODE */
2606 (iw_handler
) acx100_ioctl_get_mode
, /* SIOCGIWMODE */
2607 (iw_handler
) acx100_ioctl_set_sens
, /* SIOCSIWSENS */
2608 (iw_handler
) acx100_ioctl_get_sens
, /* SIOCGIWSENS */
2609 (iw_handler
) NULL
, /* SIOCSIWRANGE */
2610 (iw_handler
) acx100_ioctl_get_range
, /* SIOCGIWRANGE */
2611 (iw_handler
) NULL
, /* SIOCSIWPRIV */
2612 (iw_handler
) NULL
, /* SIOCGIWPRIV */
2613 (iw_handler
) NULL
, /* SIOCSIWSTATS */
2614 (iw_handler
) NULL
, /* SIOCGIWSTATS */
2615 #if IW_HANDLER_VERSION > 4
2616 iw_handler_set_spy
, /* SIOCSIWSPY */
2617 iw_handler_get_spy
, /* SIOCGIWSPY */
2618 iw_handler_set_thrspy
, /* SIOCSIWTHRSPY */
2619 iw_handler_get_thrspy
, /* SIOCGIWTHRSPY */
2620 #else /* IW_HANDLER_VERSION > 4 */
2622 (iw_handler
) NULL
/* acx100_ioctl_set_spy */, /* SIOCSIWSPY */
2623 (iw_handler
) NULL
/* acx100_ioctl_get_spy */, /* SIOCGIWSPY */
2625 (iw_handler
) NULL
, /* SIOCSIWSPY */
2626 (iw_handler
) NULL
, /* SIOCGIWSPY */
2628 (iw_handler
) NULL
, /* [nothing] */
2629 (iw_handler
) NULL
, /* [nothing] */
2630 #endif /* IW_HANDLER_VERSION > 4 */
2631 (iw_handler
) acx100_ioctl_set_ap
, /* SIOCSIWAP */
2632 (iw_handler
) acx100_ioctl_get_ap
, /* SIOCGIWAP */
2633 (iw_handler
) NULL
, /* [nothing] */
2634 (iw_handler
) acx100_ioctl_get_aplist
, /* SIOCGIWAPLIST */
2635 #if WIRELESS_EXT > 13
2636 (iw_handler
) acx100_ioctl_set_scan
, /* SIOCSIWSCAN */
2637 (iw_handler
) acx100_ioctl_get_scan
, /* SIOCGIWSCAN */
2639 (iw_handler
) NULL
, /* SIOCSIWSCAN */
2640 (iw_handler
) NULL
, /* SIOCGIWSCAN */
2641 #endif /* WE > 13 */
2642 (iw_handler
) acx100_ioctl_set_essid
, /* SIOCSIWESSID */
2643 (iw_handler
) acx100_ioctl_get_essid
, /* SIOCGIWESSID */
2644 (iw_handler
) acx100_ioctl_set_nick
, /* SIOCSIWNICKN */
2645 (iw_handler
) acx100_ioctl_get_nick
, /* SIOCGIWNICKN */
2646 (iw_handler
) NULL
, /* [nothing] */
2647 (iw_handler
) NULL
, /* [nothing] */
2648 (iw_handler
) acx100_ioctl_set_rate
, /* SIOCSIWRATE */
2649 (iw_handler
) acx100_ioctl_get_rate
, /* SIOCGIWRATE */
2650 (iw_handler
) acx100_ioctl_set_rts
, /* SIOCSIWRTS */
2651 (iw_handler
) acx100_ioctl_get_rts
, /* SIOCGIWRTS */
2652 (iw_handler
) NULL
/* acx100_ioctl_set_frag FIXME */, /* SIOCSIWFRAG */
2653 (iw_handler
) NULL
/* acx100_ioctl_get_frag FIXME */, /* SIOCGIWFRAG */
2654 (iw_handler
) acx100_ioctl_set_txpow
, /* SIOCSIWTXPOW */
2655 (iw_handler
) acx100_ioctl_get_txpow
, /* SIOCGIWTXPOW */
2656 (iw_handler
) acx100_ioctl_set_retry
, /* SIOCSIWRETRY */
2657 (iw_handler
) acx100_ioctl_get_retry
, /* SIOCGIWRETRY */
2658 (iw_handler
) acx100_ioctl_set_encode
, /* SIOCSIWENCODE */
2659 (iw_handler
) acx100_ioctl_get_encode
, /* SIOCGIWENCODE */
2660 (iw_handler
) acx100_ioctl_set_power
, /* SIOCSIWPOWER */
2661 (iw_handler
) acx100_ioctl_get_power
, /* SIOCGIWPOWER */
2664 static const iw_handler acx100_ioctl_private_handler
[] =
2667 (iw_handler
) acx100_ioctl_set_debug
, /* SIOCIWFIRSTPRIV */
2671 (iw_handler
) acx100_ioctl_list_reg_domain
,
2672 (iw_handler
) acx100_ioctl_set_reg_domain
,
2673 (iw_handler
) acx100_ioctl_get_reg_domain
,
2674 (iw_handler
) acx100_ioctl_set_short_preamble
,
2675 (iw_handler
) acx100_ioctl_get_short_preamble
,
2676 (iw_handler
) acx100_ioctl_set_antenna
,
2677 (iw_handler
) acx100_ioctl_get_antenna
,
2678 (iw_handler
) acx100_ioctl_set_rx_antenna
,
2679 (iw_handler
) acx100_ioctl_set_tx_antenna
,
2680 (iw_handler
) acx100_ioctl_set_ed_threshold
,
2681 (iw_handler
) acx100_ioctl_set_cca
,
2682 (iw_handler
) acx100_ioctl_set_led_power
,
2683 (iw_handler
) acx100_ioctl_wlansniff
,
2684 (iw_handler
) acx100_ioctl_unknown11
,
2685 (iw_handler
) acx100_ioctl_dbg_set_masks
,
2686 (iw_handler
) acx100_ioctl_acx111_info
2689 const struct iw_handler_def acx100_ioctl_handler_def
=
2691 .num_standard
= sizeof(acx100_ioctl_handler
)/sizeof(iw_handler
),
2692 .num_private
= sizeof(acx100_ioctl_private_handler
)/sizeof(iw_handler
),
2693 .num_private_args
= sizeof(acx100_ioctl_private_args
)/sizeof(struct iw_priv_args
),
2694 .standard
= (iw_handler
*) acx100_ioctl_handler
,
2695 .private = (iw_handler
*) acx100_ioctl_private_handler
,
2696 .private_args
= (struct iw_priv_args
*) acx100_ioctl_private_args
,
2697 #if WIRELESS_EXT > 15
2698 .spy_offset
= 0 /* FIXME */,
2699 #endif /* WE > 15 */
2702 #endif /* WE > 12 */
2706 #if WIRELESS_EXT < 13
2707 /*================================================================*/
2709 /*================================================================*/
2710 /*----------------------------------------------------------------
2725 * This is the *OLD* ioctl handler.
2726 * Make sure to not only place your additions here, but instead mainly
2727 * in the new one (acx100_ioctl_handler[])!
2729 *----------------------------------------------------------------*/
2730 int acx_ioctl_old(netdevice_t
*dev
, struct ifreq
*ifr
, int cmd
)
2732 wlandevice_t
*priv
= (wlandevice_t
*)dev
->priv
;
2734 #if WIRELESS_EXT < 13
2735 struct iwreq
*iwr
= (struct iwreq
*)ifr
;
2738 acxlog(L_IOCTL
, "%s cmd = 0x%04X\n", __func__
, cmd
);
2740 /* This is the way it is done in the orinoco driver.
2741 * Check to see if device is present.
2743 if (0 == netif_device_present(dev
))
2749 /* WE 13 and higher will use acx100_ioctl_handler_def */
2750 #if WIRELESS_EXT < 13
2752 /* get name == wireless protocol */
2753 result
= acx100_ioctl_get_name(dev
, NULL
,
2754 (char *)&(iwr
->u
.name
), NULL
);
2757 case SIOCSIWNWID
: /* pre-802.11, */
2758 case SIOCGIWNWID
: /* not supported. */
2759 result
= -EOPNOTSUPP
;
2763 /* set channel/frequency (Hz)
2764 data can be frequency or channel :
2766 > 1000 = frequency in Hz */
2767 result
= acx100_ioctl_set_freq(dev
, NULL
, &(iwr
->u
.freq
), NULL
);
2771 /* get channel/frequency (Hz) */
2772 result
= acx100_ioctl_get_freq(dev
, NULL
, &(iwr
->u
.freq
), NULL
);
2776 /* set operation mode */
2777 result
= acx100_ioctl_set_mode(dev
, NULL
, &(iwr
->u
.mode
), NULL
);
2781 /* get operation mode */
2782 result
= acx100_ioctl_get_mode(dev
, NULL
, &(iwr
->u
.mode
), NULL
);
2786 /* Set sensitivity */
2787 result
= acx100_ioctl_set_sens(dev
, NULL
, &(iwr
->u
.sens
), NULL
);
2791 /* Get sensitivity */
2792 result
= acx100_ioctl_get_sens(dev
, NULL
, &(iwr
->u
.sens
), NULL
);
2795 #if WIRELESS_EXT > 10
2797 /* Get range of parameters */
2799 struct iw_range range
;
2800 result
= acx100_ioctl_get_range(dev
, NULL
,
2801 &(iwr
->u
.data
), (char *)&range
);
2802 if (copy_to_user(iwr
->u
.data
.pointer
, &range
,
2803 sizeof(struct iw_range
)))
2810 result
= acx100_ioctl_get_iw_priv(iwr
);
2813 /* case SIOCSIWSPY: FIXME */
2814 /* case SIOCGIWSPY: FIXME */
2815 /* case SIOCSIWTHRSPY: FIXME */
2816 /* case SIOCGIWTHRSPY: FIXME */
2819 /* set access point by MAC address */
2820 result
= acx100_ioctl_set_ap(dev
, NULL
, &(iwr
->u
.ap_addr
),
2825 /* get access point MAC address */
2826 result
= acx100_ioctl_get_ap(dev
, NULL
, &(iwr
->u
.ap_addr
),
2831 /* get list of access points in range */
2832 result
= acx100_ioctl_get_aplist(dev
, NULL
, &(iwr
->u
.data
),
2836 #if NOT_FINISHED_YET
2837 /* FIXME: do proper interfacing to activate that! */
2839 /* start a station scan */
2840 result
= acx100_ioctl_set_scan(iwr
, priv
);
2844 /* get list of stations found during scan */
2845 result
= acx100_ioctl_get_scan(iwr
, priv
);
2850 /* set ESSID (network name) */
2852 char essid
[IW_ESSID_MAX_SIZE
+1];
2854 if (iwr
->u
.essid
.length
> IW_ESSID_MAX_SIZE
)
2859 if (copy_from_user(essid
, iwr
->u
.essid
.pointer
,
2860 iwr
->u
.essid
.length
))
2865 result
= acx100_ioctl_set_essid(dev
, NULL
,
2866 &(iwr
->u
.essid
), essid
);
2873 char essid
[IW_ESSID_MAX_SIZE
+1];
2874 if (iwr
->u
.essid
.pointer
)
2875 result
= acx100_ioctl_get_essid(dev
, NULL
,
2876 &(iwr
->u
.essid
), essid
);
2877 if (copy_to_user(iwr
->u
.essid
.pointer
, essid
,
2878 iwr
->u
.essid
.length
))
2886 char nick
[IW_ESSID_MAX_SIZE
+1];
2888 if (iwr
->u
.data
.length
> IW_ESSID_MAX_SIZE
)
2893 if (copy_from_user(nick
, iwr
->u
.data
.pointer
,
2894 iwr
->u
.data
.length
))
2899 result
= acx100_ioctl_set_nick(dev
, NULL
,
2900 &(iwr
->u
.data
), nick
);
2907 char nick
[IW_ESSID_MAX_SIZE
+1];
2908 if (iwr
->u
.data
.pointer
)
2909 result
= acx100_ioctl_get_nick(dev
, NULL
,
2910 &(iwr
->u
.data
), nick
);
2911 if (copy_to_user(iwr
->u
.data
.pointer
, nick
,
2912 iwr
->u
.data
.length
))
2918 /* set default bit rate (bps) */
2919 result
= acx100_ioctl_set_rate(dev
, NULL
, &(iwr
->u
.bitrate
),
2924 /* get default bit rate (bps) */
2925 result
= acx100_ioctl_get_rate(dev
, NULL
, &(iwr
->u
.bitrate
),
2930 /* set RTS threshold value */
2931 result
= acx100_ioctl_set_rts(dev
, NULL
, &(iwr
->u
.rts
), NULL
);
2934 /* get RTS threshold value */
2935 result
= acx100_ioctl_get_rts(dev
, NULL
, &(iwr
->u
.rts
), NULL
);
2938 /* case SIOCSIWFRAG: FIXME */
2939 /* case SIOCGIWFRAG: FIXME */
2941 #if WIRELESS_EXT > 9
2944 result
= acx100_ioctl_get_txpow(dev
, NULL
, &(iwr
->u
.txpower
),
2950 result
= acx100_ioctl_set_txpow(dev
, NULL
, &(iwr
->u
.txpower
),
2956 result
= acx100_ioctl_set_retry(dev
, NULL
, &(iwr
->u
.retry
), NULL
);
2960 result
= acx100_ioctl_get_retry(dev
, NULL
, &(iwr
->u
.retry
), NULL
);
2965 /* set encoding token & mode */
2967 if (iwr
->u
.encoding
.pointer
) {
2968 if (iwr
->u
.encoding
.length
> 29) {
2972 if (copy_from_user(key
, iwr
->u
.encoding
.pointer
, iwr
->u
.encoding
.length
)) {
2978 if (0 != iwr
->u
.encoding
.length
) {
2982 result
= acx100_ioctl_set_encode(dev
, NULL
,
2983 &(iwr
->u
.encoding
), key
);
2989 /* get encoding token & mode */
2992 result
= acx100_ioctl_get_encode(dev
, NULL
,
2993 &(iwr
->u
.encoding
), key
);
2994 if (iwr
->u
.encoding
.pointer
) {
2995 if (copy_to_user(iwr
->u
.encoding
.pointer
,
2996 key
, iwr
->u
.encoding
.length
))
3002 /******************** iwpriv ioctls below ********************/
3004 case ACX100_IOCTL_DEBUG
:
3005 acx100_ioctl_set_debug(dev
, NULL
, NULL
, iwr
->u
.name
);
3009 case ACX100_IOCTL_LIST_DOM
:
3010 acx100_ioctl_list_reg_domain(dev
, NULL
, NULL
, NULL
);
3013 case ACX100_IOCTL_SET_DOM
:
3014 acx100_ioctl_set_reg_domain(dev
, NULL
, NULL
, iwr
->u
.name
);
3017 case ACX100_IOCTL_GET_DOM
:
3018 acx100_ioctl_get_reg_domain(dev
, NULL
, NULL
, iwr
->u
.name
);
3021 case ACX100_IOCTL_SET_PREAMB
:
3022 acx100_ioctl_set_short_preamble(dev
, NULL
, NULL
, iwr
->u
.name
);
3025 case ACX100_IOCTL_GET_PREAMB
:
3026 acx100_ioctl_get_short_preamble(dev
, NULL
, NULL
, iwr
->u
.name
);
3029 case ACX100_IOCTL_SET_ANT
:
3030 acx100_ioctl_set_antenna(dev
, NULL
, NULL
, iwr
->u
.name
);
3033 case ACX100_IOCTL_GET_ANT
:
3034 acx100_ioctl_get_antenna(dev
, NULL
, NULL
, NULL
);
3037 case ACX100_IOCTL_SET_ED
:
3038 acx100_ioctl_set_ed_threshold(dev
, NULL
, NULL
, iwr
->u
.name
);
3041 case ACX100_IOCTL_SET_CCA
:
3042 acx100_ioctl_set_cca(dev
, NULL
, NULL
, iwr
->u
.name
);
3045 case ACX100_IOCTL_SET_PLED
:
3046 acx100_ioctl_set_led_power(dev
, NULL
, NULL
, iwr
->u
.name
);
3049 case ACX100_IOCTL_MONITOR
: /* set sniff (monitor) mode */
3050 acxlog(L_IOCTL
, "%s: IWPRIV monitor\n", dev
->name
);
3052 /* can only be done by admin */
3053 if (!capable(CAP_NET_ADMIN
)) {
3057 result
= acx100_ioctl_wlansniff(dev
, NULL
, NULL
, iwr
->u
.name
);
3060 case ACX100_IOCTL_RX_ANT
:
3061 acx100_ioctl_set_rx_antenna(dev
, NULL
, NULL
, iwr
->u
.name
);
3064 case ACX100_IOCTL_TX_ANT
:
3065 acx100_ioctl_set_tx_antenna(dev
, NULL
, NULL
, iwr
->u
.name
);
3068 case ACX100_IOCTL_TEST
:
3069 acx100_ioctl_unknown11(dev
, NULL
, NULL
, NULL
);
3072 case ACX100_IOCTL_ACX111_INFO
:
3073 acx100_ioctl_acx111_info(dev
, NULL
, NULL
, NULL
);
3079 acxlog(L_IOCTL
, "wireless ioctl 0x%04X queried but not implemented yet!\n", cmd
);
3080 result
= -EOPNOTSUPP
;
3084 if ((0 != (priv
->dev_state_mask
& ACX_STATE_IFACE_UP
))
3085 && (0 != priv
->set_mask
))
3086 acx100_update_card_settings(priv
, 0, 0, 0);
3088 #if WIRELESS_EXT < 13
3089 /* older WEs don't have a commit handler,
3090 * so we need to fix return code in this case */
3091 if (-EINPROGRESS
== result
)