Commit dda0e083 authored by Alexander Duyck's avatar Alexander Duyck Committed by David S. Miller

igb: add counter for dma out of sync errors

Add a counter for dma out of sync errors reported via interrupt.
Signed-off-by: default avatarAlexander Duyck <alexander.h.duyck@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 2753f4ce
...@@ -413,6 +413,7 @@ ...@@ -413,6 +413,7 @@
/* LAN connected device generates an interrupt */ /* LAN connected device generates an interrupt */
#define E1000_ICR_PHYINT 0x00001000 #define E1000_ICR_PHYINT 0x00001000
#define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */ #define E1000_ICR_EPRST 0x00100000 /* ME handware reset occurs */
#define E1000_ICR_DOUTSYNC 0x10000000 /* NIC DMA out of sync */
/* Extended Interrupt Cause Read */ /* Extended Interrupt Cause Read */
#define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */ #define E1000_EICR_RX_QUEUE0 0x00000001 /* Rx Queue 0 Interrupt */
...@@ -441,7 +442,8 @@ ...@@ -441,7 +442,8 @@
E1000_IMS_TXDW | \ E1000_IMS_TXDW | \
E1000_IMS_RXDMT0 | \ E1000_IMS_RXDMT0 | \
E1000_IMS_RXSEQ | \ E1000_IMS_RXSEQ | \
E1000_IMS_LSC) E1000_IMS_LSC | \
E1000_IMS_DOUTSYNC)
/* Interrupt Mask Set */ /* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */ #define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
...@@ -449,6 +451,7 @@ ...@@ -449,6 +451,7 @@
#define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */ #define E1000_IMS_RXSEQ E1000_ICR_RXSEQ /* rx sequence error */
#define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ #define E1000_IMS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */ #define E1000_IMS_RXT0 E1000_ICR_RXT0 /* rx timer intr */
#define E1000_IMS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
/* Extended Interrupt Mask Set */ /* Extended Interrupt Mask Set */
#define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */ #define E1000_EIMS_TCP_TIMER E1000_EICR_TCP_TIMER /* TCP Timer */
...@@ -457,6 +460,7 @@ ...@@ -457,6 +460,7 @@
/* Interrupt Cause Set */ /* Interrupt Cause Set */
#define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */ #define E1000_ICS_LSC E1000_ICR_LSC /* Link Status Change */
#define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */ #define E1000_ICS_RXDMT0 E1000_ICR_RXDMT0 /* rx desc min. threshold */
#define E1000_ICS_DOUTSYNC E1000_ICR_DOUTSYNC /* NIC DMA out of sync */
/* Extended Interrupt Cause Set */ /* Extended Interrupt Cause Set */
......
...@@ -359,6 +359,7 @@ struct e1000_hw_stats { ...@@ -359,6 +359,7 @@ struct e1000_hw_stats {
u64 lenerrs; u64 lenerrs;
u64 scvpc; u64 scvpc;
u64 hrmpc; u64 hrmpc;
u64 doosync;
}; };
struct e1000_phy_stats { struct e1000_phy_stats {
......
...@@ -88,6 +88,7 @@ static const struct igb_stats igb_gstrings_stats[] = { ...@@ -88,6 +88,7 @@ static const struct igb_stats igb_gstrings_stats[] = {
{ "rx_long_byte_count", IGB_STAT(stats.gorc) }, { "rx_long_byte_count", IGB_STAT(stats.gorc) },
{ "rx_csum_offload_good", IGB_STAT(hw_csum_good) }, { "rx_csum_offload_good", IGB_STAT(hw_csum_good) },
{ "rx_csum_offload_errors", IGB_STAT(hw_csum_err) }, { "rx_csum_offload_errors", IGB_STAT(hw_csum_err) },
{ "tx_dma_out_of_sync", IGB_STAT(stats.doosync) },
{ "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) }, { "alloc_rx_buff_failed", IGB_STAT(alloc_rx_buff_failed) },
{ "tx_smbus", IGB_STAT(stats.mgptc) }, { "tx_smbus", IGB_STAT(stats.mgptc) },
{ "rx_smbus", IGB_STAT(stats.mgprc) }, { "rx_smbus", IGB_STAT(stats.mgprc) },
......
...@@ -689,7 +689,7 @@ static void igb_irq_enable(struct igb_adapter *adapter) ...@@ -689,7 +689,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
wr32(E1000_EIAC, adapter->eims_enable_mask); wr32(E1000_EIAC, adapter->eims_enable_mask);
wr32(E1000_EIAM, adapter->eims_enable_mask); wr32(E1000_EIAM, adapter->eims_enable_mask);
wr32(E1000_EIMS, adapter->eims_enable_mask); wr32(E1000_EIMS, adapter->eims_enable_mask);
wr32(E1000_IMS, E1000_IMS_LSC); wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC);
} else { } else {
wr32(E1000_IMS, IMS_ENABLE_MASK); wr32(E1000_IMS, IMS_ENABLE_MASK);
wr32(E1000_IAM, IMS_ENABLE_MASK); wr32(E1000_IAM, IMS_ENABLE_MASK);
...@@ -3287,6 +3287,11 @@ static irqreturn_t igb_msix_other(int irq, void *data) ...@@ -3287,6 +3287,11 @@ static irqreturn_t igb_msix_other(int irq, void *data)
u32 icr = rd32(E1000_ICR); u32 icr = rd32(E1000_ICR);
/* reading ICR causes bit 31 of EICR to be cleared */ /* reading ICR causes bit 31 of EICR to be cleared */
if(icr & E1000_ICR_DOUTSYNC) {
/* HW is reporting DMA is out of sync */
adapter->stats.doosync++;
}
if (!(icr & E1000_ICR_LSC)) if (!(icr & E1000_ICR_LSC))
goto no_link_interrupt; goto no_link_interrupt;
hw->mac.get_link_status = 1; hw->mac.get_link_status = 1;
...@@ -3295,7 +3300,7 @@ static irqreturn_t igb_msix_other(int irq, void *data) ...@@ -3295,7 +3300,7 @@ static irqreturn_t igb_msix_other(int irq, void *data)
mod_timer(&adapter->watchdog_timer, jiffies + 1); mod_timer(&adapter->watchdog_timer, jiffies + 1);
no_link_interrupt: no_link_interrupt:
wr32(E1000_IMS, E1000_IMS_LSC); wr32(E1000_IMS, E1000_IMS_LSC | E1000_IMS_DOUTSYNC);
wr32(E1000_EIMS, adapter->eims_other); wr32(E1000_EIMS, adapter->eims_other);
return IRQ_HANDLED; return IRQ_HANDLED;
...@@ -3499,6 +3504,11 @@ static irqreturn_t igb_intr_msi(int irq, void *data) ...@@ -3499,6 +3504,11 @@ static irqreturn_t igb_intr_msi(int irq, void *data)
igb_write_itr(adapter->rx_ring); igb_write_itr(adapter->rx_ring);
if(icr & E1000_ICR_DOUTSYNC) {
/* HW is reporting DMA is out of sync */
adapter->stats.doosync++;
}
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
hw->mac.get_link_status = 1; hw->mac.get_link_status = 1;
if (!test_bit(__IGB_DOWN, &adapter->state)) if (!test_bit(__IGB_DOWN, &adapter->state))
...@@ -3534,6 +3544,11 @@ static irqreturn_t igb_intr(int irq, void *data) ...@@ -3534,6 +3544,11 @@ static irqreturn_t igb_intr(int irq, void *data)
if (!(icr & E1000_ICR_INT_ASSERTED)) if (!(icr & E1000_ICR_INT_ASSERTED))
return IRQ_NONE; return IRQ_NONE;
if(icr & E1000_ICR_DOUTSYNC) {
/* HW is reporting DMA is out of sync */
adapter->stats.doosync++;
}
eicr = rd32(E1000_EICR); eicr = rd32(E1000_EICR);
if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) { if (icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment