blob: 4de62b0ce86dda0451766e7c4ad3c6659dfa742b (
plain) (
blame)
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
|
#ifndef _DWMAC_H
#define _DWMAC_H
/** @file
*
* Synopsys DesignWare MAC network driver
*
*/
FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <stdint.h>
#include <ipxe/if_ether.h>
/** I/O region index */
#define DWMAC_REG_IDX 0
/** I/O region length */
#define DWMAC_REG_LEN 0x2000
/** MAC register block */
#define DWMAC_MAC 0x0000
#define DWMAC_MAC_REG( n ) ( DWMAC_MAC + ( (n) * 4 ) )
/** MAC configuration register */
#define DWMAC_CFG DWMAC_MAC_REG ( 0 )
#define DWMAC_CFG_DO 0x00002000 /**< Disable RX own frames */
#define DWMAC_CFG_FD 0x00000800 /**< Full duplex */
#define DWMAC_CFG_TXEN 0x00000008 /**< TX enabled */
#define DWMAC_CFG_RXEN 0x00000004 /**< RX enabled */
/** MAC filter register */
#define DWMAC_FILTER DWMAC_MAC_REG ( 1 )
#define DWMAC_FILTER_PR 0x00000001 /**< Promiscuous mode */
/** Flow control register */
#define DWMAC_FLOW DWMAC_MAC_REG ( 6 )
/** Version register */
#define DWMAC_VER DWMAC_MAC_REG ( 8 )
#define DWMAC_VER_USER_MAJOR( x ) \
( ( (x) >> 12 ) & 0xf ) /**< User major version */
#define DWMAC_VER_USER_MINOR( x ) \
( ( (x) >> 8 ) & 0xf ) /**< User minor version */
#define DWMAC_VER_CORE_MAJOR( x ) \
( ( (x) >> 4 ) & 0xf ) /**< Core major version */
#define DWMAC_VER_CORE_MINOR( x ) \
( ( (x) >> 0 ) & 0xf ) /**< Core minor version */
/** Debug register */
#define DWMAC_DEBUG DWMAC_MAC_REG ( 9 )
/** Interrupt status register */
#define DWMAC_ISR DWMAC_MAC_REG ( 14 )
/** MAC address high register */
#define DWMAC_ADDRH DWMAC_MAC_REG ( 16 )
/** MAC address low register */
#define DWMAC_ADDRL DWMAC_MAC_REG ( 17 )
/** A DesignWare MAC address */
union dwmac_mac {
struct {
uint32_t addrl;
uint32_t addrh;
} __attribute__ (( packed )) reg;
uint8_t raw[ETH_ALEN];
};
/** SGMII/RGMII status register */
#define DWMAC_GMII DWMAC_MAC_REG ( 54 )
#define DWMAC_GMII_LINK 0x00000008 /**< Link up */
/** DMA register block */
#define DWMAC_DMA 0x1000
#define DWMAC_DMA_REG( n ) ( DWMAC_DMA + ( (n) * 4 ) )
/** Bus mode register */
#define DWMAC_BUS DWMAC_DMA_REG ( 0 )
#define DWMAC_BUS_PBL4 0x01000000 /**< 4x PBL mode */
#define DWMAC_BUS_USP 0x00800000 /**< Use separate PBL */
#define DWMAC_BUS_RPBL(x) ( (x) << 17 ) /**< RX DMA PBL */
#define DWMAC_BUS_FB 0x00010000 /**< Fixed burst */
#define DWMAC_BUS_PBL(x) ( (x) << 8 ) /**< (TX) DMA PBL */
#define DWMAC_BUS_SWR 0x00000001 /**< Software reset */
/** Time to wait for software reset to complete */
#define DWMAC_RESET_MAX_WAIT_MS 500
/** Transmit poll demand register */
#define DWMAC_TXPOLL DWMAC_DMA_REG ( 1 )
/** Receive poll demand register */
#define DWMAC_RXPOLL DWMAC_DMA_REG ( 2 )
/** Receive descriptor list address register */
#define DWMAC_RXBASE DWMAC_DMA_REG ( 3 )
/** Transmit descriptor list address register */
#define DWMAC_TXBASE DWMAC_DMA_REG ( 4 )
/** Status register */
#define DWMAC_STATUS DWMAC_DMA_REG ( 5 )
#define DWMAC_STATUS_LINK 0x04000000 /**< Link status change */
/** Operation mode register */
#define DWMAC_OP DWMAC_DMA_REG ( 6 )
#define DWMAC_OP_RXSF 0x02000000 /**< RX store and forward */
#define DWMAC_OP_TXSF 0x00200000 /**< TX store and forward */
#define DWMAC_OP_TXEN 0x00002000 /**< TX enabled */
#define DWMAC_OP_RXEN 0x00000002 /**< RX enabled */
/** Packet drop counter register */
#define DWMAC_DROP DWMAC_DMA_REG ( 8 )
/** AXI bus mode register */
#define DWMAC_AXI DWMAC_DMA_REG ( 10 )
/** AHB or AXI status register */
#define DWMAC_AHB DWMAC_DMA_REG ( 11 )
/** Current transmit descriptor register */
#define DWMAC_TXDESC DWMAC_DMA_REG ( 18 )
/** Current receive descriptor register */
#define DWMAC_RXDESC DWMAC_DMA_REG ( 19 )
/** Current transmit buffer address register */
#define DWMAC_TXBUF DWMAC_DMA_REG ( 20 )
/** Current receive buffer address register */
#define DWMAC_RXBUF DWMAC_DMA_REG ( 21 )
/** Hardware feature register */
#define DWMAC_FEATURE DWMAC_DMA_REG ( 22 )
/** A frame descriptor
*
* We populate the descriptor with values that are valid for both
* normal and enhanced descriptor formats, to avoid needing to care
* about which version of the hardware we have.
*/
struct dwmac_descriptor {
/** Completion status */
uint32_t stat;
/** Buffer size */
uint16_t size;
/** Reserved */
uint8_t reserved_a;
/** Ring control */
uint8_t ctrl;
/** Buffer address */
uint32_t addr;
/** Next descriptor address */
uint32_t next;
} __attribute__ (( packed ));
/* Completion status */
#define DWMAC_STAT_OWN 0x80000000 /**< Owned by hardware */
#define DWMAC_STAT_TX_LAST 0x20000000 /**< Last segment (TX) */
#define DWMAC_STAT_TX_FIRST 0x10000000 /**< First segment (TX) */
#define DWMAC_STAT_TX_CHAIN 0x00100000 /**< Chained descriptor (TX) */
#define DWMAC_STAT_ERR 0x00008000 /**< Error summary */
#define DWMAC_STAT_RX_FIRST 0x00000200 /**< First segment (RX) */
#define DWMAC_STAT_RX_LAST 0x00000100 /**< Last segment (RX) */
#define DWMAC_STAT_RX_LEN(x) \
( ( (x) >> 16 ) & 0x3fff ) /**< Frame length (RX) */
/** Buffer size */
#define DWMAC_SIZE_RX_CHAIN 0x4000 /**< Chained descriptor (RX) */
/* Ring control */
#define DWMAC_CTRL_TX_LAST 0x40 /**< Last segment (TX) */
#define DWMAC_CTRL_TX_FIRST 0x20 /**< First segment (TX) */
#define DWMAC_CTRL_CHAIN 0x01 /**< Chained descriptor */
/** A DesignWare descriptor ring */
struct dwmac_ring {
/** Descriptors */
struct dwmac_descriptor *desc;
/** Descriptor ring DMA mapping */
struct dma_mapping map;
/** Producer index */
unsigned int prod;
/** Consumer index */
unsigned int cons;
/** Queue base address register (within DMA block) */
uint8_t qbase;
/** Number of descriptors */
uint8_t count;
/** Default control flags */
uint8_t ctrl;
/** Length of descriptors */
size_t len;
};
/** Number of transmit descriptors */
#define DWMAC_NUM_TX_DESC 16
/** Number of receive descriptors */
#define DWMAC_NUM_RX_DESC 16
/** Length of receive buffers
*
* Must be a multiple of 16.
*/
#define DWMAC_RX_LEN 1536
/**
* Initialise descriptor ring
*
* @v ring Descriptor ring
* @v count Number of descriptors
* @v qbase Queue base address register
* @v ctrl Default descriptor control flags
*/
static inline __attribute__ (( always_inline )) void
dwmac_init_ring ( struct dwmac_ring *ring, unsigned int count,
unsigned int qbase, unsigned int ctrl ) {
ring->qbase = ( qbase - DWMAC_DMA );
ring->count = count;
ring->ctrl = ctrl;
ring->len = ( count * sizeof ( ring->desc[0] ) );
}
/** A DesignWare MAC network card */
struct dwmac {
/** Registers */
void *regs;
/** DMA device */
struct dma_device *dma;
/** Device name (for debugging) */
const char *name;
/** Transmit ring */
struct dwmac_ring tx;
/** Receive ring */
struct dwmac_ring rx;
/** Receive I/O buffers */
struct io_buffer *rx_iobuf[DWMAC_NUM_RX_DESC];
};
#endif /* _DWMAC_H */
|