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

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