Blame SOURCES/0002-net-nfp-use-new-CPP-interface.patch

a6040a
From 6a4e7e8918cd7f82e65f82219b1d1f936fe5895f Mon Sep 17 00:00:00 2001
a6040a
From: Alejandro Lucero <alejandro.lucero@netronome.com>
a6040a
Date: Thu, 5 Apr 2018 15:42:45 +0100
a6040a
Subject: [PATCH 2/3] net/nfp: use new CPP interface
a6040a
a6040a
PF PMD support was based on NSPU interface. This patch changes the
a6040a
PMD for using the new CPP user space interface which gives more
a6040a
flexibility for adding new functionalities.
a6040a
a6040a
This change just affects initialization with the datapath being the
a6040a
same than before.
a6040a
a6040a
Signed-off-by: Alejandro Lucero <alejandro.lucero@netronome.com>
a6040a
(cherry picked from commit 896c265ef954ed22b61b1980b554b8425b300eeb)
a6040a
---
a6040a
 drivers/net/nfp/Makefile      |  17 ++-
a6040a
 drivers/net/nfp/nfp_net.c     | 342 +++++++++++++++++++++++++++++-------------
a6040a
 drivers/net/nfp/nfp_net_pmd.h |  16 +-
a6040a
 3 files changed, 264 insertions(+), 111 deletions(-)
a6040a
a6040a
diff --git a/drivers/net/nfp/Makefile b/drivers/net/nfp/Makefile
a6040a
index 4ba066ac4..f71ecde6f 100644
a6040a
--- a/drivers/net/nfp/Makefile
a6040a
+++ b/drivers/net/nfp/Makefile
a6040a
@@ -48,11 +48,24 @@ EXPORT_MAP := rte_pmd_nfp_version.map
a6040a
 
a6040a
 LIBABIVER := 1
a6040a
 
a6040a
+VPATH += $(SRCDIR)/nfpcore
a6040a
+
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_cppcore.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_cpp_pcie_ops.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_mutex.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_resource.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_crc.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_mip.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nffw.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_hwinfo.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_rtsym.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp_cmds.c
a6040a
+SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nsp_eth.c
a6040a
+
a6040a
 #
a6040a
 # all source are stored in SRCS-y
a6040a
 #
a6040a
 SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_net.c
a6040a
-SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nfpu.c
a6040a
-SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp_nspu.c
a6040a
 
a6040a
 include $(RTE_SDK)/mk/rte.lib.mk
a6040a
diff --git a/drivers/net/nfp/nfp_net.c b/drivers/net/nfp/nfp_net.c
a6040a
index 0501156ba..b923d1269 100644
a6040a
--- a/drivers/net/nfp/nfp_net.c
a6040a
+++ b/drivers/net/nfp/nfp_net.c
a6040a
@@ -1,5 +1,5 @@
a6040a
 /*
a6040a
- * Copyright (c) 2014, 2015 Netronome Systems, Inc.
a6040a
+ * Copyright (c) 2014-2018 Netronome Systems, Inc.
a6040a
  * All rights reserved.
a6040a
  *
a6040a
  * Small portions derived from code Copyright(c) 2010-2015 Intel Corporation.
a6040a
@@ -55,7 +55,13 @@
a6040a
 #include <rte_alarm.h>
a6040a
 #include <rte_spinlock.h>
a6040a
 
a6040a
-#include "nfp_nfpu.h"
a6040a
+#include "nfpcore/nfp_cpp.h"
a6040a
+#include "nfpcore/nfp_nffw.h"
a6040a
+#include "nfpcore/nfp_hwinfo.h"
a6040a
+#include "nfpcore/nfp_mip.h"
a6040a
+#include "nfpcore/nfp_rtsym.h"
a6040a
+#include "nfpcore/nfp_nsp.h"
a6040a
+
a6040a
 #include "nfp_net_pmd.h"
a6040a
 #include "nfp_net_logs.h"
a6040a
 #include "nfp_net_ctrl.h"
a6040a
@@ -95,12 +101,8 @@ static void nfp_net_stop(struct rte_eth_dev *dev);
a6040a
 static uint16_t nfp_net_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
a6040a
 				  uint16_t nb_pkts);
a6040a
 
a6040a
-/*
a6040a
- * The offset of the queue controller queues in the PCIe Target. These
a6040a
- * happen to be at the same offset on the NFP6000 and the NFP3200 so
a6040a
- * we use a single macro here.
a6040a
- */
a6040a
-#define NFP_PCIE_QUEUE(_q)	(0x800 * ((_q) & 0xff))
a6040a
+/* The offset of the queue controller queues in the PCIe Target */
a6040a
+#define NFP_PCIE_QUEUE(_q) (0x80000 + (NFP_QCP_QUEUE_ADDR_SZ * ((_q) & 0xff)))
a6040a
 
