aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/iwlwifi/pcie/trans.c
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-01-02 05:12:25 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-01-16 08:23:57 -0500
commit1c3fea82d6ebf33edadefed2d9ce3efa1a654338 (patch)
tree58c8269e2275f8ea47f8a48a22c063d8ed1ed267 /drivers/net/wireless/iwlwifi/pcie/trans.c
parentddaf5a5b300b8f9d3591b509fd8bedab1c9887be (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/wireless/iwlwifi/pcie/trans.c')
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c43
1 files changed, 42 insertions, 1 deletions
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