2012-04-24 00:29:18 +02:00
|
|
|
#ifndef _INTEL_H
|
|
|
|
#define _INTEL_H
|
|
|
|
|
|
|
|
/** @file
|
|
|
|
*
|
|
|
|
* Intel 10/100/1000 network card driver
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
FILE_LICENCE ( GPL2_OR_LATER );
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <ipxe/if_ether.h>
|
|
|
|
#include <ipxe/nvs.h>
|
|
|
|
|
|
|
|
/** Intel BAR size */
|
|
|
|
#define INTEL_BAR_SIZE ( 128 * 1024 )
|
|
|
|
|
|
|
|
/** A packet descriptor */
|
|
|
|
struct intel_descriptor {
|
|
|
|
/** Buffer address */
|
|
|
|
uint64_t address;
|
|
|
|
/** Length */
|
|
|
|
uint16_t length;
|
|
|
|
/** Reserved */
|
|
|
|
uint8_t reserved_a;
|
|
|
|
/** Command */
|
|
|
|
uint8_t command;
|
|
|
|
/** Status */
|
|
|
|
uint8_t status;
|
|
|
|
/** Errors */
|
|
|
|
uint8_t errors;
|
|
|
|
/** Reserved */
|
|
|
|
uint16_t reserved_b;
|
|
|
|
} __attribute__ (( packed ));
|
|
|
|
|
|
|
|
/** Packet descriptor command bits */
|
|
|
|
enum intel_descriptor_command {
|
|
|
|
/** Report status */
|
|
|
|
INTEL_DESC_CMD_RS = 0x08,
|
|
|
|
/** Insert frame checksum (CRC) */
|
|
|
|
INTEL_DESC_CMD_IFCS = 0x02,
|
|
|
|
/** End of packet */
|
|
|
|
INTEL_DESC_CMD_EOP = 0x01,
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Packet descriptor status bits */
|
|
|
|
enum intel_descriptor_status {
|
|
|
|
/** Descriptor done */
|
|
|
|
INTEL_DESC_STATUS_DD = 0x01,
|
|
|
|
};
|
|
|
|
|
|
|
|
/** Device Control Register */
|
|
|
|
#define INTEL_CTRL 0x00000UL
|
|
|
|
#define INTEL_CTRL_LRST 0x00000008UL /**< Link reset */
|
|
|
|
#define INTEL_CTRL_ASDE 0x00000020UL /**< Auto-speed detection */
|
|
|
|
#define INTEL_CTRL_SLU 0x00000040UL /**< Set link up */
|
|
|
|
#define INTEL_CTRL_FRCSPD 0x00000800UL /**< Force speed */
|
|
|
|
#define INTEL_CTRL_FRCDPLX 0x00001000UL /**< Force duplex */
|
|
|
|
#define INTEL_CTRL_RST 0x04000000UL /**< Device reset */
|
|
|
|
#define INTEL_CTRL_PHY_RST 0x80000000UL /**< PHY reset */
|
|
|
|
|
|
|
|
/** Time to delay for device reset, in milliseconds */
|
|
|
|
#define INTEL_RESET_DELAY_MS 20
|
|
|
|
|
|
|
|
/** Device Status Register */
|
|
|
|
#define INTEL_STATUS 0x00008UL
|
|
|
|
#define INTEL_STATUS_LU 0x00000002UL /**< Link up */
|
|
|
|
|
|
|
|
/** EEPROM Read Register */
|
|
|
|
#define INTEL_EERD 0x00014UL
|
|
|
|
#define INTEL_EERD_START 0x00000001UL /**< Start read */
|
|
|
|
#define INTEL_EERD_DONE_SMALL 0x00000010UL /**< Read done (small EERD) */
|
|
|
|
#define INTEL_EERD_DONE_LARGE 0x00000002UL /**< Read done (large EERD) */
|
|
|
|
#define INTEL_EERD_ADDR_SHIFT_SMALL 8 /**< Address shift (small) */
|
|
|
|
#define INTEL_EERD_ADDR_SHIFT_LARGE 2 /**< Address shift (large) */
|
|
|
|
#define INTEL_EERD_DATA(value) ( (value) >> 16 ) /**< Read data */
|
|
|
|
|
|
|
|
/** Maximum time to wait for EEPROM read, in milliseconds */
|
|
|
|
#define INTEL_EEPROM_MAX_WAIT_MS 100
|
|
|
|
|
|
|
|
/** EEPROM word length */
|
|
|
|
#define INTEL_EEPROM_WORD_LEN_LOG2 1
|
|
|
|
|
|
|
|
/** Minimum EEPROM size, in words */
|
|
|
|
#define INTEL_EEPROM_MIN_SIZE_WORDS 64
|
|
|
|
|
|
|
|
/** Offset of MAC address within EEPROM */
|
|
|
|
#define INTEL_EEPROM_MAC 0x00
|
|
|
|
|
|
|
|
/** Interrupt Cause Read Register */
|
|
|
|
#define INTEL_ICR 0x000c0UL
|
|
|
|
#define INTEL_IRQ_TXDW 0x00000001UL /**< Transmit descriptor done */
|
|
|
|
#define INTEL_IRQ_LSC 0x00000004UL /**< Link status change */
|
|
|
|
#define INTEL_IRQ_RXT0 0x00000080UL /**< Receive timer */
|
|
|
|
|
|
|
|
/** Interrupt Mask Set/Read Register */
|
|
|
|
#define INTEL_IMS 0x000d0UL
|
|
|
|
|
|
|
|
/** Interrupt Mask Clear Register */
|
|
|
|
#define INTEL_IMC 0x000d8UL
|
|
|
|
|
|
|
|
/** Receive Control Register */
|
|
|
|
#define INTEL_RCTL 0x00100UL
|
|
|
|
#define INTEL_RCTL_EN 0x00000002UL /**< Receive enable */
|
|
|
|
#define INTEL_RCTL_UPE 0x00000008UL /**< Unicast promiscuous mode */
|
|
|
|
#define INTEL_RCTL_MPE 0x00000010UL /**< Multicast promiscuous */
|
|
|
|
#define INTEL_RCTL_BAM 0x00008000UL /**< Broadcast accept mode */
|
|
|
|
#define INTEL_RCTL_BSIZE_BSEX(bsex,bsize) \
|
|
|
|
( ( (bsize) << 16 ) | ( (bsex) << 25 ) ) /**< Buffer size */
|
|
|
|
#define INTEL_RCTL_BSIZE_2048 INTEL_RCTL_BSIZE_BSEX ( 0, 0 )
|
|
|
|
#define INTEL_RCTL_BSIZE_BSEX_MASK INTEL_RCTL_BSIZE_BSEX ( 1, 3 )
|
|
|
|
#define INTEL_RCTL_SECRC 0x04000000UL /**< Strip CRC */
|
|
|
|
|
|
|
|
/** Transmit Control Register */
|
|
|
|
#define INTEL_TCTL 0x00400UL
|
|
|
|
#define INTEL_TCTL_EN 0x00000002UL /**< Transmit enable */
|
|
|
|
#define INTEL_TCTL_PSP 0x00000008UL /**< Pad short packets */
|
|
|
|
#define INTEL_TCTL_CT(x) ( (x) << 4 ) /**< Collision threshold */
|
|
|
|
#define INTEL_TCTL_CT_DEFAULT INTEL_TCTL_CT ( 0x0f )
|
|
|
|
#define INTEL_TCTL_CT_MASK INTEL_TCTL_CT ( 0xff )
|
|
|
|
#define INTEL_TCTL_COLD(x) ( (x) << 12 ) /**< Collision distance */
|
|
|
|
#define INTEL_TCTL_COLD_DEFAULT INTEL_TCTL_COLD ( 0x040 )
|
|
|
|
#define INTEL_TCTL_COLD_MASK INTEL_TCTL_COLD ( 0x3ff )
|
|
|
|
|
|
|
|
/** Packet Buffer Allocation */
|
|
|
|
#define INTEL_PBA 0x01000UL
|
|
|
|
|
|
|
|
/** Packet Buffer Size */
|
|
|
|
#define INTEL_PBS 0x01008UL
|
|
|
|
|
|
|
|
/** Receive Descriptor register block */
|
|
|
|
#define INTEL_RD 0x02800UL
|
|
|
|
|
|
|
|
/** Number of receive descriptors
|
|
|
|
*
|
|
|
|
* Minimum value is 8, since the descriptor ring length must be a
|
|
|
|
* multiple of 128.
|
|
|
|
*/
|
|
|
|
#define INTEL_NUM_RX_DESC 8
|
|
|
|
|
|
|
|
/** Receive descriptor ring fill level */
|
|
|
|
#define INTEL_RX_FILL 4
|
|
|
|
|
|
|
|
/** Receive buffer length */
|
|
|
|
#define INTEL_RX_MAX_LEN 2048
|
|
|
|
|
|
|
|
/** Transmit Descriptor register block */
|
|
|
|
#define INTEL_TD 0x03800UL
|
|
|
|
|
|
|
|
/** Number of transmit descriptors
|
|
|
|
*
|
|
|
|
* Descriptor ring length must be a multiple of 16. ICH8/9/10
|
|
|
|
* requires a minimum of 16 TX descriptors.
|
|
|
|
*/
|
|
|
|
#define INTEL_NUM_TX_DESC 16
|
|
|
|
|
|
|
|
/** Receive/Transmit Descriptor Base Address Low (offset) */
|
|
|
|
#define INTEL_xDBAL 0x00
|
|
|
|
|
|
|
|
/** Receive/Transmit Descriptor Base Address High (offset) */
|
|
|
|
#define INTEL_xDBAH 0x04
|
|
|
|
|
|
|
|
/** Receive/Transmit Descriptor Length (offset) */
|
|
|
|
#define INTEL_xDLEN 0x08
|
|
|
|
|
|
|
|
/** Receive/Transmit Descriptor Head (offset) */
|
|
|
|
#define INTEL_xDH 0x10
|
|
|
|
|
|
|
|
/** Receive/Transmit Descriptor Tail (offset) */
|
|
|
|
#define INTEL_xDT 0x18
|
|
|
|
|
2012-07-10 11:52:56 +02:00
|
|
|
/** Receive/Transmit Descriptor Control (offset) */
|
|
|
|
#define INTEL_xDCTL 0x28
|
|
|
|
#define INTEL_xDCTL_ENABLE 0x02000000UL /**< Queue enable */
|
|
|
|
|
2012-04-24 00:29:18 +02:00
|
|
|
/** Receive Descriptor Head */
|
|
|
|
#define INTEL_RDH ( INTEL_RD + INTEL_xDH )
|
|
|
|
|
|
|
|
/** Receive Descriptor Tail */
|
|
|
|
#define INTEL_RDT ( INTEL_RD + INTEL_xDT )
|
|
|
|
|
|
|
|
/** Transmit Descriptor Head */
|
|
|
|
#define INTEL_TDH ( INTEL_TD + INTEL_xDH )
|
|
|
|
|
|
|
|
/** Transmit Descriptor Tail */
|
|
|
|
#define INTEL_TDT ( INTEL_TD + INTEL_xDT )
|
|
|
|
|
|
|
|
/** Receive Address Low */
|
|
|
|
#define INTEL_RAL0 0x05400UL
|
|
|
|
|
|
|
|
/** Receive Address High */
|
|
|
|
#define INTEL_RAH0 0x05404UL
|
|
|
|
#define INTEL_RAH0_AV 0x80000000UL /**< Address valid */
|
|
|
|
|
|
|
|
/** Receive address */
|
|
|
|
union intel_receive_address {
|
|
|
|
struct {
|
|
|
|
uint32_t low;
|
|
|
|
uint32_t high;
|
|
|
|
} __attribute__ (( packed )) reg;
|
|
|
|
uint8_t raw[ETH_ALEN];
|
|
|
|
};
|
|
|
|
|
|
|
|
/** An Intel descriptor ring */
|
|
|
|
struct intel_ring {
|
|
|
|
/** Descriptors */
|
|
|
|
struct intel_descriptor *desc;
|
|
|
|
/** Producer index */
|
|
|
|
unsigned int prod;
|
|
|
|
/** Consumer index */
|
|
|
|
unsigned int cons;
|
|
|
|
|
|
|
|
/** Register block */
|
|
|
|
unsigned int reg;
|
|
|
|
/** Length (in bytes) */
|
|
|
|
size_t len;
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Initialise descriptor ring
|
|
|
|
*
|
|
|
|
* @v ring Descriptor ring
|
|
|
|
* @v count Number of descriptors
|
|
|
|
* @v reg Descriptor register block
|
|
|
|
*/
|
|
|
|
static inline __attribute__ (( always_inline)) void
|
|
|
|
intel_init_ring ( struct intel_ring *ring, unsigned int count,
|
|
|
|
unsigned int reg ) {
|
|
|
|
ring->len = ( count * sizeof ( ring->desc[0] ) );
|
|
|
|
ring->reg = reg;
|
|
|
|
}
|
|
|
|
|
|
|
|
/** An Intel network card */
|
|
|
|
struct intel_nic {
|
|
|
|
/** Registers */
|
|
|
|
void *regs;
|
|
|
|
/** Port number (for multi-port devices) */
|
|
|
|
unsigned int port;
|
|
|
|
|
|
|
|
/** EEPROM */
|
|
|
|
struct nvs_device eeprom;
|
|
|
|
/** EEPROM done flag */
|
|
|
|
uint32_t eerd_done;
|
|
|
|
/** EEPROM address shift */
|
|
|
|
unsigned int eerd_addr_shift;
|
|
|
|
|
|
|
|
/** Transmit descriptor ring */
|
|
|
|
struct intel_ring tx;
|
|
|
|
/** Receive descriptor ring */
|
|
|
|
struct intel_ring rx;
|
|
|
|
/** Receive I/O buffers */
|
|
|
|
struct io_buffer *rx_iobuf[INTEL_NUM_RX_DESC];
|
|
|
|
};
|
|
|
|
|
|
|
|
#endif /* _INTEL_H */
|