1 // SPDX-License-Identifier: GPL-2.0-only
2 /*******************************************************************************
3 This is the driver for the MAC 10/100 on-chip Ethernet controller
4 currently tested on all the ST boards based on STb7109 and stx7200 SoCs.
6 DWC Ether MAC 10/100 Universal version 4.0 has been used for developing
9 This contains the functions to handle the dma.
11 Copyright (C) 2007-2009 STMicroelectronics Ltd
14 Author: Giuseppe Cavallaro <peppe.cavallaro@st.com>
15 *******************************************************************************/
19 #include "dwmac_dma.h"
21 static void dwmac100_dma_init(void __iomem
*ioaddr
,
22 struct stmmac_dma_cfg
*dma_cfg
, int atds
)
24 /* Enable Application Access by writing to DMA CSR0 */
25 writel(DMA_BUS_MODE_DEFAULT
| (dma_cfg
->pbl
<< DMA_BUS_MODE_PBL_SHIFT
),
26 ioaddr
+ DMA_BUS_MODE
);
28 /* Mask interrupts by writing to CSR7 */
29 writel(DMA_INTR_DEFAULT_MASK
, ioaddr
+ DMA_INTR_ENA
);
32 static void dwmac100_dma_init_rx(void __iomem
*ioaddr
,
33 struct stmmac_dma_cfg
*dma_cfg
,
34 dma_addr_t dma_rx_phy
, u32 chan
)
36 /* RX descriptor base addr lists must be written into DMA CSR3 */
37 writel(lower_32_bits(dma_rx_phy
), ioaddr
+ DMA_RCV_BASE_ADDR
);
40 static void dwmac100_dma_init_tx(void __iomem
*ioaddr
,
41 struct stmmac_dma_cfg
*dma_cfg
,
42 dma_addr_t dma_tx_phy
, u32 chan
)
44 /* TX descriptor base addr lists must be written into DMA CSR4 */
45 writel(lower_32_bits(dma_tx_phy
), ioaddr
+ DMA_TX_BASE_ADDR
);
48 /* Store and Forward capability is not used at all.
50 * The transmit threshold can be programmed by setting the TTC bits in the DMA
53 static void dwmac100_dma_operation_mode_tx(void __iomem
*ioaddr
, int mode
,
54 u32 channel
, int fifosz
, u8 qmode
)
56 u32 csr6
= readl(ioaddr
+ DMA_CONTROL
);
59 csr6
|= DMA_CONTROL_TTC_32
;
61 csr6
|= DMA_CONTROL_TTC_64
;
63 csr6
|= DMA_CONTROL_TTC_128
;
65 writel(csr6
, ioaddr
+ DMA_CONTROL
);
68 static void dwmac100_dump_dma_regs(void __iomem
*ioaddr
, u32
*reg_space
)
72 for (i
= 0; i
< NUM_DWMAC100_DMA_REGS
; i
++)
73 reg_space
[DMA_BUS_MODE
/ 4 + i
] =
74 readl(ioaddr
+ DMA_BUS_MODE
+ i
* 4);
76 reg_space
[DMA_CUR_TX_BUF_ADDR
/ 4] =
77 readl(ioaddr
+ DMA_CUR_TX_BUF_ADDR
);
78 reg_space
[DMA_CUR_RX_BUF_ADDR
/ 4] =
79 readl(ioaddr
+ DMA_CUR_RX_BUF_ADDR
);
82 /* DMA controller has two counters to track the number of the missed frames. */
83 static void dwmac100_dma_diagnostic_fr(void *data
, struct stmmac_extra_stats
*x
,
86 struct net_device_stats
*stats
= (struct net_device_stats
*)data
;
87 u32 csr8
= readl(ioaddr
+ DMA_MISSED_FRAME_CTR
);
90 if (csr8
& DMA_MISSED_FRAME_OVE
) {
91 stats
->rx_over_errors
+= 0x800;
92 x
->rx_overflow_cntr
+= 0x800;
94 unsigned int ove_cntr
;
95 ove_cntr
= ((csr8
& DMA_MISSED_FRAME_OVE_CNTR
) >> 17);
96 stats
->rx_over_errors
+= ove_cntr
;
97 x
->rx_overflow_cntr
+= ove_cntr
;
100 if (csr8
& DMA_MISSED_FRAME_OVE_M
) {
101 stats
->rx_missed_errors
+= 0xffff;
102 x
->rx_missed_cntr
+= 0xffff;
104 unsigned int miss_f
= (csr8
& DMA_MISSED_FRAME_M_CNTR
);
105 stats
->rx_missed_errors
+= miss_f
;
106 x
->rx_missed_cntr
+= miss_f
;
111 const struct stmmac_dma_ops dwmac100_dma_ops
= {
112 .reset
= dwmac_dma_reset
,
113 .init
= dwmac100_dma_init
,
114 .init_rx_chan
= dwmac100_dma_init_rx
,
115 .init_tx_chan
= dwmac100_dma_init_tx
,
116 .dump_regs
= dwmac100_dump_dma_regs
,
117 .dma_tx_mode
= dwmac100_dma_operation_mode_tx
,
118 .dma_diagnostic_fr
= dwmac100_dma_diagnostic_fr
,
119 .enable_dma_transmission
= dwmac_enable_dma_transmission
,
120 .enable_dma_irq
= dwmac_enable_dma_irq
,
121 .disable_dma_irq
= dwmac_disable_dma_irq
,
122 .start_tx
= dwmac_dma_start_tx
,
123 .stop_tx
= dwmac_dma_stop_tx
,
124 .start_rx
= dwmac_dma_start_rx
,
125 .stop_rx
= dwmac_dma_stop_rx
,
126 .dma_interrupt
= dwmac_dma_interrupt
,