Commit 2fa4cb90 authored by Stanislaw Gruszka's avatar Stanislaw Gruszka Committed by John W. Linville

ath9k_htc: make ->sta_rc_update atomic for most calls

sta_rc_update() callback must be atomic, hence we can not take mutexes
or do other operations, which can sleep in ath9k_htc_sta_rc_update().

I think we can just return from ath9k_htc_sta_rc_update(), if it is
called without IEEE80211_RC_SUPP_RATES_CHANGED bit. That will help
with scheduling while atomic bug for most cases (except mesh and IBSS
modes).

For mesh and IBSS I do not see other solution like creating additional
workqueue, because sending firmware command require us to sleep, but
this can be done in additional patch.

Patch partially fixes bug:
https://bugzilla.redhat.com/show_bug.cgi?id=990955

Cc: stable@vger.kernel.org
Signed-off-by: default avatarStanislaw Gruszka <sgruszka@redhat.com>
Signed-off-by: default avatarJohn W. Linville <linville@tuxdriver.com>
parent 235c0dc5
...@@ -1315,21 +1315,22 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw, ...@@ -1315,21 +1315,22 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
struct ath_common *common = ath9k_hw_common(priv->ah); struct ath_common *common = ath9k_hw_common(priv->ah);
struct ath9k_htc_target_rate trate; struct ath9k_htc_target_rate trate;
if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
return;
mutex_lock(&priv->mutex); mutex_lock(&priv->mutex);
ath9k_htc_ps_wakeup(priv); ath9k_htc_ps_wakeup(priv);
if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); ath9k_htc_setup_rate(priv, sta, &trate);
ath9k_htc_setup_rate(priv, sta, &trate); if (!ath9k_htc_send_rate_cmd(priv, &trate))
if (!ath9k_htc_send_rate_cmd(priv, &trate)) ath_dbg(common, CONFIG,
ath_dbg(common, CONFIG, "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
"Supported rates for sta: %pM updated, rate caps: 0x%X\n", sta->addr, be32_to_cpu(trate.capflags));
sta->addr, be32_to_cpu(trate.capflags)); else
else ath_dbg(common, CONFIG,
ath_dbg(common, CONFIG, "Unable to update supported rates for sta: %pM\n",
"Unable to update supported rates for sta: %pM\n", sta->addr);
sta->addr);
}
ath9k_htc_ps_restore(priv); ath9k_htc_ps_restore(priv);
mutex_unlock(&priv->mutex); mutex_unlock(&priv->mutex);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment