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.c141
1 files changed, 31 insertions, 110 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8de49fe57233..fc2fa4dc3a08 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -94,8 +94,6 @@
94#include <net/iw_handler.h> 94#include <net/iw_handler.h>
95#include <net/ieee80211.h> 95#include <net/ieee80211.h>
96 96
97#include <net/ieee80211.h>
98
99#include <asm/uaccess.h> 97#include <asm/uaccess.h>
100#include <asm/io.h> 98#include <asm/io.h>
101#include <asm/system.h> 99#include <asm/system.h>
@@ -137,7 +135,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
137 135
138/* We do this this way to avoid ifdefs in the actual code */ 136/* We do this this way to avoid ifdefs in the actual code */
139#ifdef WIRELESS_SPY 137#ifdef WIRELESS_SPY
140#define SPY_NUMBER(priv) (priv->spy_number) 138#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
141#else 139#else
142#define SPY_NUMBER(priv) 0 140#define SPY_NUMBER(priv) 0
143#endif /* WIRELESS_SPY */ 141#endif /* WIRELESS_SPY */
@@ -396,10 +394,10 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev)
396 /* If a spy address is defined, we report stats of the 394 /* If a spy address is defined, we report stats of the
397 * first spy address - Jean II */ 395 * first spy address - Jean II */
398 if (SPY_NUMBER(priv)) { 396 if (SPY_NUMBER(priv)) {
399 wstats->qual.qual = priv->spy_stat[0].qual; 397 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
400 wstats->qual.level = priv->spy_stat[0].level; 398 wstats->qual.level = priv->spy_data.spy_stat[0].level;
401 wstats->qual.noise = priv->spy_stat[0].noise; 399 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
402 wstats->qual.updated = priv->spy_stat[0].updated; 400 wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
403 } 401 }
404 } else { 402 } else {
405 struct { 403 struct {
@@ -638,7 +636,7 @@ static void __orinoco_ev_txexc(struct net_device *dev, hermes_t *hw)
638 /* Read the frame header */ 636 /* Read the frame header */
639 err = hermes_bap_pread(hw, IRQ_BAP, &hdr, 637 err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
640 sizeof(struct hermes_tx_descriptor) + 638 sizeof(struct hermes_tx_descriptor) +
641 sizeof(struct ieee80211_hdr), 639 sizeof(struct ieee80211_hdr_4addr),
642 fid, 0); 640 fid, 0);
643 641
644 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID); 642 hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
@@ -718,18 +716,13 @@ static inline int is_ethersnap(void *_hdr)
718static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, 716static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
719 int level, int noise) 717 int level, int noise)
720{ 718{
721 struct orinoco_private *priv = netdev_priv(dev); 719 struct iw_quality wstats;
722 int i; 720 wstats.level = level - 0x95;
723 721 wstats.noise = noise - 0x95;
724 /* Gather wireless spy statistics: for each packet, compare the 722 wstats.qual = (level > noise) ? (level - noise) : 0;
725 * source address with out list, and if match, get the stats... */ 723 wstats.updated = 7;
726 for (i = 0; i < priv->spy_number; i++) 724 /* Update spy records */
727 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) { 725 wireless_spy_update(dev, mac, &wstats);
728 priv->spy_stat[i].level = level - 0x95;
729 priv->spy_stat[i].noise = noise - 0x95;
730 priv->spy_stat[i].qual = (level > noise) ? (level - noise) : 0;
731 priv->spy_stat[i].updated = 7;
732 }
733} 726}
734 727
735static void orinoco_stat_gather(struct net_device *dev, 728static void orinoco_stat_gather(struct net_device *dev,
@@ -2458,8 +2451,11 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2458 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2451 dev->watchdog_timeo = HZ; /* 1 second timeout */
2459 dev->get_stats = orinoco_get_stats; 2452 dev->get_stats = orinoco_get_stats;
2460 dev->ethtool_ops = &orinoco_ethtool_ops; 2453 dev->ethtool_ops = &orinoco_ethtool_ops;
2461 dev->get_wireless_stats = orinoco_get_wireless_stats;
2462 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def; 2454 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2455#ifdef WIRELESS_SPY
2456 priv->wireless_data.spy_data = &priv->spy_data;
2457 dev->wireless_data = &priv->wireless_data;
2458#endif
2463 dev->change_mtu = orinoco_change_mtu; 2459 dev->change_mtu = orinoco_change_mtu;
2464 dev->set_multicast_list = orinoco_set_multicast_list; 2460 dev->set_multicast_list = orinoco_set_multicast_list;
2465 /* we use the default eth_mac_addr for setting the MAC addr */ 2461 /* we use the default eth_mac_addr for setting the MAC addr */
@@ -2831,7 +2827,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2831 } 2827 }
2832 } 2828 }
2833 2829
2834 if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){ 2830 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
2835 /* Quality stats meaningless in ad-hoc mode */ 2831 /* Quality stats meaningless in ad-hoc mode */
2836 } else { 2832 } else {
2837 range->max_qual.qual = 0x8b - 0x2f; 2833 range->max_qual.qual = 0x8b - 0x2f;
@@ -2878,6 +2874,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2878 range->min_r_time = 0; 2874 range->min_r_time = 0;
2879 range->max_r_time = 65535 * 1000; /* ??? */ 2875 range->max_r_time = 65535 * 1000; /* ??? */
2880 2876
2877 /* Event capability (kernel) */
2878 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
2879 /* Event capability (driver) */
2880 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
2881 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
2882 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
2883 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
2884
2881 TRACE_EXIT(dev->name); 2885 TRACE_EXIT(dev->name);
2882 2886
2883 return 0; 2887 return 0;
@@ -3837,92 +3841,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
3837 return err; 3841 return err;
3838} 3842}
3839 3843
3840/* Spy is used for link quality/strength measurements in Ad-Hoc mode
3841 * Jean II */
3842static int orinoco_ioctl_setspy(struct net_device *dev,
3843 struct iw_request_info *info,
3844 struct iw_point *srq,
3845 char *extra)
3846
3847{
3848 struct orinoco_private *priv = netdev_priv(dev);
3849 struct sockaddr *address = (struct sockaddr *) extra;
3850 int number = srq->length;
3851 int i;
3852 unsigned long flags;
3853
3854 /* Make sure nobody mess with the structure while we do */
3855 if (orinoco_lock(priv, &flags) != 0)
3856 return -EBUSY;
3857
3858 /* orinoco_lock() doesn't disable interrupts, so make sure the
3859 * interrupt rx path don't get confused while we copy */
3860 priv->spy_number = 0;
3861
3862 if (number > 0) {
3863 /* Extract the addresses */
3864 for (i = 0; i < number; i++)
3865 memcpy(priv->spy_address[i], address[i].sa_data,
3866 ETH_ALEN);
3867 /* Reset stats */
3868 memset(priv->spy_stat, 0,
3869 sizeof(struct iw_quality) * IW_MAX_SPY);
3870 /* Set number of addresses */
3871 priv->spy_number = number;
3872 }
3873
3874 /* Now, let the others play */
3875 orinoco_unlock(priv, &flags);
3876
3877 /* Do NOT call commit handler */
3878 return 0;
3879}
3880
3881static int orinoco_ioctl_getspy(struct net_device *dev,
3882 struct iw_request_info *info,
3883 struct iw_point *srq,
3884 char *extra)
3885{
3886 struct orinoco_private *priv = netdev_priv(dev);
3887 struct sockaddr *address = (struct sockaddr *) extra;
3888 int number;
3889 int i;
3890 unsigned long flags;
3891
3892 if (orinoco_lock(priv, &flags) != 0)
3893 return -EBUSY;
3894
3895 number = priv->spy_number;
3896 /* Create address struct */
3897 for (i = 0; i < number; i++) {
3898 memcpy(address[i].sa_data, priv->spy_address[i], ETH_ALEN);
3899 address[i].sa_family = AF_UNIX;
3900 }
3901 if (number > 0) {
3902 /* Create address struct */
3903 for (i = 0; i < number; i++) {
3904 memcpy(address[i].sa_data, priv->spy_address[i],
3905 ETH_ALEN);
3906 address[i].sa_family = AF_UNIX;
3907 }
3908 /* Copy stats */
3909 /* In theory, we should disable irqs while copying the stats
3910 * because the rx path might update it in the middle...
3911 * Bah, who care ? - Jean II */
3912 memcpy(extra + (sizeof(struct sockaddr) * number),
3913 priv->spy_stat, sizeof(struct iw_quality) * number);
3914 }
3915 /* Reset updated flags. */
3916 for (i = 0; i < number; i++)
3917 priv->spy_stat[i].updated = 0;
3918
3919 orinoco_unlock(priv, &flags);
3920
3921 srq->length = number;
3922
3923 return 0;
3924}
3925
3926/* Trigger a scan (look for other cells in the vicinity */ 3844/* Trigger a scan (look for other cells in the vicinity */
3927static int orinoco_ioctl_setscan(struct net_device *dev, 3845static int orinoco_ioctl_setscan(struct net_device *dev,
3928 struct iw_request_info *info, 3846 struct iw_request_info *info,
@@ -4353,8 +4271,10 @@ static const iw_handler orinoco_handler[] = {
4353 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, 4271 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
4354 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, 4272 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
4355 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, 4273 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
4356 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, 4274 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
4357 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, 4275 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
4276 [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
4277 [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
4358 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, 4278 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
4359 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, 4279 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
4360 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, 4280 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
@@ -4399,6 +4319,7 @@ static const struct iw_handler_def orinoco_handler_def = {
4399 .standard = orinoco_handler, 4319 .standard = orinoco_handler,
4400 .private = orinoco_private_handler, 4320 .private = orinoco_private_handler,
4401 .private_args = orinoco_privtab, 4321 .private_args = orinoco_privtab,
4322 .get_wireless_stats = orinoco_get_wireless_stats,
4402}; 4323};
4403 4324
4404static void orinoco_get_drvinfo(struct net_device *dev, 4325static void orinoco_get_drvinfo(struct net_device *dev,