1 /*
2 * Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
3 *
4 * Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
5 * the the People's Republic of China and other countries.
6 * All Allwinner Technology Co.,Ltd. trademarks are used with permission.
7 *
8 * DISCLAIMER
9 * THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
10 * IF YOU NEED TO INTEGRATE THIRD PARTY’S TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
11 * IN ALLWINNERS’SDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
12 * ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
13 * ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
14 * COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
15 * YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTY’S TECHNOLOGY.
16 *
17 *
18 * THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
19 * PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
20 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
21 * THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
22 * OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23 * IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
25 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26 * LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32 
33 #ifndef __SUNXI_HAL_GETH_H__
34 #define __SUNXI_HAL_GETH_H__
35 
36 #ifdef __cplusplus
37 extern "C"
38 {
39 #endif
40 
41 #include <rtthread.h>
42 #include <netif/ethernetif.h>
43 #include <sunxi_hal_common.h>
44 #include <sunxi_hal_phy.h>
45 #include <interrupt.h>
46 #include <hal_gpio.h>
47 
48 #define CONFIG_DRIVERS_GETH_DEBUG
49 
50 #ifdef CONFIG_DRIVERS_GETH_DEBUG
51 #define GETH_INFO(fmt, arg...) printf("GPIO : %s()%d "fmt, __func__, __LINE__, ##arg)
52 #define GETH_ERR(fmt, arg...) printf("GPIO : %s()%d "fmt, __func__, __LINE__, ##arg)
53 #else
54 #define GETH_INFO(fmt, arg...) do {}while(0)
55 #define GETH_ERR(fmt, arg...) do {}while(0)
56 #endif
57 
58 /* Base config for geth */
59 #define IOBASE                  0x04500000
60 #define PHY_CLK_REG             (0x03000000 + 0x30)
61 #define CCMU_BASE               0x02001000
62 
63 #define CCMU_GETH_CLK_REG       0x097c
64 #define CCMU_GETH_RST_BIT       16
65 #define CCMU_GETH_GATING_BIT    0
66 #define CCMU_EPHY_CLK_REG       0x0970
67 #define CCMU_EPHY_SCLK_GATING_BIT       31
68 #define CCMU_EPHY_PLL_PERI0_GATING_BIT  30
69 
70 //#define DISABLE_AUTONEG
71 #define CONFIG_HARD_CHECKSUM
72 #define USE_EPHY25M
73 
74 #define GETH_IRQ_NUM 62
75 
76 /* Geth register list */
77 #define GETH_BASIC_CTL0         0x00
78 #define GETH_BASIC_CTL1         0x04
79 #define GETH_INT_STA            0x08
80 #define GETH_INT_EN             0x0C
81 #define GETH_TX_CTL0            0x10
82 #define GETH_TX_CTL1            0x14
83 #define GETH_TX_FLOW_CTL        0x1C
84 #define GETH_TX_DESC_LIST       0x20
85 #define GETH_RX_CTL0            0x24
86 #define GETH_RX_CTL1            0x28
87 #define GETH_RX_DESC_LIST       0x34
88 #define GETH_RX_FRM_FLT         0x38
89 #define GETH_RX_HASH0           0x40
90 #define GETH_RX_HASH1           0x44
91 #define GETH_MDIO_ADDR          0x48
92 #define GETH_MDIO_DATA          0x4C
93 #define GETH_ADDR_HI(reg)       (0x50 + ((reg) << 3))
94 #define GETH_ADDR_LO(reg)       (0x54 + ((reg) << 3))
95 #define GETH_TX_DMA_STA         0xB0
96 #define GETH_TX_CUR_DESC        0xB4
97 #define GETH_TX_CUR_BUF         0xB8
98 #define GETH_RX_DMA_STA         0xC0
99 #define GETH_RX_CUR_DESC        0xC4
100 #define GETH_RX_CUR_BUF         0xC8
101 #define GETH_RGMII_STA          0xD0
102 
103 #define MII_BUSY                0x00000001
104 #define MII_WRITE               0x00000002
105 
106 #define CTL0_DM                 0x01
107 #define CTL0_LM                 0x02
108 #define CTL0_SPEED              0x04
109 
110 #define BURST_LEN               0x3F000000
111 #define RX_TX_PRI               0x02
112 #define SOFT_RST                0x01
113 
114 #define TX_FLUSH                0x01
115 #define TX_MD                   0x02
116 #define TX_NEXT_FRM             0x04
117 #define TX_TH                   0x0700
118 
119 #define RX_FLUSH                0x01
120 #define RX_MD                   0x02
121 #define RX_RUNT_FRM             0x04
122 #define RX_ERR_FRM              0x08
123 #define RX_TH                   0x0030
124 #define STRIP_FCS               0x10000000
125 
126 #define TX_INT                  0x00000001
127 #define TX_STOP_INT             0x00000002
128 #define TX_UA_INT               0x00000004
129 #define TX_TOUT_INT             0x00000008
130 #define TX_UNF_INT              0x00000010
131 #define TX_EARLY_INT            0x00000020
132 #define RX_INT                  0x00000100
133 #define RX_UA_INT               0x00000200
134 #define RX_STOP_INT             0x00000400
135 #define RX_TOUT_INT             0x00000800
136 #define RX_OVF_INT              0x00001000
137 #define RX_EARLY_INT            0x00002000
138 #define LINK_STA_INT            0x00010000
139 
140 /* PHY address */
141 #define PHY_DM                  0x0010
142 #define PHY_AUTO_NEG            0x0020
143 #define PHY_POWERDOWN           0x0080
144 #define PHY_NEG_EN              0x1000
145 
146 #define EXT_PHY                 0
147 #define INT_PHY                 1
148 
149 #define MAX_ADDR_LEN 6
150 
151 #define ENET_FRAME_MAX_FRAMELEN 1518
152 #define DMA_DESC_RX_NUM 64
153 #define DMA_DESC_TX_NUM 64
154 #define DMA_MEM_ALIGN_SIZE  2048
155 
156 #define SYS_PAGE_SIZE (4096U)
157 #define TX_BUFFER_INDEX_NUM (6)
158 #define RX_BUFFER_INDEX_NUM (6)
159 #define TX_BD_INDEX_NUM (1)
160 #define RX_BD_INDEX_NUM (1)
161 
162 #define PBUF_MAX_BUFF_SIZE 1514
163 
164 #define SZ_2K               0x00000800
165 #define MAX_BUF_SZ  (SZ_2K - 1)
166 #define circ_inc(n, s) (((n) + 1) % (s))
167 
168 #define u8 uint8_t
169 #define u16 uint16_t
170 #define u32 uint32_t
171 
172 typedef enum rx_frame_status {
173     good_frame = 0,
174     discard_frame = 1,
175     csum_none = 2,
176     llc_snap = 4,
177 } hal_geth_rx_frame_status_t;
178 
179 typedef union {
180     struct {
181         /* TDES0 */
182         u32 deferred:1;         /* Deferred bit (only half-duplex) */
183         u32 under_err:1;        /* Underflow error */
184         u32 ex_deferral:1;      /* Excessive deferral */
185         u32 coll_cnt:4;         /* Collision count */
186         u32 vlan_tag:1;         /* VLAN Frame */
187 
188         u32 ex_coll:1;          /* Excessive collision */
189         u32 late_coll:1;        /* Late collision */
190         u32 no_carr:1;          /* No carrier */
191         u32 loss_carr:1;        /* Loss of collision */
192 
193         u32 ipdat_err:1;        /* IP payload error */
194         u32 frm_flu:1;          /* Frame flushed */
195         u32 jab_timeout:1;      /* Jabber timeout */
196         u32 err_sum:1;          /* Error summary */
197 
198         u32 iphead_err:1;       /* IP header error */
199         u32 ttss:1;             /* Transmit time stamp status */
200         u32 reserved0:13;
201         u32 own:1;              /* Own bit. CPU:0, DMA:1 */
202     } tx;
203 
204     struct {
205         /* RDES0 */
206         u32 chsum_err:1;        /* Payload checksum error */
207         u32 crc_err:1;          /* CRC error */
208         u32 dribbling:1;        /* Dribble bit error */
209         u32 mii_err:1;          /* Received error (bit3) */
210 
211         u32 recv_wt:1;          /* Received watchdog timeout */
212         u32 frm_type:1;         /* Frame type */
213         u32 late_coll:1;        /* Late Collision */
214         u32 ipch_err:1;         /* IPv header checksum error (bit7) */
215 
216         u32 last_desc:1;        /* Laset descriptor */
217         u32 first_desc:1;       /* First descriptor */
218         u32 vlan_tag:1;         /* VLAN Tag */
219         u32 over_err:1;         /* Overflow error (bit11) */
220 
221         u32 len_err:1;          /* Length error */
222         u32 sou_filter:1;       /* Source address filter fail */
223         u32 desc_err:1;         /* Descriptor error */
224         u32 err_sum:1;          /* Error summary (bit15) */
225 
226         u32 frm_len:14;         /* Frame length */
227         u32 des_filter:1;       /* Destination address filter fail */
228         u32 own:1;              /* Own bit. CPU:0, DMA:1 */
229         #define RX_PKT_OK               0x7FFFB77C
230         #define RX_LEN                  0x3FFF0000
231     } rx;
232 
233     u32 all;
234 } desc0_u;
235 
236 typedef union {
237     struct {
238         /* TDES1 */
239         u32 buf1_size:11;       /* Transmit buffer1 size */
240         u32 buf2_size:11;       /* Transmit buffer2 size */
241         u32 ttse:1;             /* Transmit time stamp enable */
242         u32 dis_pad:1;          /* Disable pad (bit23) */
243 
244         u32 adr_chain:1;        /* Second address chained */
245         u32 end_ring:1;         /* Transmit end of ring */
246         u32 crc_dis:1;          /* Disable CRC */
247         u32 cic:2;              /* Checksum insertion control (bit27:28) */
248         u32 first_sg:1;         /* First Segment */
249         u32 last_seg:1;         /* Last Segment */
250         u32 interrupt:1;        /* Interrupt on completion */
251     } tx;
252 
253     struct {
254         /* RDES1 */
255         u32 buf1_size:11;       /* Received buffer1 size */
256         u32 buf2_size:11;       /* Received buffer2 size */
257         u32 reserved1:2;
258 
259         u32 adr_chain:1;        /* Second address chained */
260         u32 end_ring:1;         /* Received end of ring */
261         u32 reserved2:5;
262         u32 dis_ic:1;           /* Disable interrupt on completion */
263     } rx;
264 
265     u32 all;
266 } desc1_u;
267 
268 typedef struct dma_desc {
269         desc0_u desc0;
270         desc1_u desc1;
271         u32 desc2;
272         u32 desc3;
273         u32 resever0;
274         u32 resever1;
275         u32 resever2;
276         u32 resever3;
277         u32 resever4;
278         u32 resever5;
279         u32 resever6;
280         u32 resever7;
281         u32 resever8;
282         u32 resever9;
283         u32 resever10;
284         u32 resever11;
285 } hal_geth_dma_desc_t;
286 
287 typedef struct geth_buffer_config
288 {
289     hal_geth_dma_desc_t *dma_desc_tx;
290     hal_geth_dma_desc_t *dma_desc_rx;
291     hal_geth_dma_desc_t *phy_dma_desc_tx;
292     hal_geth_dma_desc_t *phy_dma_desc_rx;
293 
294     void *tx_buff_addr;
295     void *rx_buff_addr;
296     void *phy_tx_buff_addr;
297     void *phy_rx_buff_addr;
298 
299 } geth_buffer_config_t;
300 
301 struct geth_device {
302     /* inherit from ethernet device */
303     struct eth_device parent;
304     /* interface address info, hw address */
305     uint8_t dev_addr[MAX_ADDR_LEN];
306     /* ethernet device base address */
307     unsigned long iobase;
308     /* phy mode */
309     phy_interface_t phy_interface;
310     rt_bool_t phy_link_status;
311     geth_buffer_config_t get_buffer_config;
312 
313     uint32_t used_type;
314     uint32_t tx_delay;
315     uint32_t rx_delay;
316 };
317 
318 typedef struct geth_priv {
319     struct hal_gmac_dma_desc_t *dma_desc_tx;
320     struct hal_gmac_dma_desc_t *dma_desc_rx;
321     char *rx_handle_buf;
322 
323     int32_t base;
324     int32_t phy_tpye;
325     int32_t phy_interface;
326 } hal_geth_priv_data_t;
327 
328 typedef struct sunxi_hal_driver_geth {
329     rt_err_t (*initialize)(rt_device_t dev);
330     void (*uninitialize)(rt_device_t dev);
331     int32_t (*get_mac_address)(const unsigned char *addr);
332     int32_t (*set_mac_address)(unsigned char *addr);
333     int32_t (*set_address_filter)(void);
334     rt_err_t (*send)(rt_device_t dev, struct pbuf *p);
335     struct pbuf* (*recv)(rt_device_t dev);
336     //int32_t (*phy_read)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
337     //int32_t (*phy_write)(uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
338 } const sunxi_hal_driver_geth_t;
339 
340 void random_ether_addr(u8 *addr);
341 void geth_set_link_mode(unsigned long iobase, int duplex, int speed);
342 void geth_mac_loopback(unsigned long iobase, int enable);
343 void geth_start_tx(unsigned long iobase);
344 void geth_stop_tx(unsigned long iobase);
345 void geth_start_rx(unsigned long iobase);
346 void geth_stop_rx(unsigned long iobase);
347 uint32_t geth_mac_reset(unsigned long iobase);
348 void geth_mac_init(unsigned long iobase);
349 void geth_set_filter(unsigned long iobase);
350 void geth_set_mac_addr(unsigned long iobase, unsigned char *addr, int index);
351 void geth_mac_enable(unsigned long iobase);
352 void geth_mac_disable(unsigned long iobase);
353 void geth_tx_poll(unsigned long iobase);
354 void geth_rx_poll(unsigned long iobase);
355 void geth_flush_tx(unsigned long iobase);
356 void geth_rx_int_enable(unsigned long iobase);
357 void geth_rx_int_disable(unsigned long iobase);
358 void geth_tx_int_enable(unsigned long iobase);
359 void geth_tx_int_disable(unsigned long iobase);
360 void geth_all_int_disable(unsigned long iobase);
361 void geth_clk_enable(uint32_t used_type,uint32_t phy_interface,uint32_t tx_delay,uint32_t rx_delay);
362 void geth_clk_disable(void);
363 uint32_t geth_mdio_read(unsigned long iobase, int phy_addr, u8 reg);
364 uint32_t geth_mdio_write(unsigned long iobase, int phy_addr, u8 reg, u16 data);
365 void rt_geth_driver_init(void);
366 void geth_loopback_enable(unsigned long iobase);
367 void geth_loopback_disable(unsigned long iobase);
368 
369 
370 #ifdef  __cplusplus
371 }
372 #endif
373 
374 #endif /* __SUNXI_HAL_GETH_H__ */
375