From: Andy Lutomirski <luto@mit.edu>
To: "reinette chatre" <reinette.chatre@intel.com>
Cc: linville@tuxdriver.com, linux-wireless@vger.kernel.org,
ipw3943-devel@lists.sourceforge.net,
Trieu 'Andrew' Nguyen <trieux.t.nguyen@intel.com>
Subject: Re: [PATCH 12/12] iwlwifi: Monitor and recover the aggregation TX flow failure
Date: Fri, 12 Feb 2010 08:53:15 -0500 [thread overview]
Message-ID: <4B755D4B.8060005@mit.edu> (raw)
In-Reply-To: <1265913725-4279-13-git-send-email-reinette.chatre@intel.com>
Reinette Chatre wrote:
> From: Trieu 'Andrew' Nguyen <trieux.t.nguyen-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
>
> 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.
Any chance this fixes big 2120? Maybe I'm too optimistic, but I'll try
to test it this afternoon.
http://bugzilla.intellinuxwireless.org/show_bug.cgi?id=2120
--Andy
>
> Signed-off-by: Trieu 'Andrew' Nguyen <trieux.t.nguyen-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> Signed-off-by: Reinette Chatre <reinette.chatre-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
> ---
> drivers/net/wireless/iwlwifi/iwl-agn.c | 14 +++++++++-
> drivers/net/wireless/iwlwifi/iwl-dev.h | 3 ++
> drivers/net/wireless/iwlwifi/iwl-rx.c | 46 ++++++++++++++++++++++++++++++++
> 3 files changed, 62 insertions(+), 1 deletions(-)
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-agn.c b/drivers/net/wireless/iwlwifi/iwl-agn.c
> index 31b156d..4157c6c 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)
> diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
> index 71cf155..f81317d 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-dev.h
> +++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
> @@ -1072,6 +1072,9 @@ struct iwl_priv {
> /* storing the jiffies when the plcp error rate is received */
> unsigned long plcp_jiffies;
>
> + /* reporting the number of tids has AGG on. 0 means no AGGREGATION */
> + u8 agg_tids_count;
> +
> /* force reset */
> unsigned long last_force_reset_jiffies;
>
> diff --git a/drivers/net/wireless/iwlwifi/iwl-rx.c b/drivers/net/wireless/iwlwifi/iwl-rx.c
> index aba8f4c..fed554a 100644
> --- a/drivers/net/wireless/iwlwifi/iwl-rx.c
> +++ b/drivers/net/wireless/iwlwifi/iwl-rx.c
> @@ -616,6 +616,11 @@ static void iwl_accumulative_statistics(struct iwl_priv *priv,
>
> #define REG_RECALIB_PERIOD (60)
>
> +/* the threshold ratio of actual_ack_cnt to expected_ack_cnt in percent */
> +#define ACK_CNT_RATIO (50)
> +#define BA_TIMEOUT_CNT (5)
> +#define BA_TIMEOUT_MAX (16)
> +
> #define PLCP_MSG "plcp_err exceeded %u, %u, %u, %u, %u, %d, %u mSecs\n"
> void iwl_rx_statistics(struct iwl_priv *priv,
> struct iwl_rx_mem_buffer *rxb)
> @@ -625,6 +630,9 @@ void iwl_rx_statistics(struct iwl_priv *priv,
> int combined_plcp_delta;
> unsigned int plcp_msec;
> unsigned long plcp_received_jiffies;
> + int actual_ack_cnt_delta;
> + int expected_ack_cnt_delta;
> + int ba_timeout_delta;
>
> IWL_DEBUG_RX(priv, "Statistics notification received (%d vs %d).\n",
> (int)sizeof(priv->statistics),
> @@ -639,6 +647,44 @@ void iwl_rx_statistics(struct iwl_priv *priv,
> #ifdef CONFIG_IWLWIFI_DEBUG
> iwl_accumulative_statistics(priv, (__le32 *)&pkt->u.stats);
> #endif
> + actual_ack_cnt_delta = le32_to_cpu(pkt->u.stats.tx.actual_ack_cnt) -
> + le32_to_cpu(priv->statistics.tx.actual_ack_cnt);
> + expected_ack_cnt_delta = le32_to_cpu(
> + pkt->u.stats.tx.expected_ack_cnt) -
> + le32_to_cpu(priv->statistics.tx.expected_ack_cnt);
> + ba_timeout_delta = le32_to_cpu(
> + pkt->u.stats.tx.agg.ba_timeout) -
> + le32_to_cpu(priv->statistics.tx.agg.ba_timeout);
> + if ((priv->agg_tids_count > 0) &&
> + (expected_ack_cnt_delta > 0) &&
> + (((actual_ack_cnt_delta * 100) / expected_ack_cnt_delta) <
> + ACK_CNT_RATIO) &&
> + (ba_timeout_delta > BA_TIMEOUT_CNT)) {
> + IWL_DEBUG_RADIO(priv,
> + "actual_ack_cnt delta = %d, expected_ack_cnt = %d\n",
> + actual_ack_cnt_delta, expected_ack_cnt_delta);
> +
> +#ifdef CONFIG_IWLWIFI_DEBUG
> + IWL_DEBUG_RADIO(priv, "rx_detected_cnt delta = %d\n",
> + priv->delta_statistics.tx.rx_detected_cnt);
> + IWL_DEBUG_RADIO(priv,
> + "ack_or_ba_timeout_collision delta = %d\n",
> + priv->delta_statistics.tx.ack_or_ba_timeout_collision);
> +#endif
> + IWL_DEBUG_RADIO(priv, "agg ba_timeout delta = %d\n",
> + ba_timeout_delta);
> + if ((actual_ack_cnt_delta == 0) &&
> + (ba_timeout_delta >=
> + BA_TIMEOUT_MAX)) {
> + IWL_DEBUG_RADIO(priv,
> + "call iwl_force_reset(IWL_FW_RESET)\n");
> + iwl_force_reset(priv, IWL_FW_RESET);
> + } else {
> + IWL_DEBUG_RADIO(priv,
> + "call iwl_force_reset(IWL_RF_RESET)\n");
> + iwl_force_reset(priv, IWL_RF_RESET);
> + }
> + }
> /*
> * check for plcp_err and trigger radio reset if it exceeds
> * the plcp error threshold plcp_delta.
prev parent reply other threads:[~2010-02-12 14:00 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-11 18:41 [PATCH 00/12] iwlwifi updates for 2.6.34 Reinette Chatre
2010-02-11 18:41 ` [PATCH 01/12] iwlwifi: clear all tx queues when firmware ready Reinette Chatre
2010-02-11 18:41 ` [PATCH 02/12] iwlwifi: multiple force reset mode Reinette Chatre
2010-02-11 18:41 ` [PATCH 03/12] iwlwifi: add debug function to reset/reload radio/firmware Reinette Chatre
2010-02-11 18:41 ` [PATCH 04/12] iwlwifi: check for aggregation frame and queue Reinette Chatre
2010-02-11 18:41 ` [PATCH 05/12] iwlwifi: remove unused op-code in PHY Calibration command Reinette Chatre
2010-02-11 20:17 ` [ipw3945-devel] " Cahill, Ben M
2010-02-11 20:22 ` Guy, Wey-Yi
2010-02-11 21:23 ` Cahill, Ben M
2010-02-11 18:41 ` [PATCH 06/12] iwlwifi: cleanup return values Reinette Chatre
2010-02-11 18:42 ` [PATCH 07/12] iwlwifi: fix scan race Reinette Chatre
2010-02-11 18:42 ` [PATCH 08/12] iwlwifi: reset card during probe Reinette Chatre
2010-02-11 18:42 ` [PATCH 09/12] iwlwifi: Adjusting PLCP error threshold for 1000 NIC Reinette Chatre
2010-02-11 18:42 ` [PATCH 10/12] iwlwifi: use dma_alloc_coherent Reinette Chatre
2010-02-11 18:42 ` [PATCH 11/12] iwlwifi: clear all the stop_queue flag after load firmware Reinette Chatre
2010-02-11 18:42 ` [PATCH 12/12] iwlwifi: Monitor and recover the aggregation TX flow failure Reinette Chatre
2010-02-12 13:53 ` Andy Lutomirski [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4B755D4B.8060005@mit.edu \
--to=luto@mit.edu \
--cc=ipw3943-devel@lists.sourceforge.net \
--cc=linux-wireless@vger.kernel.org \
--cc=linville@tuxdriver.com \
--cc=reinette.chatre@intel.com \
--cc=trieux.t.nguyen@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.