diff options
author | Michael Brown <mcb30@ipxe.org> | 2022-08-26 15:48:52 +0100 |
---|---|---|
committer | Michael Brown <mcb30@ipxe.org> | 2022-08-26 19:38:25 +0100 |
commit | 6d2cead461db7243330f3275ff9ea7ff4607c4f8 (patch) | |
tree | 5a882d2a5bbd6728f98a117b8ad007d02949a7b8 /src/drivers/net/ena.h | |
parent | 856ffe000e79a1af24ea11301447dd70b8d54ac2 (diff) | |
download | ipxe-6d2cead461db7243330f3275ff9ea7ff4607c4f8.tar.gz |
[ena] Allow for out-of-order completions
The ENA data path design has separate submission and completion
queues. Submission queues must be refilled in strict order (since
there is only a single linear tail pointer used to communicate the
existence of new entries to the hardware), and completion queue
entries include a request identifier copied verbatim from the
submission queue entry. Once the submission queue doorbell has been
rung, software never again reads from the submission queue entry and
nothing ever needs to write back to the submission queue entry since
completions are reported via the separate completion queue.
This design allows the hardware to complete submission queue entries
out of order, provided that it internally caches at least as many
entries as it leaves gaps.
Record and identify I/O buffers by request identifier (using a
circular ring buffer of unique request identifiers), and remove the
assumption that submission queue entries will be completed in order.
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/drivers/net/ena.h')
-rw-r--r-- | src/drivers/net/ena.h | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/src/drivers/net/ena.h b/src/drivers/net/ena.h index 2832b67e5..c76598730 100644 --- a/src/drivers/net/ena.h +++ b/src/drivers/net/ena.h @@ -454,6 +454,9 @@ struct ena_tx_cqe { uint16_t cons; } __attribute__ (( packed )); +/** Transmit completion request identifier */ +#define ENA_TX_CQE_ID(id) ( (id) >> 2 ) + /** Receive completion queue entry */ struct ena_rx_cqe { /** Reserved */ @@ -482,6 +485,8 @@ struct ena_sq { /** Raw data */ void *raw; } sqe; + /** Buffer IDs */ + uint8_t *ids; /** Doorbell register offset */ unsigned int doorbell; /** Total length of entries */ @@ -507,14 +512,16 @@ struct ena_sq { * @v direction Direction * @v count Number of entries * @v size Size of each entry + * @v ids Buffer IDs */ static inline __attribute__ (( always_inline )) void ena_sq_init ( struct ena_sq *sq, unsigned int direction, unsigned int count, - size_t size ) { + size_t size, uint8_t *ids ) { sq->len = ( count * size ); sq->direction = direction; sq->count = count; + sq->ids = ids; } /** Completion queue */ @@ -583,7 +590,13 @@ struct ena_nic { struct ena_qp tx; /** Receive queue */ struct ena_qp rx; - /** Receive I/O buffers */ + /** Transmit buffer IDs */ + uint8_t tx_ids[ENA_TX_COUNT]; + /** Transmit I/O buffers, indexed by buffer ID */ + struct io_buffer *tx_iobuf[ENA_TX_COUNT]; + /** Receive buffer IDs */ + uint8_t rx_ids[ENA_RX_COUNT]; + /** Receive I/O buffers, indexed by buffer ID */ struct io_buffer *rx_iobuf[ENA_RX_COUNT]; }; |