From mboxrd@z Thu Jan  1 00:00:00 1970
Return-Path: <dev-bounces@dpdk.org>
Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124])
	by inbox.dpdk.org (Postfix) with ESMTP id 12F9D425E2;
	Wed, 20 Sep 2023 03:30:09 +0200 (CEST)
Received: from mails.dpdk.org (localhost [127.0.0.1])
	by mails.dpdk.org (Postfix) with ESMTP id EFE0C402BF;
	Wed, 20 Sep 2023 03:30:08 +0200 (CEST)
Received: from NAM11-BN8-obe.outbound.protection.outlook.com
 (mail-bn8nam11on2100.outbound.protection.outlook.com [40.107.236.100])
 by mails.dpdk.org (Postfix) with ESMTP id BC26340277
 for <dev@dpdk.org>; Wed, 20 Sep 2023 03:30:07 +0200 (CEST)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=LYjvT3Ga1alniCv/HiTBqg2u3jMBFjRgaV5M1aKVr/fqFxC32HpppEpxLxg0tw7QUpB0I+iF865PLVV+5nG0XNQDVD/cBWrBj7JBSkAy04/WKU2RNxmjMrjWdG9KexUz9erNIVlkywkUgtef8KvYt2CCHaXLgjNULb3L8p9VTPO0BjVZy4+yGkcEH20jRZNGSYceY0+Btb/pyqYZqAyppP0wAs9y672w9iYVz3zaW405nkGOsNCHQlJnrXhi80vUKbmEXblFdjn7i07aiyXzEKr26lRN+Eucnhz8VHABkNKjq2QsL9jmRqL57Ad05QsZYyIJBMLk7je5SJ/AOG82dg==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; 
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1;
 bh=HRCP/IlU5DFAOmCj1iU2p4yGS9BG66ezsatrYpOwc08=;
 b=HEXRFoEYLmkTKiAy1WEWYiS+CBn4HxoOBT+3xDKEFAVcodifkM2/2qIQlN06Mzkqx8cC2PVnQtiuUS6HFD1XvQam4A/0wMBkCUqEH48yv4hLb1jwYLsUtf4Z/gWmi6Zv3pNWafw6DGE7AitnII14bfHM/kXrImBR/GGVGgcOBqG8HzboogH3yX70Q/eGq/WoGcE4pjf0D1we1StyRQNr2ruXPZ4saq2mvErFz3W4zXlycfz7iCAFYkGe/6W3byX8KM8jFvkk7KSRqnmPrrOoETJX8E8RfpdYH7jRDQQI7HA22rTB4QkfPNbRbBU2AwX9YJBwaSSs8by+hFK4CFPAFw==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=corigine.com; dmarc=pass action=none header.from=corigine.com;
 dkim=pass header.d=corigine.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
 d=corigine.onmicrosoft.com; s=selector2-corigine-onmicrosoft-com;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=HRCP/IlU5DFAOmCj1iU2p4yGS9BG66ezsatrYpOwc08=;
 b=GsKd+duySuk6sAion6BH571055pr0Lifkk+sROMKj9iQbDEJsCl9QZXsSzIpmo/bZhGhkfeTa81rh3TuZRLto+y0Fw7vO6rAXaEDLTU6njKMYP5sL2MizhL6+x0YxUKqfhOHVYvMdyqwxKYj15+SO0g1FPd1YfD1Us8NcSavpjE=
Authentication-Results: dkim=none (message not signed)
 header.d=none;dmarc=none action=none header.from=corigine.com;
Received: from SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5)
 by CH2PR13MB3623.namprd13.prod.outlook.com (2603:10b6:610:98::16)
 with Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6813.19; Wed, 20 Sep
 2023 01:29:50 +0000
Received: from SJ0PR13MB5545.namprd13.prod.outlook.com
 ([fe80::7a1c:2887:348a:84bd]) by SJ0PR13MB5545.namprd13.prod.outlook.com
 ([fe80::7a1c:2887:348a:84bd%6]) with mapi id 15.20.6792.026; Wed, 20 Sep 2023
 01:29:50 +0000
From: Chaoyong He <chaoyong.he@corigine.com>
To: dev@dpdk.org
Cc: oss-drivers@corigine.com,
	Chaoyong He <chaoyong.he@corigine.com>
Subject: [PATCH v5 26/26] net/nfp: extend the usage of nfp BAR from 8 to 24
Date: Wed, 20 Sep 2023 09:29:33 +0800
Message-Id: <20230920012933.46389-1-chaoyong.he@corigine.com>
X-Mailer: git-send-email 2.39.1
In-Reply-To: <20230918024612.1600536-1-chaoyong.he@corigine.com>
References: <20230918024612.1600536-1-chaoyong.he@corigine.com>
Content-Transfer-Encoding: 8bit
Content-Type: text/plain
X-ClientProxiedBy: SJ0PR05CA0014.namprd05.prod.outlook.com
 (2603:10b6:a03:33b::19) To SJ0PR13MB5545.namprd13.prod.outlook.com
 (2603:10b6:a03:424::5)
