diff options
Diffstat (limited to 'src/drivers/net/dwmac.h')
| -rw-r--r-- | src/drivers/net/dwmac.h | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/src/drivers/net/dwmac.h b/src/drivers/net/dwmac.h new file mode 100644 index 000000000..4de62b0ce --- /dev/null +++ b/src/drivers/net/dwmac.h @@ -0,0 +1,246 @@ +#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 */ |
