From patchwork Fri Sep 15 09:15:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Chaoyong He X-Patchwork-Id: 131502 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 CD0CA425A3; Fri, 15 Sep 2023 11:19:47 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D1284427D7; Fri, 15 Sep 2023 11:17:16 +0200 (CEST) Received: from NAM10-MW2-obe.outbound.protection.outlook.com (mail-mw2nam10on2136.outbound.protection.outlook.com [40.107.94.136]) by mails.dpdk.org (Postfix) with ESMTP id D528B42DC3 for ; Fri, 15 Sep 2023 11:17:15 +0200 (CEST) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=WDyoUz+TaOxEWZ1hEMXN43ZbodFcfRqfA4duHHm5tCi7jZsb6R7TWMvuyMmu7hZ06k6WXElfHlcNExduxQn0V3Zj4Gc4rSPMYxQzArRVmAI3YHdYi/nUaG4mcOsitg6dNj/hVsbHGfOy7FiPGGo03Ots5trkna1t8A7CoTinvQQUpJ/XdKka7dwmVdbdn4ldZ+SNz84UZoYosEyKh2/a7oVt5sGuHMceMfNFp/SaqJv6RiKvwYyGPQ/2IDXMpwvCemmjTut7RhpMkoHzsWpsy30jscIspUGMBZ8v+CEDbHgKmXguHrZwgCae5A6FNRnNk27guXmSnEYN9tZBG7+0hQ== 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=1Kp5amb6oWLByTOFQYeOZJkjVtcsT9Fw5vJd7oOAYws=; b=V6d5mZaQorybYXSG2GK2oUb76GAQNemCx28sNCAUl4QOaIPWu3nCSe8R55b3xW2njieN+f0MsmTrA7zhu6NXap9GuadMjDDqiqiBdmoXvkMlLhvAfbCnw+R9lZZijPtXDB5D0fJUbAgAGuT4EynJhkRJxOCKj3PEoTDvFBsHhwn4CHchJ173KYMpfgnXVRtefMC4s0XIzhYXnqcui6OsZo0xDpSwd27z6oxhGMzXaDLd7SY/HhbyviU+NCaKNkrqw72w9eqih1iOZt3ExQW9NN96E1XP7RJqtzrQVgp+BZtR3HmI3NaPPnzCgkOvgdYh30H86ENmUUnDKuKUCbVQhA== 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=1Kp5amb6oWLByTOFQYeOZJkjVtcsT9Fw5vJd7oOAYws=; b=boWGTra4zFmV8ujn8PVZvY31cBnpiK4ijRljqqT+tH5euPesXkMIlexCfTYR2YHYDZdmj3HyZPzazU0h7HwHBUsEnBLSzyFuJDTLJXmqdvEFa8Fduz/eWYZmV8bAsiOV/K2ZvdajlGH5SU9zPO4SllKV/LIM1vzj82guiXtN7UU= 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 CH3PR13MB6387.namprd13.prod.outlook.com (2603:10b6:610:19a::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6792.21; Fri, 15 Sep 2023 09:17:12 +0000 Received: from SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::c05c:6915:1628:70c4]) by SJ0PR13MB5545.namprd13.prod.outlook.com ([fe80::c05c:6915:1628:70c4%7]) with mapi id 15.20.6768.029; Fri, 15 Sep 2023 09:17:11 +0000 From: Chaoyong He To: dev@dpdk.org Cc: oss-drivers@corigine.com, Chaoyong He , =?utf-8?q?Niklas_S=C3=B6derlund?= Subject: [PATCH v3 27/27] net/nfp: extend the usage of nfp BAR from 8 to 24 Date: Fri, 15 Sep 2023 17:15:51 +0800 Message-Id: <20230915091551.1459606-28-chaoyong.he@corigine.com> X-Mailer: git-send-email 2.39.1 In-Reply-To: <20230915091551.1459606-1-chaoyong.he@corigine.com> References: <20230830021457.2064750-1-chaoyong.he@corigine.com> <20230915091551.1459606-1-chaoyong.he@corigine.com> X-ClientProxiedBy: PH7PR10CA0017.namprd10.prod.outlook.com (2603:10b6:510:23d::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_|CH3PR13MB6387:EE_ X-MS-Office365-Filtering-Correlation-Id: 77566d6e-6eee-4b20-075e-08dbb5cc8b0d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: yjmu5Q3Q85hiiW32wcLM/bfvxFElQiE5fVmxm+2c6MVA6x3hs6l5IEdjvSxceo3Dtr6m3xcRn+TiYZOvNcdODn0yI0dRMew2sO3+vhF+5Jqhnjf3yxJZ+gnMW8KMrMBgbj81PNxHCWD8+uJIDCo+SRgnRVB8oFB5bvv9ZdjT2OGJiiPZSJFJeedh+r+qW3aE9ravWuPffcbd7CZtLKSqqREFLMwZ1SaXjAyrOLFdOZ7rbEc94y5Le4epyAPU4agSJRs8xmKujk96bNKDFAuoA5T9vRMbMUT1/bP5DMEDdoLrPPM7+gvZAAbiP82vy3BQTtRpFSwGCFbDzsASLPaz8Vx+1uFKnB1Yu2QaybyOzOJJFTms71xQG3ZDm8Q1ZDhEt4TayEzo5iHDxQYbmLZ7pKWiyEFtIn3i0Ah+7yvVxGxu61ekBI8cZ6YPIj4ocwKri0ia1boimtKZjJvOlxQriKG4miZr+x/WMICsar3gXAXAb5HeDVCHYU5wJnilOdSafEFWKP4NTjkajb31pDsW1J4vK26WY4QqlBCzMjamX9MGj81j/qf0hxWWuewYs36tMuhrQFq0I2Q487gIJAQT+vOb/PR/9A+8hj8yM9QMTMAVF6rdICfWJ2Lj5RJp3X7vV6usZEQvxZ1q+EmM4XC8cprox7k2t1cwtfJPXQl1rZc= 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)(39840400004)(346002)(396003)(376002)(366004)(136003)(451199024)(1800799009)(186009)(107886003)(38350700002)(2906002)(2616005)(38100700002)(66574015)(86362001)(26005)(30864003)(1076003)(4326008)(44832011)(8936002)(8676002)(41300700001)(5660300002)(54906003)(316002)(36756003)(6916009)(66946007)(66476007)(66556008)(83380400001)(6666004)(6486002)(6512007)(6506007)(52116002)(478600001); DIR:OUT; SFP:1102; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?q?nnro/0hbCBCAUDphYB9ffry7Kuq/?= =?utf-8?q?bQfhNmfv4XPVdmlakhPAYEJezcJWY2Si+FSFpR0g/61DxxDSUnnEh2Ko+M5mGUqSY?= =?utf-8?q?wJXG28EAcGb8O06jfUIk85zAI5+EqfcJcRQGluPxe28H16aySrTpdyK2sMlKodcRW?= =?utf-8?q?CYK1iEjez/czgaYM06F4Kfux/9DY+LF04xZGoji0OdyY8VutYNYkMj19k54yxp+2z?= =?utf-8?q?dfuQ4HN52y4Qu/x7zrannzzmeowj0tPRzy8/1X+wgA0XcjKOBQV3i90bJXf96PDNt?= =?utf-8?q?ATmd9YEmrEplzKpjj2HJnnJU/tkyKD3S361T3bleEgiKBAVol5Bgy7MZ3P1ZgtprN?= =?utf-8?q?0Dwdr12280zRZfOmVNdPPDTh3tY2zQOkiomvFXcpIuiM7HNoaxDZh+cQhOX3w5Yi/?= =?utf-8?q?I21WQCO/8CMy2kx+bbr7CawTlOtu9aM2s4N3KTcmNC7zvFGwc+WwZM8BB1Ggz7IqA?= =?utf-8?q?pekGvLqtNgTMyRxtW1bnl3EGE3A3+SKHRlimkqsLnVikEE6u3vxSQmVVGkPjmSwiF?= =?utf-8?q?e3/XeijxMIMVv0kkypyQ4DnpywBSZ44nf5u6KppuG2SFesoKARnlFC1qyhPUdqu5H?= =?utf-8?q?Eyxq/2jFLATCMcq3M8Z7dLcaTDXo8/5CN/Vo52gH+kf0HiIt8nRf6cuZXNxyxM5Of?= =?utf-8?q?vfRigbgxwfAniQsKcUf49UjPJ6aHgJn0nAXl+QbAvG0YrJ8YKKB9CSgy3ZzM+M/fX?= =?utf-8?q?sZjloQ/UOXNwoJ266GDUwnFZZGdiFphi3uiG4kPy4TRU2cGE6U3pi+ZuK3rVxqZ1D?= =?utf-8?q?MbE2PJvW+WmoWVbePlETfpmVTtlj2xnI7Ial5Mt7s7uMXZlx8F9rJ9LNXigagDTYW?= =?utf-8?q?pMkBLcDObyff0jvoj5vwrLl9cAULbDVaHZ1agqKAm9zGTzB8pmdgHue5y9y0GKZfK?= =?utf-8?q?Umg26HEiUo8riIIU2hLuZ71pvjq86QPpJCU5he+boye3aRVPCgLMN6y9d55FK4aVp?= =?utf-8?q?JubjfYm3pHG4Lr1Eh+KYAvxdtiDDG+9SWUmvWH7Zfjg8Db/0u0DxPxuOyssPbKSqG?= =?utf-8?q?R7Pv/NthTrl/e20oXF9OfUKcfhgOv0jBW90AZushbqxYCqcJIfIBmxjyOBCTBSKNP?= =?utf-8?q?5pP/lVWwddSwDwJUJ7xs0DLbf60OFhBzvzBBjwKm31DqPZVT9gpd+z/i5Q1DYmbJv?= =?utf-8?q?uJbKUEJNoyc1AN3X1IhwsXPrwyvDcS/T8V4eO2Hi+wbQCrUdBE5WybMWKyeJr2EyG?= =?utf-8?q?C9c2graQZq2XrXlabWWL6BcBkY3bh2iCD15/HALInyfe/dZlKo3geG4dbqhqMSq/k?= =?utf-8?q?95DTSbXfbAlmXK0w22+aMrI1LPIGEqAD4V78tEOoFTx7v13Vp41U9sdDfU4LSjOWr?= =?utf-8?q?CivnRMFqTeeeC1h72AC6SEr4sTURW131YJNI8IiLRCUrHsO1KI1GSWz6uM5k6C8gE?= =?utf-8?q?xtFCyw7yDth0hre1H7vm1h+d+Iip7R8Wd2CTXIW4M3WqvOcq1dCCn2CGqQp0g/H5s?= =?utf-8?q?Z22B4fT0g46MEdUNGhPLj73U254Bz721j/wqfJI2Kno6trTQeH97Y+cmLKItENfNB?= =?utf-8?q?PJ5pd5V1E5NCWSxC7jG/ZqY1mz2jnvPCLw=3D=3D?= X-OriginatorOrg: corigine.com X-MS-Exchange-CrossTenant-Network-Message-Id: 77566d6e-6eee-4b20-075e-08dbb5cc8b0d X-MS-Exchange-CrossTenant-AuthSource: SJ0PR13MB5545.namprd13.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Sep 2023 09:17:11.6845 (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: CyWjOd3xpiYxO8xpd/pwKVvm04t0EG0jBReCV6WHz/Rr8oatVLwhR+b8/n3PwnU4l0ksO5E5zbDrF7vnAg2oOEk/biGqbj9DpaTwvOydnuk= X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH3PR13MB6387 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 | 478 ++++++++++++++++++------- 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, 349 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 e32ac1107c..709177a80e 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,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++; + } + } + + 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 (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); rte_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; @@ -800,6 +999,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 d70c8cd44a..92250c150a 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);