Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / realtek.h
diff --git a/qemu/roms/ipxe/src/drivers/net/realtek.h b/qemu/roms/ipxe/src/drivers/net/realtek.h
new file mode 100644 (file)
index 0000000..ac33405
--- /dev/null
@@ -0,0 +1,307 @@
+#ifndef _REALTEK_H
+#define _REALTEK_H
+
+/** @file
+ *
+ * Realtek 10/100/1000 network card driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <ipxe/spi.h>
+#include <ipxe/spi_bit.h>
+#include <ipxe/nvo.h>
+#include <ipxe/if_ether.h>
+
+/** PCI memory BAR size */
+#define RTL_BAR_SIZE 0x100
+
+/** A packet descriptor */
+struct realtek_descriptor {
+       /** Buffer size */
+       uint16_t length;
+       /** Flags */
+       uint16_t flags;
+       /** Reserved */
+       uint32_t reserved;
+       /** Buffer address */
+       uint64_t address;
+} __attribute__ (( packed ));
+
+/** Descriptor buffer size mask */
+#define RTL_DESC_SIZE_MASK 0x3fff
+
+/** Packet descriptor flags */
+enum realtek_descriptor_flags {
+       /** Descriptor is owned by NIC */
+       RTL_DESC_OWN = 0x8000,
+       /** End of descriptor ring */
+       RTL_DESC_EOR = 0x4000,
+       /** First segment descriptor */
+       RTL_DESC_FS = 0x2000,
+       /** Last segment descriptor */
+       RTL_DESC_LS = 0x1000,
+       /** Receive error summary */
+       RTL_DESC_RES = 0x0020,
+};
+
+/** Descriptor ring alignment */
+#define RTL_RING_ALIGN 256
+
+/** A legacy mode receive packet header */
+struct realtek_legacy_header {
+       /** Status */
+       uint16_t status;
+       /** Length */
+       uint16_t length;
+       /** Packet data */
+       uint8_t data[0];
+} __attribute__ (( packed ));
+
+/** Legacy mode status bits */
+enum realtek_legacy_status {
+       /** Received OK */
+       RTL_STAT_ROK = 0x0001,
+};
+
+/** ID Register 0 (6 bytes) */
+#define RTL_IDR0 0x00
+
+/** Multicast Register 0 (dword) */
+#define RTL_MAR0 0x08
+
+/** Multicast Register 4 (dword) */
+#define RTL_MAR4 0x0c
+
+/** Transmit Status of Descriptor N (dword, 8139 only) */
+#define RTL_TSD(n) ( 0x10 + 4 * (n) )
+#define RTL_TSD_ERTXTH(x)      ( (x) << 16 ) /**< Early TX threshold */
+#define RTL_TSD_ERTXTH_DEFAULT RTL_TSD_ERTXTH ( 256 / 32 )
+#define RTL_TSD_OWN            0x00002000UL /**< Ownership */
+
+/** Transmit Start Address of Descriptor N (dword, 8139 only) */
+#define RTL_TSAD(n) ( 0x20 + 4 * (n) )
+
+/** Transmit Normal Priority Descriptors (qword) */
+#define RTL_TNPDS 0x20
+
+/** Number of transmit descriptors
+ *
+ * This is a hardware limit when using legacy mode.
+ */
+#define RTL_NUM_TX_DESC 4
+
+/** Receive Buffer Start Address (dword, 8139 only) */
+#define RTL_RBSTART 0x30
+
+/** Receive buffer length */
+#define RTL_RXBUF_LEN 8192
+
+/** Receive buffer padding */
+#define RTL_RXBUF_PAD 2038 /* Allow space for WRAP */
+
+/** Receive buffer alignment */
+#define RTL_RXBUF_ALIGN 16
+
+/** Command Register (byte) */
+#define RTL_CR 0x37
+#define RTL_CR_RST             0x10    /**< Reset */
+#define RTL_CR_RE              0x08    /**< Receiver Enable */
+#define RTL_CR_TE              0x04    /**< Transmit Enable */
+#define RTL_CR_BUFE            0x01    /**< Receive buffer empty */
+
+/** Maximum time to wait for a reset, in milliseconds */
+#define RTL_RESET_MAX_WAIT_MS 100
+
+/** Current Address of Packet Read (word, 8139 only) */
+#define RTL_CAPR 0x38
+
+/** Transmit Priority Polling Register (byte, 8169 only) */
+#define RTL_TPPOLL_8169 0x38
+#define RTL_TPPOLL_NPQ         0x40    /**< Normal Priority Queue Polling */
+
+/** Interrupt Mask Register (word) */
+#define RTL_IMR 0x3c
+#define RTL_IRQ_PUN_LINKCHG    0x0020  /**< Packet underrun / link change */
+#define RTL_IRQ_TER            0x0008  /**< Transmit error */
+#define RTL_IRQ_TOK            0x0004  /**< Transmit OK */
+#define RTL_IRQ_RER            0x0002  /**< Receive error */
+#define RTL_IRQ_ROK            0x0001  /**< Receive OK */
+
+/** Interrupt Status Register (word) */
+#define RTL_ISR 0x3e
+
+/** Transmit (Tx) Configuration Register (dword) */
+#define RTL_TCR 0x40
+#define RTL_TCR_MXDMA(x)       ( (x) << 8 ) /**< Max DMA burst size */
+#define RTL_TCR_MXDMA_MASK     RTL_TCR_MXDMA ( 0x7 )
+#define RTL_TCR_MXDMA_DEFAULT  RTL_TCR_MXDMA ( 0x7 /* Unlimited */ )
+
+/** Receive (Rx) Configuration Register (dword) */
+#define RTL_RCR 0x44
+#define RTL_RCR_STOP_WORKING   0x01000000UL /**< Here be dragons */
+#define RTL_RCR_RXFTH(x)       ( (x) << 13 ) /**< Receive FIFO threshold */
+#define RTL_RCR_RXFTH_MASK     RTL_RCR_RXFTH ( 0x7 )
+#define RTL_RCR_RXFTH_DEFAULT  RTL_RCR_RXFTH ( 0x7 /* Whole packet */ )
+#define RTL_RCR_RBLEN(x)       ( (x) << 11 ) /**< Receive buffer length */
+#define RTL_RCR_RBLEN_MASK     RTL_RCR_RBLEN ( 0x3 )
+#define RTL_RCR_RBLEN_DEFAULT  RTL_RCR_RBLEN ( 0 /* 8kB */ )
+#define RTL_RCR_MXDMA(x)       ( (x) << 8 ) /**< Max DMA burst size */
+#define RTL_RCR_MXDMA_MASK     RTL_RCR_MXDMA ( 0x7 )
+#define RTL_RCR_MXDMA_DEFAULT  RTL_RCR_MXDMA ( 0x7 /* Unlimited */ )
+#define RTL_RCR_WRAP           0x00000080UL /**< Overrun receive buffer */
+#define RTL_RCR_9356SEL                0x00000040UL /**< EEPROM is a 93C56 */
+#define RTL_RCR_AB             0x00000008UL /**< Accept broadcast packets */
+#define RTL_RCR_AM             0x00000004UL /**< Accept multicast packets */
+#define RTL_RCR_APM            0x00000002UL /**< Accept physical match */
+#define RTL_RCR_AAP            0x00000001UL /**< Accept all packets */
+
+/** 93C46 (93C56) Command Register (byte) */
+#define RTL_9346CR 0x50
+#define RTL_9346CR_EEM(x)      ( (x) << 6 ) /**< Mode select */
+#define RTL_9346CR_EEM_EEPROM  RTL_9346CR_EEM ( 0x2 ) /**< EEPROM mode */
+#define RTL_9346CR_EEM_NORMAL  RTL_9346CR_EEM ( 0x0 ) /**< Normal mode */
+#define RTL_9346CR_EECS                0x08    /**< Chip select */
+#define RTL_9346CR_EESK                0x04    /**< Clock */
+#define RTL_9346CR_EEDI                0x02    /**< Data in */
+#define RTL_9346CR_EEDO                0x01    /**< Data out */
+
+/** Word offset of ID code word within EEPROM */
+#define RTL_EEPROM_ID ( 0x00 / 2 )
+
+/** EEPROM code word magic value */
+#define RTL_EEPROM_ID_MAGIC 0x8129
+
+/** Word offset of MAC address within EEPROM */
+#define RTL_EEPROM_MAC ( 0x0e / 2 )
+
+/** Word offset of VPD / non-volatile options within EEPROM */
+#define RTL_EEPROM_VPD ( 0x40 / 2 )
+
+/** Length of VPD / non-volatile options within EEPROM */
+#define RTL_EEPROM_VPD_LEN 0x40
+
+/** Configuration Register 1 (byte) */
+#define RTL_CONFIG1 0x52
+#define RTL_CONFIG1_VPD                0x02    /**< Vital Product Data enabled */
+
+/** Media Status Register (byte, 8139 only) */
+#define RTL_MSR 0x58
+#define RTL_MSR_TXFCE          0x80    /**< TX flow control enabled */
+#define RTL_MSR_RXFCE          0x40    /**< RX flow control enabled */
+#define RTL_MSR_AUX_STATUS     0x10    /**< Aux power present */
+#define RTL_MSR_SPEED_10       0x08    /**< 10Mbps */
+#define RTL_MSR_LINKB          0x04    /**< Inverse of link status */
+#define RTL_MSR_TXPF           0x02    /**< TX pause flag */
+#define RTL_MSR_RXPF           0x01    /**< RX pause flag */
+
+/** PHY Access Register (dword, 8169 only) */
+#define RTL_PHYAR 0x60
+#define RTL_PHYAR_FLAG         0x80000000UL /**< Read/write flag */
+
+/** Construct PHY Access Register value */
+#define RTL_PHYAR_VALUE( flag, reg, data ) ( (flag) | ( (reg) << 16 ) | (data) )
+
+/** Extract PHY Access Register data */
+#define RTL_PHYAR_DATA( value ) ( (value) & 0xffff )
+
+/** Maximum time to wait for PHY access, in microseconds */
+#define RTL_MII_MAX_WAIT_US 500
+
+/** PHY (GMII, MII, or TBI) Status Register (byte, 8169 only) */
+#define RTL_PHYSTATUS 0x6c
+#define RTL_PHYSTATUS_ENTBI    0x80    /**< TBI / GMII mode */
+#define RTL_PHYSTATUS_TXFLOW   0x40    /**< TX flow control enabled */
+#define RTL_PHYSTATUS_RXFLOW   0x20    /**< RX flow control enabled */
+#define RTL_PHYSTATUS_1000MF   0x10    /**< 1000Mbps full-duplex */
+#define RTL_PHYSTATUS_100M     0x08    /**< 100Mbps */
+#define RTL_PHYSTATUS_10M      0x04    /**< 10Mbps */
+#define RTL_PHYSTATUS_LINKSTS  0x02    /**< Link ok */
+#define RTL_PHYSTATUS_FULLDUP  0x01    /**< Full duplex */
+
+/** Transmit Priority Polling Register (byte, 8139C+ only) */
+#define RTL_TPPOLL_8139CP 0xd9
+
+/** RX Packet Maximum Size Register (word) */
+#define RTL_RMS 0xda
+
+/** C+ Command Register (word) */
+#define RTL_CPCR 0xe0
+#define RTL_CPCR_DAC           0x0010  /**< PCI Dual Address Cycle Enable */
+#define RTL_CPCR_MULRW         0x0008  /**< PCI Multiple Read/Write Enable */
+#define RTL_CPCR_CPRX          0x0002  /**< C+ receive enable */
+#define RTL_CPCR_CPTX          0x0001  /**< C+ transmit enable */
+
+/** Receive Descriptor Start Address Register (qword) */
+#define RTL_RDSAR 0xe4
+
+/** Number of receive descriptors */
+#define RTL_NUM_RX_DESC 4
+
+/** Receive buffer length */
+#define RTL_RX_MAX_LEN \
+       ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ + 4 /* extra space */ )
+
+/** A Realtek descriptor ring */
+struct realtek_ring {
+       /** Descriptors */
+       struct realtek_descriptor *desc;
+       /** Producer index */
+       unsigned int prod;
+       /** Consumer index */
+       unsigned int cons;
+
+       /** Descriptor start address register */
+       unsigned int reg;
+       /** Length (in bytes) */
+       size_t len;
+};
+
+/**
+ * Initialise descriptor ring
+ *
+ * @v ring             Descriptor ring
+ * @v count            Number of descriptors
+ * @v reg              Descriptor start address register
+ */
+static inline __attribute__ (( always_inline)) void
+realtek_init_ring ( struct realtek_ring *ring, unsigned int count,
+                   unsigned int reg ) {
+       ring->len = ( count * sizeof ( ring->desc[0] ) );
+       ring->reg = reg;
+}
+
+/** A Realtek network card */
+struct realtek_nic {
+       /** Registers */
+       void *regs;
+       /** SPI bit-bashing interface */
+       struct spi_bit_basher spibit;
+       /** EEPROM */
+       struct spi_device eeprom;
+       /** Non-volatile options */
+       struct nvo_block nvo;
+       /** MII interface */
+       struct mii_interface mii;
+
+       /** Legacy datapath mode */
+       int legacy;
+       /** PHYAR and PHYSTATUS registers are present */
+       int have_phy_regs;
+       /** TPPoll register offset */
+       unsigned int tppoll;
+
+       /** Transmit descriptor ring */
+       struct realtek_ring tx;
+       /** Receive descriptor ring */
+       struct realtek_ring rx;
+       /** Receive I/O buffers */
+       struct io_buffer *rx_iobuf[RTL_NUM_RX_DESC];
+       /** Receive buffer (legacy mode) */
+       void *rx_buffer;
+       /** Offset within receive buffer (legacy mode) */
+       unsigned int rx_offset;
+};
+
+#endif /* _REALTEK_H */