MIME-Version: 1.0
X-MS-PublicTrafficType: Email
X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|CH2PR13MB3623:EE_
X-MS-Office365-Filtering-Correlation-Id: 8a8d477a-26dd-49c0-6fee-08dbb9791512
X-MS-Exchange-SenderADCheck: 1
X-MS-Exchange-AntiSpam-Relay: 0
X-Microsoft-Antispam: BCL:0;
X-Microsoft-Antispam-Message-Info: kHu4WJQNIQWBqyCGHoejbQLnDGjsXBJDYkBy6dKYsXmcTcBYxi/0H+9CAK9nLq7AhUaV0eyDDPh+ZK/J1Qwx3lENpqYdFecLRv6rQNVG1uO5JhYDBEANa5k6fhT9SBblr7Qzyl+7aWigDHSfWG76afuLYgeZsacCnzxVjHxglxIJ44osq30yaR5Cjyae5uNUZ1gu8464bAv6SfCp0raHsajqqsukDzjhjrZeojDpQo8RMSJdEzV7aqSCNFo0h25oDx4G+kXd8VtlA8W2J3zzE6YaG3WQidKlUHiF8EFZslhdHnK973oKU6s+58zddeoaLF1Q40YnIx5cJqKdDtCrdv17NEIgy9CqEfCzfoxTDQHoECQU+pLpLwPUbYwGumKilYVLhBvvjdUS9IRG06RyNUMhoRkbiw3AQWmvUwk1L7k+thM3FLTIRc2aTzZQpKRX7yeBbDjdc+++7H5YEyvCGWRKxsxVE3AXsX3ZU+tn/2sA+1Ac/VZ/q7ayFBu81RQoYrTvtjrr5D2HDAgSwTnAdtZew9tiXJd/AP9Tuab6WaMcRv14tW97YDOcqunD60hkOOIguzLK3Gz7V1a2QTil9OoOXt2Q22lEG8WjaQ91qwck6eJy8ep0bQNPfUS6uAVDRt8dD4DrXesxFHGK9YG0KTSWg+CkPAxhGiu6dj8gaqw=
X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:;
 IPV:NLI; SFV:NSPM; H:SJ0PR13MB5545.namprd13.prod.outlook.com; PTR:; CAT:NONE;
 SFS:(13230031)(366004)(396003)(376002)(136003)(39830400003)(346002)(1800799009)(186009)(451199024)(478600001)(6486002)(6666004)(6512007)(6506007)(52116002)(8936002)(8676002)(44832011)(83380400001)(66946007)(66476007)(66556008)(6916009)(316002)(5660300002)(107886003)(2616005)(36756003)(38100700002)(38350700002)(86362001)(4326008)(26005)(2906002)(1076003)(41300700001)(30864003);
 DIR:OUT; SFP:1102; 
X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1
X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?fPcvfoLHNiGPoi0850hocoHceZ+wRkF2J3iunhfaJgSDkpHLA4O3ceXUlQOK?=
 =?us-ascii?Q?yFEh9s2Q81xtLoK7aVykf/dryFnXqPwft/5fzrOdzupaEPCkdztFH0oA4Eqm?=
 =?us-ascii?Q?j1LVqD6x7YzW4XtGr7XbXFrqAQF29Latsk6K//efJ+Xwsyr38uHuYo9UiU1G?=
 =?us-ascii?Q?ZwRuaaChyJbSz0m/rg9fAeu/rt0OCx3SxKn8ulH3dq7iUIvV2p4bAyigC66U?=
 =?us-ascii?Q?fvBcjG7wQvyYK40ltp46znFqhU/L+0tJ/AETrjuUchqWJ1AQ9JypbR+yCVlW?=
 =?us-ascii?Q?nzfVNEXhpr3VGI9Ax9FQqjgiGX0GWqrJ4YMZ8szt2Rpt8gRsbOuhD6BByAvl?=
 =?us-ascii?Q?Af7BviLtUNIt5I/EuWm6n7A7erhs2eVgdcwwXyjWJdY/s6JGelDedDOdD4Ta?=
 =?us-ascii?Q?TUrdxaTzJ/xJVH01fTP94A1LH5Hpxs+K1lIKHyFvtUaCnVNjhxpJQ2AVlmiV?=
 =?us-ascii?Q?AKDuyojDGP0vITIveFiSn/dWzkkdbeOypxbUoyqKEEVfG7k0CUX1vGfXG9Zg?=
 =?us-ascii?Q?VReNL4j3BcMygDg+TwMsltotSyUGNgRWAMLLQRtP6IPA/numcix9JNca6gIW?=
 =?us-ascii?Q?4Yz2ymJNYzY2Z0HRTPCPhNcCg6MPOr7Jo12I73fID8ARYfCjJqqcSFRSfz11?=
 =?us-ascii?Q?15tJxufe604OA+VC9qCIqyixI6LEQwSV47YEJ9czwleKGmVkkbOcl1mYyG45?=
 =?us-ascii?Q?vz42tl2N/LdOWhrGmW69GmLwEa2z4dYKtVH04HfrLGK0HFXgCX5bHfm8EP1Y?=
 =?us-ascii?Q?4KrNZZH5io9T4mva8sUt7ZL2J7Ont+XWwb2qyuuTwapvjZpQyOo0pVAkbC0v?=
 =?us-ascii?Q?TNprXgExs0CUM+rKHYJ98a1b2jHOsXdG2qxe6haY6Du8UsNQxyKOgLXPre0u?=
 =?us-ascii?Q?o9ibRiA87lkoWzwzt5sIS0wcoxEAKIe3JTZ1WPAr7ijoxKTO8i5tpPR4hnVn?=
 =?us-ascii?Q?IiiYtWl0zBiscRNIeQfIvmLz4AAfvpxIFqfbxe+eC7tg5TvKXj2oqLWUnDwm?=
 =?us-ascii?Q?DnmKvl0dX0S1MXoc+q0rq9G4swXiqedo3D6TN4n99t1bE0nDrnOEh6l5nxT1?=
 =?us-ascii?Q?+s6Xs/lcO1kdQx0/3YFjRqoIMlt7U2gky61qmCPsu2CvOWTiEkkCV81QXQzH?=
 =?us-ascii?Q?+90itDSkMkzYbydD7eHiicoS+IeoLG4L64PRZMN+tZLGP9JirKz1RTxG6AKY?=
 =?us-ascii?Q?kSeSmiN00prw3rrF2sC9dZv0AQuTiqPCAA8K/Sv75A83nzAf++WIImH/Nd+9?=
 =?us-ascii?Q?+guYFSz83OsBGXQSssRxu7HN6DMvlli1BwnWhbTopXXZzEdt0VBYPaKzef48?=
 =?us-ascii?Q?W51L8QxnxZGGQq0f6EC5nklmr+P2etN7ho3mlbtV7t0NjmBhukKKQU7UXNq3?=
 =?us-ascii?Q?+3ih2L0vTWNnHsxgsjIisZ1uOIw7c458TmQX4Clan3d0XP06OpHUMEWq8mAJ?=
 =?us-ascii?Q?GPHnLvYU4u/ctlVjA/g78BOTK9Bi5Fu6RiLljMy/DbUpcYdLpBCJsq7OMNmZ?=
 =?us-ascii?Q?MxAW3UpN51fHSu1r6IiwjowMVdkDQ8/jEgEjqfr3dFm9hx0ExgmzdbEoVMtZ?=
 =?us-ascii?Q?ryYh/7wwshBMMq7zmeNXHG4J5zhXfPXJ+4YuVNHOQXqJhEWBetTQHpS1XH8f?=
 =?us-ascii?Q?qw=3D=3D?=
