/** * @file sdrv_eth.h * @brief SemiDrive ethernet mac driver header file * * @copyright Copyright (c) 2021 Semidrive Semiconductor. * All rights reserved. * * Revision History: * ----------------- */ #ifndef DWC_ETH_QOS_H #define DWC_ETH_QOS_H #include #include #include "sdrv_ckgen.h" #include "sdrv_rstgen.h" #include "netdev.h" #include "../source/eth/sdrv_mac_lld.h" #include "../source/eth/phy/phy.h" #ifndef CONFIG_ETH_RX_DESCRIPTOR_NUM #define CONFIG_ETH_RX_DESCRIPTOR_NUM 4 #endif #ifndef CONFIG_ETH_TX_DESCRIPTOR_NUM #define CONFIG_ETH_TX_DESCRIPTOR_NUM 4//32 #endif /* assume ARCH_DMA_MINALIGN >= 16; 16 is the EQOS HW minimum */ #define ARCH_DMA_MINALIGN CONFIG_ARCH_CACHE_LINE /* Should be cache line aligned */ #define EQOS_DESCRIPTOR_ALIGN ARCH_DMA_MINALIGN #define EQOS_DESCRIPTORS_TX CONFIG_ETH_TX_DESCRIPTOR_NUM #define EQOS_DESCRIPTORS_RX CONFIG_ETH_RX_DESCRIPTOR_NUM #define EQOS_DESCRIPTORS_NUM (EQOS_DESCRIPTORS_TX + EQOS_DESCRIPTORS_RX) #define EQOS_BUFFER_ALIGN ARCH_DMA_MINALIGN #define EQOS_MAX_PACKET_SIZE ALIGN(1568, ARCH_DMA_MINALIGN) #define EQOS_RX_BUFFER_SIZE (EQOS_DESCRIPTORS_RX * EQOS_MAX_PACKET_SIZE) #define EQOS_TX_BUFFER_SIZE (EQOS_DESCRIPTORS_TX * EQOS_MAX_PACKET_SIZE) /* If rx api thread safe is guranteed by driver, * the two following macros should be defined. */ #ifndef EQOS_RX_LOCK #define EQOS_RX_LOCK(eqos) #endif #ifndef EQOS_RX_UNLOCK #define EQOS_RX_UNLOCK(eqos) #endif /* If tx api thread safe is guranteed by driver, * the two following macros should be defined. */ #ifndef EQOS_TX_LOCK #define EQOS_TX_LOCK(eqos) #endif #ifndef EQOS_TX_UNLOCK #define EQOS_TX_UNLOCK(eqos) #endif /* DMA descriptor */ /* DO NOT align this struct to cache line length, * because length of this struct is used to caculate * DSL bit value of DMA_CH_CONTROL register. * Aligning eqos dma descriptors to cache line length * is done when allocating descriptors. */ struct eqos_desc { volatile uint32_t des0; volatile uint32_t des1; volatile uint32_t des2; volatile uint32_t des3; }; #define EQOS_DESC3_OWN BIT(31) #define EQOS_DESC3_IOC BIT(30) #define EQOS_DESC3_FD BIT(29) #define EQOS_DESC3_LD BIT(28) #define EQOS_DESC3_BUF1V BIT(24) typedef enum { ETHERNET1_IDX = 0, ETHERNET2_IDX, } eth_idx_type; typedef enum { /* Controller Disable */ ETH_MODE_DOWN = 0, /* Controller Enable */ ETH_MODE_ACTIVE, } eth_mode_type; typedef enum { /* add the MAC address to the filter, meaning allow reception */ ETH_ADD_TO_FILTER = 0, /* remove the MAC address from the filter, meaning reception is blocked in the lower layer */ ETH_REMOVE_FROM_FILTER, } eth_filter_action_type; typedef enum { ETH_MAC_LAYER_SPEED_100M = 0, ETH_MAC_LAYER_SPEED_10G, ETH_MAC_LAYER_SPEED_10M, ETH_MAC_LAYER_SPEED_1G } eth_mac_layer_speed_type; typedef enum { /* MAC layer interface (data) bandwith class 1Gbit/s (e.g. GMII, RGMII, SGMII, RvGMII, USGMII)*/ ETH_MAC_LAYER_TYPE_XGMII = 0, /* MAC layer interface (data) bandwith class 100Mbit/s (e.g. RMII, RvMII, SMII, RvMII) */ ETH_MAC_LAYER_TYPE_XMII, /* MAC layer interface (data) bandwith class 10Gbit/s */ ETH_MAC_LAYER_TYPE_XXGMII, } eth_mac_layer_type; typedef enum { LIGHT = 0, REDUCED, REVERSED, SERIAL, STANDARD, UNIVERSAL_SERIAL } eth_mac_layer_sub_type; typedef enum { ETH_PHY_INTF_SEL_GMII = 0, ETH_PHY_INTF_SEL_RGMII, ETH_PHY_INTF_SEL_SGMII, ETH_PHY_INTF_SEL_TBI, ETH_PHY_INTF_SEL_RMII, ETH_PHY_INTF_SEL_RTBI, ETH_PHY_INTF_SEL_SMII, ETH_PHY_INTF_SEL_REVMII, ETH_PHY_INTF_SEL_MII, } eth_phy_intf_mode_type; typedef struct { uint32_t base; uint32_t irq_num; uint32_t mtu; uint8_t *mac_addr; /* Bus width, unit: bit. */ uint8_t dma_bus_width; /* clock & reset */ sdrv_ckgen_node_t *tx_clk; sdrv_ckgen_node_t *rmii_clk; sdrv_ckgen_node_t *phy_ref_clk; sdrv_ckgen_node_t *timer_sec_clk; sdrv_rstgen_sig_t *rst; /* mii interface config */ eth_phy_intf_mode_type phy_intf_mode; void (*set_phy_intf)(uint32_t base, eth_phy_intf_mode_type mode); /* ipv4 config */ uint8_t ip[4]; uint8_t mask[4]; /* All PHYs connected to this mac */ phy_dev_t *phy; } dwc_eth_config_t; struct eqos_priv { void *descs; int tx_desc_idx, rx_desc_idx; unsigned int desc_size; /* Channel control register DSL bits. */ uint32_t dsl; void *tx_dma_buf; void *rx_dma_buf; bool started; }; typedef void (*dma_rx_int_cb_t)(struct net_driver_s *dev); typedef struct dwc_eth_dev { bool init; dwc_eth_config_t *config; struct eqos_priv *eqos; dma_rx_int_cb_t rx_cb; phy_bus_t phy_bus; void *(*to_cpu_addr)(void *slave_addr); } dwc_eth_dev_t; /** * @brief Enable rx interrupt. * * When receive is completed, callback will be executed. * * @param [in] dev eth device. * @param [in] callback receive complete callback. */ void dwc_eth_enable_dma_rx_int(struct net_driver_s *dev, dma_rx_int_cb_t callback); /** * @brief try to read rx packet and send the packet to lwip stack. * Should be called in thread context. * If enable DMA rx interrupt, i.e. poll is false, this function * should be called after DMA rx interrupt triggered. DMA rx * interrupt will be disabled in ISR, and re-enabled in this * function after reading out all rx packets, this is helpful to * avoid too much rx interrupt. * * @param [in] dev eth device * @param [in] poll true for polling read, false for interrupt read * @return int total length of rx packets or -1 if rx nothing */ int dwc_eth_rx(struct net_driver_s *dev, bool pool); /** * @brief Initializes net driver. * * @param [in] dev eth device. * @param [in] cfg Configuration of ethernet. * @return int return ERR_OK if initialization can be completed. */ int dwc_eth_probe(struct net_driver_s *dev, dwc_eth_config_t *cfg); #endif