Skip to content

Commit

Permalink
mac80211: fix idle handling sequence
Browse files Browse the repository at this point in the history
Corey Richardson reported that my idle handling cleanup
(commit fd0f979, "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>
  • Loading branch information
Johannes Berg committed Mar 25, 2013
1 parent 3fbd45c commit 382a103
Show file tree
Hide file tree
Showing 3 changed files with 16 additions and 4 deletions.
17 changes: 14 additions & 3 deletions net/mac80211/chan.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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);
Expand All @@ -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;
Expand Down
1 change: 1 addition & 0 deletions net/mac80211/ieee80211_i.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion net/mac80211/iface.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 382a103

Please sign in to comment.