265 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			265 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /****************************************************************************
 | |
| 
 | |
| Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED.
 | |
| 
 | |
| This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT
 | |
| be copied by any method or incorporated into another program without
 | |
| the express written consent of Aerospace C.Power. This Information or any portion
 | |
| thereof remains the property of Aerospace C.Power. The Information contained herein
 | |
| is believed to be accurate and Aerospace C.Power assumes no responsibility or
 | |
| liability for its use in any way and conveys no license or title under
 | |
| any patent or copyright and makes no representation or warranty that this
 | |
| Information is free from patent or copyright infringement.
 | |
| 
 | |
| ****************************************************************************/
 | |
| 
 | |
| #ifndef _DWC_ETH_H_
 | |
| #define _DWC_ETH_H_
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| extern "C" {
 | |
| #endif
 | |
| 
 | |
| #define ROUND_UP(x, align)         (((uint32_t) (x) + (align - 1)) & ~(align - 1))
 | |
| #define ETH_BUFFER_ALIGN_SIZE(x)    ROUND_UP(x, sizeof(uint32_t))
 | |
| 
 | |
| #define ETH_ADDR_LEN                6
 | |
| #define ETH_TYPE_LEN                2
 | |
| #define ETH_CRC_LEN                 4
 | |
| #define ETH_MAX_LEN                 1518
 | |
| #define ETH_MIN_LEN                 64
 | |
| #define ETH_HDR_LEN                 (ETH_ADDR_LEN*2 + ETH_TYPE_LEN) /* 14 */
 | |
| 
 | |
| #define ETH_MTU         \
 | |
|     (ETH_MAX_LEN - ETH_CRC_LEN) /* 1514 */
 | |
| #define ETH_MIN         \
 | |
|     (ETH_MIN_LEN - ETH_CRC_LEN) /* 60 */
 | |
| 
 | |
| #define ETH_INVALID_LEN(s)  \
 | |
|     (((s) > (ETH_MAX_LEN - ETH_CRC_LEN)) || ((s) < (ETH_MIN_LEN - ETH_CRC_LEN)))
 | |
| 
 | |
| #define ETH_BUFFER_SIZE             ETH_BUFFER_ALIGN_SIZE(ETH_MAX_LEN)
 | |
| #define ETH_MAX_RX_FRAME_CNT        64
 | |
| 
 | |
| #define ETH_SPEED_10M               10
 | |
| #define ETH_SPEED_100M              100
 | |
| /* No need to support 1000M for port up-to CPU. */
 | |
| #define ETH_SPEED_1000M             1000
 | |
| 
 | |
| #define ETH_DUPLEX_HALF             0
 | |
| #define ETH_DUPLEX_FULL             1
 | |
| 
 | |
| #define ETH_RX_FLOWCTRL             1
 | |
| #define ETH_TX_FLOWCTRL             2
 | |
| 
 | |
| #define ETH_PHY_MDI                 0
 | |
| #define ETH_PHY_MDIX                1
 | |
| #define ETH_PHY_MDIX_AUTO           2
 | |
| 
 | |
| #define ETH_DEVICE_UNIT_CNT         1
 | |
| 
 | |
| #define ETH_FILTER_UNICAST          0x1
 | |
| #define ETH_FILTER_MULTICAST        0x2
 | |
| #define ETH_FILTER_BROADCAST        0x4
 | |
| #define ETH_FILTER_PROMISCUOUS      0x8
 | |
| 
 | |
| typedef enum eth_segment
 | |
| {
 | |
|     ETH_SEGMENT_FIRST = 1,
 | |
|     ETH_SEGMENT_LAST = 2,
 | |
|     ETH_SEGMENT_NORMAL = 4
 | |
| }segment_type;
 | |
| 
 | |
| #define DWC_INT_STATUS_MAC          0x00020000
 | |
| #define DWC_INT_STATUS_MTL          0x00010000
 | |
| #define DWC_INT_STATUS_DMA          0x000000FF
 | |
| 
 | |
| #define DWC_DMA_intTxCompleted      0x00000001
 | |
| #define DWC_DMA_intTxStopped        0x00000002
 | |
| #define DWC_DMA_intTxBufferRunout   0x00000004
 | |
| #define DWC_DMA_intRxCompleted      0x00000040
 | |
| #define DWC_DMA_intRxBufferRunout   0x00000080
 | |
| #define DWC_DMA_intRxStopped        0x00000100
 | |
| #define DWC_DMA_intRxWDTTimeout     0x00000200
 | |
| //#define DWC_DMA_intRxEarly          0x00000400
 | |
| //#define DWC_DMA_intTxEarly          0x00000800
 | |
| #define DWC_DMA_intRxEarly          0x00000800
 | |
| #define DWC_DMA_intTxEarly          0x00000400
 | |
| #define DWC_DMA_intBusError         0x00001000
 | |
| #define DWC_DMA_intContextDesError  0x00002000
 | |
| #define DWC_DMA_intAbnormalSum      0x00004000
 | |
| #define DWC_DMA_intNormalSum        0x00008000
 | |
| 
 | |
| #define DWC_DMA_intStatusTxDmaBitError  0x00070000
 | |
| #define DWC_DMA_intStatusRxDmaBitError  0x00380000
 | |
| 
 | |
| #define DWC_MTL_intEnableRxOverflow     0x01000000
 | |
| #define DWC_MTL_intStatusRxOverflow     0x00010000
 | |
| #define DWC_MTL_intEnableAverageBits    0x00000200
 | |
| #define DWC_MTL_intEnableTxUnderflow    0x00000100
 | |
| #define DWC_MTL_intStatusAverageBits    0x00000002
 | |
| #define DWC_MTL_INTStatusTxUnderflow    0x00000001
 | |
| 
 | |
| 
 | |
| #define DWC_ETH_INT_TX_MASK         \
 | |
|     (DWC_DMA_intTxCompleted | DWC_DMA_intTxEarly)
 | |
| 
 | |
| #define DWC_ETH_INT_RX_MASK         \
 | |
|     (DWC_DMA_intRxEarly | DWC_DMA_intRxBufferRunout | DWC_DMA_intRxCompleted)
 | |
| 
 | |
| #define DWC_ETH_INT_TRX_MASK        (DWC_ETH_INT_TX_MASK | DWC_ETH_INT_RX_MASK)
 | |
| 
 | |
| #define DWC_ETH_INT_MASK            \
 | |
|     (DWC_ETH_INT_TRX_MASK | DWC_DMA_intAbnormalSum | DWC_DMA_intNormalSum)
 | |
| 
 | |
| #define DWC_ETH_INT_MMC_MASK    \
 | |
|     (MMCIS_MASK | MMCRXIS_MASK | MMCTXIS_MASK | MMCRXIPIS_MASK)
 | |
| 
 | |
| /* RDES0 */
 | |
| #define DWC_DESC_DESC0(d)           \
 | |
|     (*(volatile uint32_t *)((uint32_t)(d)+(0)))
 | |
| 
 | |
| /* RDES1 */
 | |
| #define DWC_DESC_DESC1(d)           \
 | |
|     (*(volatile uint32_t *)((uint32_t)(d)+(sizeof(uint32_t))))
 | |
| 
 | |
| /* RDES2 */
 | |
| #define DWC_DESC_DESC2(d)            \
 | |
|     (*(volatile uint32_t *)((uint32_t)(d)+(2*sizeof(uint32_t))))
 | |
| 
 | |
| /* RDES3 */
 | |
| #define DWC_DESC_DESC3(d)          \
 | |
|     (*(volatile uint32_t *)((uint32_t)(d)+(3*sizeof(uint32_t))))
 | |
| 
 | |
| /* RDES4 */
 | |
| /* For tx it's a iot_pkt_t*, for rx it's just a pointer of data buffer. */
 | |
| #define DWC_DESC_BUFFER(d)             \
 | |
|     (*(volatile uint32_t *)((uint32_t)(d)+(4*sizeof(uint32_t))))
 | |
| 
 | |
| #define DWC_DESC_DATA_LEN_BITS      0x00003FFF
 | |
| #define DWC_DESC_DATA_LEN_OFFSET    0
 | |
| #define DWC_DESC_GET_DATA_LEN(p)        \
 | |
|     (((p) & DWC_DESC_DATA_LEN_BITS) >> DWC_DESC_DATA_LEN_OFFSET)
 | |
| #define DWC_DESC_DATA_LEN(len)        \
 | |
|     (((len) << DWC_DESC_DATA_LEN_OFFSET) & DWC_DESC_DATA_LEN_BITS)
 | |
| 
 | |
| #define DWC_DESC_STATUS_OWNER_DMA   0x80000000
 | |
| #define DWC_DESC_STATUS_FIRST_SEG   0x20000000
 | |
| #define DWC_DESC_STATUS_LAST_SEG    0x10000000
 | |
| #define DWC_DESC_STATUS_ERROR_SUM   0x00008000
 | |
| #define DWC_DESC_STATUS_CRC_PAD_INS 0x00000000
 | |
| #define DWC_DESC_STATUS_CRC_INS     0x04000000
 | |
| #define DWC_DESC_STATUS_CRC_REP     0x0C000000
 | |
| #define DWC_DESC_STATUS_CTXT        0x40000000
 | |
| #define DWC_DESC_STATUS_SA_REP_R1   0x01000000
 | |
| 
 | |
| #define DWC_DESC_STATUS_INT_ENA     0x40000000
 | |
| #define DWC_DESC_STATUS_BUF_2_ENA   0x02000000
 | |
| #define DWC_DESC_STATUS_BUF_1_ENA   0x01000000
 | |
| 
 | |
| #define DWC_DESC_CTRL_INT_ENA       0x80000000
 | |
| #define DWC_DESC_CTRL_BUF1_LEN(len) \
 | |
|     (((len) << DWC_DESC_DATA_LEN_OFFSET) & DWC_DESC_DATA_LEN_BITS)
 | |
| 
 | |
| #define DWC_RTXQEN_MODE             0x00000002
 | |
| #define DWC_RTXPBL                  0x00000010
 | |
| #define DWC_RTXQ_SIZE_1K            0x00000003
 | |
| 
 | |
| typedef struct port_statistics
 | |
| {
 | |
|     uint32_t    bytes_toltal; /* Toltal bytes of transfered packets */
 | |
|     uint32_t    pk_toltal; /* Toltal packets transfered */
 | |
|     uint32_t    pk_tf_uni; /* Unicast packets transfered */
 | |
|     uint32_t    pk_tf_broad; /* Broadcast packets transfered */
 | |
|     uint32_t    pk_tf_multi; /* Multicast packets transfered */
 | |
|     uint32_t    pk_dp_uni; /* Unicast packets dropped */
 | |
|     uint32_t    pk_dp_broad; /* Broadcast packets dropped */
 | |
|     uint32_t    pk_dp_multi; /* Multicast packets dropped */
 | |
| }t_dwc_stat;
 | |
| 
 | |
| typedef struct port_cfg
 | |
| {
 | |
|     uint8_t     enable; /* 1:enable this port. 0:disable this port. */
 | |
|     uint8_t     autonegotiation; /* 1:enable autonegotiation.
 | |
|                                 0:disable autonegotiation. */
 | |
|     uint8_t     speed; /* Port speed. Like ETH_SPEED_10M. */
 | |
|     uint8_t     duplex; /* Duplex set. Like ETH_DUPLEX_FULL. */
 | |
|     uint8_t     mdix;
 | |
|     uint8_t     flowctrl;
 | |
|     uint16_t    filter; /* Default to be set as UNICAST|BROADCAST  */
 | |
| }t_port_cfg;
 | |
| 
 | |
| typedef struct dwc_dma
 | |
| {
 | |
|     uint32_t des0;
 | |
|     uint32_t des1;
 | |
|     uint32_t des2;
 | |
|     uint32_t des3;
 | |
|     uint32_t pkt;
 | |
| }t_dwc_dma;
 | |
| 
 | |
| #define DWC_DES_MEB_END_SIZE(type, meb)   \
 | |
|     (((int)(&(((type*)0)->meb))) + sizeof(((type*)0)->meb))
 | |
| 
 | |
| #define DWC_DES_SKIP    \
 | |
|     ((sizeof(t_dwc_dma) - DWC_DES_MEB_END_SIZE(t_dwc_dma, des3)) / sizeof(int))
 | |
| 
 | |
| typedef struct dma_buf
 | |
| {
 | |
|     void        *desc_base;
 | |
|     void        *buf_base;
 | |
|     t_dwc_dma   *desc[ETH_MAX_RX_FRAME_CNT];
 | |
|     uint32_t    dinx;
 | |
|     uint32_t    last_dinx;
 | |
| }t_dwc_buf;
 | |
| 
 | |
| typedef struct multicast_list
 | |
| {
 | |
|     struct multicast_list *next;
 | |
|     uint8_t     addr[ETH_ADDR_LEN];
 | |
| }t_dwc_mcast;
 | |
| 
 | |
| typedef struct dwc_dev
 | |
| {
 | |
|     uint32_t    in_use;
 | |
|     uint8_t     unit;
 | |
|     uint8_t     phy_addr;
 | |
|     uint8_t     eth_addr[ETH_ADDR_LEN];
 | |
|     uint32_t    int_status;
 | |
|     uint32_t    int_handle;
 | |
|     void (*dwc_packet_recv)(struct dwc_dev *pc, uint8_t *p_data, uint32_t len);
 | |
|     t_port_cfg  port_cfg;
 | |
|     t_dwc_stat  statistics;
 | |
|     t_dwc_buf   rxd;
 | |
|     t_dwc_buf   txd;
 | |
|     t_dwc_mcast *mcast_lst;
 | |
| }t_dwc_ctrl;
 | |
| 
 | |
| t_dwc_ctrl * dwc_eth_open(int unit, void *recv_func);
 | |
| 
 | |
| int dwc_eth_config(t_dwc_ctrl *p_ctrl, t_port_cfg *p_cfg, uint8_t *addr);
 | |
| 
 | |
| int dwc_mac_addr_get(t_dwc_ctrl *p_ctrl, uint8_t *addr);
 | |
| 
 | |
| int dwc_eth_mcast_addr_add(t_dwc_ctrl *p_ctrl, uint8_t addr[]);
 | |
| 
 | |
| int dwc_eth_start(t_dwc_ctrl *p_ctrl);
 | |
| 
 | |
| int dwc_eth_restart(t_dwc_ctrl *p_ctrl);
 | |
| 
 | |
| int dwc_eth_send_frame(t_dwc_ctrl *p_ctrl, iot_pkt_ls* pkt_l);
 | |
| 
 | |
| int dwc_eth_close(t_dwc_ctrl *p_ctrl);
 | |
| 
 | |
| uint8_t dwc_eth_get_link_status(t_dwc_ctrl *p_ctrl);
 | |
| 
 | |
| int dwc_eth_init(void);
 | |
| 
 | |
| 
 | |
| 
 | |
| #ifdef __cplusplus
 | |
| }
 | |
| #endif
 | |
| 
 | |
| #endif
 |