* [PATCH 3.9] mac80211: fix idle handling sequence
@ 2013-03-22 21:34 Johannes Berg
0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2013-03-22 21:34 UTC (permalink / raw)
To: linux-wireless; +Cc: Corey Richardson, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Corey Richardson reported that my idle handling cleanup
(commit fd0f979a1b, "mac80211: simplify idle handling")
broke ath9k_htc. The reason appears to be that it wants
to go out of idle before switching channels. To fix it,
reimplement that sequence.
Reported-by: Corey Richardson <corey@octayn.net>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
Sorry for the delay. Could you also test this patch? I'm pretty
certain it should still fix it, but if you can I'd like to know
for sure as I now coalesce IDLE + CHANNEL changes.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/chan.c | 19 +++++++++++++++----
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/iface.c | 2 +-
3 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 78c0d90..74acd81 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
enum ieee80211_chanctx_mode mode)
{
struct ieee80211_chanctx *ctx;
+ u32 changed;
int err;
lockdep_assert_held(&local->chanctx_mtx);
@@ -76,23 +77,33 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
ctx->conf.rx_chains_dynamic = 1;
ctx->mode = mode;
+ /* acquire mutex to prevent idle from changing */
+ mutex_lock(&local->mtx);
+ /* turn idle off *before* setting channel -- some drivers need that */
+ changed = ieee80211_idle_off(local);
+
if (!local->use_chanctx) {
local->_oper_channel_type =
cfg80211_get_chandef_type(chandef);
local->_oper_channel = chandef->chan;
- ieee80211_hw_config(local, 0);
+ ieee80211_hw_config(local, changed);
} else {
+ if (changed)
+ ieee80211_hw_config(local, changed);
err = drv_add_chanctx(local, ctx);
if (err) {
kfree(ctx);
- return ERR_PTR(err);
+ ctx = ERR_PTR(err);
+
+ ieee80211_recalc_idle(local);
+ goto out;
}
}
+ /* and keep the mutex held until the new chanctx is on the list */
list_add_rcu(&ctx->list, &local->chanctx_list);
- mutex_lock(&local->mtx);
- ieee80211_recalc_idle(local);
+ out:
mutex_unlock(&local->mtx);
return ctx;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 388580a..3e2314e 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1361,6 +1361,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type);
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
+u32 ieee80211_idle_off(struct ieee80211_local *local);
void ieee80211_recalc_idle(struct ieee80211_local *local);
void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
const int offset);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 3bfe261..58150f8 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
}
-static u32 ieee80211_idle_off(struct ieee80211_local *local)
+u32 ieee80211_idle_off(struct ieee80211_local *local)
{
if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
return 0;
--
1.8.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
* [PATCH 3.9] mac80211: fix idle handling sequence
@ 2013-03-25 15:50 Johannes Berg
0 siblings, 0 replies; 2+ messages in thread
From: Johannes Berg @ 2013-03-25 15:50 UTC (permalink / raw)
To: linux-wireless; +Cc: Corey Richardson, Jonas Gorski, Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Corey Richardson reported that my idle handling cleanup
(commit fd0f979a1b, "mac80211: simplify idle handling")
broke ath9k_htc. The reason appears to be that it wants
to go out of idle before switching channels. To fix it,
reimplement that sequence.
Reported-by: Corey Richardson <corey@octayn.net>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
net/mac80211/chan.c | 17 ++++++++++++++---
net/mac80211/ieee80211_i.h | 1 +
net/mac80211/iface.c | 2 +-
3 files changed, 16 insertions(+), 4 deletions(-)
diff --git a/net/mac80211/chan.c b/net/mac80211/chan.c
index 78c0d90..931be41 100644
--- a/net/mac80211/chan.c
+++ b/net/mac80211/chan.c
@@ -63,6 +63,7 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
enum ieee80211_chanctx_mode mode)
{
struct ieee80211_chanctx *ctx;
+ u32 changed;
int err;
lockdep_assert_held(&local->chanctx_mtx);
@@ -76,6 +77,13 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
ctx->conf.rx_chains_dynamic = 1;
ctx->mode = mode;
+ /* acquire mutex to prevent idle from changing */
+ mutex_lock(&local->mtx);
+ /* turn idle off *before* setting channel -- some drivers need that */
+ changed = ieee80211_idle_off(local);
+ if (changed)
+ ieee80211_hw_config(local, changed);
+
if (!local->use_chanctx) {
local->_oper_channel_type =
cfg80211_get_chandef_type(chandef);
@@ -85,14 +93,17 @@ ieee80211_new_chanctx(struct ieee80211_local *local,
err = drv_add_chanctx(local, ctx);
if (err) {
kfree(ctx);
- return ERR_PTR(err);
+ ctx = ERR_PTR(err);
+
+ ieee80211_recalc_idle(local);
+ goto out;
}
}
+ /* and keep the mutex held until the new chanctx is on the list */
list_add_rcu(&ctx->list, &local->chanctx_list);
- mutex_lock(&local->mtx);
- ieee80211_recalc_idle(local);
+ out:
mutex_unlock(&local->mtx);
return ctx;
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 7bdefd9..5672533 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1362,6 +1362,7 @@ int ieee80211_if_change_type(struct ieee80211_sub_if_data *sdata,
enum nl80211_iftype type);
void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata);
void ieee80211_remove_interfaces(struct ieee80211_local *local);
+u32 ieee80211_idle_off(struct ieee80211_local *local);
void ieee80211_recalc_idle(struct ieee80211_local *local);
void ieee80211_adjust_monitor_flags(struct ieee80211_sub_if_data *sdata,
const int offset);
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index 3bfe261..58150f8 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -78,7 +78,7 @@ void ieee80211_recalc_txpower(struct ieee80211_sub_if_data *sdata)
ieee80211_bss_info_change_notify(sdata, BSS_CHANGED_TXPOWER);
}
-static u32 ieee80211_idle_off(struct ieee80211_local *local)
+u32 ieee80211_idle_off(struct ieee80211_local *local)
{
if (!(local->hw.conf.flags & IEEE80211_CONF_IDLE))
return 0;
--
1.8.0
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2013-03-25 15:50 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-03-22 21:34 [PATCH 3.9] mac80211: fix idle handling sequence Johannes Berg
2013-03-25 15:50 Johannes Berg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).