aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-02-11 17:14:43 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:52:40 -0500
commitcb3a8eec0e66edfe8db7d3b3bf19d25745bae3c3 (patch)
treeb4eacfc01470617fca40779bccdca6625dba7716 /net
parentabd2fdb4c606f0e5cfec3647d57ebd20f03caafd (diff)
cfg80211: age scan results on resume
Scanned BSS entries are timestamped with jiffies, which doesn't increment across suspend and hibernate. On resume, every BSS in the scan list looks like it was scanned within the last 10 seconds, irregardless of how long the machine was actually asleep. Age scan results on resume with the time spent during sleep so userspace has a clue how old they really are. Signed-off-by: Dan Williams <dcbw@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net')
-rw-r--r--net/wireless/core.h3
-rw-r--r--net/wireless/scan.c25
-rw-r--r--net/wireless/sysfs.c7
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);
113void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby); 114void wiphy_update_regulatory(struct wiphy *wiphy, enum reg_set_by setby);
114 115
115void cfg80211_bss_expire(struct cfg80211_registered_device *dev); 116void cfg80211_bss_expire(struct cfg80211_registered_device *dev);
117void 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! */
65void 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! */
65void cfg80211_bss_expire(struct cfg80211_registered_device *dev) 77void 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
599static 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
588static char * 609static char *
589ieee80211_bss(struct iw_request_info *info, 610ieee80211_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);