| #ifndef _DWMAC_H |
| #define _DWMAC_H |
| |
| /** @file |
| * |
| * Synopsys DesignWare MAC network driver |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| |
| #include <stdint.h> |
| #include <ipxe/if_ether.h> |
| |
| /** I/O region index */ |
| #define DWMAC_REG_IDX 0 |
| |
| /** I/O region length */ |
| #define DWMAC_REG_LEN 0x2000 |
| |
| /** MAC register block */ |
| #define DWMAC_MAC 0x0000 |
| #define DWMAC_MAC_REG( n ) ( DWMAC_MAC + ( (n) * 4 ) ) |
| |
| /** MAC configuration register */ |
| #define DWMAC_CFG DWMAC_MAC_REG ( 0 ) |
| #define DWMAC_CFG_DO 0x00002000 /**< Disable RX own frames */ |
| #define DWMAC_CFG_FD 0x00000800 /**< Full duplex */ |
| #define DWMAC_CFG_TXEN 0x00000008 /**< TX enabled */ |
| #define DWMAC_CFG_RXEN 0x00000004 /**< RX enabled */ |
| |
| /** MAC filter register */ |
| #define DWMAC_FILTER DWMAC_MAC_REG ( 1 ) |
| #define DWMAC_FILTER_PR 0x00000001 /**< Promiscuous mode */ |
| |
| /** Flow control register */ |
| #define DWMAC_FLOW DWMAC_MAC_REG ( 6 ) |
| |
| /** Version register */ |
| #define DWMAC_VER DWMAC_MAC_REG ( 8 ) |
| #define DWMAC_VER_USER_MAJOR( x ) \ |
| ( ( (x) >> 12 ) & 0xf ) /**< User major version */ |
| #define DWMAC_VER_USER_MINOR( x ) \ |
| ( ( (x) >> 8 ) & 0xf ) /**< User minor version */ |
| #define DWMAC_VER_CORE_MAJOR( x ) \ |
| ( ( (x) >> 4 ) & 0xf ) /**< Core major version */ |
| #define DWMAC_VER_CORE_MINOR( x ) \ |
| ( ( (x) >> 0 ) & 0xf ) /**< Core minor version */ |
| |
| /** Debug register */ |
| #define DWMAC_DEBUG DWMAC_MAC_REG ( 9 ) |
| |
| /** Interrupt status register */ |
| #define DWMAC_ISR DWMAC_MAC_REG ( 14 ) |
| |
| /** MAC address high register */ |
| #define DWMAC_ADDRH DWMAC_MAC_REG ( 16 ) |
| |
| /** MAC address low register */ |
| #define DWMAC_ADDRL DWMAC_MAC_REG ( 17 ) |
| |
| /** A DesignWare MAC address */ |
| union dwmac_mac { |
| struct { |
| uint32_t addrl; |
| uint32_t addrh; |
| } __attribute__ (( packed )) reg; |
| uint8_t raw[ETH_ALEN]; |
| }; |
| |
| /** SGMII/RGMII status register */ |
| #define DWMAC_GMII DWMAC_MAC_REG ( 54 ) |
| #define DWMAC_GMII_LINK 0x00000008 /**< Link up */ |
| |
| /** DMA register block */ |
| #define DWMAC_DMA 0x1000 |
| #define DWMAC_DMA_REG( n ) ( DWMAC_DMA + ( (n) * 4 ) ) |
| |
| /** Bus mode register */ |
| #define DWMAC_BUS DWMAC_DMA_REG ( 0 ) |
| #define DWMAC_BUS_PBL4 0x01000000 /**< 4x PBL mode */ |
| #define DWMAC_BUS_USP 0x00800000 /**< Use separate PBL */ |
| #define DWMAC_BUS_RPBL(x) ( (x) << 17 ) /**< RX DMA PBL */ |
| #define DWMAC_BUS_FB 0x00010000 /**< Fixed burst */ |
| #define DWMAC_BUS_PBL(x) ( (x) << 8 ) /**< (TX) DMA PBL */ |
| #define DWMAC_BUS_SWR 0x00000001 /**< Software reset */ |
| |
| /** Time to wait for software reset to complete */ |
| #define DWMAC_RESET_MAX_WAIT_MS 500 |
| |
| /** Transmit poll demand register */ |
| #define DWMAC_TXPOLL DWMAC_DMA_REG ( 1 ) |
| |
| /** Receive poll demand register */ |
| #define DWMAC_RXPOLL DWMAC_DMA_REG ( 2 ) |
| |
| /** Receive descriptor list address register */ |
| #define DWMAC_RXBASE DWMAC_DMA_REG ( 3 ) |
| |
| /** Transmit descriptor list address register */ |
| #define DWMAC_TXBASE DWMAC_DMA_REG ( 4 ) |
| |
| /** Status register */ |
| #define DWMAC_STATUS DWMAC_DMA_REG ( 5 ) |
| #define DWMAC_STATUS_LINK 0x04000000 /**< Link status change */ |
| |
| /** Operation mode register */ |
| #define DWMAC_OP DWMAC_DMA_REG ( 6 ) |
| #define DWMAC_OP_RXSF 0x02000000 /**< RX store and forward */ |
| #define DWMAC_OP_TXSF 0x00200000 /**< TX store and forward */ |
| #define DWMAC_OP_TXEN 0x00002000 /**< TX enabled */ |
| #define DWMAC_OP_RXEN 0x00000002 /**< RX enabled */ |
| |
| /** Packet drop counter register */ |
| #define DWMAC_DROP DWMAC_DMA_REG ( 8 ) |
| |
| /** AXI bus mode register */ |
| #define DWMAC_AXI DWMAC_DMA_REG ( 10 ) |
| |
| /** AHB or AXI status register */ |
| #define DWMAC_AHB DWMAC_DMA_REG ( 11 ) |
| |
| /** Current transmit descriptor register */ |
| #define DWMAC_TXDESC DWMAC_DMA_REG ( 18 ) |
| |
| /** Current receive descriptor register */ |
| #define DWMAC_RXDESC DWMAC_DMA_REG ( 19 ) |
| |
| /** Current transmit buffer address register */ |
| #define DWMAC_TXBUF DWMAC_DMA_REG ( 20 ) |
| |
| /** Current receive buffer address register */ |
| #define DWMAC_RXBUF DWMAC_DMA_REG ( 21 ) |
| |
| /** Hardware feature register */ |
| #define DWMAC_FEATURE DWMAC_DMA_REG ( 22 ) |
| |
| /** A frame descriptor |
| * |
| * We populate the descriptor with values that are valid for both |
| * normal and enhanced descriptor formats, to avoid needing to care |
| * about which version of the hardware we have. |
| */ |
| struct dwmac_descriptor { |
| /** Completion status */ |
| uint32_t stat; |
| /** Buffer size */ |
| uint16_t size; |
| /** Reserved */ |
| uint8_t reserved_a; |
| /** Ring control */ |
| uint8_t ctrl; |
| /** Buffer address */ |
| uint32_t addr; |
| /** Next descriptor address */ |
| uint32_t next; |
| } __attribute__ (( packed )); |
| |
| /* Completion status */ |
| #define DWMAC_STAT_OWN 0x80000000 /**< Owned by hardware */ |
| #define DWMAC_STAT_TX_LAST 0x20000000 /**< Last segment (TX) */ |
| #define DWMAC_STAT_TX_FIRST 0x10000000 /**< First segment (TX) */ |
| #define DWMAC_STAT_TX_CHAIN 0x00100000 /**< Chained descriptor (TX) */ |
| #define DWMAC_STAT_ERR 0x00008000 /**< Error summary */ |
| #define DWMAC_STAT_RX_FIRST 0x00000200 /**< First segment (RX) */ |
| #define DWMAC_STAT_RX_LAST 0x00000100 /**< Last segment (RX) */ |
| #define DWMAC_STAT_RX_LEN(x) \ |
| ( ( (x) >> 16 ) & 0x3fff ) /**< Frame length (RX) */ |
| |
| /** Buffer size */ |
| #define DWMAC_SIZE_RX_CHAIN 0x4000 /**< Chained descriptor (RX) */ |
| |
| /* Ring control */ |
| #define DWMAC_CTRL_TX_LAST 0x40 /**< Last segment (TX) */ |
| #define DWMAC_CTRL_TX_FIRST 0x20 /**< First segment (TX) */ |
| #define DWMAC_CTRL_CHAIN 0x01 /**< Chained descriptor */ |
| |
| /** A DesignWare descriptor ring */ |
| struct dwmac_ring { |
| /** Descriptors */ |
| struct dwmac_descriptor *desc; |
| /** Descriptor ring DMA mapping */ |
| struct dma_mapping map; |
| /** Producer index */ |
| unsigned int prod; |
| /** Consumer index */ |
| unsigned int cons; |
| |
| /** Queue base address register (within DMA block) */ |
| uint8_t qbase; |
| /** Number of descriptors */ |
| uint8_t count; |
| /** Default control flags */ |
| uint8_t ctrl; |
| /** Length of descriptors */ |
| size_t len; |
| }; |
| |
| /** Number of transmit descriptors */ |
| #define DWMAC_NUM_TX_DESC 16 |
| |
| /** Number of receive descriptors */ |
| #define DWMAC_NUM_RX_DESC 16 |
| |
| /** Length of receive buffers |
| * |
| * Must be a multiple of 16. |
| */ |
| #define DWMAC_RX_LEN 1536 |
| |
| /** |
| * Initialise descriptor ring |
| * |
| * @v ring Descriptor ring |
| * @v count Number of descriptors |
| * @v qbase Queue base address register |
| * @v ctrl Default descriptor control flags |
| */ |
| static inline __attribute__ (( always_inline )) void |
| dwmac_init_ring ( struct dwmac_ring *ring, unsigned int count, |
| unsigned int qbase, unsigned int ctrl ) { |
| |
| ring->qbase = ( qbase - DWMAC_DMA ); |
| ring->count = count; |
| ring->ctrl = ctrl; |
| ring->len = ( count * sizeof ( ring->desc[0] ) ); |
| } |
| |
| /** A DesignWare MAC network card */ |
| struct dwmac { |
| /** Registers */ |
| void *regs; |
| /** DMA device */ |
| struct dma_device *dma; |
| /** Device name (for debugging) */ |
| const char *name; |
| |
| /** Transmit ring */ |
| struct dwmac_ring tx; |
| /** Receive ring */ |
| struct dwmac_ring rx; |
| /** Receive I/O buffers */ |
| struct io_buffer *rx_iobuf[DWMAC_NUM_RX_DESC]; |
| }; |
| |
| #endif /* _DWMAC_H */ |