Commit a28453c0 authored by David S. Miller's avatar David S. Miller

Merge branch 'stmmac-dma-ops-multiqueue'

Joao Pinto says:

====================
net: stmmac: prepare dma operations for multiple queues

As agreed with David Miller, this patch-set is the second of 3 to enable
multiple queues in stmmac.

This second one concentrates on dma operations adding functionalities as:
a) DMA Operation Mode configuration per channel and done in the multiple
queues configuration function
b) DMA IRQ enable and Disable by channel
c) DMA start and stop by channel
d) RX and TX ring length configuration by channel
e) RX and TX set tail pointer by channel
f) DMA Channel initialization broke into Channel comon, RX and TX
initialization
g) TSO being configured for all available channels
h) DMA interrupt treatment by channel
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents e0304f58 7bac4e1e
...@@ -416,6 +416,14 @@ struct stmmac_dma_ops { ...@@ -416,6 +416,14 @@ struct stmmac_dma_ops {
int (*reset)(void __iomem *ioaddr); int (*reset)(void __iomem *ioaddr);
void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg, void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
u32 dma_tx, u32 dma_rx, int atds); u32 dma_tx, u32 dma_rx, int atds);
void (*init_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg, u32 chan);
void (*init_rx_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
u32 dma_rx_phy, u32 chan);
void (*init_tx_chan)(void __iomem *ioaddr,
struct stmmac_dma_cfg *dma_cfg,
u32 dma_tx_phy, u32 chan);
/* Configure the AXI Bus Mode Register */ /* Configure the AXI Bus Mode Register */
void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi); void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
/* Dump DMA registers */ /* Dump DMA registers */
...@@ -424,25 +432,28 @@ struct stmmac_dma_ops { ...@@ -424,25 +432,28 @@ struct stmmac_dma_ops {
* An invalid value enables the store-and-forward mode */ * An invalid value enables the store-and-forward mode */
void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode, void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
int rxfifosz); int rxfifosz);
void (*dma_rx_mode)(void __iomem *ioaddr, int mode, u32 channel,
int fifosz);
void (*dma_tx_mode)(void __iomem *ioaddr, int mode, u32 channel);
/* To track extra statistic (if supported) */ /* To track extra statistic (if supported) */
void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x, void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
void __iomem *ioaddr); void __iomem *ioaddr);
void (*enable_dma_transmission) (void __iomem *ioaddr); void (*enable_dma_transmission) (void __iomem *ioaddr);
void (*enable_dma_irq) (void __iomem *ioaddr); void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
void (*disable_dma_irq) (void __iomem *ioaddr); void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
void (*start_tx) (void __iomem *ioaddr); void (*start_tx)(void __iomem *ioaddr, u32 chan);
void (*stop_tx) (void __iomem *ioaddr); void (*stop_tx)(void __iomem *ioaddr, u32 chan);
void (*start_rx) (void __iomem *ioaddr); void (*start_rx)(void __iomem *ioaddr, u32 chan);
void (*stop_rx) (void __iomem *ioaddr); void (*stop_rx)(void __iomem *ioaddr, u32 chan);
int (*dma_interrupt) (void __iomem *ioaddr, int (*dma_interrupt) (void __iomem *ioaddr,
struct stmmac_extra_stats *x); struct stmmac_extra_stats *x, u32 chan);
/* If supported then get the optional core features */ /* If supported then get the optional core features */
void (*get_hw_feature)(void __iomem *ioaddr, void (*get_hw_feature)(void __iomem *ioaddr,
struct dma_features *dma_cap); struct dma_features *dma_cap);
/* Program the HW RX Watchdog */ /* Program the HW RX Watchdog */
void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt); void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan);
void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len); void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len); void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); void (*set_rx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan); void (*set_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan); void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
......
...@@ -247,7 +247,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr, ...@@ -247,7 +247,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24; dma_cap->enh_desc = (hw_cap & DMA_HW_FEAT_ENHDESSEL) >> 24;
} }
static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt) static void dwmac1000_rx_watchdog(void __iomem *ioaddr, u32 riwt,
u32 number_chan)
{ {
writel(riwt, ioaddr + DMA_RX_WATCHDOG); writel(riwt, ioaddr + DMA_RX_WATCHDOG);
} }
......
...@@ -185,17 +185,17 @@ ...@@ -185,17 +185,17 @@
int dwmac4_dma_reset(void __iomem *ioaddr); int dwmac4_dma_reset(void __iomem *ioaddr);
void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr); void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr);
void dwmac4_enable_dma_irq(void __iomem *ioaddr); void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac410_enable_dma_irq(void __iomem *ioaddr); void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac4_disable_dma_irq(void __iomem *ioaddr); void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac4_dma_start_tx(void __iomem *ioaddr); void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan);
void dwmac4_dma_stop_tx(void __iomem *ioaddr); void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan);
void dwmac4_dma_start_rx(void __iomem *ioaddr); void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan);
void dwmac4_dma_stop_rx(void __iomem *ioaddr); void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan);
int dwmac4_dma_interrupt(void __iomem *ioaddr, int dwmac4_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x); struct stmmac_extra_stats *x, u32 chan);
void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len); void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan);
void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len); 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); void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan); void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
......
...@@ -37,96 +37,96 @@ int dwmac4_dma_reset(void __iomem *ioaddr) ...@@ -37,96 +37,96 @@ int dwmac4_dma_reset(void __iomem *ioaddr)
void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan) void dwmac4_set_rx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
{ {
writel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(0)); writel(tail_ptr, ioaddr + DMA_CHAN_RX_END_ADDR(chan));
} }
void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan) void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan)
{ {
writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(0)); writel(tail_ptr, ioaddr + DMA_CHAN_TX_END_ADDR(chan));
} }
void dwmac4_dma_start_tx(void __iomem *ioaddr) void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0)); u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
value |= DMA_CONTROL_ST; value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0)); writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
value = readl(ioaddr + GMAC_CONFIG); value = readl(ioaddr + GMAC_CONFIG);
value |= GMAC_CONFIG_TE; value |= GMAC_CONFIG_TE;
writel(value, ioaddr + GMAC_CONFIG); writel(value, ioaddr + GMAC_CONFIG);
} }
void dwmac4_dma_stop_tx(void __iomem *ioaddr) void dwmac4_dma_stop_tx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0)); u32 value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
value &= ~DMA_CONTROL_ST; value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0)); writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));
value = readl(ioaddr + GMAC_CONFIG); value = readl(ioaddr + GMAC_CONFIG);
value &= ~GMAC_CONFIG_TE; value &= ~GMAC_CONFIG_TE;
writel(value, ioaddr + GMAC_CONFIG); writel(value, ioaddr + GMAC_CONFIG);
} }
void dwmac4_dma_start_rx(void __iomem *ioaddr) void dwmac4_dma_start_rx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0)); u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
value |= DMA_CONTROL_SR; value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0)); writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
value = readl(ioaddr + GMAC_CONFIG); value = readl(ioaddr + GMAC_CONFIG);
value |= GMAC_CONFIG_RE; value |= GMAC_CONFIG_RE;
writel(value, ioaddr + GMAC_CONFIG); writel(value, ioaddr + GMAC_CONFIG);
} }
void dwmac4_dma_stop_rx(void __iomem *ioaddr) void dwmac4_dma_stop_rx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0)); u32 value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
value &= ~DMA_CONTROL_SR; value &= ~DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0)); writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));
value = readl(ioaddr + GMAC_CONFIG); value = readl(ioaddr + GMAC_CONFIG);
value &= ~GMAC_CONFIG_RE; value &= ~GMAC_CONFIG_RE;
writel(value, ioaddr + GMAC_CONFIG); writel(value, ioaddr + GMAC_CONFIG);
} }
void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len) void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
{ {
writel(len, ioaddr + DMA_CHAN_TX_RING_LEN(STMMAC_CHAN0)); writel(len, ioaddr + DMA_CHAN_TX_RING_LEN(chan));
} }
void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len) void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
{ {
writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(STMMAC_CHAN0)); writel(len, ioaddr + DMA_CHAN_RX_RING_LEN(chan));
} }
void dwmac4_enable_dma_irq(void __iomem *ioaddr) void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan)
{ {
writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr + writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr +
DMA_CHAN_INTR_ENA(STMMAC_CHAN0)); DMA_CHAN_INTR_ENA(chan));
} }
void dwmac410_enable_dma_irq(void __iomem *ioaddr) void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan)
{ {
writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10, writel(DMA_CHAN_INTR_DEFAULT_MASK_4_10,
ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0)); ioaddr + DMA_CHAN_INTR_ENA(chan));
} }
void dwmac4_disable_dma_irq(void __iomem *ioaddr) void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan)
{ {
writel(0, ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0)); writel(0, ioaddr + DMA_CHAN_INTR_ENA(chan));
} }
int dwmac4_dma_interrupt(void __iomem *ioaddr, int dwmac4_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x) struct stmmac_extra_stats *x, u32 chan)
{ {
int ret = 0; int ret = 0;
u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(0)); u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));
/* ABNORMAL interrupts */ /* ABNORMAL interrupts */
if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) { if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
...@@ -153,7 +153,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr, ...@@ -153,7 +153,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
if (likely(intr_status & DMA_CHAN_STATUS_RI)) { if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
u32 value; u32 value;
value = readl(ioaddr + DMA_CHAN_INTR_ENA(STMMAC_CHAN0)); value = readl(ioaddr + DMA_CHAN_INTR_ENA(chan));
/* to schedule NAPI on real RIE event. */ /* to schedule NAPI on real RIE event. */
if (likely(value & DMA_CHAN_INTR_ENA_RIE)) { if (likely(value & DMA_CHAN_INTR_ENA_RIE)) {
x->rx_normal_irq_n++; x->rx_normal_irq_n++;
...@@ -172,7 +172,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr, ...@@ -172,7 +172,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
* status [21-0] expect reserved bits [5-3] * status [21-0] expect reserved bits [5-3]
*/ */
writel((intr_status & 0x3fffc7), writel((intr_status & 0x3fffc7),
ioaddr + DMA_CHAN_STATUS(STMMAC_CHAN0)); ioaddr + DMA_CHAN_STATUS(chan));
return ret; return ret;
} }
......
...@@ -137,13 +137,14 @@ ...@@ -137,13 +137,14 @@
#define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */ #define DMA_CONTROL_FTF 0x00100000 /* Flush transmit FIFO */
void dwmac_enable_dma_transmission(void __iomem *ioaddr); void dwmac_enable_dma_transmission(void __iomem *ioaddr);
void dwmac_enable_dma_irq(void __iomem *ioaddr); void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac_disable_dma_irq(void __iomem *ioaddr); void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac_dma_start_tx(void __iomem *ioaddr); void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan);
void dwmac_dma_stop_tx(void __iomem *ioaddr); void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan);
void dwmac_dma_start_rx(void __iomem *ioaddr); void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan);
void dwmac_dma_stop_rx(void __iomem *ioaddr); void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan);
int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x); int dwmac_dma_interrupt(void __iomem *ioaddr, struct stmmac_extra_stats *x,
u32 chan);
int dwmac_dma_reset(void __iomem *ioaddr); int dwmac_dma_reset(void __iomem *ioaddr);
#endif /* __DWMAC_DMA_H__ */ #endif /* __DWMAC_DMA_H__ */
...@@ -47,38 +47,38 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr) ...@@ -47,38 +47,38 @@ void dwmac_enable_dma_transmission(void __iomem *ioaddr)
writel(1, ioaddr + DMA_XMT_POLL_DEMAND); writel(1, ioaddr + DMA_XMT_POLL_DEMAND);
} }
void dwmac_enable_dma_irq(void __iomem *ioaddr) void dwmac_enable_dma_irq(void __iomem *ioaddr, u32 chan)
{ {
writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA); writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
} }
void dwmac_disable_dma_irq(void __iomem *ioaddr) void dwmac_disable_dma_irq(void __iomem *ioaddr, u32 chan)
{ {
writel(0, ioaddr + DMA_INTR_ENA); writel(0, ioaddr + DMA_INTR_ENA);
} }
void dwmac_dma_start_tx(void __iomem *ioaddr) void dwmac_dma_start_tx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CONTROL); u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_ST; value |= DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL); writel(value, ioaddr + DMA_CONTROL);
} }
void dwmac_dma_stop_tx(void __iomem *ioaddr) void dwmac_dma_stop_tx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CONTROL); u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_ST; value &= ~DMA_CONTROL_ST;
writel(value, ioaddr + DMA_CONTROL); writel(value, ioaddr + DMA_CONTROL);
} }
void dwmac_dma_start_rx(void __iomem *ioaddr) void dwmac_dma_start_rx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CONTROL); u32 value = readl(ioaddr + DMA_CONTROL);
value |= DMA_CONTROL_SR; value |= DMA_CONTROL_SR;
writel(value, ioaddr + DMA_CONTROL); writel(value, ioaddr + DMA_CONTROL);
} }
void dwmac_dma_stop_rx(void __iomem *ioaddr) void dwmac_dma_stop_rx(void __iomem *ioaddr, u32 chan)
{ {
u32 value = readl(ioaddr + DMA_CONTROL); u32 value = readl(ioaddr + DMA_CONTROL);
value &= ~DMA_CONTROL_SR; value &= ~DMA_CONTROL_SR;
...@@ -156,7 +156,7 @@ static void show_rx_process_state(unsigned int status) ...@@ -156,7 +156,7 @@ static void show_rx_process_state(unsigned int status)
#endif #endif
int dwmac_dma_interrupt(void __iomem *ioaddr, int dwmac_dma_interrupt(void __iomem *ioaddr,
struct stmmac_extra_stats *x) struct stmmac_extra_stats *x, u32 chan)
{ {
int ret = 0; int ret = 0;
/* read the status register (CSR5) */ /* read the status register (CSR5) */
......
...@@ -730,6 +730,7 @@ static int stmmac_set_coalesce(struct net_device *dev, ...@@ -730,6 +730,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
struct ethtool_coalesce *ec) struct ethtool_coalesce *ec)
{ {
struct stmmac_priv *priv = netdev_priv(dev); struct stmmac_priv *priv = netdev_priv(dev);
u32 rx_cnt = priv->plat->rx_queues_to_use;
unsigned int rx_riwt; unsigned int rx_riwt;
/* Check not supported parameters */ /* Check not supported parameters */
...@@ -768,7 +769,7 @@ static int stmmac_set_coalesce(struct net_device *dev, ...@@ -768,7 +769,7 @@ static int stmmac_set_coalesce(struct net_device *dev,
priv->tx_coal_frames = ec->tx_max_coalesced_frames; priv->tx_coal_frames = ec->tx_max_coalesced_frames;
priv->tx_coal_timer = ec->tx_coalesce_usecs; priv->tx_coal_timer = ec->tx_coalesce_usecs;
priv->rx_riwt = rx_riwt; priv->rx_riwt = rx_riwt;
priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt); priv->hw->dma->rx_watchdog(priv->ioaddr, priv->rx_riwt, rx_cnt);
return 0; return 0;
} }
......
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