lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <d9e24b8e99e4e5bec5906c9aa818b02bd0779364.1533125016.git.joabreu@synopsys.com>
Date:   Wed,  1 Aug 2018 13:10:31 +0100
From:   Jose Abreu <Jose.Abreu@...opsys.com>
To:     netdev@...r.kernel.org
Cc:     Jose Abreu <Jose.Abreu@...opsys.com>,
        "David S. Miller" <davem@...emloft.net>,
        Joao Pinto <Joao.Pinto@...opsys.com>,
        Giuseppe Cavallaro <peppe.cavallaro@...com>,
        Alexandre Torgue <alexandre.torgue@...com>
Subject: [PATCH net-next 3/9] net: stmmac: Add DMA related callbacks for XGMAC2

Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu <joabreu@...opsys.com>
Cc: David S. Miller <davem@...emloft.net>
Cc: Joao Pinto <jpinto@...opsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@...com>
Cc: Alexandre Torgue <alexandre.torgue@...com>
---
 drivers/net/ethernet/stmicro/stmmac/Makefile       |   2 +-
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h     |  56 +++
 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c | 410 +++++++++++++++++++++
 drivers/net/ethernet/stmicro/stmmac/hwif.c         |   2 +-
 drivers/net/ethernet/stmicro/stmmac/hwif.h         |   1 +
 5 files changed, 469 insertions(+), 2 deletions(-)
 create mode 100644 drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c

diff --git a/drivers/net/ethernet/stmicro/stmmac/Makefile b/drivers/net/ethernet/stmicro/stmmac/Makefile
index a6cf632c9592..da40d3bba037 100644
--- a/drivers/net/ethernet/stmicro/stmmac/Makefile
+++ b/drivers/net/ethernet/stmicro/stmmac/Makefile
@@ -5,7 +5,7 @@ stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o ring_mode.o	\
 	      dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o	\
 	      mmc_core.o stmmac_hwtstamp.o stmmac_ptp.o dwmac4_descs.o	\
 	      dwmac4_dma.o dwmac4_lib.o dwmac4_core.o dwmac5.o hwif.o \
-	      stmmac_tc.o dwxgmac2_core.o $(stmmac-y)
+	      stmmac_tc.o dwxgmac2_core.o dwxgmac2_dma.o $(stmmac-y)
 
 # Ordering matters. Generic driver must be last.
 obj-$(CONFIG_STMMAC_PLATFORM)	+= stmmac-platform.o
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
index ef63a62a699d..69d225a9c890 100644
--- a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
@@ -137,4 +137,60 @@
 #define XGMAC_ABPSIS			BIT(1)
 #define XGMAC_TXUNFIS			BIT(0)
 
