diff --git a/drivers/net/nfp/flower/nfp_flower.c b/drivers/net/nfp/flower/nfp_flower.c
index f2e6eb6a6f..6b523d98b0 100644
--- a/drivers/net/nfp/flower/nfp_flower.c
+++ b/drivers/net/nfp/flower/nfp_flower.c
@@ -859,7 +859,7 @@ nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev,
 }
 
 int
-nfp_secondary_init_app_fw_flower(struct nfp_cpp *cpp)
+nfp_secondary_init_app_fw_flower(struct nfp_pf_dev *pf_dev)
 {
 	struct rte_eth_dev *eth_dev;
 	const char *port_name = "pf_vnic_eth_dev";
@@ -872,7 +872,7 @@ nfp_secondary_init_app_fw_flower(struct nfp_cpp *cpp)
 		return -ENODEV;
 	}
 
-	eth_dev->process_private = cpp;
+	eth_dev->process_private = pf_dev->cpp;
 	eth_dev->dev_ops = &nfp_flower_pf_vnic_ops;
 	eth_dev->rx_pkt_burst = nfp_net_recv_pkts;
 	eth_dev->tx_pkt_burst = nfp_flower_pf_xmit_pkts;
diff --git a/drivers/net/nfp/flower/nfp_flower.h b/drivers/net/nfp/flower/nfp_flower.h
index 220b714018..6f27c06acc 100644
--- a/drivers/net/nfp/flower/nfp_flower.h
+++ b/drivers/net/nfp/flower/nfp_flower.h
@@ -106,7 +106,7 @@ nfp_flower_support_decap_v2(const struct nfp_app_fw_flower *app_fw_flower)
 
 int nfp_init_app_fw_flower(struct nfp_pf_dev *pf_dev,
 		const struct nfp_dev_info *dev_info);
-int nfp_secondary_init_app_fw_flower(struct nfp_cpp *cpp);
+int nfp_secondary_init_app_fw_flower(struct nfp_pf_dev *pf_dev);
 bool nfp_flower_pf_dispatch_pkts(struct nfp_net_hw *hw,
 		struct rte_mbuf *mbuf,
 		uint32_t port_id);
diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 4fae2e5540..705465046c 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -1006,9 +1006,7 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
 }
 
 static int
