iPXE
natsemi.h
Go to the documentation of this file.
00001 #ifndef _NATSEMI_H
00002 #define _NATSEMI_H
00003 
00004 /** @file
00005  *
00006  * National Semiconductor "MacPhyter" network card driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER );
00011 
00012 #include <stdint.h>
00013 #include <ipxe/spi.h>
00014 #include <ipxe/spi_bit.h>
00015 
00016 /** BAR size */
00017 #define NATSEMI_BAR_SIZE 0x100
00018 
00019 /** A 32-bit packet descriptor */
00020 struct natsemi_descriptor_32 {
00021         /** Link to next descriptor */
00022         uint32_t link;
00023         /** Command / status */
00024         uint32_t cmdsts;
00025         /** Buffer pointer */
00026         uint32_t bufptr;
00027 } __attribute__ (( packed ));
00028 
00029 /** A 64-bit packet descriptor */
00030 struct natsemi_descriptor_64 {
00031         /** Link to next descriptor */
00032         uint64_t link;
00033         /** Buffer pointer */
00034         uint64_t bufptr;
00035         /** Command / status */
00036         uint32_t cmdsts;
00037         /** Extended status */
00038         uint32_t extsts;
00039 } __attribute__ (( packed ));
00040 
00041 /** A packet descriptor
00042  *
00043  * The 32-bit and 64-bit variants are overlaid such that "cmdsts" can
00044  * be accessed as a common field, and the overall size is a power of
00045  * two (to allow the descriptor ring length to be used as an
00046  * alignment).
00047  */
00048 union natsemi_descriptor {
00049         /** Common fields */
00050         struct {
00051                 /** Reserved */
00052                 uint8_t reserved_a[16];
00053                 /** Command / status */
00054                 uint32_t cmdsts;
00055                 /** Reserved */
00056                 uint8_t reserved_b[12];
00057         } __attribute__ (( packed )) common;
00058         /** 64-bit descriptor */
00059         struct natsemi_descriptor_64 d64;
00060         /** 32-bit descriptor */
00061         struct {
00062                 /** Reserved */
00063                 uint8_t reserved[12];
00064                 /** Descriptor */
00065                 struct natsemi_descriptor_32 d32;
00066         } __attribute__ (( packed )) d32pad;
00067 };
00068 
00069 /** Descriptor buffer size mask */
00070 #define NATSEMI_DESC_SIZE_MASK 0xfff
00071 
00072 /** Packet descriptor flags */
00073 enum natsemi_descriptor_flags {
00074         /** Descriptor is owned by NIC */
00075         NATSEMI_DESC_OWN = 0x80000000UL,
00076         /** Request descriptor interrupt */
00077         NATSEMI_DESC_INTR = 0x20000000UL,
00078         /** Packet OK */
00079         NATSEMI_DESC_OK = 0x08000000UL,
00080 };
00081 
00082 /** Command Register */
00083 #define NATSEMI_CR 0x0000
00084 #define NATSEMI_CR_RST          0x00000100UL    /**< Reset */
00085 #define NATSEMI_CR_RXR          0x00000020UL    /**< Receiver reset */
00086 #define NATSEMI_CR_TXR          0x00000010UL    /**< Transmit reset */
00087 #define NATSEMI_CR_RXE          0x00000004UL    /**< Receiver enable */
00088 #define NATSEMI_CR_TXE          0x00000001UL    /**< Transmit enable */
00089 
00090 /** Maximum time to wait for a reset, in milliseconds */
00091 #define NATSEMI_RESET_MAX_WAIT_MS 100
00092 
00093 /** Configuration and Media Status Register */
00094 #define NATSEMI_CFG 0x0004
00095 #define NATSEMI_CFG_LNKSTS      0x80000000UL    /**< Link status */
00096 #define NATSEMI_CFG_SPDSTS1     0x40000000UL    /**< Speed status bit 1 */
00097 #define NATSEMI_CFG_MODE_1000   0x00400000UL    /**< 1000 Mb/s mode control */
00098 #define NATSEMI_CFG_PCI64_DET   0x00002000UL    /**< PCI 64-bit bus detected */
00099 #define NATSEMI_CFG_DATA64_EN   0x00001000UL    /**< 64-bit data enable */
00100 #define NATSEMI_CFG_M64ADDR     0x00000800UL    /**< 64-bit address enable */
00101 #define NATSEMI_CFG_EXTSTS_EN   0x00000100UL    /**< Extended status enable */
00102 
00103 /** EEPROM Access Register */
00104 #define NATSEMI_MEAR 0x0008
00105 #define NATSEMI_MEAR_EESEL      0x00000008UL    /**< EEPROM chip select */
00106 #define NATSEMI_MEAR_EECLK      0x00000004UL    /**< EEPROM serial clock */
00107 #define NATSEMI_MEAR_EEDO       0x00000002UL    /**< EEPROM data out */
00108 #define NATSEMI_MEAR_EEDI       0x00000001UL    /**< EEPROM data in */
00109 
00110 /** Size of EEPROM (in bytes) */
00111 #define NATSEMI_EEPROM_SIZE 32
00112 
00113 /** Word offset of MAC address within sane EEPROM layout */
00114 #define NATSEMI_EEPROM_MAC_SANE 0x0a
00115 
00116 /** Word offset of MAC address within insane EEPROM layout */
00117 #define NATSEMI_EEPROM_MAC_INSANE 0x06
00118 
00119 /** PCI Test Control Register */
00120 #define NATSEMI_PTSCR 0x000c
00121 #define NATSEMI_PTSCR_EELOAD_EN 0x00000004UL    /**< Enable EEPROM load */
00122 
00123 /** Maximum time to wait for a configuration reload, in milliseconds */
00124 #define NATSEMI_EELOAD_MAX_WAIT_MS 100
00125 
00126 /** Interrupt Status Register */
00127 #define NATSEMI_ISR 0x0010
00128 #define NATSEMI_IRQ_TXDESC      0x00000080UL    /**< TX descriptor */
00129 #define NATSEMI_IRQ_RXDESC      0x00000002UL    /**< RX descriptor */
00130 
00131 /** Interrupt Mask Register */
00132 #define NATSEMI_IMR 0x0014
00133 
00134 /** Interrupt Enable Register */
00135 #define NATSEMI_IER 0x0018
00136 #define NATSEMI_IER_IE          0x00000001UL    /**< Interrupt enable */
00137 
00138 /** Transmit Descriptor Pointer */
00139 #define NATSEMI_TXDP 0x0020
00140 
00141 /** Transmit Descriptor Pointer High Dword (64-bit) */
00142 #define NATSEMI_TXDP_HI_64 0x0024
00143 
00144 /** Number of transmit descriptors */
00145 #define NATSEMI_NUM_TX_DESC 4
00146 
00147 /** Transmit configuration register (32-bit) */
00148 #define NATSEMI_TXCFG_32 0x24
00149 
00150 /** Transmit configuration register (64-bit) */
00151 #define NATSEMI_TXCFG_64 0x28
00152 #define NATSEMI_TXCFG_CSI       0x80000000UL    /**< Carrier sense ignore */
00153 #define NATSEMI_TXCFG_HBI       0x40000000UL    /**< Heartbeat ignore */
00154 #define NATSEMI_TXCFG_ATP       0x10000000UL    /**< Automatic padding */
00155 #define NATSEMI_TXCFG_ECRETRY   0x00800000UL    /**< Excess collision retry */
00156 #define NATSEMI_TXCFG_MXDMA(x)  ( (x) << 20 )   /**< Max DMA burst size */
00157 #define NATSEMI_TXCFG_FLTH(x)   ( (x) << 8 )    /**< Fill threshold */
00158 #define NATSEMI_TXCFG_DRTH(x)   ( (x) << 0 )    /**< Drain threshold */
00159 
00160 /** Max DMA burst size (encoded value)
00161  *
00162  * This represents 256-byte bursts on 83815 controllers and 512-byte
00163  * bursts on 83820 controllers.
00164  */
00165 #define NATSEMI_TXCFG_MXDMA_DEFAULT NATSEMI_TXCFG_MXDMA ( 0x7 )
00166 
00167 /** Fill threshold (in units of 32 bytes)
00168  *
00169  * Must be at least as large as the max DMA burst size, so use a value
00170  * of 512 bytes.
00171  */
00172 #define NATSEMI_TXCFG_FLTH_DEFAULT NATSEMI_TXCFG_FLTH ( 512 / 32 )
00173 
00174 /** Drain threshold (in units of 32 bytes)
00175  *
00176  * Start transmission once we receive a conservative 1024 bytes, to
00177  * avoid FIFO underrun errors.  (83815 does not allow us to specify a
00178  * value of 0 for "wait until whole packet is present".)
00179  *
00180  * Fill threshold plus drain threshold must be less than the transmit
00181  * FIFO size, which is 2kB on 83815 and 8kB on 83820.
00182  */
00183 #define NATSEMI_TXCFG_DRTH_DEFAULT NATSEMI_TXCFG_DRTH ( 1024 / 32 )
00184 
00185 /** Receive Descriptor Pointer */
00186 #define NATSEMI_RXDP 0x0030
00187 
00188 /** Receive Descriptor Pointer High Dword (64-bit) */
00189 #define NATSEMI_RXDP_HI_64 0x0034
00190 
00191 /** Number of receive descriptors */
00192 #define NATSEMI_NUM_RX_DESC 4
00193 
00194 /** Receive buffer length */
00195 #define NATSEMI_RX_MAX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ )
00196 
00197 /** Receive configuration register (32-bit) */
00198 #define NATSEMI_RXCFG_32 0x34
00199 
00200 /** Receive configuration register (64-bit) */
00201 #define NATSEMI_RXCFG_64 0x38
00202 #define NATSEMI_RXCFG_ARP       0x40000000UL    /**< Accept runt packets */
00203 #define NATSEMI_RXCFG_ATX       0x10000000UL    /**< Accept transmit packets */
00204 #define NATSEMI_RXCFG_ALP       0x08000000UL    /**< Accept long packets */
00205 #define NATSEMI_RXCFG_MXDMA(x)  ( (x) << 20 )   /**< Max DMA burst size */
00206 #define NATSEMI_RXCFG_DRTH(x)   ( (x) << 1 )    /**< Drain threshold */
00207 
00208 /** Max DMA burst size (encoded value)
00209  *
00210  * This represents 256-byte bursts on 83815 controllers and 512-byte
00211  * bursts on 83820 controllers.
00212  */
00213 #define NATSEMI_RXCFG_MXDMA_DEFAULT NATSEMI_RXCFG_MXDMA ( 0x7 )
00214 
00215 /** Drain threshold (in units of 8 bytes)
00216  *
00217  * Start draining after 64 bytes.
00218  *
00219  * Must be large enough to allow packet's accept/reject status to be
00220  * determined before draining begins.
00221  */
00222 #define NATSEMI_RXCFG_DRTH_DEFAULT NATSEMI_RXCFG_DRTH ( 64 / 8 )
00223 
00224 /** Receive Filter/Match Control Register */
00225 #define NATSEMI_RFCR 0x0048
00226 #define NATSEMI_RFCR_RFEN       0x80000000UL    /**< RX filter enable */
00227 #define NATSEMI_RFCR_AAB        0x40000000UL    /**< Accept all broadcast */
00228 #define NATSEMI_RFCR_AAM        0x20000000UL    /**< Accept all multicast */
00229 #define NATSEMI_RFCR_AAU        0x10000000UL    /**< Accept all unicast */
00230 #define NATSEMI_RFCR_RFADDR( addr ) ( (addr) << 0 ) /**< Extended address */
00231 #define NATSEMI_RFCR_RFADDR_MASK NATSEMI_RFCR_RFADDR ( 0x3ff )
00232 
00233 /** Perfect match filter address base */
00234 #define NATSEMI_RFADDR_PMATCH_BASE 0x000
00235 
00236 /** Receive Filter/Match Data Register */
00237 #define NATSEMI_RFDR 0x004c
00238 #define NATSEMI_RFDR_BMASK      0x00030000UL    /**< Byte mask */
00239 #define NATSEMI_RFDR_DATA( value ) ( (value) & 0xffff ) /**< Filter data */
00240 
00241 /** National Semiconductor network card flags */
00242 enum natsemi_nic_flags {
00243         /** EEPROM is little-endian */
00244         NATSEMI_EEPROM_LITTLE_ENDIAN = 0x0001,
00245         /** EEPROM layout is insane */
00246         NATSEMI_EEPROM_INSANE = 0x0002,
00247         /** Card supports 64-bit operation */
00248         NATSEMI_64BIT = 0x0004,
00249         /** Card supports 1000Mbps link */
00250         NATSEMI_1000 = 0x0008,
00251 };
00252 
00253 /** A National Semiconductor descriptor ring */
00254 struct natsemi_ring {
00255         /** Descriptors */
00256         union natsemi_descriptor *desc;
00257         /** Producer index */
00258         unsigned int prod;
00259         /** Consumer index */
00260         unsigned int cons;
00261 
00262         /** Number of descriptors */
00263         unsigned int count;
00264         /** Descriptor start address register */
00265         unsigned int reg;
00266 };
00267 
00268 /**
00269  * Initialise descriptor ring
00270  *
00271  * @v ring              Descriptor ring
00272  * @v count             Number of descriptors
00273  * @v reg               Descriptor start address register
00274  */
00275 static inline __attribute__ (( always_inline)) void
00276 natsemi_init_ring ( struct natsemi_ring *ring, unsigned int count,
00277                     unsigned int reg ) {
00278         ring->count = count;
00279         ring->reg = reg;
00280 }
00281 
00282 /** A National Semiconductor network card */
00283 struct natsemi_nic {
00284         /** Flags */
00285         unsigned int flags;
00286         /** Registers */
00287         void *regs;
00288         /** SPI bit-bashing interface */
00289         struct spi_bit_basher spibit;
00290         /** EEPROM */
00291         struct spi_device eeprom;
00292 
00293         /** Transmit descriptor ring */
00294         struct natsemi_ring tx;
00295         /** Receive descriptor ring */
00296         struct natsemi_ring rx;
00297         /** Receive I/O buffers */
00298         struct io_buffer *rx_iobuf[NATSEMI_NUM_RX_DESC];
00299 
00300         /** Link status (cache) */
00301         uint32_t cfg;
00302 };
00303 
00304 /**
00305  * Check if card can access physical address
00306  *
00307  * @v natsemi           National Semiconductor device
00308  * @v address           Physical address
00309  * @v address_ok        Card can access physical address
00310  */
00311 static inline __attribute__ (( always_inline )) int
00312 natsemi_address_ok ( struct natsemi_nic *natsemi, physaddr_t address ) {
00313 
00314         /* In a 32-bit build, all addresses can be accessed */
00315         if ( sizeof ( physaddr_t ) <= sizeof ( uint32_t ) )
00316                 return 1;
00317 
00318         /* A 64-bit card can access all addresses */
00319         if ( natsemi->flags & NATSEMI_64BIT )
00320                 return 1;
00321 
00322         /* A 32-bit card can access all addresses below 4GB */
00323         if ( ( address & ~0xffffffffULL ) == 0 )
00324                 return 1;
00325 
00326         return 0;
00327 }
00328 
00329 #endif /* _NATSEMI_H */