X-OriginatorOrg: corigine.com
X-MS-Exchange-CrossTenant-Network-Message-Id: 8a8d477a-26dd-49c0-6fee-08dbb9791512
X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-OriginalArrivalTime: 20 Sep 2023 01:29:50.1829 (UTC)
X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted
X-MS-Exchange-CrossTenant-Id: fe128f2c-073b-4c20-818e-7246a585940c
X-MS-Exchange-CrossTenant-MailboxType: HOSTED
X-MS-Exchange-CrossTenant-UserPrincipalName: bD4qfYfZDROwkdOJUVUajjXAgFs7hqKzICgVDWrWSATwzMAlenKRlvquKKn4IJCH/YrCmolep6cV1jISlTxvammVt9KSOU54BLXXfOLGQpM=
X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH2PR13MB3623
X-BeenThere: dev@dpdk.org
X-Mailman-Version: 2.1.29
Precedence: list
List-Id: DPDK patches and discussions <dev.dpdk.org>
List-Unsubscribe: <https://mails.dpdk.org/options/dev>,
 <mailto:dev-request@dpdk.org?subject=unsubscribe>
List-Archive: <http://mails.dpdk.org/archives/dev/>
List-Post: <mailto:dev@dpdk.org>
List-Help: <mailto:dev-request@dpdk.org?subject=help>
List-Subscribe: <https://mails.dpdk.org/listinfo/dev>,
 <mailto:dev-request@dpdk.org?subject=subscribe>
Errors-To: dev-bounces@dpdk.org

Sync the logic from kernel driver, adjust the definition of structure,
and extend the usage of nfp BAR from 8 to 24.

This will greatly enhance the scalability of nfp PMD.

Signed-off-by: Chaoyong He <chaoyong.he@corigine.com>
---
 drivers/net/nfp/nfp_ethdev.c           |   8 +-
 drivers/net/nfp/nfpcore/nfp6000_pcie.c | 477 ++++++++++++++++++-------
 drivers/net/nfp/nfpcore/nfp6000_pcie.h |   1 +
 drivers/net/nfp/nfpcore/nfp_cpp.h      |   5 +-
 drivers/net/nfp/nfpcore/nfp_cppcore.c  |   2 +-
 5 files changed, 348 insertions(+), 145 deletions(-)

diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c
index 673bb06d00..b2a2cd9ed8 100644
--- a/drivers/net/nfp/nfp_ethdev.c
+++ b/drivers/net/nfp/nfp_ethdev.c
@@ -920,9 +920,9 @@ nfp_pf_init(struct rte_pci_device *pci_dev)
 	 * use a lock file if UIO is being used.
 	 */
 	if (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)
-		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, false);
+		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, dev_info, false);
 	else
