diff options
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r-- | drivers/net/wireless/orinoco.c | 240 |
1 files changed, 77 insertions, 163 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index cf3daaa1b369..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 */ |
220 | struct hermes_tx_descriptor_802_11 { | 206 | struct 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 */ |
255 | struct hermes_rx_descriptor { | 242 | struct 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; |
@@ -578,8 +563,9 @@ static int orinoco_xmit(struct sk_buff *skb, struct net_device *dev) | |||
578 | txfid, NULL); | 563 | txfid, NULL); |
579 | if (err) { | 564 | if (err) { |
580 | netif_start_queue(dev); | 565 | netif_start_queue(dev); |
581 | printk(KERN_ERR "%s: Error %d transmitting packet\n", | 566 | if (net_ratelimit()) |
582 | dev->name, err); | 567 | printk(KERN_ERR "%s: Error %d transmitting packet\n", |
568 | dev->name, err); | ||
583 | stats->tx_errors++; | 569 | stats->tx_errors++; |
584 | goto fail; | 570 | goto fail; |
585 | } | 571 | } |
@@ -633,16 +619,17 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
633 | struct orinoco_private *priv = netdev_priv(dev); | 619 | struct orinoco_private *priv = netdev_priv(dev); |
634 | struct net_device_stats *stats = &priv->stats; | 620 | struct net_device_stats *stats = &priv->stats; |
635 | u16 fid = hermes_read_regn(hw, TXCOMPLFID); | 621 | u16 fid = hermes_read_regn(hw, TXCOMPLFID); |
622 | u16 status; | ||
636 | struct hermes_tx_descriptor_802_11 hdr; | 623 | struct hermes_tx_descriptor_802_11 hdr; |
637 | int err = 0; | 624 | int err = 0; |
638 | 625 | ||
639 | if (fid == DUMMY_FID) | 626 | if (fid == DUMMY_FID) |
640 | return; /* Nothing's really happened */ | 627 | return; /* Nothing's really happened */ |
641 | 628 | ||
642 | /* Read the frame header */ | 629 | /* Read part of the frame header - we need status and addr1 */ |
643 | err = hermes_bap_pread(hw, IRQ_BAP, &hdr, | 630 | err = hermes_bap_pread(hw, IRQ_BAP, &hdr, |
644 | sizeof(struct hermes_tx_descriptor) + | 631 | offsetof(struct hermes_tx_descriptor_802_11, |
645 | sizeof(struct ieee80211_hdr), | 632 | addr2), |
646 | fid, 0); | 633 | fid, 0); |
647 | 634 | ||
648 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); | 635 | hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); |
@@ -662,8 +649,8 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw) | |||
662 | * exceeded, because that's the only status that really mean | 649 | * exceeded, because that's the only status that really mean |
663 | * that this particular node went away. | 650 | * that this particular node went away. |
664 | * Other errors means that *we* screwed up. - Jean II */ | 651 | * Other errors means that *we* screwed up. - Jean II */ |
665 | hdr.status = le16_to_cpu(hdr.status); | 652 | status = le16_to_cpu(hdr.status); |
666 | if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) { | 653 | if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) { |
667 | union iwreq_data wrqu; | 654 | union iwreq_data wrqu; |
668 | 655 | ||
669 | /* Copy 802.11 dest address. | 656 | /* Copy 802.11 dest address. |
@@ -722,18 +709,13 @@ static inline int is_ethersnap(void *_hdr) | |||
722 | static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, | 709 | static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, |
723 | int level, int noise) | 710 | int level, int noise) |
724 | { | 711 | { |
725 | struct orinoco_private *priv = netdev_priv(dev); | 712 | struct iw_quality wstats; |
726 | int i; | 713 | wstats.level = level - 0x95; |
727 | 714 | wstats.noise = noise - 0x95; | |
728 | /* Gather wireless spy statistics: for each packet, compare the | 715 | wstats.qual = (level > noise) ? (level - noise) : 0; |
729 | * source address with out list, and if match, get the stats... */ | 716 | wstats.updated = 7; |
730 | for (i = 0; i < priv->spy_number; i++) | 717 | /* Update spy records */ |
731 | if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) { | 718 | wireless_spy_update(dev, mac, &wstats); |
732 | priv->spy_stat[i].level = level - 0x95; | ||
733 | priv->spy_stat[i].noise = noise - 0x95; | ||
734 | priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0; | ||
735 | priv->spy_stat[i].updated = 7; | ||
736 | } | ||
737 | } | 719 | } |
738 | 720 | ||
739 | static void orinoco_stat_gather(struct net_device *dev, | 721 | static void orinoco_stat_gather(struct net_device *dev, |
@@ -1054,7 +1036,7 @@ static void orinoco_join_ap(struct net_device *dev) | |||
1054 | unsigned long flags; | 1036 | unsigned long flags; |
1055 | struct join_req { | 1037 | struct join_req { |
1056 | u8 bssid[ETH_ALEN]; | 1038 | u8 bssid[ETH_ALEN]; |
1057 | u16 channel; | 1039 | __le16 channel; |
1058 | } __attribute__ ((packed)) req; | 1040 | } __attribute__ ((packed)) req; |
1059 | const int atom_len = offsetof(struct prism2_scan_apinfo, atim); | 1041 | const int atom_len = offsetof(struct prism2_scan_apinfo, atim); |
1060 | struct prism2_scan_apinfo *atom = NULL; | 1042 | struct prism2_scan_apinfo *atom = NULL; |
@@ -1069,7 +1051,7 @@ static void orinoco_join_ap(struct net_device *dev) | |||
1069 | return; | 1051 | return; |
1070 | 1052 | ||
1071 | if (orinoco_lock(priv, &flags) != 0) | 1053 | if (orinoco_lock(priv, &flags) != 0) |
1072 | goto out; | 1054 | goto fail_lock; |
1073 | 1055 | ||
1074 | /* Sanity checks in case user changed something in the meantime */ | 1056 | /* Sanity checks in case user changed something in the meantime */ |
1075 | if (! priv->bssid_fixed) | 1057 | if (! priv->bssid_fixed) |
@@ -1114,8 +1096,10 @@ static void orinoco_join_ap(struct net_device *dev) | |||
1114 | printk(KERN_ERR "%s: Error issuing join request\n", dev->name); | 1096 | printk(KERN_ERR "%s: Error issuing join request\n", dev->name); |
1115 | 1097 | ||
1116 | out: | 1098 | out: |
1117 | kfree(buf); | ||
1118 | orinoco_unlock(priv, &flags); | 1099 | orinoco_unlock(priv, &flags); |
1100 | |||
1101 | fail_lock: | ||
1102 | kfree(buf); | ||
1119 | } | 1103 | } |
1120 | 1104 | ||
1121 | /* Send new BSSID to userspace */ | 1105 | /* Send new BSSID to userspace */ |
@@ -1133,12 +1117,14 @@ static void orinoco_send_wevents(struct net_device *dev) | |||
1133 | err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID, | 1117 | err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID, |
1134 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); | 1118 | ETH_ALEN, NULL, wrqu.ap_addr.sa_data); |
1135 | if (err != 0) | 1119 | if (err != 0) |
1136 | return; | 1120 | goto out; |
1137 | 1121 | ||
1138 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; | 1122 | wrqu.ap_addr.sa_family = ARPHRD_ETHER; |
1139 | 1123 | ||
1140 | /* Send event to user space */ | 1124 | /* Send event to user space */ |
1141 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); | 1125 | wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL); |
1126 | |||
1127 | out: | ||
1142 | orinoco_unlock(priv, &flags); | 1128 | orinoco_unlock(priv, &flags); |
1143 | } | 1129 | } |
1144 | 1130 | ||
@@ -1147,8 +1133,8 @@ static void __orinoco_ev_info(struct net_device *dev, hermes_t *hw) | |||
1147 | struct orinoco_private *priv = netdev_priv(dev); | 1133 | struct orinoco_private *priv = netdev_priv(dev); |
1148 | u16 infofid; | 1134 | u16 infofid; |
1149 | struct { | 1135 | struct { |
1150 | u16 len; | 1136 | __le16 len; |
1151 | u16 type; | 1137 | __le16 type; |
1152 | } __attribute__ ((packed)) info; | 1138 | } __attribute__ ((packed)) info; |
1153 | int len, type; | 1139 | int len, type; |
1154 | int err; | 1140 | int err; |
@@ -2463,6 +2449,10 @@ struct net_device *alloc_orinocodev(int sizeof_card, | |||
2463 | dev->get_stats = orinoco_get_stats; | 2449 | dev->get_stats = orinoco_get_stats; |
2464 | dev->ethtool_ops = &orinoco_ethtool_ops; | 2450 | dev->ethtool_ops = &orinoco_ethtool_ops; |
2465 | 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 | ||
2466 | dev->change_mtu = orinoco_change_mtu; | 2456 | dev->change_mtu = orinoco_change_mtu; |
2467 | dev->set_multicast_list = orinoco_set_multicast_list; | 2457 | dev->set_multicast_list = orinoco_set_multicast_list; |
2468 | /* 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 */ |
@@ -2834,7 +2824,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev, | |||
2834 | } | 2824 | } |
2835 | } | 2825 | } |
2836 | 2826 | ||
2837 | if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){ | 2827 | if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){ |
2838 | /* Quality stats meaningless in ad-hoc mode */ | 2828 | /* Quality stats meaningless in ad-hoc mode */ |
2839 | } else { | 2829 | } else { |
2840 | range->max_qual.qual = 0x8b - 0x2f; | 2830 | range->max_qual.qual = 0x8b - 0x2f; |
@@ -2881,6 +2871,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev, | |||
2881 | range->min_r_time = 0; | 2871 | range->min_r_time = 0; |
2882 | range->max_r_time = 65535 * 1000; /* ??? */ | 2872 | range->max_r_time = 65535 * 1000; /* ??? */ |
2883 | 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 | |||
2884 | TRACE_EXIT(dev->name); | 2882 | TRACE_EXIT(dev->name); |
2885 | 2883 | ||
2886 | return 0; | 2884 | return 0; |
@@ -3840,92 +3838,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev, | |||
3840 | return err; | 3838 | return err; |
3841 | } | 3839 | } |
3842 | 3840 | ||
3843 | /* Spy is used for link quality/strength measurements in Ad-Hoc mode | ||
3844 | * Jean II */ | ||
3845 | static int orinoco_ioctl_setspy(struct net_device *dev, | ||
3846 | struct iw_request_info *info, | ||
3847 | struct iw_point *srq, | ||
3848 | char *extra) | ||
3849 | |||
3850 | { | ||
3851 | struct orinoco_private *priv = netdev_priv(dev); | ||
3852 | struct sockaddr *address = (struct sockaddr *) extra; | ||
3853 | int number = srq->length; | ||
3854 | int i; | ||
3855 | unsigned long flags; | ||
3856 | |||
3857 | /* Make sure nobody mess with the structure while we do */ | ||
3858 | if (orinoco_lock(priv, &flags) != 0) | ||
3859 | return -EBUSY; | ||
3860 | |||
3861 | /* orinoco_lock() doesn't disable interrupts, so make sure the | ||
3862 | * interrupt rx path don't get confused while we copy */ | ||
3863 | priv->spy_number = 0; | ||
3864 | |||
3865 | if (number > 0) { | ||
3866 | /* Extract the addresses */ | ||
3867 | for (i = 0; i < number; i++) | ||
3868 | memcpy(priv->spy_address[i], address[i].sa_data, | ||
3869 | ETH_ALEN); | ||
3870 | /* Reset stats */ | ||
3871 | memset(priv->spy_stat, 0, | ||
3872 | sizeof(struct iw_quality) * IW_MAX_SPY); | ||
3873 | /* Set number of addresses */ | ||
3874 | priv->spy_number = number; | ||
3875 | } | ||
3876 | |||
3877 | /* Now, let the others play */ | ||
3878 | orinoco_unlock(priv, &flags); | ||
3879 | |||
3880 | /* Do NOT call commit handler */ | ||
3881 | return 0; | ||
3882 | } | ||
3883 | |||
3884 | static int orinoco_ioctl_getspy(struct net_device *dev, | ||
3885 | struct iw_request_info *info, | ||
3886 | struct iw_point *srq, | ||
3887 | char *extra) | ||
3888 | { | ||
3889 | struct orinoco_private *priv = netdev_priv(dev); | ||
3890 | struct sockaddr *address = (struct sockaddr *) extra; | ||
3891 | int number; | ||
3892 | int i; | ||
3893 | unsigned long flags; | ||
3894 | |||
3895 | if (orinoco_lock(priv, &flags) != 0) | ||
3896 | return -EBUSY; | ||
3897 | |||
3898 | number = priv->spy_number; | ||
3899 | /* Create address struct */ | ||
3900 | for (i = 0; i < number; i++) { | ||
3901 | memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN); | ||
3902 | address[i].sa_family = AF_UNIX; | ||
3903 | } | ||
3904 | if (number > 0) { | ||
3905 | /* Create address struct */ | ||
3906 | for (i = 0; i < number; i++) { | ||
3907 | memcpy(address[i].sa_data, priv->spy_address[i], | ||
3908 | ETH_ALEN); | ||
3909 | address[i].sa_family = AF_UNIX; | ||
3910 | } | ||
3911 | /* Copy stats */ | ||
3912 | /* In theory, we should disable irqs while copying the stats | ||
3913 | * because the rx path might update it in the middle... | ||
3914 | * Bah, who care ? - Jean II */ | ||
3915 | memcpy(extra + (sizeof(struct sockaddr) * number), | ||
3916 | priv->spy_stat, sizeof(struct iw_quality) * number); | ||
3917 | } | ||
3918 | /* Reset updated flags. */ | ||
3919 | for (i = 0; i < number; i++) | ||
3920 | priv->spy_stat[i].updated = 0; | ||
3921 | |||
3922 | orinoco_unlock(priv, &flags); | ||
3923 | |||
3924 | srq->length = number; | ||
3925 | |||
3926 | return 0; | ||
3927 | } | ||
3928 | |||
3929 | /* Trigger a scan (look for other cells in the vicinity */ | 3841 | /* Trigger a scan (look for other cells in the vicinity */ |
3930 | static int orinoco_ioctl_setscan(struct net_device *dev, | 3842 | static int orinoco_ioctl_setscan(struct net_device *dev, |
3931 | struct iw_request_info *info, | 3843 | struct iw_request_info *info, |
@@ -3998,7 +3910,7 @@ static int orinoco_ioctl_setscan(struct net_device *dev, | |||
3998 | HERMES_HOSTSCAN_SYMBOL_BCAST); | 3910 | HERMES_HOSTSCAN_SYMBOL_BCAST); |
3999 | break; | 3911 | break; |
4000 | case FIRMWARE_TYPE_INTERSIL: { | 3912 | case FIRMWARE_TYPE_INTERSIL: { |
4001 | u16 req[3]; | 3913 | __le16 req[3]; |
4002 | 3914 | ||
4003 | req[0] = cpu_to_le16(0x3fff); /* All channels */ | 3915 | req[0] = cpu_to_le16(0x3fff); /* All channels */ |
4004 | req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */ | 3916 | req[1] = cpu_to_le16(0x0001); /* rate 1 Mbps */ |
@@ -4072,7 +3984,7 @@ static inline int orinoco_translate_scan(struct net_device *dev, | |||
4072 | case FIRMWARE_TYPE_INTERSIL: | 3984 | case FIRMWARE_TYPE_INTERSIL: |
4073 | offset = 4; | 3985 | offset = 4; |
4074 | if (priv->has_hostscan) { | 3986 | if (priv->has_hostscan) { |
4075 | atom_len = le16_to_cpup((u16 *)scan); | 3987 | atom_len = le16_to_cpup((__le16 *)scan); |
4076 | /* Sanity check for atom_len */ | 3988 | /* Sanity check for atom_len */ |
4077 | if (atom_len < sizeof(struct prism2_scan_apinfo)) { | 3989 | if (atom_len < sizeof(struct prism2_scan_apinfo)) { |
4078 | 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", |
@@ -4356,8 +4268,10 @@ static const iw_handler orinoco_handler[] = { | |||
4356 | [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, | 4268 | [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, |
4357 | [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, | 4269 | [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, |
4358 | [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, | 4270 | [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, |
4359 | [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, | 4271 | [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy, |
4360 | [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, | ||
4361 | [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, | 4275 | [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, |
4362 | [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, | 4276 | [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, |
4363 | [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, | 4277 | [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, |