summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastien Griffoul <sebastien.griffoul@intel.com>2016-05-24 16:29:39 +0200
committerAnas Nashif <nashif@linux.intel.com>2016-05-26 15:12:25 +0000
commit8237d0f882124d9aa9e9e79336de79b8f71deabb (patch)
tree9e60741fea086f8031710983f80bc020ce5ed4c4
parent0595c47e170a92b25a29e08865fea63d3d5710d0 (diff)
eth: Fix spurious interrupt issues
The ethernet driver generates a lot of spurious interrupts. These spurious interrupts have two sources: 1) The Mac Management Counter (MMC) module generates a lot of interrupts (GMI - bit 27 of the status register). Unfortunately the Interrupt enable register doesn't allow us to enable/disable it (bit 27 is reserved). Therefore the only way to mask this interrupt is to mask all the MMC interrupts (register REG_MMC_RX_INTR_MASK, REG_MMC_TX_INTR_MASK and REG_MMC_RX_IPC_INTR_MASK). By default these interrupts are not masked. 2) The RX interrupt is not correctly acknowledged. According to the datasheet, NIS is a sticky bit and must be cleared (by writing 1 to this bit) each time a corresponding bit, which causes NIS to be set, is cleared. Change-Id: I2033973849d87cddc328c65d0d4ad36b5a0c934e Signed-off-by: Sebastien Griffoul <sebastien.griffoul@intel.com>
-rw-r--r--drivers/ethernet/eth_dw.c7
-rw-r--r--drivers/ethernet/eth_dw_priv.h8
2 files changed, 14 insertions, 1 deletions
diff --git a/drivers/ethernet/eth_dw.c b/drivers/ethernet/eth_dw.c
index 921bfa66b..366cc1ac0 100644
--- a/drivers/ethernet/eth_dw.c
+++ b/drivers/ethernet/eth_dw.c
@@ -165,7 +165,7 @@ void eth_dw_isr(struct device *port)
eth_rx(port);
/* Acknowledge the interrupt. */
- eth_write(base_addr, REG_ADDR_STATUS, STATUS_RX_INT);
+ eth_write(base_addr, REG_ADDR_STATUS, STATUS_NORMAL_INT | STATUS_RX_INT);
}
#ifdef CONFIG_PCI
@@ -260,6 +260,11 @@ static int eth_initialize(struct device *port)
/* Enable receive interrupts */
INT_ENABLE_RX);
+ /* Mask all the MMC interrupts */
+ eth_write(base_addr, REG_MMC_RX_INTR_MASK, MMC_DEFAULT_MASK);
+ eth_write(base_addr, REG_MMC_TX_INTR_MASK, MMC_DEFAULT_MASK);
+ eth_write(base_addr, REG_MMC_RX_IPC_INTR_MASK, MMC_DEFAULT_MASK);
+
eth_write(base_addr, REG_ADDR_DMA_OPERATION,
/* Enable receive store-and-forward mode for simplicity. */
OP_MODE_25_RX_STORE_N_FORWARD |
diff --git a/drivers/ethernet/eth_dw_priv.h b/drivers/ethernet/eth_dw_priv.h
index caaaf5999..f5dfdedb5 100644
--- a/drivers/ethernet/eth_dw_priv.h
+++ b/drivers/ethernet/eth_dw_priv.h
@@ -170,11 +170,14 @@ struct eth_runtime {
volatile uint8_t rx_buf[UIP_BUFSIZE];
};
+#define MMC_DEFAULT_MASK 0xffffffff
+
#define MAC_CONF_14_RMII_100M BIT(14)
#define MAC_CONF_11_DUPLEX BIT(11)
#define MAC_CONF_3_TX_EN BIT(3)
#define MAC_CONF_2_RX_EN BIT(2)
+#define STATUS_NORMAL_INT BIT(16)
#define STATUS_RX_INT BIT(6)
#define OP_MODE_25_RX_STORE_N_FORWARD BIT(25)
@@ -188,6 +191,11 @@ struct eth_runtime {
#define REG_ADDR_MAC_CONF 0x0000
#define REG_ADDR_MACADDR_HI 0x0040
#define REG_ADDR_MACADDR_LO 0x0044
+
+#define REG_MMC_RX_INTR_MASK 0x010c
+#define REG_MMC_TX_INTR_MASK 0x0110
+#define REG_MMC_RX_IPC_INTR_MASK 0x0200
+
#define REG_ADDR_TX_POLL_DEMAND 0x1004
#define REG_ADDR_RX_POLL_DEMAND 0x1008
#define REG_ADDR_RX_DESC_LIST 0x100C