diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index 8dd9e23c78..80874e23de 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -372,7 +372,7 @@ nfp_flower_init_ctrl_vnic(struct nfp_app_fw_flower *app_fw_flower,
 		 */
 		tz = rte_eth_dma_zone_reserve(eth_dev, ctrl_rxring_name, i,
 				sizeof(struct nfp_net_rx_desc) *
-				hw->dev_info->max_qc_size,
+				hw_priv->dev_info->max_qc_size,
 				NFP_MEMZONE_ALIGN, numa_node);
 		if (tz == NULL) {
 			PMD_DRV_LOG(ERR, "Error allocating rx dma");
@@ -430,7 +430,7 @@ nfp_flower_init_ctrl_vnic(struct nfp_app_fw_flower *app_fw_flower,
 		 */
 		tz = rte_eth_dma_zone_reserve(eth_dev, ctrl_txring_name, i,
 				sizeof(struct nfp_net_nfd3_tx_desc) *
-				hw->dev_info->max_qc_size,
+				hw_priv->dev_info->max_qc_size,
 				NFP_MEMZONE_ALIGN, numa_node);
 		if (tz == NULL) {
 			PMD_DRV_LOG(ERR, "Error allocating tx dma");
@@ -639,8 +639,7 @@ nfp_flower_nfd_func_register(struct nfp_app_fw_flower *app_fw_flower)
 }
 
 int
-nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv,
-		const struct nfp_dev_info *dev_info)
+nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv)
 {
 	int ret;
 	int err;
@@ -709,7 +708,6 @@ nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv,
 	app_fw_flower->pf_hw = pf_hw;
 	pf_hw->super.ctrl_bar = pf_dev->ctrl_bar;
 	pf_hw->cpp = pf_dev->cpp;
-	pf_hw->dev_info = dev_info;
 
 	ret = nfp_flower_init_vnic_common(hw_priv, pf_hw, "pf_vnic");
 	if (ret != 0) {
@@ -734,7 +732,6 @@ nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv,
 
 	/* Now populate the ctrl vNIC */
 	ctrl_hw->cpp = pf_dev->cpp;
-	ctrl_hw->dev_info = dev_info;
 
 	ret = nfp_flower_init_ctrl_vnic(app_fw_flower, hw_priv);
 	if (ret != 0) {
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 5cc29dcc87..5c2f338a20 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -104,8 +104,7 @@ nfp_flower_support_decap_v2(const struct nfp_app_fw_flower *app_fw_flower)
 	return app_fw_flower->ext_features & NFP_FL_FEATS_DECAP_V2;
 }
 
-int nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv,
-		const struct nfp_dev_info *dev_info);
+int nfp_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv);
 void nfp_uninit_app_fw_flower(struct nfp_net_hw_priv *hw_priv);
 int nfp_secondary_init_app_fw_flower(struct nfp_net_hw_priv *hw_priv);
 bool nfp_flower_pf_dispatch_pkts(struct nfp_net_hw_priv *hw_priv,
diff --git a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
index 681a63eacd..ee96cd8e46 100644
--- a/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
+++ b/drivers/net/nfp/nfd3/nfp_nfd3_dp.c
@@ -385,10 +385,12 @@ nfp_net_nfd3_tx_queue_setup(struct rte_eth_dev *dev,
 	struct nfp_net_txq *txq;
 	uint16_t tx_free_thresh;
 	const struct rte_memzone *tz;
+	struct nfp_net_hw_priv *hw_priv;
 
 	hw = nfp_net_get_hw(dev);
+	hw_priv = dev->process_private;
 
-	nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	nfp_net_tx_desc_limits(hw, hw_priv, &min_tx_desc, &max_tx_desc);
 
 	/* Validating number of descriptors */
 	tx_desc_sz = nb_desc * sizeof(struct nfp_net_nfd3_tx_desc);
diff --git a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
index 83eaec9c24..3ba97e23a9 100644
--- a/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
+++ b/drivers/net/nfp/nfdk/nfp_nfdk_dp.c
@@ -464,10 +464,12 @@ nfp_net_nfdk_tx_queue_setup(struct rte_eth_dev *dev,
 	uint16_t tx_free_thresh;
 	struct nfp_net_txq *txq;
 	const struct rte_memzone *tz;
+	struct nfp_net_hw_priv *hw_priv;
 
 	hw = nfp_net_get_hw(dev);
+	hw_priv = dev->process_private;
 
-	nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	nfp_net_tx_desc_limits(hw, hw_priv, &min_tx_desc, &max_tx_desc);
 
 	/* Validating number of descriptors */
 	tx_desc_sz = nb_desc * sizeof(struct nfp_net_nfdk_tx_desc);
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 58e155e92b..38fe153ab4 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1494,8 +1494,7 @@ nfp_enable_multi_pf(struct nfp_pf_dev *pf_dev)
 }
 
 static int
-nfp_init_app_fw_nic(struct nfp_net_hw_priv *hw_priv,
-		const struct nfp_dev_info *dev_info)
+nfp_init_app_fw_nic(struct nfp_net_hw_priv *hw_priv)
 {
 	uint8_t i;
 	uint8_t id;
@@ -1601,7 +1600,6 @@ nfp_init_app_fw_nic(struct nfp_net_hw_priv *hw_priv,
 		/* Add this device to the PF's array of physical ports */
 		app_fw_nic->ports[id] = hw;
 
-		hw->dev_info = dev_info;
 		hw->cpp = pf_dev->cpp;
 		hw->eth_dev = eth_dev;
 		hw->idx = id;
@@ -1968,6 +1966,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
 	PMD_INIT_LOG(DEBUG, "qc_bar address: %p", pf_dev->qc_bar);
 
 	hw_priv->pf_dev = pf_dev;
+	hw_priv->dev_info = dev_info;
 
 	/*
 	 * PF initialization has been done at this point. Call app specific
@@ -1982,7 +1981,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
 		}
 
 		PMD_INIT_LOG(INFO, "Initializing coreNIC");
-		ret = nfp_init_app_fw_nic(hw_priv, dev_info);
+		ret = nfp_init_app_fw_nic(hw_priv);
 		if (ret != 0) {
 			PMD_INIT_LOG(ERR, "Could not initialize coreNIC!");
 			goto hwqueues_cleanup;
@@ -1990,7 +1989,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
 		break;
 	case NFP_APP_FW_FLOWER_NIC:
 		PMD_INIT_LOG(INFO, "Initializing Flower");
-		ret = nfp_init_app_fw_flower(hw_priv, dev_info);
+		ret = nfp_init_app_fw_flower(hw_priv);
 		if (ret != 0) {
 			PMD_INIT_LOG(ERR, "Could not initialize Flower!");
 			goto hwqueues_cleanup;
@@ -2187,6 +2186,7 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 	pf_dev->sync = sync;
 
 	hw_priv->pf_dev = pf_dev;
+	hw_priv->dev_info = dev_info;
 
 	/* Call app specific init code now */
 	switch (app_fw_id) {
diff --git a/drivers/net/nfp/nfp_ethdev_vf.c b/drivers/net/nfp/nfp_ethdev_vf.c
index 88da593190..bd3745a5c5 100644
--- a/drivers/net/nfp/nfp_ethdev_vf.c
+++ b/drivers/net/nfp/nfp_ethdev_vf.c
@@ -162,14 +162,17 @@ nfp_netvf_close(struct rte_eth_dev *dev)
 {
 	struct nfp_net_hw *net_hw;
 	struct rte_pci_device *pci_dev;
+	struct nfp_net_hw_priv *hw_priv;
 
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
 
 	net_hw = dev->data->dev_private;
 	pci_dev = RTE_ETH_DEV_TO_PCI(dev);
+	hw_priv = dev->process_private;
 
 	rte_free(net_hw->eth_xstats_base);
+	rte_free(hw_priv);
 
 	/*
 	 * We assume that the DPDK application is stopping all the
@@ -255,6 +258,7 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 	uint64_t tx_bar_off = 0;
 	uint64_t rx_bar_off = 0;
 	struct rte_pci_device *pci_dev;
+	struct nfp_net_hw_priv *hw_priv;
 	const struct nfp_dev_info *dev_info;
 
 	port = eth_dev->data->port_id;
@@ -267,7 +271,6 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 	}
 
 	net_hw = eth_dev->data->dev_private;
-	net_hw->dev_info = dev_info;
 	hw = &net_hw->super;
 
 	hw->ctrl_bar = pci_dev->mem_resource[0].addr;
@@ -284,6 +287,17 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 
 	nfp_netvf_ethdev_ops_mount(net_hw, eth_dev);
 
+	hw_priv = rte_zmalloc(NULL, sizeof(*hw_priv), 0);
+	if (hw_priv == NULL) {
+		PMD_INIT_LOG(ERR, "Can not alloc memory for hw priv data");
+		err = -ENOMEM;
+		goto hw_priv_free;
+	}
+
+	hw_priv->dev_info = dev_info;
+
+	eth_dev->process_private = hw_priv;
+
 	/* For secondary processes, the primary has done all the work */
 	if (rte_eal_process_type() != RTE_PROC_PRIMARY)
 		return 0;
@@ -366,6 +380,8 @@ nfp_netvf_init(struct rte_eth_dev *eth_dev)
 
 free_xstats:
 	rte_free(net_hw->eth_xstats_base);
+hw_priv_free:
+	rte_free(hw_priv);
 
 	return err;
 }
diff --git a/drivers/net/nfp/nfp_net_common.c b/drivers/net/nfp/nfp_net_common.c
index 60d77b6178..8cc8b77318 100644
--- a/drivers/net/nfp/nfp_net_common.c
+++ b/drivers/net/nfp/nfp_net_common.c
@@ -1144,16 +1144,17 @@ nfp_net_xstats_reset(struct rte_eth_dev *dev)
 }
 
 void
-nfp_net_rx_desc_limits(struct nfp_net_hw *hw,
+nfp_net_rx_desc_limits(struct nfp_net_hw_priv *hw_priv,
 		uint16_t *min_rx_desc,
 		uint16_t *max_rx_desc)
 {
-	*max_rx_desc = hw->dev_info->max_qc_size;
-	*min_rx_desc = hw->dev_info->min_qc_size;
+	*max_rx_desc = hw_priv->dev_info->max_qc_size;
+	*min_rx_desc = hw_priv->dev_info->min_qc_size;
 }
 
 void
 nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
+		struct nfp_net_hw_priv *hw_priv,
 		uint16_t *min_tx_desc,
 		uint16_t *max_tx_desc)
 {
@@ -1164,8 +1165,8 @@ nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
 	else
 		tx_dpp = NFDK_TX_DESC_PER_SIMPLE_PKT;
 
-	*max_tx_desc = hw->dev_info->max_qc_size / tx_dpp;
-	*min_tx_desc = hw->dev_info->min_qc_size / tx_dpp;
+	*max_tx_desc = hw_priv->dev_info->max_qc_size / tx_dpp;
+	*min_tx_desc = hw_priv->dev_info->min_qc_size / tx_dpp;
 }
 
 int
@@ -1183,8 +1184,8 @@ nfp_net_infos_get(struct rte_eth_dev *dev, struct rte_eth_dev_info *dev_info)
 	hw = nfp_net_get_hw(dev);
 	hw_priv = dev->process_private;
 
-	nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
-	nfp_net_tx_desc_limits(hw, &min_tx_desc, &max_tx_desc);
+	nfp_net_rx_desc_limits(hw_priv, &min_rx_desc, &max_rx_desc);
+	nfp_net_tx_desc_limits(hw, hw_priv, &min_tx_desc, &max_tx_desc);
 
 	dev_info->max_rx_queues = (uint16_t)hw->max_rx_queues;
 	dev_info->max_tx_queues = (uint16_t)hw->max_tx_queues;
diff --git a/drivers/net/nfp/nfp_net_common.h b/drivers/net/nfp/nfp_net_common.h
index 8dbe2fb973..31deeb43ce 100644
--- a/drivers/net/nfp/nfp_net_common.h
+++ b/drivers/net/nfp/nfp_net_common.h
@@ -158,6 +158,9 @@ struct nfp_app_fw_nic {
 
 struct nfp_net_hw_priv {
 	struct nfp_pf_dev *pf_dev;
+
+	/** NFP ASIC params */
+	const struct nfp_dev_info *dev_info;
 };
 
 struct nfp_net_hw {
@@ -177,9 +180,6 @@ struct nfp_net_hw {
 	uint32_t rx_offset;
 	enum nfp_net_meta_format meta_format;
 
-	/** NFP ASIC params */
-	const struct nfp_dev_info *dev_info;
-
 	uint8_t *tx_bar;
 	uint8_t *rx_bar;
 
@@ -297,10 +297,11 @@ void nfp_net_close_rx_queue(struct rte_eth_dev *dev);
 void nfp_net_stop_tx_queue(struct rte_eth_dev *dev);
 void nfp_net_close_tx_queue(struct rte_eth_dev *dev);
 int nfp_net_set_vxlan_port(struct nfp_net_hw *hw, size_t idx, uint16_t port);
-void nfp_net_rx_desc_limits(struct nfp_net_hw *hw,
+void nfp_net_rx_desc_limits(struct nfp_net_hw_priv *hw_priv,
 		uint16_t *min_rx_desc,
 		uint16_t *max_rx_desc);
 void nfp_net_tx_desc_limits(struct nfp_net_hw *hw,
+		struct nfp_net_hw_priv *hw_priv,
 		uint16_t *min_tx_desc,
 		uint16_t *max_tx_desc);
 int nfp_net_check_dma_mask(struct nfp_net_hw *hw, char *name);
diff --git a/drivers/net/nfp/nfp_rxtx.c b/drivers/net/nfp/nfp_rxtx.c
index 12f362a4f4..8697c5d711 100644
--- a/drivers/net/nfp/nfp_rxtx.c
+++ b/drivers/net/nfp/nfp_rxtx.c
@@ -606,10 +606,12 @@ nfp_net_rx_queue_setup(struct rte_eth_dev *dev,
 	struct nfp_net_hw *hw;
 	struct nfp_net_rxq *rxq;
 	const struct rte_memzone *tz;
+	struct nfp_net_hw_priv *hw_priv;
 
 	hw = nfp_net_get_hw(dev);
+	hw_priv = dev->process_private;
 
-	nfp_net_rx_desc_limits(hw, &min_rx_desc, &max_rx_desc);
+	nfp_net_rx_desc_limits(hw_priv, &min_rx_desc, &max_rx_desc);
 
 	/* Validating number of descriptors */
 	rx_desc_sz = nb_desc * sizeof(struct nfp_net_rx_desc);
