aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r--drivers/net/wireless/orinoco.c235
1 files changed, 74 insertions, 161 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 15ceaf615756..d3d4ec9e242e 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -77,30 +77,16 @@
77#define DRIVER_NAME "orinoco" 77#define DRIVER_NAME "orinoco"
78 78
79#include <linux/config.h> 79#include <linux/config.h>
80
81#include <linux/module.h> 80#include <linux/module.h>
82#include <linux/kernel.h> 81#include <linux/kernel.h>
83#include <linux/init.h> 82#include <linux/init.h>
84#include <linux/ptrace.h>
85#include <linux/slab.h>
86#include <linux/string.h>
87#include <linux/timer.h>
88#include <linux/ioport.h>
89#include <linux/netdevice.h> 83#include <linux/netdevice.h>
90#include <linux/if_arp.h>
91#include <linux/etherdevice.h> 84#include <linux/etherdevice.h>
92#include <linux/ethtool.h> 85#include <linux/ethtool.h>
93#include <linux/wireless.h> 86#include <linux/wireless.h>
94#include <net/iw_handler.h> 87#include <net/iw_handler.h>
95#include <net/ieee80211.h> 88#include <net/ieee80211.h>
96 89
97#include <net/ieee80211.h>
98
99#include <asm/uaccess.h>
100#include <asm/io.h>
101#include <asm/system.h>
102
103#include "hermes.h"
104#include "hermes_rid.h" 90#include "hermes_rid.h"
105#include "orinoco.h" 91#include "orinoco.h"
106 92
@@ -137,7 +123,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
137 123
138/* We do this this way to avoid ifdefs in the actual code */ 124/* We do this this way to avoid ifdefs in the actual code */
139#ifdef WIRELESS_SPY 125#ifdef WIRELESS_SPY
140#define SPY_NUMBER(priv) (priv->spy_number) 126#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
141#else 127#else
142#define SPY_NUMBER(priv) 0 128#define SPY_NUMBER(priv) 0
143#endif /* WIRELESS_SPY */ 129#endif /* WIRELESS_SPY */
@@ -216,31 +202,32 @@ static struct {
216/********************************************************************/ 202/********************************************************************/
217 203
218/* Used in Event handling. 204/* Used in Event handling.
219 * We avoid nested structres as they break on ARM -- Moustafa */ 205 * We avoid nested structures as they break on ARM -- Moustafa */
220struct hermes_tx_descriptor_802_11 { 206struct hermes_tx_descriptor_802_11 {
221 /* hermes_tx_descriptor */ 207 /* hermes_tx_descriptor */
222 u16 status; 208 __le16 status;
223 u16 reserved1; 209 __le16 reserved1;
224 u16 reserved2; 210 __le16 reserved2;
225 u32 sw_support; 211 __le32 sw_support;
226 u8 retry_count; 212 u8 retry_count;
227 u8 tx_rate; 213 u8 tx_rate;
228 u16 tx_control; 214 __le16 tx_control;
229 215
230 /* ieee802_11_hdr */ 216 /* ieee80211_hdr */
231 u16 frame_ctl; 217 __le16 frame_ctl;
232 u16 duration_id; 218 __le16 duration_id;
233 u8 addr1[ETH_ALEN]; 219 u8 addr1[ETH_ALEN];
234 u8 addr2[ETH_ALEN]; 220 u8 addr2[ETH_ALEN];
235 u8 addr3[ETH_ALEN]; 221 u8 addr3[ETH_ALEN];
236 u16 seq_ctl; 222 __le16 seq_ctl;
237 u8 addr4[ETH_ALEN]; 223 u8 addr4[ETH_ALEN];
238 u16 data_len; 224
225 __le16 data_len;
239 226
240 /* ethhdr */ 227 /* ethhdr */
241 unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ 228 u8 h_dest[ETH_ALEN]; /* destination eth addr */
242 unsigned char h_source[ETH_ALEN]; /* source ether addr */ 229 u8 h_source[ETH_ALEN]; /* source ether addr */
243 unsigned short h_proto; /* packet type ID field */ 230 __be16 h_proto; /* packet type ID field */
244 231
245 /* p8022_hdr */ 232 /* p8022_hdr */
246 u8 dsap; 233 u8 dsap;
@@ -248,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
248 u8 ctrl; 235 u8 ctrl;
249 u8 oui[3]; 236 u8 oui[3];
250 237
251 u16 ethertype; 238 __be16 ethertype;
252} __attribute__ ((packed)); 239} __attribute__ ((packed));
253 240
254/* Rx frame header except compatibility 802.3 header */ 241/* Rx frame header except compatibility 802.3 header */
255struct hermes_rx_descriptor { 242struct hermes_rx_descriptor {
256 /* Control */ 243 /* Control */
257 u16 status; 244 __le16 status;
258 u32 time; 245 __le32 time;
259 u8 silence; 246 u8 silence;
260 u8 signal; 247 u8 signal;
261 u8 rate; 248 u8 rate;
262 u8 rxflow; 249 u8 rxflow;
263 u32 reserved; 250 __le32 reserved;
264 251
265 /* 802.11 header */ 252 /* 802.11 header */
266 u16 frame_ctl; 253 __le16 frame_ctl;
267 u16 duration_id; 254 __le16 duration_id;
268 u8 addr1[ETH_ALEN]; 255 u8 addr1[ETH_ALEN];
269 u8 addr2[ETH_ALEN]; 256 u8 addr2[ETH_ALEN];
270 u8 addr3[ETH_ALEN]; 257 u8 addr3[ETH_ALEN];
271 u16 seq_ctl; 258 __le16 seq_ctl;
272 u8 addr4[ETH_ALEN]; 259 u8 addr4[ETH_ALEN];
273 260
274 /* Data length */ 261 /* Data length */
275 u16 data_len; 262 __le16 data_len;
276} __attribute__ ((packed)); 263} __attribute__ ((packed));
277 264
278/********************************************************************/ 265/********************************************************************/
@@ -396,14 +383,14 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
396 /* If a spy address is defined, we report stats of the 383 /* If a spy address is defined, we report stats of the
397 * first spy address - Jean II */ 384 * first spy address - Jean II */
398 if (SPY_NUMBER(priv)) { 385 if (SPY_NUMBER(priv)) {
399 wstats->qual.qual = priv->spy_stat[0].qual; 386 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
400 wstats->qual.level = priv->spy_stat[0].level; 387 wstats->qual.level = priv->spy_data.spy_stat[0].level;
401 wstats->qual.noise = priv->spy_stat[0].noise; 388 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
402 wstats->qual.updated = priv->spy_stat[0].updated; 389 wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
403 } 390 }
404 } else { 391 } else {
405 struct { 392 struct {
406 u16 qual, signal, noise; 393 __le16 qual, signal, noise;
407 } __attribute__ ((packed)) cq; 394 } __attribute__ ((packed)) cq;
408 395
409 err = HERMES_READ_RECORD(hw, USER_BAP, 396 err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -505,11 +492,9 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev)
505 492
506 /* Check packet length, pad short packets, round up odd length */ 493 /* Check packet length, pad short packets, round up odd length */
507 len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN); 494 len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
508 if (skb->len < len) { 495 skb = skb_padto(skb, len);
509 skb = skb_padto(skb, len); 496 if (skb == NULL)
510 if (skb == NULL) 497 goto fail;
511 goto fail;
512 }
513 len -= ETH_HLEN; 498 len -= ETH_HLEN;
514 499
515 eh = (struct ethhdr *)skb->data; 500 eh = (struct ethhdr *)skb->data;
@@ -634,16 +619,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
634 struct orinoco_private *priv = netdev_priv(dev); 619 struct orinoco_private *priv = netdev_priv(dev);
635 struct net_device_stats *stats = &priv->stats; 620 struct net_device_stats *stats = &priv->stats;
636 u16 fid = hermes_read_regn(hw, TXCOMPLFID); 621 u16 fid = hermes_read_regn(hw, TXCOMPLFID);
622 u16 status;
637 struct hermes_tx_descriptor_802_11 hdr; 623 struct hermes_tx_descriptor_802_11 hdr;
638 int err = 0; 624 int err = 0;
639 625
640 if (fid == DUMMY_FID) 626 if (fid == DUMMY_FID)
641 return; /* Nothing's really happened */ 627 return; /* Nothing's really happened */
642 628
643 /* Read the frame header */ 629 /* Read part of the frame header - we need status and addr1 */
644 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, 630 err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
645 sizeof(struct hermes_tx_descriptor) + 631 offsetof(struct hermes_tx_descriptor_802_11,
646 sizeof(struct ieee80211_hdr), 632 addr2),
647 fid, 0); 633 fid, 0);
648 634
649 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 635 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -663,8 +649,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
663 * exceeded, because that's the only status that really mean 649 * exceeded, because that's the only status that really mean
664 * that this particular node went away. 650 * that this particular node went away.
665 * Other errors means that *we* screwed up. - Jean II */ 651 * Other errors means that *we* screwed up. - Jean II */
666 hdr.status = le16_to_cpu(hdr.status); 652 status = le16_to_cpu(hdr.status);
667 if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) { 653 if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
668 union iwreq_data wrqu; 654 union iwreq_data wrqu;
669 655
670 /* Copy 802.11 dest address. 656 /* Copy 802.11 dest address.
@@ -723,18 +709,13 @@ static inline int is_ethersnap(void *_hdr)
723static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, 709static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
724 int level, int noise) 710 int level, int noise)
725{ 711{
726 struct orinoco_private *priv = netdev_priv(dev); 712 struct iw_quality wstats;
727 int i; 713 wstats.level = level - 0x95;
728 714 wstats.noise = noise - 0x95;
729 /* Gather wireless spy statistics: for each packet, compare the 715 wstats.qual = (level > noise) ? (level - noise) : 0;
730 * source address with out list, and if match, get the stats... */ 716 wstats.updated = 7;
731 for (i = 0; i < priv->spy_number; i++) 717 /* Update spy records */
732 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) { 718 wireless_spy_update(dev, mac, &wstats);
733 priv->spy_stat[i].level = level - 0x95;
734 priv->spy_stat[i].noise = noise - 0x95;
735 priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
736 priv->spy_stat[i].updated = 7;
737 }
738} 719}
739 720
740static void orinoco_stat_gather(struct net_device *dev, 721static void orinoco_stat_gather(struct net_device *dev,
@@ -1055,7 +1036,7 @@ static void orinoco_join_ap(struct net_device *dev)
1055 unsigned long flags; 1036 unsigned long flags;
1056 struct join_req { 1037 struct join_req {
1057 u8 bssid[ETH_ALEN]; 1038 u8 bssid[ETH_ALEN];
1058 u16 channel; 1039 __le16 channel;
1059 } __attribute__ ((packed)) req; 1040 } __attribute__ ((packed)) req;
1060 const int atom_len = offsetof(struct prism2_scan_apinfo, atim); 1041 const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
1061 struct prism2_scan_apinfo *atom = NULL; 1042 struct prism2_scan_apinfo *atom = NULL;
@@ -1070,7 +1051,7 @@ static void orinoco_join_ap(struct net_device *dev)
1070 return; 1051 return;
1071 1052
1072 if (orinoco_lock(priv, &flags) != 0) 1053 if (orinoco_lock(priv, &flags) != 0)
1073 goto out; 1054 goto fail_lock;
1074 1055
1075 /* Sanity checks in case user changed something in the meantime */ 1056 /* Sanity checks in case user changed something in the meantime */
1076 if (! priv->bssid_fixed) 1057 if (! priv->bssid_fixed)
@@ -1115,8 +1096,10 @@ static void orinoco_join_ap(struct net_device *dev)
1115 printk(KERN_ERR "%s: Error issuing join request\n", dev->name); 1096 printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
1116 1097
1117 out: 1098 out:
1118 kfree(buf);
1119 orinoco_unlock(priv, &flags); 1099 orinoco_unlock(priv, &flags);
1100
1101 fail_lock:
1102 kfree(buf);
1120} 1103}
1121 1104
1122/* Send new BSSID to userspace */ 1105/* Send new BSSID to userspace */
@@ -1134,12 +1117,14 @@ static void orinoco_send_wevents(struct net_device *dev)
1134 err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID, 1117 err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
1135 ETH_ALEN, NULL, wrqu.ap_addr.sa_data); 1118 ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
1136 if (err != 0) 1119 if (err != 0)
1137 return; 1120 goto out;
1138 1121
1139 wrqu.ap_addr.sa_family = ARPHRD_ETHER; 1122 wrqu.ap_addr.sa_family = ARPHRD_ETHER;
1140 1123
1141 /* Send event to user space */ 1124 /* Send event to user space */
1142 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); 1125 wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
1126
1127 out:
1143 orinoco_unlock(priv, &flags); 1128 orinoco_unlock(priv, &flags);
1144} 1129}
1145 1130
@@ -1148,8 +1133,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw)
1148 struct orinoco_private *priv = netdev_priv(dev); 1133 struct orinoco_private *priv = netdev_priv(dev);
1149 u16 infofid; 1134 u16 infofid;
1150 struct { 1135 struct {
1151 u16 len; 1136 __le16 len;
1152 u16 type; 1137 __le16 type;
1153 } __attribute__ ((packed)) info; 1138 } __attribute__ ((packed)) info;
1154 int len, type; 1139 int len, type;
1155 int err; 1140 int err;
@@ -2464,6 +2449,10 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2464 dev->get_stats = orinoco_get_stats; 2449 dev->get_stats = orinoco_get_stats;
2465 dev->ethtool_ops = &orinoco_ethtool_ops; 2450 dev->ethtool_ops = &orinoco_ethtool_ops;
2466 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; 2451 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2452#ifdef WIRELESS_SPY
2453 priv->wireless_data.spy_data = &priv->spy_data;
2454 dev->wireless_data = &priv->wireless_data;
2455#endif
2467 dev->change_mtu = orinoco_change_mtu; 2456 dev->change_mtu = orinoco_change_mtu;
2468 dev->set_multicast_list = orinoco_set_multicast_list; 2457 dev->set_multicast_list = orinoco_set_multicast_list;
2469 /* we use the default eth_mac_addr for setting the MAC addr */ 2458 /* we use the default eth_mac_addr for setting the MAC addr */
@@ -2835,7 +2824,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2835 } 2824 }
2836 } 2825 }
2837 2826
2838 if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){ 2827 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
2839 /* Quality stats meaningless in ad-hoc mode */ 2828 /* Quality stats meaningless in ad-hoc mode */
2840 } else { 2829 } else {
2841 range->max_qual.qual = 0x8b - 0x2f; 2830 range->max_qual.qual = 0x8b - 0x2f;
@@ -2882,6 +2871,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2882 range->min_r_time = 0; 2871 range->min_r_time = 0;
2883 range->max_r_time = 65535 * 1000; /* ??? */ 2872 range->max_r_time = 65535 * 1000; /* ??? */
2884 2873
2874 /* Event capability (kernel) */
2875 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
2876 /* Event capability (driver) */
2877 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
2878 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
2879 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
2880 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
2881
2885 TRACE_EXIT(dev->name); 2882 TRACE_EXIT(dev->name);
2886 2883
2887 return 0; 2884 return 0;
@@ -3841,92 +3838,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
3841 return err; 3838 return err;
3842} 3839}
3843 3840
3844/* Spy is used for link quality/strength measurements in Ad-Hoc mode
3845 * Jean II */
3846static int orinoco_ioctl_setspy(struct net_device *dev,
3847 struct iw_request_info *info,
3848 struct iw_point *srq,
3849 char *extra)
3850
3851{
3852 struct orinoco_private *priv = netdev_priv(dev);
3853 struct sockaddr *address = (struct sockaddr *) extra;
3854 int number = srq->length;
3855 int i;
3856 unsigned long flags;
3857
3858 /* Make sure nobody mess with the structure while we do */
3859 if (orinoco_lock(priv, &flags) != 0)
3860 return -EBUSY;
3861
3862 /* orinoco_lock() doesn't disable interrupts, so make sure the
3863 * interrupt rx path don't get confused while we copy */
3864 priv->spy_number = 0;
3865
3866 if (number > 0) {
3867 /* Extract the addresses */
3868 for (i = 0; i < number; i++)
3869 memcpy(priv->spy_address[i], address[i].sa_data,
3870 ETH_ALEN);
3871 /* Reset stats */
3872 memset(priv->spy_stat, 0,
3873 sizeof(struct iw_quality) * IW_MAX_SPY);
3874 /* Set number of addresses */
3875 priv->spy_number = number;
3876 }
3877
3878 /* Now, let the others play */
3879 orinoco_unlock(priv, &flags);
3880
3881 /* Do NOT call commit handler */
3882 return 0;
3883}
3884
3885static int orinoco_ioctl_getspy(struct net_device *dev,
3886 struct iw_request_info *info,
3887 struct iw_point *srq,
3888 char *extra)
3889{
3890 struct orinoco_private *priv = netdev_priv(dev);
3891 struct sockaddr *address = (struct sockaddr *) extra;
3892 int number;
3893 int i;
3894 unsigned long flags;
3895
3896 if (orinoco_lock(priv, &flags) != 0)
3897 return -EBUSY;
3898
3899 number = priv->spy_number;
3900 /* Create address struct */
3901 for (i = 0; i < number; i++) {
3902 memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
3903 address[i].sa_family = AF_UNIX;
3904 }
3905 if (number > 0) {
3906 /* Create address struct */
3907 for (i = 0; i < number; i++) {
3908 memcpy(address[i].sa_data, priv->spy_address[i],
3909 ETH_ALEN);
3910 address[i].sa_family = AF_UNIX;
3911 }
3912 /* Copy stats */
3913 /* In theory, we should disable irqs while copying the stats
3914 * because the rx path might update it in the middle...
3915 * Bah, who care ? - Jean II */
3916 memcpy(extra + (sizeof(struct sockaddr) * number),
3917 priv->spy_stat, sizeof(struct iw_quality) * number);
3918 }
3919 /* Reset updated flags. */
3920 for (i = 0; i < number; i++)
3921 priv->spy_stat[i].updated = 0;
3922
3923 orinoco_unlock(priv, &flags);
3924
3925 srq->length = number;
3926
3927 return 0;
3928}
3929
3930/* Trigger a scan (look for other cells in the vicinity */ 3841/* Trigger a scan (look for other cells in the vicinity */
3931static int orinoco_ioctl_setscan(struct net_device *dev, 3842static int orinoco_ioctl_setscan(struct net_device *dev,
3932 struct iw_request_info *info, 3843 struct iw_request_info *info,
@@ -3999,7 +3910,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev,
3999 HERMES_HOSTSCAN_SYMBOL_BCAST); 3910 HERMES_HOSTSCAN_SYMBOL_BCAST);
4000 break; 3911 break;
4001 case FIRMWARE_TYPE_INTERSIL: { 3912 case FIRMWARE_TYPE_INTERSIL: {
4002 u16 req[3]; 3913 __le16 req[3];
4003 3914
4004 req[0] = cpu_to_le16(0x3fff); /* All channels */ 3915 req[0] = cpu_to_le16(0x3fff); /* All channels */
4005 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */ 3916 req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */
@@ -4073,7 +3984,7 @@ static inline int orinoco_translate_scan(struct net_device *dev,
4073 case FIRMWARE_TYPE_INTERSIL: 3984 case FIRMWARE_TYPE_INTERSIL:
4074 offset = 4; 3985 offset = 4;
4075 if (priv->has_hostscan) { 3986 if (priv->has_hostscan) {
4076 atom_len = le16_to_cpup((u16 *)scan); 3987 atom_len = le16_to_cpup((__le16 *)scan);
4077 /* Sanity check for atom_len */ 3988 /* Sanity check for atom_len */
4078 if (atom_len < sizeof(struct prism2_scan_apinfo)) { 3989 if (atom_len < sizeof(struct prism2_scan_apinfo)) {
4079 printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n", 3990 printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
@@ -4357,8 +4268,10 @@ static const iw_handler orinoco_handler[] = {
4357 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, 4268 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
4358 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, 4269 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
4359 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, 4270 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
4360 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, 4271 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
4361 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, 4272 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
4273 [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
4274 [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
4362 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, 4275 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
4363 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, 4276 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
4364 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, 4277 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,