From patchwork Thu Aug 24 11:09:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 130730 X-Patchwork-Delegate: ferruh.yigit@amd.com Return-Path: X-Original-To: patchwork@inbox.dpdk.org Delivered-To: patchwork@inbox.dpdk.org Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id E95E8430EF; Thu, 24 Aug 2023 13:14:22 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 5FBAF432FD; Thu, 24 Aug 2023 13:11:40 +0200 (CEST) Received: from NAM10-DM6-obe.outbound.protection.outlook.com (mail-dm6nam10on2099.outbound.protection.outlook.com [40.107.93.99]) by mails.dpdk.org (Postfix) with ESMTP id E123542D0E for ; Thu, 24 Aug 2023 13:11:36 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AWpJbKvX9WJ7cTL5L4okLw2isvWDpTvHlvqpBlYRkhnCssvOmylePi/jQyrlTY+5zEOVxEZK15h9nu8kUHmJ26k0TrxqZYsB5hDGgjTL/KKCD1ZZlItUuvz4pRM8PEl7kNYDXVWcZiAUM0ajxMeBKO6Q6shoNEzdtJR0ipZGytiXLAzZIzEa/HiHZ+UNo6X4SOCwoZ8M2gNigFnMZFzPolswOSGQQ21azDw6eNL0zllnAGAADN1u9y5hJoz1ksvyPNm6xLkF2+GRAn66N7ceF/OYEEKbEcLWnY2HFztWPAhIAzxtRLLReF2VT3NE+pcU9d9zBrBaIPbSb2lGZTtV6g== 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=ZuI/jsvo1Z0EEF5z0VDcUd+fHNZTwwzOCZ0BbW4ZcYI=; b=O87a9M6Jbi34saGn+igTQh6+BcjzfEeOr9jyUrsl9erN/B+Dnj+8cFcayjJX2oDyHzDF/0ZwLel2iExr2c93g3IjeqQcLjjIimQL5ZzwghlghpnllXYeJPicxHgOKPa8OUrjch3yT8rE5gsyrLlACax75TCNnpyESCro7XMh4VK4KqnIjJeqHOgm+Vv/xFYOK92aesnku6Ip4ewp95KsmdM5A4sX8sK7sUxbziXLCPS7+nc2YhZ3QY6a2ffB0iwoVGR4h1gkboREbZe9wiwsCFgW6nG3gENhFFFUATZcAtMoBfp6YoVZiWaOLwUYUKzZV9paLIGmwKMHu777WbQ0mg== 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=ZuI/jsvo1Z0EEF5z0VDcUd+fHNZTwwzOCZ0BbW4ZcYI=; b=fWdMPFJ6ju6AUUfPCOfX9C+rjyzKs9uX4myanl55KM22o7G6lPAD5N6t+JRb8CdbymHgjlaJYCt7EE4D2sxaKD4maSVfeJaCjS36iXRgXO3xKa1/nypMslzUZAPweRo1+m4zm1K4j+4winaPmgVLzelIGDWbVnuib0Tjdcr5wFo= 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 PH7PR13MB6116.namprd13.prod.outlook.com (2603:10b6:510:2b7::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6699.20; Thu, 24 Aug 2023 11:11:35 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::51fe:5846:af8b:bace]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::51fe:5846:af8b:bace%3]) with mapi id 15.20.6699.020; Thu, 24 Aug 2023 11:11:35 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, niklas.soderlund@corigine.com, Chaoyong He Subject: [PATCH 27/27] net/nfp: extend the usage of nfp BAR from 8 to 24 Date: Thu, 24 Aug 2023 19:09:56 +0800 Message-Id: <20230824110956.1943559-28-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230824110956.1943559-1-chaoyong.he@corigine.com> References: <20230824110956.1943559-1-chaoyong.he@corigine.com> X-ClientProxiedBy: SJ0PR05CA0005.namprd05.prod.outlook.com (2603:10b6:a03:33b::10) To SJ0PR13MB5545.namprd13.prod.outlook.com (2603:10b6:a03:424::5) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR13MB5545:EE_|PH7PR13MB6116:EE_ X-MS-Office365-Filtering-Correlation-Id: c0403e95-91d7-41c4-ad39-08dba492e0bf X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 7CuKaHeU8tXstGRx6dlcxFuJ8FROkamoZxqk1z4L4myY9UgicJcx5lSlC/LzMK4oXdJU4+Fjm/sedL5hFr6fqFURk6b0tJwAO8Ygg31MZAR0dAtFmmpTRTPVqIA5jQIA7BE08Et5m9Wz1ksYhX+bBQQAZhzmP8sCJ/cbsCf4amGPrEBwwZQmoGuNv8XUVFsJU4NyXcUWbHF7pPmQtRm+dWnAXmWMSyQpJUCzvShr9CzhvWIJZE5URAan3N0kSK16FSmsRNXcc4OAK4BHsMia+Eq7HTCSb2hI+O10GGm6+2AWfWdIlvZRU+Ro5NZBwjZoGaguCyna06xbPnw+Y9YB8cqzt6GmFCW38W+5kz6iQa89nxyxhNYF7IoxQQVrWXbZRq7EHTrg9cq5+zMffnUARZRGP16s/ZxtBi5kU0pj4f2eMTzEfJYOqXabzrXcQ9EQLSMAeuzmVyzedE17xIq8aUCufJOuRaIBHLYi9uvu4NBOXfXRn0KTREjFmzfZ6glIzx+xsVW7LsYbz8tnD35Y+werXLgm3HrJ+RTuW4kXwJwZOXz9+8cIWddES8/h6zNyV2JKEp6trkWa6ndwzkCdL/vlZ2tmwrJ/kMiMKF6OsNx/bD48M8HSYVuUBQkWEntZmtS4ndgLOOEs8BQv8dtMk94KB15hk/7Zse1W4lU7V/7ISs4kNJScXXcGAbyV6fFV 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)(39830400003)(346002)(396003)(136003)(376002)(1800799009)(186009)(451199024)(6506007)(26005)(1076003)(2616005)(107886003)(52116002)(12101799020)(6512007)(66574015)(6486002)(83380400001)(38100700002)(8676002)(8936002)(36756003)(316002)(4326008)(41300700001)(30864003)(2906002)(86362001)(5660300002)(44832011)(38350700002)(6666004)(6916009)(478600001)(66476007)(66946007)(66556008); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?n0vQTAKlxcVnIyG6WJSjlXYyQtgd?= =?utf-8?q?YzY7QnVD9kijmQsocEKKh3BbJprFoy1MkMc6AX855OyidhdHuUpL81TD02lbAXDPg?= =?utf-8?q?HE/F8yV8dcDVR+1GMX3565I2EUYTG3cW8JuJT97o1cnQsASK1R+YqA0iGSQnA9+ne?= =?utf-8?q?mcC8yAPABpit1es1kvpROY0aX2CT31jaH+gnNcQg1nwvyqGMsDm2RyESjfyhUZeZ3?= =?utf-8?q?BbGgHnyr7bTAtz+/juigIbvnwAiiswOvb9TJLbxlsKkto/c8jmaOmq90ZmZMfi/1Q?= =?utf-8?q?uxd8NyM9u7aMTuXaaR2l2Bz5GBCMMGn6YO5/WsOFpt/8HqS4S9hTvKUZ03Ag6EcW2?= =?utf-8?q?IqfOl4/01sjkvGzOaVjEQrGKjyoutmcyQHaycd42Dodw5qNFU+a0EYVhgPRibz+uo?= =?utf-8?q?ZHXAsn1rQy7OINw4UUmKUl8seCbZKI4Vr4rv73247c6PMeuQI765zBxQfZDn8269o?= =?utf-8?q?kTH1kzzfNSQmix0odN3W33DYvcgtUsvFpwDqm54ESimm7hgpZYDjzhYQyer+fRmSn?= =?utf-8?q?yAxAtBAL03IL2bh4oB3xffeMhV7/+f83qkyXiWZXIb9vAYM5YDedybEjl9QvQ26l4?= =?utf-8?q?blU3VW6v9CIxMWtPTCp9D4i0gWTkGxToQ9xxseSkDsH77Gmjxil9znRwobTqaPx74?= =?utf-8?q?ZjjEeSsZsnVFeV34/+N1QxAe+aDrrPtFAmz2QG2Ktl6N67ZjdNBGZJLFG80n8pY3D?= =?utf-8?q?ZptshDuxdYWQkDqcb95FAK8Bt5GA1qQaKD59yvw3pttuiXcsCjTict1RoxM6ZN9I3?= =?utf-8?q?YxvcxR4KjYvtAY5ZeHDFfjr1u75OEIvcyKrWXanKWvVdRNkh4O3R+SLCmst+eV8rD?= =?utf-8?q?9f6GvUcVhBSI3doiA2pSrzzBtkn2TKzm3T5eBmPZsY3D3+rG/Q/BV7lh6TqdEaKT/?= =?utf-8?q?EVAQ6r2dogi1hiWwTHVbIrOscfh7nWdstiy1L5KZqVUNw8nL7teRKLR+eAqntusJS?= =?utf-8?q?F4hIpN9pF2xlrJw7SV0fmmwq/MOBH0j4kzjIvOWL2YkPHtQqRgFijLUhIEVGknut0?= =?utf-8?q?yTvh6W2DVoymzTf/WpU44VgUyxNx5fJkh5jBLi3+TC/4UGfeEdcSx4AE0i33zifEz?= =?utf-8?q?2Qn1utO5bqO0AbcFDtj847GSbp9k+fTcqikijzQYiFk03YIX3iVjzlGVEpPzTlyjJ?= =?utf-8?q?7bGDfeaIQf/rI+v+cHig5HyKf/fze8fGq4ziVHABR3gkVzMA1QwfQ0K9Gzdl/9pI1?= =?utf-8?q?DxaL0uVzYTeYQxKytzOkPqJ4AjWii4itcD/sGwFFNj9L3iBK5Dxj7gosHlbe784Js?= =?utf-8?q?oXBD3M+jeUeVhXE3B0zVyF6UHxwDp70lSAe8DGd+5KVOVqqNU706W51gJ+yeCEeD1?= =?utf-8?q?CLn9aZ7CWepSYS9QGV9MY4KDF6SJrzTcscleonbFlTkgg4npct+nPcbqrKiW2VLaz?= =?utf-8?q?llI1qr7IU+j5guYcsz1w5UqobX+NYOvyVwu1KDlS6Nk8VA7Pctm9i5pTzMXsKzIT/?= =?utf-8?q?MjEKFeMVZcmlxlsSe+MfsozY1G3FxEptvHV2i8dmm2eA6tIaOpEFX+JtdbV2c6NRJ?= =?utf-8?q?aiY6Kw/abtt+SygHVjUzDAz/Af5pFmeFDA=3D=3D?= X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: c0403e95-91d7-41c4-ad39-08dba492e0bf X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 24 Aug 2023 11:11:34.9515 (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: szp0S5BRc4auaHgDFfKIewwIbu9lD6YPxp78DV/EwPmLB24/UDHtxWdG2TWQHaCFjst9GBLR4iQkB/qVdcbq9uAP3ErE1lB4ixLXdel65hQ= X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR13MB6116 X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: DPDK patches and discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-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 Reviewed-by: Niklas Söderlund --- drivers/net/nfp/nfp_ethdev.c | 8 +- drivers/net/nfp/nfpcore/nfp6000_pcie.c | 475 ++++++++++++++++++------- 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, 346 insertions(+), 145 deletions(-) diff --git a/drivers/net/nfp/nfp_ethdev.c b/drivers/net/nfp/nfp_ethdev.c index 6eefec3836..d6454d8964 100644 --- a/drivers/net/nfp/nfp_ethdev.c +++ b/drivers/net/nfp/nfp_ethdev.c @@ -918,9 +918,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 a3bc7a14c4..525c372aa7 100644 --- a/drivers/net/nfp/nfpcore/nfp6000_pcie.c +++ b/drivers/net/nfp/nfpcore/nfp6000_pcie.c @@ -19,6 +19,8 @@ #include #include +#include + #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,320 @@ 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++; + } + } + + if (nfp->bars < min_bars) { + PMD_DRV_LOG(ERR, "Not enough usable BARs found."); + return -EINVAL; } - 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); + 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 (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 +577,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 +595,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 +603,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 +654,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 +825,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 +916,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 +928,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 +945,6 @@ nfp6000_free(struct nfp_cpp *cpp) nfp_disable_bars(desc); if (nfp_cpp_driver_need_lock(cpp)) close(desc->lock); - close(desc->device); rte_free(desc); } @@ -789,6 +984,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; @@ -800,6 +996,9 @@ nfp_cpp_from_nfp6000_pcie(struct rte_pci_device *pci_dev, if (nfp == NULL) return NULL; + nfp->pci_dev = pci_dev; + nfp->dev_info = dev_info; + ret = nfp6000_get_interface(pci_dev, &interface); if (ret != 0) { PMD_DRV_LOG(ERR, "Get interface failed."); 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 6f46dbf5b7..8a55670f84 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"); rte_free(cpp);