diff options
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/orinoco.c | 41 |
1 files changed, 22 insertions, 19 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index a3a32430ae9d..3eab7e0b8507 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -686,7 +686,7 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
686 | struct orinoco_private *priv = netdev_priv(dev); | 686 | struct orinoco_private *priv = netdev_priv(dev); |
687 | hermes_t *hw = &priv->hw; | 687 | hermes_t *hw = &priv->hw; |
688 | struct iw_statistics *wstats = &priv->wstats; | 688 | struct iw_statistics *wstats = &priv->wstats; |
689 | int err = 0; | 689 | int err; |
690 | unsigned long flags; | 690 | unsigned long flags; |
691 | 691 | ||
692 | if (! netif_device_present(dev)) { | 692 | if (! netif_device_present(dev)) { |
@@ -695,9 +695,21 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
695 | return NULL; /* FIXME: Can we do better than this? */ | 695 | return NULL; /* FIXME: Can we do better than this? */ |
696 | } | 696 | } |
697 | 697 | ||
698 | /* If busy, return the old stats. Returning NULL may cause | ||
699 | * the interface to disappear from /proc/net/wireless */ | ||
698 | if (orinoco_lock(priv, &flags) != 0) | 700 | if (orinoco_lock(priv, &flags) != 0) |
699 | return NULL; /* FIXME: Erg, we've been signalled, how | 701 | return wstats; |
700 | * do we propagate this back up? */ | 702 | |
703 | /* We can't really wait for the tallies inquiry command to | ||
704 | * complete, so we just use the previous results and trigger | ||
705 | * a new tallies inquiry command for next time - Jean II */ | ||
706 | /* FIXME: Really we should wait for the inquiry to come back - | ||
707 | * as it is the stats we give don't make a whole lot of sense. | ||
708 | * Unfortunately, it's not clear how to do that within the | ||
709 | * wireless extensions framework: I think we're in user | ||
710 | * context, but a lock seems to be held by the time we get in | ||
711 | * here so we're not safe to sleep here. */ | ||
712 | hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
701 | 713 | ||
702 | if (priv->iw_mode == IW_MODE_ADHOC) { | 714 | if (priv->iw_mode == IW_MODE_ADHOC) { |
703 | memset(&wstats->qual, 0, sizeof(wstats->qual)); | 715 | memset(&wstats->qual, 0, sizeof(wstats->qual)); |
@@ -716,25 +728,16 @@ static struct iw_statistics *orinoco_get_wireless_stats(struct net_device *dev) | |||
716 | 728 | ||
717 | err = HERMES_READ_RECORD(hw, USER_BAP, | 729 | err = HERMES_READ_RECORD(hw, USER_BAP, |
718 | HERMES_RID_COMMSQUALITY, &cq); | 730 | HERMES_RID_COMMSQUALITY, &cq); |
719 | 731 | ||
720 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); | 732 | if (!err) { |
721 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; | 733 | wstats->qual.qual = (int)le16_to_cpu(cq.qual); |
722 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; | 734 | wstats->qual.level = (int)le16_to_cpu(cq.signal) - 0x95; |
723 | wstats->qual.updated = 7; | 735 | wstats->qual.noise = (int)le16_to_cpu(cq.noise) - 0x95; |
736 | wstats->qual.updated = 7; | ||
737 | } | ||
724 | } | 738 | } |
725 | 739 | ||
726 | /* We can't really wait for the tallies inquiry command to | ||
727 | * complete, so we just use the previous results and trigger | ||
728 | * a new tallies inquiry command for next time - Jean II */ | ||
729 | /* FIXME: We're in user context (I think?), so we should just | ||
730 | wait for the tallies to come through */ | ||
731 | err = hermes_inquire(hw, HERMES_INQ_TALLIES); | ||
732 | |||
733 | orinoco_unlock(priv, &flags); | 740 | orinoco_unlock(priv, &flags); |
734 | |||
735 | if (err) | ||
736 | return NULL; | ||
737 | |||
738 | return wstats; | 741 | return wstats; |
739 | } | 742 | } |
740 | 743 | ||