OSDN Git Service

net: stmmac: Add DMA related callbacks for XGMAC2
authorJose Abreu <Jose.Abreu@synopsys.com>
Wed, 8 Aug 2018 08:04:31 +0000 (09:04 +0100)
committerDavid S. Miller <davem@davemloft.net>
Thu, 9 Aug 2018 18:16:28 +0000 (11:16 -0700)
Add the DMA related callbacks for the new IP block XGMAC2.

Signed-off-by: Jose Abreu <joabreu@synopsys.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Joao Pinto <jpinto@synopsys.com>
Cc: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Cc: Alexandre Torgue <alexandre.torgue@st.com>
Cc: Florian Fainelli <f.fainelli@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
drivers/net/ethernet/stmicro/stmmac/Makefile
drivers/net/ethernet/stmicro/stmmac/dwxgmac2.h
drivers/net/ethernet/stmicro/stmmac/dwxgmac2_dma.c [new file with mode: 0644]
drivers/net/ethernet/stmicro/stmmac/hwif.c
drivers/net/ethernet/stmicro/stmmac/hwif.h

index a6cf632..da40d3b 100644 (file)
@@ -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
index 7832571..a699233 100644 (file)
 #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_BLEN                     GENMASK(7, 1)
+#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 (file)
index 0000000..2090903
--- /dev/null
@@ -0,0 +1,411 @@
+// 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;
+
+       value &= ~XGMAC_BLEN;
+       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,
+};
index 4fa46f0..4030199 100644 (file)
@@ -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,
index ff0fd69..3106eac 100644 (file)
@@ -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 */