aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDan Williams <dcbw@redhat.com>2009-02-11 13:26:06 -0500
committerJohn W. Linville <linville@tuxdriver.com>2009-02-27 14:52:43 -0500
commitc3d72b968129ad4aec86c5fc8d2380f01ebebc53 (patch)
treebb1d4054bba06cab388b6ecfee6d2dddef4e7108
parentbc8263f1d86946ffe97eb249fc1d6660da1e1055 (diff)
ipw2x00: 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>
-rw-r--r--drivers/net/wireless/ipw2x00/ieee80211.h3
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.c12
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2100.h4
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.c10
-rw-r--r--drivers/net/wireless/ipw2x00/ipw2200.h4
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_module.c15
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_rx.c2
-rw-r--r--drivers/net/wireless/ipw2x00/libipw_wx.c24
8 files changed, 65 insertions, 9 deletions
diff --git a/drivers/net/wireless/ipw2x00/ieee80211.h b/drivers/net/wireless/ipw2x00/ieee80211.h
index adb7cf31f781..7515fad00f92 100644
--- a/drivers/net/wireless/ipw2x00/ieee80211.h
+++ b/drivers/net/wireless/ipw2x00/ieee80211.h
@@ -1119,6 +1119,9 @@ static inline int ieee80211_is_cck_rate(u8 rate)
1119extern void free_ieee80211(struct net_device *dev); 1119extern void free_ieee80211(struct net_device *dev);
1120extern struct net_device *alloc_ieee80211(int sizeof_priv); 1120extern struct net_device *alloc_ieee80211(int sizeof_priv);
1121 1121
1122extern void ieee80211_networks_age(struct ieee80211_device *ieee,
1123 unsigned long age_secs);
1124
1122extern int ieee80211_set_encryption(struct ieee80211_device *ieee); 1125extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
1123 1126
1124/* ieee80211_tx.c */ 1127/* ieee80211_tx.c */
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.c b/drivers/net/wireless/ipw2x00/ipw2100.c
index 52b1cf5160f7..3a6d810a7608 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.c
+++ b/drivers/net/wireless/ipw2x00/ipw2100.c
@@ -1692,7 +1692,13 @@ static int ipw2100_up(struct ipw2100_priv *priv, int deferred)
1692 u32 lock; 1692 u32 lock;
1693 u32 ord_len = sizeof(lock); 1693 u32 ord_len = sizeof(lock);
1694 1694
1695 /* Quite if manually disabled. */ 1695 /* Age scan list entries found before suspend */
1696 if (priv->suspend_time) {
1697 ieee80211_networks_age(priv->ieee, priv->suspend_time);
1698 priv->suspend_time = 0;
1699 }
1700
1701 /* Quiet if manually disabled. */
1696 if (priv->status & STATUS_RF_KILL_SW) { 1702 if (priv->status & STATUS_RF_KILL_SW) {
1697 IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable " 1703 IPW_DEBUG_INFO("%s: Radio is disabled by Manual Disable "
1698 "switch\n", priv->net_dev->name); 1704 "switch\n", priv->net_dev->name);
@@ -6415,6 +6421,8 @@ static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
6415 pci_disable_device(pci_dev); 6421 pci_disable_device(pci_dev);
6416 pci_set_power_state(pci_dev, PCI_D3hot); 6422 pci_set_power_state(pci_dev, PCI_D3hot);
6417 6423
6424 priv->suspend_at = get_seconds();
6425
6418 mutex_unlock(&priv->action_mutex); 6426 mutex_unlock(&priv->action_mutex);
6419 6427
6420 return 0; 6428 return 0;
@@ -6458,6 +6466,8 @@ static int ipw2100_resume(struct pci_dev *pci_dev)
6458 * the queue of needed */ 6466 * the queue of needed */
6459 netif_device_attach(dev); 6467 netif_device_attach(dev);
6460 6468
6469 priv->suspend_time = get_seconds() - priv->suspend_at;
6470
6461 /* Bring the device back up */ 6471 /* Bring the device back up */
6462 if (!(priv->status & STATUS_RF_KILL_SW)) 6472 if (!(priv->status & STATUS_RF_KILL_SW))
6463 ipw2100_up(priv, 0); 6473 ipw2100_up(priv, 0);
diff --git a/drivers/net/wireless/ipw2x00/ipw2100.h b/drivers/net/wireless/ipw2x00/ipw2100.h
index 46b135d21670..f183d951cd32 100644
--- a/drivers/net/wireless/ipw2x00/ipw2100.h
+++ b/drivers/net/wireless/ipw2x00/ipw2100.h
@@ -591,6 +591,10 @@ struct ipw2100_priv {
591 591
592 int user_requested_scan; 592 int user_requested_scan;
593 593
594 /* Track time in suspend */
595 unsigned long suspend_at;
596 unsigned long suspend_time;
597
594 u32 interrupts; 598 u32 interrupts;
595 int tx_interrupts; 599 int tx_interrupts;
596 int rx_interrupts; 600 int rx_interrupts;
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.c b/drivers/net/wireless/ipw2x00/ipw2200.c
index 01c4ede90662..a7fb08aecf3f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.c
+++ b/drivers/net/wireless/ipw2x00/ipw2200.c
@@ -11238,6 +11238,12 @@ static int ipw_up(struct ipw_priv *priv)
11238{ 11238{
11239 int rc, i, j; 11239 int rc, i, j;
11240 11240
11241 /* Age scan list entries found before suspend */
11242 if (priv->suspend_time) {
11243 ieee80211_networks_age(priv->ieee, priv->suspend_time);
11244 priv->suspend_time = 0;
11245 }
11246
11241 if (priv->status & STATUS_EXIT_PENDING) 11247 if (priv->status & STATUS_EXIT_PENDING)
11242 return -EIO; 11248 return -EIO;
11243 11249
@@ -11838,6 +11844,8 @@ static int ipw_pci_suspend(struct pci_dev *pdev, pm_message_t state)
11838 pci_disable_device(pdev); 11844 pci_disable_device(pdev);
11839 pci_set_power_state(pdev, pci_choose_state(pdev, state)); 11845 pci_set_power_state(pdev, pci_choose_state(pdev, state));
11840 11846
11847 priv->suspend_at = get_seconds();
11848
11841 return 0; 11849 return 0;
11842} 11850}
11843 11851
@@ -11873,6 +11881,8 @@ static int ipw_pci_resume(struct pci_dev *pdev)
11873 * the queue of needed */ 11881 * the queue of needed */
11874 netif_device_attach(dev); 11882 netif_device_attach(dev);
11875 11883
11884 priv->suspend_time = get_seconds() - priv->suspend_at;
11885
11876 /* Bring the device back up */ 11886 /* Bring the device back up */
11877 queue_work(priv->workqueue, &priv->up); 11887 queue_work(priv->workqueue, &priv->up);
11878 11888
diff --git a/drivers/net/wireless/ipw2x00/ipw2200.h b/drivers/net/wireless/ipw2x00/ipw2200.h
index 3e66c998dfea..05e8ccf01c5f 100644
--- a/drivers/net/wireless/ipw2x00/ipw2200.h
+++ b/drivers/net/wireless/ipw2x00/ipw2200.h
@@ -1347,6 +1347,10 @@ struct ipw_priv {
1347 1347
1348 s8 tx_power; 1348 s8 tx_power;
1349 1349
1350 /* Track time in suspend */
1351 unsigned long suspend_at;
1352 unsigned long suspend_time;
1353
1350#ifdef CONFIG_PM 1354#ifdef CONFIG_PM
1351 u32 pm_state[16]; 1355 u32 pm_state[16];
1352#endif 1356#endif
diff --git a/drivers/net/wireless/ipw2x00/libipw_module.c b/drivers/net/wireless/ipw2x00/libipw_module.c
index 0f233ab6a95b..ec7753446bd3 100644
--- a/drivers/net/wireless/ipw2x00/libipw_module.c
+++ b/drivers/net/wireless/ipw2x00/libipw_module.c
@@ -105,6 +105,21 @@ static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
105 ieee->networks = NULL; 105 ieee->networks = NULL;
106} 106}
107 107
108void ieee80211_networks_age(struct ieee80211_device *ieee,
109 unsigned long age_secs)
110{
111 struct ieee80211_network *network = NULL;
112 unsigned long flags;
113 unsigned long age_jiffies = msecs_to_jiffies(age_secs * MSEC_PER_SEC);
114
115 spin_lock_irqsave(&ieee->lock, flags);
116 list_for_each_entry(network, &ieee->network_list, list) {
117 network->last_scanned -= age_jiffies;
118 }
119 spin_unlock_irqrestore(&ieee->lock, flags);
120}
121EXPORT_SYMBOL(ieee80211_networks_age);
122
108static void ieee80211_networks_initialize(struct ieee80211_device *ieee) 123static void ieee80211_networks_initialize(struct ieee80211_device *ieee)
109{ 124{
110 int i; 125 int i;
diff --git a/drivers/net/wireless/ipw2x00/libipw_rx.c b/drivers/net/wireless/ipw2x00/libipw_rx.c
index 4865475e8a81..8d9e96f9eb28 100644
--- a/drivers/net/wireless/ipw2x00/libipw_rx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_rx.c
@@ -1616,7 +1616,7 @@ static void ieee80211_process_probe_response(struct ieee80211_device
1616 break; 1616 break;
1617 1617
1618 if ((oldest == NULL) || 1618 if ((oldest == NULL) ||
1619 (target->last_scanned < oldest->last_scanned)) 1619 time_before(target->last_scanned, oldest->last_scanned))
1620 oldest = target; 1620 oldest = target;
1621 } 1621 }
1622 1622
diff --git a/drivers/net/wireless/ipw2x00/libipw_wx.c b/drivers/net/wireless/ipw2x00/libipw_wx.c
index dfbadb3b9bd5..3c0812db030a 100644
--- a/drivers/net/wireless/ipw2x00/libipw_wx.c
+++ b/drivers/net/wireless/ipw2x00/libipw_wx.c
@@ -43,6 +43,16 @@ static const char *ieee80211_modes[] = {
43 "?", "a", "b", "ab", "g", "ag", "bg", "abg" 43 "?", "a", "b", "ab", "g", "ag", "bg", "abg"
44}; 44};
45 45
46static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
47{
48 unsigned long end = jiffies;
49
50 if (end >= start)
51 return jiffies_to_msecs(end - start);
52
53 return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
54}
55
46#define MAX_CUSTOM_LEN 64 56#define MAX_CUSTOM_LEN 64
47static char *ieee80211_translate_scan(struct ieee80211_device *ieee, 57static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
48 char *start, char *stop, 58 char *start, char *stop,
@@ -216,8 +226,8 @@ static char *ieee80211_translate_scan(struct ieee80211_device *ieee,
216 iwe.cmd = IWEVCUSTOM; 226 iwe.cmd = IWEVCUSTOM;
217 p = custom; 227 p = custom;
218 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), 228 p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
219 " Last beacon: %dms ago", 229 " Last beacon: %ums ago",
220 jiffies_to_msecs(jiffies - network->last_scanned)); 230 elapsed_jiffies_msecs(network->last_scanned));
221 iwe.u.data.length = p - custom; 231 iwe.u.data.length = p - custom;
222 if (iwe.u.data.length) 232 if (iwe.u.data.length)
223 start = iwe_stream_add_point(info, start, stop, &iwe, custom); 233 start = iwe_stream_add_point(info, start, stop, &iwe, custom);
@@ -277,15 +287,15 @@ int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
277 time_after(network->last_scanned + ieee->scan_age, jiffies)) 287 time_after(network->last_scanned + ieee->scan_age, jiffies))
278 ev = ieee80211_translate_scan(ieee, ev, stop, network, 288 ev = ieee80211_translate_scan(ieee, ev, stop, network,
279 info); 289 info);
280 else 290 else {
281 IEEE80211_DEBUG_SCAN("Not showing network '%s (" 291 IEEE80211_DEBUG_SCAN("Not showing network '%s ("
282 "%pM)' due to age (%dms).\n", 292 "%pM)' due to age (%ums).\n",
283 print_ssid(ssid, network->ssid, 293 print_ssid(ssid, network->ssid,
284 network->ssid_len), 294 network->ssid_len),
285 network->bssid, 295 network->bssid,
286 jiffies_to_msecs(jiffies - 296 elapsed_jiffies_msecs(
287 network-> 297 network->last_scanned));
288 last_scanned)); 298 }
289 } 299 }
290 300
291 spin_unlock_irqrestore(&ieee->lock, flags); 301 spin_unlock_irqrestore(&ieee->lock, flags);