123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588 |
- #ifndef _ENA_H
- #define _ENA_H
-
- /** @file
- *
- * Amazon ENA network driver
- *
- */
-
- FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
-
- #include <stdint.h>
- #include <ipxe/if_ether.h>
-
- /** BAR size */
- #define ENA_BAR_SIZE 16384
-
- /** Queue alignment */
- #define ENA_ALIGN 4096
-
- /** Number of admin queue entries */
- #define ENA_AQ_COUNT 2
-
- /** Number of admin completion queue entries */
- #define ENA_ACQ_COUNT 2
-
- /** Number of transmit queue entries */
- #define ENA_TX_COUNT 16
-
- /** Number of receive queue entries */
- #define ENA_RX_COUNT 16
-
- /** Base address low register offset */
- #define ENA_BASE_LO 0x0
-
- /** Base address high register offset */
- #define ENA_BASE_HI 0x4
-
- /** Capability register value */
- #define ENA_CAPS( count, size ) ( ( (size) << 16 ) | ( (count) << 0 ) )
-
- /** Admin queue base address register */
- #define ENA_AQ_BASE 0x10
-
- /** Admin queue capabilities register */
- #define ENA_AQ_CAPS 0x18
-
- /** Admin completion queue base address register */
- #define ENA_ACQ_BASE 0x20
-
- /** Admin completion queue capabilities register */
- #define ENA_ACQ_CAPS 0x28
-
- /** Admin queue doorbell register */
- #define ENA_AQ_DB 0x2c
-
- /** Maximum time to wait for admin requests */
- #define ENA_ADMIN_MAX_WAIT_MS 5000
-
- /** Device control register */
- #define ENA_CTRL 0x54
- #define ENA_CTRL_RESET 0x00000001UL /**< Reset */
-
- /** Maximum time to wait for reset */
- #define ENA_RESET_MAX_WAIT_MS 1000
-
- /** Device status register */
- #define ENA_STAT 0x58
- #define ENA_STAT_READY 0x00000001UL /**< Ready */
-
- /** Admin queue entry header */
- struct ena_aq_header {
- /** Request identifier */
- uint8_t id;
- /** Reserved */
- uint8_t reserved;
- /** Opcode */
- uint8_t opcode;
- /** Flags */
- uint8_t flags;
- } __attribute__ (( packed ));
-
- /** Admin queue ownership phase flag */
- #define ENA_AQ_PHASE 0x01
-
- /** Admin completion queue entry header */
- struct ena_acq_header {
- /** Request identifier */
- uint8_t id;
- /** Reserved */
- uint8_t reserved;
- /** Status */
- uint8_t status;
- /** Flags */
- uint8_t flags;
- /** Extended status */
- uint16_t ext;
- /** Consumer index */
- uint16_t cons;
- } __attribute__ (( packed ));
-
- /** Admin completion queue ownership phase flag */
- #define ENA_ACQ_PHASE 0x01
-
- /** Device attributes */
- #define ENA_DEVICE_ATTRIBUTES 1
-
- /** Device attributes */
- struct ena_device_attributes {
- /** Implementation */
- uint32_t implementation;
- /** Device version */
- uint32_t version;
- /** Supported features */
- uint32_t features;
- /** Reserved */
- uint8_t reserved_a[4];
- /** Physical address width */
- uint32_t physical;
- /** Virtual address width */
- uint32_t virtual;
- /** MAC address */
- uint8_t mac[ETH_ALEN];
- /** Reserved */
- uint8_t reserved_b[2];
- /** Maximum MTU */
- uint32_t mtu;
- } __attribute__ (( packed ));
-
- /** Feature */
- union ena_feature {
- /** Device attributes */
- struct ena_device_attributes device;
- };
-
- /** Submission queue direction */
- enum ena_sq_direction {
- /** Transmit */
- ENA_SQ_TX = 0x20,
- /** Receive */
- ENA_SQ_RX = 0x40,
- };
-
- /** Create submission queue */
- #define ENA_CREATE_SQ 1
-
- /** Create submission queue request */
- struct ena_create_sq_req {
- /** Header */
- struct ena_aq_header header;
- /** Direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved_a;
- /** Policy */
- uint16_t policy;
- /** Completion queue identifier */
- uint16_t cq_id;
- /** Number of entries */
- uint16_t count;
- /** Base address */
- uint64_t address;
- /** Writeback address */
- uint64_t writeback;
- /** Reserved */
- uint8_t reserved_b[8];
- } __attribute__ (( packed ));
-
- /** Submission queue policy */
- enum ena_sq_policy {
- /** Use host memory */
- ENA_SQ_HOST_MEMORY = 0x0001,
- /** Memory is contiguous */
- ENA_SQ_CONTIGUOUS = 0x0100,
- };
-
- /** Create submission queue response */
- struct ena_create_sq_rsp {
- /** Header */
- struct ena_acq_header header;
- /** Submission queue identifier */
- uint16_t id;
- /** Reserved */
- uint8_t reserved[2];
- /** Doorbell register offset */
- uint32_t doorbell;
- /** LLQ descriptor ring offset */
- uint32_t llq_desc;
- /** LLQ header offset */
- uint32_t llq_data;
- } __attribute__ (( packed ));
-
- /** Destroy submission queue */
- #define ENA_DESTROY_SQ 2
-
- /** Destroy submission queue request */
- struct ena_destroy_sq_req {
- /** Header */
- struct ena_aq_header header;
- /** Submission queue identifier */
- uint16_t id;
- /** Direction */
- uint8_t direction;
- /** Reserved */
- uint8_t reserved;
- } __attribute__ (( packed ));
-
- /** Destroy submission queue response */
- struct ena_destroy_sq_rsp {
- /** Header */
- struct ena_acq_header header;
- } __attribute__ (( packed ));
-
- /** Create completion queue */
- #define ENA_CREATE_CQ 3
-
- /** Create completion queue request */
- struct ena_create_cq_req {
- /** Header */
- struct ena_aq_header header;
- /** Interrupts enabled */
- uint8_t intr;
- /** Entry size (in 32-bit words) */
- uint8_t size;
- /** Number of entries */
- uint16_t count;
- /** MSI-X vector */
- uint32_t vector;
- /** Base address */
- uint64_t address;
- } __attribute__ (( packed ));
-
- /** Create completion queue response */
- struct ena_create_cq_rsp {
- /** Header */
- struct ena_acq_header header;
- /** Completion queue identifier */
- uint16_t id;
- /** Actual number of entries */
- uint16_t count;
- /** NUMA node register offset */
- uint32_t node;
- /** Doorbell register offset */
- uint32_t doorbell;
- /** Interrupt unmask register offset */
- uint32_t intr;
- } __attribute__ (( packed ));
-
- /** Destroy completion queue */
- #define ENA_DESTROY_CQ 4
-
- /** Destroy completion queue request */
- struct ena_destroy_cq_req {
- /** Header */
- struct ena_aq_header header;
- /** Completion queue identifier */
- uint16_t id;
- /** Reserved */
- uint8_t reserved[2];
- } __attribute__ (( packed ));
-
- /** Destroy completion queue response */
- struct ena_destroy_cq_rsp {
- /** Header */
- struct ena_acq_header header;
- } __attribute__ (( packed ));
-
- /** Get feature */
- #define ENA_GET_FEATURE 8
-
- /** Get feature request */
- struct ena_get_feature_req {
- /** Header */
- struct ena_aq_header header;
- /** Length */
- uint32_t len;
- /** Address */
- uint64_t address;
- /** Flags */
- uint8_t flags;
- /** Feature identifier */
- uint8_t id;
- /** Reserved */
- uint8_t reserved[2];
- } __attribute__ (( packed ));
-
- /** Get feature response */
- struct ena_get_feature_rsp {
- /** Header */
- struct ena_acq_header header;
- /** Feature */
- union ena_feature feature;
- } __attribute__ (( packed ));
-
- /** Get statistics */
- #define ENA_GET_STATS 11
-
- /** Get statistics request */
- struct ena_get_stats_req {
- /** Header */
- struct ena_aq_header header;
- /** Reserved */
- uint8_t reserved_a[12];
- /** Type */
- uint8_t type;
- /** Scope */
- uint8_t scope;
- /** Reserved */
- uint8_t reserved_b[2];
- /** Queue ID */
- uint16_t queue;
- /** Device ID */
- uint16_t device;
- } __attribute__ (( packed ));
-
- /** Basic statistics */
- #define ENA_STATS_TYPE_BASIC 0
-
- /** Ethernet statistics */
- #define ENA_STATS_SCOPE_ETH 1
-
- /** My device */
- #define ENA_DEVICE_MINE 0xffff
-
- /** Get statistics response */
- struct ena_get_stats_rsp {
- /** Header */
- struct ena_acq_header header;
- /** Transmit byte count */
- uint64_t tx_bytes;
- /** Transmit packet count */
- uint64_t tx_packets;
- /** Receive byte count */
- uint64_t rx_bytes;
- /** Receive packet count */
- uint64_t rx_packets;
- /** Receive drop count */
- uint64_t rx_drops;
- } __attribute__ (( packed ));
-
- /** Admin queue request */
- union ena_aq_req {
- /** Header */
- struct ena_aq_header header;
- /** Create submission queue */
- struct ena_create_sq_req create_sq;
- /** Destroy submission queue */
- struct ena_destroy_sq_req destroy_sq;
- /** Create completion queue */
- struct ena_create_cq_req create_cq;
- /** Destroy completion queue */
- struct ena_destroy_cq_req destroy_cq;
- /** Get feature */
- struct ena_get_feature_req get_feature;
- /** Get statistics */
- struct ena_get_stats_req get_stats;
- /** Padding */
- uint8_t pad[64];
- };
-
- /** Admin completion queue response */
- union ena_acq_rsp {
- /** Header */
- struct ena_acq_header header;
- /** Create submission queue */
- struct ena_create_sq_rsp create_sq;
- /** Destroy submission queue */
- struct ena_destroy_sq_rsp destroy_sq;
- /** Create completion queue */
- struct ena_create_cq_rsp create_cq;
- /** Destroy completion queue */
- struct ena_destroy_cq_rsp destroy_cq;
- /** Get feature */
- struct ena_get_feature_rsp get_feature;
- /** Get statistics */
- struct ena_get_stats_rsp get_stats;
- /** Padding */
- uint8_t pad[64];
- };
-
- /** Admin queue */
- struct ena_aq {
- /** Requests */
- union ena_aq_req *req;
- /** Producer counter */
- unsigned int prod;
- };
-
- /** Admin completion queue */
- struct ena_acq {
- /** Responses */
- union ena_acq_rsp *rsp;
- /** Consumer counter */
- unsigned int cons;
- /** Phase */
- unsigned int phase;
- };
-
- /** Transmit submission queue entry */
- struct ena_tx_sqe {
- /** Length */
- uint16_t len;
- /** Reserved */
- uint8_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Reserved */
- uint8_t reserved_b[3];
- /** Request identifier */
- uint8_t id;
- /** Address */
- uint64_t address;
- } __attribute__ (( packed ));
-
- /** Receive submission queue entry */
- struct ena_rx_sqe {
- /** Length */
- uint16_t len;
- /** Reserved */
- uint8_t reserved_a;
- /** Flags */
- uint8_t flags;
- /** Request identifier */
- uint16_t id;
- /** Reserved */
- uint8_t reserved_b[2];
- /** Address */
- uint64_t address;
- } __attribute__ (( packed ));
-
- /** Submission queue ownership phase flag */
- #define ENA_SQE_PHASE 0x01
-
- /** This is the first descriptor */
- #define ENA_SQE_FIRST 0x04
-
- /** This is the last descriptor */
- #define ENA_SQE_LAST 0x08
-
- /** Request completion */
- #define ENA_SQE_CPL 0x10
-
- /** Transmit completion queue entry */
- struct ena_tx_cqe {
- /** Request identifier */
- uint16_t id;
- /** Status */
- uint8_t status;
- /** Flags */
- uint8_t flags;
- /** Reserved */
- uint8_t reserved[2];
- /** Consumer index */
- uint16_t cons;
- } __attribute__ (( packed ));
-
- /** Receive completion queue entry */
- struct ena_rx_cqe {
- /** Reserved */
- uint8_t reserved_a[3];
- /** Flags */
- uint8_t flags;
- /** Length */
- uint16_t len;
- /** Request identifier */
- uint16_t id;
- /** Reserved */
- uint8_t reserved_b[8];
- } __attribute__ (( packed ));
-
- /** Completion queue ownership phase flag */
- #define ENA_CQE_PHASE 0x01
-
- /** Submission queue */
- struct ena_sq {
- /** Entries */
- union {
- /** Transmit submission queue entries */
- struct ena_tx_sqe *tx;
- /** Receive submission queue entries */
- struct ena_rx_sqe *rx;
- /** Raw data */
- void *raw;
- } sqe;
- /** Doorbell register offset */
- unsigned int doorbell;
- /** Total length of entries */
- size_t len;
- /** Producer counter */
- unsigned int prod;
- /** Phase */
- unsigned int phase;
- /** Submission queue identifier */
- uint16_t id;
- /** Direction */
- uint8_t direction;
- /** Number of entries */
- uint8_t count;
- };
-
- /**
- * Initialise submission queue
- *
- * @v sq Submission queue
- * @v direction Direction
- * @v count Number of entries
- * @v size Size of each entry
- */
- static inline __attribute__ (( always_inline )) void
- ena_sq_init ( struct ena_sq *sq, unsigned int direction, unsigned int count,
- size_t size ) {
-
- sq->len = ( count * size );
- sq->direction = direction;
- sq->count = count;
- }
-
- /** Completion queue */
- struct ena_cq {
- /** Entries */
- union {
- /** Transmit completion queue entries */
- struct ena_tx_cqe *tx;
- /** Receive completion queue entries */
- struct ena_rx_cqe *rx;
- /** Raw data */
- void *raw;
- } cqe;
- /** Doorbell register offset */
- unsigned int doorbell;
- /** Total length of entries */
- size_t len;
- /** Consumer counter */
- unsigned int cons;
- /** Phase */
- unsigned int phase;
- /** Completion queue identifier */
- uint16_t id;
- /** Entry size (in 32-bit words) */
- uint8_t size;
- /** Requested number of entries */
- uint8_t requested;
- /** Actual number of entries */
- uint8_t actual;
- /** Actual number of entries minus one */
- uint8_t mask;
- };
-
- /**
- * Initialise completion queue
- *
- * @v cq Completion queue
- * @v count Number of entries
- * @v size Size of each entry
- */
- static inline __attribute__ (( always_inline )) void
- ena_cq_init ( struct ena_cq *cq, unsigned int count, size_t size ) {
-
- cq->len = ( count * size );
- cq->size = ( size / sizeof ( uint32_t ) );
- cq->requested = count;
- }
-
- /** Queue pair */
- struct ena_qp {
- /** Submission queue */
- struct ena_sq sq;
- /** Completion queue */
- struct ena_cq cq;
- };
-
- /** An ENA network card */
- struct ena_nic {
- /** Registers */
- void *regs;
- /** Admin queue */
- struct ena_aq aq;
- /** Admin completion queue */
- struct ena_acq acq;
- /** Transmit queue */
- struct ena_qp tx;
- /** Receive queue */
- struct ena_qp rx;
- /** Receive I/O buffers */
- struct io_buffer *rx_iobuf[ENA_RX_COUNT];
- };
-
- #endif /* _ENA_H */
|