aboutsummaryrefslogtreecommitdiffstats
path: root/src/drivers/net/ena.h
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2022-08-26 15:48:52 +0100
committerMichael Brown <mcb30@ipxe.org>2022-08-26 19:38:25 +0100
commit6d2cead461db7243330f3275ff9ea7ff4607c4f8 (patch)
tree5a882d2a5bbd6728f98a117b8ad007d02949a7b8 /src/drivers/net/ena.h
parent856ffe000e79a1af24ea11301447dd70b8d54ac2 (diff)
downloadipxe-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.h17
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];
};