+/* DMA Registers */
+#define XGMAC_DMA_MODE			0x00003000
+#define XGMAC_SWR			BIT(0)
+#define XGMAC_DMA_SYSBUS_MODE		0x00003004
+#define XGMAC_WR_OSR_LMT		GENMASK(29, 24)
+#define XGMAC_WR_OSR_LMT_SHIFT		24
+#define XGMAC_RD_OSR_LMT		GENMASK(21, 16)
+#define XGMAC_RD_OSR_LMT_SHIFT		16
+#define XGMAC_EN_LPI			BIT(15)
+#define XGMAC_LPI_XIT_PKT		BIT(14)
+#define XGMAC_AAL			BIT(12)
+#define XGMAC_BLEN256			BIT(7)
+#define XGMAC_BLEN128			BIT(6)
+#define XGMAC_BLEN64			BIT(5)
+#define XGMAC_BLEN32			BIT(4)
+#define XGMAC_BLEN16			BIT(3)
+#define XGMAC_BLEN8			BIT(2)
+#define XGMAC_BLEN4			BIT(1)
+#define XGMAC_UNDEF			BIT(0)
+#define XGMAC_DMA_CH_CONTROL(x)		(0x00003100 + (0x80 * (x)))
+#define XGMAC_PBLx8			BIT(16)
+#define XGMAC_DMA_CH_TX_CONTROL(x)	(0x00003104 + (0x80 * (x)))
+#define XGMAC_TxPBL			GENMASK(21, 16)
+#define XGMAC_TxPBL_SHIFT		16
+#define XGMAC_TSE			BIT(12)
+#define XGMAC_OSP			BIT(4)
+#define XGMAC_TXST			BIT(0)
+#define XGMAC_DMA_CH_RX_CONTROL(x)	(0x00003108 + (0x80 * (x)))
+#define XGMAC_RxPBL			GENMASK(21, 16)
+#define XGMAC_RxPBL_SHIFT		16
+#define XGMAC_RXST			BIT(0)
+#define XGMAC_DMA_CH_TxDESC_LADDR(x)	(0x00003114 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_LADDR(x)	(0x0000311c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_TAIL_LPTR(x)	(0x00003124 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_TAIL_LPTR(x)	(0x0000312c + (0x80 * (x)))
+#define XGMAC_DMA_CH_TxDESC_RING_LEN(x)		(0x00003130 + (0x80 * (x)))
+#define XGMAC_DMA_CH_RxDESC_RING_LEN(x)		(0x00003134 + (0x80 * (x)))
+#define XGMAC_DMA_CH_INT_EN(x)		(0x00003138 + (0x80 * (x)))
+#define XGMAC_NIE			BIT(15)
+#define XGMAC_AIE			BIT(14)
+#define XGMAC_RBUE			BIT(7)
+#define XGMAC_RIE			BIT(6)
+#define XGMAC_TIE			BIT(0)
+#define XGMAC_DMA_INT_DEFAULT_EN	(XGMAC_NIE | XGMAC_AIE | XGMAC_RBUE | \
+					XGMAC_RIE | XGMAC_TIE)
+#define XGMAC_DMA_CH_Rx_WATCHDOG(x)	(0x0000313c + (0x80 * (x)))
+#define XGMAC_RWT			GENMASK(7, 0)
+#define XGMAC_DMA_CH_STATUS(x)		(0x00003160 + (0x80 * (x)))
+#define XGMAC_NIS			BIT(15)
+#define XGMAC_AIS			BIT(14)
+#define XGMAC_FBE			BIT(12)
+#define XGMAC_RBU			BIT(7)
+#define XGMAC_RI			BIT(6)
+#define XGMAC_TPS			BIT(1)
+#define XGMAC_TI			BIT(0)
+
 #endif /* __STMMAC_DWXGMAC2_H__ */
