[Jaunty] SRU: Wifi drivers fixes for age scan

Amit Kucheria amit.kucheria at canonical.com
Thu Apr 23 06:34:02 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)

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 <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
> 

> -- 
> kernel-team mailing list
> kernel-team at lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team


-- 
----------------------------------------------------------------------
Amit Kucheria, Kernel Engineer || amit at canonical.com
----------------------------------------------------------------------




More information about the kernel-team mailing list