aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWey-Yi Guy <wey-yi.w.guy@intel.com>2010-09-05 13:49:41 -0400
committerWey-Yi Guy <wey-yi.w.guy@intel.com>2010-09-17 16:17:19 -0400
commit91835ba401189a81e5ad1f932f880d8eed8c9db2 (patch)
tree1d6e9f761524291b467da157d0a791d6eef667da
parenta437fbb96fe4eab241f06bbd7c7c1070ccdb2544 (diff)
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>
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-agn-lib.c79
-rw-r--r--drivers/net/wireless/iwlwifi/iwl-dev.h29
2 files changed, 108 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)
46 tx_resp->frame_count) & MAX_SN; 46 tx_resp->frame_count) & MAX_SN;
47} 47}
48 48
49static void iwlagn_count_tx_err_status(struct iwl_priv *priv, u16 status)
50{
51 status &= TX_STATUS_MSK;
52
53 switch (status) {
54 case TX_STATUS_POSTPONE_DELAY:
55 priv->_agn.reply_tx_stats.pp_delay++;
56 break;
57 case TX_STATUS_POSTPONE_FEW_BYTES:
58 priv->_agn.reply_tx_stats.pp_few_bytes++;
59 break;
60 case TX_STATUS_POSTPONE_BT_PRIO:
61 priv->_agn.reply_tx_stats.pp_bt_prio++;
62 break;
63 case TX_STATUS_POSTPONE_QUIET_PERIOD:
64 priv->_agn.reply_tx_stats.pp_quiet_period++;
65 break;
66 case TX_STATUS_POSTPONE_CALC_TTAK:
67 priv->_agn.reply_tx_stats.pp_calc_ttak++;
68 break;
69 case TX_STATUS_FAIL_INTERNAL_CROSSED_RETRY:
70 priv->_agn.reply_tx_stats.int_crossed_retry++;
71 break;
72 case TX_STATUS_FAIL_SHORT_LIMIT:
73 priv->_agn.reply_tx_stats.short_limit++;
74 break;
75 case TX_STATUS_FAIL_LONG_LIMIT:
76 priv->_agn.reply_tx_stats.long_limit++;
77 break;
78 case TX_STATUS_FAIL_FIFO_UNDERRUN:
79 priv->_agn.reply_tx_stats.fifo_underrun++;
80 break;
81 case TX_STATUS_FAIL_DRAIN_FLOW:
82 priv->_agn.reply_tx_stats.drain_flow++;
83 break;
84 case TX_STATUS_FAIL_RFKILL_FLUSH:
85 priv->_agn.reply_tx_stats.rfkill_flush++;
86 break;
87 case TX_STATUS_FAIL_LIFE_EXPIRE:
88 priv->_agn.reply_tx_stats.life_expire++;
89 break;
90 case TX_STATUS_FAIL_DEST_PS:
91 priv->_agn.reply_tx_stats.dest_ps++;
92 break;
93 case TX_STATUS_FAIL_HOST_ABORTED:
94 priv->_agn.reply_tx_stats.host_abort++;
95 break;
96 case TX_STATUS_FAIL_BT_RETRY:
97 priv->_agn.reply_tx_stats.bt_retry++;
98 break;
99 case TX_STATUS_FAIL_STA_INVALID:
100 priv->_agn.reply_tx_stats.sta_invalid++;
101 break;
102 case TX_STATUS_FAIL_FRAG_DROPPED:
103 priv->_agn.reply_tx_stats.frag_drop++;
104 break;
105 case TX_STATUS_FAIL_TID_DISABLE:
106 priv->_agn.reply_tx_stats.tid_disable++;
107 break;
108 case TX_STATUS_FAIL_FIFO_FLUSHED:
109 priv->_agn.reply_tx_stats.fifo_flush++;
110 break;
111 case TX_STATUS_FAIL_INSUFFICIENT_CF_POLL:
112 priv->_agn.reply_tx_stats.insuff_cf_poll++;
113 break;
114 case TX_STATUS_FAIL_FW_DROP:
115 priv->_agn.reply_tx_stats.fail_hw_drop++;
116 break;
117 case TX_STATUS_FAIL_STA_COLOR_MISMATCH_DROP:
118 priv->_agn.reply_tx_stats.sta_color_mismatch++;
119 break;
120 default:
121 priv->_agn.reply_tx_stats.unknown++;
122 break;
123 }
124}
125
49static void iwlagn_set_tx_status(struct iwl_priv *priv, 126static void iwlagn_set_tx_status(struct iwl_priv *priv,
50 struct ieee80211_tx_info *info, 127 struct ieee80211_tx_info *info,
51 struct iwl5000_tx_resp *tx_resp, 128 struct iwl5000_tx_resp *tx_resp,
@@ -59,6 +136,8 @@ static void iwlagn_set_tx_status(struct iwl_priv *priv,
59 info->flags |= iwl_tx_status_to_mac80211(status); 136 info->flags |= iwl_tx_status_to_mac80211(status);
60 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags), 137 iwlagn_hwrate_to_tx_control(priv, le32_to_cpu(tx_resp->rate_n_flags),
61 info); 138 info);
139 if (!iwl_is_tx_success(status))
140 iwlagn_count_tx_err_status(priv, status);
62 141
63 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags " 142 IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x) rate_n_flags "
64 "0x%x retries %d\n", 143 "0x%x retries %d\n",
diff --git a/drivers/net/wireless/iwlwifi/iwl-dev.h b/drivers/net/wireless/iwlwifi/iwl-dev.h
index 4e3a69271e34..bfa4864ec6d3 100644
--- a/drivers/net/wireless/iwlwifi/iwl-dev.h
+++ b/drivers/net/wireless/iwlwifi/iwl-dev.h
@@ -957,6 +957,33 @@ struct isr_statistics {
957 u32 unhandled; 957 u32 unhandled;
958}; 958};
959 959
960/* reply_tx_statistics (for _agn devices) */
961struct reply_tx_error_statistics {
962 u32 pp_delay;
963 u32 pp_few_bytes;
964 u32 pp_bt_prio;
965 u32 pp_quiet_period;
966 u32 pp_calc_ttak;
967 u32 int_crossed_retry;
968 u32 short_limit;
969 u32 long_limit;
970 u32 fifo_underrun;
971 u32 drain_flow;
972 u32 rfkill_flush;
973 u32 life_expire;
974 u32 dest_ps;
975 u32 host_abort;
976 u32 bt_retry;
977 u32 sta_invalid;
978 u32 frag_drop;
979 u32 tid_disable;
980 u32 fifo_flush;
981 u32 insuff_cf_poll;
982 u32 fail_hw_drop;
983 u32 sta_color_mismatch;
984 u32 unknown;
985};
986
960#ifdef CONFIG_IWLWIFI_DEBUGFS 987#ifdef CONFIG_IWLWIFI_DEBUGFS
961/* management statistics */ 988/* management statistics */
962enum iwl_mgmt_stats { 989enum iwl_mgmt_stats {
@@ -1415,6 +1442,8 @@ struct iwl_priv {
1415 1442
1416 struct iwl_notif_statistics statistics; 1443 struct iwl_notif_statistics statistics;
1417 struct iwl_bt_notif_statistics statistics_bt; 1444 struct iwl_bt_notif_statistics statistics_bt;
1445 /* counts reply_tx error */
1446 struct reply_tx_error_statistics reply_tx_stats;
1418#ifdef CONFIG_IWLWIFI_DEBUGFS 1447#ifdef CONFIG_IWLWIFI_DEBUGFS
1419 struct iwl_notif_statistics accum_statistics; 1448 struct iwl_notif_statistics accum_statistics;
1420 struct iwl_notif_statistics delta_statistics; 1449 struct iwl_notif_statistics delta_statistics;