diff options
| -rw-r--r-- | drivers/net/wireless/orinoco.c | 137 | ||||
| -rw-r--r-- | drivers/net/wireless/orinoco.h | 6 |
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) | |||
| 718 | static inline void orinoco_spy_gather(struct net_device *dev, u_char *mac, | 718 | static 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 | ||
| 735 | static void orinoco_stat_gather(struct net_device *dev, | 730 | static 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 */ | ||
| 3842 | static 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 | |||
| 3881 | static 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 */ |
| 3927 | static int orinoco_ioctl_setscan(struct net_device *dev, | 3847 | static 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 | ||
| 4404 | static void orinoco_get_drvinfo(struct net_device *dev, | 4327 | static 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 */ |
