blob: 4de62b0ce86dda0451766e7c4ad3c6659dfa742b [file] [log] [blame]
#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 */