a6040a
 /* Maximum value which can be added to a queue with one transaction */
a6040a
 #define NFP_QCP_MAX_ADD	0x7f
a6040a
@@ -618,47 +620,29 @@ nfp_net_cfg_queue_setup(struct nfp_net_hw *hw)
a6040a
 #define ETH_ADDR_LEN	6
a6040a
 
a6040a
 static void
a6040a
-nfp_eth_copy_mac_reverse(uint8_t *dst, const uint8_t *src)
a6040a
+nfp_eth_copy_mac(uint8_t *dst, const uint8_t *src)
a6040a
 {
a6040a
 	int i;
a6040a
 
a6040a
 	for (i = 0; i < ETH_ADDR_LEN; i++)
a6040a
-		dst[ETH_ADDR_LEN - i - 1] = src[i];
a6040a
+		dst[i] = src[i];
a6040a
 }
a6040a
 
a6040a
 static int
a6040a
 nfp_net_pf_read_mac(struct nfp_net_hw *hw, int port)
a6040a
 {
a6040a
-	union eth_table_entry *entry;
a6040a
-	int idx, i;
a6040a
-
a6040a
-	idx = port;
a6040a
-	entry = hw->eth_table;
a6040a
-
a6040a
-	/* Reading NFP ethernet table obtained before */
a6040a
-	for (i = 0; i < NSP_ETH_MAX_COUNT; i++) {
a6040a
-		if (!(entry->port & NSP_ETH_PORT_LANES_MASK)) {
a6040a
-			/* port not in use */
a6040a
-			entry++;
a6040a
-			continue;
a6040a
-		}
a6040a
-		if (idx == 0)
a6040a
-			break;
a6040a
-		idx--;
a6040a
-		entry++;
a6040a
-	}
a6040a
-
a6040a
-	if (i == NSP_ETH_MAX_COUNT)
a6040a
-		return -EINVAL;
a6040a
+	struct nfp_eth_table *nfp_eth_table;
a6040a
 
a6040a
+	nfp_eth_table = nfp_eth_read_ports(hw->cpp);
a6040a
 	/*
a6040a
 	 * hw points to port0 private data. We need hw now pointing to
a6040a
 	 * right port.
a6040a
 	 */
a6040a
 	hw += port;
a6040a
-	nfp_eth_copy_mac_reverse((uint8_t *)&hw->mac_addr,
a6040a
-				 (uint8_t *)&entry->mac_addr);
a6040a
+	nfp_eth_copy_mac((uint8_t *)&hw->mac_addr,
a6040a
+			 (uint8_t *)&nfp_eth_table->ports[port].mac_addr);
a6040a
 
a6040a
+	free(nfp_eth_table);
a6040a
 	return 0;
a6040a
 }
a6040a
 
a6040a
@@ -809,7 +793,7 @@ nfp_net_start(struct rte_eth_dev *dev)
a6040a
 
a6040a
 	if (hw->is_pf)
a6040a
 		/* Configure the physical port up */
a6040a
-		nfp_nsp_eth_config(hw->nspu_desc, hw->pf_port_idx, 1);
a6040a
+		nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 1);
a6040a
 
a6040a
 	hw->ctrl = new_ctrl;
a6040a
 
a6040a
@@ -860,7 +844,7 @@ nfp_net_stop(struct rte_eth_dev *dev)
a6040a
 
a6040a
 	if (hw->is_pf)
a6040a
 		/* Configure the physical port down */
a6040a
-		nfp_nsp_eth_config(hw->nspu_desc, hw->pf_port_idx, 0);
a6040a
+		nfp_eth_set_configured(hw->cpp, hw->pf_port_idx, 0);
a6040a
 }
