From 97af743207466ff8b477e14bfb7af0ba2c93375b Mon Sep 17 00:00:00 2001 From: Bob Copeland Date: Wed, 29 Jul 2009 10:13:03 +0200 Subject: mac80211: disable beacons before removing the associated interface When downing interfaces, it's a good idea to tell the driver to stop sending beacons; that way the driver doesn't need special code in ops->remove_interface() when it should already handle the case in bss_info_changed(). This fixes a potential crash with at least ath5k since the vif pointer will be nullified while beacon interrupts are still active. Signed-off-by: Bob Copeland Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- net/mac80211/pm.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'net/mac80211/pm.c') diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 5e3d476972f..3320f7daaf2 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -96,6 +96,10 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) if (!netif_running(sdata->dev)) continue; + /* disable beaconing */ + ieee80211_bss_info_change_notify(sdata, + BSS_CHANGED_BEACON_ENABLED); + conf.vif = &sdata->vif; conf.type = sdata->vif.type; conf.mac_addr = sdata->dev->dev_addr; -- cgit v1.2.3 From 42935ecaf4e784d0815afa9a7e5fe7e141157ca3 Mon Sep 17 00:00:00 2001 From: "Luis R. Rodriguez" Date: Wed, 29 Jul 2009 20:08:07 -0400 Subject: mac80211: redefine usage of the mac80211 workqueue The mac80211 workqueue exists to enable mac80211 and drivers to queue their own work on a single threaded workqueue. mac80211 takes care to flush the workqueue during suspend but we never really had requirements on drivers for how they should use the workqueue in consideration for suspend. We extend mac80211 to document how the mac80211 workqueue should be used, how it should not be used and finally move raw access to the workqueue to mac80211 only. Drivers and mac80211 use helpers to queue work onto the mac80211 workqueue: * ieee80211_queue_work() * ieee80211_queue_delayed_work() These helpers will now warn if mac80211 already completed its suspend cycle and someone is trying to queue work. mac80211 flushes the mac80211 workqueue prior to suspend a few times, but we haven't taken the care to ensure drivers won't add more work after suspend. To help with this we add a warning when someone tries to add work and mac80211 already completed the suspend cycle. Drivers should ensure they cancel any work or delayed work in the mac80211 stop() callback. Signed-off-by: Luis R. Rodriguez Signed-off-by: John W. Linville --- net/mac80211/pm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'net/mac80211/pm.c') diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index 3320f7daaf2..a5d2f1fb441 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -26,7 +26,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) /* make quiescing visible to timers everywhere */ mb(); - flush_workqueue(local->hw.workqueue); + flush_workqueue(local->workqueue); /* Don't try to run timers while suspended. */ del_timer_sync(&local->sta_cleanup); @@ -117,7 +117,7 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) * shouldn't be doing (or cancel everything in the * stop callback) that but better safe than sorry. */ - flush_workqueue(local->hw.workqueue); + flush_workqueue(local->workqueue); local->suspended = true; /* need suspended to be visible before quiescing is false */ -- cgit v1.2.3 From 84f6a01ce05fa671f7745b6e041e698a2d1f1341 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Thu, 20 Aug 2009 20:02:20 +0200 Subject: mac80211: fix configure_filter invocation after stop Since configure_filter can sleep now, any multicast configuration needed to be postponed to a work struct. This, however, lead to a problem that we could queue the work, stop the device and then afterwards invoke configure_filter which may lead to driver hangs and is a bug. To fix this, we can just cancel the filter work since it's unnecessary to do after stopping the hw. Since there are various places that call drv_stop, and two of them do very similar things, the code for them can be put into a shared function at the same time. Signed-off-by: Johannes Berg Reported-by: Lennert Buytenhek Tested-by: Lennert Buytenhek Signed-off-by: John W. Linville --- net/mac80211/pm.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) (limited to 'net/mac80211/pm.c') diff --git a/net/mac80211/pm.c b/net/mac80211/pm.c index a5d2f1fb441..e535f1c988f 100644 --- a/net/mac80211/pm.c +++ b/net/mac80211/pm.c @@ -107,17 +107,8 @@ int __ieee80211_suspend(struct ieee80211_hw *hw) } /* stop hardware - this must stop RX */ - if (local->open_count) { - ieee80211_led_radio(local, false); - drv_stop(local); - } - - /* - * flush again, in case driver queued work -- it - * shouldn't be doing (or cancel everything in the - * stop callback) that but better safe than sorry. - */ - flush_workqueue(local->workqueue); + if (local->open_count) + ieee80211_stop_device(local); local->suspended = true; /* need suspended to be visible before quiescing is false */ -- cgit v1.2.3