diff options
author | Emmanuel Grumbach <emmanuel.grumbach@intel.com> | 2013-01-02 05:12:25 -0500 |
---|---|---|
committer | Johannes Berg <johannes.berg@intel.com> | 2013-01-16 08:23:57 -0500 |
commit | 1c3fea82d6ebf33edadefed2d9ce3efa1a654338 (patch) | |
tree | 58c8269e2275f8ea47f8a48a22c063d8ed1ed267 /drivers/net | |
parent | ddaf5a5b300b8f9d3591b509fd8bedab1c9887be (diff) |
iwlwifi: improve the reports in TX path
Also when things go wrong (queues don't get emtpy), try to
get some data from the HW.
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Diffstat (limited to 'drivers/net')
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/mac80211.c | 3 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/dvm/tx.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/trans.c | 43 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/pcie/tx.c | 7 |
4 files changed, 61 insertions, 20 deletions
diff --git a/drivers/net/wireless/iwlwifi/dvm/mac80211.c b/drivers/net/wireless/iwlwifi/dvm/mac80211.c index fef17c15562b..2da2627e1743 100644 --- a/drivers/net/wireless/iwlwifi/dvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/dvm/mac80211.c | |||
@@ -521,9 +521,6 @@ static void iwlagn_mac_tx(struct ieee80211_hw *hw, | |||
521 | { | 521 | { |
522 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); | 522 | struct iwl_priv *priv = IWL_MAC80211_GET_DVM(hw); |
523 | 523 | ||
524 | IWL_DEBUG_TX(priv, "dev->xmit(%d bytes) at rate 0x%02x\n", skb->len, | ||
525 | ieee80211_get_tx_rate(hw, IEEE80211_SKB_CB(skb))->bitrate); | ||
526 | |||
527 | if (iwlagn_tx_skb(priv, control->sta, skb)) | 524 | if (iwlagn_tx_skb(priv, control->sta, skb)) |
528 | ieee80211_free_txskb(hw, skb); | 525 | ieee80211_free_txskb(hw, skb); |
529 | } | 526 | } |
diff --git a/drivers/net/wireless/iwlwifi/dvm/tx.c b/drivers/net/wireless/iwlwifi/dvm/tx.c index df76881385ae..b0aad71c12a0 100644 --- a/drivers/net/wireless/iwlwifi/dvm/tx.c +++ b/drivers/net/wireless/iwlwifi/dvm/tx.c | |||
@@ -231,13 +231,11 @@ static void iwlagn_tx_cmd_build_hwcrypto(struct iwl_priv *priv, | |||
231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); | 231 | memcpy(tx_cmd->key, keyconf->key, keyconf->keylen); |
232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) | 232 | if (info->flags & IEEE80211_TX_CTL_AMPDU) |
233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; | 233 | tx_cmd->tx_flags |= TX_CMD_FLG_AGG_CCMP_MSK; |
234 | IWL_DEBUG_TX(priv, "tx_cmd with AES hwcrypto\n"); | ||
235 | break; | 234 | break; |
236 | 235 | ||
237 | case WLAN_CIPHER_SUITE_TKIP: | 236 | case WLAN_CIPHER_SUITE_TKIP: |
238 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; | 237 | tx_cmd->sec_ctl = TX_CMD_SEC_TKIP; |
239 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); | 238 | ieee80211_get_tkip_p2k(keyconf, skb_frag, tx_cmd->key); |
240 | IWL_DEBUG_TX(priv, "tx_cmd with tkip hwcrypto\n"); | ||
241 | break; | 239 | break; |
242 | 240 | ||
243 | case WLAN_CIPHER_SUITE_WEP104: | 241 | case WLAN_CIPHER_SUITE_WEP104: |
@@ -355,8 +353,6 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
355 | } | 353 | } |
356 | } | 354 | } |
357 | 355 | ||
358 | IWL_DEBUG_TX(priv, "station Id %d\n", sta_id); | ||
359 | |||
360 | if (sta) | 356 | if (sta) |
361 | sta_priv = (void *)sta->drv_priv; | 357 | sta_priv = (void *)sta->drv_priv; |
362 | 358 | ||
@@ -472,6 +468,9 @@ int iwlagn_tx_skb(struct iwl_priv *priv, | |||
472 | WARN_ON_ONCE(is_agg && | 468 | WARN_ON_ONCE(is_agg && |
473 | priv->queue_to_mac80211[txq_id] != info->hw_queue); | 469 | priv->queue_to_mac80211[txq_id] != info->hw_queue); |
474 | 470 | ||
471 | IWL_DEBUG_TX(priv, "TX to [%d|%d] Q:%d - seq: 0x%x\n", sta_id, tid, | ||
472 | txq_id, seq_number); | ||
473 | |||
475 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) | 474 | if (iwl_trans_tx(priv->trans, skb, dev_cmd, txq_id)) |
476 | goto drop_unlock_sta; | 475 | goto drop_unlock_sta; |
477 | 476 | ||
@@ -953,12 +952,6 @@ static void iwl_rx_reply_tx_agg(struct iwl_priv *priv, | |||
953 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | | 952 | if (status & (AGG_TX_STATE_FEW_BYTES_MSK | |
954 | AGG_TX_STATE_ABORT_MSK)) | 953 | AGG_TX_STATE_ABORT_MSK)) |
955 | continue; | 954 | continue; |
956 | |||
957 | IWL_DEBUG_TX_REPLY(priv, "status %s (0x%08x), " | ||
958 | "try-count (0x%08x)\n", | ||
959 | iwl_get_agg_tx_fail_reason(fstatus), | ||
960 | fstatus & AGG_TX_STATUS_MSK, | ||
961 | fstatus & AGG_TX_TRY_MSK); | ||
962 | } | 955 | } |
963 | } | 956 | } |
964 | 957 | ||
@@ -1212,16 +1205,27 @@ int iwlagn_rx_reply_tx(struct iwl_priv *priv, struct iwl_rx_cmd_buffer *rxb, | |||
1212 | freed++; | 1205 | freed++; |
1213 | } | 1206 | } |
1214 | 1207 | ||
1215 | WARN_ON(!is_agg && freed != 1); | 1208 | if (!is_agg && freed != 1) |
1209 | IWL_ERR(priv, "Q: %d, freed %d\n", txq_id, freed); | ||
1216 | 1210 | ||
1217 | /* | 1211 | /* |
1218 | * An offchannel frame can be send only on the AUX queue, where | 1212 | * An offchannel frame can be send only on the AUX queue, where |
1219 | * there is no aggregation (and reordering) so it only is single | 1213 | * there is no aggregation (and reordering) so it only is single |
1220 | * skb is expected to be processed. | 1214 | * skb is expected to be processed. |
1221 | */ | 1215 | */ |
1222 | WARN_ON(is_offchannel_skb && freed != 1); | 1216 | if (is_offchannel_skb && freed != 1) |
1217 | IWL_ERR(priv, "OFFCHANNEL SKB freed %d\n", freed); | ||
1223 | } | 1218 | } |
1224 | 1219 | ||
1220 | IWL_DEBUG_TX_REPLY(priv, "TXQ %d status %s (0x%08x)\n", txq_id, | ||
1221 | iwl_get_tx_fail_reason(status), status); | ||
1222 | |||
1223 | IWL_DEBUG_TX_REPLY(priv, | ||
1224 | "\t\t\t\tinitial_rate 0x%x retries %d, idx=%d ssn=%d seq_ctl=0x%x\n", | ||
1225 | le32_to_cpu(tx_resp->rate_n_flags), | ||
1226 | tx_resp->failure_frame, SEQ_TO_INDEX(sequence), ssn, | ||
1227 | le16_to_cpu(tx_resp->seq_ctl)); | ||
1228 | |||
1225 | iwl_check_abort_status(priv, tx_resp->frame_count, status); | 1229 | iwl_check_abort_status(priv, tx_resp->frame_count, status); |
1226 | spin_unlock(&priv->sta_lock); | 1230 | spin_unlock(&priv->sta_lock); |
1227 | 1231 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/trans.c b/drivers/net/wireless/iwlwifi/pcie/trans.c index 59340ff13a64..c57641eb83d5 100644 --- a/drivers/net/wireless/iwlwifi/pcie/trans.c +++ b/drivers/net/wireless/iwlwifi/pcie/trans.c | |||
@@ -890,6 +890,8 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
890 | struct iwl_queue *q; | 890 | struct iwl_queue *q; |
891 | int cnt; | 891 | int cnt; |
892 | unsigned long now = jiffies; | 892 | unsigned long now = jiffies; |
893 | u32 scd_sram_addr; | ||
894 | u8 buf[16]; | ||
893 | int ret = 0; | 895 | int ret = 0; |
894 | 896 | ||
895 | /* waiting for all the tx frames complete might take a while */ | 897 | /* waiting for all the tx frames complete might take a while */ |
@@ -903,11 +905,50 @@ static int iwl_trans_pcie_wait_txq_empty(struct iwl_trans *trans) | |||
903 | msleep(1); | 905 | msleep(1); |
904 | 906 | ||
905 | if (q->read_ptr != q->write_ptr) { | 907 | if (q->read_ptr != q->write_ptr) { |
906 | IWL_ERR(trans, "fail to flush all tx fifo queues\n"); | 908 | IWL_ERR(trans, |
909 | "fail to flush all tx fifo queues Q %d\n", cnt); | ||
907 | ret = -ETIMEDOUT; | 910 | ret = -ETIMEDOUT; |
908 | break; | 911 | break; |
909 | } | 912 | } |
910 | } | 913 | } |
914 | |||
915 | if (!ret) | ||
916 | return 0; | ||
917 | |||
918 | IWL_ERR(trans, "Current SW read_ptr %d write_ptr %d\n", | ||
919 | txq->q.read_ptr, txq->q.write_ptr); | ||
920 | |||
921 | scd_sram_addr = trans_pcie->scd_base_addr + | ||
922 | SCD_TX_STTS_QUEUE_OFFSET(txq->q.id); | ||
923 | iwl_trans_read_mem_bytes(trans, scd_sram_addr, buf, sizeof(buf)); | ||
924 | |||
925 | iwl_print_hex_error(trans, buf, sizeof(buf)); | ||
926 | |||
927 | for (cnt = 0; cnt < FH_TCSR_CHNL_NUM; cnt++) | ||
928 | IWL_ERR(trans, "FH TRBs(%d) = 0x%08x\n", cnt, | ||
929 | iwl_read_direct32(trans, FH_TX_TRB_REG(cnt))); | ||
930 | |||
931 | for (cnt = 0; cnt < trans->cfg->base_params->num_of_queues; cnt++) { | ||
932 | u32 status = iwl_read_prph(trans, SCD_QUEUE_STATUS_BITS(cnt)); | ||
933 | u8 fifo = (status >> SCD_QUEUE_STTS_REG_POS_TXF) & 0x7; | ||
934 | bool active = !!(status & BIT(SCD_QUEUE_STTS_REG_POS_ACTIVE)); | ||
935 | u32 tbl_dw = | ||
936 | iwl_trans_read_mem32(trans, trans_pcie->scd_base_addr + | ||
937 | SCD_TRANS_TBL_OFFSET_QUEUE(cnt)); | ||
938 | |||
939 | if (cnt & 0x1) | ||
940 | tbl_dw = (tbl_dw & 0xFFFF0000) >> 16; | ||
941 | else | ||
942 | tbl_dw = tbl_dw & 0x0000FFFF; | ||
943 | |||
944 | IWL_ERR(trans, | ||
945 | "Q %d is %sactive and mapped to fifo %d ra_tid 0x%04x [%d,%d]\n", | ||
946 | cnt, active ? "" : "in", fifo, tbl_dw, | ||
947 | iwl_read_prph(trans, | ||
948 | SCD_QUEUE_RDPTR(cnt)) & (txq->q.n_bd - 1), | ||
949 | iwl_read_prph(trans, SCD_QUEUE_WRPTR(cnt))); | ||
950 | } | ||
951 | |||
911 | return ret; | 952 | return ret; |
912 | } | 953 | } |
913 | 954 | ||
diff --git a/drivers/net/wireless/iwlwifi/pcie/tx.c b/drivers/net/wireless/iwlwifi/pcie/tx.c index fd3280fca445..a93f06762b96 100644 --- a/drivers/net/wireless/iwlwifi/pcie/tx.c +++ b/drivers/net/wireless/iwlwifi/pcie/tx.c | |||
@@ -309,6 +309,9 @@ void iwl_pcie_txq_inc_wr_ptr(struct iwl_trans *trans, struct iwl_txq *txq) | |||
309 | return; | 309 | return; |
310 | } | 310 | } |
311 | 311 | ||
312 | IWL_DEBUG_TX(trans, "Q:%d WR: 0x%x\n", txq_id, | ||
313 | txq->q.write_ptr); | ||
314 | |||
312 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, | 315 | iwl_write_direct32(trans, HBUS_TARG_WRPTR, |
313 | txq->q.write_ptr | (txq_id << 8)); | 316 | txq->q.write_ptr | (txq_id << 8)); |
314 | 317 | ||
@@ -1660,10 +1663,6 @@ int iwl_trans_pcie_tx(struct iwl_trans *trans, struct sk_buff *skb, | |||
1660 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); | 1663 | tx_cmd->dram_lsb_ptr = cpu_to_le32(scratch_phys); |
1661 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); | 1664 | tx_cmd->dram_msb_ptr = iwl_get_dma_hi_addr(scratch_phys); |
1662 | 1665 | ||
1663 | IWL_DEBUG_TX(trans, "sequence nr = 0X%x\n", | ||
1664 | le16_to_cpu(dev_cmd->hdr.sequence)); | ||
1665 | IWL_DEBUG_TX(trans, "tx_flags = 0X%x\n", le32_to_cpu(tx_cmd->tx_flags)); | ||
1666 | |||
1667 | /* Set up entry for this TFD in Tx byte-count array */ | 1666 | /* Set up entry for this TFD in Tx byte-count array */ |
1668 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); | 1667 | iwl_pcie_txq_update_byte_cnt_tbl(trans, txq, le16_to_cpu(tx_cmd->len)); |
1669 | 1668 | ||