diff --git a/drivers/common/sfc_efx/base/efx_impl.h b/drivers/common/sfc_efx/base/efx_impl.h
index c373192554..fc0a654f80 100644
--- a/drivers/common/sfc_efx/base/efx_impl.h
+++ b/drivers/common/sfc_efx/base/efx_impl.h
@@ -1439,6 +1439,7 @@ typedef struct efx_mcdi_init_rxq_params_s {
 	uint32_t	es_max_dma_len;
 	uint32_t	es_buf_stride;
 	uint32_t	hol_block_timeout;
+	uint32_t	prefix_id;
 } efx_mcdi_init_rxq_params_t;
 
 LIBEFX_INTERNAL
diff --git a/drivers/common/sfc_efx/base/efx_mcdi.c b/drivers/common/sfc_efx/base/efx_mcdi.c
index aa19c7c759..b8e45b458d 100644
--- a/drivers/common/sfc_efx/base/efx_mcdi.c
+++ b/drivers/common/sfc_efx/base/efx_mcdi.c
@@ -2692,8 +2692,8 @@ efx_mcdi_init_rxq(
 {
 	efx_nic_cfg_t *encp = &(enp->en_nic_cfg);
 	efx_mcdi_req_t req;
-	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_V4_IN_LEN,
-		MC_CMD_INIT_RXQ_V4_OUT_LEN);
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_INIT_RXQ_V5_IN_LEN,
+		MC_CMD_INIT_RXQ_V5_OUT_LEN);
 	int npages = efx_rxq_nbufs(enp, ndescs);
 	int i;
 	efx_qword_t *dma_addr;
@@ -2747,9 +2747,9 @@ efx_mcdi_init_rxq(
 
 	req.emr_cmd = MC_CMD_INIT_RXQ;
 	req.emr_in_buf = payload;
-	req.emr_in_length = MC_CMD_INIT_RXQ_V4_IN_LEN;
+	req.emr_in_length = MC_CMD_INIT_RXQ_V5_IN_LEN;
 	req.emr_out_buf = payload;
-	req.emr_out_length = MC_CMD_INIT_RXQ_V4_OUT_LEN;
+	req.emr_out_length = MC_CMD_INIT_RXQ_V5_OUT_LEN;
 
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_SIZE, ndescs);
 	MCDI_IN_SET_DWORD(req, INIT_RXQ_EXT_IN_TARGET_EVQ, eep->ee_index);
