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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
|
/*
* Copyright (c) 2006-2023, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2023-11-25 GuEe-GUI first version
*/
#ifndef __MACB_H__
#define __MACB_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include "../ethernet_dm.h"
/* Queue 0 (legacy offsets) */
#define GEM_NCR 0x0000
#define GEM_NCFGR 0x0004
#define GEM_NSR 0x0008
#define GEM_USRIO 0x000c
#define GEM_DMACFG 0x0010
#define GEM_TSR 0x0014
#define GEM_TSR_TGO RT_BIT(3)
#define GEM_TSR_COMP RT_BIT(5)
#define GEM_RSR 0x0020
#define GEM_ISR 0x0024
#define GEM_IER 0x0028
#define GEM_IDR 0x002c
#define GEM_IMR 0x0030
#define GEM_ISR0 0x0400 /* GEM queue 0 ISR */
#define GEM_IER0 0x0600 /* GEM queue 0 IER */
#define GEM_IDR0 0x0620 /* GEM queue 0 IDR */
#define GEM_IMR0 0x0640 /* GEM queue 0 IMR */
#define GEM_MAN 0x0034 /* PHY maintenance (was wrongly 0x340) */
/*
* GEM queue 0 uses legacy MACB ring/IRQ registers; GEM_*Q1+ live at 0x440/0x480.
* Linux: queue0 -> MACB_TBQP/RBQP/ISR/IER; queue1+ -> GEM_TBQP(n)/GEM_RBQP(n).
*/
#define GEM_RBQP 0x0018
#define GEM_TBQP 0x001c
#define GEM_RBQP1 0x0480
#define GEM_TBQP1 0x0440
#define MACB_MAX_QUEUES 8
#define GEM_QUEUE_TBQP(q) (0x0440 + ((q) << 2))
#define GEM_QUEUE_RBQP(q) (0x0480 + ((q) << 2))
#define GEM_JML 0x0048
#define GEM_PBUFRXCUT 0x0044
#define GEM_INTMOD 0x005c
#define GEM_INTMOD_TX_MOD_SHIFT 16
#define GEM_INTMOD_RX_MOD_SHIFT 0
#define GEM_SA1B 0x0088
#define GEM_SA1T 0x008c
#define GEM_DCFG1 0x0280
#define GEM_DCFG1_IRQCOR_SHIFT 23
#define GEM_DCFG5 0x0290
#define GEM_DCFG6 0x0294
#define GEM_DCFG6_DAW64_SHIFT 23
#define GEM_RBQPH 0x04d4
#define GEM_TBQPH 0x04c8
#define GEM_AMP 0x0054
#define GEM_AMP_AR2R_MAX_PIPE_SHIFT 0
#define GEM_AMP_AW2W_MAX_PIPE_SHIFT 8
#define GEM_AMP_AW2B_FILL_SHIFT 16
#define GEM_USRIO_RGMII RT_BIT(0)
/* TSU / 1588 */
#define GEM_TISUBN 0x01bc
#define GEM_TSH 0x01c0
#define GEM_TSL 0x01d0
#define GEM_TN 0x01d4
#define GEM_TA 0x01d8
#define GEM_TI 0x01dc
/* NCR */
#define GEM_NCR_LLB RT_BIT(1)
#define GEM_NCR_RE RT_BIT(2)
#define GEM_NCR_TE RT_BIT(3)
#define GEM_NCR_MPE RT_BIT(4)
#define GEM_NCR_CLRSTAT RT_BIT(5)
#define GEM_NCR_TSTART RT_BIT(9)
/*
* NCFGR: GEM uses same SPD/FD as MACB (bit0/1); gigabit is GEM_GBE @ bit10,
* not bit31.
*/
#define GEM_NCFGR_SPD RT_BIT(0) /* 100 Mbps */
#define GEM_NCFGR_FD RT_BIT(1) /* Full duplex */
#define GEM_NCFGR_GBE RT_BIT(10) /* 1000 Mbps (GEM) */
#define GEM_NCFGR_BIG RT_BIT(8) /* Receive 1536-byte frames */
#define GEM_NCFGR_DRFCS RT_BIT(17) /* Discard RX FCS */
/* DBW in NCFGR bits [22:21] */
#define GEM_NCFGR_DBW_SHIFT 21
/* MDC clock divider in NCFGR bits [20:18] */
#define GEM_NCFGR_CLK_SHIFT 18
/* NSR */
#define GEM_NSR_IDLE RT_BIT(2)
/* RSR */
#define GEM_RSR_BNA RT_BIT(0)
#define GEM_RSR_REC RT_BIT(1)
#define GEM_RSR_OVR RT_BIT(2)
/* ISR / IER / IDR / IMR: queue 0 @ 0x24..0x30; extra GEM queues @ 0x400/0x600 */
#define GEM_INT_MFD RT_BIT(0)
#define GEM_INT_HRESP RT_BIT(11)
#define GEM_INT_RCOMP RT_BIT(1)
#define GEM_INT_RXUBR RT_BIT(2)
#define GEM_INT_TXUBR RT_BIT(3)
#define GEM_INT_TUND RT_BIT(4)
#define GEM_INT_RLE RT_BIT(5)
#define GEM_INT_TXERR RT_BIT(6)
#define GEM_INT_TCOMP RT_BIT(7)
#define GEM_INT_LINK RT_BIT(9)
#define GEM_INT_ROVR RT_BIT(10)
#define GEM_INT_RX_BITS (GEM_INT_RCOMP | GEM_INT_RXUBR | GEM_INT_ROVR)
#define GEM_INT_TX_BITS (GEM_INT_TCOMP | GEM_INT_TUND | GEM_INT_RLE | GEM_INT_TXERR)
/* MAN (MDIO clause 22) */
#define GEM_MAN_SOF 1
#define GEM_MAN_WRITE 1
#define GEM_MAN_READ 2
#define GEM_MAN_CODE 2
#define GEM_MAN_DATA_OFF 0
#define GEM_MAN_DATA_SZ 16
#define GEM_MAN_CODE_OFF 16
#define GEM_MAN_CODE_SZ 2
#define GEM_MAN_REGA_OFF 18
#define GEM_MAN_REGA_SZ 5
#define GEM_MAN_PHYA_OFF 23
#define GEM_MAN_PHYA_SZ 5
#define GEM_MAN_RW_OFF 28
#define GEM_MAN_RW_SZ 2
#define GEM_MAN_SOF_OFF 30
#define GEM_MAN_SOF_SZ 2
#define GEM_MAN_BF(name, val) (((val) & ((1 << GEM_MAN_##name##_SZ) - 1)) << GEM_MAN_##name##_OFF)
/*
* RX descriptor word @addr: OWNERSHIP uses bit0 (RX_USED); WRAP is bit1.
* Word @ctrl: frame length in bits [11:0], SOF/EOF for single-buffer frames.
*/
#define GEM_RX_USED RT_BIT(0) /* In addr */
#define GEM_RX_WRAP RT_BIT(1) /* In addr */
#define GEM_RX_LEN_MASK 0x0fff /* FRMLEN in ctrl */
#define GEM_RX_SOF RT_BIT(14)
#define GEM_RX_EOF RT_BIT(15)
/* TX descriptor @ctrl (GEM length bits [13:0]) */
#define GEM_TX_LAST RT_BIT(15)
#define GEM_TX_NOCRC RT_BIT(16)
#define GEM_TX_WRAP RT_BIT(30)
#define GEM_TX_USED RT_BIT(31)
#define GEM_TX_LEN_MASK 0x3fff
/* DMACFG */
#define GEM_DMACFG_FBLDO_SHIFT 0
#define GEM_DMACFG_ENDIA_DESC_SHIFT 6
#define GEM_DMACFG_ENDIA_PKT_SHIFT 7
#define GEM_DMACFG_RXBMS_SHIFT 8
#define GEM_DMACFG_TXPBMS_SHIFT 10
#define GEM_DMACFG_RXBS_SHIFT 16
#define GEM_DMACFG_DDRP_SHIFT 24
#define GEM_DMACFG_RXEXT_SHIFT 28
#define GEM_DMACFG_TXEXT_SHIFT 29
#define GEM_DMACFG_ADDR64_SHIFT 30
#define GEM_DMACFG_RXBS_MASK 0xff
#define GEM_CLK_DIV8 0
#define GEM_CLK_DIV16 1
#define GEM_CLK_DIV32 2
#define GEM_CLK_DIV48 3
#define GEM_CLK_DIV64 4
#define GEM_CLK_DIV96 5
#define GEM_CLK_DIV128 6
#define GEM_CLK_DIV224 7
/* DCFG5: TSU present */
#define GEM_DCFG5_TSU_SHIFT 8
#define GEM_DBW32 0
#define GEM_DBW64 1
#define GEM_DBW128 2
#define MACB_CAP_USRIO_HAS_CLKEN RT_BIT(1)
#define MACB_CAP_USRIO_DEFAULT_MII_GMII RT_BIT(2)
#define MACB_CAP_NO_GIGABIT_HALF RT_BIT(3)
#define MACB_CAP_USRIO_DISABLED RT_BIT(4)
#define MACB_CAP_JUMBO RT_BIT(5)
#define MACB_CAP_GEM_HAS_PTP RT_BIT(6)
#define MACB_CAP_BD_RD_PREFETCH RT_BIT(7)
#define MACB_CAP_NEEDS_RSTONUBR RT_BIT(8)
#define MACB_CAP_MIIONRGMII RT_BIT(9)
#define MACB_CAP_NEED_TSUCLK RT_BIT(10)
#define MACB_CAP_QUEUE_DISABLE RT_BIT(11)
#define MACB_CAP_QBV RT_BIT(12)
#define MACB_CAP_CLK_HW_CHG RT_BIT(15)
#define MACB_CAP_MACB_IS_EMAC RT_BIT(16)
#define MACB_CAP_GIGABIT_MODE_AVAILABLE RT_BIT(18)
#define MACB_CAP_SG_DISABLED RT_BIT(19)
#define MACB_CAP_NO_LSO RT_BIT(24)
struct macb_eth;
struct macb_config
{
rt_uint32_t caps;
rt_uint8_t dma_burst_length;
rt_uint16_t jumbo_max_len;
rt_uint16_t max_tx_len;
};
struct macb_dma_desc
{
rt_uint32_t addr;
rt_uint32_t ctrl;
};
struct macb_dma_desc_64
{
rt_uint32_t addrh;
rt_uint32_t resvd;
};
#define MACB_RX_RING_SIZE 32
#define MACB_TX_RING_SIZE 16
#define MACB_RX_BUFFER_SIZE 1536
/* RXBS encoding: buffer_bytes / 64 */
#define MACB_RX_BUFFER_SIZE_DIV64 (MACB_RX_BUFFER_SIZE / 64)
struct macb_eth
{
struct eth_device parent;
#ifdef RT_ETHERNET_CADENCE_PTP
struct rt_ptp_clock ptp_parent;
#endif
struct rt_device *dev;
struct rt_phy_device *phy;
struct mii_bus *mii;
int irq;
void *regs;
struct rt_clk *pclk;
struct rt_clk *hclk;
struct rt_clk *tsu_clk;
struct rt_clk *tx_clk;
rt_uint8_t mac[6];
rt_bool_t is_gem;
rt_bool_t dma_64bit;
rt_bool_t native_io;
rt_bool_t isr_clear_on_write;
rt_uint32_t ncr_shadow;
rt_uint32_t ncfgr_shadow;
const struct macb_config *config;
rt_uint16_t max_tx_len;
int phy_interface;
rt_ssize_t phy_reset_pin;
rt_uint8_t phy_reset_active;
rt_uint16_t phy_reset_ms;
rt_uint8_t aw2w_max_pipe;
rt_uint8_t ar2r_max_pipe;
rt_bool_t use_aw2b_fill;
struct macb_dma_desc *rx_ring;
struct macb_dma_desc *tx_ring;
rt_uint8_t *rx_buffer;
rt_uint8_t *tx_buffer;
rt_size_t dma_blob_size;
rt_ubase_t dma_blob_handle;
rt_ubase_t rx_ring_dma;
rt_ubase_t tx_ring_dma;
rt_ubase_t rx_buffer_dma;
rt_ubase_t tx_buffer_dma;
struct macb_dma_desc *dummy_desc;
rt_ubase_t dummy_desc_dma;
rt_size_t dummy_desc_size;
rt_uint32_t rx_tail;
rt_uint32_t tx_head;
rt_uint32_t tx_tail;
rt_bool_t net_registered;
rt_bool_t irq_installed;
rt_bool_t hw_ready;
rt_bool_t mac_started;
rt_bool_t phy_configured;
#ifdef RT_USING_SYSTEM_WORKQUEUE
struct rt_work phy_retry_work;
int phy_retry_count;
#endif
struct rt_mutex mdio_lock;
struct rt_semaphore tx_sem;
};
#define raw_to_macb_eth(raw) \
rt_container_of(rt_container_of(raw, struct eth_device, parent), struct macb_eth, parent)
#define raw_to_macb_ptp(raw) \
rt_container_of(raw, struct macb_eth, ptp_parent)
rt_inline rt_uint32_t macb_readl(struct macb_eth *eth, rt_uint32_t off)
{
if (eth->native_io)
{
return *(volatile rt_uint32_t *)((rt_uint8_t *)eth->regs + off);
}
return HWREG32(eth->regs + off);
}
rt_inline void macb_writel(struct macb_eth *eth, rt_uint32_t off, rt_uint32_t val)
{
if (eth->native_io)
{
*(volatile rt_uint32_t *)((rt_uint8_t *)eth->regs + off) = val;
}
else
{
HWREG32(eth->regs + off) = val;
}
}
rt_err_t macb_eth_hw_init(struct macb_eth *eth);
void macb_eth_hw_stop(struct macb_eth *eth);
rt_err_t macb_eth_common_probe(struct macb_eth *eth);
rt_err_t macb_eth_common_remove(struct macb_eth *eth);
#ifdef RT_ETHERNET_CADENCE_PTP
rt_err_t macb_ptp_register(struct macb_eth *eth);
void macb_ptp_unregister(struct macb_eth *eth);
#endif
#endif /* __MACB_H__ */
|