aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ath/ath9k
diff options
context:
space:
mode:
authorStanislaw Gruszka <sgruszka@redhat.com>2014-01-28 03:14:48 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-02-04 15:30:06 -0500
commit2fa4cb905605c863bf570027233af7afd8149ae4 (patch)
treed2891782e2e56d8a19474e8ea0c6334b16786b25 /drivers/net/wireless/ath/ath9k
parent235c0dc55aa52157bbaf2917e0a4bd8ae965c43a (diff)
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: Stanislaw Gruszka <sgruszka@redhat.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath9k')
-rw-r--r--drivers/net/wireless/ath/ath9k/htc_drv_main.c25
1 files changed, 13 insertions, 12 deletions
diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_main.c b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
index 608d739d1378..a57af9b96a39 100644
--- a/drivers/net/wireless/ath/ath9k/htc_drv_main.c
+++ b/drivers/net/wireless/ath/ath9k/htc_drv_main.c
@@ -1315,21 +1315,22 @@ static void ath9k_htc_sta_rc_update(struct ieee80211_hw *hw,
1315 struct ath_common *common = ath9k_hw_common(priv->ah); 1315 struct ath_common *common = ath9k_hw_common(priv->ah);
1316 struct ath9k_htc_target_rate trate; 1316 struct ath9k_htc_target_rate trate;
1317 1317
1318 if (!(changed & IEEE80211_RC_SUPP_RATES_CHANGED))
1319 return;
1320
1318 mutex_lock(&priv->mutex); 1321 mutex_lock(&priv->mutex);
1319 ath9k_htc_ps_wakeup(priv); 1322 ath9k_htc_ps_wakeup(priv);
1320 1323
1321 if (changed & IEEE80211_RC_SUPP_RATES_CHANGED) { 1324 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate));
1322 memset(&trate, 0, sizeof(struct ath9k_htc_target_rate)); 1325 ath9k_htc_setup_rate(priv, sta, &trate);
1323 ath9k_htc_setup_rate(priv, sta, &trate); 1326 if (!ath9k_htc_send_rate_cmd(priv, &trate))
1324 if (!ath9k_htc_send_rate_cmd(priv, &trate)) 1327 ath_dbg(common, CONFIG,
1325 ath_dbg(common, CONFIG, 1328 "Supported rates for sta: %pM updated, rate caps: 0x%X\n",
1326 "Supported rates for sta: %pM updated, rate caps: 0x%X\n", 1329 sta->addr, be32_to_cpu(trate.capflags));
1327 sta->addr, be32_to_cpu(trate.capflags)); 1330 else
1328 else 1331 ath_dbg(common, CONFIG,
1329 ath_dbg(common, CONFIG, 1332 "Unable to update supported rates for sta: %pM\n",
1330 "Unable to update supported rates for sta: %pM\n", 1333 sta->addr);
1331 sta->addr);
1332 }
1333 1334
1334 ath9k_htc_ps_restore(priv); 1335 ath9k_htc_ps_restore(priv);
1335 mutex_unlock(&priv->mutex); 1336 mutex_unlock(&priv->mutex);