summaryrefslogtreecommitdiffstats
path: root/src/drivers/net/natsemi.h
diff options
context:
space:
mode:
authorMichael Brown2012-04-24 22:48:48 +0200
committerMichael Brown2012-04-26 15:17:24 +0200
commit2c1e8d2cb13e2c46c43968765f220ef64f416940 (patch)
tree8eb294049f3234d234df73907e19dc02dbfadb21 /src/drivers/net/natsemi.h
parent[crypto] Do not allow build-time cryptography settings to be overridden (diff)
downloadipxe-2c1e8d2cb13e2c46c43968765f220ef64f416940.tar.gz
ipxe-2c1e8d2cb13e2c46c43968765f220ef64f416940.tar.xz
ipxe-2c1e8d2cb13e2c46c43968765f220ef64f416940.zip
[natsemi] Replace driver for National Semicondutor NICs
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/natsemi.h')
-rw-r--r--src/drivers/net/natsemi.h485
1 files changed, 291 insertions, 194 deletions
diff --git a/src/drivers/net/natsemi.h b/src/drivers/net/natsemi.h
index ae827ba39..e3444712b 100644
--- a/src/drivers/net/natsemi.h
+++ b/src/drivers/net/natsemi.h
@@ -1,232 +1,329 @@
-FILE_LICENCE ( GPL_ANY );
+#ifndef _NATSEMI_H
+#define _NATSEMI_H
-#define NATSEMI_HW_TIMEOUT 400
+/** @file
+ *
+ * National Semiconductor "MacPhyter" network card driver
+ *
+ */
+
+FILE_LICENCE ( GPL2_OR_LATER );
-#define TX_RING_SIZE 4
-#define NUM_RX_DESC 4
-#define RX_BUF_SIZE 1536
-#define OWN 0x80000000
-#define DSIZE 0x00000FFF
-#define CRC_SIZE 4
+#include <stdint.h>
+#include <ipxe/spi.h>
+#include <ipxe/spi_bit.h>
-struct natsemi_tx {
+/** 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 ));
-struct natsemi_rx {
- uint32_t link;
+/** 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;
- uint32_t bufptr;
-};
+ /** Extended status */
+ uint32_t extsts;
+} __attribute__ (( packed ));
-struct natsemi_private {
- unsigned short ioaddr;
- unsigned short tx_cur;
- unsigned short tx_dirty;
- unsigned short rx_cur;
- struct natsemi_tx tx[TX_RING_SIZE];
- struct natsemi_rx rx[NUM_RX_DESC];
-
- /* need to add iobuf as we cannot free iobuf->data in close without this
- * alternatively substracting sizeof(head) and sizeof(list_head) can also
- * give the same.
- */
- struct io_buffer *iobuf[NUM_RX_DESC];
-
- /* netdev_tx_complete needs pointer to the iobuf of the data so as to free
- * it from the memory.
- */
- struct io_buffer *tx_iobuf[TX_RING_SIZE];
- struct spi_bit_basher spibit;
- struct spi_device eeprom;
- struct nvo_block nvo;
+/** 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;
};
-/*
- * Support for fibre connections on Am79C874:
- * This phy needs a special setup when connected to a fibre cable.
- * http://www.amd.com/files/connectivitysolutions/networking/archivednetworking/22235.pdf
- */
-#define PHYID_AM79C874 0x0022561b
+/** Descriptor buffer size mask */
+#define NATSEMI_DESC_SIZE_MASK 0xfff
-enum {
- MII_MCTRL = 0x15, /* mode control register */
- MII_FX_SEL = 0x0001, /* 100BASE-FX (fiber) */
- MII_EN_SCRM = 0x0004, /* enable scrambler (tp) */
+/** 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
-/* values we might find in the silicon revision register */
-#define SRR_DP83815_C 0x0302
-#define SRR_DP83815_D 0x0403
-#define SRR_DP83816_A4 0x0504
-#define SRR_DP83816_A5 0x0505
+/** 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 */
-/* NATSEMI: Offsets to the device registers.
- * Unlike software-only systems, device drivers interact with complex hardware.
- * It's not useful to define symbolic names for every register bit in the
- * device.
+/** Max DMA burst size (encoded value)
+ *
+ * This represents 256-byte bursts on 83815 controllers and 512-byte
+ * bursts on 83820 controllers.
*/
-enum register_offsets {
- ChipCmd = 0x00,
- ChipConfig = 0x04,
- EECtrl = 0x08,
- PCIBusCfg = 0x0C,
- IntrStatus = 0x10,
- IntrMask = 0x14,
- IntrEnable = 0x18,
- TxRingPtr = 0x20,
- TxConfig = 0x24,
- RxRingPtr = 0x30,
- RxConfig = 0x34,
- ClkRun = 0x3C,
- WOLCmd = 0x40,
- PauseCmd = 0x44,
- RxFilterAddr = 0x48,
- RxFilterData = 0x4C,
- BootRomAddr = 0x50,
- BootRomData = 0x54,
- SiliconRev = 0x58,
- StatsCtrl = 0x5C,
- StatsData = 0x60,
- RxPktErrs = 0x60,
- RxMissed = 0x68,
- RxCRCErrs = 0x64,
- PCIPM = 0x44,
- PhyStatus = 0xC0,
- MIntrCtrl = 0xC4,
- MIntrStatus = 0xC8,
-
- /* These are from the spec, around page 78... on a separate table.
- */
- PGSEL = 0xCC,
- PMDCSR = 0xE4,
- TSTDAT = 0xFC,
- DSPCFG = 0xF4,
- SDCFG = 0x8C,
- BasicControl = 0x80,
- BasicStatus = 0x84
-
-};
+#define NATSEMI_TXCFG_MXDMA_DEFAULT NATSEMI_TXCFG_MXDMA ( 0x7 )
-/* the values for the 'magic' registers above (PGSEL=1) */
-#define PMDCSR_VAL 0x189c /* enable preferred adaptation circuitry */
-#define TSTDAT_VAL 0x0
-#define DSPCFG_VAL 0x5040
-#define SDCFG_VAL 0x008c /* set voltage thresholds for Signal Detect */
-#define DSPCFG_LOCK 0x20 /* coefficient lock bit in DSPCFG */
-#define DSPCFG_COEF 0x1000 /* see coefficient (in TSTDAT) bit in DSPCFG */
-#define TSTDAT_FIXED 0xe8 /* magic number for bad coefficients */
+/** 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 )
-/* Bit in ChipCmd.
+/** 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.
*/
-enum ChipCmdBits {
- ChipReset = 0x100,
- RxReset = 0x20,
- TxReset = 0x10,
- RxOff = 0x08,
- RxOn = 0x04,
- TxOff = 0x02,
- TxOn = 0x01
-};
+#define NATSEMI_TXCFG_DRTH_DEFAULT NATSEMI_TXCFG_DRTH ( 1024 / 32 )
-enum ChipConfig_bits {
- CfgPhyDis = 0x200,
- CfgPhyRst = 0x400,
- CfgExtPhy = 0x1000,
- CfgAnegEnable = 0x2000,
- CfgAneg100 = 0x4000,
- CfgAnegFull = 0x8000,
- CfgAnegDone = 0x8000000,
- CfgFullDuplex = 0x20000000,
- CfgSpeed100 = 0x40000000,
- CfgLink = 0x80000000,
-};
+/** Receive Descriptor Pointer */
+#define NATSEMI_RXDP 0x0030
+/** Receive Descriptor Pointer High Dword (64-bit) */
+#define NATSEMI_RXDP_HI_64 0x0034
-/* Bits in the RxMode register.
- */
-enum rx_mode_bits {
- AcceptErr = 0x20,
- AcceptRunt = 0x10,
- AcceptBroadcast = 0xC0000000,
- AcceptMulticast = 0x00200000,
- AcceptAllMulticast = 0x20000000,
- AcceptAllPhys = 0x10000000,
- AcceptMyPhys = 0x08000000,
- RxFilterEnable = 0x80000000
-};
+/** 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 */ )
-/* Bits in network_desc.status
+/** 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.
*/
-enum desc_status_bits {
- DescOwn = 0x80000000,
- DescMore = 0x40000000,
- DescIntr = 0x20000000,
- DescNoCRC = 0x10000000,
- DescPktOK = 0x08000000,
- RxTooLong = 0x00400000
-};
+#define NATSEMI_RXCFG_MXDMA_DEFAULT NATSEMI_RXCFG_MXDMA ( 0x7 )
-/*Bits in Interrupt Mask register
+/** 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.
*/
-enum Intr_mask_register_bits {
- RxOk = 0x001,
- RxErr = 0x004,
- TxOk = 0x040,
- TxErr = 0x100
-};
-
-enum MIntrCtrl_bits {
- MICRIntEn = 0x2,
-};
+#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
-/* CFG bits [13:16] [18:23] */
-#define CFG_RESET_SAVE 0xfde000
-/* WCSR bits [0:4] [9:10] */
-#define WCSR_RESET_SAVE 0x61f
-/* RFCR bits [20] [22] [27:31] */
-#define RFCR_RESET_SAVE 0xf8500000;
-
-/* Delay between EEPROM clock transitions.
- No extra delay is needed with 33Mhz PCI, but future 66Mhz access may need
- a delay. */
-#define eeprom_delay(ee_addr) inl(ee_addr)
-
-enum EEPROM_Ctrl_Bits {
- EE_ShiftClk = 0x04,
- EE_DataIn = 0x01,
- EE_ChipSelect = 0x08,
- EE_DataOut = 0x02
+/** 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,
};
-#define EE_Write0 (EE_ChipSelect)
-#define EE_Write1 (EE_ChipSelect | EE_DataIn)
+/** A National Semiconductor descriptor ring */
+struct natsemi_ring {
+ /** Descriptors */
+ union natsemi_descriptor *desc;
+ /** Producer index */
+ unsigned int prod;
+ /** Consumer index */
+ unsigned int cons;
-/* The EEPROM commands include the alway-set leading bit. */
-enum EEPROM_Cmds {
- EE_WriteCmd=(5 << 6), EE_ReadCmd=(6 << 6), EE_EraseCmd=(7 << 6),
+ /** Number of descriptors */
+ unsigned int count;
+ /** Descriptor start address register */
+ unsigned int reg;
};
-/* EEPROM access , values are devices specific
+/**
+ * Initialise descriptor ring
+ *
+ * @v ring Descriptor ring
+ * @v count Number of descriptors
+ * @v reg Descriptor start address register
*/
-#define EE_CS 0x08 /* EEPROM chip select */
-#define EE_SK 0x04 /* EEPROM shift clock */
-#define EE_DI 0x01 /* Data in */
-#define EE_DO 0x02 /* Data out */
+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;
+}
-/* Offsets within EEPROM (these are word offsets)
- */
-#define EE_MAC 7
-#define EE_REG EECtrl
-
-static const uint8_t natsemi_ee_bits[] = {
- [SPI_BIT_SCLK] = EE_SK,
- [SPI_BIT_MOSI] = EE_DI,
- [SPI_BIT_MISO] = EE_DO,
- [SPI_BIT_SS(0)] = EE_CS,
+/** 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 address below 4GB */
+ if ( ( address & 0xffffffffUL ) == 0 )
+ return 1;
+
+ return 0;
+}
+
+#endif /* _NATSEMI_H */