[Jaunty] SRU: Wifi drivers fixes for age scan

classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

[Jaunty] SRU: Wifi drivers fixes for age scan

Stefan Bader-2
https://bugs.launchpad.net/ubuntu/+source/linux/+bug/336055

SRU justification:

Impact: The houskeeping of the wireless stack does not account for the time
spent in suspend. So after resume it will think the AP's from the last scan are
still valid and tries to reconnect to the one connected to before suspended.

Fix: Account for the time spent in suspend when resuming. Patch taken from
https://bugzilla.redhat.com/attachment.cgi?id=333270 and tested by the
reported. (Had been withdrawn from pre-release inclusion as it changes the ABI)

Testcase: Connect to an access point, suspend, move away and resume.

--

When all other means of communication fail, try words!



From f795503c5966a69001dc79084ca63a1d2650fd7b Mon Sep 17 00:00:00 2001
From: Tim Gardner <[hidden email]>
Date: Wed, 8 Apr 2009 06:51:49 -0700
Subject: [PATCH] UBUNTU: SAUCE: (drop after 2.6.28) Wifi suspend/resume scan timeout fixes

OriginalAuthor: Dan Williams
OriginalLocation: https://bugzilla.redhat.com/attachment.cgi?id=333270
Bug: #336055
BumpABI: yes

ABI changes:
- 199 symbols changed hash and weren't ignored
- Module hash change summary...
    drivers/net/wireless/iwlwifi/iwlcore            : 101
    net/mac80211/mac80211                           :  39
    drivers/net/wireless/rt2x00/rt2x00lib           :  23
    drivers/net/wireless/rt2x00/rt2x00usb           :  11
    drivers/net/wireless/libertas_tf/libertas_tf    :   8
    net/wireless/cfg80211                           :   6
    drivers/net/wireless/p54/p54common              :   5
    drivers/net/wireless/rt2x00/rt2x00pci           :   4
    drivers/net/wireless/libertas_tf/libertas_tf_usb:   2

https://bugzilla.redhat.com/show_bug.cgi?id=466136

Signed-off-by: Tim Gardner <[hidden email]>
Acked-by: Stefan Bader <[hidden email]>
---
 include/net/cfg80211.h |    6 ++++++
 include/net/wireless.h |    3 +++
 net/mac80211/cfg.c     |   28 ++++++++++++++++++++++++++++
 net/mac80211/rx.c      |    1 +
 net/mac80211/scan.c    |   13 +++++++++++--
 net/mac80211/tx.c      |    1 +
 net/wireless/core.h    |    2 ++
 net/wireless/sysfs.c   |   35 +++++++++++++++++++++++++++++++++++
 8 files changed, 87 insertions(+), 2 deletions(-)

diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
index 0e85ec3..44fb3b9 100644
--- a/include/net/cfg80211.h
+++ b/include/net/cfg80211.h
@@ -363,6 +363,9 @@ struct wiphy;
  * wireless extensions but this is subject to reevaluation as soon as this
  * code is used more widely and we have a first user without wext.
  *
+ * @suspend: wiphy device needs to be suspended
+ * @resume: wiphy device needs to be resumed
+ *
  * @add_virtual_intf: create a new virtual interface with the given name,
  * must set the struct wireless_dev's iftype.
  *
@@ -402,6 +405,9 @@ struct wiphy;
  * @change_bss: Modify parameters for a given BSS.
  */
 struct cfg80211_ops {
+ int (*suspend)(struct wiphy *wiphy);
+ int (*resume)(struct wiphy *wiphy);
+
  int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
     enum nl80211_iftype type, u32 *flags,
     struct vif_params *params);
diff --git a/include/net/wireless.h b/include/net/wireless.h
index 721efb3..4c87939 100644
--- a/include/net/wireless.h
+++ b/include/net/wireless.h
@@ -212,6 +212,9 @@ struct wiphy {
  /* dir in debugfs: ieee80211/<wiphyname> */
  struct dentry *debugfsdir;
 
+ /* time spent in suspend, in seconds */
+ unsigned long suspend_duration;
+
  char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
 };
 
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 855126a..33d931f 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -991,6 +991,32 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
  return 0;
 }
 
