diff --git a/drivers/net/sfc/sfc_dp_rx.h b/drivers/net/sfc/sfc_dp_rx.h
index 3aba39658e..362be933a9 100644
--- a/drivers/net/sfc/sfc_dp_rx.h
+++ b/drivers/net/sfc/sfc_dp_rx.h
@@ -159,7 +159,8 @@ typedef void (sfc_dp_rx_qdestroy_t)(struct sfc_dp_rxq *dp_rxq);
  * It handovers EvQ to the datapath.
  */
 typedef int (sfc_dp_rx_qstart_t)(struct sfc_dp_rxq *dp_rxq,
-				 unsigned int evq_read_ptr);
+				 unsigned int evq_read_ptr,
+				 const efx_rx_prefix_layout_t *pinfo);
 
 /**
  * Receive queue stop function called before flush.
diff --git a/drivers/net/sfc/sfc_ef100_rx.c b/drivers/net/sfc/sfc_ef100_rx.c
index 2f5c5ab533..5d46d5bac1 100644
--- a/drivers/net/sfc/sfc_ef100_rx.c
+++ b/drivers/net/sfc/sfc_ef100_rx.c
@@ -18,6 +18,7 @@
 
 #include "efx_types.h"
 #include "efx_regs_ef100.h"
+#include "efx.h"
 
 #include "sfc_debug.h"
 #include "sfc_tweak.h"
@@ -337,6 +338,23 @@ sfc_ef100_rx_class_decode(const efx_word_t class, uint64_t *ol_flags)
 	return ptype;
 }
 
+/*
+ * Below function relies on the following fields in Rx prefix.
+ * Some fields are mandatory, some fields are optional.
+ * See sfc_ef100_rx_qstart() below.
+ */
+static const efx_rx_prefix_layout_t sfc_ef100_rx_prefix_layout = {
+	.erpl_fields	= {
+#define	SFC_EF100_RX_PREFIX_FIELD(_name, _big_endian) \
+	EFX_RX_PREFIX_FIELD(_name, ESF_GZ_RX_PREFIX_ ## _name, _big_endian)
+
+		SFC_EF100_RX_PREFIX_FIELD(LENGTH, B_FALSE),
+		SFC_EF100_RX_PREFIX_FIELD(CLASS, B_FALSE),
+
+#undef	SFC_EF100_RX_PREFIX_FIELD
+	}
+};
+
 static bool
 sfc_ef100_rx_prefix_to_offloads(const efx_oword_t *rx_prefix,
 				struct rte_mbuf *m)
@@ -667,8 +685,6 @@ sfc_ef100_rx_qcreate(uint16_t port_id, uint16_t queue_id,
 	rxq->evq_hw_ring = info->evq_hw_ring;
 	rxq->max_fill_level = info->max_fill_level;
 	rxq->refill_threshold = info->refill_threshold;
-	rxq->rearm_data =
-		sfc_ef100_mk_mbuf_rearm_data(port_id, info->prefix_size);
 	rxq->prefix_size = info->prefix_size;
 	rxq->buf_size = info->buf_size;
 	rxq->refill_mb_pool = info->refill_mb_pool;
@@ -702,13 +718,32 @@ sfc_ef100_rx_qdestroy(struct sfc_dp_rxq *dp_rxq)
 
 static sfc_dp_rx_qstart_t sfc_ef100_rx_qstart;
 static int
-sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr)
+sfc_ef100_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr,
+		    const efx_rx_prefix_layout_t *pinfo)
 {
 	struct sfc_ef100_rxq *rxq = sfc_ef100_rxq_by_dp_rxq(dp_rxq);
+	uint32_t unsup_rx_prefix_fields;
 
 	SFC_ASSERT(rxq->completed == 0);
 	SFC_ASSERT(rxq->added == 0);
 
+	/* Prefix must fit into reserved Rx buffer space */
+	if (pinfo->erpl_length > rxq->prefix_size)
+		return ENOTSUP;
+
+	unsup_rx_prefix_fields =
+		efx_rx_prefix_layout_check(pinfo, &sfc_ef100_rx_prefix_layout);
+
+	/* LENGTH and CLASS filds must always be present */
+	if ((unsup_rx_prefix_fields &
+	     ((1U << EFX_RX_PREFIX_FIELD_LENGTH) |
+	      (1U << EFX_RX_PREFIX_FIELD_CLASS))) != 0)
+		return ENOTSUP;
+
+	rxq->prefix_size = pinfo->erpl_length;
+	rxq->rearm_data = sfc_ef100_mk_mbuf_rearm_data(rxq->dp.dpq.port_id,
+						       rxq->prefix_size);
+
 	sfc_ef100_rx_qrefill(rxq);
 
 	rxq->evq_read_ptr = evq_read_ptr;
diff --git a/drivers/net/sfc/sfc_ef10_essb_rx.c b/drivers/net/sfc/sfc_ef10_essb_rx.c
index d9bf28525b..17e4c140f5 100644
--- a/drivers/net/sfc/sfc_ef10_essb_rx.c
+++ b/drivers/net/sfc/sfc_ef10_essb_rx.c
@@ -17,6 +17,7 @@
 
 #include "efx_types.h"
 #include "efx_regs_ef10.h"
+#include "efx.h"
 
 #include "sfc_debug.h"
 #include "sfc_tweak.h"
@@ -304,6 +305,27 @@ sfc_ef10_essb_rx_process_ev(struct sfc_ef10_essb_rxq *rxq, efx_qword_t rx_ev)
 	} while (ready > 0);
 }
 