a6040a
 
a6040a
 /* Reset and stop device. The device can not be restarted. */
a6040a
@@ -2633,10 +2617,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	uint64_t tx_bar_off = 0, rx_bar_off = 0;
a6040a
 	uint32_t start_q;
a6040a
 	int stride = 4;
a6040a
-
a6040a
-	nspu_desc_t *nspu_desc = NULL;
a6040a
-	uint64_t bar_offset;
a6040a
 	int port = 0;
a6040a
+	int err;
a6040a
 
a6040a
 	PMD_INIT_FUNC_TRACE();
a6040a
 
a6040a
@@ -2657,7 +2639,6 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 
a6040a
 		/* This points to the specific port private data */
a6040a
 		hw = &hwport0[port];
a6040a
-		hw->pf_port_idx = port;
a6040a
 	} else {
a6040a
 		hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
a6040a
 		hwport0 = 0;
a6040a
@@ -2691,19 +2672,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	}
a6040a
 
a6040a
 	if (hw->is_pf && port == 0) {
a6040a
-		nspu_desc = hw->nspu_desc;
a6040a
-
a6040a
-		if (nfp_nsp_map_ctrl_bar(nspu_desc, &bar_offset) != 0) {
a6040a
-			/*
a6040a
-			 * A firmware should be there after PF probe so this
a6040a
-			 * should not happen.
a6040a
-			 */
a6040a
-			RTE_LOG(ERR, PMD, "PF BAR symbol resolution failed\n");
a6040a
-			return -ENODEV;
a6040a
+		hw->ctrl_bar = nfp_rtsym_map(hw->sym_tbl, "_pf0_net_bar0",
a6040a
+					     hw->total_ports * 32768,
a6040a
+					     &hw->ctrl_area);
a6040a
+		if (!hw->ctrl_bar) {
a6040a
+			printf("nfp_rtsym_map fails for _pf0_net_ctrl_bar\n");
a6040a
+			return -EIO;
a6040a
 		}
a6040a
 
a6040a
-		/* vNIC PF control BAR is a subset of PF PCI device BAR */
a6040a
-		hw->ctrl_bar += bar_offset;
a6040a
 		PMD_INIT_LOG(DEBUG, "ctrl bar: %p\n", hw->ctrl_bar);
a6040a
 	}
a6040a
 
a6040a
@@ -2727,13 +2703,14 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	case PCI_DEVICE_ID_NFP6000_PF_NIC:
a6040a
 	case PCI_DEVICE_ID_NFP6000_VF_NIC:
a6040a
 		start_q = nn_cfg_readl(hw, NFP_NET_CFG_START_TXQ);
a6040a
-		tx_bar_off = NFP_PCIE_QUEUE(start_q);
a6040a
+		tx_bar_off = start_q * NFP_QCP_QUEUE_ADDR_SZ;
a6040a
 		start_q = nn_cfg_readl(hw, NFP_NET_CFG_START_RXQ);
a6040a
-		rx_bar_off = NFP_PCIE_QUEUE(start_q);
a6040a
+		rx_bar_off = start_q * NFP_QCP_QUEUE_ADDR_SZ;
a6040a
 		break;
a6040a
 	default:
a6040a
 		RTE_LOG(ERR, PMD, "nfp_net: no device ID matching\n");
a6040a
-		return -ENODEV;
a6040a
+		err = -ENODEV;
a6040a
+		goto dev_err_ctrl_map;
a6040a
 	}
a6040a
 
a6040a
 	PMD_INIT_LOG(DEBUG, "tx_bar_off: 0x%" PRIx64 "\n", tx_bar_off);
