aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPavel Roskin <proski@gnu.org>2005-09-09 18:43:02 -0400
committerJeff Garzik <jgarzik@pobox.com>2005-09-14 08:30:54 -0400
commit343c686c04eec556645f251f7d6c9b3d7335dae0 (patch)
tree2713fbd5e71f7a7dbe94634a1bc4eb81a1ed8af5
parentb81e8e1f4a51556586f72711a165bc3a0de230f3 (diff)
[PATCH] orinoco: WE-18 support
Author: Jean Tourrilhes <jt@hpl.hp.com> Signed-off-by: Pavel Roskin <proski@gnu.org> Use new Wireless Extension API for wireless stats. Signed-off-by: Jeff Garzik <jgarzik@pobox.com>
-rw-r--r--drivers/net/wireless/orinoco.c137
-rw-r--r--drivers/net/wireless/orinoco.h6
2 files changed, 33 insertions, 110 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8de49fe57233..639b8e4ba684 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -137,7 +137,7 @@ MODULE_PARM_DESC(force_monitor, "Allow monitor mode for all firmware versions");
137 137
138/* We do this this way to avoid ifdefs in the actual code */ 138/* We do this this way to avoid ifdefs in the actual code */
139#ifdef WIRELESS_SPY 139#ifdef WIRELESS_SPY
140#define SPY_NUMBER(priv) (priv->spy_number) 140#define SPY_NUMBER(priv) (priv->spy_data.spy_number)
141#else 141#else
142#define SPY_NUMBER(priv) 0 142#define SPY_NUMBER(priv) 0
143#endif /* WIRELESS_SPY */ 143#endif /* WIRELESS_SPY */
@@ -396,10 +396,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 396 /* If a spy address is defined, we report stats of the
397 * first spy address - Jean II */ 397 * first spy address - Jean II */
398 if (SPY_NUMBER(priv)) { 398 if (SPY_NUMBER(priv)) {
399 wstats->qual.qual = priv->spy_stat[0].qual; 399 wstats->qual.qual = priv->spy_data.spy_stat[0].qual;
400 wstats->qual.level = priv->spy_stat[0].level; 400 wstats->qual.level = priv->spy_data.spy_stat[0].level;
401 wstats->qual.noise = priv->spy_stat[0].noise; 401 wstats->qual.noise = priv->spy_data.spy_stat[0].noise;
402 wstats->qual.updated = priv->spy_stat[0].updated; 402 wstats->qual.updated = priv->spy_data.spy_stat[0].updated;
403 } 403 }
404 } else { 404 } else {
405 struct { 405 struct {
@@ -718,18 +718,13 @@ static inline int is_ethersnap(void *_hdr)
718static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, 718static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac,
719 int level, int noise) 719 int level, int noise)
720{ 720{
721 struct orinoco_private *priv = netdev_priv(dev); 721 struct iw_quality wstats;
722 int i; 722 wstats.level = level - 0x95;
723 723 wstats.noise = noise - 0x95;
724 /* Gather wireless spy statistics: for each packet, compare the 724 wstats.qual = (level > noise) ? (level - noise) : 0;
725 * source address with out list, and if match, get the stats... */ 725 wstats.updated = 7;
726 for (i = 0; i < priv->spy_number; i++) 726 /* Update spy records */
727 if (!memcmp(mac, priv->spy_address[i], ETH_ALEN)) { 727 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} 728}
734 729
735static void orinoco_stat_gather(struct net_device *dev, 730static void orinoco_stat_gather(struct net_device *dev,
@@ -2458,8 +2453,11 @@ struct net_device *alloc_orinocodev(int sizeof_card,
2458 dev->watchdog_timeo = HZ; /* 1 second timeout */ 2453 dev->watchdog_timeo = HZ; /* 1 second timeout */
2459 dev->get_stats = orinoco_get_stats; 2454 dev->get_stats = orinoco_get_stats;
2460 dev->ethtool_ops = &orinoco_ethtool_ops; 2455 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; 2456 dev->wireless_handlers = (struct iw_handler_def *)&orinoco_handler_def;
2457#ifdef WIRELESS_SPY
2458 priv->wireless_data.spy_data = &priv->spy_data;
2459 dev->wireless_data = &priv->wireless_data;
2460#endif
2463 dev->change_mtu = orinoco_change_mtu; 2461 dev->change_mtu = orinoco_change_mtu;
2464 dev->set_multicast_list = orinoco_set_multicast_list; 2462 dev->set_multicast_list = orinoco_set_multicast_list;
2465 /* we use the default eth_mac_addr for setting the MAC addr */ 2463 /* we use the default eth_mac_addr for setting the MAC addr */
@@ -2831,7 +2829,7 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2831 } 2829 }
2832 } 2830 }
2833 2831
2834 if ((priv->iw_mode == IW_MODE_ADHOC) && (priv->spy_number == 0)){ 2832 if ((priv->iw_mode == IW_MODE_ADHOC) && (!SPY_NUMBER(priv))){
2835 /* Quality stats meaningless in ad-hoc mode */ 2833 /* Quality stats meaningless in ad-hoc mode */
2836 } else { 2834 } else {
2837 range->max_qual.qual = 0x8b - 0x2f; 2835 range->max_qual.qual = 0x8b - 0x2f;
@@ -2878,6 +2876,14 @@ static int orinoco_ioctl_getiwrange(struct net_device *dev,
2878 range->min_r_time = 0; 2876 range->min_r_time = 0;
2879 range->max_r_time = 65535 * 1000; /* ??? */ 2877 range->max_r_time = 65535 * 1000; /* ??? */
2880 2878
2879 /* Event capability (kernel) */
2880 IW_EVENT_CAPA_SET_KERNEL(range->event_capa);
2881 /* Event capability (driver) */
2882 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWTHRSPY);
2883 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWAP);
2884 IW_EVENT_CAPA_SET(range->event_capa, SIOCGIWSCAN);
2885 IW_EVENT_CAPA_SET(range->event_capa, IWEVTXDROP);
2886
2881 TRACE_EXIT(dev->name); 2887 TRACE_EXIT(dev->name);
2882 2888
2883 return 0; 2889 return 0;
@@ -3837,92 +3843,6 @@ static int orinoco_ioctl_getrid(struct net_device *dev,
3837 return err; 3843 return err;
3838} 3844}
3839 3845
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 */ 3846/* Trigger a scan (look for other cells in the vicinity */
3927static int orinoco_ioctl_setscan(struct net_device *dev, 3847static int orinoco_ioctl_setscan(struct net_device *dev,
3928 struct iw_request_info *info, 3848 struct iw_request_info *info,
@@ -4353,8 +4273,10 @@ static const iw_handler orinoco_handler[] = {
4353 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens, 4273 [SIOCSIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setsens,
4354 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens, 4274 [SIOCGIWSENS -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getsens,
4355 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange, 4275 [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getiwrange,
4356 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setspy, 4276 [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
4357 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getspy, 4277 [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
4278 [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
4279 [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
4358 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap, 4280 [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setwap,
4359 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap, 4281 [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_getwap,
4360 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan, 4282 [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) orinoco_ioctl_setscan,
@@ -4399,6 +4321,7 @@ static const struct iw_handler_def orinoco_handler_def = {
4399 .standard = orinoco_handler, 4321 .standard = orinoco_handler,
4400 .private = orinoco_private_handler, 4322 .private = orinoco_private_handler,
4401 .private_args = orinoco_privtab, 4323 .private_args = orinoco_privtab,
4324 .get_wireless_stats = orinoco_get_wireless_stats,
4402}; 4325};
4403 4326
4404static void orinoco_get_drvinfo(struct net_device *dev, 4327static void orinoco_get_drvinfo(struct net_device *dev,
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 2f213a7103fe..c800563034a7 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -13,6 +13,7 @@
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/netdevice.h> 14#include <linux/netdevice.h>
15#include <linux/wireless.h> 15#include <linux/wireless.h>
16#include <net/iw_handler.h>
16#include <linux/version.h> 17#include <linux/version.h>
17 18
18#include "hermes.h" 19#include "hermes.h"
@@ -112,9 +113,8 @@ struct orinoco_private {
112 u16 pm_on, pm_mcast, pm_period, pm_timeout; 113 u16 pm_on, pm_mcast, pm_period, pm_timeout;
113 u16 preamble; 114 u16 preamble;
114#ifdef WIRELESS_SPY 115#ifdef WIRELESS_SPY
115 int spy_number; 116 struct iw_spy_data spy_data; /* iwspy support */
116 u_char spy_address[IW_MAX_SPY][ETH_ALEN]; 117 struct iw_public_data wireless_data;
117 struct iw_quality spy_stat[IW_MAX_SPY];
118#endif 118#endif
119 119
120 /* Configuration dependent variables */ 120 /* Configuration dependent variables */