| #ifndef _CGEM_H |
| #define _CGEM_H |
| |
| /** @file |
| * |
| * Cadence Gigabit Ethernet MAC (GEM) network driver |
| * |
| */ |
| |
| FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); |
| |
| #include <ipxe/if_ether.h> |
| #include <ipxe/mii.h> |
| #include <ipxe/dma.h> |
| #include <ipxe/retry.h> |
| |
| /** I/O region index */ |
| #define CGEM_REG_IDX 0 |
| |
| /** I/O region length */ |
| #define CGEM_REG_LEN 0x800 |
| |
| /** Network control register */ |
| #define CGEM_NWCTRL 0x000 |
| #define CGEM_NWCTRL_STARTTX 0x00000200 /**< Start transmission */ |
| #define CGEM_NWCTRL_STATCLR 0x00000020 /**< Clear statistics */ |
| #define CGEM_NWCTRL_MDEN 0x00000010 /**< MII interface enable */ |
| #define CGEM_NWCTRL_TXEN 0x00000008 /**< Transmit enable */ |
| #define CGEM_NWCTRL_RXEN 0x00000004 /**< Receive enable */ |
| |
| /** Normal value for network control register while up and running */ |
| #define CGEM_NWCTRL_NORMAL \ |
| ( CGEM_NWCTRL_MDEN | CGEM_NWCTRL_TXEN | CGEM_NWCTRL_RXEN ) |
| |
| /** Network configuration register */ |
| #define CGEM_NWCFG 0x004 |
| |
| /** Network status register */ |
| #define CGEM_NWSR 0x008 |
| #define CGEM_NWSR_MII_IDLE 0x00000004 /**< MII interface is idle */ |
| |
| /** DMA configuration register */ |
| #define CGEM_DMACR 0x010 |
| #define CGEM_DMACR_RXBUF( x ) ( ( (x) / 64 ) << 16 ) /**< RX buffer size */ |
| #define CGEM_DMACR_TXSIZE( x ) ( (x) << 10 ) /**< TX memory size */ |
| #define CGEM_DMACR_TXSIZE_MAX \ |
| CGEM_DMACR_TXSIZE ( 0x1 ) /**< Max TX memory size */ |
| #define CGEM_DMACR_RXSIZE( x ) ( (x) << 8 ) /**< RX memory size */ |
| #define CGEM_DMACR_RXSIZE_MAX \ |
| CGEM_DMACR_RXSIZE ( 0x3 ) /**< Max RX memory size */ |
| #define CGEM_DMACR_BLENGTH( x ) ( (x) << 0 ) /**< DMA burst length */ |
| #define CGEM_DMACR_BLENGTH_MAX \ |
| CGEM_DMACR_BLENGTH ( 0x10 ) /**< Max DMA burst length */ |
| |
| /** RX queue base address register */ |
| #define CGEM_RXQBASE 0x018 |
| |
| /** TX queue base address register */ |
| #define CGEM_TXQBASE 0x01c |
| |
| /** Interrupt disable register */ |
| #define CGEM_IDR 0x02c |
| #define CGEM_IDR_ALL 0xffffffff /**< Disable all interrupts */ |
| |
| /** PHY maintenance register */ |
| #define CGEM_PHYMNTNC 0x034 |
| #define CGEM_PHYMNTNC_CLAUSE22 0x40000000 /**< Clause 22 operation */ |
| #define CGEM_PHYMNTNC_OP_WRITE 0x10000000 /**< Write to PHY register */ |
| #define CGEM_PHYMNTNC_OP_READ 0x20000000 /**< Read from PHY register */ |
| #define CGEM_PHYMNTNC_ADDR( x ) ( (x) << 23 ) /**< PHY address */ |
| #define CGEM_PHYMNTNC_REG( x ) ( (x) << 18 ) /**< Register address */ |
| #define CGEM_PHYMNTNC_FIXED 0x00020000 /**< Fixed value to write */ |
| #define CGEM_PHYMNTNC_DATA_MASK 0x0000ffff /**< Data mask */ |
| |
| /** Maximum time to wait for PHY access, in microseconds */ |
| #define CGEM_MII_MAX_WAIT_US 500 |
| |
| /** Link state check interval */ |
| #define CGEM_LINK_INTERVAL ( 2 * TICKS_PER_SEC ) |
| |
| /** Local MAC address (low half) register */ |
| #define CGEM_LADDRL 0x088 |
| |
| /** Local MAC address (high half) register */ |
| #define CGEM_LADDRH 0x08c |
| |
| /** A Cadence GEM descriptor */ |
| struct cgem_descriptor { |
| /** Buffer address */ |
| uint32_t addr; |
| /** Flags */ |
| uint32_t flags; |
| } __attribute__ (( packed )); |
| |
| /** Transmit flags */ |
| #define CGEM_TX_FL_OWNED 0x80000000 /**< Owned by software */ |
| #define CGEM_TX_FL_WRAP 0x40000000 /**< End of descriptor ring */ |
| #define CGEM_TX_FL_LAST 0x00008000 /**< Last buffer in frame */ |
| |
| /** Transmit ring length */ |
| #define CGEM_NUM_TX_DESC 8 |
| |
| /** Receive flags (in buffer address) */ |
| #define CGEM_RX_ADDR_OWNED 0x00000001 /**< Owned by software */ |
| #define CGEM_RX_ADDR_WRAP 0x00000002 /**< End of descriptor ring */ |
| |
| /** Receive flags */ |
| #define CGEM_RX_FL_LEN( x ) ( (x) & 0x1fff ) /**< RX packet length */ |
| |
| /** Receive ring length */ |
| #define CGEM_NUM_RX_DESC 8 |
| |
| /** Length of receive buffers |
| * |
| * Must be a multiple of 64. |
| */ |
| #define CGEM_RX_LEN 1536 |
| |
| /** A Cadence GEM MAC address */ |
| union cgem_mac { |
| struct { |
| uint32_t low; |
| uint32_t high; |
| } __attribute__ (( packed )) reg; |
| uint8_t raw[ETH_ALEN]; |
| }; |
| |
| /** A Cadence GEM descriptor ring */ |
| struct cgem_ring { |
| /** Descriptors */ |
| struct cgem_descriptor *desc; |
| /** Descriptor ring DMA mapping */ |
| struct dma_mapping map; |
| /** Producer index */ |
| unsigned int prod; |
| /** Consumer index */ |
| unsigned int cons; |
| |
| /** Queue base address register */ |
| uint8_t qbase; |
| /** Number of descriptors */ |
| uint8_t count; |
| /** Length of descriptors */ |
| uint16_t len; |
| }; |
| |
| /** |
| * Initialise descriptor ring |
| * |
| * @v ring Descriptor ring |
| * @v count Number of descriptors |
| * @v qbase Queue base address register |
| */ |
| static inline __attribute__ (( always_inline )) void |
| cgem_init_ring ( struct cgem_ring *ring, unsigned int count, |
| unsigned int qbase ) { |
| |
| ring->qbase = qbase; |
| ring->count = count; |
| ring->len = ( count * sizeof ( ring->desc[0] ) ); |
| } |
| |
| /** A Cadence GEM network card */ |
| struct cgem_nic { |
| /** Registers */ |
| void *regs; |
| /** DMA device */ |
| struct dma_device *dma; |
| /** Network device */ |
| struct net_device *netdev; |
| /** Device name (for debugging) */ |
| const char *name; |
| |
| /** PHY interface */ |
| struct mii_interface mdio; |
| /** PHY device */ |
| struct mii_device mii; |
| /** Link state timer */ |
| struct retry_timer timer; |
| |
| /** Transmit ring */ |
| struct cgem_ring tx; |
| /** Receive ring */ |
| struct cgem_ring rx; |
| /** Receive I/O buffers */ |
| struct io_buffer *rx_iobuf[CGEM_NUM_RX_DESC]; |
| }; |
| |
| #endif /* _CGEM_H */ |