+/*
+ * Below function relies on the following length and layout of the
+ * Rx prefix.
+ */
+static const efx_rx_prefix_layout_t sfc_ef10_essb_rx_prefix_layout = {
+	.erpl_length	= ES_EZ_ESSB_RX_PREFIX_LEN,
+	.erpl_fields	= {
+#define	SFC_EF10_ESSB_RX_PREFIX_FIELD(_efx, _ef10) \
+	EFX_RX_PREFIX_FIELD(_efx, ES_EZ_ESSB_RX_PREFIX_ ## _ef10, B_FALSE)
+
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(LENGTH, DATA_LEN),
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(USER_MARK, MARK),
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH_VALID, HASH_VALID),
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(USER_MARK_VALID, MARK_VALID),
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(USER_FLAG, MATCH_FLAG),
+		SFC_EF10_ESSB_RX_PREFIX_FIELD(RSS_HASH, HASH),
+
+#undef	SFC_EF10_ESSB_RX_PREFIX_FIELD
+	}
+};
+
 static unsigned int
 sfc_ef10_essb_rx_get_pending(struct sfc_ef10_essb_rxq *rxq,
 			     struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
@@ -633,10 +655,18 @@ sfc_ef10_essb_rx_qdestroy(struct sfc_dp_rxq *dp_rxq)
 
 static sfc_dp_rx_qstart_t sfc_ef10_essb_rx_qstart;
 static int
-sfc_ef10_essb_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr)
+sfc_ef10_essb_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr,
+			const efx_rx_prefix_layout_t *pinfo)
 {
 	struct sfc_ef10_essb_rxq *rxq = sfc_ef10_essb_rxq_by_dp_rxq(dp_rxq);
 
+	if (pinfo->erpl_length != sfc_ef10_essb_rx_prefix_layout.erpl_length)
+		return ENOTSUP;
+
+	if (efx_rx_prefix_layout_check(pinfo,
+				       &sfc_ef10_essb_rx_prefix_layout) != 0)
+		return ENOTSUP;
+
 	rxq->evq_read_ptr = evq_read_ptr;
 
 	/* Initialize before refill */
diff --git a/drivers/net/sfc/sfc_ef10_rx.c b/drivers/net/sfc/sfc_ef10_rx.c
index 62d0b6206b..e6bf3b9f42 100644
--- a/drivers/net/sfc/sfc_ef10_rx.c
+++ b/drivers/net/sfc/sfc_ef10_rx.c
@@ -223,6 +223,18 @@ sfc_ef10_rx_pending(struct sfc_ef10_rxq *rxq, struct rte_mbuf **rx_pkts,
 	return rx_pkts;
 }
 
+/*
+ * Below Rx pseudo-header (aka Rx prefix) accesssors rely on the
+ * following fields layout.
+ */
+static const efx_rx_prefix_layout_t sfc_ef10_rx_prefix_layout = {
+	.erpl_fields	= {
+		[EFX_RX_PREFIX_FIELD_RSS_HASH]	=
+		    { 0, sizeof(uint32_t) * CHAR_BIT, B_FALSE },
+		[EFX_RX_PREFIX_FIELD_LENGTH]	=
+		    { 8 * CHAR_BIT, sizeof(uint16_t) * CHAR_BIT, B_FALSE },
+	}
+};
 static uint16_t
 sfc_ef10_rx_pseudo_hdr_get_len(const uint8_t *pseudo_hdr)
 {
@@ -700,7 +712,8 @@ sfc_ef10_rx_qdestroy(struct sfc_dp_rxq *dp_rxq)
 
 static sfc_dp_rx_qstart_t sfc_ef10_rx_qstart;
 static int
-sfc_ef10_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr)
+sfc_ef10_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr,
+		   const efx_rx_prefix_layout_t *pinfo)
 {
 	struct sfc_ef10_rxq *rxq = sfc_ef10_rxq_by_dp_rxq(dp_rxq);
 
@@ -708,6 +721,10 @@ sfc_ef10_rx_qstart(struct sfc_dp_rxq *dp_rxq, unsigned int evq_read_ptr)
 	SFC_ASSERT(rxq->pending == 0);
 	SFC_ASSERT(rxq->added == 0);
 
+	if (pinfo->erpl_length != rxq->prefix_size ||
+	    efx_rx_prefix_layout_check(pinfo, &sfc_ef10_rx_prefix_layout) != 0)
+		return ENOTSUP;
+
 	sfc_ef10_rx_qrefill(rxq);
 
 	rxq->evq_read_ptr = evq_read_ptr;
diff --git a/drivers/net/sfc/sfc_rx.c b/drivers/net/sfc/sfc_rx.c
index 09afb519d5..ff4e69e679 100644
--- a/drivers/net/sfc/sfc_rx.c
+++ b/drivers/net/sfc/sfc_rx.c
@@ -528,13 +528,22 @@ static sfc_dp_rx_qpurge_t sfc_efx_rx_qpurge;
 static sfc_dp_rx_qstart_t sfc_efx_rx_qstart;
 static int
 sfc_efx_rx_qstart(struct sfc_dp_rxq *dp_rxq,
-		  __rte_unused unsigned int evq_read_ptr)
+		  __rte_unused unsigned int evq_read_ptr,
+		  const efx_rx_prefix_layout_t *pinfo)
 {
 	/* libefx-based datapath is specific to libefx-based PMD */
 	struct sfc_efx_rxq *rxq = sfc_efx_rxq_by_dp_rxq(dp_rxq);
 	struct sfc_rxq *crxq = sfc_rxq_by_dp_rxq(dp_rxq);
 	int rc;
 
+	/*
+	 * libefx API is used to extract information from Rx prefix and
+	 * it guarantees consistency. Just do length check to ensure
+	 * that we reserved space in Rx buffers correctly.
+	 */
+	if (rxq->prefix_size != pinfo->erpl_length)
+		return ENOTSUP;
+
 	rxq->common = crxq->common;
 
 	rxq->pending = rxq->completed = rxq->added = rxq->pushed = 0;
@@ -760,6 +769,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	struct sfc_rxq_info *rxq_info;
 	struct sfc_rxq *rxq;
 	struct sfc_evq *evq;
+	efx_rx_prefix_layout_t pinfo;
 	int rc;
 
 	sfc_log_init(sa, "sw_index=%u", sw_index);
@@ -811,9 +821,13 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 	if (rc != 0)
 		goto fail_rx_qcreate;
 
+	rc = efx_rx_prefix_get_layout(rxq->common, &pinfo);
+	if (rc != 0)
+		goto fail_prefix_get_layout;
+
 	efx_rx_qenable(rxq->common);
 
-	rc = sa->priv.dp_rx->qstart(rxq_info->dp, evq->read_ptr);
+	rc = sa->priv.dp_rx->qstart(rxq_info->dp, evq->read_ptr, &pinfo);
 	if (rc != 0)
 		goto fail_dp_qstart;
 
@@ -839,6 +853,7 @@ sfc_rx_qstart(struct sfc_adapter *sa, unsigned int sw_index)
 fail_dp_qstart:
 	efx_rx_qdestroy(rxq->common);
 
+fail_prefix_get_layout:
 fail_rx_qcreate:
 fail_bad_contig_block_size:
 fail_mp_get_info:
