cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dwxgmac2_dma.c (15785B)


      1// SPDX-License-Identifier: (GPL-2.0 OR MIT)
      2/*
      3 * Copyright (c) 2018 Synopsys, Inc. and/or its affiliates.
      4 * stmmac XGMAC support.
      5 */
      6
      7#include <linux/iopoll.h>
      8#include "stmmac.h"
      9#include "dwxgmac2.h"
     10
     11static int dwxgmac2_dma_reset(void __iomem *ioaddr)
     12{
     13	u32 value = readl(ioaddr + XGMAC_DMA_MODE);
     14
     15	/* DMA SW reset */
     16	writel(value | XGMAC_SWR, ioaddr + XGMAC_DMA_MODE);
     17
     18	return readl_poll_timeout(ioaddr + XGMAC_DMA_MODE, value,
     19				  !(value & XGMAC_SWR), 0, 100000);
     20}
     21
     22static void dwxgmac2_dma_init(void __iomem *ioaddr,
     23			      struct stmmac_dma_cfg *dma_cfg, int atds)
     24{
     25	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
     26
     27	if (dma_cfg->aal)
     28		value |= XGMAC_AAL;
     29
     30	if (dma_cfg->eame)
     31		value |= XGMAC_EAME;
     32
     33	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
     34}
     35
     36static void dwxgmac2_dma_init_chan(void __iomem *ioaddr,
     37				   struct stmmac_dma_cfg *dma_cfg, u32 chan)
     38{
     39	u32 value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
     40
     41	if (dma_cfg->pblx8)
     42		value |= XGMAC_PBLx8;
     43
     44	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
     45	writel(XGMAC_DMA_INT_DEFAULT_EN, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
     46}
     47
     48static void dwxgmac2_dma_init_rx_chan(void __iomem *ioaddr,
     49				      struct stmmac_dma_cfg *dma_cfg,
     50				      dma_addr_t phy, u32 chan)
     51{
     52	u32 rxpbl = dma_cfg->rxpbl ?: dma_cfg->pbl;
     53	u32 value;
     54
     55	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
     56	value &= ~XGMAC_RxPBL;
     57	value |= (rxpbl << XGMAC_RxPBL_SHIFT) & XGMAC_RxPBL;
     58	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
     59
     60	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_HADDR(chan));
     61	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_RxDESC_LADDR(chan));
     62}
     63
     64static void dwxgmac2_dma_init_tx_chan(void __iomem *ioaddr,
     65				      struct stmmac_dma_cfg *dma_cfg,
     66				      dma_addr_t phy, u32 chan)
     67{
     68	u32 txpbl = dma_cfg->txpbl ?: dma_cfg->pbl;
     69	u32 value;
     70
     71	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
     72	value &= ~XGMAC_TxPBL;
     73	value |= (txpbl << XGMAC_TxPBL_SHIFT) & XGMAC_TxPBL;
     74	value |= XGMAC_OSP;
     75	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
     76
     77	writel(upper_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_HADDR(chan));
     78	writel(lower_32_bits(phy), ioaddr + XGMAC_DMA_CH_TxDESC_LADDR(chan));
     79}
     80
     81static void dwxgmac2_dma_axi(void __iomem *ioaddr, struct stmmac_axi *axi)
     82{
     83	u32 value = readl(ioaddr + XGMAC_DMA_SYSBUS_MODE);
     84	int i;
     85
     86	if (axi->axi_lpi_en)
     87		value |= XGMAC_EN_LPI;
     88	if (axi->axi_xit_frm)
     89		value |= XGMAC_LPI_XIT_PKT;
     90
     91	value &= ~XGMAC_WR_OSR_LMT;
     92	value |= (axi->axi_wr_osr_lmt << XGMAC_WR_OSR_LMT_SHIFT) &
     93		XGMAC_WR_OSR_LMT;
     94
     95	value &= ~XGMAC_RD_OSR_LMT;
     96	value |= (axi->axi_rd_osr_lmt << XGMAC_RD_OSR_LMT_SHIFT) &
     97		XGMAC_RD_OSR_LMT;
     98
     99	if (!axi->axi_fb)
    100		value |= XGMAC_UNDEF;
    101
    102	value &= ~XGMAC_BLEN;
    103	for (i = 0; i < AXI_BLEN; i++) {
    104		switch (axi->axi_blen[i]) {
    105		case 256:
    106			value |= XGMAC_BLEN256;
    107			break;
    108		case 128:
    109			value |= XGMAC_BLEN128;
    110			break;
    111		case 64:
    112			value |= XGMAC_BLEN64;
    113			break;
    114		case 32:
    115			value |= XGMAC_BLEN32;
    116			break;
    117		case 16:
    118			value |= XGMAC_BLEN16;
    119			break;
    120		case 8:
    121			value |= XGMAC_BLEN8;
    122			break;
    123		case 4:
    124			value |= XGMAC_BLEN4;
    125			break;
    126		}
    127	}
    128
    129	writel(value, ioaddr + XGMAC_DMA_SYSBUS_MODE);
    130	writel(XGMAC_TDPS, ioaddr + XGMAC_TX_EDMA_CTRL);
    131	writel(XGMAC_RDPS, ioaddr + XGMAC_RX_EDMA_CTRL);
    132}
    133
    134static void dwxgmac2_dma_dump_regs(void __iomem *ioaddr, u32 *reg_space)
    135{
    136	int i;
    137
    138	for (i = (XGMAC_DMA_MODE / 4); i < XGMAC_REGSIZE; i++)
    139		reg_space[i] = readl(ioaddr + i * 4);
    140}
    141
    142static void dwxgmac2_dma_rx_mode(void __iomem *ioaddr, int mode,
    143				 u32 channel, int fifosz, u8 qmode)
    144{
    145	u32 value = readl(ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
    146	unsigned int rqs = fifosz / 256 - 1;
    147
    148	if (mode == SF_DMA_MODE) {
    149		value |= XGMAC_RSF;
    150	} else {
    151		value &= ~XGMAC_RSF;
    152		value &= ~XGMAC_RTC;
    153
    154		if (mode <= 64)
    155			value |= 0x0 << XGMAC_RTC_SHIFT;
    156		else if (mode <= 96)
    157			value |= 0x2 << XGMAC_RTC_SHIFT;
    158		else
    159			value |= 0x3 << XGMAC_RTC_SHIFT;
    160	}
    161
    162	value &= ~XGMAC_RQS;
    163	value |= (rqs << XGMAC_RQS_SHIFT) & XGMAC_RQS;
    164
    165	if ((fifosz >= 4096) && (qmode != MTL_QUEUE_AVB)) {
    166		u32 flow = readl(ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
    167		unsigned int rfd, rfa;
    168
    169		value |= XGMAC_EHFC;
    170
    171		/* Set Threshold for Activating Flow Control to min 2 frames,
    172		 * i.e. 1500 * 2 = 3000 bytes.
    173		 *
    174		 * Set Threshold for Deactivating Flow Control to min 1 frame,
    175		 * i.e. 1500 bytes.
    176		 */
    177		switch (fifosz) {
    178		case 4096:
    179			/* This violates the above formula because of FIFO size
    180			 * limit therefore overflow may occur in spite of this.
    181			 */
    182			rfd = 0x03; /* Full-2.5K */
    183			rfa = 0x01; /* Full-1.5K */
    184			break;
    185
    186		default:
    187			rfd = 0x07; /* Full-4.5K */
    188			rfa = 0x04; /* Full-3K */
    189			break;
    190		}
    191
    192		flow &= ~XGMAC_RFD;
    193		flow |= rfd << XGMAC_RFD_SHIFT;
    194
    195		flow &= ~XGMAC_RFA;
    196		flow |= rfa << XGMAC_RFA_SHIFT;
    197
    198		writel(flow, ioaddr + XGMAC_MTL_RXQ_FLOW_CONTROL(channel));
    199	}
    200
    201	writel(value, ioaddr + XGMAC_MTL_RXQ_OPMODE(channel));
    202
    203	/* Enable MTL RX overflow */
    204	value = readl(ioaddr + XGMAC_MTL_QINTEN(channel));
    205	writel(value | XGMAC_RXOIE, ioaddr + XGMAC_MTL_QINTEN(channel));
    206}
    207
    208static void dwxgmac2_dma_tx_mode(void __iomem *ioaddr, int mode,
    209				 u32 channel, int fifosz, u8 qmode)
    210{
    211	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
    212	unsigned int tqs = fifosz / 256 - 1;
    213
    214	if (mode == SF_DMA_MODE) {
    215		value |= XGMAC_TSF;
    216	} else {
    217		value &= ~XGMAC_TSF;
    218		value &= ~XGMAC_TTC;
    219
    220		if (mode <= 64)
    221			value |= 0x0 << XGMAC_TTC_SHIFT;
    222		else if (mode <= 96)
    223			value |= 0x2 << XGMAC_TTC_SHIFT;
    224		else if (mode <= 128)
    225			value |= 0x3 << XGMAC_TTC_SHIFT;
    226		else if (mode <= 192)
    227			value |= 0x4 << XGMAC_TTC_SHIFT;
    228		else if (mode <= 256)
    229			value |= 0x5 << XGMAC_TTC_SHIFT;
    230		else if (mode <= 384)
    231			value |= 0x6 << XGMAC_TTC_SHIFT;
    232		else
    233			value |= 0x7 << XGMAC_TTC_SHIFT;
    234	}
    235
    236	/* Use static TC to Queue mapping */
    237	value |= (channel << XGMAC_Q2TCMAP_SHIFT) & XGMAC_Q2TCMAP;
    238
    239	value &= ~XGMAC_TXQEN;
    240	if (qmode != MTL_QUEUE_AVB)
    241		value |= 0x2 << XGMAC_TXQEN_SHIFT;
    242	else
    243		value |= 0x1 << XGMAC_TXQEN_SHIFT;
    244
    245	value &= ~XGMAC_TQS;
    246	value |= (tqs << XGMAC_TQS_SHIFT) & XGMAC_TQS;
    247
    248	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
    249}
    250
    251static void dwxgmac2_enable_dma_irq(void __iomem *ioaddr, u32 chan,
    252				    bool rx, bool tx)
    253{
    254	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
    255
    256	if (rx)
    257		value |= XGMAC_DMA_INT_DEFAULT_RX;
    258	if (tx)
    259		value |= XGMAC_DMA_INT_DEFAULT_TX;
    260
    261	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
    262}
    263
    264static void dwxgmac2_disable_dma_irq(void __iomem *ioaddr, u32 chan,
    265				     bool rx, bool tx)
    266{
    267	u32 value = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
    268
    269	if (rx)
    270		value &= ~XGMAC_DMA_INT_DEFAULT_RX;
    271	if (tx)
    272		value &= ~XGMAC_DMA_INT_DEFAULT_TX;
    273
    274	writel(value, ioaddr + XGMAC_DMA_CH_INT_EN(chan));
    275}
    276
    277static void dwxgmac2_dma_start_tx(void __iomem *ioaddr, u32 chan)
    278{
    279	u32 value;
    280
    281	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    282	value |= XGMAC_TXST;
    283	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    284
    285	value = readl(ioaddr + XGMAC_TX_CONFIG);
    286	value |= XGMAC_CONFIG_TE;
    287	writel(value, ioaddr + XGMAC_TX_CONFIG);
    288}
    289
    290static void dwxgmac2_dma_stop_tx(void __iomem *ioaddr, u32 chan)
    291{
    292	u32 value;
    293
    294	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    295	value &= ~XGMAC_TXST;
    296	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    297
    298	value = readl(ioaddr + XGMAC_TX_CONFIG);
    299	value &= ~XGMAC_CONFIG_TE;
    300	writel(value, ioaddr + XGMAC_TX_CONFIG);
    301}
    302
    303static void dwxgmac2_dma_start_rx(void __iomem *ioaddr, u32 chan)
    304{
    305	u32 value;
    306
    307	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    308	value |= XGMAC_RXST;
    309	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    310
    311	value = readl(ioaddr + XGMAC_RX_CONFIG);
    312	value |= XGMAC_CONFIG_RE;
    313	writel(value, ioaddr + XGMAC_RX_CONFIG);
    314}
    315
    316static void dwxgmac2_dma_stop_rx(void __iomem *ioaddr, u32 chan)
    317{
    318	u32 value;
    319
    320	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    321	value &= ~XGMAC_RXST;
    322	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    323}
    324
    325static int dwxgmac2_dma_interrupt(void __iomem *ioaddr,
    326				  struct stmmac_extra_stats *x, u32 chan,
    327				  u32 dir)
    328{
    329	u32 intr_status = readl(ioaddr + XGMAC_DMA_CH_STATUS(chan));
    330	u32 intr_en = readl(ioaddr + XGMAC_DMA_CH_INT_EN(chan));
    331	int ret = 0;
    332
    333	if (dir == DMA_DIR_RX)
    334		intr_status &= XGMAC_DMA_STATUS_MSK_RX;
    335	else if (dir == DMA_DIR_TX)
    336		intr_status &= XGMAC_DMA_STATUS_MSK_TX;
    337
    338	/* ABNORMAL interrupts */
    339	if (unlikely(intr_status & XGMAC_AIS)) {
    340		if (unlikely(intr_status & XGMAC_RBU)) {
    341			x->rx_buf_unav_irq++;
    342			ret |= handle_rx;
    343		}
    344		if (unlikely(intr_status & XGMAC_TPS)) {
    345			x->tx_process_stopped_irq++;
    346			ret |= tx_hard_error;
    347		}
    348		if (unlikely(intr_status & XGMAC_FBE)) {
    349			x->fatal_bus_error_irq++;
    350			ret |= tx_hard_error;
    351		}
    352	}
    353
    354	/* TX/RX NORMAL interrupts */
    355	if (likely(intr_status & XGMAC_NIS)) {
    356		x->normal_irq_n++;
    357
    358		if (likely(intr_status & XGMAC_RI)) {
    359			x->rx_normal_irq_n++;
    360			ret |= handle_rx;
    361		}
    362		if (likely(intr_status & (XGMAC_TI | XGMAC_TBU))) {
    363			x->tx_normal_irq_n++;
    364			ret |= handle_tx;
    365		}
    366	}
    367
    368	/* Clear interrupts */
    369	writel(intr_en & intr_status, ioaddr + XGMAC_DMA_CH_STATUS(chan));
    370
    371	return ret;
    372}
    373
    374static int dwxgmac2_get_hw_feature(void __iomem *ioaddr,
    375				   struct dma_features *dma_cap)
    376{
    377	u32 hw_cap;
    378
    379	/*  MAC HW feature 0 */
    380	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE0);
    381	dma_cap->vlins = (hw_cap & XGMAC_HWFEAT_SAVLANINS) >> 27;
    382	dma_cap->rx_coe = (hw_cap & XGMAC_HWFEAT_RXCOESEL) >> 16;
    383	dma_cap->tx_coe = (hw_cap & XGMAC_HWFEAT_TXCOESEL) >> 14;
    384	dma_cap->eee = (hw_cap & XGMAC_HWFEAT_EEESEL) >> 13;
    385	dma_cap->atime_stamp = (hw_cap & XGMAC_HWFEAT_TSSEL) >> 12;
    386	dma_cap->av = (hw_cap & XGMAC_HWFEAT_AVSEL) >> 11;
    387	dma_cap->av &= !((hw_cap & XGMAC_HWFEAT_RAVSEL) >> 10);
    388	dma_cap->arpoffsel = (hw_cap & XGMAC_HWFEAT_ARPOFFSEL) >> 9;
    389	dma_cap->rmon = (hw_cap & XGMAC_HWFEAT_MMCSEL) >> 8;
    390	dma_cap->pmt_magic_frame = (hw_cap & XGMAC_HWFEAT_MGKSEL) >> 7;
    391	dma_cap->pmt_remote_wake_up = (hw_cap & XGMAC_HWFEAT_RWKSEL) >> 6;
    392	dma_cap->vlhash = (hw_cap & XGMAC_HWFEAT_VLHASH) >> 4;
    393	dma_cap->mbps_1000 = (hw_cap & XGMAC_HWFEAT_GMIISEL) >> 1;
    394
    395	/* MAC HW feature 1 */
    396	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE1);
    397	dma_cap->l3l4fnum = (hw_cap & XGMAC_HWFEAT_L3L4FNUM) >> 27;
    398	dma_cap->hash_tb_sz = (hw_cap & XGMAC_HWFEAT_HASHTBLSZ) >> 24;
    399	dma_cap->rssen = (hw_cap & XGMAC_HWFEAT_RSSEN) >> 20;
    400	dma_cap->tsoen = (hw_cap & XGMAC_HWFEAT_TSOEN) >> 18;
    401	dma_cap->sphen = (hw_cap & XGMAC_HWFEAT_SPHEN) >> 17;
    402
    403	dma_cap->addr64 = (hw_cap & XGMAC_HWFEAT_ADDR64) >> 14;
    404	switch (dma_cap->addr64) {
    405	case 0:
    406		dma_cap->addr64 = 32;
    407		break;
    408	case 1:
    409		dma_cap->addr64 = 40;
    410		break;
    411	case 2:
    412		dma_cap->addr64 = 48;
    413		break;
    414	default:
    415		dma_cap->addr64 = 32;
    416		break;
    417	}
    418
    419	dma_cap->tx_fifo_size =
    420		128 << ((hw_cap & XGMAC_HWFEAT_TXFIFOSIZE) >> 6);
    421	dma_cap->rx_fifo_size =
    422		128 << ((hw_cap & XGMAC_HWFEAT_RXFIFOSIZE) >> 0);
    423
    424	/* MAC HW feature 2 */
    425	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE2);
    426	dma_cap->pps_out_num = (hw_cap & XGMAC_HWFEAT_PPSOUTNUM) >> 24;
    427	dma_cap->number_tx_channel =
    428		((hw_cap & XGMAC_HWFEAT_TXCHCNT) >> 18) + 1;
    429	dma_cap->number_rx_channel =
    430		((hw_cap & XGMAC_HWFEAT_RXCHCNT) >> 12) + 1;
    431	dma_cap->number_tx_queues =
    432		((hw_cap & XGMAC_HWFEAT_TXQCNT) >> 6) + 1;
    433	dma_cap->number_rx_queues =
    434		((hw_cap & XGMAC_HWFEAT_RXQCNT) >> 0) + 1;
    435
    436	/* MAC HW feature 3 */
    437	hw_cap = readl(ioaddr + XGMAC_HW_FEATURE3);
    438	dma_cap->tbssel = (hw_cap & XGMAC_HWFEAT_TBSSEL) >> 27;
    439	dma_cap->fpesel = (hw_cap & XGMAC_HWFEAT_FPESEL) >> 26;
    440	dma_cap->estwid = (hw_cap & XGMAC_HWFEAT_ESTWID) >> 23;
    441	dma_cap->estdep = (hw_cap & XGMAC_HWFEAT_ESTDEP) >> 20;
    442	dma_cap->estsel = (hw_cap & XGMAC_HWFEAT_ESTSEL) >> 19;
    443	dma_cap->asp = (hw_cap & XGMAC_HWFEAT_ASP) >> 14;
    444	dma_cap->dvlan = (hw_cap & XGMAC_HWFEAT_DVLAN) >> 13;
    445	dma_cap->frpes = (hw_cap & XGMAC_HWFEAT_FRPES) >> 11;
    446	dma_cap->frpbs = (hw_cap & XGMAC_HWFEAT_FRPPB) >> 9;
    447	dma_cap->frpsel = (hw_cap & XGMAC_HWFEAT_FRPSEL) >> 3;
    448
    449	return 0;
    450}
    451
    452static void dwxgmac2_rx_watchdog(void __iomem *ioaddr, u32 riwt, u32 queue)
    453{
    454	writel(riwt & XGMAC_RWT, ioaddr + XGMAC_DMA_CH_Rx_WATCHDOG(queue));
    455}
    456
    457static void dwxgmac2_set_rx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
    458{
    459	writel(len, ioaddr + XGMAC_DMA_CH_RxDESC_RING_LEN(chan));
    460}
    461
    462static void dwxgmac2_set_tx_ring_len(void __iomem *ioaddr, u32 len, u32 chan)
    463{
    464	writel(len, ioaddr + XGMAC_DMA_CH_TxDESC_RING_LEN(chan));
    465}
    466
    467static void dwxgmac2_set_rx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
    468{
    469	writel(ptr, ioaddr + XGMAC_DMA_CH_RxDESC_TAIL_LPTR(chan));
    470}
    471
    472static void dwxgmac2_set_tx_tail_ptr(void __iomem *ioaddr, u32 ptr, u32 chan)
    473{
    474	writel(ptr, ioaddr + XGMAC_DMA_CH_TxDESC_TAIL_LPTR(chan));
    475}
    476
    477static void dwxgmac2_enable_tso(void __iomem *ioaddr, bool en, u32 chan)
    478{
    479	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    480
    481	if (en)
    482		value |= XGMAC_TSE;
    483	else
    484		value &= ~XGMAC_TSE;
    485
    486	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    487}
    488
    489static void dwxgmac2_qmode(void __iomem *ioaddr, u32 channel, u8 qmode)
    490{
    491	u32 value = readl(ioaddr + XGMAC_MTL_TXQ_OPMODE(channel));
    492	u32 flow = readl(ioaddr + XGMAC_RX_FLOW_CTRL);
    493
    494	value &= ~XGMAC_TXQEN;
    495	if (qmode != MTL_QUEUE_AVB) {
    496		value |= 0x2 << XGMAC_TXQEN_SHIFT;
    497		writel(0, ioaddr + XGMAC_MTL_TCx_ETS_CONTROL(channel));
    498	} else {
    499		value |= 0x1 << XGMAC_TXQEN_SHIFT;
    500		writel(flow & (~XGMAC_RFE), ioaddr + XGMAC_RX_FLOW_CTRL);
    501	}
    502
    503	writel(value, ioaddr +  XGMAC_MTL_TXQ_OPMODE(channel));
    504}
    505
    506static void dwxgmac2_set_bfsize(void __iomem *ioaddr, int bfsize, u32 chan)
    507{
    508	u32 value;
    509
    510	value = readl(ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    511	value &= ~XGMAC_RBSZ;
    512	value |= bfsize << XGMAC_RBSZ_SHIFT;
    513	writel(value, ioaddr + XGMAC_DMA_CH_RX_CONTROL(chan));
    514}
    515
    516static void dwxgmac2_enable_sph(void __iomem *ioaddr, bool en, u32 chan)
    517{
    518	u32 value = readl(ioaddr + XGMAC_RX_CONFIG);
    519
    520	value &= ~XGMAC_CONFIG_HDSMS;
    521	value |= XGMAC_CONFIG_HDSMS_256; /* Segment max 256 bytes */
    522	writel(value, ioaddr + XGMAC_RX_CONFIG);
    523
    524	value = readl(ioaddr + XGMAC_DMA_CH_CONTROL(chan));
    525	if (en)
    526		value |= XGMAC_SPH;
    527	else
    528		value &= ~XGMAC_SPH;
    529	writel(value, ioaddr + XGMAC_DMA_CH_CONTROL(chan));
    530}
    531
    532static int dwxgmac2_enable_tbs(void __iomem *ioaddr, bool en, u32 chan)
    533{
    534	u32 value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    535
    536	if (en)
    537		value |= XGMAC_EDSE;
    538	else
    539		value &= ~XGMAC_EDSE;
    540
    541	writel(value, ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan));
    542
    543	value = readl(ioaddr + XGMAC_DMA_CH_TX_CONTROL(chan)) & XGMAC_EDSE;
    544	if (en && !value)
    545		return -EIO;
    546
    547	writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL0);
    548	writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL1);
    549	writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL2);
    550	writel(XGMAC_DEF_FTOS, ioaddr + XGMAC_DMA_TBS_CTRL3);
    551	return 0;
    552}
    553
    554const struct stmmac_dma_ops dwxgmac210_dma_ops = {
    555	.reset = dwxgmac2_dma_reset,
    556	.init = dwxgmac2_dma_init,
    557	.init_chan = dwxgmac2_dma_init_chan,
    558	.init_rx_chan = dwxgmac2_dma_init_rx_chan,
    559	.init_tx_chan = dwxgmac2_dma_init_tx_chan,
    560	.axi = dwxgmac2_dma_axi,
    561	.dump_regs = dwxgmac2_dma_dump_regs,
    562	.dma_rx_mode = dwxgmac2_dma_rx_mode,
    563	.dma_tx_mode = dwxgmac2_dma_tx_mode,
    564	.enable_dma_irq = dwxgmac2_enable_dma_irq,
    565	.disable_dma_irq = dwxgmac2_disable_dma_irq,
    566	.start_tx = dwxgmac2_dma_start_tx,
    567	.stop_tx = dwxgmac2_dma_stop_tx,
    568	.start_rx = dwxgmac2_dma_start_rx,
    569	.stop_rx = dwxgmac2_dma_stop_rx,
    570	.dma_interrupt = dwxgmac2_dma_interrupt,
    571	.get_hw_feature = dwxgmac2_get_hw_feature,
    572	.rx_watchdog = dwxgmac2_rx_watchdog,
    573	.set_rx_ring_len = dwxgmac2_set_rx_ring_len,
    574	.set_tx_ring_len = dwxgmac2_set_tx_ring_len,
    575	.set_rx_tail_ptr = dwxgmac2_set_rx_tail_ptr,
    576	.set_tx_tail_ptr = dwxgmac2_set_tx_tail_ptr,
    577	.enable_tso = dwxgmac2_enable_tso,
    578	.qmode = dwxgmac2_qmode,
    579	.set_bfsize = dwxgmac2_set_bfsize,
    580	.enable_sph = dwxgmac2_enable_sph,
    581	.enable_tbs = dwxgmac2_enable_tbs,
    582};