-nfp_secondary_init_app_fw_nic(struct rte_pci_device *pci_dev,
-		struct nfp_rtsym_table *sym_tbl,
-		struct nfp_cpp *cpp)
+nfp_secondary_init_app_fw_nic(struct nfp_pf_dev *pf_dev)
 {
 	uint32_t i;
 	int err = 0;
@@ -1017,7 +1015,7 @@ nfp_secondary_init_app_fw_nic(struct rte_pci_device *pci_dev,
 	struct nfp_net_hw *hw;
 
 	/* Read the number of vNIC's created for the PF */
-	total_vnics = nfp_rtsym_read_le(sym_tbl, "nfd_cfg_pf0_num_ports", &err);
+	total_vnics = nfp_rtsym_read_le(pf_dev->sym_tbl, "nfd_cfg_pf0_num_ports", &err);
 	if (err != 0 || total_vnics == 0 || total_vnics > 8) {
 		PMD_INIT_LOG(ERR, "nfd_cfg_pf0_num_ports symbol with wrong value");
 		return -ENODEV;
@@ -1027,7 +1025,7 @@ nfp_secondary_init_app_fw_nic(struct rte_pci_device *pci_dev,
 		struct rte_eth_dev *eth_dev;
 		char port_name[RTE_ETH_NAME_MAX_LEN];
 		snprintf(port_name, sizeof(port_name), "%s_port%u",
-				pci_dev->device.name, i);
+				pf_dev->pci_dev->device.name, i);
 
 		PMD_INIT_LOG(DEBUG, "Secondary attaching to port %s", port_name);
 		eth_dev = rte_eth_dev_attach_secondary(port_name);
@@ -1037,7 +1035,7 @@ nfp_secondary_init_app_fw_nic(struct rte_pci_device *pci_dev,
 			break;
 		}
 
-		eth_dev->process_private = cpp;
+		eth_dev->process_private = pf_dev->cpp;
 		hw = eth_dev->data->dev_private;
 		nfp_net_ethdev_ops_mount(hw, eth_dev);
 
@@ -1057,7 +1055,9 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 {
 	int ret = 0;
 	struct nfp_cpp *cpp;
+	struct nfp_pf_dev *pf_dev;
 	enum nfp_app_fw_id app_fw_id;
+	char name[RTE_ETH_NAME_MAX_LEN];
 	struct nfp_rtsym_table *sym_tbl;
 	const struct nfp_dev_info *dev_info;
 
@@ -1075,6 +1075,14 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 		return -ENODEV;
 	}
 
+	/* Allocate memory for the PF "device" */
+	snprintf(name, sizeof(name), "nfp_pf%d", 0);
+	pf_dev = rte_zmalloc(name, sizeof(*pf_dev), 0);
+	if (pf_dev == NULL) {
+		PMD_INIT_LOG(ERR, "Can't allocate memory for the PF device");
+		return -ENOMEM;
+	}
+
 	/*
 	 * When device bound to UIO, the device could be used, by mistake,
 	 * by two DPDK apps, and the UIO driver does not avoid it. This
@@ -1089,7 +1097,8 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 
 	if (cpp == NULL) {
 		PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
-		return -EIO;
+		ret = -EIO;
+		goto pf_cleanup;
 	}
 
 	/*
@@ -1099,20 +1108,29 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 	sym_tbl = nfp_rtsym_table_read(cpp);
 	if (sym_tbl == NULL) {
 		PMD_INIT_LOG(ERR, "Something is wrong with the firmware symbol table");
-		return -EIO;
+		ret = -EIO;
+		goto pf_cleanup;
 	}
 
 	/* Read the app ID of the firmware loaded */
 	app_fw_id = nfp_rtsym_read_le(sym_tbl, "_pf0_net_app_id", &ret);
 	if (ret != 0) {
 		PMD_INIT_LOG(ERR, "Couldn't read app_fw_id from fw");
+		ret = -EIO;
 		goto sym_tbl_cleanup;
 	}
 
+	/* Populate the newly created PF device */
+	pf_dev->app_fw_id = app_fw_id;
+	pf_dev->cpp = cpp;
+	pf_dev->sym_tbl = sym_tbl;
+	pf_dev->pci_dev = pci_dev;
+
+	/* Call app specific init code now */
 	switch (app_fw_id) {
 	case NFP_APP_FW_CORE_NIC:
 		PMD_INIT_LOG(INFO, "Initializing coreNIC");
-		ret = nfp_secondary_init_app_fw_nic(pci_dev, sym_tbl, cpp);
+		ret = nfp_secondary_init_app_fw_nic(pf_dev);
 		if (ret != 0) {
 			PMD_INIT_LOG(ERR, "Could not initialize coreNIC!");
 			goto sym_tbl_cleanup;
@@ -1120,7 +1138,7 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 		break;
 	case NFP_APP_FW_FLOWER_NIC:
 		PMD_INIT_LOG(INFO, "Initializing Flower");
-		ret = nfp_secondary_init_app_fw_flower(cpp);
+		ret = nfp_secondary_init_app_fw_flower(pf_dev);
 		if (ret != 0) {
 			PMD_INIT_LOG(ERR, "Could not initialize Flower!");
 			goto sym_tbl_cleanup;
@@ -1132,8 +1150,12 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 		goto sym_tbl_cleanup;
 	}
 
+	return 0;
+
 sym_tbl_cleanup:
 	free(sym_tbl);
+pf_cleanup:
+	rte_free(pf_dev);
 
 	return ret;
 }
