diff options
Diffstat (limited to 'qemu/roms/ipxe/src/drivers/net/intel.h')
-rw-r--r-- | qemu/roms/ipxe/src/drivers/net/intel.h | 267 |
1 files changed, 267 insertions, 0 deletions
diff --git a/qemu/roms/ipxe/src/drivers/net/intel.h b/qemu/roms/ipxe/src/drivers/net/intel.h new file mode 100644 index 000000000..8c4479bb4 --- /dev/null +++ b/qemu/roms/ipxe/src/drivers/net/intel.h @@ -0,0 +1,267 @@ +#ifndef _INTEL_H +#define _INTEL_H + +/** @file + * + * Intel 10/100/1000 network card driver + * + */ + +FILE_LICENCE ( GPL2_OR_LATER ); + +#include <stdint.h> +#include <ipxe/if_ether.h> +#include <ipxe/nvs.h> + +/** Intel BAR size */ +#define INTEL_BAR_SIZE ( 128 * 1024 ) + +/** A packet descriptor */ +struct intel_descriptor { + /** Buffer address */ + uint64_t address; + /** Length */ + uint16_t length; + /** Reserved */ + uint8_t reserved_a; + /** Command */ + uint8_t command; + /** Status */ + uint8_t status; + /** Errors */ + uint8_t errors; + /** Reserved */ + uint16_t reserved_b; +} __attribute__ (( packed )); + +/** Packet descriptor command bits */ +enum intel_descriptor_command { + /** Report status */ + INTEL_DESC_CMD_RS = 0x08, + /** Insert frame checksum (CRC) */ + INTEL_DESC_CMD_IFCS = 0x02, + /** End of packet */ + INTEL_DESC_CMD_EOP = 0x01, +}; + +/** Packet descriptor status bits */ +enum intel_descriptor_status { + /** Descriptor done */ + INTEL_DESC_STATUS_DD = 0x01, +}; + +/** Device Control Register */ +#define INTEL_CTRL 0x00000UL +#define INTEL_CTRL_LRST 0x00000008UL /**< Link reset */ +#define INTEL_CTRL_ASDE 0x00000020UL /**< Auto-speed detection */ +#define INTEL_CTRL_SLU 0x00000040UL /**< Set link up */ +#define INTEL_CTRL_FRCSPD 0x00000800UL /**< Force speed */ +#define INTEL_CTRL_FRCDPLX 0x00001000UL /**< Force duplex */ +#define INTEL_CTRL_RST 0x04000000UL /**< Device reset */ +#define INTEL_CTRL_PHY_RST 0x80000000UL /**< PHY reset */ + +/** Time to delay for device reset, in milliseconds */ +#define INTEL_RESET_DELAY_MS 20 + +/** Device Status Register */ +#define INTEL_STATUS 0x00008UL +#define INTEL_STATUS_LU 0x00000002UL /**< Link up */ + +/** EEPROM Read Register */ +#define INTEL_EERD 0x00014UL +#define INTEL_EERD_START 0x00000001UL /**< Start read */ +#define INTEL_EERD_DONE_SMALL 0x00000010UL /**< Read done (small EERD) */ +#define INTEL_EERD_DONE_LARGE 0x00000002UL /**< Read done (large EERD) */ +#define INTEL_EERD_ADDR_SHIFT_SMALL 8 /**< Address shift (small) */ +#define INTEL_EERD_ADDR_SHIFT_LARGE 2 /**< Address shift (large) */ +#define INTEL_EERD_DATA(value) ( (value) >> 16 ) /**< Read data */ + +/** Maximum time to wait for EEPROM read, in milliseconds */ +#define INTEL_EEPROM_MAX_WAIT_MS 100 + +/** EEPROM word length */ +#define INTEL_EEPROM_WORD_LEN_LOG2 1 + +/** Minimum EEPROM size, in words */ +#define INTEL_EEPROM_MIN_SIZE_WORDS 64 + +/** Offset of MAC address within EEPROM */ +#define INTEL_EEPROM_MAC 0x00 + +/** Interrupt Cause Read Register */ +#define INTEL_ICR 0x000c0UL +#define INTEL_IRQ_TXDW 0x00000001UL /**< Transmit descriptor done */ +#define INTEL_IRQ_LSC 0x00000004UL /**< Link status change */ +#define INTEL_IRQ_RXT0 0x00000080UL /**< Receive timer */ +#define INTEL_IRQ_RXO 0x00000400UL /**< Receive overrun */ + +/** Interrupt Mask Set/Read Register */ +#define INTEL_IMS 0x000d0UL + +/** Interrupt Mask Clear Register */ +#define INTEL_IMC 0x000d8UL + +/** Receive Control Register */ +#define INTEL_RCTL 0x00100UL +#define INTEL_RCTL_EN 0x00000002UL /**< Receive enable */ +#define INTEL_RCTL_UPE 0x00000008UL /**< Unicast promiscuous mode */ +#define INTEL_RCTL_MPE 0x00000010UL /**< Multicast promiscuous */ +#define INTEL_RCTL_BAM 0x00008000UL /**< Broadcast accept mode */ +#define INTEL_RCTL_BSIZE_BSEX(bsex,bsize) \ + ( ( (bsize) << 16 ) | ( (bsex) << 25 ) ) /**< Buffer size */ +#define INTEL_RCTL_BSIZE_2048 INTEL_RCTL_BSIZE_BSEX ( 0, 0 ) +#define INTEL_RCTL_BSIZE_BSEX_MASK INTEL_RCTL_BSIZE_BSEX ( 1, 3 ) +#define INTEL_RCTL_SECRC 0x04000000UL /**< Strip CRC */ + +/** Transmit Control Register */ +#define INTEL_TCTL 0x00400UL +#define INTEL_TCTL_EN 0x00000002UL /**< Transmit enable */ +#define INTEL_TCTL_PSP 0x00000008UL /**< Pad short packets */ +#define INTEL_TCTL_CT(x) ( (x) << 4 ) /**< Collision threshold */ +#define INTEL_TCTL_CT_DEFAULT INTEL_TCTL_CT ( 0x0f ) +#define INTEL_TCTL_CT_MASK INTEL_TCTL_CT ( 0xff ) +#define INTEL_TCTL_COLD(x) ( (x) << 12 ) /**< Collision distance */ +#define INTEL_TCTL_COLD_DEFAULT INTEL_TCTL_COLD ( 0x040 ) +#define INTEL_TCTL_COLD_MASK INTEL_TCTL_COLD ( 0x3ff ) + +/** Packet Buffer Allocation */ +#define INTEL_PBA 0x01000UL + +/** Packet Buffer Size */ +#define INTEL_PBS 0x01008UL + +/** Receive Descriptor register block */ +#define INTEL_RD 0x02800UL + +/** Number of receive descriptors + * + * Minimum value is 8, since the descriptor ring length must be a + * multiple of 128. + */ +#define INTEL_NUM_RX_DESC 16 + +/** Receive descriptor ring fill level */ +#define INTEL_RX_FILL 8 + +/** Receive buffer length */ +#define INTEL_RX_MAX_LEN 2048 + +/** Transmit Descriptor register block */ +#define INTEL_TD 0x03800UL + +/** Number of transmit descriptors + * + * Descriptor ring length must be a multiple of 16. ICH8/9/10 + * requires a minimum of 16 TX descriptors. + */ +#define INTEL_NUM_TX_DESC 16 + +/** Transmit descriptor ring maximum fill level */ +#define INTEL_TX_FILL ( INTEL_NUM_TX_DESC - 1 ) + +/** Receive/Transmit Descriptor Base Address Low (offset) */ +#define INTEL_xDBAL 0x00 + +/** Receive/Transmit Descriptor Base Address High (offset) */ +#define INTEL_xDBAH 0x04 + +/** Receive/Transmit Descriptor Length (offset) */ +#define INTEL_xDLEN 0x08 + +/** Receive/Transmit Descriptor Head (offset) */ +#define INTEL_xDH 0x10 + +/** Receive/Transmit Descriptor Tail (offset) */ +#define INTEL_xDT 0x18 + +/** Receive/Transmit Descriptor Control (offset) */ +#define INTEL_xDCTL 0x28 +#define INTEL_xDCTL_ENABLE 0x02000000UL /**< Queue enable */ + +/** Receive Address Low */ +#define INTEL_RAL0 0x05400UL + +/** Receive Address High */ +#define INTEL_RAH0 0x05404UL +#define INTEL_RAH0_AV 0x80000000UL /**< Address valid */ + +/** Receive address */ +union intel_receive_address { + struct { + uint32_t low; + uint32_t high; + } __attribute__ (( packed )) reg; + uint8_t raw[ETH_ALEN]; +}; + +/** An Intel descriptor ring */ +struct intel_ring { + /** Descriptors */ + struct intel_descriptor *desc; + /** Producer index */ + unsigned int prod; + /** Consumer index */ + unsigned int cons; + + /** Register block */ + unsigned int reg; + /** Length (in bytes) */ + size_t len; +}; + +/** + * Initialise descriptor ring + * + * @v ring Descriptor ring + * @v count Number of descriptors + * @v reg Descriptor register block + */ +static inline __attribute__ (( always_inline)) void +intel_init_ring ( struct intel_ring *ring, unsigned int count, + unsigned int reg ) { + ring->len = ( count * sizeof ( ring->desc[0] ) ); + ring->reg = reg; +} + +/** An Intel network card */ +struct intel_nic { + /** Registers */ + void *regs; + /** Port number (for multi-port devices) */ + unsigned int port; + /** Flags */ + unsigned int flags; + + /** EEPROM */ + struct nvs_device eeprom; + /** EEPROM done flag */ + uint32_t eerd_done; + /** EEPROM address shift */ + unsigned int eerd_addr_shift; + + /** Transmit descriptor ring */ + struct intel_ring tx; + /** Receive descriptor ring */ + struct intel_ring rx; + /** Receive I/O buffers */ + struct io_buffer *rx_iobuf[INTEL_NUM_RX_DESC]; +}; + +/** Driver flags */ +enum intel_flags { + /** PBS/PBA errata workaround required */ + INTEL_PBS_ERRATA = 0x0001, +}; + +extern int intel_create_ring ( struct intel_nic *intel, + struct intel_ring *ring ); +extern void intel_destroy_ring ( struct intel_nic *intel, + struct intel_ring *ring ); +extern void intel_refill_rx ( struct intel_nic *intel ); +extern void intel_empty_rx ( struct intel_nic *intel ); +extern int intel_transmit ( struct net_device *netdev, + struct io_buffer *iobuf ); +extern void intel_poll_tx ( struct net_device *netdev ); +extern void intel_poll_rx ( struct net_device *netdev ); + +#endif /* _INTEL_H */ |