diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2013-04-07 10:13:44 +0300 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-04-08 13:32:20 +0200 |
commit | 2d055afdcada4bd8b510e9d2a8566fbded3c9696 (patch) | |
tree | 3462550733d3646acf56b9048772ed21f6ead8f5 /drivers/net/wireless/iwlwifi/dvm/mac80211.c | |
parent | ff40231282d4eb57c5008ed48fef6dd1be9f3130 (diff) |
iwlwifi: dvm: handle FLUSH ampdu actions from mac80211
Until now we didn't handle properly the FLUSH ampdu action
coming from mac80211. This could result in SCD queue leak:
mac80211 would STOP_FLUSH an AMPDU Tx session and remove
the station. If we had still packets on the ring, we
wouldn't deallocate the SCD queue and wait for it to be
empty.
The indication of the queue being empty comes from the Tx
response flow which relies on the tid_data structure. The
problem is that this structure has been cleared when the
station has been removed.
In order to solve this issue, block in the STOP_FLUSH
ampdu_action until the SCD queue is flushed, and only then,
let mac80211 move forward to remove the station.
iwlagn_txfifo_flush had to be enhanced to allow this.
The bug fixed here caused the "txq_id mismatch: 12 0" print.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/dvm/mac80211.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index a7294fa4d7e5..fc3879804622 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c @@ -777,9 +777,12 @@ static int iwlagn_mac_ampdu_action(struct ieee80211_hw *hw, IWL_DEBUG_HT(priv, "start Tx\n"); ret = iwlagn_tx_agg_start(priv, vif, sta, tid, ssn); break; - case IEEE80211_AMPDU_TX_STOP_CONT: case IEEE80211_AMPDU_TX_STOP_FLUSH: case IEEE80211_AMPDU_TX_STOP_FLUSH_CONT: + IWL_DEBUG_HT(priv, "Flush Tx\n"); + ret = iwlagn_tx_agg_flush(priv, vif, sta, tid); + break; + case IEEE80211_AMPDU_TX_STOP_CONT: IWL_DEBUG_HT(priv, "stop Tx\n"); ret = iwlagn_tx_agg_stop(priv, vif, sta, tid); if ((ret == 0) && (priv->agg_tids_count > 0)) { @@ -1122,7 +1125,7 @@ static void iwlagn_mac_flush(struct ieee80211_hw *hw, u32 queues, bool drop) */ if (drop) { IWL_DEBUG_MAC80211(priv, "send flush command\n"); - if (iwlagn_txfifo_flush(priv)) { + if (iwlagn_txfifo_flush(priv, 0)) { IWL_ERR(priv, "flush request fail\n"); goto done; } |