a6040a
@@ -2741,17 +2718,19 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 
a6040a
 	if (hw->is_pf && port == 0) {
a6040a
 		/* configure access to tx/rx vNIC BARs */
a6040a
-		nfp_nsp_map_queues_bar(nspu_desc, &bar_offset);
a6040a
-		PMD_INIT_LOG(DEBUG, "tx/rx bar_offset: %" PRIx64 "\n",
a6040a
-				    bar_offset);
a6040a
-		hwport0->hw_queues = (uint8_t *)pci_dev->mem_resource[0].addr;
a6040a
-
a6040a
-		/* vNIC PF tx/rx BARs are a subset of PF PCI device */
a6040a
-		hwport0->hw_queues += bar_offset;
a6040a
+		hwport0->hw_queues = nfp_cpp_map_area(hw->cpp, 0, 0,
a6040a
+						      NFP_PCIE_QUEUE(0),
a6040a
+						      NFP_QCP_QUEUE_AREA_SZ,
a6040a
+						      &hw->hwqueues_area);
a6040a
+
a6040a
+		if (!hwport0->hw_queues) {
a6040a
+			printf("nfp_rtsym_map fails for net.qc\n");
a6040a
+			err = -EIO;
a6040a
+			goto dev_err_ctrl_map;
a6040a
+		}
a6040a
 
a6040a
-		/* Lets seize the chance to read eth table from hw */
a6040a
-		if (nfp_nsp_eth_read_table(nspu_desc, &hw->eth_table))
a6040a
-			return -ENODEV;
a6040a
+		PMD_INIT_LOG(DEBUG, "tx/rx bar address: 0x%p\n",
a6040a
+				    hwport0->hw_queues);
a6040a
 	}
a6040a
 
