aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
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
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')
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/mac80211.c3
-rw-r--r--drivers/net/wireless/iwlwifi/dvm/tx.c28
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/trans.c43
-rw-r--r--drivers/net/wireless/iwlwifi/pcie/tx.c7
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