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