diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-rs.c | 15 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-tx.c | 18 |
2 files changed, 26 insertions, 7 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c index 6aebcedaca8d..8bf7c20b9d39 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-rs.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-rs.c | |||
@@ -298,10 +298,23 @@ static void rs_tl_turn_on_agg_for_tid(struct iwl_priv *priv, | |||
298 | struct iwl_lq_sta *lq_data, u8 tid, | 298 | struct iwl_lq_sta *lq_data, u8 tid, |
299 | struct ieee80211_sta *sta) | 299 | struct ieee80211_sta *sta) |
300 | { | 300 | { |
301 | int ret; | ||
302 | |||
301 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { | 303 | if (rs_tl_get_load(lq_data, tid) > IWL_AGG_LOAD_THRESHOLD) { |
302 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", | 304 | IWL_DEBUG_HT(priv, "Starting Tx agg: STA: %pM tid: %d\n", |
303 | sta->addr, tid); | 305 | sta->addr, tid); |
304 | ieee80211_start_tx_ba_session(sta, tid); | 306 | ret = ieee80211_start_tx_ba_session(sta, tid); |
307 | if (ret == -EAGAIN) { | ||
308 | /* | ||
309 | * driver and mac80211 is out of sync | ||
310 | * this might be cause by reloading firmware | ||
311 | * stop the tx ba session here | ||
312 | */ | ||
313 | IWL_DEBUG_HT(priv, "Fail start Tx agg on tid: %d\n", | ||
314 | tid); | ||
315 | ret = ieee80211_stop_tx_ba_session(sta, tid, | ||
316 | WLAN_BACK_INITIATOR); | ||
317 | } | ||
305 | } | 318 | } |
306 | } | 319 | } |
307 | 320 | ||
diff --git a/drivers/net/wireless/iwlwifi/iwl-tx.c b/drivers/net/wireless/iwlwifi/iwl-tx.c index d365d13e3291..3788a3d4ddc2 100644 --- a/drivers/net/wireless/iwlwifi/iwl-tx.c +++ b/drivers/net/wireless/iwlwifi/iwl-tx.c | |||
@@ -806,8 +806,10 @@ int iwl_tx_skb(struct iwl_priv *priv, struct sk_buff *skb) | |||
806 | hdr->seq_ctrl |= cpu_to_le16(seq_number); | 806 | hdr->seq_ctrl |= cpu_to_le16(seq_number); |
807 | seq_number += 0x10; | 807 | seq_number += 0x10; |
808 | /* aggregation is on for this <sta,tid> */ | 808 | /* aggregation is on for this <sta,tid> */ |
809 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 809 | if (info->flags & IEEE80211_TX_CTL_AMPDU && |
810 | priv->stations[sta_id].tid[tid].agg.state == IWL_AGG_ON) { | ||
810 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; | 811 | txq_id = priv->stations[sta_id].tid[tid].agg.txq_id; |
812 | } | ||
811 | } | 813 | } |
812 | 814 | ||
813 | txq = &priv->txq[txq_id]; | 815 | txq = &priv->txq[txq_id]; |
@@ -1328,7 +1330,7 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1328 | { | 1330 | { |
1329 | int tx_fifo_id, txq_id, sta_id, ssn = -1; | 1331 | int tx_fifo_id, txq_id, sta_id, ssn = -1; |
1330 | struct iwl_tid_data *tid_data; | 1332 | struct iwl_tid_data *tid_data; |
1331 | int ret, write_ptr, read_ptr; | 1333 | int write_ptr, read_ptr; |
1332 | unsigned long flags; | 1334 | unsigned long flags; |
1333 | 1335 | ||
1334 | if (!ra) { | 1336 | if (!ra) { |
@@ -1380,13 +1382,17 @@ int iwl_tx_agg_stop(struct iwl_priv *priv , const u8 *ra, u16 tid) | |||
1380 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; | 1382 | priv->stations[sta_id].tid[tid].agg.state = IWL_AGG_OFF; |
1381 | 1383 | ||
1382 | spin_lock_irqsave(&priv->lock, flags); | 1384 | spin_lock_irqsave(&priv->lock, flags); |
1383 | ret = priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, | 1385 | /* |
1386 | * the only reason this call can fail is queue number out of range, | ||
1387 | * which can happen if uCode is reloaded and all the station | ||
1388 | * information are lost. if it is outside the range, there is no need | ||
1389 | * to deactivate the uCode queue, just return "success" to allow | ||
1390 | * mac80211 to clean up it own data. | ||
1391 | */ | ||
1392 | priv->cfg->ops->lib->txq_agg_disable(priv, txq_id, ssn, | ||
1384 | tx_fifo_id); | 1393 | tx_fifo_id); |
1385 | spin_unlock_irqrestore(&priv->lock, flags); | 1394 | spin_unlock_irqrestore(&priv->lock, flags); |
1386 | 1395 | ||
1387 | if (ret) | ||
1388 | return ret; | ||
1389 | |||
1390 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); | 1396 | ieee80211_stop_tx_ba_cb_irqsafe(priv->vif, ra, tid); |
1391 | 1397 | ||
1392 | return 0; | 1398 | return 0; |