Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / drivers / net / natsemi.h
diff --git a/qemu/roms/ipxe/src/drivers/net/natsemi.h b/qemu/roms/ipxe/src/drivers/net/natsemi.h
new file mode 100644 (file)
index 0000000..7e8d6f8
--- /dev/null
@@ -0,0 +1,329 @@
+#ifndef _NATSEMI_H
+#define _NATSEMI_H
+
+/** @file
+ *
+ * National Semiconductor "MacPhyter" network card driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
+
+#include <stdint.h>
+#include <ipxe/spi.h>
+#include <ipxe/spi_bit.h>
+
+/** BAR size */
+#define NATSEMI_BAR_SIZE 0x100
+
+/** A 32-bit packet descriptor */
+struct natsemi_descriptor_32 {
+       /** Link to next descriptor */
+       uint32_t link;
+       /** Command / status */
+       uint32_t cmdsts;
+       /** Buffer pointer */
+       uint32_t bufptr;
+} __attribute__ (( packed ));
+
+/** A 64-bit packet descriptor */
+struct natsemi_descriptor_64 {
+       /** Link to next descriptor */
+       uint64_t link;
+       /** Buffer pointer */
+       uint64_t bufptr;
+       /** Command / status */
+       uint32_t cmdsts;
+       /** Extended status */
+       uint32_t extsts;
+} __attribute__ (( packed ));
+
+/** A packet descriptor
+ *
+ * The 32-bit and 64-bit variants are overlaid such that "cmdsts" can
+ * be accessed as a common field, and the overall size is a power of
+ * two (to allow the descriptor ring length to be used as an
+ * alignment).
+ */
+union natsemi_descriptor {
+       /** Common fields */
+       struct {
+               /** Reserved */
+               uint8_t reserved_a[16];
+               /** Command / status */
+               uint32_t cmdsts;
+               /** Reserved */
+               uint8_t reserved_b[12];
+       } __attribute__ (( packed )) common;
+       /** 64-bit descriptor */
+       struct natsemi_descriptor_64 d64;
+       /** 32-bit descriptor */
+       struct {
+               /** Reserved */
+               uint8_t reserved[12];
+               /** Descriptor */
+               struct natsemi_descriptor_32 d32;
+       } __attribute__ (( packed )) d32pad;
+};
+
+/** Descriptor buffer size mask */
+#define NATSEMI_DESC_SIZE_MASK 0xfff
+
+/** Packet descriptor flags */
+enum natsemi_descriptor_flags {
+       /** Descriptor is owned by NIC */
+       NATSEMI_DESC_OWN = 0x80000000UL,
+       /** Request descriptor interrupt */
+       NATSEMI_DESC_INTR = 0x20000000UL,
+       /** Packet OK */
+       NATSEMI_DESC_OK = 0x08000000UL,
+};
+
+/** Command Register */
+#define NATSEMI_CR 0x0000
+#define NATSEMI_CR_RST         0x00000100UL    /**< Reset */
+#define NATSEMI_CR_RXR         0x00000020UL    /**< Receiver reset */
+#define NATSEMI_CR_TXR         0x00000010UL    /**< Transmit reset */
+#define NATSEMI_CR_RXE         0x00000004UL    /**< Receiver enable */
+#define NATSEMI_CR_TXE         0x00000001UL    /**< Transmit enable */
+
+/** Maximum time to wait for a reset, in milliseconds */
+#define NATSEMI_RESET_MAX_WAIT_MS 100
+
+/** Configuration and Media Status Register */
+#define NATSEMI_CFG 0x0004
+#define NATSEMI_CFG_LNKSTS     0x80000000UL    /**< Link status */
+#define NATSEMI_CFG_SPDSTS1    0x40000000UL    /**< Speed status bit 1 */
+#define NATSEMI_CFG_MODE_1000  0x00400000UL    /**< 1000 Mb/s mode control */
+#define NATSEMI_CFG_PCI64_DET  0x00002000UL    /**< PCI 64-bit bus detected */
+#define NATSEMI_CFG_DATA64_EN  0x00001000UL    /**< 64-bit data enable */
+#define NATSEMI_CFG_M64ADDR    0x00000800UL    /**< 64-bit address enable */
+#define NATSEMI_CFG_EXTSTS_EN  0x00000100UL    /**< Extended status enable */
+
+/** EEPROM Access Register */
+#define NATSEMI_MEAR 0x0008
+#define NATSEMI_MEAR_EESEL     0x00000008UL    /**< EEPROM chip select */
+#define NATSEMI_MEAR_EECLK     0x00000004UL    /**< EEPROM serial clock */
+#define NATSEMI_MEAR_EEDO      0x00000002UL    /**< EEPROM data out */
+#define NATSEMI_MEAR_EEDI      0x00000001UL    /**< EEPROM data in */
+
+/** Size of EEPROM (in bytes) */
+#define NATSEMI_EEPROM_SIZE 32
+
+/** Word offset of MAC address within sane EEPROM layout */
+#define NATSEMI_EEPROM_MAC_SANE 0x0a
+
+/** Word offset of MAC address within insane EEPROM layout */
+#define NATSEMI_EEPROM_MAC_INSANE 0x06
+
+/** PCI Test Control Register */
+#define NATSEMI_PTSCR 0x000c
+#define NATSEMI_PTSCR_EELOAD_EN        0x00000004UL    /**< Enable EEPROM load */
+
+/** Maximum time to wait for a configuration reload, in milliseconds */
+#define NATSEMI_EELOAD_MAX_WAIT_MS 100
+
+/** Interrupt Status Register */
+#define NATSEMI_ISR 0x0010
+#define NATSEMI_IRQ_TXDESC     0x00000080UL    /**< TX descriptor */
+#define NATSEMI_IRQ_RXDESC     0x00000002UL    /**< RX descriptor */
+
+/** Interrupt Mask Register */
+#define NATSEMI_IMR 0x0014
+
+/** Interrupt Enable Register */
+#define NATSEMI_IER 0x0018
+#define NATSEMI_IER_IE         0x00000001UL    /**< Interrupt enable */
+
+/** Transmit Descriptor Pointer */
+#define NATSEMI_TXDP 0x0020
+
+/** Transmit Descriptor Pointer High Dword (64-bit) */
+#define NATSEMI_TXDP_HI_64 0x0024
+
+/** Number of transmit descriptors */
+#define NATSEMI_NUM_TX_DESC 4
+
+/** Transmit configuration register (32-bit) */
+#define NATSEMI_TXCFG_32 0x24
+
+/** Transmit configuration register (64-bit) */
+#define NATSEMI_TXCFG_64 0x28
+#define NATSEMI_TXCFG_CSI      0x80000000UL    /**< Carrier sense ignore */
+#define NATSEMI_TXCFG_HBI      0x40000000UL    /**< Heartbeat ignore */
+#define NATSEMI_TXCFG_ATP      0x10000000UL    /**< Automatic padding */
+#define NATSEMI_TXCFG_ECRETRY  0x00800000UL    /**< Excess collision retry */
+#define NATSEMI_TXCFG_MXDMA(x) ( (x) << 20 )   /**< Max DMA burst size */
+#define NATSEMI_TXCFG_FLTH(x)  ( (x) << 8 )    /**< Fill threshold */
+#define NATSEMI_TXCFG_DRTH(x)  ( (x) << 0 )    /**< Drain threshold */
+
+/** Max DMA burst size (encoded value)
+ *
+ * This represents 256-byte bursts on 83815 controllers and 512-byte
+ * bursts on 83820 controllers.
+ */
+#define NATSEMI_TXCFG_MXDMA_DEFAULT NATSEMI_TXCFG_MXDMA ( 0x7 )
+
+/** Fill threshold (in units of 32 bytes)
+ *
+ * Must be at least as large as the max DMA burst size, so use a value
+ * of 512 bytes.
+ */
+#define NATSEMI_TXCFG_FLTH_DEFAULT NATSEMI_TXCFG_FLTH ( 512 / 32 )
+
+/** Drain threshold (in units of 32 bytes)
+ *
+ * Start transmission once we receive a conservative 1024 bytes, to
+ * avoid FIFO underrun errors.  (83815 does not allow us to specify a
+ * value of 0 for "wait until whole packet is present".)
+ *
+ * Fill threshold plus drain threshold must be less than the transmit
+ * FIFO size, which is 2kB on 83815 and 8kB on 83820.
+ */
+#define NATSEMI_TXCFG_DRTH_DEFAULT NATSEMI_TXCFG_DRTH ( 1024 / 32 )
+
+/** Receive Descriptor Pointer */
+#define NATSEMI_RXDP 0x0030
+
+/** Receive Descriptor Pointer High Dword (64-bit) */
+#define NATSEMI_RXDP_HI_64 0x0034
+
+/** Number of receive descriptors */
+#define NATSEMI_NUM_RX_DESC 4
+
+/** Receive buffer length */
+#define NATSEMI_RX_MAX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ )
+
+/** Receive configuration register (32-bit) */
+#define NATSEMI_RXCFG_32 0x34
+
+/** Receive configuration register (64-bit) */
+#define NATSEMI_RXCFG_64 0x38
+#define NATSEMI_RXCFG_ARP      0x40000000UL    /**< Accept runt packets */
+#define NATSEMI_RXCFG_ATX      0x10000000UL    /**< Accept transmit packets */
+#define NATSEMI_RXCFG_ALP      0x08000000UL    /**< Accept long packets */
+#define NATSEMI_RXCFG_MXDMA(x) ( (x) << 20 )   /**< Max DMA burst size */
+#define NATSEMI_RXCFG_DRTH(x)  ( (x) << 1 )    /**< Drain threshold */
+
+/** Max DMA burst size (encoded value)
+ *
+ * This represents 256-byte bursts on 83815 controllers and 512-byte
+ * bursts on 83820 controllers.
+ */
+#define NATSEMI_RXCFG_MXDMA_DEFAULT NATSEMI_RXCFG_MXDMA ( 0x7 )
+
+/** Drain threshold (in units of 8 bytes)
+ *
+ * Start draining after 64 bytes.
+ *
+ * Must be large enough to allow packet's accept/reject status to be
+ * determined before draining begins.
+ */
+#define NATSEMI_RXCFG_DRTH_DEFAULT NATSEMI_RXCFG_DRTH ( 64 / 8 )
+
+/** Receive Filter/Match Control Register */
+#define NATSEMI_RFCR 0x0048
+#define NATSEMI_RFCR_RFEN      0x80000000UL    /**< RX filter enable */
+#define NATSEMI_RFCR_AAB       0x40000000UL    /**< Accept all broadcast */
+#define NATSEMI_RFCR_AAM       0x20000000UL    /**< Accept all multicast */
+#define NATSEMI_RFCR_AAU       0x10000000UL    /**< Accept all unicast */
+#define NATSEMI_RFCR_RFADDR( addr ) ( (addr) << 0 ) /**< Extended address */
+#define NATSEMI_RFCR_RFADDR_MASK NATSEMI_RFCR_RFADDR ( 0x3ff )
+
+/** Perfect match filter address base */
+#define NATSEMI_RFADDR_PMATCH_BASE 0x000
+
+/** Receive Filter/Match Data Register */
+#define NATSEMI_RFDR 0x004c
+#define NATSEMI_RFDR_BMASK     0x00030000UL    /**< Byte mask */
+#define NATSEMI_RFDR_DATA( value ) ( (value) & 0xffff ) /**< Filter data */
+
+/** National Semiconductor network card flags */
+enum natsemi_nic_flags {
+       /** EEPROM is little-endian */
+       NATSEMI_EEPROM_LITTLE_ENDIAN = 0x0001,
+       /** EEPROM layout is insane */
+       NATSEMI_EEPROM_INSANE = 0x0002,
+       /** Card supports 64-bit operation */
+       NATSEMI_64BIT = 0x0004,
+       /** Card supports 1000Mbps link */
+       NATSEMI_1000 = 0x0008,
+};
+
+/** A National Semiconductor descriptor ring */
+struct natsemi_ring {
+       /** Descriptors */
+       union natsemi_descriptor *desc;
+       /** Producer index */
+       unsigned int prod;
+       /** Consumer index */
+       unsigned int cons;
+
+       /** Number of descriptors */
+       unsigned int count;
+       /** Descriptor start address register */
+       unsigned int reg;
+};
+
+/**
+ * Initialise descriptor ring
+ *
+ * @v ring             Descriptor ring
+ * @v count            Number of descriptors
+ * @v reg              Descriptor start address register
+ */
+static inline __attribute__ (( always_inline)) void
+natsemi_init_ring ( struct natsemi_ring *ring, unsigned int count,
+                   unsigned int reg ) {
+       ring->count = count;
+       ring->reg = reg;
+}
+
+/** A National Semiconductor network card */
+struct natsemi_nic {
+       /** Flags */
+       unsigned int flags;
+       /** Registers */
+       void *regs;
+       /** SPI bit-bashing interface */
+       struct spi_bit_basher spibit;
+       /** EEPROM */
+       struct spi_device eeprom;
+
+       /** Transmit descriptor ring */
+       struct natsemi_ring tx;
+       /** Receive descriptor ring */
+       struct natsemi_ring rx;
+       /** Receive I/O buffers */
+       struct io_buffer *rx_iobuf[NATSEMI_NUM_RX_DESC];
+
+       /** Link status (cache) */
+       uint32_t cfg;
+};
+
+/**
+ * Check if card can access physical address
+ *
+ * @v natsemi          National Semiconductor device
+ * @v address          Physical address
+ * @v address_ok       Card can access physical address
+ */
+static inline __attribute__ (( always_inline )) int
+natsemi_address_ok ( struct natsemi_nic *natsemi, physaddr_t address ) {
+
+       /* In a 32-bit build, all addresses can be accessed */
+       if ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) )
+               return 1;
+
+       /* A 64-bit card can access all addresses */
+       if ( natsemi->flags & NATSEMI_64BIT )
+               return 1;
+
+       /* A 32-bit card can access all addresses below 4GB */
+       if ( ( address & ~0xffffffffULL ) == 0 )
+               return 1;
+
+       return 0;
+}
+
+#endif /* _NATSEMI_H */