diff options
-rw-r--r-- | net/wireless/core.h | 3 | ||||
-rw-r--r-- | net/wireless/scan.c | 25 | ||||
-rw-r--r-- | net/wireless/sysfs.c | 7 |
3 files changed, 33 insertions, 2 deletions
diff --git a/net/wireless/core.h b/net/wireless/core.h index e29ad4cd464f..5d0c682d737a 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -49,6 +49,7 @@ struct cfg80211_registered_device { | |||
49 | struct rb_root bss_tree; | 49 | struct rb_root bss_tree; |
50 | u32 bss_generation; | 50 | u32 bss_generation; |
51 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ | 51 | struct cfg80211_scan_request *scan_req; /* protected by RTNL */ |
52 | unsigned long suspend_at; | ||
52 | 53 | ||
53 | /* must be last because of the way we do wiphy_priv(), | 54 | /* must be last because of the way we do wiphy_priv(), |
54 | * and it should at least be aligned to NETDEV_ALIGN */ | 55 | * and it should at least be aligned to NETDEV_ALIGN */ |
@@ -113,5 +114,7 @@ void ieee80211_set_bitrate_flags(struct wiphy *wiphy); | |||
113 | void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); | 114 | void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); |
114 | 115 | ||
115 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); | 116 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev); |
117 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | ||
118 | unsigned long age_secs); | ||
116 | 119 | ||
117 | #endif /* __NET_WIRELESS_CORE_H */ | 120 | #endif /* __NET_WIRELESS_CORE_H */ |
diff --git a/net/wireless/scan.c b/net/wireless/scan.c index b1893c863b97..9fad1631d6cb 100644 --- a/net/wireless/scan.c +++ b/net/wireless/scan.c | |||
@@ -62,6 +62,18 @@ static void bss_release(struct kref *ref) | |||
62 | } | 62 | } |
63 | 63 | ||
64 | /* must hold dev->bss_lock! */ | 64 | /* must hold dev->bss_lock! */ |
65 | void cfg80211_bss_age(struct cfg80211_registered_device *dev, | ||
66 | unsigned long age_secs) | ||
67 | { | ||
68 | struct cfg80211_internal_bss *bss; | ||
69 | unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC); | ||
70 | |||
71 | list_for_each_entry(bss, &dev->bss_list, list) { | ||
72 | bss->ts -= age_jiffies; | ||
73 | } | ||
74 | } | ||
75 | |||
76 | /* must hold dev->bss_lock! */ | ||
65 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev) | 77 | void cfg80211_bss_expire(struct cfg80211_registered_device *dev) |
66 | { | 78 | { |
67 | struct cfg80211_internal_bss *bss, *tmp; | 79 | struct cfg80211_internal_bss *bss, *tmp; |
@@ -584,6 +596,15 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info, | |||
584 | } | 596 | } |
585 | } | 597 | } |
586 | 598 | ||
599 | static inline unsigned int elapsed_jiffies_msecs(unsigned long start) | ||
600 | { | ||
601 | unsigned long end = jiffies; | ||
602 | |||
603 | if (end >= start) | ||
604 | return jiffies_to_msecs(end - start); | ||
605 | |||
606 | return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1); | ||
607 | } | ||
587 | 608 | ||
588 | static char * | 609 | static char * |
589 | ieee80211_bss(struct iw_request_info *info, | 610 | ieee80211_bss(struct iw_request_info *info, |
@@ -763,8 +784,8 @@ ieee80211_bss(struct iw_request_info *info, | |||
763 | &iwe, buf); | 784 | &iwe, buf); |
764 | memset(&iwe, 0, sizeof(iwe)); | 785 | memset(&iwe, 0, sizeof(iwe)); |
765 | iwe.cmd = IWEVCUSTOM; | 786 | iwe.cmd = IWEVCUSTOM; |
766 | sprintf(buf, " Last beacon: %dms ago", | 787 | sprintf(buf, " Last beacon: %ums ago", |
767 | jiffies_to_msecs(jiffies - bss->ts)); | 788 | elapsed_jiffies_msecs(bss->ts)); |
768 | iwe.u.data.length = strlen(buf); | 789 | iwe.u.data.length = strlen(buf); |
769 | current_ev = iwe_stream_add_point(info, current_ev, | 790 | current_ev = iwe_stream_add_point(info, current_ev, |
770 | end_buf, &iwe, buf); | 791 | end_buf, &iwe, buf); |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index 26a72b0797a0..15feaeb5ced5 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -60,6 +60,8 @@ static int wiphy_suspend(struct device *dev, pm_message_t state) | |||
60 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); | 60 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); |
61 | int ret = 0; | 61 | int ret = 0; |
62 | 62 | ||
63 | rdev->suspend_at = get_seconds(); | ||
64 | |||
63 | if (rdev->ops->suspend) { | 65 | if (rdev->ops->suspend) { |
64 | rtnl_lock(); | 66 | rtnl_lock(); |
65 | ret = rdev->ops->suspend(&rdev->wiphy); | 67 | ret = rdev->ops->suspend(&rdev->wiphy); |
@@ -74,6 +76,11 @@ static int wiphy_resume(struct device *dev) | |||
74 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); | 76 | struct cfg80211_registered_device *rdev = dev_to_rdev(dev); |
75 | int ret = 0; | 77 | int ret = 0; |
76 | 78 | ||
79 | /* Age scan results with time spent in suspend */ | ||
80 | spin_lock_bh(&rdev->bss_lock); | ||
81 | cfg80211_bss_age(rdev, get_seconds() - rdev->suspend_at); | ||
82 | spin_unlock_bh(&rdev->bss_lock); | ||
83 | |||
77 | if (rdev->ops->resume) { | 84 | if (rdev->ops->resume) { |
78 | rtnl_lock(); | 85 | rtnl_lock(); |
79 | ret = rdev->ops->resume(&rdev->wiphy); | 86 | ret = rdev->ops->resume(&rdev->wiphy); |