Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: (GPL-2.0 OR MIT)
0002 /*
0003  * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
0004  * stmmac XGMAC support.
0005  */
0006 
0007 #include <linux/iopoll.h>
0008 #include "stmmac.h"
0009 #include "dwxgmac2.h"
0010 
0011 static int dwxgmac2_dma_reset(void __iomem *ioaddr)
0012 {
0013     u32 value = readl(ioaddr + XGMAC_DMA_MODE);
0014 
0015     /* DMA SW reset */
0016     writel(value | XGMAC_SWR, ioaddr + XGMAC_DMA_MODE);
0017 
0018     return readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
0019                   !(value & XGMAC_SWR), 0, 100000);
0020 }
0021 
0022 static void dwxgmac2_dma_init(void __iomem *ioaddr,
0023                   struct stmmac_dma_cfg *dma_cfg, int atds)
0024 {
0025     u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
0026 
0027     if (dma_cfg->aal)
0028         value |= XGMAC_AAL;
0029 
0030     if (dma_cfg->eame)
0031         value |= XGMAC_EAME;
0032 
0033     writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
0034 }
0035 
0036 static void dwxgmac2_dma_init_chan(void __iomem *ioaddr,
0037                    struct stmmac_dma_cfg *dma_cfg, u32 chan)
0038 {
0039     u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
0040 
0041     if (dma_cfg->pblx8)
0042         value |= XGMAC_PBLx8;
0043 
0044     writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
0045     writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0046 }
0047 
0048 static void dwxgmac2_dma_init_rx_chan(void __iomem *ioaddr,
0049                       struct stmmac_dma_cfg *dma_cfg,
0050                       dma_addr_t phy, u32 chan)
0051 {
0052     u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
0053     u32 value;
0054 
0055     value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0056     value &= ~XGMAC_RxPBL;
0057     value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL;
0058     writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0059 
0060     writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
0061     writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
0062 }
0063 
0064 static void dwxgmac2_dma_init_tx_chan(void __iomem *ioaddr,
0065                       struct stmmac_dma_cfg *dma_cfg,
0066                       dma_addr_t phy, u32 chan)
0067 {
0068     u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
0069     u32 value;
0070 
0071     value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0072     value &= ~XGMAC_TxPBL;
0073     value |= (txpbl << XGMAC_TxPBL_SHIFT) & XGMAC_TxPBL;
0074     value |= XGMAC_OSP;
0075     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0076 
0077     writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
0078     writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
0079 }
0080 
0081 static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
0082 {
0083     u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
0084     int i;
0085 
0086     if (axi->axi_lpi_en)
0087         value |= XGMAC_EN_LPI;
0088     if (axi->axi_xit_frm)
0089         value |= XGMAC_LPI_XIT_PKT;
0090 
0091     value &= ~XGMAC_WR_OSR_LMT;
0092     value |= (axi->axi_wr_osr_lmt << XGMAC_WR_OSR_LMT_SHIFT) &
0093         XGMAC_WR_OSR_LMT;
0094 
0095     value &= ~XGMAC_RD_OSR_LMT;
0096     value |= (axi->axi_rd_osr_lmt << XGMAC_RD_OSR_LMT_SHIFT) &
0097         XGMAC_RD_OSR_LMT;
0098 
0099     if (!axi->axi_fb)
0100         value |= XGMAC_UNDEF;
0101 
0102     value &= ~XGMAC_BLEN;
0103     for (i = 0; i < AXI_BLEN; i++) {
0104         switch (axi->axi_blen[i]) {
0105         case 256:
0106             value |= XGMAC_BLEN256;
0107             break;
0108         case 128:
0109             value |= XGMAC_BLEN128;
0110             break;
0111         case 64:
0112             value |= XGMAC_BLEN64;
0113             break;
0114         case 32:
0115             value |= XGMAC_BLEN32;
0116             break;
0117         case 16:
0118             value |= XGMAC_BLEN16;
0119             break;
0120         case 8:
0121             value |= XGMAC_BLEN8;
0122             break;
0123         case 4:
0124             value |= XGMAC_BLEN4;
0125             break;
0126         }
0127     }
0128 
0129     writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
0130     writel(XGMAC_TDPS, ioaddr + XGMAC_TX_EDMA_CTRL);
0131     writel(XGMAC_RDPS, ioaddr + XGMAC_RX_EDMA_CTRL);
0132 }
0133 
0134 static void dwxgmac2_dma_dump_regs(void __iomem *ioaddr, u32 *reg_space)
0135 {
0136     int i;
0137 
0138     for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE; i++)
0139         reg_space[i] = readl(ioaddr + i * 4);
0140 }
0141 
0142 static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
0143                  u32 channel, int fifosz, u8 qmode)
0144 {
0145     u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
0146     unsigned int rqs = fifosz / 256 - 1;
0147 
0148     if (mode == SF_DMA_MODE) {
0149         value |= XGMAC_RSF;
0150     } else {
0151         value &= ~XGMAC_RSF;
0152         value &= ~XGMAC_RTC;
0153 
0154         if (mode <= 64)
0155             value |= 0x0 << XGMAC_RTC_SHIFT;
0156         else if (mode <= 96)
0157             value |= 0x2 << XGMAC_RTC_SHIFT;
0158         else
0159             value |= 0x3 << XGMAC_RTC_SHIFT;
0160     }
0161 
0162     value &= ~XGMAC_RQS;
0163     value |= (rqs << XGMAC_RQS_SHIFT) & XGMAC_RQS;
0164 
0165     if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
0166         u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
0167         unsigned int rfd, rfa;
0168 
0169         value |= XGMAC_EHFC;
0170 
0171         /* Set Threshold for Activating Flow Control to min 2 frames,
0172          * i.e. 1500 * 2 = 3000 bytes.
0173          *
0174          * Set Threshold for Deactivating Flow Control to min 1 frame,
0175          * i.e. 1500 bytes.
0176          */
0177         switch (fifosz) {
0178         case 4096:
0179             /* This violates the above formula because of FIFO size
0180              * limit therefore overflow may occur in spite of this.
0181              */
0182             rfd = 0x03; /* Full-2.5K */
0183             rfa = 0x01; /* Full-1.5K */
0184             break;
0185 
0186         default:
0187             rfd = 0x07; /* Full-4.5K */
0188             rfa = 0x04; /* Full-3K */
0189             break;
0190         }
0191 
0192         flow &= ~XGMAC_RFD;
0193         flow |= rfd << XGMAC_RFD_SHIFT;
0194 
0195         flow &= ~XGMAC_RFA;
0196         flow |= rfa << XGMAC_RFA_SHIFT;
0197 
0198         writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
0199     }
0200 
0201     writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
0202 
0203     /* Enable MTL RX overflow */
0204     value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
0205     writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
0206 }
0207 
0208 static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
0209                  u32 channel, int fifosz, u8 qmode)
0210 {
0211     u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
0212     unsigned int tqs = fifosz / 256 - 1;
0213 
0214     if (mode == SF_DMA_MODE) {
0215         value |= XGMAC_TSF;
0216     } else {
0217         value &= ~XGMAC_TSF;
0218         value &= ~XGMAC_TTC;
0219 
0220         if (mode <= 64)
0221             value |= 0x0 << XGMAC_TTC_SHIFT;
0222         else if (mode <= 96)
0223             value |= 0x2 << XGMAC_TTC_SHIFT;
0224         else if (mode <= 128)
0225             value |= 0x3 << XGMAC_TTC_SHIFT;
0226         else if (mode <= 192)
0227             value |= 0x4 << XGMAC_TTC_SHIFT;
0228         else if (mode <= 256)
0229             value |= 0x5 << XGMAC_TTC_SHIFT;
0230         else if (mode <= 384)
0231             value |= 0x6 << XGMAC_TTC_SHIFT;
0232         else
0233             value |= 0x7 << XGMAC_TTC_SHIFT;
0234     }
0235 
0236     /* Use static TC to Queue mapping */
0237     value |= (channel << XGMAC_Q2TCMAP_SHIFT) & XGMAC_Q2TCMAP;
0238 
0239     value &= ~XGMAC_TXQEN;
0240     if (qmode != MTL_QUEUE_AVB)
0241         value |= 0x2 << XGMAC_TXQEN_SHIFT;
0242     else
0243         value |= 0x1 << XGMAC_TXQEN_SHIFT;
0244 
0245     value &= ~XGMAC_TQS;
0246     value |= (tqs << XGMAC_TQS_SHIFT) & XGMAC_TQS;
0247 
0248     writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
0249 }
0250 
0251 static void dwxgmac2_enable_dma_irq(void __iomem *ioaddr, u32 chan,
0252                     bool rx, bool tx)
0253 {
0254     u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0255 
0256     if (rx)
0257         value |= XGMAC_DMA_INT_DEFAULT_RX;
0258     if (tx)
0259         value |= XGMAC_DMA_INT_DEFAULT_TX;
0260 
0261     writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0262 }
0263 
0264 static void dwxgmac2_disable_dma_irq(void __iomem *ioaddr, u32 chan,
0265                      bool rx, bool tx)
0266 {
0267     u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0268 
0269     if (rx)
0270         value &= ~XGMAC_DMA_INT_DEFAULT_RX;
0271     if (tx)
0272         value &= ~XGMAC_DMA_INT_DEFAULT_TX;
0273 
0274     writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0275 }
0276 
0277 static void dwxgmac2_dma_start_tx(void __iomem *ioaddr, u32 chan)
0278 {
0279     u32 value;
0280 
0281     value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0282     value |= XGMAC_TXST;
0283     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0284 
0285     value = readl(ioaddr + XGMAC_TX_CONFIG);
0286     value |= XGMAC_CONFIG_TE;
0287     writel(value, ioaddr + XGMAC_TX_CONFIG);
0288 }
0289 
0290 static void dwxgmac2_dma_stop_tx(void __iomem *ioaddr, u32 chan)
0291 {
0292     u32 value;
0293 
0294     value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0295     value &= ~XGMAC_TXST;
0296     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0297 
0298     value = readl(ioaddr + XGMAC_TX_CONFIG);
0299     value &= ~XGMAC_CONFIG_TE;
0300     writel(value, ioaddr + XGMAC_TX_CONFIG);
0301 }
0302 
0303 static void dwxgmac2_dma_start_rx(void __iomem *ioaddr, u32 chan)
0304 {
0305     u32 value;
0306 
0307     value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0308     value |= XGMAC_RXST;
0309     writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0310 
0311     value = readl(ioaddr + XGMAC_RX_CONFIG);
0312     value |= XGMAC_CONFIG_RE;
0313     writel(value, ioaddr + XGMAC_RX_CONFIG);
0314 }
0315 
0316 static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan)
0317 {
0318     u32 value;
0319 
0320     value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0321     value &= ~XGMAC_RXST;
0322     writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0323 }
0324 
0325 static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
0326                   struct stmmac_extra_stats *x, u32 chan,
0327                   u32 dir)
0328 {
0329     u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
0330     u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
0331     int ret = 0;
0332 
0333     if (dir == DMA_DIR_RX)
0334         intr_status &= XGMAC_DMA_STATUS_MSK_RX;
0335     else if (dir == DMA_DIR_TX)
0336         intr_status &= XGMAC_DMA_STATUS_MSK_TX;
0337 
0338     /* ABNORMAL interrupts */
0339     if (unlikely(intr_status & XGMAC_AIS)) {
0340         if (unlikely(intr_status & XGMAC_RBU)) {
0341             x->rx_buf_unav_irq++;
0342             ret |= handle_rx;
0343         }
0344         if (unlikely(intr_status & XGMAC_TPS)) {
0345             x->tx_process_stopped_irq++;
0346             ret |= tx_hard_error;
0347         }
0348         if (unlikely(intr_status & XGMAC_FBE)) {
0349             x->fatal_bus_error_irq++;
0350             ret |= tx_hard_error;
0351         }
0352     }
0353 
0354     /* TX/RX NORMAL interrupts */
0355     if (likely(intr_status & XGMAC_NIS)) {
0356         x->normal_irq_n++;
0357 
0358         if (likely(intr_status & XGMAC_RI)) {
0359             x->rx_normal_irq_n++;
0360             ret |= handle_rx;
0361         }
0362         if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
0363             x->tx_normal_irq_n++;
0364             ret |= handle_tx;
0365         }
0366     }
0367 
0368     /* Clear interrupts */
0369     writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(chan));
0370 
0371     return ret;
0372 }
0373 
0374 static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
0375                    struct dma_features *dma_cap)
0376 {
0377     u32 hw_cap;
0378 
0379     /*  MAC HW feature 0 */
0380     hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
0381     dma_cap->vlins = (hw_cap & XGMAC_HWFEAT_SAVLANINS) >> 27;
0382     dma_cap->rx_coe = (hw_cap & XGMAC_HWFEAT_RXCOESEL) >> 16;
0383     dma_cap->tx_coe = (hw_cap & XGMAC_HWFEAT_TXCOESEL) >> 14;
0384     dma_cap->eee = (hw_cap & XGMAC_HWFEAT_EEESEL) >> 13;
0385     dma_cap->atime_stamp = (hw_cap & XGMAC_HWFEAT_TSSEL) >> 12;
0386     dma_cap->av = (hw_cap & XGMAC_HWFEAT_AVSEL) >> 11;
0387     dma_cap->av &= !((hw_cap & XGMAC_HWFEAT_RAVSEL) >> 10);
0388     dma_cap->arpoffsel = (hw_cap & XGMAC_HWFEAT_ARPOFFSEL) >> 9;
0389     dma_cap->rmon = (hw_cap & XGMAC_HWFEAT_MMCSEL) >> 8;
0390     dma_cap->pmt_magic_frame = (hw_cap & XGMAC_HWFEAT_MGKSEL) >> 7;
0391     dma_cap->pmt_remote_wake_up = (hw_cap & XGMAC_HWFEAT_RWKSEL) >> 6;
0392     dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
0393     dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
0394 
0395     /* MAC HW feature 1 */
0396     hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
0397     dma_cap->l3l4fnum = (hw_cap & XGMAC_HWFEAT_L3L4FNUM) >> 27;
0398     dma_cap->hash_tb_sz = (hw_cap & XGMAC_HWFEAT_HASHTBLSZ) >> 24;
0399     dma_cap->rssen = (hw_cap & XGMAC_HWFEAT_RSSEN) >> 20;
0400     dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;
0401     dma_cap->sphen = (hw_cap & XGMAC_HWFEAT_SPHEN) >> 17;
0402 
0403     dma_cap->addr64 = (hw_cap & XGMAC_HWFEAT_ADDR64) >> 14;
0404     switch (dma_cap->addr64) {
0405     case 0:
0406         dma_cap->addr64 = 32;
0407         break;
0408     case 1:
0409         dma_cap->addr64 = 40;
0410         break;
0411     case 2:
0412         dma_cap->addr64 = 48;
0413         break;
0414     default:
0415         dma_cap->addr64 = 32;
0416         break;
0417     }
0418 
0419     dma_cap->tx_fifo_size =
0420         128 << ((hw_cap & XGMAC_HWFEAT_TXFIFOSIZE) >> 6);
0421     dma_cap->rx_fifo_size =
0422         128 << ((hw_cap & XGMAC_HWFEAT_RXFIFOSIZE) >> 0);
0423 
0424     /* MAC HW feature 2 */
0425     hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2);
0426     dma_cap->pps_out_num = (hw_cap & XGMAC_HWFEAT_PPSOUTNUM) >> 24;
0427     dma_cap->number_tx_channel =
0428         ((hw_cap & XGMAC_HWFEAT_TXCHCNT) >> 18) + 1;
0429     dma_cap->number_rx_channel =
0430         ((hw_cap & XGMAC_HWFEAT_RXCHCNT) >> 12) + 1;
0431     dma_cap->number_tx_queues =
0432         ((hw_cap & XGMAC_HWFEAT_TXQCNT) >> 6) + 1;
0433     dma_cap->number_rx_queues =
0434         ((hw_cap & XGMAC_HWFEAT_RXQCNT) >> 0) + 1;
0435 
0436     /* MAC HW feature 3 */
0437     hw_cap = readl(ioaddr + XGMAC_HW_FEATURE3);
0438     dma_cap->tbssel = (hw_cap & XGMAC_HWFEAT_TBSSEL) >> 27;
0439     dma_cap->fpesel = (hw_cap & XGMAC_HWFEAT_FPESEL) >> 26;
0440     dma_cap->estwid = (hw_cap & XGMAC_HWFEAT_ESTWID) >> 23;
0441     dma_cap->estdep = (hw_cap & XGMAC_HWFEAT_ESTDEP) >> 20;
0442     dma_cap->estsel = (hw_cap & XGMAC_HWFEAT_ESTSEL) >> 19;
0443     dma_cap->asp = (hw_cap & XGMAC_HWFEAT_ASP) >> 14;
0444     dma_cap->dvlan = (hw_cap & XGMAC_HWFEAT_DVLAN) >> 13;
0445     dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;
0446     dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9;
0447     dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3;
0448 
0449     return 0;
0450 }
0451 
0452 static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 queue)
0453 {
0454     writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(queue));
0455 }
0456 
0457 static void dwxgmac2_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
0458 {
0459     writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
0460 }
0461 
0462 static void dwxgmac2_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
0463 {
0464     writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
0465 }
0466 
0467 static void dwxgmac2_set_rx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
0468 {
0469     writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
0470 }
0471 
0472 static void dwxgmac2_set_tx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
0473 {
0474     writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
0475 }
0476 
0477 static void dwxgmac2_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
0478 {
0479     u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0480 
0481     if (en)
0482         value |= XGMAC_TSE;
0483     else
0484         value &= ~XGMAC_TSE;
0485 
0486     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0487 }
0488 
0489 static void dwxgmac2_qmode(void __iomem *ioaddr, u32 channel, u8 qmode)
0490 {
0491     u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
0492     u32 flow = readl(ioaddr + XGMAC_RX_FLOW_CTRL);
0493 
0494     value &= ~XGMAC_TXQEN;
0495     if (qmode != MTL_QUEUE_AVB) {
0496         value |= 0x2 << XGMAC_TXQEN_SHIFT;
0497         writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(channel));
0498     } else {
0499         value |= 0x1 << XGMAC_TXQEN_SHIFT;
0500         writel(flow & (~XGMAC_RFE), ioaddr + XGMAC_RX_FLOW_CTRL);
0501     }
0502 
0503     writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
0504 }
0505 
0506 static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
0507 {
0508     u32 value;
0509 
0510     value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0511     value &= ~XGMAC_RBSZ;
0512     value |= bfsize << XGMAC_RBSZ_SHIFT;
0513     writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
0514 }
0515 
0516 static void dwxgmac2_enable_sph(void __iomem *ioaddr, bool en, u32 chan)
0517 {
0518     u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
0519 
0520     value &= ~XGMAC_CONFIG_HDSMS;
0521     value |= XGMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
0522     writel(value, ioaddr + XGMAC_RX_CONFIG);
0523 
0524     value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
0525     if (en)
0526         value |= XGMAC_SPH;
0527     else
0528         value &= ~XGMAC_SPH;
0529     writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
0530 }
0531 
0532 static int dwxgmac2_enable_tbs(void __iomem *ioaddr, bool en, u32 chan)
0533 {
0534     u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0535 
0536     if (en)
0537         value |= XGMAC_EDSE;
0538     else
0539         value &= ~XGMAC_EDSE;
0540 
0541     writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
0542 
0543     value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)) & XGMAC_EDSE;
0544     if (en && !value)
0545         return -EIO;
0546 
0547     writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL0);
0548     writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL1);
0549     writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL2);
0550     writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL3);
0551     return 0;
0552 }
0553 
0554 const struct stmmac_dma_ops dwxgmac210_dma_ops = {
0555     .reset = dwxgmac2_dma_reset,
0556     .init = dwxgmac2_dma_init,
0557     .init_chan = dwxgmac2_dma_init_chan,
0558     .init_rx_chan = dwxgmac2_dma_init_rx_chan,
0559     .init_tx_chan = dwxgmac2_dma_init_tx_chan,
0560     .axi = dwxgmac2_dma_axi,
0561     .dump_regs = dwxgmac2_dma_dump_regs,
0562     .dma_rx_mode = dwxgmac2_dma_rx_mode,
0563     .dma_tx_mode = dwxgmac2_dma_tx_mode,
0564     .enable_dma_irq = dwxgmac2_enable_dma_irq,
0565     .disable_dma_irq = dwxgmac2_disable_dma_irq,
0566     .start_tx = dwxgmac2_dma_start_tx,
0567     .stop_tx = dwxgmac2_dma_stop_tx,
0568     .start_rx = dwxgmac2_dma_start_rx,
0569     .stop_rx = dwxgmac2_dma_stop_rx,
0570     .dma_interrupt = dwxgmac2_dma_interrupt,
0571     .get_hw_feature = dwxgmac2_get_hw_feature,
0572     .rx_watchdog = dwxgmac2_rx_watchdog,
0573     .set_rx_ring_len = dwxgmac2_set_rx_ring_len,
0574     .set_tx_ring_len = dwxgmac2_set_tx_ring_len,
0575     .set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
0576     .set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
0577     .enable_tso = dwxgmac2_enable_tso,
0578     .qmode = dwxgmac2_qmode,
0579     .set_bfsize = dwxgmac2_set_bfsize,
0580     .enable_sph = dwxgmac2_enable_sph,
0581     .enable_tbs = dwxgmac2_enable_tbs,
0582 };