a6040a
 	if (hw->is_pf) {
a6040a
@@ -2811,7 +2790,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	eth_dev->data->mac_addrs = rte_zmalloc("mac_addr", ETHER_ADDR_LEN, 0);
a6040a
 	if (eth_dev->data->mac_addrs == NULL) {
a6040a
 		PMD_INIT_LOG(ERR, "Failed to space for MAC address");
a6040a
-		return -ENOMEM;
a6040a
+		err = -ENOMEM;
a6040a
+		goto dev_err_queues_map;
a6040a
 	}
a6040a
 
a6040a
 	if (hw->is_pf) {
a6040a
@@ -2822,6 +2802,8 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	}
a6040a
 
a6040a
 	if (!is_valid_assigned_ether_addr((struct ether_addr *)&hw->mac_addr)) {
a6040a
+		PMD_INIT_LOG(INFO, "Using random mac address for port %d\n",
a6040a
+				   port);
a6040a
 		/* Using random mac addresses for VFs */
a6040a
 		eth_random_addr(&hw->mac_addr[0]);
a6040a
 		nfp_net_write_mac(hw, (uint8_t *)&hw->mac_addr);
a6040a
@@ -2850,11 +2832,19 @@ nfp_net_init(struct rte_eth_dev *eth_dev)
a6040a
 	nfp_net_stats_reset(eth_dev);
a6040a
 
a6040a
 	return 0;
a6040a
+
a6040a
+dev_err_queues_map:
a6040a
+		nfp_cpp_area_free(hw->hwqueues_area);
a6040a
+dev_err_ctrl_map:
a6040a
+		nfp_cpp_area_free(hw->ctrl_area);
a6040a
+
a6040a
+	return err;
a6040a
 }
a6040a
 
a6040a
 static int
a6040a
 nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
a6040a
-		  nfpu_desc_t *nfpu_desc, void **priv)
a6040a
+		  struct nfp_cpp *cpp, struct nfp_hwinfo *hwinfo,
a6040a
+		  int phys_port, struct nfp_rtsym_table *sym_tbl, void **priv)
a6040a
 {
a6040a
 	struct rte_eth_dev *eth_dev;
a6040a
 	struct nfp_net_hw *hw;
a6040a
@@ -2892,12 +2882,16 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
a6040a
 	 * Then dev_private is adjusted per port.
a6040a
 	 */
a6040a
 	hw = (struct nfp_net_hw *)(eth_dev->data->dev_private) + port;
a6040a
-	hw->nspu_desc = nfpu_desc->nspu;
a6040a
-	hw->nfpu_desc = nfpu_desc;
a6040a
+	hw->cpp = cpp;
a6040a
+	hw->hwinfo = hwinfo;
a6040a
+	hw->sym_tbl = sym_tbl;
a6040a
+	hw->pf_port_idx = phys_port;
a6040a
 	hw->is_pf = 1;
a6040a
 	if (ports > 1)
a6040a
 		hw->pf_multiport_enabled = 1;
a6040a
 
a6040a
+	hw->total_ports = ports;
a6040a
+
a6040a
 	eth_dev->device = &dev->device;
a6040a
 	rte_eth_copy_pci_info(eth_dev, dev);
a6040a
 
a6040a
@@ -2911,55 +2905,191 @@ nfp_pf_create_dev(struct rte_pci_device *dev, int port, int ports,
a6040a
 	return ret;
a6040a
 }
a6040a
 
a6040a
+#define DEFAULT_FW_PATH       "/lib/firmware/netronome"
a6040a
+
a6040a
+static int
a6040a
+nfp_fw_upload(struct rte_pci_device *dev, struct nfp_nsp *nsp, char *card)
a6040a
+{
a6040a
+	struct nfp_cpp *cpp = nsp->cpp;
a6040a
+	int fw_f;
a6040a
+	char *fw_buf;
a6040a
+	char fw_name[100];
a6040a
+	char serial[100];
a6040a
+	struct stat file_stat;
a6040a
+	off_t fsize, bytes;
a6040a
+
a6040a
+	/* Looking for firmware file in order of priority */
a6040a
+
a6040a
+	/* First try to find a firmware image specific for this device */
a6040a
+	sprintf(serial, "serial-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x",
a6040a
+		cpp->serial[0], cpp->serial[1], cpp->serial[2], cpp->serial[3],
a6040a
+		cpp->serial[4], cpp->serial[5], cpp->interface >> 8,
a6040a
+		cpp->interface & 0xff);
a6040a
+
a6040a
+	sprintf(fw_name, "%s/%s.nffw", DEFAULT_FW_PATH, serial);
a6040a
+
a6040a
+	RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
a6040a
+	fw_f = open(fw_name, O_RDONLY);
a6040a
+	if (fw_f > 0)
a6040a
+		goto read_fw;
a6040a
+
a6040a
+	/* Then try the PCI name */
a6040a
+	sprintf(fw_name, "%s/pci-%s.nffw", DEFAULT_FW_PATH, dev->device.name);
a6040a
+
a6040a
+	RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
a6040a
+	fw_f = open(fw_name, O_RDONLY);
a6040a
+	if (fw_f > 0)
a6040a
+		goto read_fw;
a6040a
+
a6040a
+	/* Finally try the card type and media */
a6040a
+	sprintf(fw_name, "%s/%s", DEFAULT_FW_PATH, card);
a6040a
+	RTE_LOG(DEBUG, PMD, "Trying with fw file: %s\n", fw_name);
a6040a
+	fw_f = open(fw_name, O_RDONLY);
a6040a
+	if (fw_f < 0) {
a6040a
+		RTE_LOG(INFO, PMD, "Firmware file %s not found.", fw_name);
a6040a
+		return -ENOENT;
a6040a
+	}
a6040a
+
a6040a
+read_fw:
a6040a
+	if (fstat(fw_f, &file_stat) < 0) {
a6040a
+		RTE_LOG(INFO, PMD, "Firmware file %s size is unknown", fw_name);
a6040a
+		close(fw_f);
a6040a
+		return -ENOENT;
a6040a
+	}
a6040a
+
a6040a
+	fsize = file_stat.st_size;
a6040a
+	RTE_LOG(INFO, PMD, "Firmware file found at %s with size: %" PRIu64 "\n",
a6040a
+			    fw_name, (uint64_t)fsize);
a6040a
+
a6040a
+	fw_buf = malloc((size_t)fsize);
a6040a
+	if (!fw_buf) {
a6040a
+		RTE_LOG(INFO, PMD, "malloc failed for fw buffer");
a6040a
+		close(fw_f);
a6040a
+		return -ENOMEM;
a6040a
+	}
a6040a
+	memset(fw_buf, 0, fsize);
a6040a
+
a6040a
+	bytes = read(fw_f, fw_buf, fsize);
a6040a
+	if (bytes != fsize) {
a6040a
+		RTE_LOG(INFO, PMD, "Reading fw to buffer failed.\n"
a6040a
+				   "Just %" PRIu64 " of %" PRIu64 " bytes read",
a6040a
+				   (uint64_t)bytes, (uint64_t)fsize);
a6040a
+		free(fw_buf);
a6040a
+		close(fw_f);
a6040a
+		return -EIO;
a6040a
+	}
a6040a
+
a6040a
+	RTE_LOG(INFO, PMD, "Uploading the firmware ...");
a6040a
+	nfp_nsp_load_fw(nsp, fw_buf, bytes);
a6040a
+	RTE_LOG(INFO, PMD, "Done");
a6040a
+
a6040a
+	free(fw_buf);
a6040a
+	close(fw_f);
a6040a
+
a6040a
+	return 0;
a6040a
+}
a6040a
+
a6040a
+static int
a6040a
+nfp_fw_setup(struct rte_pci_device *dev, struct nfp_cpp *cpp,
a6040a
+	     struct nfp_eth_table *nfp_eth_table, struct nfp_hwinfo *hwinfo)
a6040a
+{
a6040a
+	struct nfp_nsp *nsp;
a6040a
+	const char *nfp_fw_model;
a6040a
+	char card_desc[100];
a6040a
+	int err = 0;
a6040a
+
a6040a
+	nfp_fw_model = nfp_hwinfo_lookup(hwinfo, "assembly.partno");
a6040a
+
a6040a
+	if (nfp_fw_model) {
a6040a
+		RTE_LOG(INFO, PMD, "firmware model found: %s\n", nfp_fw_model);
a6040a
+	} else {
a6040a
+		RTE_LOG(ERR, PMD, "firmware model NOT found\n");
a6040a
+		return -EIO;
a6040a
+	}
a6040a
+
a6040a
+	if (nfp_eth_table->count == 0 || nfp_eth_table->count > 8) {
a6040a
+		RTE_LOG(ERR, PMD, "NFP ethernet table reports wrong ports: %u\n",
a6040a
+		       nfp_eth_table->count);
a6040a
+		return -EIO;
a6040a
+	}
a6040a
+
a6040a
+	RTE_LOG(INFO, PMD, "NFP ethernet port table reports %u ports\n",
a6040a
+			   nfp_eth_table->count);
a6040a
+
a6040a
+	RTE_LOG(INFO, PMD, "Port speed: %u\n", nfp_eth_table->ports[0].speed);
a6040a
+
a6040a
+	sprintf(card_desc, "nic_%s_%dx%d.nffw", nfp_fw_model,
a6040a
+		nfp_eth_table->count, nfp_eth_table->ports[0].speed / 1000);
a6040a
+
a6040a
+	nsp = nfp_nsp_open(cpp);
a6040a
+	if (!nsp) {
a6040a
+		RTE_LOG(ERR, PMD, "NFP error when obtaining NSP handle\n");
a6040a
+		return -EIO;
a6040a
+	}
a6040a
+
a6040a
+	nfp_nsp_device_soft_reset(nsp);
a6040a
+	err = nfp_fw_upload(dev, nsp, card_desc);
a6040a
+
a6040a
+	nfp_nsp_close(nsp);
a6040a
+	return err;
a6040a
+}
a6040a
+
a6040a
 static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
a6040a
 			    struct rte_pci_device *dev)
