iPXE
realtek.h
Go to the documentation of this file.
00001 #ifndef _REALTEK_H
00002 #define _REALTEK_H
00003 
00004 /** @file
00005  *
00006  * Realtek 10/100/1000 network card driver
00007  *
00008  */
00009 
00010 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
00011 
00012 #include <ipxe/spi.h>
00013 #include <ipxe/spi_bit.h>
00014 #include <ipxe/nvo.h>
00015 #include <ipxe/if_ether.h>
00016 
00017 /** PCI memory BAR size */
00018 #define RTL_BAR_SIZE 0x100
00019 
00020 /** A packet descriptor */
00021 struct realtek_descriptor {
00022         /** Buffer size */
00023         uint16_t length;
00024         /** Flags */
00025         uint16_t flags;
00026         /** Reserved */
00027         uint32_t reserved;
00028         /** Buffer address */
00029         uint64_t address;
00030 } __attribute__ (( packed ));
00031 
00032 /** Descriptor buffer size mask */
00033 #define RTL_DESC_SIZE_MASK 0x3fff
00034 
00035 /** Packet descriptor flags */
00036 enum realtek_descriptor_flags {
00037         /** Descriptor is owned by NIC */
00038         RTL_DESC_OWN = 0x8000,
00039         /** End of descriptor ring */
00040         RTL_DESC_EOR = 0x4000,
00041         /** First segment descriptor */
00042         RTL_DESC_FS = 0x2000,
00043         /** Last segment descriptor */
00044         RTL_DESC_LS = 0x1000,
00045         /** Receive error summary */
00046         RTL_DESC_RES = 0x0020,
00047 };
00048 
00049 /** Descriptor ring alignment */
00050 #define RTL_RING_ALIGN 256
00051 
00052 /** A legacy mode receive packet header */
00053 struct realtek_legacy_header {
00054         /** Status */
00055         uint16_t status;
00056         /** Length */
00057         uint16_t length;
00058         /** Packet data */
00059         uint8_t data[0];
00060 } __attribute__ (( packed ));
00061 
00062 /** Legacy mode status bits */
00063 enum realtek_legacy_status {
00064         /** Received OK */
00065         RTL_STAT_ROK = 0x0001,
00066 };
00067 
00068 /** ID Register 0 (6 bytes) */
00069 #define RTL_IDR0 0x00
00070 
00071 /** Multicast Register 0 (dword) */
00072 #define RTL_MAR0 0x08
00073 
00074 /** Multicast Register 4 (dword) */
00075 #define RTL_MAR4 0x0c
00076 
00077 /** Transmit Status of Descriptor N (dword, 8139 only) */
00078 #define RTL_TSD(n) ( 0x10 + 4 * (n) )
00079 #define RTL_TSD_ERTXTH(x)       ( (x) << 16 ) /**< Early TX threshold */
00080 #define RTL_TSD_ERTXTH_DEFAULT RTL_TSD_ERTXTH ( 256 / 32 )
00081 #define RTL_TSD_OWN             0x00002000UL /**< Ownership */
00082 
00083 /** Transmit Start Address of Descriptor N (dword, 8139 only) */
00084 #define RTL_TSAD(n) ( 0x20 + 4 * (n) )
00085 
00086 /** Transmit Normal Priority Descriptors (qword) */
00087 #define RTL_TNPDS 0x20
00088 
00089 /** Number of transmit descriptors
00090  *
00091  * This is a hardware limit when using legacy mode.
00092  */
00093 #define RTL_NUM_TX_DESC 4
00094 
00095 /** Receive Buffer Start Address (dword, 8139 only) */
00096 #define RTL_RBSTART 0x30
00097 
00098 /** Receive buffer length */
00099 #define RTL_RXBUF_LEN 8192
00100 
00101 /** Receive buffer padding */
00102 #define RTL_RXBUF_PAD 2038 /* Allow space for WRAP */
00103 
00104 /** Receive buffer alignment */
00105 #define RTL_RXBUF_ALIGN 16
00106 
00107 /** Command Register (byte) */
00108 #define RTL_CR 0x37
00109 #define RTL_CR_RST              0x10    /**< Reset */
00110 #define RTL_CR_RE               0x08    /**< Receiver Enable */
00111 #define RTL_CR_TE               0x04    /**< Transmit Enable */
00112 #define RTL_CR_BUFE             0x01    /**< Receive buffer empty */
00113 
00114 /** Maximum time to wait for a reset, in milliseconds */
00115 #define RTL_RESET_MAX_WAIT_MS 100
00116 
00117 /** Current Address of Packet Read (word, 8139 only) */
00118 #define RTL_CAPR 0x38
00119 
00120 /** Transmit Priority Polling Register (byte, 8169 only) */
00121 #define RTL_TPPOLL_8169 0x38
00122 #define RTL_TPPOLL_NPQ          0x40    /**< Normal Priority Queue Polling */
00123 
00124 /** Interrupt Mask Register (word) */
00125 #define RTL_IMR 0x3c
00126 #define RTL_IRQ_PUN_LINKCHG     0x0020  /**< Packet underrun / link change */
00127 #define RTL_IRQ_TER             0x0008  /**< Transmit error */
00128 #define RTL_IRQ_TOK             0x0004  /**< Transmit OK */
00129 #define RTL_IRQ_RER             0x0002  /**< Receive error */
00130 #define RTL_IRQ_ROK             0x0001  /**< Receive OK */
00131 
00132 /** Interrupt Status Register (word) */
00133 #define RTL_ISR 0x3e
00134 
00135 /** Transmit (Tx) Configuration Register (dword) */
00136 #define RTL_TCR 0x40
00137 #define RTL_TCR_MXDMA(x)        ( (x) << 8 ) /**< Max DMA burst size */
00138 #define RTL_TCR_MXDMA_MASK      RTL_TCR_MXDMA ( 0x7 )
00139 #define RTL_TCR_MXDMA_DEFAULT   RTL_TCR_MXDMA ( 0x7 /* Unlimited */ )
00140 
00141 /** Receive (Rx) Configuration Register (dword) */
00142 #define RTL_RCR 0x44
00143 #define RTL_RCR_STOP_WORKING    0x01000000UL /**< Here be dragons */
00144 #define RTL_RCR_RXFTH(x)        ( (x) << 13 ) /**< Receive FIFO threshold */
00145 #define RTL_RCR_RXFTH_MASK      RTL_RCR_RXFTH ( 0x7 )
00146 #define RTL_RCR_RXFTH_DEFAULT   RTL_RCR_RXFTH ( 0x7 /* Whole packet */ )
00147 #define RTL_RCR_RBLEN(x)        ( (x) << 11 ) /**< Receive buffer length */
00148 #define RTL_RCR_RBLEN_MASK      RTL_RCR_RBLEN ( 0x3 )
00149 #define RTL_RCR_RBLEN_DEFAULT   RTL_RCR_RBLEN ( 0 /* 8kB */ )
00150 #define RTL_RCR_MXDMA(x)        ( (x) << 8 ) /**< Max DMA burst size */
00151 #define RTL_RCR_MXDMA_MASK      RTL_RCR_MXDMA ( 0x7 )
00152 #define RTL_RCR_MXDMA_DEFAULT   RTL_RCR_MXDMA ( 0x7 /* Unlimited */ )
00153 #define RTL_RCR_WRAP            0x00000080UL /**< Overrun receive buffer */
00154 #define RTL_RCR_9356SEL         0x00000040UL /**< EEPROM is a 93C56 */
00155 #define RTL_RCR_AB              0x00000008UL /**< Accept broadcast packets */
00156 #define RTL_RCR_AM              0x00000004UL /**< Accept multicast packets */
00157 #define RTL_RCR_APM             0x00000002UL /**< Accept physical match */
00158 #define RTL_RCR_AAP             0x00000001UL /**< Accept all packets */
00159 
00160 /** 93C46 (93C56) Command Register (byte) */
00161 #define RTL_9346CR 0x50
00162 #define RTL_9346CR_EEM(x)       ( (x) << 6 ) /**< Mode select */
00163 #define RTL_9346CR_EEM_EEPROM   RTL_9346CR_EEM ( 0x2 ) /**< EEPROM mode */
00164 #define RTL_9346CR_EEM_NORMAL   RTL_9346CR_EEM ( 0x0 ) /**< Normal mode */
00165 #define RTL_9346CR_EECS         0x08    /**< Chip select */
00166 #define RTL_9346CR_EESK         0x04    /**< Clock */
00167 #define RTL_9346CR_EEDI         0x02    /**< Data in */
00168 #define RTL_9346CR_EEDO         0x01    /**< Data out */
00169 
00170 /** Word offset of ID code word within EEPROM */
00171 #define RTL_EEPROM_ID ( 0x00 / 2 )
00172 
00173 /** EEPROM code word magic value */
00174 #define RTL_EEPROM_ID_MAGIC 0x8129
00175 
00176 /** Word offset of MAC address within EEPROM */
00177 #define RTL_EEPROM_MAC ( 0x0e / 2 )
00178 
00179 /** Word offset of VPD / non-volatile options within EEPROM */
00180 #define RTL_EEPROM_VPD ( 0x40 / 2 )
00181 
00182 /** Length of VPD / non-volatile options within EEPROM */
00183 #define RTL_EEPROM_VPD_LEN 0x40
00184 
00185 /** Configuration Register 1 (byte) */
00186 #define RTL_CONFIG1 0x52
00187 #define RTL_CONFIG1_VPD         0x02    /**< Vital Product Data enabled */
00188 
00189 /** Media Status Register (byte, 8139 only) */
00190 #define RTL_MSR 0x58
00191 #define RTL_MSR_TXFCE           0x80    /**< TX flow control enabled */
00192 #define RTL_MSR_RXFCE           0x40    /**< RX flow control enabled */
00193 #define RTL_MSR_AUX_STATUS      0x10    /**< Aux power present */
00194 #define RTL_MSR_SPEED_10        0x08    /**< 10Mbps */
00195 #define RTL_MSR_LINKB           0x04    /**< Inverse of link status */
00196 #define RTL_MSR_TXPF            0x02    /**< TX pause flag */
00197 #define RTL_MSR_RXPF            0x01    /**< RX pause flag */
00198 
00199 /** PHY Access Register (dword, 8169 only) */
00200 #define RTL_PHYAR 0x60
00201 #define RTL_PHYAR_FLAG          0x80000000UL /**< Read/write flag */
00202 
00203 /** Construct PHY Access Register value */
00204 #define RTL_PHYAR_VALUE( flag, reg, data ) ( (flag) | ( (reg) << 16 ) | (data) )
00205 
00206 /** Extract PHY Access Register data */
00207 #define RTL_PHYAR_DATA( value ) ( (value) & 0xffff )
00208 
00209 /** Maximum time to wait for PHY access, in microseconds */
00210 #define RTL_MII_MAX_WAIT_US 500
00211 
00212 /** PHY (GMII, MII, or TBI) Status Register (byte, 8169 only) */
00213 #define RTL_PHYSTATUS 0x6c
00214 #define RTL_PHYSTATUS_ENTBI     0x80    /**< TBI / GMII mode */
00215 #define RTL_PHYSTATUS_TXFLOW    0x40    /**< TX flow control enabled */
00216 #define RTL_PHYSTATUS_RXFLOW    0x20    /**< RX flow control enabled */
00217 #define RTL_PHYSTATUS_1000MF    0x10    /**< 1000Mbps full-duplex */
00218 #define RTL_PHYSTATUS_100M      0x08    /**< 100Mbps */
00219 #define RTL_PHYSTATUS_10M       0x04    /**< 10Mbps */
00220 #define RTL_PHYSTATUS_LINKSTS   0x02    /**< Link ok */
00221 #define RTL_PHYSTATUS_FULLDUP   0x01    /**< Full duplex */
00222 
00223 /** Transmit Priority Polling Register (byte, 8139C+ only) */
00224 #define RTL_TPPOLL_8139CP 0xd9
00225 
00226 /** RX Packet Maximum Size Register (word) */
00227 #define RTL_RMS 0xda
00228 
00229 /** C+ Command Register (word) */
00230 #define RTL_CPCR 0xe0
00231 #define RTL_CPCR_DAC            0x0010  /**< PCI Dual Address Cycle Enable */
00232 #define RTL_CPCR_MULRW          0x0008  /**< PCI Multiple Read/Write Enable */
00233 #define RTL_CPCR_CPRX           0x0002  /**< C+ receive enable */
00234 #define RTL_CPCR_CPTX           0x0001  /**< C+ transmit enable */
00235 
00236 /** Receive Descriptor Start Address Register (qword) */
00237 #define RTL_RDSAR 0xe4
00238 
00239 /** Number of receive descriptors */
00240 #define RTL_NUM_RX_DESC 4
00241 
00242 /** Receive buffer length */
00243 #define RTL_RX_MAX_LEN \
00244         ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ + 4 /* extra space */ )
00245 
00246 /** A Realtek descriptor ring */
00247 struct realtek_ring {
00248         /** Descriptors */
00249         struct realtek_descriptor *desc;
00250         /** Producer index */
00251         unsigned int prod;
00252         /** Consumer index */
00253         unsigned int cons;
00254 
00255         /** Descriptor start address register */
00256         unsigned int reg;
00257         /** Length (in bytes) */
00258         size_t len;
00259 };
00260 
00261 /**
00262  * Initialise descriptor ring
00263  *
00264  * @v ring              Descriptor ring
00265  * @v count             Number of descriptors
00266  * @v reg               Descriptor start address register
00267  */
00268 static inline __attribute__ (( always_inline)) void
00269 realtek_init_ring ( struct realtek_ring *ring, unsigned int count,
00270                     unsigned int reg ) {
00271         ring->len = ( count * sizeof ( ring->desc[0] ) );
00272         ring->reg = reg;
00273 }
00274 
00275 /** A Realtek network card */
00276 struct realtek_nic {
00277         /** Registers */
00278         void *regs;
00279         /** SPI bit-bashing interface */
00280         struct spi_bit_basher spibit;
00281         /** EEPROM */
00282         struct spi_device eeprom;
00283         /** Non-volatile options */
00284         struct nvo_block nvo;
00285         /** MII interface */
00286         struct mii_interface mdio;
00287         /** MII device */
00288         struct mii_device mii;
00289 
00290         /** Legacy datapath mode */
00291         int legacy;
00292         /** PHYAR and PHYSTATUS registers are present */
00293         int have_phy_regs;
00294         /** TPPoll register offset */
00295         unsigned int tppoll;
00296 
00297         /** Transmit descriptor ring */
00298         struct realtek_ring tx;
00299         /** Receive descriptor ring */
00300         struct realtek_ring rx;
00301         /** Receive I/O buffers */
00302         struct io_buffer *rx_iobuf[RTL_NUM_RX_DESC];
00303         /** Receive buffer (legacy mode) */
00304         void *rx_buffer;
00305         /** Offset within receive buffer (legacy mode) */
00306         unsigned int rx_offset;
00307 };
00308 
00309 #endif /* _REALTEK_H */