@@ -2787,6 +2787,8 @@ efx_mcdi_init_rxq(
 		MCDI_IN_SET_DWORD(req, INIT_RXQ_V4_IN_BUFFER_SIZE_BYTES,
 		    params->buf_size);
 
+	MCDI_IN_SET_DWORD(req, INIT_RXQ_V5_IN_RX_PREFIX_ID, params->prefix_id);
+
 	dma_addr = MCDI_IN2(req, efx_qword_t, INIT_RXQ_IN_DMA_ADDR);
 	addr = EFSYS_MEM_ADDR(esmp);
 
diff --git a/drivers/common/sfc_efx/base/rhead_rx.c b/drivers/common/sfc_efx/base/rhead_rx.c
index 38c905444a..d683f280ce 100644
--- a/drivers/common/sfc_efx/base/rhead_rx.c
+++ b/drivers/common/sfc_efx/base/rhead_rx.c
@@ -10,6 +10,12 @@
 
 #if EFSYS_OPT_RIVERHEAD
 
+/*
+ * Maximum number of Rx prefixes supported by Rx prefix choice to be
+ * returned from firmware.
+ */
+#define	RHEAD_RX_PREFIX_IDS_MAX		16
+
 /*
  * Default Rx prefix layout on Riverhead if FW does not support Rx
  * prefix choice using MC_CMD_GET_RX_PREFIX_ID and query its layout
@@ -265,6 +271,312 @@ rhead_rx_qenable(
 	_NOTE(ARGUNUSED(erp))
 }
 
+static	__checkReturn	efx_rc_t
+efx_mcdi_get_rx_prefix_ids(
+	__in					efx_nic_t *enp,
+	__in					uint32_t mcdi_fields_mask,
+	__in					unsigned int max_ids,
+	__out					unsigned int *nids,
+	__out_ecount_part(max_ids, *nids)	uint32_t *idsp)
+{
+	efx_mcdi_req_t req;
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_GET_RX_PREFIX_ID_IN_LEN,
+		MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX);
+	efx_rc_t rc;
+	uint32_t num;
+
+	req.emr_cmd = MC_CMD_GET_RX_PREFIX_ID;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_GET_RX_PREFIX_ID_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_GET_RX_PREFIX_ID_OUT_LENMAX;
+
+	MCDI_IN_SET_DWORD(req, GET_RX_PREFIX_ID_IN_FIELDS, mcdi_fields_mask);
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_GET_RX_PREFIX_ID_OUT_LENMIN) {
+		rc = EMSGSIZE;
+		goto fail2;
+	}
+
+	num = MCDI_OUT_DWORD(req, GET_RX_PREFIX_ID_OUT_NUM_RX_PREFIX_IDS);
+
+	if (req.emr_out_length_used != MC_CMD_GET_RX_PREFIX_ID_OUT_LEN(num)) {
+		rc = EMSGSIZE;
+		goto fail3;
+	}
+
+	*nids = MIN(num, max_ids);
+
+	EFX_STATIC_ASSERT(sizeof (idsp[0]) ==
+	    MC_CMD_GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID_LEN);
+	memcpy(idsp,
+	    MCDI_OUT2(req, uint32_t, GET_RX_PREFIX_ID_OUT_RX_PREFIX_ID),
+	    *nids * sizeof (idsp[0]));
+
+	return (0);
+
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static	__checkReturn	efx_rx_prefix_field_t
+efx_mcdi_rx_prefix_field_map(unsigned int mcdi_idx)
+{
+	static const efx_rx_prefix_field_t efx_mcdi_to_rx_prefix_field[] = {
+#define	EFX_MCDI_TO_RX_PREFIX_FIELD(_field) \
+	[RX_PREFIX_FIELD_INFO_ ## _field] = EFX_RX_PREFIX_FIELD_ ## _field
+
+		EFX_MCDI_TO_RX_PREFIX_FIELD(LENGTH),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH_VALID),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(USER_FLAG),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(CLASS),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(PARTIAL_TSTAMP),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(RSS_HASH),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(USER_MARK),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(INGRESS_VPORT),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(CSUM_FRAME),
+		EFX_MCDI_TO_RX_PREFIX_FIELD(VLAN_STRIP_TCI),
+
+#undef	EFX_MCDI_TO_RX_PREFIX_FIELD
+	};
+
+	if (mcdi_idx >= EFX_ARRAY_SIZE(efx_mcdi_to_rx_prefix_field))
+		return (EFX_RX_PREFIX_NFIELDS);
+
+	return (efx_mcdi_to_rx_prefix_field[mcdi_idx]);
+}
+
+static	__checkReturn	int
+efx_rx_prefix_field_map_to_mcdi(
+	__in		efx_rx_prefix_field_t field)
+{
+	static const int efx_rx_prefix_field_to_mcdi[] = {
+		[EFX_RX_PREFIX_FIELD_LENGTH] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_LENGTH),
+		[EFX_RX_PREFIX_FIELD_ORIG_LENGTH] = -1,
+		[EFX_RX_PREFIX_FIELD_CLASS] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CLASS),
+		[EFX_RX_PREFIX_FIELD_RSS_HASH] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH),
+		[EFX_RX_PREFIX_FIELD_RSS_HASH_VALID] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_RSS_HASH_VALID),
+		[EFX_RX_PREFIX_FIELD_PARTIAL_TSTAMP] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_PARTIAL_TSTAMP),
+		[EFX_RX_PREFIX_FIELD_VLAN_STRIP_TCI] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_VLAN_STRIP_TCI),
+		[EFX_RX_PREFIX_FIELD_INNER_VLAN_STRIP_TCI] = -1,
+		[EFX_RX_PREFIX_FIELD_USER_FLAG] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_FLAG),
+		[EFX_RX_PREFIX_FIELD_USER_MARK] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_USER_MARK),
+		[EFX_RX_PREFIX_FIELD_USER_MARK_VALID] = -1,
+		[EFX_RX_PREFIX_FIELD_CSUM_FRAME] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_CSUM_FRAME),
+		[EFX_RX_PREFIX_FIELD_INGRESS_VPORT] =
+			EFX_LOW_BIT(MC_CMD_GET_RX_PREFIX_ID_IN_INGRESS_VPORT),
+	};
+
+	if (field >= EFX_ARRAY_SIZE(efx_rx_prefix_field_to_mcdi))
+		return (-1);
+
+	return (efx_rx_prefix_field_to_mcdi[field]);
+}
+
+static	__checkReturn	efx_rc_t
+efx_rx_prefix_fields_mask_to_mcdi(
+	__in		uint32_t fields_mask,
+	__out		uint32_t *mcdi_fields_maskp)
+{
+	uint32_t mcdi_fields_mask = 0;
+	unsigned int i;
+
+	for (i = 0; i < EFX_RX_PREFIX_NFIELDS; ++i) {
+		if (fields_mask & (1U << i)) {
+			int mcdi_field = efx_rx_prefix_field_map_to_mcdi(i);
+
+			if (mcdi_field < 0)
+				return (EINVAL);
+
+			mcdi_fields_mask |= (1U << mcdi_field);
+		}
+	}
+
+	*mcdi_fields_maskp = mcdi_fields_mask;
+	return (0);
+}
+
+static	__checkReturn	efx_rc_t
+efx_mcdi_query_rx_prefix_id(
+	__in		efx_nic_t *enp,
+	__in		uint32_t prefix_id,
+	__out		efx_rx_prefix_layout_t *erplp)
+{
+	efx_mcdi_req_t req;
+	EFX_MCDI_DECLARE_BUF(payload, MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN,
+		MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX);
+	efx_rc_t rc;
+	size_t response_len;
+	const efx_dword_t *resp;
+	const efx_dword_t *finfo;
+	unsigned int num_fields;
+	unsigned int mcdi_field;
+	efx_rx_prefix_field_t field;
+	unsigned int i;
+
+	req.emr_cmd = MC_CMD_QUERY_RX_PREFIX_ID;
+	req.emr_in_buf = payload;
+	req.emr_in_length = MC_CMD_QUERY_RX_PREFIX_ID_IN_LEN;
+	req.emr_out_buf = payload;
+	req.emr_out_length = MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMAX;
+
+	MCDI_IN_SET_DWORD(req, QUERY_RX_PREFIX_ID_IN_RX_PREFIX_ID, prefix_id);
+
+	efx_mcdi_execute(enp, &req);
+
+	if (req.emr_rc != 0) {
+		rc = req.emr_rc;
+		goto fail1;
+	}
+
+	if (req.emr_out_length_used < MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN) {
+		rc = EMSGSIZE;
+		goto fail2;
+	}
+
+	if (MCDI_OUT_BYTE(req, QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE) !=
+	    MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_TYPE_FIXED) {
+		rc = ENOTSUP;
+		goto fail3;
+	}
+
+	EFX_STATIC_ASSERT(MC_CMD_QUERY_RX_PREFIX_ID_OUT_LENMIN >=
+	    MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST);
+	response_len = req.emr_out_length_used -
+	    MC_CMD_QUERY_RX_PREFIX_ID_OUT_RESPONSE_OFST;
+
+	if (response_len < RX_PREFIX_FIXED_RESPONSE_LENMIN) {
+		rc = EMSGSIZE;
+		goto fail4;
+	}
+
+	resp = MCDI_OUT2(req, efx_dword_t, QUERY_RX_PREFIX_ID_OUT_RESPONSE);
+
+	memset(erplp, 0, sizeof (*erplp));
+	erplp->erpl_id = prefix_id;
+	erplp->erpl_length =
+	    EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_PREFIX_LENGTH_BYTES);
+	num_fields =
+	    EFX_DWORD_FIELD(*resp, RX_PREFIX_FIXED_RESPONSE_FIELD_COUNT);
+
+	if (response_len < RX_PREFIX_FIXED_RESPONSE_LEN(num_fields)) {
+		rc = EMSGSIZE;
+		goto fail5;
+	}
+
+	finfo = (const efx_dword_t *)((const uint8_t *)resp +
+	     RX_PREFIX_FIXED_RESPONSE_FIELDS_OFST);
+
+	for (i = 0; i < num_fields; ++i, ++finfo) {
+		mcdi_field = EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_TYPE);
+
+		field = efx_mcdi_rx_prefix_field_map(mcdi_field);
+		if (field >= EFX_RX_PREFIX_NFIELDS)
+			continue;
+
+		erplp->erpl_fields[field].erpfi_offset_bits =
+		    EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_OFFSET_BITS);
+		erplp->erpl_fields[field].erpfi_width_bits =
+		    EFX_DWORD_FIELD(*finfo, RX_PREFIX_FIELD_INFO_WIDTH_BITS);
+	}
+
+	return (0);
+
+fail5:
+	EFSYS_PROBE(fail5);
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
+static	__checkReturn	efx_rc_t
+rhead_rx_choose_prefix_id(
+	__in		efx_nic_t *enp,
+	__in		uint32_t fields_mask,
+	__out		efx_rx_prefix_layout_t *erplp)
+{
+	efx_rx_prefix_layout_t erpl;
+	uint32_t prefix_ids[RHEAD_RX_PREFIX_IDS_MAX];
+	uint32_t mcdi_fields_mask;
+	unsigned int num = 0;
+	unsigned int i;
+	efx_rc_t rc;
+
+	rc = efx_rx_prefix_fields_mask_to_mcdi(fields_mask, &mcdi_fields_mask);
+	if (rc != 0)
+		goto fail1;
+
+	memset(erplp, 0, sizeof (*erplp));
+
+	rc = efx_mcdi_get_rx_prefix_ids(enp, mcdi_fields_mask,
+	    EFX_ARRAY_SIZE(prefix_ids), &num, prefix_ids);
+	if (rc == ENOTSUP) {
+		/* Not supported MCDI, use default prefix ID */
+		*erplp = rhead_default_rx_prefix_layout;
+		goto done;
+	}
+	if (rc != 0)
+		goto fail2;
+
+	if (num == 0) {
+		rc = ENOTSUP;
+		goto fail3;
+	}
+
+	for (i = 0; i < num; ++i) {
+		rc = efx_mcdi_query_rx_prefix_id(enp, prefix_ids[i], &erpl);
+		if (rc != 0)
+			goto fail4;
+
+		/* Choose the smallest prefix which meets our requirements */
+		if (i == 0 || erpl.erpl_length < erplp->erpl_length)
+			*erplp = erpl;
+	}
+
+done:
+	return (0);
+
+fail4:
+	EFSYS_PROBE(fail4);
+fail3:
+	EFSYS_PROBE(fail3);
+fail2:
+	EFSYS_PROBE(fail2);
+fail1:
+	EFSYS_PROBE1(fail1, efx_rc_t, rc);
+
+	return (rc);
+}
+
 	__checkReturn	efx_rc_t
 rhead_rx_qcreate(
 	__in		efx_nic_t *enp,
@@ -281,6 +593,7 @@ rhead_rx_qcreate(
 {
 	const efx_nic_cfg_t *encp = efx_nic_cfg_get(enp);
 	efx_mcdi_init_rxq_params_t params;
+	efx_rx_prefix_layout_t erpl;
 	efx_rc_t rc;
 
 	_NOTE(ARGUNUSED(id))
@@ -310,6 +623,20 @@ rhead_rx_qcreate(
 	else
 		params.disable_scatter = encp->enc_rx_disable_scatter_supported;
 
+	/*
+	 * LENGTH is required in EF100 host interface, as receive events
+	 * do not include the packet length.
+	 * NOTE: Required fields are hard-wired now. Future designs will
+	 * want to allow the client (driver) code to have control over
+	 * which fields are required or may be allow to request so-called
+	 * default Rx prefix (which ID is equal to 0).
+	 */
+	if ((rc = rhead_rx_choose_prefix_id(enp,
+	    (1U << EFX_RX_PREFIX_FIELD_LENGTH), &erpl)) != 0)
+		goto fail3;
+
+	params.prefix_id = erpl.erpl_id;
+
 	/*
 	 * Ignore EFX_RXQ_FLAG_INNER_CLASSES since in accordance with
 	 * EF100 host interface both inner and outer classes are provided
@@ -318,15 +645,17 @@ rhead_rx_qcreate(
 
 	if ((rc = efx_mcdi_init_rxq(enp, ndescs, eep, label, index,
 		    esmp, &params)) != 0)
-		goto fail3;
+		goto fail4;
 
 	erp->er_eep = eep;
 	erp->er_label = label;
 	erp->er_buf_size = params.buf_size;
-	erp->er_prefix_layout = rhead_default_rx_prefix_layout;
+	erp->er_prefix_layout = erpl;
 
 	return (0);
 
+fail4:
+	EFSYS_PROBE(fail4);
 fail3:
 	EFSYS_PROBE(fail3);
 fail2:
