|
@@ -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",
|