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

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
Loading
Loading
Loading
Loading
+21 −10
Original line number Diff line number Diff line
@@ -416,6 +416,14 @@ struct stmmac_dma_ops {
	int (*reset)(void __iomem *ioaddr);
	void (*init)(void __iomem *ioaddr, struct stmmac_dma_cfg *dma_cfg,
		     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 */
	void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi);
	/* Dump DMA registers */
@@ -424,25 +432,28 @@ struct stmmac_dma_ops {
	 * An invalid value enables the store-and-forward mode */
	void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode,
			 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) */
	void (*dma_diagnostic_fr) (void *data, struct stmmac_extra_stats *x,
				   void __iomem *ioaddr);
	void (*enable_dma_transmission) (void __iomem *ioaddr);
	void (*enable_dma_irq) (void __iomem *ioaddr);
	void (*disable_dma_irq) (void __iomem *ioaddr);
	void (*start_tx) (void __iomem *ioaddr);
	void (*stop_tx) (void __iomem *ioaddr);
	void (*start_rx) (void __iomem *ioaddr);
	void (*stop_rx) (void __iomem *ioaddr);
	void (*enable_dma_irq)(void __iomem *ioaddr, u32 chan);
	void (*disable_dma_irq)(void __iomem *ioaddr, u32 chan);
	void (*start_tx)(void __iomem *ioaddr, u32 chan);
	void (*stop_tx)(void __iomem *ioaddr, u32 chan);
	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);
			      struct stmmac_extra_stats *x, u32 chan);
	/* If supported then get the optional core features */
	void (*get_hw_feature)(void __iomem *ioaddr,
			       struct dma_features *dma_cap);
	/* Program the HW RX Watchdog */
	void (*rx_watchdog) (void __iomem *ioaddr, u32 riwt);
	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len);
	void (*set_rx_ring_len)(void __iomem *ioaddr, u32 len);
	void (*rx_watchdog)(void __iomem *ioaddr, u32 riwt, u32 number_chan);
	void (*set_tx_ring_len)(void __iomem *ioaddr, u32 len, u32 chan);
	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_tx_tail_ptr)(void __iomem *ioaddr, u32 tail_ptr, u32 chan);
	void (*enable_tso)(void __iomem *ioaddr, bool en, u32 chan);
+2 −1
Original line number Diff line number Diff line
@@ -247,7 +247,8 @@ static void dwmac1000_get_hw_feature(void __iomem *ioaddr,
	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);
}
+101 −91
Original line number Diff line number Diff line
@@ -71,36 +71,48 @@ static void dwmac4_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
	writel(value, ioaddr + DMA_SYS_BUS_MODE);
}

static void dwmac4_dma_init_channel(void __iomem *ioaddr,
void dwmac4_dma_init_rx_chan(void __iomem *ioaddr,
			     struct stmmac_dma_cfg *dma_cfg,
				    u32 dma_tx_phy, u32 dma_rx_phy,
				    u32 channel)
			     u32 dma_rx_phy, u32 chan)
{
	u32 value;
	int txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
	int rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;

	/* set PBL for each channels. Currently we affect same configuration
	 * on each channel
	 */
	value = readl(ioaddr + DMA_CHAN_CONTROL(channel));
	if (dma_cfg->pblx8)
		value = value | DMA_BUS_MODE_PBL;
	writel(value, ioaddr + DMA_CHAN_CONTROL(channel));
	value = readl(ioaddr + DMA_CHAN_RX_CONTROL(chan));
	value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));

	writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(chan));
}

void dwmac4_dma_init_tx_chan(void __iomem *ioaddr,
			     struct stmmac_dma_cfg *dma_cfg,
			     u32 dma_tx_phy, u32 chan)
{
	u32 value;
	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;

	value = readl(ioaddr + DMA_CHAN_TX_CONTROL(channel));
	value = readl(ioaddr + DMA_CHAN_TX_CONTROL(chan));
	value = value | (txpbl << DMA_BUS_MODE_PBL_SHIFT);
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(channel));
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));

	value = readl(ioaddr + DMA_CHAN_RX_CONTROL(channel));
	value = value | (rxpbl << DMA_BUS_MODE_RPBL_SHIFT);
	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(channel));
	writel(dma_tx_phy, ioaddr + DMA_CHAN_TX_BASE_ADDR(chan));
}

	/* Mask interrupts by writing to CSR7 */
	writel(DMA_CHAN_INTR_DEFAULT_MASK, ioaddr + DMA_CHAN_INTR_ENA(channel));
void dwmac4_dma_init_channel(void __iomem *ioaddr,
			     struct stmmac_dma_cfg *dma_cfg, u32 chan)
{
	u32 value;

