On Tue, 2008-12-09 at 10:40 -0500, Bob Copeland wrote: > On Sun, 23 Nov 2008 10:19:13 +0100, Johannes Berg wrote > > I think this should run through interfaces twice, in the first run to > > remove keys, then remove stas and then in the second run remove the > > interfaces, because otherwise you may be having keys left when the sta > > for which the key was has been removed. > > Is this what you had in mind? (now on top of your cfg80211 patch, btw > it called ->suspend() in the resume hook) Can you adopt that patch too? > I tested this with ath5k, it works in the sense that device suspends and > resumes without any hangs or errors. > > However, netif_running(sdata->dev) seems to randomly be false for wlan0 on > the resume side so the interface doesn't always come up. I haven't had > time to track that down but it's not consistent. I think it's just a bug below? > +int __ieee80211_suspend(struct ieee80211_hw *hw) > +{ > + struct ieee80211_local *local = hw_to_local(hw); > + struct ieee80211_sub_if_data *sdata; > + struct ieee80211_if_init_conf conf; > + struct sta_info *sta; > + > + printk(KERN_DEBUG "mac80211: suspending\n"); > + > + flush_workqueue(local->hw.workqueue); > + > + /* disable keys */ > + list_for_each_entry(sdata, &local->interfaces, list) > + ieee80211_disable_keys(sdata); > + > + /* remove STAs */ > + list_for_each_entry(sta, &local->sta_list, list) { > + > + /* disable aggregation */ > + ieee80211_sta_tear_down_BA_sessions(sdata, sta->sta.addr); > + > + if (local->ops->sta_notify) { > + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN) > + sdata = container_of(sdata->bss, > + struct ieee80211_sub_if_data, > + u.ap); > + > + local->ops->sta_notify(hw, &sdata->vif, > + STA_NOTIFY_REMOVE, &sta->sta); > + } > + } That looks pretty good. > + /* remove all interfaces */ > + list_for_each_entry(sdata, &local->interfaces, list) { > + > + if (sdata->vif.type == NL80211_IFTYPE_AP_VLAN && > + sdata->vif.type == NL80211_IFTYPE_MONITOR && > + netif_running(sdata->dev)) { But shouldn't that be != _AP_VLAN && != _MONITOR && running? > + /* add interfaces */ > + list_for_each_entry(sdata, &local->interfaces, list) { > + > + if (sdata->vif.type != NL80211_IFTYPE_AP_VLAN && > + sdata->vif.type != NL80211_IFTYPE_MONITOR && > + netif_running(sdata->dev)) { Like here > diff --git a/net/mac80211/pm.h b/net/mac80211/pm.h > new file mode 100644 > index 0000000..3d5ff02 > --- /dev/null > +++ b/net/mac80211/pm.h > @@ -0,0 +1,9 @@ > +#ifndef __MAC80211_PM_H > +#define __MAC80211_PM_H > + > +#ifdef CONFIG_PM > +int __ieee80211_suspend(struct ieee80211_hw *hw); > +int __ieee80211_resume(struct ieee80211_hw *hw); > +#endif I'd just add those to ieee80211_i.h, and I don't think you really need to protect them with #ifdef CONFIG_PM johannes
Attachment:
signature.asc
Description: This is a digitally signed message part