From b80667eee2af9c1a36ec45a06f9ff85dd8768412 Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Fri, 9 Dec 2011 07:26:13 -0800 Subject: [PATCH] iwlagn: add IRQ tracing The legacy IRQs could be read from a trace by their IO accesses, but reading the ICT doesn't leave any trace (pun intended ;-) ) so in order to see what input they get we need to add specific tracepoints. While at it, fix whitespace in two related places. Signed-off-by: Johannes Berg Signed-off-by: Wey-Yi Guy --- drivers/net/wireless/iwlwifi/iwl-devtrace.h | 29 +++++++++++++++++ .../net/wireless/iwlwifi/iwl-trans-pcie-rx.c | 32 ++++++++++++------- 2 files changed, 50 insertions(+), 11 deletions(-) diff --git a/drivers/net/wireless/iwlwifi/iwl-devtrace.h b/drivers/net/wireless/iwlwifi/iwl-devtrace.h index f9d3319ecad5..9b212a8f30bb 100644 --- a/drivers/net/wireless/iwlwifi/iwl-devtrace.h +++ b/drivers/net/wireless/iwlwifi/iwl-devtrace.h @@ -90,6 +90,35 @@ TRACE_EVENT(iwlwifi_dev_iowrite32, TP_printk("[%p] write io[%#x] = %#x)", __entry->priv, __entry->offs, __entry->val) ); +TRACE_EVENT(iwlwifi_dev_irq, + TP_PROTO(void *priv), + TP_ARGS(priv), + TP_STRUCT__entry( + PRIV_ENTRY + ), + TP_fast_assign( + PRIV_ASSIGN; + ), + /* TP_printk("") doesn't compile */ + TP_printk("%d", 0) +); + +TRACE_EVENT(iwlwifi_dev_ict_read, + TP_PROTO(void *priv, u32 index, u32 value), + TP_ARGS(priv, index, value), + TP_STRUCT__entry( + PRIV_ENTRY + __field(u32, index) + __field(u32, value) + ), + TP_fast_assign( + PRIV_ASSIGN; + __entry->index = index; + __entry->value = value; + ), + TP_printk("read ict[%d] = %#.8x", __entry->index, __entry->value) +); + #undef TRACE_SYSTEM #define TRACE_SYSTEM iwlwifi_ucode diff --git a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c index 791005d47836..06d5698cd03e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c +++ b/drivers/net/wireless/iwlwifi/iwl-trans-pcie-rx.c @@ -1281,6 +1281,8 @@ static irqreturn_t iwl_isr(int irq, void *data) if (!trans) return IRQ_NONE; + trace_iwlwifi_dev_irq(priv(trans)); + trans_pcie = IWL_TRANS_GET_PCIE_TRANS(trans); spin_lock_irqsave(&trans->shrd->lock, flags); @@ -1355,6 +1357,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) struct iwl_trans_pcie *trans_pcie; u32 inta, inta_mask; u32 val = 0; + u32 read; unsigned long flags; if (!trans) @@ -1368,6 +1371,8 @@ irqreturn_t iwl_isr_ict(int irq, void *data) if (!trans_pcie->use_ict) return iwl_isr(irq, data); + trace_iwlwifi_dev_irq(priv(trans)); + spin_lock_irqsave(&trans->shrd->lock, flags); /* Disable (but don't clear!) interrupts here to avoid @@ -1382,24 +1387,29 @@ irqreturn_t iwl_isr_ict(int irq, void *data) /* Ignore interrupt if there's nothing in NIC to service. * This may be due to IRQ shared with another device, * or due to sporadic interrupts thrown from our NIC. */ - if (!trans_pcie->ict_tbl[trans_pcie->ict_index]) { + read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); + trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, read); + if (!read) { IWL_DEBUG_ISR(trans, "Ignore interrupt, inta == 0\n"); goto none; } - /* read all entries that not 0 start with ict_index */ - while (trans_pcie->ict_tbl[trans_pcie->ict_index]) { - - val |= le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); + /* + * Collect all entries up to the first 0, starting from ict_index; + * note we already read at ict_index. + */ + do { + val |= read; IWL_DEBUG_ISR(trans, "ICT index %d value 0x%08X\n", - trans_pcie->ict_index, - le32_to_cpu( - trans_pcie->ict_tbl[trans_pcie->ict_index])); + trans_pcie->ict_index, read); trans_pcie->ict_tbl[trans_pcie->ict_index] = 0; trans_pcie->ict_index = iwl_queue_inc_wrap(trans_pcie->ict_index, ICT_COUNT); - } + read = le32_to_cpu(trans_pcie->ict_tbl[trans_pcie->ict_index]); + trace_iwlwifi_dev_ict_read(priv(trans), trans_pcie->ict_index, + read); + } while (read); /* We should not get this value, just ignore it. */ if (val == 0xffffffff) @@ -1426,7 +1436,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) if (likely(inta)) tasklet_schedule(&trans_pcie->irq_tasklet); else if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && - !trans_pcie->inta) { + !trans_pcie->inta) { /* Allow interrupt if was disabled by this handler and * no tasklet was schedules, We should not enable interrupt, * tasklet will enable it. @@ -1442,7 +1452,7 @@ irqreturn_t iwl_isr_ict(int irq, void *data) * only Re-enable if disabled by irq. */ if (test_bit(STATUS_INT_ENABLED, &trans->shrd->status) && - !trans_pcie->inta) + !trans_pcie->inta) iwl_enable_interrupts(trans); spin_unlock_irqrestore(&trans->shrd->lock, flags); -- 2.34.1