+#ifdef CONFIG_PM
+static int ieee80211_suspend(struct wiphy *wiphy)
+{
+ return 0;
+}
+
+static int ieee80211_resume(struct wiphy *wiphy)
+{
+ struct ieee80211_local *local = wiphy_priv(wiphy);
+ unsigned long age_jiffies;
+ struct ieee80211_bss *bss;
+
+ age_jiffies = msecs_to_jiffies(wiphy->suspend_duration * MSEC_PER_SEC);
+ spin_lock_bh(&local->bss_lock);
+ list_for_each_entry(bss, &local->bss_list, list) {
+ bss->last_update -= age_jiffies;
+ }
+ spin_unlock_bh(&local->bss_lock);
+
+ return 0;
+}
+#else
+#define ieee80211_suspend NULL
+#define ieee80211_resume NULL
+#endif
+
 struct cfg80211_ops mac80211_config_ops = {
  .add_virtual_intf = ieee80211_add_iface,
  .del_virtual_intf = ieee80211_del_iface,
@@ -1015,4 +1041,6 @@ struct cfg80211_ops mac80211_config_ops = {
  .dump_mpath = ieee80211_dump_mpath,
 #endif
  .change_bss = ieee80211_change_bss,
+ .suspend = ieee80211_suspend,
+ .resume = ieee80211_resume,
 };
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index cf6b121..2d7dfad 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1,3 +1,4 @@
+#define ETH_P_PAE 0x888E
 /*
  * Copyright 2002-2005, Instant802 Networks, Inc.
  * Copyright 2005-2006, Devicescape Software, Inc.
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 416bb41..8164740 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -749,6 +749,15 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
  }
 }
 
+static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
+{
+ unsigned long end = jiffies;
+
+ if (end >= start)
+ return jiffies_to_msecs(end - start);
+
+ return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
+}
 
 static char *
 ieee80211_scan_result(struct ieee80211_local *local,
@@ -861,8 +870,8 @@ ieee80211_scan_result(struct ieee80211_local *local,
   &iwe, buf);
  memset(&iwe, 0, sizeof(iwe));
  iwe.cmd = IWEVCUSTOM;
- sprintf(buf, " Last beacon: %dms ago",
- jiffies_to_msecs(jiffies - bss->last_update));
+ sprintf(buf, " Last beacon: %ums ago",
+ elapsed_jiffies_msecs(bss->last_update));
  iwe.u.data.length = strlen(buf);
  current_ev = iwe_stream_add_point(info, current_ev,
   end_buf, &iwe, buf);
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
index e24ae1b..67b2dc5 100644
--- a/net/mac80211/tx.c
+++ b/net/mac80211/tx.c
@@ -1,3 +1,4 @@
+#define ETH_P_PAE 0x888E
 /*
  * Copyright 2002-2005, Instant802 Networks, Inc.
  * Copyright 2005-2006, Devicescape Software, Inc.
diff --git a/net/wireless/core.h b/net/wireless/core.h
index 771cc5c..ff01ec3 100644
--- a/net/wireless/core.h
+++ b/net/wireless/core.h
@@ -28,6 +28,8 @@ struct cfg80211_registered_device {
  struct mutex devlist_mtx;
  struct list_head netdev_list;
 
+ unsigned long suspend_at;
+
  /* must be last because of the way we do wiphy_priv(),
  * and it should at least be aligned to NETDEV_ALIGN */
  struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
index 29f820e..cc9e9e4 100644
--- a/net/wireless/sysfs.c
+++ b/net/wireless/sysfs.c
@@ -60,6 +60,39 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
 }
 #endif
 
