1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31#include <asm/io.h>
32#include "dwmac100.h"
33#include "dwmac_dma.h"
34
35static int dwmac100_dma_init(void __iomem *ioaddr, int pbl, int fb, int mb,
36 int burst_len, u32 dma_tx, u32 dma_rx, int atds)
37{
38 u32 value = readl(ioaddr + DMA_BUS_MODE);
39 int limit;
40
41
42 value |= DMA_BUS_MODE_SFT_RESET;
43 writel(value, ioaddr + DMA_BUS_MODE);
44 limit = 10;
45 while (limit--) {
46 if (!(readl(ioaddr + DMA_BUS_MODE) & DMA_BUS_MODE_SFT_RESET))
47 break;
48 mdelay(10);
49 }
50 if (limit < 0)
51 return -EBUSY;
52
53
54 writel(DMA_BUS_MODE_DEFAULT | (pbl << DMA_BUS_MODE_PBL_SHIFT),
55 ioaddr + DMA_BUS_MODE);
56
57
58 writel(DMA_INTR_DEFAULT_MASK, ioaddr + DMA_INTR_ENA);
59
60
61
62
63 writel(dma_tx, ioaddr + DMA_TX_BASE_ADDR);
64 writel(dma_rx, ioaddr + DMA_RCV_BASE_ADDR);
65
66 return 0;
67}
68
69
70
71
72
73
74static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode,
75 int rxmode, int rxfifosz)
76{
77 u32 csr6 = readl(ioaddr + DMA_CONTROL);
78
79 if (txmode <= 32)
80 csr6 |= DMA_CONTROL_TTC_32;
81 else if (txmode <= 64)
82 csr6 |= DMA_CONTROL_TTC_64;
83 else
84 csr6 |= DMA_CONTROL_TTC_128;
85
86 writel(csr6, ioaddr + DMA_CONTROL);
87}
88
89static void dwmac100_dump_dma_regs(void __iomem *ioaddr)
90{
91 int i;
92
93 pr_debug("DWMAC 100 DMA CSR\n");
94 for (i = 0; i < 9; i++)
95 pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i,
96 (DMA_BUS_MODE + i * 4),
97 readl(ioaddr + DMA_BUS_MODE + i * 4));
98
99 pr_debug("\tCSR20 (0x%x): 0x%08x, CSR21 (0x%x): 0x%08x\n",
100 DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR),
101 DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR));
102}
103
104
105static void dwmac100_dma_diagnostic_fr(void *data, struct stmmac_extra_stats *x,
106 void __iomem *ioaddr)
107{
108 struct net_device_stats *stats = (struct net_device_stats *)data;
109 u32 csr8 = readl(ioaddr + DMA_MISSED_FRAME_CTR);
110
111 if (unlikely(csr8)) {
112 if (csr8 & DMA_MISSED_FRAME_OVE) {
113 stats->rx_over_errors += 0x800;
114 x->rx_overflow_cntr += 0x800;
115 } else {
116 unsigned int ove_cntr;
117 ove_cntr = ((csr8 & DMA_MISSED_FRAME_OVE_CNTR) >> 17);
118 stats->rx_over_errors += ove_cntr;
119 x->rx_overflow_cntr += ove_cntr;
120 }
121
122 if (csr8 & DMA_MISSED_FRAME_OVE_M) {
123 stats->rx_missed_errors += 0xffff;
124 x->rx_missed_cntr += 0xffff;
125 } else {
126 unsigned int miss_f = (csr8 & DMA_MISSED_FRAME_M_CNTR);
127 stats->rx_missed_errors += miss_f;
128 x->rx_missed_cntr += miss_f;
129 }
130 }
131}
132
133const struct stmmac_dma_ops dwmac100_dma_ops = {
134 .init = dwmac100_dma_init,
135 .dump_regs = dwmac100_dump_dma_regs,
136 .dma_mode = dwmac100_dma_operation_mode,
137 .dma_diagnostic_fr = dwmac100_dma_diagnostic_fr,
138 .enable_dma_transmission = dwmac_enable_dma_transmission,
139 .enable_dma_irq = dwmac_enable_dma_irq,
140 .disable_dma_irq = dwmac_disable_dma_irq,
141 .start_tx = dwmac_dma_start_tx,
142 .stop_tx = dwmac_dma_stop_tx,
143 .start_rx = dwmac_dma_start_rx,
144 .stop_rx = dwmac_dma_stop_rx,
145 .dma_interrupt = dwmac_dma_interrupt,
146};
147