-		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, true);
+		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, dev_info, true);
 
 	if (cpp == NULL) {
 		PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
@@ -1121,9 +1121,9 @@ nfp_pf_secondary_init(struct rte_pci_device *pci_dev)
 	 * use a lock file if UIO is being used.
 	 */
 	if (pci_dev->kdrv == RTE_PCI_KDRV_VFIO)
-		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, false);
+		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, dev_info, false);
 	else
-		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, true);
+		cpp = nfp_cpp_from_nfp6000_pcie(pci_dev, dev_info, true);
 
 	if (cpp == NULL) {
 		PMD_INIT_LOG(ERR, "A CPP handle can not be obtained");
diff --git a/drivers/net/nfp/nfpcore/nfp6000_pcie.c b/drivers/net/nfp/nfpcore/nfp6000_pcie.c
index 40076cdc11..13cf523506 100644
--- a/drivers/net/nfp/nfpcore/nfp6000_pcie.c
+++ b/drivers/net/nfp/nfpcore/nfp6000_pcie.c
@@ -19,6 +19,8 @@
 #include <unistd.h>
 #include <fcntl.h>
 
+#include <rte_io.h>
+
 #include "nfp_cpp.h"
 #include "nfp_logs.h"
 #include "nfp_target.h"
@@ -59,20 +61,12 @@
 #define NFP_PCIE_P2C_GENERAL_TOKEN_OFFSET(bar, x) ((x) << ((bar)->bitsize - 4))
 #define NFP_PCIE_P2C_GENERAL_SIZE(bar)             (1 << ((bar)->bitsize - 4))
 
-#define NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(id, bar, slot) \
-	(NFP_PCIE_BAR(id) + ((bar) * 8 + (slot)) * 4)
-
-#define NFP_PCIE_CPP_BAR_PCIETOCPPEXPBAR(bar, slot) \
-	(((bar) * 8 + (slot)) * 4)
+#define NFP_PCIE_P2C_EXPBAR_OFFSET(bar_index)      ((bar_index) * 4)
 
 struct nfp_pcie_user;
 struct nfp6000_area_priv;
 
 /* Describes BAR configuration and usage */
-#define NFP_BAR_MIN 1
-#define NFP_BAR_MID 5
-#define NFP_BAR_MAX 7
-
 struct nfp_bar {
 	struct nfp_pcie_user *nfp;    /**< Backlink to owner */
 	uint32_t barcfg;     /**< BAR config CSR */
@@ -80,22 +74,26 @@ struct nfp_bar {
 	uint64_t mask;       /**< Mask of the BAR aperture (read only) */
 	uint32_t bitsize;    /**< Bit size of the BAR aperture (read only) */
 	uint32_t index;      /**< Index of the BAR */
-	int lock;            /**< If the BAR has been locked */
+	bool lock;           /**< If the BAR has been locked */
 
-	char *csr;
 	char *iomem;         /**< mapped IO memory */
+	struct rte_mem_resource *resource;    /**< IOMEM resource window */
 };
 
-#define BUSDEV_SZ    13
+#define NFP_PCI_BAR_MAX    (PCI_64BIT_BAR_COUNT * 8)
+
 struct nfp_pcie_user {
-	struct nfp_bar bar[NFP_BAR_MAX];
+	struct rte_pci_device *pci_dev;
+	const struct nfp_dev_info *dev_info;
 
-	int device;
 	int lock;
-	char busdev[BUSDEV_SZ];
-	int barsz;
-	int dev_id;
-	char *cfg;
+
+	/* PCI BAR management */
+	uint32_t bars;
+	struct nfp_bar bar[NFP_PCI_BAR_MAX];
+
+	/* Reserved BAR access */
+	char *csr;
 };
 
 /* Generic CPP bus access interface. */
@@ -206,19 +204,19 @@ nfp_bar_write(struct nfp_pcie_user *nfp,
 		struct nfp_bar *bar,
 		uint32_t newcfg)
 {
-	int base;
-	int slot;
-
-	base = bar->index >> 3;
-	slot = bar->index & 7;
+	uint32_t xbar;
 
-	if (nfp->cfg == NULL)
-		return (-ENOMEM);
+	xbar = NFP_PCIE_P2C_EXPBAR_OFFSET(bar->index);
 
-	bar->csr = nfp->cfg +
-			NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(nfp->dev_id, base, slot);
-
-	*(uint32_t *)(bar->csr) = newcfg;
+	if (nfp->csr != NULL) {
+		rte_write32(newcfg, nfp->csr + xbar);
+		/* Readback to ensure BAR is flushed */
+		rte_read32(nfp->csr + xbar);
+	} else {
+		xbar += nfp->dev_info->pcie_cfg_expbar_offset;
+		rte_pci_write_config(nfp->pci_dev, &newcfg, sizeof(uint32_t),
+				xbar);
+	}
 
 	bar->barcfg = newcfg;
 
@@ -249,105 +247,323 @@ nfp_reconfigure_bar(struct nfp_pcie_user *nfp,
 	return nfp_bar_write(nfp, bar, newcfg);
 }
 
-/*
- * Map all PCI bars. We assume that the BAR with the PCIe config block is
- * already mapped.
+static uint32_t
+nfp_bitsize_calc(uint64_t mask)
+{
+	uint64_t tmp = mask;
+	uint32_t bit_size = 0;
+
+	if (tmp == 0)
+		return 0;
+
+	for (; tmp != 0; tmp >>= 1)
+		bit_size++;
+
+	return bit_size;
+}
+
+static int
+nfp_cmp_bars(const void *ptr_a,
+		const void *ptr_b)
+{
+	const struct nfp_bar *a = ptr_a;
+	const struct nfp_bar *b = ptr_b;
+
+	if (a->bitsize == b->bitsize)
+		return a->index - b->index;
+	else
+		return a->bitsize - b->bitsize;
+}
+
+static bool
+nfp_bars_for_secondary(uint32_t index)
+{
+	uint8_t tmp = index & 0x07;
+
+	if (tmp == 0x06 || tmp == 0x07)
+		return true;
+	else
+		return false;
+}
+
+/**
+ * Map all PCI bars and fetch the actual BAR configurations from the board.
+ * We assume that the BAR with the PCIe config block is already mapped.
  *
  * BAR0.0: Reserved for General Mapping (for MSI-X access to PCIe SRAM)
+ * BAR0.1: --
+ * BAR0.2: --
+ * BAR0.3: --
+ * BAR0.4: --
+ * BAR0.5: --
+ * BAR0.6: --
+ * BAR0.7: --
  *
- *         Halving PCItoCPPBars for primary and secondary processes.
- *         For CoreNIC firmware:
- *         NFP PMD just requires two fixed slots, one for configuration BAR,
- *         and another for accessing the hw queues. Another slot is needed
- *         for setting the link up or down. Secondary processes do not need
- *         to map the first two slots again, but it requires one slot for
- *         accessing the link, even if it is not likely the secondary process
- *         starting the port.
- *         For Flower firmware:
- *         NFP PMD need another fixed slots, used as the configureation BAR
- *         for ctrl vNIC.
+ * BAR1.0-BAR1.7: --
+ * BAR2.0-BAR2.7: --
  */
 static int
 nfp_enable_bars(struct nfp_pcie_user *nfp)
 {
-	int x;
-	int end;
-	int start;
+	int pf;
+	uint32_t i;
+	uint8_t min_bars;
 	struct nfp_bar *bar;
+	enum rte_proc_type_t type;
+	struct rte_mem_resource *res;
+	const uint32_t barcfg_msix_general = NFP_PCIE_BAR_PCIE2CPP_MAPTYPE
+			(NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_GENERAL) |
+			NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT;
+
+	type = rte_eal_process_type();
+	if (type == RTE_PROC_PRIMARY)
+		min_bars = 12;
+	else
+		min_bars = 4;
+
+	for (i = 0; i < RTE_DIM(nfp->bar); i++) {
+		if (i != 0) {
+			if (type == RTE_PROC_PRIMARY) {
+				if (nfp_bars_for_secondary(i))
+					continue;
+			} else {
+				if (!nfp_bars_for_secondary(i))
+					continue;
+			}
+		}
 
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		start = NFP_BAR_MID;
-		end = NFP_BAR_MIN;
-	} else {
-		start = NFP_BAR_MAX;
-		end = NFP_BAR_MID;
+		/* 24 NFP bars mapping into BAR0, BAR2 and BAR4 */
+		res = &nfp->pci_dev->mem_resource[(i >> 3) * 2];
+
+		/* Skip over BARs that are not mapped */
+		if (res->addr != NULL) {
+			bar = &nfp->bar[i];
+			bar->resource = res;
+			bar->barcfg = 0;
+
+			bar->nfp = nfp;
+			bar->index = i;
+			/* The resource shared by 8 bars */
+			bar->mask = (res->len >> 3) - 1;
+			bar->bitsize = nfp_bitsize_calc(bar->mask);
+			bar->base = 0;
+			bar->lock = false;
+			bar->iomem = (char *)res->addr +
+					((bar->index & 7) << bar->bitsize);
+
+			nfp->bars++;
+		}
 	}
 
-	for (x = start; x > end; x--) {
-		bar = &nfp->bar[x - 1];
-		bar->barcfg = 0;
-		bar->nfp = nfp;
-		bar->index = x;
-		bar->mask = (1 << (nfp->barsz - 3)) - 1;
-		bar->bitsize = nfp->barsz - 3;
-		bar->base = 0;
-		bar->iomem = NULL;
-		bar->lock = 0;
-		bar->csr = nfp->cfg + NFP_PCIE_CFG_BAR_PCIETOCPPEXPBAR(nfp->dev_id,
-				bar->index >> 3, bar->index & 7);
-		bar->iomem = nfp->cfg + (bar->index << bar->bitsize);
+	if (nfp->bars < min_bars) {
+		PMD_DRV_LOG(ERR, "Not enough usable BARs found.");
+		return -EINVAL;
 	}
+
+	switch (nfp->pci_dev->id.device_id) {
+	case PCI_DEVICE_ID_NFP3800_PF_NIC:
+		pf = nfp->pci_dev->addr.function & 0x07;
+		nfp->csr = nfp->bar[0].iomem + NFP_PCIE_BAR(pf);
+		break;
+	case PCI_DEVICE_ID_NFP4000_PF_NIC:
+	case PCI_DEVICE_ID_NFP6000_PF_NIC:
+		nfp->csr = nfp->bar[0].iomem + NFP_PCIE_BAR(0);
+		break;
+	default:
+		PMD_DRV_LOG(ERR, "Unsupported device ID: %04hx!",
+				nfp->pci_dev->id.device_id);
+		return -EINVAL;
+	}
+
+	/* Configure, and lock, BAR0.0 for General Target use (MSI-X SRAM) */
+	bar = &nfp->bar[0];
+	bar->lock = true;
+
+	nfp_bar_write(nfp, bar, barcfg_msix_general);
+
+	/* Sort bars by bit size - use the smallest possible first. */
+	qsort(&nfp->bar[0], nfp->bars, sizeof(nfp->bar[0]), nfp_cmp_bars);
+
 	return 0;
 }
 
-static struct nfp_bar *
-nfp_alloc_bar(struct nfp_pcie_user *nfp)
+/* Check if BAR can be used with the given parameters. */
+static bool
+matching_bar_exist(struct nfp_bar *bar,
+		int target,
+		int action,
+		int token,
+		uint64_t offset,
+		size_t size,
+		int width)
 {
-	int x;
-	int end;
-	int start;
-	struct nfp_bar *bar;
+	int bar_width;
+	int bar_token;
+	int bar_target;
+	int bar_action;
+	uint32_t map_type;
+
+	bar_width = NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_OF(bar->barcfg);
+	switch (bar_width) {
+	case NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_32BIT:
+		bar_width = 4;
+		break;
+	case NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_64BIT:
+		bar_width = 8;
+		break;
+	case NFP_PCIE_BAR_PCIE2CPP_LENGTHSELECT_0BYTE:
+		bar_width = 0;
+		break;
+	default:
+		bar_width = -1;
+		break;
+	}
 
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		start = NFP_BAR_MID;
-		end = NFP_BAR_MIN;
-	} else {
-		start = NFP_BAR_MAX;
-		end = NFP_BAR_MID;
+	/* Make sure to match up the width */
+	if (bar_width != width)
+		return false;
+
+	bar_token = NFP_PCIE_BAR_PCIE2CPP_TOKEN_BASEADDRESS_OF(bar->barcfg);
+	bar_action = NFP_PCIE_BAR_PCIE2CPP_ACTION_BASEADDRESS_OF(bar->barcfg);
+	map_type = NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_OF(bar->barcfg);
+	switch (map_type) {
+	case NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_TARGET:
+		bar_token = -1;
+		/* FALLTHROUGH */
+	case NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_BULK:
+		bar_action = NFP_CPP_ACTION_RW;
+		if (action == 0)
+			action = NFP_CPP_ACTION_RW;
+		/* FALLTHROUGH */
+	case NFP_PCIE_BAR_PCIE2CPP_MAPTYPE_FIXED:
+		break;
+	default:
+		/* We don't match explicit bars through the area interface */
+		return false;
 	}
 
-	for (x = start; x > end; x--) {
-		bar = &nfp->bar[x - 1];
-		if (bar->lock == 0) {
-			bar->lock = 1;
-			return bar;
-		}
+	bar_target = NFP_PCIE_BAR_PCIE2CPP_TARGET_BASEADDRESS_OF(bar->barcfg);
+	if ((bar_target < 0 || bar_target == target) &&
+			(bar_token < 0 || bar_token == token) &&
+			bar_action == action &&
+			bar->base <= offset &&
+			(bar->base + (1 << bar->bitsize)) >= (offset + size))
+		return true;
+
+	/* No match */
+	return false;
+}
+
+static int
+find_matching_bar(struct nfp_pcie_user *nfp,
+		int target,
+		int action,
+		int token,
+		uint64_t offset,
+		size_t size,
+		int width)
+{
+	uint32_t n;
+
+	for (n = 0; n < nfp->bars; n++) {
+		struct nfp_bar *bar = &nfp->bar[n];
+
+		if (bar->lock)
+			continue;
+
+		if (matching_bar_exist(bar, target, action, token,
+				offset, size, width))
+			return n;
+	}
+
+	return -1;
+}
+
+/* Return EAGAIN if no resource is available */
+static int
+find_unused_bar_noblock(struct nfp_pcie_user *nfp,
+		int target,
+		int action,
+		int token,
+		uint64_t offset,
+		size_t size,
+		int width)
+{
+	int ret;
+	uint32_t n;
+	const struct nfp_bar *bar;
+
+	for (n = 0; n < nfp->bars; n++) {
+		bar = &nfp->bar[n];
+
+		if (bar->bitsize == 0)
+			continue;
+
+		/* Just check to see if we can make it fit... */
+		ret = nfp_compute_bar(bar, NULL, NULL, target, action,
+				token, offset, size, width);
+		if (ret != 0)
+			continue;
+
+		if (!bar->lock)
+			return n;
+	}
+
+	return -EAGAIN;
+}
+
+static int
+nfp_alloc_bar(struct nfp_pcie_user *nfp,
+		struct nfp6000_area_priv *priv)
+{
+	int ret;
+	int bar_num;
+	size_t size = priv->size;
+	int token = priv->token;
+	int target = priv->target;
+	int action = priv->action;
+	int width = priv->width.bar;
+	uint64_t offset = priv->offset;
+
+	/* Bar size should small than 16MB */
+	if (size > (1 << 24))
+		return -EINVAL;
+
+	bar_num = find_matching_bar(nfp, target, action, token,
+			offset, size, width);
+	if (bar_num >= 0) {
+		/* Found a perfect match. */
+		nfp->bar[bar_num].lock = true;
+		return bar_num;
 	}
 
-	return NULL;
+	bar_num = find_unused_bar_noblock(nfp, target, action, token,
+			offset, size, width);
+	if (bar_num < 0)
+		return bar_num;
+
+	nfp->bar[bar_num].lock = true;
+	ret = nfp_reconfigure_bar(nfp, &nfp->bar[bar_num],
+			target, action, token, offset, size, width);
+	if (ret < 0) {
+		nfp->bar[bar_num].lock = false;
+		return ret;
+	}
+
+	return bar_num;
 }
 
 static void
 nfp_disable_bars(struct nfp_pcie_user *nfp)
 {
-	int x;
-	int end;
-	int start;
+	uint32_t i;
 	struct nfp_bar *bar;
 
-	if (rte_eal_process_type() == RTE_PROC_PRIMARY) {
-		start = NFP_BAR_MID;
-		end = NFP_BAR_MIN;
-	} else {
-		start = NFP_BAR_MAX;
-		end = NFP_BAR_MID;
-	}
-
-	for (x = start; x > end; x--) {
-		bar = &nfp->bar[x - 1];
-		if (bar->iomem) {
+	for (i = 0; i < nfp->bars; i++) {
+		bar = &nfp->bar[i];
+		if (bar->iomem != NULL) {
 			bar->iomem = NULL;
-			bar->lock = 0;
+			bar->lock = false;
 		}
 	}
 }
@@ -364,7 +580,6 @@ nfp6000_area_init(struct nfp_cpp_area *area,
 	uint32_t target = NFP_CPP_ID_TARGET_of(dest);
 	uint32_t action = NFP_CPP_ID_ACTION_of(dest);
 	struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
-	struct nfp_pcie_user *nfp = nfp_cpp_priv(nfp_cpp_area_cpp(area));
 
 	pp = nfp_target_pushpull(NFP_CPP_ID(target, action, token), address);
 	if (pp < 0)
@@ -383,9 +598,7 @@ nfp6000_area_init(struct nfp_cpp_area *area,
 	else
 		priv->width.bar = priv->width.write;
 
-	priv->bar = nfp_alloc_bar(nfp);
-	if (priv->bar == NULL)
-		return -ENOMEM;
+	priv->bar = NULL;
 
 	priv->target = target;
 	priv->action = action;
@@ -393,17 +606,29 @@ nfp6000_area_init(struct nfp_cpp_area *area,
 	priv->offset = address;
 	priv->size = size;
 
-	ret = nfp_reconfigure_bar(nfp, priv->bar, priv->target, priv->action,
-			priv->token, priv->offset, priv->size,
-			priv->width.bar);
-
 	return ret;
 }
 
 static int
 nfp6000_area_acquire(struct nfp_cpp_area *area)
 {
+	int bar_num;
 	struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
+	struct nfp_pcie_user *nfp = nfp_cpp_priv(nfp_cpp_area_cpp(area));
+
+	/* Already allocated. */
+	if (priv->bar != NULL)
+		return 0;
+
+	bar_num = nfp_alloc_bar(nfp, priv);
+	if (bar_num < 0) {
+		PMD_DRV_LOG(ERR, "Failed to allocate bar %d:%d:%d:%#lx: %d",
+				priv->target, priv->action, priv->token,
+				priv->offset, bar_num);
+		return bar_num;
+	}
+
+	priv->bar = &nfp->bar[bar_num];
 
 	/* Calculate offset into BAR. */
 	if (nfp_bar_maptype(priv->bar) ==
@@ -432,7 +657,7 @@ nfp6000_area_release(struct nfp_cpp_area *area)
 {
 	struct nfp6000_area_priv *priv = nfp_cpp_area_priv(area);
 
-	priv->bar->lock = 0;
+	priv->bar->lock = false;
 	priv->bar = NULL;
 	priv->iomem = NULL;
 }
@@ -603,7 +828,8 @@ nfp_acquire_process_lock(struct nfp_pcie_user *desc)
 
 	memset(&lock, 0, sizeof(lock));
 
-	snprintf(lockname, sizeof(lockname), "/var/lock/nfp_%s", desc->busdev);
+	snprintf(lockname, sizeof(lockname), "/var/lock/nfp_%s",
+			desc->pci_dev->device.name);
 	desc->lock = open(lockname, O_RDWR | O_CREAT, 0666);
 	if (desc->lock < 0)
 		return desc->lock;
@@ -693,32 +919,11 @@ nfp6000_get_serial(struct rte_pci_device *dev,
 }
 
 static int
-nfp6000_set_barsz(struct rte_pci_device *dev,
-		struct nfp_pcie_user *desc)
-{
-	int i = 0;
-	uint64_t tmp;
-
-	tmp = dev->mem_resource[0].len;
-
-	while (tmp >>= 1)
-		i++;
-
-	desc->barsz = i;
-
-	return 0;
-}
-
-static int
-nfp6000_init(struct nfp_cpp *cpp,
-		struct rte_pci_device *dev)
+nfp6000_init(struct nfp_cpp *cpp)
 {
 	int ret = 0;
 	struct nfp_pcie_user *desc = nfp_cpp_priv(cpp);
 
-	memset(desc->busdev, 0, BUSDEV_SZ);
-	strlcpy(desc->busdev, dev->device.name, sizeof(desc->busdev));
-
 	if (rte_eal_process_type() == RTE_PROC_PRIMARY &&
 			nfp_cpp_driver_need_lock(cpp)) {
 		ret = nfp_acquire_process_lock(desc);
@@ -726,12 +931,6 @@ nfp6000_init(struct nfp_cpp *cpp,
 			return -1;
 	}
 
-	if (nfp6000_set_barsz(dev, desc) < 0)
-		return -1;
-
-	desc->cfg = dev->mem_resource[0].addr;
-	desc->dev_id = dev->addr.function & 0x7;
-
 	ret = nfp_enable_bars(desc);
 	if (ret != 0) {
 		PMD_DRV_LOG(ERR, "Enable bars failed");
@@ -749,7 +948,6 @@ nfp6000_free(struct nfp_cpp *cpp)
 	nfp_disable_bars(desc);
 	if (nfp_cpp_driver_need_lock(cpp))
 		close(desc->lock);
-	close(desc->device);
 	free(desc);
 }
 
@@ -789,6 +987,7 @@ nfp_cpp_operations *nfp_cpp_transport_operations(void)
  */
 struct nfp_cpp *
 nfp_cpp_from_nfp6000_pcie(struct rte_pci_device *pci_dev,
+		const struct nfp_dev_info *dev_info,
 		bool driver_lock_needed)
 {
 	int ret;
@@ -801,6 +1000,8 @@ nfp_cpp_from_nfp6000_pcie(struct rte_pci_device *pci_dev,
 		return NULL;
 
 	memset(nfp, 0, sizeof(*nfp));
+	nfp->pci_dev = pci_dev;
+	nfp->dev_info = dev_info;
 
 	ret = nfp6000_get_interface(pci_dev, &interface);
 	if (ret != 0) {
diff --git a/drivers/net/nfp/nfpcore/nfp6000_pcie.h b/drivers/net/nfp/nfpcore/nfp6000_pcie.h
index 8847f6f946..8e2cfb69e6 100644
--- a/drivers/net/nfp/nfpcore/nfp6000_pcie.h
+++ b/drivers/net/nfp/nfpcore/nfp6000_pcie.h
@@ -14,6 +14,7 @@
 const struct nfp_cpp_operations *nfp_cpp_transport_operations(void);
 
 struct nfp_cpp *nfp_cpp_from_nfp6000_pcie(struct rte_pci_device *pci_dev,
+		const struct nfp_dev_info *dev_info,
 		bool driver_lock_needed);
 
 #endif /* __NFP6000_PCIE_H__ */
diff --git a/drivers/net/nfp/nfpcore/nfp_cpp.h b/drivers/net/nfp/nfpcore/nfp_cpp.h
index e879c7c920..2defc4fa16 100644
--- a/drivers/net/nfp/nfpcore/nfp_cpp.h
+++ b/drivers/net/nfp/nfpcore/nfp_cpp.h
@@ -18,6 +18,8 @@ struct nfp_cpp_area;
 
 #define NFP_CPP_NUM_TARGETS             16
 
+#define PCI_64BIT_BAR_COUNT             3
+
 /*
  * NFP CPP operations structure
  */
@@ -26,8 +28,7 @@ struct nfp_cpp_operations {
 	size_t area_priv_size;
 
 	/* Instance an NFP CPP */
-	int (*init)(struct nfp_cpp *cpp,
-			struct rte_pci_device *dev);
+	int (*init)(struct nfp_cpp *cpp);
 
 	/*
 	 * Free the bus.
diff --git a/drivers/net/nfp/nfpcore/nfp_cppcore.c b/drivers/net/nfp/nfpcore/nfp_cppcore.c
index 8b2d00a6a1..f9b08a12b6 100644
--- a/drivers/net/nfp/nfpcore/nfp_cppcore.c
+++ b/drivers/net/nfp/nfpcore/nfp_cppcore.c
@@ -947,7 +947,7 @@ nfp_cpp_alloc(struct rte_pci_device *pci_dev,
 	 * NOTE: cpp_lock is NOT locked for op->init,
 	 * since it may call NFP CPP API operations
 	 */
-	err = cpp->op->init(cpp, pci_dev);
+	err = cpp->op->init(cpp);
 	if (err < 0) {
 		PMD_DRV_LOG(ERR, "NFP interface initialization failed");
 		free(cpp);
-- 
2.39.1