* [PATCH for-next v2 0/3] RDMA/efa: Add support for 128B admin v2 SQ entry
@ 2026-07-31 7:50 Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 1/3] RDMA/efa: Decouple admin command payload from admin header Yonatan Nachum
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Yonatan Nachum @ 2026-07-31 7:50 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: mrgolin, sleybo, matua, gal.pressman, Yonatan Nachum
Changelog:
v2:
* Rebase on for-next branch instead of wip/leon-for-next.
v1: https://lore.kernel.org/all/20260726123854.638687-1-ynachum@amazon.com/
-------------------------------------------------------------------------
Add support for the new 128-byte admin v2 SQ entry format. The v2 entry
extends the v1 header with checksum and payload version fields, and
carries a larger inline payload.
The series first decouples admin command payloads from admin headers,
then generalizes the SQ ring to use a configurable entry size, and
finally adds the v2 entry format selection based on device API version.
Yonatan Nachum (3):
RDMA/efa: Decouple admin command payload from admin header
RDMA/efa: Generalize the admin SQ
RDMA/efa: Add support for 128B admin v2 SQ entry
.../infiniband/hw/efa/efa_admin_cmds_defs.h | 116 +++--------
drivers/infiniband/hw/efa/efa_admin_defs.h | 33 ++-
drivers/infiniband/hw/efa/efa_com.c | 194 +++++++++++-------
drivers/infiniband/hw/efa/efa_com.h | 16 +-
drivers/infiniband/hw/efa/efa_com_cmd.c | 170 +++++----------
5 files changed, 240 insertions(+), 289 deletions(-)
--
2.50.1
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH for-next v2 1/3] RDMA/efa: Decouple admin command payload from admin header
2026-07-31 7:50 [PATCH for-next v2 0/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
@ 2026-07-31 7:50 ` Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 2/3] RDMA/efa: Generalize the admin SQ Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 3/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
2 siblings, 0 replies; 4+ messages in thread
From: Yonatan Nachum @ 2026-07-31 7:50 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: mrgolin, sleybo, matua, gal.pressman, Yonatan Nachum,
Daniel Kranzdorf
Remove aq_common_desc from all EFA admin command descriptors so that
command structs represent pure payloads. This allows attaching different
headers to the same command by copying the payload into the generic
header payload field. The admin header is now constructed in a single
place which improves separability.
Reviewed-by: Daniel Kranzdorf <dkkranzd@amazon.com>
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
---
.../infiniband/hw/efa/efa_admin_cmds_defs.h | 116 +++---------
drivers/infiniband/hw/efa/efa_admin_defs.h | 8 +-
drivers/infiniband/hw/efa/efa_com.c | 53 +++---
drivers/infiniband/hw/efa/efa_com.h | 7 +-
drivers/infiniband/hw/efa/efa_com_cmd.c | 170 ++++++------------
5 files changed, 112 insertions(+), 242 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
index 95d1493153cd..ab830764e3b4 100644
--- a/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
+++ b/drivers/infiniband/hw/efa/efa_admin_cmds_defs.h
@@ -102,9 +102,6 @@ struct efa_admin_qp_alloc_size {
};
struct efa_admin_create_qp_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* Protection Domain associated with this QP */
u16 pd;
@@ -167,7 +164,7 @@ struct efa_admin_create_qp_cmd {
/* MBZ */
u32 reserved2;
-};
+} __packed;
struct efa_admin_create_qp_resp {
/* Common Admin Queue completion descriptor */
@@ -208,9 +205,6 @@ struct efa_admin_create_qp_resp {
};
struct efa_admin_modify_qp_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/*
* Mask indicating which fields should be updated
* 0 : qp_state
@@ -246,7 +240,7 @@ struct efa_admin_modify_qp_cmd {
/* MBZ */
u16 reserved2;
-};
+} __packed;
struct efa_admin_modify_qp_resp {
/* Common Admin Queue completion descriptor */
@@ -254,12 +248,9 @@ struct efa_admin_modify_qp_resp {
};
struct efa_admin_query_qp_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* QP handle returned by create_qp command */
u32 qp_handle;
-};
+} __packed;
struct efa_admin_query_qp_resp {
/* Common Admin Queue completion descriptor */
@@ -285,12 +276,9 @@ struct efa_admin_query_qp_resp {
};
struct efa_admin_destroy_qp_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* QP handle returned by create_qp command */
u32 qp_handle;
-};
+} __packed;
struct efa_admin_destroy_qp_resp {
/* Common Admin Queue completion descriptor */
@@ -302,9 +290,6 @@ struct efa_admin_destroy_qp_resp {
* once for the same destination
*/
struct efa_admin_create_ah_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* Destination address in network byte order */
u8 dest_addr[16];
@@ -313,7 +298,7 @@ struct efa_admin_create_ah_cmd {
/* MBZ */
u16 reserved;
-};
+} __packed;
struct efa_admin_create_ah_resp {
/* Common Admin Queue completion descriptor */
@@ -327,15 +312,12 @@ struct efa_admin_create_ah_resp {
};
struct efa_admin_destroy_ah_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* Target interface address handle (opaque) */
u16 ah;
/* PD number */
u16 pd;
-};
+} __packed;
struct efa_admin_destroy_ah_resp {
/* Common Admin Queue completion descriptor */
@@ -349,9 +331,6 @@ struct efa_admin_destroy_ah_resp {
* on users working with very large datasets (i.e. full GPU memory mapping).
*/
struct efa_admin_reg_mr_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* Protection Domain */
u16 pd;
@@ -413,7 +392,7 @@ struct efa_admin_reg_mr_cmd {
* the region.
*/
u64 iova;
-};
+} __packed;
struct efa_admin_reg_mr_resp {
/* Common Admin Queue completion descriptor */
@@ -459,12 +438,9 @@ struct efa_admin_reg_mr_resp {
};
struct efa_admin_dereg_mr_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* L_Key, memory region's l_key */
u32 l_key;
-};
+} __packed;
struct efa_admin_dereg_mr_resp {
/* Common Admin Queue completion descriptor */
@@ -476,9 +452,6 @@ struct efa_admin_dereg_mr_resp {
* Addresses in kernel verbs semantics, ready for fast registration use.
*/
struct efa_admin_alloc_mr_cmd {
- /* Common Admin Queue descriptor */
- struct efa_admin_aq_common_desc aq_common_desc;
-
/* Protection Domain */
u16 pd;
@@ -487,7 +460,7 @@ struct efa_admin_alloc_mr_cmd {
/* Maximum number of pages this MR supports. */
u32 max_pages;
-};
+} __packed;
struct efa_admin_alloc_mr_resp {
/* Common Admin Queue completion descriptor */
@@ -507,8 +480,6 @@ struct efa_admin_alloc_mr_resp {
};
struct efa_admin_create_cq_cmd {
- struct efa_admin_aq_common_desc aq_common_desc;
-
/*
* 4:0 : reserved5 - MBZ
* 5 : interrupt_mode_enabled - if set, cq operates
@@ -561,7 +532,7 @@ struct efa_admin_create_cq_cmd {
/* UAR number */
u16 uar;
-};
+} __packed;
struct efa_admin_create_cq_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -582,13 +553,11 @@ struct efa_admin_create_cq_resp {
};
struct efa_admin_destroy_cq_cmd {
- struct efa_admin_aq_common_desc aq_common_desc;
-
u16 cq_idx;
/* MBZ */
u16 reserved1;
-};
+} __packed;
struct efa_admin_destroy_cq_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -599,14 +568,7 @@ struct efa_admin_destroy_cq_resp {
* buffer pointed by AQ entry
*/
struct efa_admin_aq_get_stats_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
- union {
- /* command specific inline data */
- u32 inline_data_w1[3];
-
- struct efa_admin_ctrl_buff_info control_buffer;
- } u;
+ struct efa_admin_ctrl_buff_info control_buffer;
/* stats type as defined in enum efa_admin_get_stats_type */
u8 type;
@@ -615,7 +577,7 @@ struct efa_admin_aq_get_stats_cmd {
u8 scope;
u16 scope_modifier;
-};
+} __packed;
struct efa_admin_basic_stats {
u64 tx_bytes;
@@ -903,14 +865,12 @@ struct efa_admin_hw_hints {
};
struct efa_admin_get_feature_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
struct efa_admin_ctrl_buff_info control_buffer;
struct efa_admin_get_set_feature_common_desc feature_common;
u32 raw[11];
-};
+} __packed;
struct efa_admin_get_feature_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -935,8 +895,6 @@ struct efa_admin_get_feature_resp {
};
struct efa_admin_set_feature_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
struct efa_admin_ctrl_buff_info control_buffer;
struct efa_admin_get_set_feature_common_desc feature_common;
@@ -947,7 +905,7 @@ struct efa_admin_set_feature_cmd {
/* AENQ configuration */
struct efa_admin_feature_aenq_desc aenq;
} u;
-};
+} __packed;
struct efa_admin_set_feature_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -957,10 +915,6 @@ struct efa_admin_set_feature_resp {
} u;
};
-struct efa_admin_alloc_pd_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-};
-
struct efa_admin_alloc_pd_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -972,23 +926,17 @@ struct efa_admin_alloc_pd_resp {
};
struct efa_admin_dealloc_pd_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* PD number */
u16 pd;
/* MBZ */
u16 reserved;
-};
+} __packed;
struct efa_admin_dealloc_pd_resp {
struct efa_admin_acq_common_desc acq_common_desc;
};
-struct efa_admin_alloc_uar_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-};
-
struct efa_admin_alloc_uar_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1000,22 +948,18 @@ struct efa_admin_alloc_uar_resp {
};
struct efa_admin_dealloc_uar_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* UAR number */
u16 uar;
/* MBZ */
u16 reserved;
-};
+} __packed;
struct efa_admin_dealloc_uar_resp {
struct efa_admin_acq_common_desc acq_common_desc;
};
struct efa_admin_create_eq_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* Size of the EQ in entries, must be power of 2 */
u16 depth;
@@ -1041,7 +985,7 @@ struct efa_admin_create_eq_cmd {
/* MBZ */
u32 reserved;
-};
+} __packed;
struct efa_admin_create_eq_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1054,14 +998,12 @@ struct efa_admin_create_eq_resp {
};
struct efa_admin_destroy_eq_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* EQ number */
u16 eqn;
/* MBZ */
u16 reserved;
-};
+} __packed;
struct efa_admin_destroy_eq_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1134,10 +1076,8 @@ struct efa_admin_host_info {
};
struct efa_admin_service_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
u8 buffer[60];
-};
+} __packed;
struct efa_admin_service_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1147,8 +1087,6 @@ struct efa_admin_service_resp {
/* Create Counter command */
struct efa_admin_create_event_counter_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* UAR number */
u16 uar;
@@ -1157,7 +1095,7 @@ struct efa_admin_create_event_counter_cmd {
/* Counter physical address */
u64 paddr;
-};
+} __packed;
struct efa_admin_create_event_counter_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1170,11 +1108,9 @@ struct efa_admin_create_event_counter_resp {
};
struct efa_admin_destroy_event_counter_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* Counter handle */
u32 cntr_handle;
-};
+} __packed;
struct efa_admin_destroy_event_counter_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1206,8 +1142,6 @@ struct efa_admin_event_counter_attach_qp_events {
};
struct efa_admin_attach_detach_event_counter_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* Counter handle */
u32 cntr_handle;
@@ -1220,7 +1154,7 @@ struct efa_admin_attach_detach_event_counter_cmd {
union {
struct efa_admin_event_counter_attach_qp_events qp_events;
} u;
-};
+} __packed;
struct efa_admin_attach_detach_event_counter_resp {
struct efa_admin_acq_common_desc acq_common_desc;
@@ -1235,8 +1169,6 @@ enum efa_admin_event_counter_modify_ops {
};
struct efa_admin_modify_event_counter_cmd {
- struct efa_admin_aq_common_desc aq_common_descriptor;
-
/* Counter handle */
u32 cntr_handle;
@@ -1248,7 +1180,7 @@ struct efa_admin_modify_event_counter_cmd {
/* Value for SET or ADD */
u64 value;
-};
+} __packed;
struct efa_admin_modify_event_counter_resp {
struct efa_admin_acq_common_desc acq_common_desc;
diff --git a/drivers/infiniband/hw/efa/efa_admin_defs.h b/drivers/infiniband/hw/efa/efa_admin_defs.h
index 02f86edabed8..0a14b3abe6f9 100644
--- a/drivers/infiniband/hw/efa/efa_admin_defs.h
+++ b/drivers/infiniband/hw/efa/efa_admin_defs.h
@@ -55,13 +55,7 @@ struct efa_admin_ctrl_buff_info {
struct efa_admin_aq_entry {
struct efa_admin_aq_common_desc aq_common_descriptor;
- union {
- u32 inline_data_w1[3];
-
- struct efa_admin_ctrl_buff_info control_buffer;
- } u;
-
- u32 inline_data_w4[12];
+ u32 request_payload[15];
};
struct efa_admin_acq_common_desc {
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index 7097d1c2f23d..8d8be22b76c8 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -634,8 +634,10 @@ static int efa_com_wait_and_process_admin_cq(struct efa_comp_ctx *comp_ctx,
/**
* efa_com_cmd_exec - Execute admin command
* @aq: admin queue.
- * @cmd: the admin command to execute.
- * @cmd_size: the command size.
+ * @opcode: the admin command opcode.
+ * @flags: the admin command header flags.
+ * @payload: the admin command payload.
+ * @payload_size: the payload size.
* @comp: command completion return entry.
* @comp_size: command completion size.
* Submit an admin command and then wait until the device will return a
@@ -645,22 +647,24 @@ static int efa_com_wait_and_process_admin_cq(struct efa_comp_ctx *comp_ctx,
* @return - 0 on success, negative value on failure.
*/
int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
- struct efa_admin_aq_entry *cmd,
- size_t cmd_size,
- struct efa_admin_acq_entry *comp,
- size_t comp_size)
+ u8 opcode, u8 flags,
+ void *payload, size_t payload_size,
+ struct efa_admin_acq_entry *comp, size_t comp_size)
{
+ struct efa_admin_aq_entry aq_entry = {};
struct efa_comp_ctx *comp_ctx;
int err;
+ if (payload_size > sizeof(aq_entry.request_payload))
+ return -EINVAL;
+
might_sleep();
/* In case of queue FULL */
down(&aq->avail_cmds);
- ibdev_dbg(aq->efa_dev, "%s (opcode %d)\n",
- efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
- cmd->aq_common_descriptor.opcode);
+ ibdev_dbg(aq->efa_dev, "%s (opcode %d)\n", efa_com_cmd_str(opcode),
+ opcode);
comp_ctx = efa_com_alloc_comp_ctx(aq);
if (!comp_ctx) {
@@ -669,13 +673,17 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
return -EINVAL;
}
- err = efa_com_submit_admin_cmd(aq, comp_ctx, cmd, cmd_size, comp, comp_size);
+ aq_entry.aq_common_descriptor.opcode = opcode;
+ aq_entry.aq_common_descriptor.flags = flags;
+ if (payload)
+ memcpy(aq_entry.request_payload, payload, payload_size);
+
+ err = efa_com_submit_admin_cmd(aq, comp_ctx, &aq_entry, sizeof(aq_entry), comp, comp_size);
if (err) {
ibdev_err_ratelimited(
aq->efa_dev,
"Failed to submit command %s (opcode %u) err %d\n",
- efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
- cmd->aq_common_descriptor.opcode, err);
+ efa_com_cmd_str(opcode), opcode, err);
efa_com_dealloc_comp_ctx(aq, comp_ctx);
up(&aq->avail_cmds);
@@ -688,8 +696,7 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
ibdev_err_ratelimited(
aq->efa_dev,
"Failed to process command %s (opcode %u) err %d\n",
- efa_com_cmd_str(cmd->aq_common_descriptor.opcode),
- cmd->aq_common_descriptor.opcode, err);
+ efa_com_cmd_str(opcode), opcode, err);
atomic64_inc(&aq->stats.cmd_err);
}
@@ -1156,7 +1163,6 @@ static int efa_com_create_eq(struct efa_com_dev *edev,
struct efa_admin_create_eq_cmd cmd = {};
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_CREATE_EQ;
EFA_SET(&cmd.caps, EFA_ADMIN_CREATE_EQ_CMD_ENTRY_SIZE_WORDS,
params->entry_size_in_bytes / 4);
cmd.depth = params->depth;
@@ -1166,11 +1172,9 @@ static int efa_com_create_eq(struct efa_com_dev *edev,
efa_com_set_dma_addr(params->dma_addr, &cmd.ba.mem_addr_high,
&cmd.ba.mem_addr_low);
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_EQ, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to create eq[%d]\n", err);
@@ -1190,14 +1194,11 @@ static void efa_com_destroy_eq(struct efa_com_dev *edev,
struct efa_admin_destroy_eq_cmd cmd = {};
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_DESTROY_EQ;
cmd.eqn = params->eqn;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_EQ, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err)
ibdev_err_ratelimited(edev->efa_dev,
"Failed to destroy EQ-%u [%d]\n", cmd.eqn,
diff --git a/drivers/infiniband/hw/efa/efa_com.h b/drivers/infiniband/hw/efa/efa_com.h
index 599db9d583bf..f979e36ec158 100644
--- a/drivers/infiniband/hw/efa/efa_com.h
+++ b/drivers/infiniband/hw/efa/efa_com.h
@@ -174,10 +174,9 @@ int efa_com_validate_version(struct efa_com_dev *edev);
int efa_com_get_dma_width(struct efa_com_dev *edev);
int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
- struct efa_admin_aq_entry *cmd,
- size_t cmd_size,
- struct efa_admin_acq_entry *comp,
- size_t comp_size);
+ u8 opcode, u8 flags,
+ void *payload, size_t payload_size,
+ struct efa_admin_acq_entry *comp, size_t comp_size);
void efa_com_aenq_intr_handler(struct efa_com_dev *edev, void *data);
void efa_com_eq_comp_intr_handler(struct efa_com_dev *edev,
struct efa_com_eq *eeq);
diff --git a/drivers/infiniband/hw/efa/efa_com_cmd.c b/drivers/infiniband/hw/efa/efa_com_cmd.c
index 198a27d02b18..1b00f16b8ea8 100644
--- a/drivers/infiniband/hw/efa/efa_com_cmd.c
+++ b/drivers/infiniband/hw/efa/efa_com_cmd.c
@@ -17,8 +17,6 @@ int efa_com_create_qp(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- create_qp_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_QP;
-
create_qp_cmd.pd = params->pd;
create_qp_cmd.qp_type = params->qp_type;
create_qp_cmd.rq_base_addr = params->rq_base_addr;
@@ -41,9 +39,8 @@ int efa_com_create_qp(struct efa_com_dev *edev,
if (params->sq_64_bit_req_id)
EFA_SET(&create_qp_cmd.flags, EFA_ADMIN_CREATE_QP_CMD_SQ_64_BIT_REQ_ID, 1);
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&create_qp_cmd,
- sizeof(create_qp_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_QP, 0,
+ &create_qp_cmd, sizeof(create_qp_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -71,7 +68,6 @@ int efa_com_modify_qp(struct efa_com_dev *edev,
struct efa_admin_modify_qp_resp resp;
int err;
- cmd.aq_common_desc.opcode = EFA_ADMIN_MODIFY_QP;
cmd.modify_mask = params->modify_mask;
cmd.qp_handle = params->qp_handle;
cmd.qp_state = params->qp_state;
@@ -81,11 +77,9 @@ int efa_com_modify_qp(struct efa_com_dev *edev,
cmd.sq_drained_async_notify = params->sq_drained_async_notify;
cmd.rnr_retry = params->rnr_retry;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_QP, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(
edev->efa_dev,
@@ -106,14 +100,11 @@ int efa_com_query_qp(struct efa_com_dev *edev,
struct efa_admin_query_qp_resp resp;
int err;
- cmd.aq_common_desc.opcode = EFA_ADMIN_QUERY_QP;
cmd.qp_handle = params->qp_handle;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_QUERY_QP, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to query qp-%u [%d]\n",
@@ -138,12 +129,10 @@ int efa_com_destroy_qp(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- qp_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_QP;
qp_cmd.qp_handle = params->qp_handle;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&qp_cmd,
- sizeof(qp_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_QP, 0,
+ &qp_cmd, sizeof(qp_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -165,7 +154,6 @@ int efa_com_create_cq(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- create_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_CQ;
EFA_SET(&create_cmd.cq_caps_2,
EFA_ADMIN_CREATE_CQ_CMD_CQ_ENTRY_SIZE_WORDS,
params->entry_size_in_bytes / 4);
@@ -190,9 +178,8 @@ int efa_com_create_cq(struct efa_com_dev *edev,
&create_cmd.cq_ba.mem_addr_high,
&create_cmd.cq_ba.mem_addr_low);
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&create_cmd,
- sizeof(create_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_CQ, 0,
+ &create_cmd, sizeof(create_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -219,11 +206,9 @@ int efa_com_destroy_cq(struct efa_com_dev *edev,
int err;
destroy_cmd.cq_idx = params->cq_idx;
- destroy_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_CQ;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&destroy_cmd,
- sizeof(destroy_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_CQ, 0,
+ &destroy_cmd, sizeof(destroy_cmd),
(struct efa_admin_acq_entry *)&destroy_resp,
sizeof(destroy_resp));
@@ -244,9 +229,9 @@ int efa_com_register_mr(struct efa_com_dev *edev,
struct efa_admin_reg_mr_resp cmd_completion;
struct efa_com_admin_queue *aq = &edev->aq;
struct efa_admin_reg_mr_cmd mr_cmd = {};
+ u8 flags = 0;
int err;
- mr_cmd.aq_common_desc.opcode = EFA_ADMIN_REG_MR;
mr_cmd.pd = params->pd;
mr_cmd.mr_length = params->mr_length_in_bytes;
EFA_SET(&mr_cmd.flags, EFA_ADMIN_REG_MR_CMD_PHYS_PAGE_SIZE_SHIFT,
@@ -264,16 +249,13 @@ int efa_com_register_mr(struct efa_com_dev *edev,
params->pbl.pbl.address.mem_addr_low;
mr_cmd.pbl.pbl.address.mem_addr_high =
params->pbl.pbl.address.mem_addr_high;
- EFA_SET(&mr_cmd.aq_common_desc.flags,
- EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
+ EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
if (params->indirect)
- EFA_SET(&mr_cmd.aq_common_desc.flags,
- EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
+ EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA_INDIRECT, 1);
}
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&mr_cmd,
- sizeof(mr_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_REG_MR, flags,
+ &mr_cmd, sizeof(mr_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -305,12 +287,10 @@ int efa_com_dereg_mr(struct efa_com_dev *edev,
struct efa_admin_dereg_mr_cmd mr_cmd = {};
int err;
- mr_cmd.aq_common_desc.opcode = EFA_ADMIN_DEREG_MR;
mr_cmd.l_key = params->l_key;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&mr_cmd,
- sizeof(mr_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DEREG_MR, 0,
+ &mr_cmd, sizeof(mr_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -345,14 +325,11 @@ int efa_com_create_ah(struct efa_com_dev *edev,
return 0;
}
- ah_cmd.aq_common_desc.opcode = EFA_ADMIN_CREATE_AH;
-
memcpy(ah_cmd.dest_addr, params->dest_addr, sizeof(ah_cmd.dest_addr));
ah_cmd.pd = params->pdn;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&ah_cmd,
- sizeof(ah_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_AH, 0,
+ &ah_cmd, sizeof(ah_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -389,13 +366,11 @@ int efa_com_destroy_ah(struct efa_com_dev *edev,
if (entry->usecnt > 1)
goto out_put;
- ah_cmd.aq_common_desc.opcode = EFA_ADMIN_DESTROY_AH;
ah_cmd.ah = entry->ah;
ah_cmd.pd = entry->key.pd;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&ah_cmd,
- sizeof(ah_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_AH, 0,
+ &ah_cmd, sizeof(ah_cmd),
(struct efa_admin_acq_entry *)&cmd_completion,
sizeof(cmd_completion));
if (err) {
@@ -436,6 +411,7 @@ static int efa_com_get_feature_ex(struct efa_com_dev *edev,
{
struct efa_admin_get_feature_cmd get_cmd = {};
struct efa_com_admin_queue *aq;
+ u8 flags = 0;
int err;
if (!efa_com_check_supported_feature_id(edev, feature_id)) {
@@ -447,11 +423,8 @@ static int efa_com_get_feature_ex(struct efa_com_dev *edev,
aq = &edev->aq;
- get_cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_FEATURE;
-
if (control_buff_size)
- EFA_SET(&get_cmd.aq_common_descriptor.flags,
- EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
+ EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
efa_com_set_dma_addr(control_buf_dma_addr,
&get_cmd.control_buffer.address.mem_addr_high,
@@ -459,12 +432,9 @@ static int efa_com_get_feature_ex(struct efa_com_dev *edev,
get_cmd.control_buffer.length = control_buff_size;
get_cmd.feature_common.feature_id = feature_id;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)
- &get_cmd,
- sizeof(get_cmd),
- (struct efa_admin_acq_entry *)
- get_resp,
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_FEATURE, flags,
+ &get_cmd, sizeof(get_cmd),
+ (struct efa_admin_acq_entry *)get_resp,
sizeof(*get_resp));
if (err) {
@@ -630,6 +600,7 @@ int efa_com_set_feature_ex(struct efa_com_dev *edev,
u32 control_buff_size)
{
struct efa_com_admin_queue *aq;
+ u8 flags = 0;
int err;
if (!efa_com_check_supported_feature_id(edev, feature_id)) {
@@ -641,11 +612,8 @@ int efa_com_set_feature_ex(struct efa_com_dev *edev,
aq = &edev->aq;
- set_cmd->aq_common_descriptor.opcode = EFA_ADMIN_SET_FEATURE;
if (control_buff_size) {
- set_cmd->aq_common_descriptor.flags = 0;
- EFA_SET(&set_cmd->aq_common_descriptor.flags,
- EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
+ EFA_SET(&flags, EFA_ADMIN_AQ_COMMON_DESC_CTRL_DATA, 1);
efa_com_set_dma_addr(control_buf_dma_addr,
&set_cmd->control_buffer.address.mem_addr_high,
&set_cmd->control_buffer.address.mem_addr_low);
@@ -653,9 +621,8 @@ int efa_com_set_feature_ex(struct efa_com_dev *edev,
set_cmd->control_buffer.length = control_buff_size;
set_cmd->feature_common.feature_id = feature_id;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)set_cmd,
- sizeof(*set_cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_SET_FEATURE, flags,
+ set_cmd, sizeof(*set_cmd),
(struct efa_admin_acq_entry *)set_resp,
sizeof(*set_resp));
@@ -726,17 +693,12 @@ int efa_com_alloc_pd(struct efa_com_dev *edev,
struct efa_com_alloc_pd_result *result)
{
struct efa_com_admin_queue *aq = &edev->aq;
- struct efa_admin_alloc_pd_cmd cmd = {};
struct efa_admin_alloc_pd_resp resp;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_PD;
-
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_PD, 0,
+ NULL, 0,
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to allocate pd[%d]\n", err);
@@ -756,14 +718,11 @@ int efa_com_dealloc_pd(struct efa_com_dev *edev,
struct efa_admin_dealloc_pd_resp resp;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_PD;
cmd.pd = params->pdn;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_PD, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to deallocate pd-%u [%d]\n",
@@ -778,17 +737,12 @@ int efa_com_alloc_uar(struct efa_com_dev *edev,
struct efa_com_alloc_uar_result *result)
{
struct efa_com_admin_queue *aq = &edev->aq;
- struct efa_admin_alloc_uar_cmd cmd = {};
struct efa_admin_alloc_uar_resp resp;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_ALLOC_UAR;
-
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_ALLOC_UAR, 0,
+ NULL, 0,
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to allocate uar[%d]\n", err);
@@ -808,14 +762,11 @@ int efa_com_dealloc_uar(struct efa_com_dev *edev,
struct efa_admin_dealloc_uar_resp resp;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_DEALLOC_UAR;
cmd.uar = params->uarn;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DEALLOC_UAR, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(edev->efa_dev,
"Failed to deallocate uar-%u [%d]\n",
@@ -840,16 +791,13 @@ int efa_com_get_stats(struct efa_com_dev *edev,
struct efa_admin_basic_stats *bs;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_GET_STATS;
cmd.type = params->type;
cmd.scope = params->scope;
cmd.scope_modifier = params->scope_modifier;
- err = efa_com_cmd_exec(aq,
- (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
- (struct efa_admin_acq_entry *)&resp,
- sizeof(resp));
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_GET_STATS, 0,
+ &cmd, sizeof(cmd),
+ (struct efa_admin_acq_entry *)&resp, sizeof(resp));
if (err) {
ibdev_err_ratelimited(
edev->efa_dev,
@@ -910,12 +858,11 @@ int efa_com_create_event_counter(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_CREATE_EVENT_COUNTER;
cmd.uar = params->uarn;
cmd.paddr = params->dma_addr;
- err = efa_com_cmd_exec(aq, (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_CREATE_EVENT_COUNTER, 0,
+ &cmd, sizeof(cmd),
(struct efa_admin_acq_entry *)&resp,
sizeof(resp));
if (err) {
@@ -937,11 +884,10 @@ int efa_com_destroy_event_counter(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_DESTROY_EVENT_COUNTER;
cmd.cntr_handle = params->cntr_handle;
- err = efa_com_cmd_exec(aq, (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_DESTROY_EVENT_COUNTER, 0,
+ &cmd, sizeof(cmd),
(struct efa_admin_acq_entry *)&resp,
sizeof(resp));
if (err) {
@@ -963,14 +909,13 @@ static int efa_com_attach_detach_event_counter(struct efa_com_dev *edev, u8 opco
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- cmd.aq_common_descriptor.opcode = opcode;
cmd.cntr_handle = cntr_handle;
cmd.attach_type = EFA_ADMIN_EVENT_COUNTER_ATTACH_QP_EVENTS;
cmd.u.qp_events.qp_handle = qp_handle;
cmd.u.qp_events.events = events;
- err = efa_com_cmd_exec(aq, (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
+ err = efa_com_cmd_exec(aq, opcode, 0,
+ &cmd, sizeof(cmd),
(struct efa_admin_acq_entry *)&resp,
sizeof(resp));
if (err) {
@@ -1014,13 +959,12 @@ int efa_com_modify_event_counter(struct efa_com_dev *edev,
struct efa_com_admin_queue *aq = &edev->aq;
int err;
- cmd.aq_common_descriptor.opcode = EFA_ADMIN_MODIFY_EVENT_COUNTER;
cmd.cntr_handle = params->cntr_handle;
cmd.operation = params->operation;
cmd.value = params->value;
- err = efa_com_cmd_exec(aq, (struct efa_admin_aq_entry *)&cmd,
- sizeof(cmd),
+ err = efa_com_cmd_exec(aq, EFA_ADMIN_MODIFY_EVENT_COUNTER, 0,
+ &cmd, sizeof(cmd),
(struct efa_admin_acq_entry *)&resp,
sizeof(resp));
if (err) {
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH for-next v2 2/3] RDMA/efa: Generalize the admin SQ
2026-07-31 7:50 [PATCH for-next v2 0/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 1/3] RDMA/efa: Decouple admin command payload from admin header Yonatan Nachum
@ 2026-07-31 7:50 ` Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 3/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
2 siblings, 0 replies; 4+ messages in thread
From: Yonatan Nachum @ 2026-07-31 7:50 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: mrgolin, sleybo, matua, gal.pressman, Yonatan Nachum
As preparation for admin v2 entry size which is 128B, generalize the SQ
ring to use a generic buffer and use the right offset into it using the
configured entry size. This will allow us to choose different entry size
on SQ init with minimal changes.
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
---
drivers/infiniband/hw/efa/efa_com.c | 48 +++++++++++++----------------
drivers/infiniband/hw/efa/efa_com.h | 3 +-
2 files changed, 24 insertions(+), 27 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index 8d8be22b76c8..72b87f8cd086 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -138,14 +138,13 @@ static int efa_com_admin_init_sq(struct efa_com_dev *edev)
{
struct efa_com_admin_queue *aq = &edev->aq;
struct efa_com_admin_sq *sq = &aq->sq;
- u16 size = aq->depth * sizeof(*sq->entries);
+ u32 addr_high, addr_low;
u32 aq_caps = 0;
- u32 addr_high;
- u32 addr_low;
- sq->entries =
- dma_alloc_coherent(aq->dmadev, size, &sq->dma_addr, GFP_KERNEL);
- if (!sq->entries)
+ sq->entry_size = sizeof(struct efa_admin_aq_entry);
+ sq->buffer = dma_alloc_coherent(aq->dmadev, aq->depth * sq->entry_size,
+ &sq->dma_addr, GFP_KERNEL);
+ if (!sq->buffer)
return -ENOMEM;
spin_lock_init(&sq->lock);
@@ -163,8 +162,7 @@ static int efa_com_admin_init_sq(struct efa_com_dev *edev)
writel(addr_high, edev->reg_bar + EFA_REGS_AQ_BASE_HI_OFF);
EFA_SET(&aq_caps, EFA_REGS_AQ_CAPS_AQ_DEPTH, aq->depth);
- EFA_SET(&aq_caps, EFA_REGS_AQ_CAPS_AQ_ENTRY_SIZE,
- sizeof(struct efa_admin_aq_entry));
+ EFA_SET(&aq_caps, EFA_REGS_AQ_CAPS_AQ_ENTRY_SIZE, sq->entry_size);
writel(aq_caps, edev->reg_bar + EFA_REGS_AQ_CAPS_OFF);
@@ -330,24 +328,22 @@ static void __efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
struct efa_admin_acq_entry *comp,
size_t comp_size_in_bytes)
{
- struct efa_admin_aq_entry *aqe;
- u16 queue_size_mask;
- u16 cmd_id;
- u16 ctx_id;
- u16 pi;
+ u16 queue_size_mask, cmd_id, ctx_id, pi;
+ struct efa_com_admin_sq *sq = &aq->sq;
+ u8 *aqe;
queue_size_mask = aq->depth - 1;
- pi = aq->sq.pc & queue_size_mask;
+ pi = sq->pc & queue_size_mask;
ctx_id = efa_com_get_comp_ctx_id(aq, comp_ctx);
/* cmd_id LSBs are the ctx_id and MSBs are entropy bits from pc */
cmd_id = ctx_id & queue_size_mask;
- cmd_id |= aq->sq.pc << ilog2(aq->depth);
+ cmd_id |= sq->pc << ilog2(aq->depth);
cmd_id &= EFA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK;
cmd->aq_common_descriptor.command_id = cmd_id;
EFA_SET(&cmd->aq_common_descriptor.flags,
- EFA_ADMIN_AQ_COMMON_DESC_PHASE, aq->sq.phase);
+ EFA_ADMIN_AQ_COMMON_DESC_PHASE, sq->phase);
comp_ctx->status = EFA_CMD_SUBMITTED;
comp_ctx->comp_size = comp_size_in_bytes;
@@ -357,18 +353,18 @@ static void __efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
reinit_completion(&comp_ctx->wait_event);
- aqe = &aq->sq.entries[pi];
- memset(aqe, 0, sizeof(*aqe));
+ aqe = sq->buffer + sq->entry_size * pi;
+ memset(aqe, 0, sq->entry_size);
memcpy(aqe, cmd, cmd_size_in_bytes);
- aq->sq.pc++;
+ sq->pc++;
atomic64_inc(&aq->stats.submitted_cmd);
- if ((aq->sq.pc & queue_size_mask) == 0)
- aq->sq.phase = !aq->sq.phase;
+ if ((sq->pc & queue_size_mask) == 0)
+ sq->phase = !sq->phase;
/* barrier not needed in case of writel */
- writel(aq->sq.pc, aq->sq.db_addr);
+ writel(sq->pc, sq->db_addr);
}
static inline int efa_com_init_comp_ctxt(struct efa_com_admin_queue *aq)
@@ -723,8 +719,8 @@ void efa_com_admin_destroy(struct efa_com_dev *edev)
devm_kfree(edev->dmadev, aq->comp_ctx_pool);
devm_kfree(edev->dmadev, aq->comp_ctx);
- size = aq->depth * sizeof(*sq->entries);
- dma_free_coherent(edev->dmadev, size, sq->entries, sq->dma_addr);
+ size = aq->depth * sq->entry_size;
+ dma_free_coherent(edev->dmadev, size, sq->buffer, sq->dma_addr);
size = aq->depth * sizeof(*cq->entries);
dma_free_coherent(edev->dmadev, size, cq->entries, cq->dma_addr);
@@ -843,8 +839,8 @@ int efa_com_admin_init(struct efa_com_dev *edev,
dma_free_coherent(edev->dmadev, aq->depth * sizeof(*aq->cq.entries),
aq->cq.entries, aq->cq.dma_addr);
err_destroy_sq:
- dma_free_coherent(edev->dmadev, aq->depth * sizeof(*aq->sq.entries),
- aq->sq.entries, aq->sq.dma_addr);
+ dma_free_coherent(edev->dmadev, aq->depth * aq->sq.entry_size,
+ aq->sq.buffer, aq->sq.dma_addr);
err_destroy_comp_ctxt:
devm_kfree(edev->dmadev, aq->comp_ctx);
err_destroy_ah_cache:
diff --git a/drivers/infiniband/hw/efa/efa_com.h b/drivers/infiniband/hw/efa/efa_com.h
index f979e36ec158..069c9dd98328 100644
--- a/drivers/infiniband/hw/efa/efa_com.h
+++ b/drivers/infiniband/hw/efa/efa_com.h
@@ -33,7 +33,8 @@ struct efa_com_admin_cq {
};
struct efa_com_admin_sq {
- struct efa_admin_aq_entry *entries;
+ u8 *buffer;
+ u16 entry_size;
dma_addr_t dma_addr;
spinlock_t lock; /* Protects ASQ */
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH for-next v2 3/3] RDMA/efa: Add support for 128B admin v2 SQ entry
2026-07-31 7:50 [PATCH for-next v2 0/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 1/3] RDMA/efa: Decouple admin command payload from admin header Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 2/3] RDMA/efa: Generalize the admin SQ Yonatan Nachum
@ 2026-07-31 7:50 ` Yonatan Nachum
2 siblings, 0 replies; 4+ messages in thread
From: Yonatan Nachum @ 2026-07-31 7:50 UTC (permalink / raw)
To: jgg, leon, linux-rdma
Cc: mrgolin, sleybo, matua, gal.pressman, Yonatan Nachum, Tom Sela
Add the new admin v2 format which is 128B in size and its header extends
the v1 header with checksum and payload version.
On admin SQ init check if the API version reported by the device
supports the admin v2 SQ entry and if so use it. Store the payload
offset and max size in the SQ for quick access in admin command
execution flow.
Using the admin SQ v2 entry implicitly enable the checksum in its
header so set it for device to validate against.
Reviewed-by: Michael Margolin <mrgolin@amazon.com>
Reviewed-by: Tom Sela <tomsela@amazon.com>
Signed-off-by: Yonatan Nachum <ynachum@amazon.com>
---
drivers/infiniband/hw/efa/efa_admin_defs.h | 29 +++++-
drivers/infiniband/hw/efa/efa_com.c | 113 +++++++++++++++------
drivers/infiniband/hw/efa/efa_com.h | 6 ++
3 files changed, 116 insertions(+), 32 deletions(-)
diff --git a/drivers/infiniband/hw/efa/efa_admin_defs.h b/drivers/infiniband/hw/efa/efa_admin_defs.h
index 0a14b3abe6f9..bf1721e31a70 100644
--- a/drivers/infiniband/hw/efa/efa_admin_defs.h
+++ b/drivers/infiniband/hw/efa/efa_admin_defs.h
@@ -7,7 +7,7 @@
#define _EFA_ADMIN_H_
#define EFA_ADMIN_API_VERSION_MAJOR 0
-#define EFA_ADMIN_API_VERSION_MINOR 2
+#define EFA_ADMIN_API_VERSION_MINOR 3
enum efa_admin_aq_completion_status {
EFA_ADMIN_SUCCESS = 0,
@@ -41,6 +41,21 @@ struct efa_admin_aq_common_desc {
u8 flags;
};
+struct efa_admin_aq_common_desc_v2 {
+ struct efa_admin_aq_common_desc common;
+
+ /*
+ * Poly 0x8005 CRC16 with initial value 0xFFFF and final XOR of
+ * 0xFFFF. The checksum covers the entire admin command entry
+ * including the zeroed checksum field.
+ */
+ u16 checksum;
+
+ u8 payload_ver;
+
+ u8 reserved[5];
+};
+
/*
* used in efa_admin_aq_entry. Can point directly to control data, or to a
* page list chunk. Used also at the end of indirect mode page list chunks,
@@ -58,6 +73,12 @@ struct efa_admin_aq_entry {
u32 request_payload[15];
};
+struct efa_admin_aq_entry_v2 {
+ struct efa_admin_aq_common_desc_v2 aq_common_descriptor;
+
+ u32 request_payload[29];
+};
+
struct efa_admin_acq_common_desc {
/*
* command identifier to associate it with the aq descriptor
@@ -74,7 +95,11 @@ struct efa_admin_acq_common_desc {
*/
u8 flags;
- /* Poly 0x8005 CRC16 with initial value 0xFFFF and final XOR of 0xFFFF */
+ /*
+ * Poly 0x8005 CRC16 with initial value 0xFFFF and final XOR of 0xFFFF.
+ * The checksum covers the entire admin completion entry including the
+ * zeroed checksum field.
+ */
u16 checksum;
u16 reserved;
diff --git a/drivers/infiniband/hw/efa/efa_com.c b/drivers/infiniband/hw/efa/efa_com.c
index 72b87f8cd086..74ad1d640fa6 100644
--- a/drivers/infiniband/hw/efa/efa_com.c
+++ b/drivers/infiniband/hw/efa/efa_com.c
@@ -25,11 +25,16 @@
#define EFA_CRC16_INIT_VAL 0xffff
-#define EFA_CRC_MIN_ADMIN_API_VERSION_MAJOR 0
-#define EFA_CRC_MIN_ADMIN_API_VERSION_MINOR 2
+#define EFA_ADMIN_SQ_MAX_ENT_SIZE sizeof(struct efa_admin_aq_entry_v2)
-#define EFA_MIN_ADMIN_API_VERSION_MAJOR 0
-#define EFA_MIN_ADMIN_API_VERSION_MINOR 1
+#define EFA_CRC_MIN_API_VERSION_MAJOR 0
+#define EFA_CRC_MIN_API_VERSION_MINOR 2
+
+#define EFA_ADMIN_V2_MIN_API_VERSION_MAJOR 0
+#define EFA_ADMIN_V2_MIN_API_VERSION_MINOR 3
+
+#define EFA_MIN_API_VERSION_MAJOR 0
+#define EFA_MIN_API_VERSION_MINOR 1
enum efa_cmd_status {
EFA_CMD_UNUSED,
@@ -82,6 +87,16 @@ void efa_com_set_dma_addr(dma_addr_t addr, u32 *addr_high, u32 *addr_low)
*addr_high = upper_32_bits(addr);
}
+static u32 efa_com_construct_ver(u32 major, u32 minor)
+{
+ u32 ver = 0;
+
+ EFA_SET(&ver, EFA_REGS_VERSION_MAJOR_VERSION, major);
+ EFA_SET(&ver, EFA_REGS_VERSION_MINOR_VERSION, minor);
+
+ return ver;
+}
+
static u32 efa_com_reg_read32(struct efa_com_dev *edev, u16 offset)
{
struct efa_com_mmio_read *mmio_read = &edev->mmio_read;
@@ -138,10 +153,23 @@ static int efa_com_admin_init_sq(struct efa_com_dev *edev)
{
struct efa_com_admin_queue *aq = &edev->aq;
struct efa_com_admin_sq *sq = &aq->sq;
+ u32 aq_caps = 0, admin_v2_min_ver = 0;
u32 addr_high, addr_low;
- u32 aq_caps = 0;
- sq->entry_size = sizeof(struct efa_admin_aq_entry);
+ admin_v2_min_ver = efa_com_construct_ver(EFA_ADMIN_V2_MIN_API_VERSION_MAJOR,
+ EFA_ADMIN_V2_MIN_API_VERSION_MINOR);
+ if (edev->dev_api_ver >= admin_v2_min_ver) {
+ sq->entry_size = sizeof(struct efa_admin_aq_entry_v2);
+ sq->payload_offset = offsetof(struct efa_admin_aq_entry_v2, request_payload);
+ sq->proto_ver = EFA_ADMIN_V2_PROTO_VER;
+ } else {
+ sq->entry_size = sizeof(struct efa_admin_aq_entry);
+ sq->payload_offset = offsetof(struct efa_admin_aq_entry, request_payload);
+ sq->proto_ver = EFA_ADMIN_V1_PROTO_VER;
+ }
+
+ sq->max_payload_size = sq->entry_size - sq->payload_offset;
+
sq->buffer = dma_alloc_coherent(aq->dmadev, aq->depth * sq->entry_size,
&sq->dma_addr, GFP_KERNEL);
if (!sq->buffer)
@@ -184,8 +212,8 @@ static int efa_com_admin_init_cq(struct efa_com_dev *edev)
spin_lock_init(&cq->lock);
- EFA_SET(&crc_min_ver, EFA_REGS_VERSION_MAJOR_VERSION, EFA_CRC_MIN_ADMIN_API_VERSION_MAJOR);
- EFA_SET(&crc_min_ver, EFA_REGS_VERSION_MINOR_VERSION, EFA_CRC_MIN_ADMIN_API_VERSION_MINOR);
+ crc_min_ver = efa_com_construct_ver(EFA_CRC_MIN_API_VERSION_MAJOR,
+ EFA_CRC_MIN_API_VERSION_MINOR);
if (edev->dev_api_ver >= crc_min_ver)
cq->validate_checksum = true;
@@ -321,13 +349,45 @@ static inline struct efa_comp_ctx *efa_com_get_comp_ctx_by_cmd_id(struct efa_com
return &aq->comp_ctx[ctx_id];
}
+static u16 efa_com_calc_crc16_checksum(u8 *buff, u32 buff_size)
+{
+ return crc16(EFA_CRC16_INIT_VAL, buff, buff_size) ^ EFA_CRC16_INIT_VAL;
+}
+
+static void efa_com_construct_aq_entry(struct efa_com_admin_queue *aq, u8 *aq_entry, u16 cmd_id,
+ u8 opcode, u8 flags, void *payload, size_t payload_size)
+{
+ struct efa_admin_aq_common_desc_v2 *common_v2 = NULL;
+ struct efa_admin_aq_common_desc *common;
+ struct efa_com_admin_sq *sq = &aq->sq;
+
+ if (sq->proto_ver == EFA_ADMIN_V1_PROTO_VER) {
+ common = (struct efa_admin_aq_common_desc *)aq_entry;
+ } else {
+ common_v2 = (struct efa_admin_aq_common_desc_v2 *)aq_entry;
+ common = &common_v2->common;
+ }
+
+ common->command_id = cmd_id;
+ common->opcode = opcode;
+ common->flags = flags;
+ EFA_SET(&common->flags, EFA_ADMIN_AQ_COMMON_DESC_PHASE, sq->phase);
+
+ if (payload)
+ memcpy(aq_entry + sq->payload_offset, payload, payload_size);
+
+ if (common_v2)
+ common_v2->checksum = efa_com_calc_crc16_checksum(aq_entry, sq->entry_size);
+}
+
static void __efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
struct efa_comp_ctx *comp_ctx,
- struct efa_admin_aq_entry *cmd,
- size_t cmd_size_in_bytes,
+ u8 opcode, u8 flags,
+ void *payload, size_t payload_size,
struct efa_admin_acq_entry *comp,
size_t comp_size_in_bytes)
{
+ u8 aq_entry[EFA_ADMIN_SQ_MAX_ENT_SIZE] = {};
u16 queue_size_mask, cmd_id, ctx_id, pi;
struct efa_com_admin_sq *sq = &aq->sq;
u8 *aqe;
@@ -341,21 +401,19 @@ static void __efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
cmd_id |= sq->pc << ilog2(aq->depth);
cmd_id &= EFA_ADMIN_AQ_COMMON_DESC_COMMAND_ID_MASK;
- cmd->aq_common_descriptor.command_id = cmd_id;
- EFA_SET(&cmd->aq_common_descriptor.flags,
- EFA_ADMIN_AQ_COMMON_DESC_PHASE, sq->phase);
+ efa_com_construct_aq_entry(aq, aq_entry, cmd_id, opcode, flags, payload, payload_size);
comp_ctx->status = EFA_CMD_SUBMITTED;
comp_ctx->comp_size = comp_size_in_bytes;
comp_ctx->user_cqe = comp;
- comp_ctx->cmd_opcode = cmd->aq_common_descriptor.opcode;
+ comp_ctx->cmd_opcode = opcode;
comp_ctx->cmd_id = cmd_id;
reinit_completion(&comp_ctx->wait_event);
aqe = sq->buffer + sq->entry_size * pi;
memset(aqe, 0, sq->entry_size);
- memcpy(aqe, cmd, cmd_size_in_bytes);
+ memcpy(aqe, aq_entry, sq->entry_size);
sq->pc++;
atomic64_inc(&aq->stats.submitted_cmd);
@@ -399,8 +457,8 @@ static inline int efa_com_init_comp_ctxt(struct efa_com_admin_queue *aq)
static int efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
struct efa_comp_ctx *comp_ctx,
- struct efa_admin_aq_entry *cmd,
- size_t cmd_size_in_bytes,
+ u8 opcode, u8 flags,
+ void *payload, size_t payload_size,
struct efa_admin_acq_entry *comp,
size_t comp_size_in_bytes)
{
@@ -411,8 +469,8 @@ static int efa_com_submit_admin_cmd(struct efa_com_admin_queue *aq,
return -ENODEV;
}
- __efa_com_submit_admin_cmd(aq, comp_ctx, cmd, cmd_size_in_bytes, comp,
- comp_size_in_bytes);
+ __efa_com_submit_admin_cmd(aq, comp_ctx, opcode, flags, payload,
+ payload_size, comp, comp_size_in_bytes);
spin_unlock(&aq->sq.lock);
return 0;
@@ -426,7 +484,7 @@ static bool efa_com_cqe_checksum_valid(struct efa_com_admin_queue *aq,
cqe->acq_common_descriptor.checksum = 0;
- calc_checksum = crc16(EFA_CRC16_INIT_VAL, (u8 *)cqe, sizeof(*cqe)) ^ EFA_CRC16_INIT_VAL;
+ calc_checksum = efa_com_calc_crc16_checksum((u8 *)cqe, sizeof(*cqe));
if (calc_checksum != cqe_checksum) {
ibdev_err(aq->efa_dev,
"Received completion with invalid checksum, cqe[%u], calc[%u], sq producer[%d], sq consumer[%d], cq consumer[%d]\n",
@@ -647,11 +705,10 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
void *payload, size_t payload_size,
struct efa_admin_acq_entry *comp, size_t comp_size)
{
- struct efa_admin_aq_entry aq_entry = {};
struct efa_comp_ctx *comp_ctx;
int err;
- if (payload_size > sizeof(aq_entry.request_payload))
+ if (payload_size > aq->sq.max_payload_size)
return -EINVAL;
might_sleep();
@@ -669,12 +726,8 @@ int efa_com_cmd_exec(struct efa_com_admin_queue *aq,
return -EINVAL;
}
- aq_entry.aq_common_descriptor.opcode = opcode;
- aq_entry.aq_common_descriptor.flags = flags;
- if (payload)
- memcpy(aq_entry.request_payload, payload, payload_size);
-
- err = efa_com_submit_admin_cmd(aq, comp_ctx, &aq_entry, sizeof(aq_entry), comp, comp_size);
+ err = efa_com_submit_admin_cmd(aq, comp_ctx, opcode, flags, payload, payload_size, comp,
+ comp_size);
if (err) {
ibdev_err_ratelimited(
aq->efa_dev,
@@ -1003,8 +1056,8 @@ int efa_com_validate_version(struct efa_com_dev *edev)
EFA_GET(&ver, EFA_REGS_VERSION_MAJOR_VERSION),
EFA_GET(&ver, EFA_REGS_VERSION_MINOR_VERSION));
- EFA_SET(&min_ver, EFA_REGS_VERSION_MAJOR_VERSION, EFA_MIN_ADMIN_API_VERSION_MAJOR);
- EFA_SET(&min_ver, EFA_REGS_VERSION_MINOR_VERSION, EFA_MIN_ADMIN_API_VERSION_MINOR);
+ min_ver = efa_com_construct_ver(EFA_MIN_API_VERSION_MAJOR,
+ EFA_MIN_API_VERSION_MINOR);
if (ver < min_ver) {
ibdev_err(edev->efa_dev,
"EFA version is lower than the minimal version the driver supports\n");
diff --git a/drivers/infiniband/hw/efa/efa_com.h b/drivers/infiniband/hw/efa/efa_com.h
index 069c9dd98328..0341704d0921 100644
--- a/drivers/infiniband/hw/efa/efa_com.h
+++ b/drivers/infiniband/hw/efa/efa_com.h
@@ -22,6 +22,9 @@
#define EFA_MAX_HANDLERS 256
+#define EFA_ADMIN_V1_PROTO_VER 0
+#define EFA_ADMIN_V2_PROTO_VER 1
+
struct efa_com_admin_cq {
struct efa_admin_acq_entry *entries;
dma_addr_t dma_addr;
@@ -35,8 +38,11 @@ struct efa_com_admin_cq {
struct efa_com_admin_sq {
u8 *buffer;
u16 entry_size;
+ u16 payload_offset;
+ u16 max_payload_size;
dma_addr_t dma_addr;
spinlock_t lock; /* Protects ASQ */
+ u8 proto_ver;
u32 __iomem *db_addr;
--
2.50.1
^ permalink raw reply related [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-31 7:50 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-31 7:50 [PATCH for-next v2 0/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 1/3] RDMA/efa: Decouple admin command payload from admin header Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 2/3] RDMA/efa: Generalize the admin SQ Yonatan Nachum
2026-07-31 7:50 ` [PATCH for-next v2 3/3] RDMA/efa: Add support for 128B admin v2 SQ entry Yonatan Nachum
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox