#ifndef _NATSEMI_H #define _NATSEMI_H /** @file * * National Semiconductor "MacPhyter" network card driver * */ FILE_LICENCE ( GPL2_OR_LATER ); #include #include #include /** 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 */