rt-thread/bsp/allwinner/libraries/sunxi-hal/include/hal/sunxi_hal_geth.h

375 lines
12 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (c) 2019-2025 Allwinner Technology Co., Ltd. ALL rights reserved.
*
* Allwinner is a trademark of Allwinner Technology Co.,Ltd., registered in
* the the People's Republic of China and other countries.
* All Allwinner Technology Co.,Ltd. trademarks are used with permission.
*
* DISCLAIMER
* THIRD PARTY LICENCES MAY BE REQUIRED TO IMPLEMENT THE SOLUTION/PRODUCT.
* IF YOU NEED TO INTEGRATE THIRD PARTYS TECHNOLOGY (SONY, DTS, DOLBY, AVS OR MPEGLA, ETC.)
* IN ALLWINNERSSDK OR PRODUCTS, YOU SHALL BE SOLELY RESPONSIBLE TO OBTAIN
* ALL APPROPRIATELY REQUIRED THIRD PARTY LICENCES.
* ALLWINNER SHALL HAVE NO WARRANTY, INDEMNITY OR OTHER OBLIGATIONS WITH RESPECT TO MATTERS
* COVERED UNDER ANY REQUIRED THIRD PARTY LICENSE.
* YOU ARE SOLELY RESPONSIBLE FOR YOUR USAGE OF THIRD PARTYS TECHNOLOGY.
*
*
* THIS SOFTWARE IS PROVIDED BY ALLWINNER"AS IS" AND TO THE MAXIMUM EXTENT
* PERMITTED BY LAW, ALLWINNER EXPRESSLY DISCLAIMS ALL WARRANTIES OF ANY KIND,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WITHOUT LIMITATION REGARDING
* THE TITLE, NON-INFRINGEMENT, ACCURACY, CONDITION, COMPLETENESS, PERFORMANCE
* OR MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* IN NO EVENT SHALL ALLWINNER BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS, OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef __SUNXI_HAL_GETH_H__
#define __SUNXI_HAL_GETH_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include <rtthread.h>
#include <netif/ethernetif.h>
#include <sunxi_hal_common.h>
#include <sunxi_hal_phy.h>
#include <interrupt.h>
#include <hal_gpio.h>
#define CONFIG_DRIVERS_GETH_DEBUG
#ifdef CONFIG_DRIVERS_GETH_DEBUG
#define GETH_INFO(fmt, arg...) printf("GPIO : %s()%d "fmt, __func__, __LINE__, ##arg)
#define GETH_ERR(fmt, arg...) printf("GPIO : %s()%d "fmt, __func__, __LINE__, ##arg)
#else
#define GETH_INFO(fmt, arg...) do {}while(0)
#define GETH_ERR(fmt, arg...) do {}while(0)
#endif
/* Base config for geth */
#define IOBASE 0x04500000
#define PHY_CLK_REG (0x03000000 + 0x30)
#define CCMU_BASE 0x02001000
#define CCMU_GETH_CLK_REG 0x097c
#define CCMU_GETH_RST_BIT 16
#define CCMU_GETH_GATING_BIT 0
#define CCMU_EPHY_CLK_REG 0x0970
#define CCMU_EPHY_SCLK_GATING_BIT 31
#define CCMU_EPHY_PLL_PERI0_GATING_BIT 30
//#define DISABLE_AUTONEG
#define CONFIG_HARD_CHECKSUM
#define USE_EPHY25M
#define GETH_IRQ_NUM 62
/* Geth register list */
#define GETH_BASIC_CTL0 0x00
#define GETH_BASIC_CTL1 0x04
#define GETH_INT_STA 0x08
#define GETH_INT_EN 0x0C
#define GETH_TX_CTL0 0x10
#define GETH_TX_CTL1 0x14
#define GETH_TX_FLOW_CTL 0x1C
#define GETH_TX_DESC_LIST 0x20
#define GETH_RX_CTL0 0x24
#define GETH_RX_CTL1 0x28
#define GETH_RX_DESC_LIST 0x34
#define GETH_RX_FRM_FLT 0x38
#define GETH_RX_HASH0 0x40
#define GETH_RX_HASH1 0x44
#define GETH_MDIO_ADDR 0x48
#define GETH_MDIO_DATA 0x4C
#define GETH_ADDR_HI(reg) (0x50 + ((reg) << 3))
#define GETH_ADDR_LO(reg) (0x54 + ((reg) << 3))
#define GETH_TX_DMA_STA 0xB0
#define GETH_TX_CUR_DESC 0xB4
#define GETH_TX_CUR_BUF 0xB8
#define GETH_RX_DMA_STA 0xC0
#define GETH_RX_CUR_DESC 0xC4
#define GETH_RX_CUR_BUF 0xC8
#define GETH_RGMII_STA 0xD0
#define MII_BUSY 0x00000001
#define MII_WRITE 0x00000002
#define CTL0_DM 0x01
#define CTL0_LM 0x02
#define CTL0_SPEED 0x04
#define BURST_LEN 0x3F000000
#define RX_TX_PRI 0x02
#define SOFT_RST 0x01
#define TX_FLUSH 0x01
#define TX_MD 0x02
#define TX_NEXT_FRM 0x04
#define TX_TH 0x0700
#define RX_FLUSH 0x01
#define RX_MD 0x02
#define RX_RUNT_FRM 0x04
#define RX_ERR_FRM 0x08
#define RX_TH 0x0030
#define STRIP_FCS 0x10000000
#define TX_INT 0x00000001
#define TX_STOP_INT 0x00000002
#define TX_UA_INT 0x00000004
#define TX_TOUT_INT 0x00000008
#define TX_UNF_INT 0x00000010
#define TX_EARLY_INT 0x00000020
#define RX_INT 0x00000100
#define RX_UA_INT 0x00000200
#define RX_STOP_INT 0x00000400
#define RX_TOUT_INT 0x00000800
#define RX_OVF_INT 0x00001000
#define RX_EARLY_INT 0x00002000
#define LINK_STA_INT 0x00010000
/* PHY address */
#define PHY_DM 0x0010
#define PHY_AUTO_NEG 0x0020
#define PHY_POWERDOWN 0x0080
#define PHY_NEG_EN 0x1000
#define EXT_PHY 0
#define INT_PHY 1
#define MAX_ADDR_LEN 6
#define ENET_FRAME_MAX_FRAMELEN 1518
#define DMA_DESC_RX_NUM 64
#define DMA_DESC_TX_NUM 64
#define DMA_MEM_ALIGN_SIZE 2048
#define SYS_PAGE_SIZE (4096U)
#define TX_BUFFER_INDEX_NUM (6)
#define RX_BUFFER_INDEX_NUM (6)
#define TX_BD_INDEX_NUM (1)
#define RX_BD_INDEX_NUM (1)
#define PBUF_MAX_BUFF_SIZE 1514
#define SZ_2K 0x00000800
#define MAX_BUF_SZ (SZ_2K - 1)
#define circ_inc(n, s) (((n) + 1) % (s))
#define u8 uint8_t
#define u16 uint16_t
#define u32 uint32_t
typedef enum rx_frame_status {
good_frame = 0,
discard_frame = 1,
csum_none = 2,
llc_snap = 4,
} hal_geth_rx_frame_status_t;
typedef union {
struct {
/* TDES0 */
u32 deferred:1; /* Deferred bit (only half-duplex) */
u32 under_err:1; /* Underflow error */
u32 ex_deferral:1; /* Excessive deferral */
u32 coll_cnt:4; /* Collision count */
u32 vlan_tag:1; /* VLAN Frame */
u32 ex_coll:1; /* Excessive collision */
u32 late_coll:1; /* Late collision */
u32 no_carr:1; /* No carrier */
u32 loss_carr:1; /* Loss of collision */
u32 ipdat_err:1; /* IP payload error */
u32 frm_flu:1; /* Frame flushed */
u32 jab_timeout:1; /* Jabber timeout */
u32 err_sum:1; /* Error summary */
u32 iphead_err:1; /* IP header error */
u32 ttss:1; /* Transmit time stamp status */
u32 reserved0:13;
u32 own:1; /* Own bit. CPU:0, DMA:1 */
} tx;
struct {
/* RDES0 */
u32 chsum_err:1; /* Payload checksum error */
u32 crc_err:1; /* CRC error */
u32 dribbling:1; /* Dribble bit error */
u32 mii_err:1; /* Received error (bit3) */
u32 recv_wt:1; /* Received watchdog timeout */
u32 frm_type:1; /* Frame type */
u32 late_coll:1; /* Late Collision */
u32 ipch_err:1; /* IPv header checksum error (bit7) */
u32 last_desc:1; /* Laset descriptor */
u32 first_desc:1; /* First descriptor */
u32 vlan_tag:1; /* VLAN Tag */
u32 over_err:1; /* Overflow error (bit11) */
u32 len_err:1; /* Length error */
u32 sou_filter:1; /* Source address filter fail */
u32 desc_err:1; /* Descriptor error */
u32 err_sum:1; /* Error summary (bit15) */
u32 frm_len:14; /* Frame length */
u32 des_filter:1; /* Destination address filter fail */
u32 own:1; /* Own bit. CPU:0, DMA:1 */
#define RX_PKT_OK 0x7FFFB77C
#define RX_LEN 0x3FFF0000
} rx;
u32 all;
} desc0_u;
typedef union {
struct {
/* TDES1 */
u32 buf1_size:11; /* Transmit buffer1 size */
u32 buf2_size:11; /* Transmit buffer2 size */
u32 ttse:1; /* Transmit time stamp enable */
u32 dis_pad:1; /* Disable pad (bit23) */
u32 adr_chain:1; /* Second address chained */
u32 end_ring:1; /* Transmit end of ring */
u32 crc_dis:1; /* Disable CRC */
u32 cic:2; /* Checksum insertion control (bit27:28) */
u32 first_sg:1; /* First Segment */
u32 last_seg:1; /* Last Segment */
u32 interrupt:1; /* Interrupt on completion */
} tx;
struct {
/* RDES1 */
u32 buf1_size:11; /* Received buffer1 size */
u32 buf2_size:11; /* Received buffer2 size */
u32 reserved1:2;
u32 adr_chain:1; /* Second address chained */
u32 end_ring:1; /* Received end of ring */
u32 reserved2:5;
u32 dis_ic:1; /* Disable interrupt on completion */
} rx;
u32 all;
} desc1_u;
typedef struct dma_desc {
desc0_u desc0;
desc1_u desc1;
u32 desc2;
u32 desc3;
u32 resever0;
u32 resever1;
u32 resever2;
u32 resever3;
u32 resever4;
u32 resever5;
u32 resever6;
u32 resever7;
u32 resever8;
u32 resever9;
u32 resever10;
u32 resever11;
} hal_geth_dma_desc_t;
typedef struct geth_buffer_config
{
hal_geth_dma_desc_t *dma_desc_tx;
hal_geth_dma_desc_t *dma_desc_rx;
hal_geth_dma_desc_t *phy_dma_desc_tx;
hal_geth_dma_desc_t *phy_dma_desc_rx;
void *tx_buff_addr;
void *rx_buff_addr;
void *phy_tx_buff_addr;
void *phy_rx_buff_addr;
} geth_buffer_config_t;
struct geth_device {
/* inherit from ethernet device */
struct eth_device parent;
/* interface address info, hw address */
uint8_t dev_addr[MAX_ADDR_LEN];
/* ethernet device base address */
unsigned long iobase;
/* phy mode */
phy_interface_t phy_interface;
rt_bool_t phy_link_status;
geth_buffer_config_t get_buffer_config;
uint32_t used_type;
uint32_t tx_delay;
uint32_t rx_delay;
};
typedef struct geth_priv {
struct hal_gmac_dma_desc_t *dma_desc_tx;
struct hal_gmac_dma_desc_t *dma_desc_rx;
char *rx_handle_buf;
int32_t base;
int32_t phy_tpye;
int32_t phy_interface;
} hal_geth_priv_data_t;
typedef struct sunxi_hal_driver_geth {
rt_err_t (*initialize)(rt_device_t dev);
void (*uninitialize)(rt_device_t dev);
int32_t (*get_mac_address)(const unsigned char *addr);
int32_t (*set_mac_address)(unsigned char *addr);
int32_t (*set_address_filter)(void);
rt_err_t (*send)(rt_device_t dev, struct pbuf *p);
struct pbuf* (*recv)(rt_device_t dev);
//int32_t (*phy_read)(uint8_t phy_addr, uint8_t reg_addr, uint16_t *data);
//int32_t (*phy_write)(uint8_t phy_addr, uint8_t reg_addr, uint16_t data);
} const sunxi_hal_driver_geth_t;
void random_ether_addr(u8 *addr);
void geth_set_link_mode(unsigned long iobase, int duplex, int speed);
void geth_mac_loopback(unsigned long iobase, int enable);
void geth_start_tx(unsigned long iobase);
void geth_stop_tx(unsigned long iobase);
void geth_start_rx(unsigned long iobase);
void geth_stop_rx(unsigned long iobase);
uint32_t geth_mac_reset(unsigned long iobase);
void geth_mac_init(unsigned long iobase);
void geth_set_filter(unsigned long iobase);
void geth_set_mac_addr(unsigned long iobase, unsigned char *addr, int index);
void geth_mac_enable(unsigned long iobase);
void geth_mac_disable(unsigned long iobase);
void geth_tx_poll(unsigned long iobase);
void geth_rx_poll(unsigned long iobase);
void geth_flush_tx(unsigned long iobase);
void geth_rx_int_enable(unsigned long iobase);
void geth_rx_int_disable(unsigned long iobase);
void geth_tx_int_enable(unsigned long iobase);
void geth_tx_int_disable(unsigned long iobase);
void geth_all_int_disable(unsigned long iobase);
void geth_clk_enable(uint32_t used_type,uint32_t phy_interface,uint32_t tx_delay,uint32_t rx_delay);
void geth_clk_disable(void);
uint32_t geth_mdio_read(unsigned long iobase, int phy_addr, u8 reg);
uint32_t geth_mdio_write(unsigned long iobase, int phy_addr, u8 reg, u16 data);
void rt_geth_driver_init(void);
void geth_loopback_enable(unsigned long iobase);
void geth_loopback_disable(unsigned long iobase);
#ifdef __cplusplus
}
#endif
#endif /* __SUNXI_HAL_GETH_H__ */