summaryrefslogtreecommitdiff
path: root/drivers/net/wireless/iwlwifi/iwl-agn.c
diff options
context:
space:
mode:
authorTrieu 'Andrew' Nguyen <trieux.t.nguyen@intel.com>2010-02-10 10:27:34 -0800
committerReinette Chatre <reinette.chatre@intel.com>2010-02-11 10:27:41 -0800
commit1db5950f1d0b82e07371b211a48317b8972da063 (patch)
tree6fc4f38f2c8cfd3a212c5eb18e326dd5d409ca2c /drivers/net/wireless/iwlwifi/iwl-agn.c
parenta9e10fb9b1c6ad16e73cf2656951fce3a817611e (diff)
iwlwifi: Monitor and recover the aggregation TX flow failure
This change monitors the tx statistics to detect the drop in throughput. When the throughput drops, the ratio of the actual_ack_count and the expected_ ack_count also drops. At the same time, the aggregated ba_timeout (the number of ba timeout retries) also rises. If the actual_ack_count/expected_ack_count ratio is 0 and the number of ba timeout retries rises to 16, no tx packets (tcp, udp, or ping - icmp) can be delivered. The driver recovers from this situation by reseting the uCode firmware. If the actual_ack_count/expected_ ack_count ratio drops below 50% (but not 0) and the aggregated ba_timeout retries just exceed 5 (but not 16), then the driver can reset the radio to bring the throughput up. Signed-off-by: Trieu 'Andrew' Nguyen <trieux.t.nguyen@intel.com> Signed-off-by: Reinette Chatre <reinette.chatre@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn.c')
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn.c14
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
index 31b156d58d7f..4157c6c8645f 100644
--- a/drivers/net/wireless/iwlwifi/iwl-agn.c
+++ b/drivers/net/wireless/iwlwifi/iwl-agn.c
@@ -2941,10 +2941,21 @@ static int iwl_mac_ampdu_action(struct ieee80211_hw *hw,
return ret;
case IEEE80211_AMPDU_TX_START:
IWL_DEBUG_HT(priv, "start Tx\n");
- return iwl_tx_agg_start(priv, sta->addr, tid, ssn);
+ ret = iwl_tx_agg_start(priv, sta->addr, tid, ssn);
+ if (ret == 0) {
+ priv->agg_tids_count++;
+ IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
+ priv->agg_tids_count);
+ }
+ return ret;
case IEEE80211_AMPDU_TX_STOP:
IWL_DEBUG_HT(priv, "stop Tx\n");
ret = iwl_tx_agg_stop(priv, sta->addr, tid);
+ if ((ret == 0) && (priv->agg_tids_count > 0)) {
+ priv->agg_tids_count--;
+ IWL_DEBUG_HT(priv, "priv->agg_tids_count = %u\n",
+ priv->agg_tids_count);
+ }
if (test_bit(STATUS_EXIT_PENDING, &priv->status))
return 0;
else
@@ -3364,6 +3375,7 @@ static int iwl_init_drv(struct iwl_priv *priv)
priv->iw_mode = NL80211_IFTYPE_STATION;
priv->current_ht_config.smps = IEEE80211_SMPS_STATIC;
priv->missed_beacon_threshold = IWL_MISSED_BEACON_THRESHOLD_DEF;
+ priv->agg_tids_count = 0;
/* Choose which receivers/antennas to use */
if (priv->cfg->ops->hcmd->set_rxon_chain)