mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
net: stmmac: introduce DMA interrupt status masking per traffic direction
In preparation to make stmmac support multi-vector MSI, we introduce the interrupt status masking according to RX, TX or RXTX. Default to use RXTX inside stmmac_dma_interrupt(), so there is no run-time logic difference now. Signed-off-by: Ong Boon Leong <boon.leong.ong@intel.com> Signed-off-by: Voon Weifeng <weifeng.voon@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
6c996e1994
commit
7e1c520c0d
|
|
@ -309,6 +309,12 @@ enum dma_irq_status {
|
|||
handle_tx = 0x8,
|
||||
};
|
||||
|
||||
enum dma_irq_dir {
|
||||
DMA_DIR_RX = 0x1,
|
||||
DMA_DIR_TX = 0x2,
|
||||
DMA_DIR_RXTX = 0x3,
|
||||
};
|
||||
|
||||
/* EEE and LPI defines */
|
||||
#define CORE_IRQ_TX_PATH_IN_LPI_MODE (1 << 0)
|
||||
#define CORE_IRQ_TX_PATH_EXIT_LPI_MODE (1 << 1)
|
||||
|
|
|
|||
|
|
@ -239,6 +239,22 @@ static const struct emac_variant emac_variant_h6 = {
|
|||
#define EMAC_RX_EARLY_INT BIT(13)
|
||||
#define EMAC_RGMII_STA_INT BIT(16)
|
||||
|
||||
#define EMAC_INT_MSK_COMMON EMAC_RGMII_STA_INT
|
||||
#define EMAC_INT_MSK_TX (EMAC_TX_INT | \
|
||||
EMAC_TX_DMA_STOP_INT | \
|
||||
EMAC_TX_BUF_UA_INT | \
|
||||
EMAC_TX_TIMEOUT_INT | \
|
||||
EMAC_TX_UNDERFLOW_INT | \
|
||||
EMAC_TX_EARLY_INT |\
|
||||
EMAC_INT_MSK_COMMON)
|
||||
#define EMAC_INT_MSK_RX (EMAC_RX_INT | \
|
||||
EMAC_RX_BUF_UA_INT | \
|
||||
EMAC_RX_DMA_STOP_INT | \
|
||||
EMAC_RX_TIMEOUT_INT | \
|
||||
EMAC_RX_OVERFLOW_INT | \
|
||||
EMAC_RX_EARLY_INT | \
|
||||
EMAC_INT_MSK_COMMON)
|
||||
|
||||
#define MAC_ADDR_TYPE_DST BIT(31)
|
||||
|
||||
/* H3 specific bits for EPHY */
|
||||
|
|
@ -412,13 +428,19 @@ static void sun8i_dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
|
|||
}
|
||||
|
||||
static int sun8i_dwmac_dma_interrupt(void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan)
|
||||
struct stmmac_extra_stats *x, u32 chan,
|
||||
u32 dir)
|
||||
{
|
||||
u32 v;
|
||||
int ret = 0;
|
||||
|
||||
v = readl(ioaddr + EMAC_INT_STA);
|
||||
|
||||
if (dir == DMA_DIR_RX)
|
||||
v &= EMAC_INT_MSK_RX;
|
||||
else if (dir == DMA_DIR_TX)
|
||||
v &= EMAC_INT_MSK_TX;
|
||||
|
||||
if (v & EMAC_TX_INT) {
|
||||
ret |= handle_tx;
|
||||
x->tx_normal_irq_n++;
|
||||
|
|
|
|||
|
|
@ -149,6 +149,25 @@
|
|||
#define DMA_CHAN_STATUS_TPS BIT(1)
|
||||
#define DMA_CHAN_STATUS_TI BIT(0)
|
||||
|
||||
#define DMA_CHAN_STATUS_MSK_COMMON (DMA_CHAN_STATUS_NIS | \
|
||||
DMA_CHAN_STATUS_AIS | \
|
||||
DMA_CHAN_STATUS_CDE | \
|
||||
DMA_CHAN_STATUS_FBE)
|
||||
|
||||
#define DMA_CHAN_STATUS_MSK_RX (DMA_CHAN_STATUS_REB | \
|
||||
DMA_CHAN_STATUS_ERI | \
|
||||
DMA_CHAN_STATUS_RWT | \
|
||||
DMA_CHAN_STATUS_RPS | \
|
||||
DMA_CHAN_STATUS_RBU | \
|
||||
DMA_CHAN_STATUS_RI | \
|
||||
DMA_CHAN_STATUS_MSK_COMMON)
|
||||
|
||||
#define DMA_CHAN_STATUS_MSK_TX (DMA_CHAN_STATUS_ETI | \
|
||||
DMA_CHAN_STATUS_TBU | \
|
||||
DMA_CHAN_STATUS_TPS | \
|
||||
DMA_CHAN_STATUS_TI | \
|
||||
DMA_CHAN_STATUS_MSK_COMMON)
|
||||
|
||||
/* Interrupt enable bits per channel */
|
||||
#define DMA_CHAN_INTR_ENA_NIE BIT(16)
|
||||
#define DMA_CHAN_INTR_ENA_AIE BIT(15)
|
||||
|
|
@ -206,7 +225,7 @@ void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan);
|
|||
void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
|
||||
void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
|
||||
int dwmac4_dma_interrupt(void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan);
|
||||
struct stmmac_extra_stats *x, u32 chan, u32 dir);
|
||||
void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
|
||||
void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
|
||||
void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
|
||||
|
|
|
|||
|
|
@ -135,12 +135,17 @@ void dwmac410_disable_dma_irq(void __iomem *ioaddr, u32 chan, bool rx, bool tx)
|
|||
}
|
||||
|
||||
int dwmac4_dma_interrupt(void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan)
|
||||
struct stmmac_extra_stats *x, u32 chan, u32 dir)
|
||||
{
|
||||
u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));
|
||||
u32 intr_en = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
|
||||
int ret = 0;
|
||||
|
||||
if (dir == DMA_DIR_RX)
|
||||
intr_status &= DMA_CHAN_STATUS_MSK_RX;
|
||||
else if (dir == DMA_DIR_TX)
|
||||
intr_status &= DMA_CHAN_STATUS_MSK_TX;
|
||||
|
||||
/* ABNORMAL interrupts */
|
||||
if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
|
||||
if (unlikely(intr_status & DMA_CHAN_STATUS_RBU))
|
||||
|
|
|
|||
|
|
@ -128,6 +128,26 @@
|
|||
#define DMA_STATUS_TI 0x00000001 /* Transmit Interrupt */
|
||||
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
|
||||
|
||||
#define DMA_STATUS_MSK_COMMON (DMA_STATUS_NIS | \
|
||||
DMA_STATUS_AIS | \
|
||||
DMA_STATUS_FBI)
|
||||
|
||||
#define DMA_STATUS_MSK_RX (DMA_STATUS_ERI | \
|
||||
DMA_STATUS_RWT | \
|
||||
DMA_STATUS_RPS | \
|
||||
DMA_STATUS_RU | \
|
||||
DMA_STATUS_RI | \
|
||||
DMA_STATUS_OVF | \
|
||||
DMA_STATUS_MSK_COMMON)
|
||||
|
||||
#define DMA_STATUS_MSK_TX (DMA_STATUS_ETI | \
|
||||
DMA_STATUS_UNF | \
|
||||
DMA_STATUS_TJT | \
|
||||
DMA_STATUS_TU | \
|
||||
DMA_STATUS_TPS | \
|
||||
DMA_STATUS_TI | \
|
||||
DMA_STATUS_MSK_COMMON)
|
||||
|
||||
#define NUM_DWMAC100_DMA_REGS 9
|
||||
#define NUM_DWMAC1000_DMA_REGS 23
|
||||
|
||||
|
|
@ -139,7 +159,7 @@ void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan);
|
|||
void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan);
|
||||
void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
|
||||
int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x,
|
||||
u32 chan);
|
||||
u32 chan, u32 dir);
|
||||
int dwmac_dma_reset(void __iomem *ioaddr);
|
||||
|
||||
#endif /* __DWMAC_DMA_H__ */
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ static void show_rx_process_state(unsigned int status)
|
|||
#endif
|
||||
|
||||
int dwmac_dma_interrupt(void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan)
|
||||
struct stmmac_extra_stats *x, u32 chan, u32 dir)
|
||||
{
|
||||
int ret = 0;
|
||||
/* read the status register (CSR5) */
|
||||
|
|
@ -167,6 +167,12 @@ int dwmac_dma_interrupt(void __iomem *ioaddr,
|
|||
show_tx_process_state(intr_status);
|
||||
show_rx_process_state(intr_status);
|
||||
#endif
|
||||
|
||||
if (dir == DMA_DIR_RX)
|
||||
intr_status &= DMA_STATUS_MSK_RX;
|
||||
else if (dir == DMA_DIR_TX)
|
||||
intr_status &= DMA_STATUS_MSK_TX;
|
||||
|
||||
/* ABNORMAL interrupts */
|
||||
if (unlikely(intr_status & DMA_STATUS_AIS)) {
|
||||
if (unlikely(intr_status & DMA_STATUS_UNF)) {
|
||||
|
|
|
|||
|
|
@ -412,6 +412,12 @@
|
|||
#define XGMAC_TI BIT(0)
|
||||
#define XGMAC_REGSIZE ((0x0000317c + (0x80 * 15)) / 4)
|
||||
|
||||
#define XGMAC_DMA_STATUS_MSK_COMMON (XGMAC_NIS | XGMAC_AIS | XGMAC_FBE)
|
||||
#define XGMAC_DMA_STATUS_MSK_RX (XGMAC_RBU | XGMAC_RI | \
|
||||
XGMAC_DMA_STATUS_MSK_COMMON)
|
||||
#define XGMAC_DMA_STATUS_MSK_TX (XGMAC_TBU | XGMAC_TPS | XGMAC_TI | \
|
||||
XGMAC_DMA_STATUS_MSK_COMMON)
|
||||
|
||||
/* Descriptors */
|
||||
#define XGMAC_TDES0_LTV BIT(31)
|
||||
#define XGMAC_TDES0_LT GENMASK(7, 0)
|
||||
|
|
|
|||
|
|
@ -323,12 +323,18 @@ static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan)
|
|||
}
|
||||
|
||||
static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan)
|
||||
struct stmmac_extra_stats *x, u32 chan,
|
||||
u32 dir)
|
||||
{
|
||||
u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
|
||||
u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
|
||||
int ret = 0;
|
||||
|
||||
if (dir == DMA_DIR_RX)
|
||||
intr_status &= XGMAC_DMA_STATUS_MSK_RX;
|
||||
else if (dir == DMA_DIR_TX)
|
||||
intr_status &= XGMAC_DMA_STATUS_MSK_TX;
|
||||
|
||||
/* ABNORMAL interrupts */
|
||||
if (unlikely(intr_status & XGMAC_AIS)) {
|
||||
if (unlikely(intr_status & XGMAC_RBU)) {
|
||||
|
|
|
|||
|
|
@ -201,7 +201,7 @@ struct stmmac_dma_ops {
|
|||
void (*start_rx)(void __iomem *ioaddr, u32 chan);
|
||||
void (*stop_rx)(void __iomem *ioaddr, u32 chan);
|
||||
int (*dma_interrupt) (void __iomem *ioaddr,
|
||||
struct stmmac_extra_stats *x, u32 chan);
|
||||
struct stmmac_extra_stats *x, u32 chan, u32 dir);
|
||||
/* If supported then get the optional core features */
|
||||
void (*get_hw_feature)(void __iomem *ioaddr,
|
||||
struct dma_features *dma_cap);
|
||||
|
|
|
|||
|
|
@ -2337,10 +2337,10 @@ static bool stmmac_safety_feat_interrupt(struct stmmac_priv *priv)
|
|||
return false;
|
||||
}
|
||||
|
||||
static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan)
|
||||
static int stmmac_napi_check(struct stmmac_priv *priv, u32 chan, u32 dir)
|
||||
{
|
||||
int status = stmmac_dma_interrupt_status(priv, priv->ioaddr,
|
||||
&priv->xstats, chan);
|
||||
&priv->xstats, chan, dir);
|
||||
struct stmmac_channel *ch = &priv->channel[chan];
|
||||
unsigned long flags;
|
||||
|
||||
|
|
@ -2386,7 +2386,8 @@ static void stmmac_dma_interrupt(struct stmmac_priv *priv)
|
|||
channels_to_check = ARRAY_SIZE(status);
|
||||
|
||||
for (chan = 0; chan < channels_to_check; chan++)
|
||||
status[chan] = stmmac_napi_check(priv, chan);
|
||||
status[chan] = stmmac_napi_check(priv, chan,
|
||||
DMA_DIR_RXTX);
|
||||
|
||||
for (chan = 0; chan < tx_channel_count; chan++) {
|
||||
if (unlikely(status[chan] & tx_hard_error_bump_tc)) {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user