diff --git a/doc/guides/rel_notes/release_22_11.rst b/doc/guides/rel_notes/release_22_11.rst
index 2e076ba2ad..26ca22efe0 100644
--- a/doc/guides/rel_notes/release_22_11.rst
+++ b/doc/guides/rel_notes/release_22_11.rst
@@ -55,6 +55,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =======================================================
 
+* ** Added support ethdev support for mulitiple mbuf pools per Rx queue.**
+
+  * Added new Rx offload flag ''RTE_ETH_RX_OFFLOAD_MUL_MEMPOOL'' to support
+    mulitiple mbuf pools per Rx queue. Thisi capability allows PMD to choose
+    a memory pool based on the packet's length
+
 * **Updated Wangxun ngbe driver.**
 
   * Added support to set device link down/up.
diff --git a/lib/ethdev/rte_ethdev.c b/lib/ethdev/rte_ethdev.c
index 1979dc0850..eed4834e6b 100644
--- a/lib/ethdev/rte_ethdev.c
+++ b/lib/ethdev/rte_ethdev.c
@@ -1634,6 +1634,44 @@ rte_eth_dev_is_removed(uint16_t port_id)
 	return ret;
 }
 
+static int
+rte_eth_rx_queue_check_mempool(struct rte_mempool **rx_mempool,
+			       uint16_t n_pool, uint32_t *mbp_buf_size,
+			       const struct rte_eth_dev_info *dev_info)
+{
+	uint16_t pool_idx;
+
+	if (n_pool > dev_info->max_pools) {
+		RTE_ETHDEV_LOG(ERR,
+			       "Too many Rx mempools %u vs maximum %u\n",
+			       n_pool, dev_info->max_pools);
+		return -EINVAL;
+	}
+
+	for (pool_idx = 0; pool_idx < n_pool; pool_idx++) {
+		struct rte_mempool *mpl = rx_mempool[pool_idx];
+
+		if (mpl == NULL) {
+			RTE_ETHDEV_LOG(ERR, "null Rx mempool pointer\n");
+			return -EINVAL;
+		}
+
+		*mbp_buf_size = rte_pktmbuf_data_room_size(mpl);
+		if (*mbp_buf_size < dev_info->min_rx_bufsize +
+		    RTE_PKTMBUF_HEADROOM) {
+			RTE_ETHDEV_LOG(ERR,
+				       "%s mbuf_data_room_size %u < %u (RTE_PKTMBUF_HEADROOM=%u + min_rx_bufsize(dev)=%u)\n",
+					mpl->name, *mbp_buf_size,
+					RTE_PKTMBUF_HEADROOM + dev_info->min_rx_bufsize,
+					RTE_PKTMBUF_HEADROOM,
+					dev_info->min_rx_bufsize);
+			return -EINVAL;
+		}
+	}
+
+	return 0;
+}
+
 static int
 rte_eth_rx_queue_check_split(const struct rte_eth_rxseg_split *rx_seg,
 			     uint16_t n_seg, uint32_t *mbp_buf_size,
@@ -1733,9 +1771,12 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 
 	if (mp != NULL) {
 		/* Single pool configuration check. */
-		if (rx_conf != NULL && rx_conf->rx_nseg != 0) {
+		if (((rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) &&
+		    rx_conf != NULL && rx_conf->rx_nseg != 0) ||
+		   ((rx_conf->offloads & RTE_ETH_RX_OFFLOAD_MUL_MEMPOOL) &&
+		    rx_conf != NULL && rx_conf->rx_npool != 0)) {
 			RTE_ETHDEV_LOG(ERR,
-				       "Ambiguous segment configuration\n");
+				       "Ambiguous Rx mempools configuration\n");
 			return -EINVAL;
 		}
 		/*
@@ -1763,30 +1804,43 @@ rte_eth_rx_queue_setup(uint16_t port_id, uint16_t rx_queue_id,
 				       dev_info.min_rx_bufsize);
 			return -EINVAL;
 		}
-	} else {
+	} else if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
 		const struct rte_eth_rxseg_split *rx_seg;
 		uint16_t n_seg;
 
 		/* Extended multi-segment configuration check. */
 		if (rx_conf == NULL || rx_conf->rx_seg == NULL || rx_conf->rx_nseg == 0) {
 			RTE_ETHDEV_LOG(ERR,
-				       "Memory pool is null and no extended configuration provided\n");
+				       "Memory pool is null and no multi-segment configuration provided\n");
 			return -EINVAL;
 		}
 
 		rx_seg = (const struct rte_eth_rxseg_split *)rx_conf->rx_seg;
 		n_seg = rx_conf->rx_nseg;
 
-		if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) {
-			ret = rte_eth_rx_queue_check_split(rx_seg, n_seg,
+		ret = rte_eth_rx_queue_check_split(rx_seg, n_seg,
 							   &mbp_buf_size,
 							   &dev_info);
-			if (ret != 0)
-				return ret;
-		} else {
-			RTE_ETHDEV_LOG(ERR, "No Rx segmentation offload configured\n");
+		if (ret != 0)
+			return ret;
+	} else if (rx_conf->offloads & RTE_ETH_RX_OFFLOAD_MUL_MEMPOOL) {
+		/* Extended multi-pool configuration check. */
+		if (rx_conf == NULL || rx_conf->rx_mempools == NULL || rx_conf->rx_npool == 0) {
+			RTE_ETHDEV_LOG(ERR,
+				       "Memory pool is null and no multi-pool configuration provided\n");
 			return -EINVAL;
 		}
+
+		ret = rte_eth_rx_queue_check_mempool(rx_conf->rx_mempools,
+						     rx_conf->rx_npool,
+						     &mbp_buf_size,
+						     &dev_info);
+
+		if (ret != 0)
+			return ret;
+	} else {
+		RTE_ETHDEV_LOG(ERR, "Missing Rx mempool configuration\n");
+		return -EINVAL;
 	}
 
 	/* Use default specified by driver, if nb_rx_desc is zero */
diff --git a/lib/ethdev/rte_ethdev.h b/lib/ethdev/rte_ethdev.h
index b62ac5bb6f..306c2b3573 100644
--- a/lib/ethdev/rte_ethdev.h
+++ b/lib/ethdev/rte_ethdev.h
@@ -1067,6 +1067,25 @@ struct rte_eth_rxconf {
 	 */
 	union rte_eth_rxseg *rx_seg;
 
+	/**
+	 * Points to an array of mempools.
+	 *
+	 * Valid only when RTE_ETH_RX_OFFLOAD_MUL_MEMPOOL flag is set in
+	 * Rx offloads.
+	 *
+	 * This provides support for  multiple mbuf pools per Rx queue.
+	 *
+	 * This is often useful for saving the memory where the application can
+	 * create a different pools to steer the specific size of the packet, thus
+	 * enabling effective use of memory.
+	 *
+	 * Note that on Rx scatter enable, a packet may be delivered using a chain
+	 * of mbufs obtained from single mempool or multiple mempools based on
+	 * the NIC implementation.
+	 */
+	struct rte_mempool **rx_mempools;
+	uint16_t rx_npool; /** < number of mempools */
+
 	uint64_t reserved_64s[2]; /**< Reserved for future fields */
 	void *reserved_ptrs[2];   /**< Reserved for future fields */
 };
@@ -1395,6 +1414,7 @@ struct rte_eth_conf {
 #define RTE_ETH_RX_OFFLOAD_OUTER_UDP_CKSUM  RTE_BIT64(18)
 #define RTE_ETH_RX_OFFLOAD_RSS_HASH         RTE_BIT64(19)
 #define RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT     RTE_BIT64(20)
+#define RTE_ETH_RX_OFFLOAD_MUL_MEMPOOL      RTE_BIT64(21)
 
 #define RTE_ETH_RX_OFFLOAD_CHECKSUM (RTE_ETH_RX_OFFLOAD_IPV4_CKSUM | \
 				 RTE_ETH_RX_OFFLOAD_UDP_CKSUM | \
@@ -1615,6 +1635,8 @@ struct rte_eth_dev_info {
 	/** Configured number of Rx/Tx queues */
 	uint16_t nb_rx_queues; /**< Number of Rx queues. */
 	uint16_t nb_tx_queues; /**< Number of Tx queues. */
+	/** Maximum number of pools supported per Rx queue. */
+	uint16_t max_pools;
 	/** Rx parameter recommendations */
 	struct rte_eth_dev_portconf default_rxportconf;
 	/** Tx parameter recommendations */
