aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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);