diff options
Diffstat (limited to 'src/drivers/net/exanic.h')
-rw-r--r-- | src/drivers/net/exanic.h | 257 |
1 files changed, 257 insertions, 0 deletions
diff --git a/src/drivers/net/exanic.h b/src/drivers/net/exanic.h new file mode 100644 index 00000000..fd9f5b8c --- /dev/null +++ b/src/drivers/net/exanic.h @@ -0,0 +1,257 @@ +#ifndef _EXANIC_H +#define _EXANIC_H + +/** @file + * + * Exablaze ExaNIC driver + * + */ + +FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); + +#include <stdint.h> +#include <ipxe/pci.h> +#include <ipxe/ethernet.h> +#include <ipxe/uaccess.h> +#include <ipxe/retry.h> +#include <ipxe/i2c.h> +#include <ipxe/bitbash.h> + +/** Maximum number of ports */ +#define EXANIC_MAX_PORTS 8 + +/** Register BAR */ +#define EXANIC_REGS_BAR PCI_BASE_ADDRESS_0 + +/** Transmit region BAR */ +#define EXANIC_TX_BAR PCI_BASE_ADDRESS_2 + +/** Alignment for DMA regions */ +#define EXANIC_ALIGN 0x1000 + +/** Flag for 32-bit DMA addresses */ +#define EXANIC_DMA_32_BIT 0x00000001UL + +/** Register set length */ +#define EXANIC_REGS_LEN 0x2000 + +/** Transmit feedback region length */ +#define EXANIC_TXF_LEN 0x1000 + +/** Transmit feedback slot + * + * This is a policy decision. + */ +#define EXANIC_TXF_SLOT( index ) ( 0x40 * (index) ) + +/** Receive region length */ +#define EXANIC_RX_LEN 0x200000 + +/** Transmit feedback base address register */ +#define EXANIC_TXF_BASE 0x0014 + +/** Capabilities register */ +#define EXANIC_CAPS 0x0038 +#define EXANIC_CAPS_100M 0x01000000UL /**< 100Mbps supported */ +#define EXANIC_CAPS_1G 0x02000000UL /**< 1Gbps supported */ +#define EXANIC_CAPS_10G 0x04000000UL /**< 10Gbps supported */ +#define EXANIC_CAPS_40G 0x08000000UL /**< 40Gbps supported */ +#define EXANIC_CAPS_100G 0x10000000UL /**< 100Gbps supported */ +#define EXANIC_CAPS_SPEED_MASK 0x1f000000UL /**< Supported speeds mask */ + +/** I2C GPIO register */ +#define EXANIC_I2C 0x012c + +/** Port register offset */ +#define EXANIC_PORT_REGS( index ) ( 0x0200 + ( 0x40 * (index) ) ) + +/** Port enable register */ +#define EXANIC_PORT_ENABLE 0x0000 +#define EXANIC_PORT_ENABLE_ENABLED 0x00000001UL /**< Port is enabled */ + +/** Port speed register */ +#define EXANIC_PORT_SPEED 0x0004 + +/** Port status register */ +#define EXANIC_PORT_STATUS 0x0008 +#define EXANIC_PORT_STATUS_LINK 0x00000008UL /**< Link is up */ +#define EXANIC_PORT_STATUS_ABSENT 0x80000000UL /**< Port is not present */ + +/** Port MAC address (second half) register */ +#define EXANIC_PORT_MAC 0x000c + +/** Port flags register */ +#define EXANIC_PORT_FLAGS 0x0010 +#define EXANIC_PORT_FLAGS_PROMISC 0x00000001UL /**< Promiscuous mode */ + +/** Port receive chunk base address register */ +#define EXANIC_PORT_RX_BASE 0x0014 + +/** Port transmit command register */ +#define EXANIC_PORT_TX_COMMAND 0x0020 + +/** Port transmit region offset register */ +#define EXANIC_PORT_TX_OFFSET 0x0024 + +/** Port transmit region length register */ +#define EXANIC_PORT_TX_LEN 0x0028 + +/** Port MAC address (first half) register */ +#define EXANIC_PORT_OUI 0x0030 + +/** Port interrupt configuration register */ +#define EXANIC_PORT_IRQ 0x0034 + +/** An ExaNIC transmit chunk descriptor */ +struct exanic_tx_descriptor { + /** Feedback ID */ + uint16_t txf_id; + /** Feedback slot */ + uint16_t txf_slot; + /** Payload length (including padding */ + uint16_t len; + /** Payload type */ + uint8_t type; + /** Flags */ + uint8_t flags; +} __attribute__ (( packed )); + +/** An ExaNIC transmit chunk */ +struct exanic_tx_chunk { + /** Descriptor */ + struct exanic_tx_descriptor desc; + /** Padding */ + uint8_t pad[2]; + /** Payload data */ + uint8_t data[2038]; +} __attribute__ (( packed )); + +/** Raw Ethernet frame type */ +#define EXANIC_TYPE_RAW 0x01 + +/** An ExaNIC receive chunk descriptor */ +struct exanic_rx_descriptor { + /** Timestamp */ + uint32_t timestamp; + /** Status (valid only on final chunk) */ + uint8_t status; + /** Length (zero except on the final chunk) */ + uint8_t len; + /** Filter number */ + uint8_t filter; + /** Generation */ + uint8_t generation; +} __attribute__ (( packed )); + +/** An ExaNIC receive chunk */ +struct exanic_rx_chunk { + /** Payload data */ + uint8_t data[120]; + /** Descriptor */ + struct exanic_rx_descriptor desc; +} __attribute__ (( packed )); + +/** Receive status error mask */ +#define EXANIC_STATUS_ERROR_MASK 0x0f + +/** An ExaNIC I2C bus configuration */ +struct exanic_i2c_config { + /** GPIO bit for pulling SCL low */ + uint8_t setscl; + /** GPIO bit for pulling SDA low */ + uint8_t setsda; + /** GPIO bit for reading SDA */ + uint8_t getsda; +}; + +/** EEPROM address */ +#define EXANIC_EEPROM_ADDRESS 0x50 + +/** An ExaNIC port */ +struct exanic_port { + /** Network device */ + struct net_device *netdev; + /** Port registers */ + void *regs; + + /** Transmit region offset */ + size_t tx_offset; + /** Transmit region */ + void *tx; + /** Number of transmit descriptors */ + uint16_t tx_count; + /** Transmit producer counter */ + uint16_t tx_prod; + /** Transmit consumer counter */ + uint16_t tx_cons; + /** Transmit feedback slot */ + uint16_t txf_slot; + /** Transmit feedback region */ + uint16_t *txf; + + /** Receive region */ + userptr_t rx; + /** Receive consumer counter */ + unsigned int rx_cons; + /** Receive I/O buffer (if any) */ + struct io_buffer *rx_iobuf; + /** Receive status */ + int rx_rc; + + /** Port status */ + uint32_t status; + /** Default link speed (as raw register value) */ + uint32_t default_speed; + /** Speed capability bitmask */ + uint32_t speeds; + /** Current attempted link speed (as a capability bit index) */ + unsigned int speed; + /** Port status check timer */ + struct retry_timer timer; +}; + +/** An ExaNIC */ +struct exanic { + /** Registers */ + void *regs; + /** Transmit region */ + void *tx; + /** Transmit feedback region */ + void *txf; + + /** I2C bus configuration */ + struct exanic_i2c_config i2cfg; + /** I2C bit-bashing interface */ + struct i2c_bit_basher basher; + /** I2C serial EEPROM */ + struct i2c_device eeprom; + + /** Capabilities */ + uint32_t caps; + /** Base MAC address */ + uint8_t mac[ETH_ALEN]; + + /** Ports */ + struct exanic_port *port[EXANIC_MAX_PORTS]; +}; + +/** Maximum used length of transmit region + * + * This is a policy decision to avoid overflowing the 16-bit transmit + * producer and consumer counters. + */ +#define EXANIC_MAX_TX_LEN ( 256 * sizeof ( struct exanic_tx_chunk ) ) + +/** Maximum length of received packet + * + * This is a policy decision. + */ +#define EXANIC_MAX_RX_LEN ( ETH_FRAME_LEN + 4 /* VLAN */ + 4 /* CRC */ ) + +/** Interval between link state checks + * + * This is a policy decision. + */ +#define EXANIC_LINK_INTERVAL ( 1 * TICKS_PER_SEC ) + +#endif /* _EXANIC_H */ |