a6040a
 {
a6040a
-	nfpu_desc_t *nfpu_desc;
a6040a
-	nspu_desc_t *nspu_desc;
a6040a
-	uint64_t offset_symbol;
a6040a
-	uint8_t *bar_offset;
a6040a
-	int major, minor;
a6040a
+	struct nfp_cpp *cpp;
a6040a
+	struct nfp_hwinfo *hwinfo;
a6040a
+	struct nfp_rtsym_table *sym_tbl;
a6040a
+	struct nfp_eth_table *nfp_eth_table = NULL;
a6040a
 	int total_ports;
a6040a
 	void *priv = 0;
a6040a
 	int ret = -ENODEV;
a6040a
+	int err;
a6040a
 	int i;
a6040a
 
a6040a
 	if (!dev)
a6040a
 		return ret;
a6040a
 
a6040a
-	nfpu_desc = rte_malloc("nfp nfpu", sizeof(nfpu_desc_t), 0);
a6040a
-	if (!nfpu_desc)
a6040a
-		return -ENOMEM;
a6040a
-
a6040a
-	if (nfpu_open(dev, nfpu_desc, 0) < 0) {
a6040a
-		RTE_LOG(ERR, PMD,
a6040a
-			"nfpu_open failed\n");
a6040a
-		goto nfpu_error;
a6040a
+	cpp = nfp_cpp_from_device_name(dev->device.name);
a6040a
+	if (!cpp) {
a6040a
+		RTE_LOG(ERR, PMD, "A CPP handle can not be obtained");
a6040a
+		ret = -EIO;
a6040a
+		goto error;
a6040a
 	}
a6040a
 
a6040a
-	nspu_desc = nfpu_desc->nspu;
a6040a
+	hwinfo = nfp_hwinfo_read(cpp);
a6040a
+	if (!hwinfo) {
a6040a
+		RTE_LOG(ERR, PMD, "Error reading hwinfo table");
a6040a
+		return -EIO;
a6040a
+	}
a6040a
 
a6040a
+	nfp_eth_table = nfp_eth_read_ports(cpp);
a6040a
+	if (!nfp_eth_table) {
a6040a
+		RTE_LOG(ERR, PMD, "Error reading NFP ethernet table\n");
a6040a
+		return -EIO;
a6040a
+	}
a6040a
 
a6040a
-	/* Check NSP ABI version */
a6040a
-	if (nfp_nsp_get_abi_version(nspu_desc, &major, &minor) < 0) {
a6040a
-		RTE_LOG(INFO, PMD, "NFP NSP not present\n");
a6040a
+	if (nfp_fw_setup(dev, cpp, nfp_eth_table, hwinfo)) {
a6040a
+		RTE_LOG(INFO, PMD, "Error when uploading firmware\n");
a6040a
+		ret = -EIO;
a6040a
 		goto error;
a6040a
 	}
a6040a
-	PMD_INIT_LOG(INFO, "nspu ABI version: %d.%d\n", major, minor);
a6040a
 
a6040a
-	if ((major == 0) && (minor < 20)) {
a6040a
-		RTE_LOG(INFO, PMD, "NFP NSP ABI version too old. Required 0.20 or higher\n");
a6040a
+	/* Now the symbol table should be there */
a6040a
+	sym_tbl = nfp_rtsym_table_read(cpp);
a6040a
+	if (!sym_tbl) {
a6040a
+		RTE_LOG(ERR, PMD, "Something is wrong with the firmware"
a6040a
+				" symbol table");
a6040a
+		ret = -EIO;
a6040a
 		goto error;
a6040a
 	}
a6040a
 
a6040a
-	ret = nfp_nsp_fw_setup(nspu_desc, "nfd_cfg_pf0_num_ports",
a6040a
-			       &offset_symbol);
a6040a
-	if (ret)
a6040a
+	total_ports = nfp_rtsym_read_le(sym_tbl, "nfd_cfg_pf0_num_ports", &err;;
a6040a
+	if (total_ports != (int)nfp_eth_table->count) {
a6040a
+		RTE_LOG(ERR, PMD, "Inconsistent number of ports\n");
a6040a
+		ret = -EIO;
a6040a
 		goto error;
a6040a
-
a6040a
-	bar_offset = (uint8_t *)dev->mem_resource[0].addr;
a6040a
-	bar_offset += offset_symbol;
a6040a
-	total_ports = (uint32_t)*bar_offset;
a6040a
+	}
a6040a
 	PMD_INIT_LOG(INFO, "Total pf ports: %d\n", total_ports);
a6040a
 
a6040a
 	if (total_ports <= 0 || total_ports > 8) {
a6040a
@@ -2969,18 +3099,15 @@ static int nfp_pf_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
a6040a
 	}
a6040a
 
a6040a
 	for (i = 0; i < total_ports; i++) {
a6040a
-		ret = nfp_pf_create_dev(dev, i, total_ports, nfpu_desc, &priv;;
a6040a
+		ret = nfp_pf_create_dev(dev, i, total_ports, cpp, hwinfo,
a6040a
+					nfp_eth_table->ports[i].index,
a6040a
+					sym_tbl, &priv;;
a6040a
 		if (ret)
a6040a
-			goto error;
a6040a
+			break;
a6040a
 	}
a6040a
 
a6040a
-	return 0;
a6040a
-
a6040a
 error:
a6040a
-	nfpu_close(nfpu_desc);
a6040a
-nfpu_error:
a6040a
-	rte_free(nfpu_desc);
a6040a
-
a6040a
+	free(nfp_eth_table);
a6040a
 	return ret;
a6040a
 }
a6040a
 
a6040a
@@ -3025,8 +3152,19 @@ static int eth_nfp_pci_remove(struct rte_pci_device *pci_dev)
a6040a
 	if ((pci_dev->id.device_id == PCI_DEVICE_ID_NFP4000_PF_NIC) ||
a6040a
 	    (pci_dev->id.device_id == PCI_DEVICE_ID_NFP6000_PF_NIC)) {
a6040a
 		port = get_pf_port_number(eth_dev->data->name);
a6040a
+		/*
a6040a
+		 * hotplug is not possible with multiport PF although freeing
a6040a
+		 * data structures can be done for first port.
a6040a
+		 */
a6040a
+		if (port != 0)
a6040a
+			return -ENOTSUP;
a6040a
 		hwport0 = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
a6040a
 		hw = &hwport0[port];
a6040a
+		nfp_cpp_area_free(hw->ctrl_area);
a6040a
+		nfp_cpp_area_free(hw->hwqueues_area);
a6040a
+		free(hw->hwinfo);
a6040a
+		free(hw->sym_tbl);
a6040a
+		nfp_cpp_free(hw->cpp);
a6040a
 	} else {
a6040a
 		hw = NFP_NET_DEV_PRIVATE_TO_HW(eth_dev->data->dev_private);
a6040a
 	}
a6040a
diff --git a/drivers/net/nfp/nfp_net_pmd.h b/drivers/net/nfp/nfp_net_pmd.h
a6040a
index 1ae0ea626..097c871b5 100644
a6040a
--- a/drivers/net/nfp/nfp_net_pmd.h
a6040a
+++ b/drivers/net/nfp/nfp_net_pmd.h
a6040a
@@ -1,5 +1,5 @@
a6040a
 /*
a6040a
- * Copyright (c) 2014, 2015 Netronome Systems, Inc.
a6040a
+ * Copyright (c) 2014-2018 Netronome Systems, Inc.
a6040a
  * All rights reserved.
a6040a
  *
a6040a
  * Redistribution and use in source and binary forms, with or without
a6040a
@@ -63,6 +63,7 @@ struct nfp_net_adapter;
a6040a
 #define NFP_NET_CRTL_BAR        0
a6040a
 #define NFP_NET_TX_BAR          2
a6040a
 #define NFP_NET_RX_BAR          2
a6040a
+#define NFP_QCP_QUEUE_AREA_SZ			0x80000
a6040a
 
a6040a
 /* Macros for accessing the Queue Controller Peripheral 'CSRs' */
a6040a
 #define NFP_QCP_QUEUE_OFF(_x)                 ((_x) * 0x800)
a6040a
@@ -430,20 +431,21 @@ struct nfp_net_hw {
a6040a
 	/* Records starting point for counters */
a6040a
 	struct rte_eth_stats eth_stats_base;
a6040a
 
a6040a
-#ifdef NFP_NET_LIBNFP
a6040a
 	struct nfp_cpp *cpp;
a6040a
 	struct nfp_cpp_area *ctrl_area;
a6040a
-	struct nfp_cpp_area *tx_area;
a6040a
-	struct nfp_cpp_area *rx_area;
a6040a
+	struct nfp_cpp_area *hwqueues_area;
a6040a
 	struct nfp_cpp_area *msix_area;
a6040a
-#endif
a6040a
+
a6040a
 	uint8_t *hw_queues;
a6040a
 	uint8_t is_pf;
a6040a
 	uint8_t pf_port_idx;
a6040a
 	uint8_t pf_multiport_enabled;
a6040a
+	uint8_t total_ports;
a6040a
+
a6040a
 	union eth_table_entry *eth_table;
a6040a
-	nspu_desc_t *nspu_desc;
a6040a
-	nfpu_desc_t *nfpu_desc;
a6040a
+
a6040a
+	struct nfp_hwinfo *hwinfo;
a6040a
+	struct nfp_rtsym_table *sym_tbl;
a6040a
 };
a6040a
 
a6040a
 struct nfp_net_adapter {
a6040a
-- 
a6040a
2.14.3
a6040a