+static int wiphy_suspend(struct device *dev, pm_message_t state)
+{
+ struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
+ int ret = 0;
+
+ rdev->wiphy.suspend_duration = 0;
+ rdev->suspend_at = get_seconds();
+
+ if (rdev->ops->suspend) {
+ rtnl_lock();
+ ret = rdev->ops->suspend(&rdev->wiphy);
+ rtnl_unlock();
+ }
+
+ return ret;
+}
+
+static int wiphy_resume(struct device *dev)
+{
+ struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
+ int ret = 0;
+
+ rdev->wiphy.suspend_duration = get_seconds() - rdev->suspend_at;
+
+ if (rdev->ops->resume) {
+ rtnl_lock();
+ ret = rdev->ops->resume(&rdev->wiphy);
+ rtnl_unlock();
+ }
+
+ return ret;
+}
+
 struct class ieee80211_class = {
  .name = "ieee80211",
  .owner = THIS_MODULE,
@@ -68,6 +101,8 @@ struct class ieee80211_class = {
 #ifdef CONFIG_HOTPLUG
  .dev_uevent = wiphy_uevent,
 #endif
+ .suspend = wiphy_suspend,
+ .resume = wiphy_resume,
 };
 
 int wiphy_sysfs_init(void)
--
1.5.4.3


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [Jaunty] SRU: Wifi drivers fixes for age scan

Amit Kucheria-6
On Wed, Apr 22, 2009 at 10:38:49PM +0200, Stefan Bader wrote:

> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/336055
>
> SRU justification:
>
> Impact: The houskeeping of the wireless stack does not account for the
> time spent in suspend. So after resume it will think the AP's from the
> last scan are still valid and tries to reconnect to the one connected to
> before suspended.
>
> Fix: Account for the time spent in suspend when resuming. Patch taken
> from https://bugzilla.redhat.com/attachment.cgi?id=333270 and tested by
> the reported. (Had been withdrawn from pre-release inclusion as it
> changes the ABI)

So what is the changed behaviour?

Does it reinitiate a scan? I am guessing when bss->last_update falls below 0, that AP is 'dropped' from the list?
Will this fix NM stupidly trying to connect to my AP at home when I am in the coffee shop?

> Testcase: Connect to an access point, suspend, move away and resume.
>
> --
>
> When all other means of communication fail, try words!
>
>

> From f795503c5966a69001dc79084ca63a1d2650fd7b Mon Sep 17 00:00:00 2001
> From: Tim Gardner <[hidden email]>
> Date: Wed, 8 Apr 2009 06:51:49 -0700
> Subject: [PATCH] UBUNTU: SAUCE: (drop after 2.6.28) Wifi suspend/resume scan timeout fixes
>
> OriginalAuthor: Dan Williams
> OriginalLocation: https://bugzilla.redhat.com/attachment.cgi?id=333270
> Bug: #336055
> BumpABI: yes
>
> ABI changes:
> - 199 symbols changed hash and weren't ignored
> - Module hash change summary...
>     drivers/net/wireless/iwlwifi/iwlcore            : 101
>     net/mac80211/mac80211                           :  39
>     drivers/net/wireless/rt2x00/rt2x00lib           :  23
>     drivers/net/wireless/rt2x00/rt2x00usb           :  11
>     drivers/net/wireless/libertas_tf/libertas_tf    :   8
>     net/wireless/cfg80211                           :   6
>     drivers/net/wireless/p54/p54common              :   5
>     drivers/net/wireless/rt2x00/rt2x00pci           :   4
>     drivers/net/wireless/libertas_tf/libertas_tf_usb:   2
>
> https://bugzilla.redhat.com/show_bug.cgi?id=466136
>
> Signed-off-by: Tim Gardner <[hidden email]>
> Acked-by: Stefan Bader <[hidden email]>
> ---
>  include/net/cfg80211.h |    6 ++++++
>  include/net/wireless.h |    3 +++
>  net/mac80211/cfg.c     |   28 ++++++++++++++++++++++++++++
>  net/mac80211/rx.c      |    1 +
>  net/mac80211/scan.c    |   13 +++++++++++--
>  net/mac80211/tx.c      |    1 +
>  net/wireless/core.h    |    2 ++
>  net/wireless/sysfs.c   |   35 +++++++++++++++++++++++++++++++++++
>  8 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 0e85ec3..44fb3b9 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -363,6 +363,9 @@ struct wiphy;
>   * wireless extensions but this is subject to reevaluation as soon as this
>   * code is used more widely and we have a first user without wext.
>   *
> + * @suspend: wiphy device needs to be suspended
> + * @resume: wiphy device needs to be resumed
> + *
>   * @add_virtual_intf: create a new virtual interface with the given name,
>   * must set the struct wireless_dev's iftype.
>   *
> @@ -402,6 +405,9 @@ struct wiphy;
>   * @change_bss: Modify parameters for a given BSS.
>   */
>  struct cfg80211_ops {
> + int (*suspend)(struct wiphy *wiphy);
> + int (*resume)(struct wiphy *wiphy);
> +
>   int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
>      enum nl80211_iftype type, u32 *flags,
>      struct vif_params *params);
> diff --git a/include/net/wireless.h b/include/net/wireless.h
> index 721efb3..4c87939 100644
> --- a/include/net/wireless.h
> +++ b/include/net/wireless.h
> @@ -212,6 +212,9 @@ struct wiphy {
>   /* dir in debugfs: ieee80211/<wiphyname> */
>   struct dentry *debugfsdir;
>  
> + /* time spent in suspend, in seconds */
> + unsigned long suspend_duration;
> +
>   char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
>  };
>  
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 855126a..33d931f 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -991,6 +991,32 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
>   return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int ieee80211_suspend(struct wiphy *wiphy)
> +{
> + return 0;
> +}
> +
> +static int ieee80211_resume(struct wiphy *wiphy)
> +{
> + struct ieee80211_local *local = wiphy_priv(wiphy);
> + unsigned long age_jiffies;
> + struct ieee80211_bss *bss;
> +
> + age_jiffies = msecs_to_jiffies(wiphy->suspend_duration * MSEC_PER_SEC);
> + spin_lock_bh(&local->bss_lock);
> + list_for_each_entry(bss, &local->bss_list, list) {
> + bss->last_update -= age_jiffies;
> + }
> + spin_unlock_bh(&local->bss_lock);
> +
> + return 0;
> +}
> +#else
> +#define ieee80211_suspend NULL
> +#define ieee80211_resume NULL
> +#endif
> +
>  struct cfg80211_ops mac80211_config_ops = {
>   .add_virtual_intf = ieee80211_add_iface,
>   .del_virtual_intf = ieee80211_del_iface,
> @@ -1015,4 +1041,6 @@ struct cfg80211_ops mac80211_config_ops = {
>   .dump_mpath = ieee80211_dump_mpath,
>  #endif
>   .change_bss = ieee80211_change_bss,
> + .suspend = ieee80211_suspend,
> + .resume = ieee80211_resume,
>  };
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index cf6b121..2d7dfad 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1,3 +1,4 @@
> +#define ETH_P_PAE 0x888E
>  /*
>   * Copyright 2002-2005, Instant802 Networks, Inc.
>   * Copyright 2005-2006, Devicescape Software, Inc.
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index 416bb41..8164740 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -749,6 +749,15 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
>   }
>  }
>  
> +static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
> +{
> + unsigned long end = jiffies;
> +
> + if (end >= start)
> + return jiffies_to_msecs(end - start);
> +
> + return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
> +}
>  
>  static char *
>  ieee80211_scan_result(struct ieee80211_local *local,
> @@ -861,8 +870,8 @@ ieee80211_scan_result(struct ieee80211_local *local,
>    &iwe, buf);
>   memset(&iwe, 0, sizeof(iwe));
>   iwe.cmd = IWEVCUSTOM;
> - sprintf(buf, " Last beacon: %dms ago",
> - jiffies_to_msecs(jiffies - bss->last_update));
> + sprintf(buf, " Last beacon: %ums ago",
> + elapsed_jiffies_msecs(bss->last_update));
>   iwe.u.data.length = strlen(buf);
>   current_ev = iwe_stream_add_point(info, current_ev,
>    end_buf, &iwe, buf);
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index e24ae1b..67b2dc5 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -1,3 +1,4 @@
> +#define ETH_P_PAE 0x888E
>  /*
>   * Copyright 2002-2005, Instant802 Networks, Inc.
>   * Copyright 2005-2006, Devicescape Software, Inc.
> diff --git a/net/wireless/core.h b/net/wireless/core.h
> index 771cc5c..ff01ec3 100644
> --- a/net/wireless/core.h
> +++ b/net/wireless/core.h
> @@ -28,6 +28,8 @@ struct cfg80211_registered_device {
>   struct mutex devlist_mtx;
>   struct list_head netdev_list;
>  
> + unsigned long suspend_at;
> +
>   /* must be last because of the way we do wiphy_priv(),
>   * and it should at least be aligned to NETDEV_ALIGN */
>   struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
> diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
> index 29f820e..cc9e9e4 100644
> --- a/net/wireless/sysfs.c
> +++ b/net/wireless/sysfs.c
> @@ -60,6 +60,39 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
>  }
>  #endif
>  
> +static int wiphy_suspend(struct device *dev, pm_message_t state)
> +{
> + struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
> + int ret = 0;
> +
> + rdev->wiphy.suspend_duration = 0;
> + rdev->suspend_at = get_seconds();
> +
> + if (rdev->ops->suspend) {
> + rtnl_lock();
> + ret = rdev->ops->suspend(&rdev->wiphy);
> + rtnl_unlock();
> + }
> +
> + return ret;
> +}
> +
> +static int wiphy_resume(struct device *dev)
> +{
> + struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
> + int ret = 0;
> +
> + rdev->wiphy.suspend_duration = get_seconds() - rdev->suspend_at;
> +
> + if (rdev->ops->resume) {
> + rtnl_lock();
> + ret = rdev->ops->resume(&rdev->wiphy);
> + rtnl_unlock();
> + }
> +
> + return ret;
> +}
> +
>  struct class ieee80211_class = {
>   .name = "ieee80211",
>   .owner = THIS_MODULE,
> @@ -68,6 +101,8 @@ struct class ieee80211_class = {
>  #ifdef CONFIG_HOTPLUG
>   .dev_uevent = wiphy_uevent,
>  #endif
> + .suspend = wiphy_suspend,
> + .resume = wiphy_resume,
>  };
>  
>  int wiphy_sysfs_init(void)
> --
> 1.5.4.3
>

> --
> kernel-team mailing list
> [hidden email]
> https://lists.ubuntu.com/mailman/listinfo/kernel-team


--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || [hidden email]
----------------------------------------------------------------------

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [Jaunty] SRU: Wifi drivers fixes for age scan

Stefan Bader-2
Amit Kucheria wrote:

> On Wed, Apr 22, 2009 at 10:38:49PM +0200, Stefan Bader wrote:
>> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/336055
>>
>> SRU justification:
>>
>> Impact: The houskeeping of the wireless stack does not account for the
>> time spent in suspend. So after resume it will think the AP's from the
>> last scan are still valid and tries to reconnect to the one connected to
>> before suspended.
>>
>> Fix: Account for the time spent in suspend when resuming. Patch taken
>> from https://bugzilla.redhat.com/attachment.cgi?id=333270 and tested by
>> the reported. (Had been withdrawn from pre-release inclusion as it
>> changes the ABI)
>
> So what is the changed behaviour?
>
> Does it reinitiate a scan? I am guessing when bss->last_update falls below 0, that AP is 'dropped' from the list?

As it accounts for the time suspended it will know the last scan was ages ago.

> Will this fix NM stupidly trying to connect to my AP at home when I am in the coffee shop?

That is the intention. :)




--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [Jaunty] SRU: Wifi drivers fixes for age scan

Stefan Bader-2
In reply to this post by Amit Kucheria-6
But Tim might be more competent to comment.

--

When all other means of communication fail, try words!



--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [Jaunty] SRU: Wifi drivers fixes for age scan

Amit Kucheria-6
In reply to this post by Stefan Bader-2
On Wed, Apr 22, 2009 at 10:38:49PM +0200, Stefan Bader wrote:

> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/336055
>
> SRU justification:
>
> Impact: The houskeeping of the wireless stack does not account for the
> time spent in suspend. So after resume it will think the AP's from the
> last scan are still valid and tries to reconnect to the one connected to
> before suspended.
>
> Fix: Account for the time spent in suspend when resuming. Patch taken
> from https://bugzilla.redhat.com/attachment.cgi?id=333270 and tested by
> the reported. (Had been withdrawn from pre-release inclusion as it
> changes the ABI)
>
> Testcase: Connect to an access point, suspend, move away and resume.
>
> --
>
> When all other means of communication fail, try words!
>
>

> From f795503c5966a69001dc79084ca63a1d2650fd7b Mon Sep 17 00:00:00 2001
> From: Tim Gardner <[hidden email]>
> Date: Wed, 8 Apr 2009 06:51:49 -0700
> Subject: [PATCH] UBUNTU: SAUCE: (drop after 2.6.28) Wifi suspend/resume scan timeout fixes
>
> OriginalAuthor: Dan Williams
> OriginalLocation: https://bugzilla.redhat.com/attachment.cgi?id=333270
> Bug: #336055
> BumpABI: yes
>
> ABI changes:
> - 199 symbols changed hash and weren't ignored
> - Module hash change summary...
>     drivers/net/wireless/iwlwifi/iwlcore            : 101
>     net/mac80211/mac80211                           :  39
>     drivers/net/wireless/rt2x00/rt2x00lib           :  23
>     drivers/net/wireless/rt2x00/rt2x00usb           :  11
>     drivers/net/wireless/libertas_tf/libertas_tf    :   8
>     net/wireless/cfg80211                           :   6
>     drivers/net/wireless/p54/p54common              :   5
>     drivers/net/wireless/rt2x00/rt2x00pci           :   4
>     drivers/net/wireless/libertas_tf/libertas_tf_usb:   2
>
> https://bugzilla.redhat.com/show_bug.cgi?id=466136
>
> Signed-off-by: Tim Gardner <[hidden email]>
> Acked-by: Stefan Bader <[hidden email]>
> ---
>  include/net/cfg80211.h |    6 ++++++
>  include/net/wireless.h |    3 +++
>  net/mac80211/cfg.c     |   28 ++++++++++++++++++++++++++++
>  net/mac80211/rx.c      |    1 +
>  net/mac80211/scan.c    |   13 +++++++++++--
>  net/mac80211/tx.c      |    1 +
>  net/wireless/core.h    |    2 ++
>  net/wireless/sysfs.c   |   35 +++++++++++++++++++++++++++++++++++
>  8 files changed, 87 insertions(+), 2 deletions(-)
>
> diff --git a/include/net/cfg80211.h b/include/net/cfg80211.h
> index 0e85ec3..44fb3b9 100644
> --- a/include/net/cfg80211.h
> +++ b/include/net/cfg80211.h
> @@ -363,6 +363,9 @@ struct wiphy;
>   * wireless extensions but this is subject to reevaluation as soon as this
>   * code is used more widely and we have a first user without wext.
>   *
> + * @suspend: wiphy device needs to be suspended
> + * @resume: wiphy device needs to be resumed
> + *
>   * @add_virtual_intf: create a new virtual interface with the given name,
>   * must set the struct wireless_dev's iftype.
>   *
> @@ -402,6 +405,9 @@ struct wiphy;
>   * @change_bss: Modify parameters for a given BSS.
>   */
>  struct cfg80211_ops {
> + int (*suspend)(struct wiphy *wiphy);
> + int (*resume)(struct wiphy *wiphy);
> +
>   int (*add_virtual_intf)(struct wiphy *wiphy, char *name,
>      enum nl80211_iftype type, u32 *flags,
>      struct vif_params *params);
> diff --git a/include/net/wireless.h b/include/net/wireless.h
> index 721efb3..4c87939 100644
> --- a/include/net/wireless.h
> +++ b/include/net/wireless.h
> @@ -212,6 +212,9 @@ struct wiphy {
>   /* dir in debugfs: ieee80211/<wiphyname> */
>   struct dentry *debugfsdir;
>  
> + /* time spent in suspend, in seconds */
> + unsigned long suspend_duration;
> +
>   char priv[0] __attribute__((__aligned__(NETDEV_ALIGN)));
>  };
>  
> diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
> index 855126a..33d931f 100644
> --- a/net/mac80211/cfg.c
> +++ b/net/mac80211/cfg.c
> @@ -991,6 +991,32 @@ static int ieee80211_change_bss(struct wiphy *wiphy,
>   return 0;
>  }
>  
> +#ifdef CONFIG_PM
> +static int ieee80211_suspend(struct wiphy *wiphy)
> +{
> + return 0;
> +}
> +
> +static int ieee80211_resume(struct wiphy *wiphy)
> +{
> + struct ieee80211_local *local = wiphy_priv(wiphy);
> + unsigned long age_jiffies;
> + struct ieee80211_bss *bss;
> +
> + age_jiffies = msecs_to_jiffies(wiphy->suspend_duration * MSEC_PER_SEC);
> + spin_lock_bh(&local->bss_lock);
> + list_for_each_entry(bss, &local->bss_list, list) {
> + bss->last_update -= age_jiffies;
> + }
> + spin_unlock_bh(&local->bss_lock);
> +
> + return 0;
> +}
> +#else
> +#define ieee80211_suspend NULL
> +#define ieee80211_resume NULL
> +#endif
> +
>  struct cfg80211_ops mac80211_config_ops = {
>   .add_virtual_intf = ieee80211_add_iface,
>   .del_virtual_intf = ieee80211_del_iface,
> @@ -1015,4 +1041,6 @@ struct cfg80211_ops mac80211_config_ops = {
>   .dump_mpath = ieee80211_dump_mpath,
>  #endif
>   .change_bss = ieee80211_change_bss,
> + .suspend = ieee80211_suspend,
> + .resume = ieee80211_resume,
>  };
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index cf6b121..2d7dfad 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1,3 +1,4 @@
> +#define ETH_P_PAE 0x888E
>  /*
>   * Copyright 2002-2005, Instant802 Networks, Inc.
>   * Copyright 2005-2006, Devicescape Software, Inc.
> diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
> index 416bb41..8164740 100644
> --- a/net/mac80211/scan.c
> +++ b/net/mac80211/scan.c
> @@ -749,6 +749,15 @@ static void ieee80211_scan_add_ies(struct iw_request_info *info,
>   }
>  }
>  
> +static inline unsigned int elapsed_jiffies_msecs(unsigned long start)
> +{
> + unsigned long end = jiffies;
> +
> + if (end >= start)
> + return jiffies_to_msecs(end - start);
> +
> + return jiffies_to_msecs(end + (MAX_JIFFY_OFFSET - start) + 1);
> +}
>  
>  static char *
>  ieee80211_scan_result(struct ieee80211_local *local,
> @@ -861,8 +870,8 @@ ieee80211_scan_result(struct ieee80211_local *local,
>    &iwe, buf);
>   memset(&iwe, 0, sizeof(iwe));
>   iwe.cmd = IWEVCUSTOM;
> - sprintf(buf, " Last beacon: %dms ago",
> - jiffies_to_msecs(jiffies - bss->last_update));
> + sprintf(buf, " Last beacon: %ums ago",
> + elapsed_jiffies_msecs(bss->last_update));
>   iwe.u.data.length = strlen(buf);
>   current_ev = iwe_stream_add_point(info, current_ev,
>    end_buf, &iwe, buf);
> diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
> index e24ae1b..67b2dc5 100644
> --- a/net/mac80211/tx.c
> +++ b/net/mac80211/tx.c
> @@ -1,3 +1,4 @@
> +#define ETH_P_PAE 0x888E
>  /*
>   * Copyright 2002-2005, Instant802 Networks, Inc.
>   * Copyright 2005-2006, Devicescape Software, Inc.
> diff --git a/net/wireless/core.h b/net/wireless/core.h
> index 771cc5c..ff01ec3 100644
> --- a/net/wireless/core.h
> +++ b/net/wireless/core.h
> @@ -28,6 +28,8 @@ struct cfg80211_registered_device {
>   struct mutex devlist_mtx;
>   struct list_head netdev_list;
>  
> + unsigned long suspend_at;
> +
>   /* must be last because of the way we do wiphy_priv(),
>   * and it should at least be aligned to NETDEV_ALIGN */
>   struct wiphy wiphy __attribute__((__aligned__(NETDEV_ALIGN)));
> diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c
> index 29f820e..cc9e9e4 100644
> --- a/net/wireless/sysfs.c
> +++ b/net/wireless/sysfs.c
> @@ -60,6 +60,39 @@ static int wiphy_uevent(struct device *dev, struct kobj_uevent_env *env)
>  }
>  #endif
>  
> +static int wiphy_suspend(struct device *dev, pm_message_t state)
> +{
> + struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
> + int ret = 0;
> +
> + rdev->wiphy.suspend_duration = 0;
> + rdev->suspend_at = get_seconds();
> +
> + if (rdev->ops->suspend) {
> + rtnl_lock();
> + ret = rdev->ops->suspend(&rdev->wiphy);
> + rtnl_unlock();
> + }
> +
> + return ret;
> +}
> +
> +static int wiphy_resume(struct device *dev)
> +{
> + struct cfg80211_registered_device *rdev = dev_to_rdev(dev);
> + int ret = 0;
> +
> + rdev->wiphy.suspend_duration = get_seconds() - rdev->suspend_at;
> +
> + if (rdev->ops->resume) {
> + rtnl_lock();
> + ret = rdev->ops->resume(&rdev->wiphy);
> + rtnl_unlock();
> + }
> +
> + return ret;
> +}
> +
>  struct class ieee80211_class = {
>   .name = "ieee80211",
>   .owner = THIS_MODULE,
> @@ -68,6 +101,8 @@ struct class ieee80211_class = {
>  #ifdef CONFIG_HOTPLUG
>   .dev_uevent = wiphy_uevent,
>  #endif
> + .suspend = wiphy_suspend,
> + .resume = wiphy_resume,
>  };
>  
>  int wiphy_sysfs_init(void)
> --
> 1.5.4.3
>

ACK

--
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || [hidden email]
----------------------------------------------------------------------

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

Re: [Jaunty] SRU: Wifi drivers fixes for age scan

Tim Gardner-2
In reply to this post by Amit Kucheria-6
Amit Kucheria wrote:

> On Wed, Apr 22, 2009 at 10:38:49PM +0200, Stefan Bader wrote:
>> https://bugs.launchpad.net/ubuntu/+source/linux/+bug/336055
>>
>> SRU justification:
>>
>> Impact: The houskeeping of the wireless stack does not account for the
>> time spent in suspend. So after resume it will think the AP's from the
>> last scan are still valid and tries to reconnect to the one connected to
>> before suspended.
>>
>> Fix: Account for the time spent in suspend when resuming. Patch taken
>> from https://bugzilla.redhat.com/attachment.cgi?id=333270 and tested by
>> the reported. (Had been withdrawn from pre-release inclusion as it
>> changes the ABI)
>
> So what is the changed behaviour?
>
> Does it reinitiate a scan? I am guessing when bss->last_update falls below 0, that AP is 'dropped' from the list?
> Will this fix NM stupidly trying to connect to my AP at home when I am in the coffee shop?
>

That is precisely the case this patch is intended to fix.

--
Tim Gardner [hidden email]

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team