	writel(dma_tx_phy, ioaddr + DMA_CHAN_TX_BASE_ADDR(channel));
	writel(dma_rx_phy, ioaddr + DMA_CHAN_RX_BASE_ADDR(channel));
	/* common channel control register config */
	value = readl(ioaddr + DMA_CHAN_CONTROL(chan));
	if (dma_cfg->pblx8)
		value = value | DMA_BUS_MODE_PBL;
	writel(value, ioaddr + DMA_CHAN_CONTROL(chan));

	/* Mask interrupts by writing to CSR7 */
	writel(DMA_CHAN_INTR_DEFAULT_MASK,
	       ioaddr + DMA_CHAN_INTR_ENA(chan));
}

static void dwmac4_dma_init(void __iomem *ioaddr,
@@ -108,7 +120,6 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
			    u32 dma_tx, u32 dma_rx, int atds)
{
	u32 value = readl(ioaddr + DMA_SYS_BUS_MODE);
	int i;

	/* Set the Fixed burst mode */
	if (dma_cfg->fixed_burst)
@@ -122,9 +133,6 @@ static void dwmac4_dma_init(void __iomem *ioaddr,
		value |= DMA_SYS_BUS_AAL;

	writel(value, ioaddr + DMA_SYS_BUS_MODE);

	for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
		dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i);
}

static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel,
@@ -174,78 +182,34 @@ static void dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space)
		_dwmac4_dump_dma_regs(ioaddr, i, reg_space);
}

static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt)
static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 number_chan)
{
	int i;
	u32 chan;

	for (i = 0; i < DMA_CHANNEL_NB_MAX; i++)
		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(i));
	for (chan = 0; chan < number_chan; chan++)
		writel(riwt, ioaddr + DMA_CHAN_RX_WATCHDOG(chan));
}

static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
				    int rxmode, u32 channel, int rxfifosz)
