[Jaunty] SRU: Wifi drivers fixes for age scan
Amit Kucheria
amit.kucheria at canonical.com
Thu Apr 23 07:19:01 UTC 2009
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 <tim.gardner at canonical.com>
> 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 <tim.gardner at canonical.com>
> Acked-by: Stefan Bader <stefan.bader at canonical.com>
> ---
> 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 || amit at canonical.com
----------------------------------------------------------------------
More information about the kernel-team
mailing list