diff options
author | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-09-05 21:49:41 +0400 |
---|---|---|
committer | Wey-Yi Guy <wey-yi.w.guy@intel.com> | 2010-09-18 00:17:19 +0400 |
commit | 91835ba401189a81e5ad1f932f880d8eed8c9db2 (patch) | |
tree | 1d6e9f761524291b467da157d0a791d6eef667da /drivers/net/wireless/iwlwifi/iwl-agn-lib.c | |
parent | a437fbb96fe4eab241f06bbd7c7c1070ccdb2544 (diff) | |
download | linux-91835ba401189a81e5ad1f932f880d8eed8c9db2.tar.xz |
iwlagn: keep track fail tx reason counter
If uCode fail to transmit frame, it will send reply tx back
to driver with failure status; keep the counters of each failure
cases for debugging.
Signed-off-by: Wey-Yi Guy <wey-yi.w.guy@intel.com>
Diffstat (limited to 'drivers/net/wireless/iwlwifi/iwl-agn-lib.c')
-rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-agn-lib.c | 79 |
1 files changed, 79 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c index 12170cfcff4e..68a2ab399e3e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-agn-lib.c +++ b/drivers/net/wireless/iwlwifi/iwl-agn-lib.c @@ -46,6 +46,83 @@ static inline u32 iwlagn_get_scd_ssn(struct iwl5000_tx_resp *tx_resp) tx_resp->frame_count) & MAX_SN; } +static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status) +{ + status &= TX_STATUS_MSK; + + switch (status) { + case TX_STATUS_POSTPONE_DELAY: + priv->_agn.reply_tx_stats.pp_delay++; + break; + case TX_STATUS_POSTPONE_FEW_BYTES: + priv->_agn.reply_tx_stats.pp_few_bytes++; + break; + case TX_STATUS_POSTPONE_BT_PRIO: + priv->_agn.reply_tx_stats.pp_bt_prio++; + break; + case TX_STATUS_POSTPONE_QUIET_PERIOD: + priv->_agn.reply_tx_stats.pp_quiet_period++; + break; + case TX_STATUS_POSTPONE_CALC_TTAK: + priv->_agn.reply_tx_stats.pp_calc_ttak++; + break; + case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY: + priv->_agn.reply_tx_stats.int_crossed_retry++; + break; + case TX_STATUS_FAIL_SHORT_LIMIT: + priv->_agn.reply_tx_stats.short_limit++; + break; + case TX_STATUS_FAIL_LONG_LIMIT: + priv->_agn.reply_tx_stats.long_limit++; + break; + case TX_STATUS_FAIL_FIFO_UNDERRUN: + priv->_agn.reply_tx_stats.fifo_underrun++; + break; + case TX_STATUS_FAIL_DRAIN_FLOW: + priv->_agn.reply_tx_stats.drain_flow++; + break; + case TX_STATUS_FAIL_RFKILL_FLUSH: + priv->_agn.reply_tx_stats.rfkill_flush++; + break; + case TX_STATUS_FAIL_LIFE_EXPIRE: + priv->_agn.reply_tx_stats.life_expire++; + break; + case TX_STATUS_FAIL_DEST_PS: + priv->_agn.reply_tx_stats.dest_ps++; + break; + case TX_STATUS_FAIL_HOST_ABORTED: + priv->_agn.reply_tx_stats.host_abort++; + break; + case TX_STATUS_FAIL_BT_RETRY: + priv->_agn.reply_tx_stats.bt_retry++; + break; + case TX_STATUS_FAIL_STA_INVALID: + priv->_agn.reply_tx_stats.sta_invalid++; + break; + case TX_STATUS_FAIL_FRAG_DROPPED: + priv->_agn.reply_tx_stats.frag_drop++; + break; + case TX_STATUS_FAIL_TID_DISABLE: + priv->_agn.reply_tx_stats.tid_disable++; + break; + case TX_STATUS_FAIL_FIFO_FLUSHED: + priv->_agn.reply_tx_stats.fifo_flush++; + break; + case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL: + priv->_agn.reply_tx_stats.insuff_cf_poll++; + break; + case TX_STATUS_FAIL_FW_DROP: + priv->_agn.reply_tx_stats.fail_hw_drop++; + break; + case TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP: + priv->_agn.reply_tx_stats.sta_color_mismatch++; + break; + default: + priv->_agn.reply_tx_stats.unknown++; + break; + } +} + static void iwlagn_set_tx_status(struct iwl_priv *priv, struct ieee80211_tx_info *info, struct iwl5000_tx_resp *tx_resp, @@ -59,6 +136,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv, info->flags |= iwl_tx_status_to_mac80211(status); iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), info); + if (!iwl_is_tx_success(status)) + iwlagn_count_tx_err_status(priv, status); IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " "0x%x retries %d\n", |