static void dwmac4_dma_rx_chan_op_mode(void __iomem *ioaddr, int mode,
				       u32 channel, int fifosz)
{
	unsigned int rqs = rxfifosz / 256 - 1;
	u32 mtl_tx_op, mtl_rx_op, mtl_rx_int;

	/* Following code only done for channel 0, other channels not yet
	 * supported.
	 */
	mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));

	if (txmode == SF_DMA_MODE) {
		pr_debug("GMAC: enable TX store and forward mode\n");
		/* Transmit COE type 2 cannot be done in cut-through mode. */
		mtl_tx_op |= MTL_OP_MODE_TSF;
	} else {
		pr_debug("GMAC: disabling TX SF (threshold %d)\n", txmode);
		mtl_tx_op &= ~MTL_OP_MODE_TSF;
		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
		/* Set the transmit threshold */
		if (txmode <= 32)
			mtl_tx_op |= MTL_OP_MODE_TTC_32;
		else if (txmode <= 64)
			mtl_tx_op |= MTL_OP_MODE_TTC_64;
		else if (txmode <= 96)
			mtl_tx_op |= MTL_OP_MODE_TTC_96;
		else if (txmode <= 128)
			mtl_tx_op |= MTL_OP_MODE_TTC_128;
		else if (txmode <= 192)
			mtl_tx_op |= MTL_OP_MODE_TTC_192;
		else if (txmode <= 256)
			mtl_tx_op |= MTL_OP_MODE_TTC_256;
		else if (txmode <= 384)
			mtl_tx_op |= MTL_OP_MODE_TTC_384;
		else
			mtl_tx_op |= MTL_OP_MODE_TTC_512;
	}
	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
	 * with reset values: TXQEN off, TQS 256 bytes.
	 *
	 * Write the bits in both cases, since it will have no effect when RO.
	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
	 * be RO, however, writing the whole TQS field will result in a value
	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
	 */
	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
	unsigned int rqs = fifosz / 256 - 1;
	u32 mtl_rx_op, mtl_rx_int;

	mtl_rx_op = readl(ioaddr + MTL_CHAN_RX_OP_MODE(channel));

	if (rxmode == SF_DMA_MODE) {
	if (mode == SF_DMA_MODE) {
		pr_debug("GMAC: enable RX store and forward mode\n");
		mtl_rx_op |= MTL_OP_MODE_RSF;
	} else {
		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", rxmode);
		pr_debug("GMAC: disable RX SF mode (threshold %d)\n", mode);
		mtl_rx_op &= ~MTL_OP_MODE_RSF;
		mtl_rx_op &= MTL_OP_MODE_RTC_MASK;
		if (rxmode <= 32)
		if (mode <= 32)
			mtl_rx_op |= MTL_OP_MODE_RTC_32;
		else if (rxmode <= 64)
		else if (mode <= 64)
			mtl_rx_op |= MTL_OP_MODE_RTC_64;
		else if (rxmode <= 96)
		else if (mode <= 96)
			mtl_rx_op |= MTL_OP_MODE_RTC_96;
		else
			mtl_rx_op |= MTL_OP_MODE_RTC_128;
@@ -255,7 +219,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
	mtl_rx_op |= rqs << MTL_OP_MODE_RQS_SHIFT;

	/* enable flow control only if each channel gets 4 KiB or more FIFO */
	if (rxfifosz >= 4096) {
	if (fifosz >= 4096) {
		unsigned int rfd, rfa;

		mtl_rx_op |= MTL_OP_MODE_EHFC;
@@ -266,7 +230,7 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
		 * Set Threshold for Deactivating Flow Control to min 1 frame,
		 * i.e. 1500 bytes.
		 */
		switch (rxfifosz) {
		switch (fifosz) {
		case 4096:
			/* This violates the above formula because of FIFO size
			 * limit therefore overflow may occur in spite of this.
@@ -306,11 +270,49 @@ static void dwmac4_dma_chan_op_mode(void __iomem *ioaddr, int txmode,
	       ioaddr + MTL_CHAN_INT_CTRL(channel));
}

static void dwmac4_dma_operation_mode(void __iomem *ioaddr, int txmode,
				      int rxmode, int rxfifosz)
static void dwmac4_dma_tx_chan_op_mode(void __iomem *ioaddr, int mode,
				       u32 channel)
{
	/* Only Channel 0 is actually configured and used */
	dwmac4_dma_chan_op_mode(ioaddr, txmode, rxmode, 0, rxfifosz);
	u32 mtl_tx_op = readl(ioaddr + MTL_CHAN_TX_OP_MODE(channel));

	if (mode == SF_DMA_MODE) {
		pr_debug("GMAC: enable TX store and forward mode\n");
		/* Transmit COE type 2 cannot be done in cut-through mode. */
		mtl_tx_op |= MTL_OP_MODE_TSF;
	} else {
		pr_debug("GMAC: disabling TX SF (threshold %d)\n", mode);
		mtl_tx_op &= ~MTL_OP_MODE_TSF;
		mtl_tx_op &= MTL_OP_MODE_TTC_MASK;
		/* Set the transmit threshold */
		if (mode <= 32)
			mtl_tx_op |= MTL_OP_MODE_TTC_32;
		else if (mode <= 64)
			mtl_tx_op |= MTL_OP_MODE_TTC_64;
		else if (mode <= 96)
			mtl_tx_op |= MTL_OP_MODE_TTC_96;
		else if (mode <= 128)
			mtl_tx_op |= MTL_OP_MODE_TTC_128;
		else if (mode <= 192)
			mtl_tx_op |= MTL_OP_MODE_TTC_192;
		else if (mode <= 256)
			mtl_tx_op |= MTL_OP_MODE_TTC_256;
		else if (mode <= 384)
			mtl_tx_op |= MTL_OP_MODE_TTC_384;
		else
			mtl_tx_op |= MTL_OP_MODE_TTC_512;
	}
	/* For an IP with DWC_EQOS_NUM_TXQ == 1, the fields TXQEN and TQS are RO
	 * with reset values: TXQEN on, TQS == DWC_EQOS_TXFIFO_SIZE.
	 * For an IP with DWC_EQOS_NUM_TXQ > 1, the fields TXQEN and TQS are R/W
	 * with reset values: TXQEN off, TQS 256 bytes.
	 *
	 * Write the bits in both cases, since it will have no effect when RO.
	 * For DWC_EQOS_NUM_TXQ > 1, the top bits in MTL_OP_MODE_TQS_MASK might
	 * be RO, however, writing the whole TQS field will result in a value
	 * equal to DWC_EQOS_TXFIFO_SIZE, just like for DWC_EQOS_NUM_TXQ == 1.
	 */
	mtl_tx_op |= MTL_OP_MODE_TXQEN | MTL_OP_MODE_TQS_MASK;
	writel(mtl_tx_op, ioaddr +  MTL_CHAN_TX_OP_MODE(channel));
}

static void dwmac4_get_hw_feature(void __iomem *ioaddr,
@@ -385,9 +387,13 @@ static void dwmac4_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
const struct stmmac_dma_ops dwmac4_dma_ops = {
	.reset = dwmac4_dma_reset,
	.init = dwmac4_dma_init,
	.init_chan = dwmac4_dma_init_channel,
	.init_rx_chan = dwmac4_dma_init_rx_chan,
	.init_tx_chan = dwmac4_dma_init_tx_chan,
	.axi = dwmac4_dma_axi,
	.dump_regs = dwmac4_dump_dma_regs,
	.dma_mode = dwmac4_dma_operation_mode,
	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
	.enable_dma_irq = dwmac4_enable_dma_irq,
	.disable_dma_irq = dwmac4_disable_dma_irq,
	.start_tx = dwmac4_dma_start_tx,
@@ -407,9 +413,13 @@ const struct stmmac_dma_ops dwmac4_dma_ops = {
const struct stmmac_dma_ops dwmac410_dma_ops = {
	.reset = dwmac4_dma_reset,
	.init = dwmac4_dma_init,
	.init_chan = dwmac4_dma_init_channel,
	.init_rx_chan = dwmac4_dma_init_rx_chan,
	.init_tx_chan = dwmac4_dma_init_tx_chan,
	.axi = dwmac4_dma_axi,
	.dump_regs = dwmac4_dump_dma_regs,
	.dma_mode = dwmac4_dma_operation_mode,
	.dma_rx_mode = dwmac4_dma_rx_chan_op_mode,
	.dma_tx_mode = dwmac4_dma_tx_chan_op_mode,
	.enable_dma_irq = dwmac410_enable_dma_irq,
	.disable_dma_irq = dwmac4_disable_dma_irq,
	.start_tx = dwmac4_dma_start_tx,
+10 −10
Original line number Diff line number Diff line
@@ -185,17 +185,17 @@

int dwmac4_dma_reset(void __iomem *ioaddr);
void dwmac4_enable_dma_transmission(void __iomem *ioaddr, u32 tail_ptr);
void dwmac4_enable_dma_irq(void __iomem *ioaddr);
void dwmac410_enable_dma_irq(void __iomem *ioaddr);
void dwmac4_disable_dma_irq(void __iomem *ioaddr);
void dwmac4_dma_start_tx(void __iomem *ioaddr);
void dwmac4_dma_stop_tx(void __iomem *ioaddr);
void dwmac4_dma_start_rx(void __iomem *ioaddr);
void dwmac4_dma_stop_rx(void __iomem *ioaddr);
void dwmac4_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac410_enable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac4_disable_dma_irq(void __iomem *ioaddr, u32 chan);
void dwmac4_dma_start_tx(void __iomem *ioaddr, u32 chan);
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);
void dwmac4_set_rx_ring_len(void __iomem *ioaddr, u32 len);
void dwmac4_set_tx_ring_len(void __iomem *ioaddr, u32 len);
			 struct stmmac_extra_stats *x, u32 chan);
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);
void dwmac4_set_tx_tail_ptr(void __iomem *ioaddr, u32 tail_ptr, u32 chan);

+28 −28
Original line number Diff line number Diff line
@@ -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)
{
	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)
{
	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;
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));

	value = readl(ioaddr + GMAC_CONFIG);
	value |= GMAC_CONFIG_TE;
	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;
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(STMMAC_CHAN0));
	writel(value, ioaddr + DMA_CHAN_TX_CONTROL(chan));

	value = readl(ioaddr + GMAC_CONFIG);
	value &= ~GMAC_CONFIG_TE;
	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;

	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));

	value = readl(ioaddr + GMAC_CONFIG);
	value |= GMAC_CONFIG_RE;
	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;
	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(STMMAC_CHAN0));
	writel(value, ioaddr + DMA_CHAN_RX_CONTROL(chan));

	value = readl(ioaddr + GMAC_CONFIG);
	value &= ~GMAC_CONFIG_RE;
	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 +
	       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,
	       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,
			 struct stmmac_extra_stats *x)
			 struct stmmac_extra_stats *x, u32 chan)
{
	int ret = 0;

	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(0));
	u32 intr_status = readl(ioaddr + DMA_CHAN_STATUS(chan));

	/* ABNORMAL interrupts */
	if (unlikely(intr_status & DMA_CHAN_STATUS_AIS)) {
@@ -153,7 +153,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
		if (likely(intr_status & DMA_CHAN_STATUS_RI)) {
			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. */
			if (likely(value & DMA_CHAN_INTR_ENA_RIE)) {
				x->rx_normal_irq_n++;
@@ -172,7 +172,7 @@ int dwmac4_dma_interrupt(void __iomem *ioaddr,
	 * status [21-0] expect reserved bits [5-3]
	 */
	writel((intr_status & 0x3fffc7),
	       ioaddr + DMA_CHAN_STATUS(STMMAC_CHAN0));
	       ioaddr + DMA_CHAN_STATUS(chan));

	return ret;
}
Loading