diff --git a/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
new file mode 100644
index 000000000000..50d9fffc32b5
--- /dev/null
+++ b/drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c
@@ -0,0 +1,410 @@
+// SPDX-License-Identifier: (GPL-2.0 OR MIT)
+/*
+ * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
+ * stmmac XGMAC support.
+ */
+
+#include <linux/iopoll.h>
+#include "stmmac.h"
+#include "dwxgmac2.h"
+
+static int dwxgmac2_dma_reset(void __iomem *ioaddr)
+{
+	u32 value = readl(ioaddr + XGMAC_DMA_MODE);
+
+	/* DMA SW reset */
+	writel(value | XGMAC_SWR, ioaddr + XGMAC_DMA_MODE);
+
+	return readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
+				  !(value & XGMAC_SWR), 0, 100000);
+}
+
+static void dwxgmac2_dma_init(void __iomem *ioaddr,
+			      struct stmmac_dma_cfg *dma_cfg, int atds)
+{
+	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
+
+	if (dma_cfg->aal)
+		value |= XGMAC_AAL;
+
+	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
+}
+
+static void dwxgmac2_dma_init_chan(void __iomem *ioaddr,
+				   struct stmmac_dma_cfg *dma_cfg, u32 chan)
+{
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+
+	if (dma_cfg->pblx8)
+		value |= XGMAC_PBLx8;
+
+	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
+	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+}
+
+static void dwxgmac2_dma_init_rx_chan(void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 dma_rx_phy, u32 chan)
+{
+	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value &= ~XGMAC_RxPBL;
+	value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+
+	writel(dma_rx_phy, ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
+}
+
+static void dwxgmac2_dma_init_tx_chan(void __iomem *ioaddr,
+				      struct stmmac_dma_cfg *dma_cfg,
+				      u32 dma_tx_phy, u32 chan)
+{
+	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value &= ~XGMAC_TxPBL;
+	value |= (txpbl << XGMAC_TxPBL_SHIFT) & XGMAC_TxPBL;
+	value |= XGMAC_OSP;
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	writel(dma_tx_phy, ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
+}
+
+static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
+{
+	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
+	int i;
+
+	if (axi->axi_lpi_en)
+		value |= XGMAC_EN_LPI;
+	if (axi->axi_xit_frm)
+		value |= XGMAC_LPI_XIT_PKT;
+
+	value &= ~XGMAC_WR_OSR_LMT;
+	value |= (axi->axi_wr_osr_lmt << XGMAC_WR_OSR_LMT_SHIFT) &
+		XGMAC_WR_OSR_LMT;
+
+	value &= ~XGMAC_RD_OSR_LMT;
+	value |= (axi->axi_rd_osr_lmt << XGMAC_RD_OSR_LMT_SHIFT) &
+		XGMAC_RD_OSR_LMT;
+
+	for (i = 0; i < AXI_BLEN; i++) {
+		if (axi->axi_blen[i])
+			value &= ~XGMAC_UNDEF;
+
+		switch (axi->axi_blen[i]) {
+		case 256:
+			value |= XGMAC_BLEN256;
+			break;
+		case 128:
+			value |= XGMAC_BLEN128;
+			break;
+		case 64:
+			value |= XGMAC_BLEN64;
+			break;
+		case 32:
+			value |= XGMAC_BLEN32;
+			break;
+		case 16:
+			value |= XGMAC_BLEN16;
+			break;
+		case 8:
+			value |= XGMAC_BLEN8;
+			break;
+		case 4:
+			value |= XGMAC_BLEN4;
+			break;
+		}
+	}
+
+	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
+}
+
+static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
+				 u32 channel, int fifosz, u8 qmode)
+{
+	u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+	unsigned int rqs = fifosz / 256 - 1;
+
+	if (mode == SF_DMA_MODE) {
+		value |= XGMAC_RSF;
+	} else {
+		value &= ~XGMAC_RSF;
+		value &= ~XGMAC_RTC;
+
+		if (mode <= 64)
+			value |= 0x0 << XGMAC_RTC_SHIFT;
+		else if (mode <= 96)
+			value |= 0x2 << XGMAC_RTC_SHIFT;
+		else
+			value |= 0x3 << XGMAC_RTC_SHIFT;
+	}
+
+	value &= ~XGMAC_RQS;
+	value |= (rqs << XGMAC_RQS_SHIFT) & XGMAC_RQS;
+
+	writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
+
+	/* Enable MTL RX overflow */
+	value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
+	writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
+}
+
+static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
+				 u32 channel, int fifosz, u8 qmode)
+{
+	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
+	unsigned int tqs = fifosz / 256 - 1;
+
+	if (mode == SF_DMA_MODE) {
+		value |= XGMAC_TSF;
+	} else {
+		value &= ~XGMAC_TSF;
+		value &= ~XGMAC_TTC;
+
+		if (mode <= 64)
+			value |= 0x0 << XGMAC_TTC_SHIFT;
+		else if (mode <= 96)
+			value |= 0x2 << XGMAC_TTC_SHIFT;
+		else if (mode <= 128)
+			value |= 0x3 << XGMAC_TTC_SHIFT;
+		else if (mode <= 192)
+			value |= 0x4 << XGMAC_TTC_SHIFT;
+		else if (mode <= 256)
+			value |= 0x5 << XGMAC_TTC_SHIFT;
+		else if (mode <= 384)
+			value |= 0x6 << XGMAC_TTC_SHIFT;
+		else
+			value |= 0x7 << XGMAC_TTC_SHIFT;
+	}
+
+	value &= ~XGMAC_TXQEN;
+	if (qmode != MTL_QUEUE_AVB)
+		value |= 0x2 << XGMAC_TXQEN_SHIFT;
+	else
+		value |= 0x1 << XGMAC_TXQEN_SHIFT;
+
+	value &= ~XGMAC_TQS;
+	value |= (tqs << XGMAC_TQS_SHIFT) & XGMAC_TQS;
+
+	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
+}
+
+static void dwxgmac2_enable_dma_irq(void __iomem *ioaddr, u32 chan)
+{
+	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+}
+
+static void dwxgmac2_disable_dma_irq(void __iomem *ioaddr, u32 chan)
+{
+	writel(0, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+}
+
+static void dwxgmac2_dma_start_tx(void __iomem *ioaddr, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value |= XGMAC_TXST;
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	value = readl(ioaddr + XGMAC_TX_CONFIG);
+	value |= XGMAC_CONFIG_TE;
+	writel(value, ioaddr + XGMAC_TX_CONFIG);
+}
+
+static void dwxgmac2_dma_stop_tx(void __iomem *ioaddr, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+	value &= ~XGMAC_TXST;
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	value = readl(ioaddr + XGMAC_TX_CONFIG);
+	value &= ~XGMAC_CONFIG_TE;
+	writel(value, ioaddr + XGMAC_TX_CONFIG);
+}
+
+static void dwxgmac2_dma_start_rx(void __iomem *ioaddr, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value |= XGMAC_RXST;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+
+	value = readl(ioaddr + XGMAC_RX_CONFIG);
+	value |= XGMAC_CONFIG_RE;
+	writel(value, ioaddr + XGMAC_RX_CONFIG);
+}
+
+static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value &= ~XGMAC_RXST;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+
+	value = readl(ioaddr + XGMAC_RX_CONFIG);
+	value &= ~XGMAC_CONFIG_RE;
+	writel(value, ioaddr + XGMAC_RX_CONFIG);
+}
+
+static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
+				  struct stmmac_extra_stats *x, u32 chan)
+{
+	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
+	int ret = 0;
+
+	/* ABNORMAL interrupts */
+	if (unlikely(intr_status & XGMAC_AIS)) {
+		if (unlikely(intr_status & XGMAC_TPS)) {
+			x->tx_process_stopped_irq++;
+			ret |= tx_hard_error;
+		}
+		if (unlikely(intr_status & XGMAC_FBE)) {
+			x->fatal_bus_error_irq++;
+			ret |= tx_hard_error;
+		}
+	}
+
+	/* TX/RX NORMAL interrupts */
+	if (likely(intr_status & XGMAC_NIS)) {
+		x->normal_irq_n++;
+
+		if (likely(intr_status & XGMAC_RI)) {
+			u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
+			if (likely(value & XGMAC_RIE)) {
+				x->rx_normal_irq_n++;
+				ret |= handle_rx;
+			}
+		}
+		if (likely(intr_status & XGMAC_TI)) {
+			x->tx_normal_irq_n++;
+			ret |= handle_tx;
+		}
+	}
+
+	/* Clear interrupts */
+	writel(~0x0, ioaddr + XGMAC_DMA_CH_STATUS(chan));
+
+	return ret;
+}
+
+static void dwxgmac2_get_hw_feature(void __iomem *ioaddr,
+				    struct dma_features *dma_cap)
+{
+	u32 hw_cap;
+
+	/*  MAC HW feature 0 */
+	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
+	dma_cap->rx_coe = (hw_cap & XGMAC_HWFEAT_RXCOESEL) >> 16;
+	dma_cap->tx_coe = (hw_cap & XGMAC_HWFEAT_TXCOESEL) >> 14;
+	dma_cap->atime_stamp = (hw_cap & XGMAC_HWFEAT_TSSEL) >> 12;
+	dma_cap->av = (hw_cap & XGMAC_HWFEAT_AVSEL) >> 11;
+	dma_cap->av &= (hw_cap & XGMAC_HWFEAT_RAVSEL) >> 10;
+	dma_cap->pmt_magic_frame = (hw_cap & XGMAC_HWFEAT_MGKSEL) >> 7;
+	dma_cap->pmt_remote_wake_up = (hw_cap & XGMAC_HWFEAT_RWKSEL) >> 6;
+	dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
+
+	/* MAC HW feature 1 */
+	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
+	dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;
+	dma_cap->tx_fifo_size =
+		128 << ((hw_cap & XGMAC_HWFEAT_TXFIFOSIZE) >> 6);
+	dma_cap->rx_fifo_size =
+		128 << ((hw_cap & XGMAC_HWFEAT_RXFIFOSIZE) >> 0);
+
+	/* MAC HW feature 2 */
+	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2);
+	dma_cap->pps_out_num = (hw_cap & XGMAC_HWFEAT_PPSOUTNUM) >> 24;
+	dma_cap->number_tx_channel =
+		((hw_cap & XGMAC_HWFEAT_TXCHCNT) >> 18) + 1;
+	dma_cap->number_rx_channel =
+		((hw_cap & XGMAC_HWFEAT_RXCHCNT) >> 12) + 1;
+	dma_cap->number_tx_queues =
+		((hw_cap & XGMAC_HWFEAT_TXQCNT) >> 6) + 1;
+	dma_cap->number_rx_queues =
+		((hw_cap & XGMAC_HWFEAT_RXQCNT) >> 0) + 1;
+}
+
+static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 nchan)
+{
+	u32 i;
+
+	for (i = 0; i < nchan; i++)
+		writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(i));
+}
+
+static void dwxgmac2_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
+{
+	writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
+}
+
+static void dwxgmac2_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
+{
+	writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
+}
+
+static void dwxgmac2_set_rx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
+{
+	writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
+}
+
+static void dwxgmac2_set_tx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
+{
+	writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
+}
+
+static void dwxgmac2_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
+{
+	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+
+	if (en)
+		value |= XGMAC_TSE;
+	else 
+		value &= ~XGMAC_TSE;
+
+	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
+}
+
+static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
+{
+	u32 value;
+
+	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+	value |= bfsize << 1;
+	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
+}
+
+const struct stmmac_dma_ops dwxgmac210_dma_ops = {
+	.reset = dwxgmac2_dma_reset,
+	.init = dwxgmac2_dma_init,
+	.init_chan = dwxgmac2_dma_init_chan,
+	.init_rx_chan = dwxgmac2_dma_init_rx_chan,
+	.init_tx_chan = dwxgmac2_dma_init_tx_chan,
+	.axi = dwxgmac2_dma_axi,
+	.dump_regs = NULL,
+	.dma_rx_mode = dwxgmac2_dma_rx_mode,
+	.dma_tx_mode = dwxgmac2_dma_tx_mode,
+	.enable_dma_irq = dwxgmac2_enable_dma_irq,
+	.disable_dma_irq = dwxgmac2_disable_dma_irq,
+	.start_tx = dwxgmac2_dma_start_tx,
+	.stop_tx = dwxgmac2_dma_stop_tx,
+	.start_rx = dwxgmac2_dma_start_rx,
+	.stop_rx = dwxgmac2_dma_stop_rx,
+	.dma_interrupt = dwxgmac2_dma_interrupt,
+	.get_hw_feature = dwxgmac2_get_hw_feature,
+	.rx_watchdog = dwxgmac2_rx_watchdog,
+	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
+	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
+	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
+	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
+	.enable_tso = dwxgmac2_enable_tso,
+	.set_bfsize = dwxgmac2_set_bfsize,
+};
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.c b/drivers/net/ethernet/stmicro/stmmac/hwif.c
index 4fa46f064720..4030199aee7b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.c
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.c
@@ -197,7 +197,7 @@ static const struct stmmac_hwif_entry {
 			.mmc_off = 0,
 		},
 		.desc = NULL,
-		.dma = NULL,
+		.dma = &dwxgmac210_dma_ops,
 		.mac = &dwxgmac210_ops,
 		.hwtimestamp = NULL,
 		.mode = NULL,
diff --git a/drivers/net/ethernet/stmicro/stmmac/hwif.h b/drivers/net/ethernet/stmicro/stmmac/hwif.h
index ff0fd6978260..3106eaca60cd 100644
--- a/drivers/net/ethernet/stmicro/stmmac/hwif.h
+++ b/drivers/net/ethernet/stmicro/stmmac/hwif.h
@@ -480,6 +480,7 @@ extern const struct stmmac_dma_ops dwmac410_dma_ops;
 extern const struct stmmac_ops dwmac510_ops;
 extern const struct stmmac_tc_ops dwmac510_tc_ops;
 extern const struct stmmac_ops dwxgmac210_ops;
+extern const struct stmmac_dma_ops dwxgmac210_dma_ops;
 
 #define GMAC_VERSION		0x00000020	/* GMAC CORE Version */
 #define GMAC4_VERSION		0x00000110	/* GMAC4+ CORE Version */
-- 
2.7.4


Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