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
|
/*
* Copyright (c) 2006-2022, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2022-11-26 GuEe-GUI first version
*/
#ifndef __DWMAC_H__
#define __DWMAC_H__
#include <rthw.h>
#include <rtthread.h>
#include <rtdevice.h>
#include <drivers/misc.h>
#include "../ethernet_dm.h"
/* GMAC4 MAC registers (offset from mac_base) */
#define GMAC_CONFIG 0x0000
#define GMAC_PACKET_FILTER 0x0008
#define GMAC_MDIO_ADDR 0x0200
#define GMAC_MDIO_DATA 0x0204
#define GMAC_ADDR_HIGH(reg) (0x0300 + (reg) * 8)
#define GMAC_ADDR_LOW(reg) (0x0304 + (reg) * 8)
#define GMAC_RXQ_CTRL0 0x00a0
#define GMAC_RXQ_CTRL1 0x00a4
#define GMAC_CONFIG_RE RT_BIT(0)
#define GMAC_CONFIG_TE RT_BIT(1)
#define GMAC_CONFIG_DM RT_BIT(13)
#define GMAC_CONFIG_FES RT_BIT(14)
#define GMAC_CONFIG_PS RT_BIT(15)
#define GMAC_CONFIG_IPC RT_BIT(27)
#define GMAC_PF_PM RT_BIT(4)
#define GMAC_RX_DCB_QUEUE_ENABLE(q) RT_BIT(((q) * 2) + 1)
#define GMAC_RXQCTRL_MCBCQEN RT_BIT(20)
#define GMAC_RXQCTRL_MCBCQ_MASK RT_GENMASK(18, 16)
#define GMAC_RXQCTRL_MCBCQ_SHIFT 16
/* DMA top-level (offset from mac_base) */
#define DMA_BUS_MODE 0x1000
#define DMA_SYS_BUS_MODE 0x1004
#define DMA_BUS_MODE_SFT_RESET RT_BIT(0)
#define DMA_SYS_BUS_FB RT_BIT(0)
#define DMA_SYS_BUS_MB RT_BIT(14)
#define DMA_SYS_BUS_AAL RT_BIT(12)
#define DMA_AXI_BLEN16 RT_BIT(3)
#define DMA_AXI_BLEN8 RT_BIT(2)
#define DMA_AXI_BLEN4 RT_BIT(1)
#define DMA_AXI_BLEN32 RT_BIT(4)
#define DMA_AXI_BLEN64 RT_BIT(5)
#define DMA_AXI_BLEN128 RT_BIT(6)
#define DMA_AXI_BLEN256 RT_BIT(7)
#define DMA_AXI_WR_OSR_LMT_SHIFT 24
#define DMA_AXI_RD_OSR_LMT_SHIFT 16
#define DMA_CHAN_BASE 0x1100
#define DMA_CHAN_OFFSET 0x80
#define DMA_CHAN_CONTROL(c) (DMA_CHAN_BASE + (c) * DMA_CHAN_OFFSET)
#define DMA_CHAN_TX_CONTROL(c) (DMA_CHAN_CONTROL(c) + 0x04)
#define DMA_CHAN_RX_CONTROL(c) (DMA_CHAN_CONTROL(c) + 0x08)
#define DMA_CHAN_TX_BASE_ADDR(c) (DMA_CHAN_CONTROL(c) + 0x14)
#define DMA_CHAN_RX_BASE_ADDR(c) (DMA_CHAN_CONTROL(c) + 0x1c)
#define DMA_CHAN_TX_END_ADDR(c) (DMA_CHAN_CONTROL(c) + 0x20)
#define DMA_CHAN_RX_END_ADDR(c) (DMA_CHAN_CONTROL(c) + 0x28)
#define DMA_CHAN_TX_RING_LEN(c) (DMA_CHAN_CONTROL(c) + 0x2c)
#define DMA_CHAN_RX_RING_LEN(c) (DMA_CHAN_CONTROL(c) + 0x30)
#define DMA_CHAN_INTR_ENA(c) (DMA_CHAN_CONTROL(c) + 0x34)
#define DMA_CHAN_STATUS(c) (DMA_CHAN_CONTROL(c) + 0x60)
#define DMA_CONTROL_ST RT_BIT(0)
#define DMA_CONTROL_SR RT_BIT(0)
#define DMA_CONTROL_OSP RT_BIT(4)
#define DMA_CONTROL_TSE RT_BIT(12)
#define DMA_BUS_MODE_PBL_SHIFT 16
#define DMA_BUS_MODE_RPBL_SHIFT 16
#define DMA_RBSZ_SHIFT 1
#define DMA_RBSZ_MASK RT_GENMASK(14, 1)
#define DMA_CHAN_STATUS_TI RT_BIT(0)
#define DMA_CHAN_STATUS_RI RT_BIT(6)
#define DMA_CHAN_STATUS_NIS RT_BIT(15)
#define DMA_CHAN_INTR_ENA_RIE RT_BIT(6)
#define DMA_CHAN_INTR_ENA_TIE RT_BIT(0)
#define DMA_CHAN_INTR_ENA_NIE RT_BIT(16)
#define DMA_CHAN_INTR_ENA_AIE RT_BIT(15)
#define DMA_CHAN_INTR_ENA_NIE_4_10 RT_BIT(15)
#define DMA_CHAN_INTR_ENA_AIE_4_10 RT_BIT(14)
#define DMA_CHAN_INTR_ENA_FBE RT_BIT(12)
#define DMA_CHAN_INTR_DEFAULT_MASK (DMA_CHAN_INTR_ENA_NIE | \
DMA_CHAN_INTR_ENA_AIE | \
DMA_CHAN_INTR_ENA_FBE | \
DMA_CHAN_INTR_ENA_RIE | \
DMA_CHAN_INTR_ENA_TIE)
#define DMA_CHAN_INTR_DEFAULT_MASK_4_10 (DMA_CHAN_INTR_ENA_NIE_4_10 | \
DMA_CHAN_INTR_ENA_AIE_4_10 | \
DMA_CHAN_INTR_ENA_FBE | \
DMA_CHAN_INTR_ENA_RIE | \
DMA_CHAN_INTR_ENA_TIE)
#define MTL_OPERATION_MODE 0x0c00
#define MTL_RXQ_DMA_MAP0 0x0c30
#define MTL_RXQ_DMA_QXMDMACH_MASK(q) (0xf << (8 * (q)))
#define MTL_RXQ_DMA_QXMDMACH(chan, q) ((chan) << (8 * (q)))
#define MTL_CHAN_BASE 0x0d00
#define MTL_CHAN_OFFSET 0x40
#define MTL_CHAN_TX_OP_MODE(c) (MTL_CHAN_BASE + (c) * MTL_CHAN_OFFSET)
#define MTL_CHAN_RX_OP_MODE(c) (MTL_CHAN_BASE + (c) * MTL_CHAN_OFFSET + 0x30)
#define MTL_OP_MODE_RSF RT_BIT(5)
#define MTL_OP_MODE_TSF RT_BIT(1)
#define MTL_OP_MODE_TXQEN RT_BIT(3)
/* Enhanced descriptors (DWMAC4) */
#define TDES2_BUFFER1_SIZE_MASK RT_GENMASK(13, 0)
#define TDES3_PACKET_SIZE_MASK RT_GENMASK(14, 0)
#define TDES3_CHECKSUM_INSERTION_SHIFT 16
#define TDES3_CHECKSUM_INSERTION_FULL (3 << TDES3_CHECKSUM_INSERTION_SHIFT)
#define TDES3_FIRST_DESCRIPTOR RT_BIT(29)
#define TDES3_LAST_DESCRIPTOR RT_BIT(28)
#define TDES3_OWN RT_BIT(31)
#define RDES3_OWN RT_BIT(31)
#define RDES3_INT_ON_COMPLETION_EN RT_BIT(30)
#define RDES3_BUFFER1_VALID_ADDR RT_BIT(24)
#define RDES3_PACKET_SIZE_MASK RT_GENMASK(14, 0)
#define MII_ADDR_GBUSY RT_BIT(0)
#define MII_DATA_GD_MASK RT_GENMASK(15, 0)
#define MII_GMAC4_GOC_SHIFT 2
#define MII_GMAC4_WRITE (1 << MII_GMAC4_GOC_SHIFT)
#define MII_GMAC4_READ (3 << MII_GMAC4_GOC_SHIFT)
#define MII_GMAC4_ADDR_SHIFT 21
#define MII_GMAC4_ADDR_MASK RT_GENMASK(25, 21)
#define MII_GMAC4_REG_SHIFT 16
#define MII_GMAC4_REG_MASK RT_GENMASK(20, 16)
#define MII_GMAC4_CSR_SHIFT 8
#define MII_GMAC4_CSR_100_150M (0x4 << MII_GMAC4_CSR_SHIFT)
#define DWMAC_RX_RING_SIZE 32
#define DWMAC_TX_RING_SIZE 16
#define DWMAC_RX_BUFFER_SIZE 1536
#define DWMAC_CHAN 0
#define DWMAC_DMA_PBL 8
#define DWMAC_MDIO_TIMEOUT_US 10000
enum dwmac_core_type
{
DWMAC_CORE_GMAC4,
};
struct dwmac_desc
{
rt_uint32_t des0;
rt_uint32_t des1;
rt_uint32_t des2;
rt_uint32_t des3;
};
#define DWMAC_CAP_TSO RT_BIT(0)
#define DWMAC_CAP_PTP RT_BIT(1)
struct dwmac_axi_cfg
{
rt_uint32_t wr_osr_lmt;
rt_uint32_t rd_osr_lmt;
rt_bool_t fixed_burst;
rt_bool_t mixed_burst;
rt_bool_t aal;
rt_uint32_t blen_mask;
};
struct dwmac_mtl_cfg
{
rt_uint32_t rx_queues;
rt_uint32_t tx_queues;
};
struct dwmac_eth;
struct dwmac_plat_ops
{
rt_uint32_t flags;
rt_err_t (*parse_ofw)(struct dwmac_eth *eth);
rt_err_t (*init)(struct dwmac_eth *eth);
void (*exit)(struct dwmac_eth *eth);
rt_err_t (*fix_link_speed)(struct dwmac_eth *eth, int speed);
};
struct dwmac_config
{
enum dwmac_core_type core_type;
rt_uint32_t caps;
rt_uint8_t dma_pbl;
const struct dwmac_plat_ops *plat;
};
struct dwmac_eth
{
struct eth_device parent;
struct rt_device *dev;
void *mac_base;
int irq;
struct rt_phy_device *phy;
struct mii_bus *mii;
rt_uint8_t mac[6];
int phy_interface;
struct rt_clk *stmmac_clk;
struct rt_clk *mac_clk_speed;
struct rt_clk *mac_clk_rx;
struct rt_clk *mac_clk_tx;
struct rt_clk *clk_mac_refout;
struct rt_clk *ptp_clk;
struct rt_clk *aclk;
struct rt_clk *pclk;
struct rt_reset_control *rst;
#ifdef RT_USING_REGULATOR
struct rt_regulator *phy_supply;
#endif
rt_ssize_t phy_reset_pin;
rt_uint8_t phy_reset_active;
rt_uint32_t phy_reset_delays[3];
struct dwmac_desc *rx_ring;
struct dwmac_desc *tx_ring;
rt_ubase_t rx_ring_dma;
rt_ubase_t tx_ring_dma;
rt_uint8_t *rx_buffers;
rt_ubase_t rx_buffers_dma;
rt_uint8_t *tx_buffers;
rt_ubase_t tx_buffers_dma;
rt_size_t dma_blob_size;
rt_ubase_t dma_blob_handle;
rt_uint32_t tx_idx;
rt_uint32_t rx_idx;
rt_uint8_t dma_pbl;
rt_uint8_t dma_txpbl;
rt_uint8_t dma_rxpbl;
rt_bool_t tso_en;
struct dwmac_axi_cfg axi;
struct dwmac_mtl_cfg mtl;
rt_bool_t hw_ready;
rt_bool_t mac_started;
rt_bool_t net_registered;
rt_bool_t irq_installed;
rt_bool_t phy_configured;
#ifdef RT_USING_SYSTEM_WORKQUEUE
struct rt_work phy_retry_work;
rt_bool_t phy_work_inited;
#endif
const struct dwmac_config *config;
void *plat_priv;
#ifdef RT_ETHERNET_DWMAC_PTP
struct rt_ptp_clock ptp_parent;
rt_uint32_t ptp_clk_rate;
rt_uint32_t default_addend;
rt_uint32_t sub_second_inc;
rt_uint32_t systime_flags;
rt_uint8_t pps_out_num;
rt_uint8_t aux_snapshot_num;
#endif /* RT_ETHERNET_DWMAC_PTP */
};
#define dwmac_readl(eth, reg) HWREG32((rt_uint8_t *)(eth)->mac_base + (reg))
#define dwmac_writel(eth, reg, val) HWREG32((rt_uint8_t *)(eth)->mac_base + (reg)) = (val)
rt_inline const struct dwmac_plat_ops *dwmac_plat(const struct dwmac_eth *eth)
{
if (eth && eth->config && eth->config->plat)
{
return eth->config->plat;
}
return RT_NULL;
}
rt_err_t dwmac_probe(struct dwmac_eth *eth);
rt_err_t dwmac_remove(struct dwmac_eth *eth);
rt_err_t dwmac_eth_common_probe(struct dwmac_eth *eth);
rt_err_t dwmac_eth_common_remove(struct dwmac_eth *eth);
#ifdef RT_ETHERNET_DWMAC_PTP
rt_err_t dwmac_ptp_register(struct dwmac_eth *eth);
void dwmac_ptp_unregister(struct dwmac_eth *eth);
#endif /* RT_ETHERNET_DWMAC_PTP */
#endif /* __DWMAC_H__ */
|