From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (mails.dpdk.org [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 79B0342536; Thu, 7 Sep 2023 14:43:42 +0200 (CEST) Received: from mails.dpdk.org (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 132D3402AF; Thu, 7 Sep 2023 14:43:42 +0200 (CEST) Received: from mgamail.intel.com (mgamail.intel.com [134.134.136.65]) by mails.dpdk.org (Postfix) with ESMTP id 022834026C for ; Thu, 7 Sep 2023 14:43:39 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1694090620; x=1725626620; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=4vORtILKTvwWHhuUvwqpUDGbdqxGrmTobcU7BD4BPJI=; b=fEz/ScKApck8ubPAQA8E/NSJs37R+HgohFy6Zk38pluu5djhc50Kc5pK /2iEIWtFToQKVaWUnNG7JtOa/ykTAJRDlpiok8ly5mHfd8udxN2/HDDTl 527yq/uO8L/PHbd3dQ3XyMcJkdW7yGV8oYpM3RGhoELYqHR4piWOMp69v OM77RAguYGA208gDHzXXP1u9gIWKU6uBP5vCX+TfVRGwc61kmlcmUUXg6 QE1TVUwC3aYwy4VkQhDGTk0rtzQoqOLR3qUbdaZavnWZceQS/Xckq6iH2 NjaATTTE2+Pf+cp6V/zQLrbyUY+QuHn97JVSSODdnj236IPY5CqQ5sUQM Q==; X-IronPort-AV: E=McAfee;i="6600,9927,10825"; a="381126432" X-IronPort-AV: E=Sophos;i="6.02,235,1688454000"; d="scan'208";a="381126432" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Sep 2023 05:43:38 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=McAfee;i="6600,9927,10825"; a="771259823" X-IronPort-AV: E=Sophos;i="6.02,235,1688454000"; d="scan'208";a="771259823" Received: from fmsmsx601.amr.corp.intel.com ([10.18.126.81]) by orsmga008.jf.intel.com with ESMTP/TLS/AES256-GCM-SHA384; 07 Sep 2023 05:43:37 -0700 Received: from fmsmsx612.amr.corp.intel.com (10.18.126.92) by fmsmsx601.amr.corp.intel.com (10.18.126.81) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32; Thu, 7 Sep 2023 05:43:37 -0700 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx612.amr.corp.intel.com (10.18.126.92) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.32 via Frontend Transport; Thu, 7 Sep 2023 05:43:37 -0700 Received: from NAM04-BN8-obe.outbound.protection.outlook.com (104.47.74.45) by edgegateway.intel.com (192.55.55.68) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.2507.27; Thu, 7 Sep 2023 05:43:36 -0700 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=AQulyFZuTPUol4uPbwiCFp8jE6uR+8FsUXgz1xftNgVXasNMDhe42AxDP/Zmdwf+bRSXwuhwro8uhEcxKlboMA3sDrXuXcld8IHHb1F++JAp+z8fYqeFvtUSo+nd/esZBRjwHGrbKmPgM9NMyLZthJcUyYcmtzVgIdj6L1iXHFmlhaSBgGO3zi33LX/f4bax3Azcf1//jNFgXAvXW/6vXI4qENRAjdbn5bgEE0Mb+Bu+7pNII64DJaQ8YmB2t2bbb0JeYyvCHw5O6FAv20BR4PeMZV5qwLCY5DZ2GpFIWGpvU4/qYFMw7Wf/P7tVn9YmvKu883cbMZV2qb6nXnEU2g== 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=qnTf3mKNSBWSIsf6dgexu/MhLGESB96+ZJS+LuT5V5s=; b=aaZdBte2nu1gK3EGZoelkmmt59ciwHqtfKhbeSI8CEck0EeCIKaeTC3mOqZiqwZkR1I5onkBZ/Hzp9A7+BlyR1bIbLBe+uIep3aUEkIGfdyiTPVtAREiK7WcRYFGlnPdPLRysoUTUyKopCC9fRMmCtGAPalt1w0zd64soD/gvWzan39YNCiblkZlQCIkHwas0rkJZOvjYXXSyxoAL+guP66Jr01J1IFog8x4FyhEsrrP73OeeV2oc8gz6xdpz/y1GLaNl9HuKZjFg1PjW3kmIEbDpyDafYlJ1PtDXL4AjPQOnzUE/YtKKoHqTaw5ytzeMjoMTrQBE6KSUNN/mp2riQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=intel.com; dmarc=pass action=none header.from=intel.com; dkim=pass header.d=intel.com; arc=none Received: from CH3PR11MB8362.namprd11.prod.outlook.com (2603:10b6:610:175::6) by LV2PR11MB5998.namprd11.prod.outlook.com (2603:10b6:408:17e::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6745.32; Thu, 7 Sep 2023 12:43:33 +0000 Received: from CH3PR11MB8362.namprd11.prod.outlook.com ([fe80::88c2:332c:5e8a:25e]) by CH3PR11MB8362.namprd11.prod.outlook.com ([fe80::88c2:332c:5e8a:25e%7]) with mapi id 15.20.6768.029; Thu, 7 Sep 2023 12:43:33 +0000 From: "Xia, Chenbo" To: David Marchand , "dev@dpdk.org" CC: "thomas@monjalon.net" , "ferruh.yigit@amd.com" , "nipun.gupta@amd.com" , "Richardson, Bruce" , "Burakov, Anatoly" , Jay Zhou , "McDaniel, Timothy" , Julien Aube , Rahul Lakkireddy , "Guo, Junfeng" , Jeroen de Borst , Rushil Gupta , Joshua Washington , Dongdong Liu , Yisen Zhuang , "Maxime Coquelin" , Gaetan Rivet Subject: RE: [PATCH v2 04/15] bus/pci: find PCI capability Thread-Topic: [PATCH v2 04/15] bus/pci: find PCI capability Thread-Index: AQHZ1CO7Hw0jmQkPA0SBfbe/UjXEsbAN5i6A Date: Thu, 7 Sep 2023 12:43:32 +0000 Message-ID: References: <20230803075038.307012-1-david.marchand@redhat.com> <20230821113549.3191921-1-david.marchand@redhat.com> <20230821113549.3191921-5-david.marchand@redhat.com> In-Reply-To: <20230821113549.3191921-5-david.marchand@redhat.com> Accept-Language: en-US, zh-CN Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=intel.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: CH3PR11MB8362:EE_|LV2PR11MB5998:EE_ x-ms-office365-filtering-correlation-id: 1aab986a-3bd7-4120-2c64-08dbafa00b84 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 33Sxd0tidWZw54UmcdYerGobQsXCidGhnwsah0fEK9R2KG2guRfuWh+Nv76DieADbeM52kDpq4U9X/w1VudsdOMTanX2DG57AzmfMkUn71OZ2Xga0KBV+LwAhoNNOMH1QilDdpN7ZulfdJs17IuKqTPUWJj9KlWIoCjc/6vEoki3m+TawUaek9vbBERe6HMpojp1OtrcOoZqCCmq993/mcVWGEwV8BsBmsUZ+atrLC8UEaMdXf3KttGu/WjZzW+rIX6tBqrxn7goQgEuDnayhtsKaT1kCWUG78fM07AYcicYg2uwwmZ6RcY0e1HxrTnFpMOtkv5kvixyP3ZjO83O24ykiPeX3QD9kgqNbgv+bKF34eVKWc9B69nebrGoR5NMsV+Zi9/tSC6doA9ydH/Qcy6I55pFQIDSnmYDVwwd9ZudkDY3hoEYXIcxk6Rc6dRdkMtqoFLuhJY8a+BiZh6NfV88TXuG9cUW03CO+/drLX+Vc1OenIQe1nt1Ukl2q2F5VjDLfj5EcfHtsjtvPCtGmMXmNYYezH4Pxj2OY5kTLD+rtFx3L8tspmHP6X7U1GY9PONOIJMSMkzU9gBaK8d2Uz+04O/CrAGpy2tAIwoGzabu6rBWn4s9wd1eN66z9wDR x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:CH3PR11MB8362.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230031)(39860400002)(136003)(366004)(346002)(376002)(396003)(186009)(451199024)(1800799009)(66446008)(2906002)(110136005)(66946007)(86362001)(76116006)(66556008)(33656002)(316002)(55016003)(66476007)(64756008)(54906003)(8936002)(52536014)(5660300002)(8676002)(4326008)(41300700001)(9686003)(83380400001)(30864003)(38070700005)(38100700002)(7416002)(122000001)(82960400001)(6506007)(478600001)(26005)(7696005)(53546011)(71200400001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?8oVbc1AMCqgwT7IpcHi6B8q/XFwJGN1Fx66RzbLYIkvRAbSflcacrRuQXu3A?= =?us-ascii?Q?DvdzYTfA2JowDC4fiNEaUqWtqHLkZmDsnBJukKTwnj/z0w71y0MCeAW6vuai?= =?us-ascii?Q?OCgJGeHUoe9ijxB5odOKtX4HYw8hsqTb4qMiamHYB+c6cuUMgldk3WqewzCe?= =?us-ascii?Q?gKfwNgOr0VyaHlLkKQ+XYcYCqQ0XRW3GD4Fe7/nv67otshftJE3thaGfCohd?= =?us-ascii?Q?KkzOnfTbkhPW3uBtaPsVd/AC6DbNnO915Jp76TnjATBjxBpomoRC60hWh7lQ?= =?us-ascii?Q?pkVvMEAqjSkaiP6brawfe9b79JRpqo90LhwToQy4vd6Wu6Kg0PFWrOHqsP/w?= =?us-ascii?Q?KIxLoNIlGSAQxym6+jidKzzeohIHb0MqLFtQcqiNdonAFYQ33toQXaEfAQk3?= =?us-ascii?Q?x3x7EImcLfv4vS8lmL6aPtlqyqspoZsLtm3cw2iuIiVhokwqzzE9uEiv8pDb?= =?us-ascii?Q?P0kcPY1BXm9ACwK3V0cuE9X/mgIW6nWCeV3CM4N7NMTGrdHf42Q+mrpV6mKx?= =?us-ascii?Q?tXT8nn0Ir/Kf+6CMYZUAlIsOAdhou0cJ5mXdIqN5SCRMKFI2j2VQeFUKLYA5?= =?us-ascii?Q?NqH8GbHBxFOzWkpQn7zTBCTj01BUUapJeZNcoI8r95YGcCgt6JD8fsfxNmKY?= =?us-ascii?Q?8KD1dSk02fEr43zOLQxtqro1XM2wT0QDuZE1vw4xArl2qlQVy/ev8FDRlc2R?= =?us-ascii?Q?HhaxfZaoJ7yksz81is2WbhoBi0vAk8wQDxIOY6vJSTUIBZ4u6mMlHTf7FFtd?= =?us-ascii?Q?DuOWc77EwYVlMtcdCaIDsLSkyQbTm3JyfACjAeMiGdW5vnEqm5NeYqx7v4Lg?= =?us-ascii?Q?N4KV2Izc78B8mijS3F+uLrIJlYAbi97IklzwrHR67gWQoxDELznLNO317Tqb?= =?us-ascii?Q?t9/ZeWh/ejBVcOccXgQR2d5LIubAlYTksorapzrL+gObn5N9qwDWVefhSi3H?= =?us-ascii?Q?99lHCGnLeXgZHlt5eSdL45BTObwUtIOKDykQOypEy6cucRjzhy1gJ/k9W4pG?= =?us-ascii?Q?60KLy7ydKf9O/ONIc2mju1rEqUCW4Hy0GeQ3EoGyj8xmaevmVy8kZflhLP3A?= =?us-ascii?Q?PtIt/AbGSK38mClT6t+qSnGzWmas8t79IKcdEgt3H50CrKipzagF6lVhp8g2?= =?us-ascii?Q?HyjZb3CA/pnlA4218BcYuqecwqxtvdINxddTUws0WKAo7odHrzCGf9ZcNaor?= =?us-ascii?Q?pzu2BinanblOcOPeMWAi09DC70V/SAWFIAi8/cq090fLteTDVpwIsbFdwDeA?= =?us-ascii?Q?WrjibjPvd3gk6eyoVcKF2i5NuMhO7vAokv22F7kBjPAl/Vy1Fik8w+HrJP1W?= =?us-ascii?Q?vxcor/PTOpeEPqgospd+0mU+AmijtZfGIQ/V91yQ1+EIImVjpcpi7QfrU5fD?= =?us-ascii?Q?VDj7n2r5ABPmPl2eyCQOCem5ZbYeKpBmBoKFrnazCYubJTkR7oo3B0FEnI0h?= =?us-ascii?Q?M927Uaf7YsHUOZvg3DsqtohPLPiv/L4dxTHOANMm390bprJv80aCxuX9FtUK?= =?us-ascii?Q?h2cVsj7QDv9RikvcL4ePTIOoH2P5Nw/gdifSFaR/P4K7GsTKZItaO8LG2g0c?= =?us-ascii?Q?zl37sWtZk2Kr9Mrmk10/kyzeN83Hthf033Q8nsLv?= Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: CH3PR11MB8362.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 1aab986a-3bd7-4120-2c64-08dbafa00b84 X-MS-Exchange-CrossTenant-originalarrivaltime: 07 Sep 2023 12:43:32.5383 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 46c98d88-e344-4ed4-8496-4ed7712e255d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 0puMTlVJ65eefSviJk1fJjiX+mcMwJVS522tEsZb8d5H0i7ZP7KGY8Vi6dKkqrubRec3Rdq+WY0giJGfyMT8uw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: LV2PR11MB5998 X-OriginatorOrg: intel.com 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 Hi David, > -----Original Message----- > From: David Marchand > Sent: Monday, August 21, 2023 7:36 PM > To: dev@dpdk.org > Cc: thomas@monjalon.net; ferruh.yigit@amd.com; Xia, Chenbo > ; nipun.gupta@amd.com; Richardson, Bruce > ; Burakov, Anatoly ; > Jay Zhou ; McDaniel, Timothy > ; Julien Aube ; Rahul > Lakkireddy ; Guo, Junfeng > ; Jeroen de Borst ; Rushil > Gupta ; Joshua Washington ; > Dongdong Liu ; Yisen Zhuang > ; Maxime Coquelin ; > Gaetan Rivet > Subject: [PATCH v2 04/15] bus/pci: find PCI capability >=20 > Introduce two helpers so that drivers stop reinventing the wheel when it > comes to finding capabilities in a device PCI configuration space. > Use it in existing drivers. >=20 > Note: > - base/ drivers code is left untouched, only some wrappers in cxgbe > are touched, > - bnx2x maintained a per device cache of capabilities, this code has been > reworked to only cache the capabilities used in this driver, >=20 > Signed-off-by: David Marchand > Acked-by: Bruce Richardson > --- > Changes since v1: > - updated commitlog, > - separated VFIO changes for using standard PCI helper in a separate > patch, > - marked new experimental symbols with current version, > - reordered defines in rte_pci.h, >=20 > --- > drivers/bus/pci/linux/pci_vfio.c | 74 ++++-------------- > drivers/bus/pci/pci_common.c | 45 +++++++++++ > drivers/bus/pci/rte_bus_pci.h | 31 ++++++++ > drivers/bus/pci/version.map | 4 + > drivers/crypto/virtio/virtio_pci.c | 57 +++++--------- > drivers/event/dlb2/pf/dlb2_main.c | 42 +--------- > drivers/net/bnx2x/bnx2x.c | 41 +++++----- > drivers/net/cxgbe/base/adapter.h | 28 +------ > drivers/net/gve/gve_ethdev.c | 46 ++--------- > drivers/net/gve/gve_ethdev.h | 4 - > drivers/net/hns3/hns3_ethdev_vf.c | 79 +++---------------- > drivers/net/virtio/virtio_pci.c | 121 +++++------------------------ > lib/pci/rte_pci.h | 11 +++ > 13 files changed, 186 insertions(+), 397 deletions(-) >=20 > diff --git a/drivers/bus/pci/linux/pci_vfio.c > b/drivers/bus/pci/linux/pci_vfio.c > index 958f8b3b52..614ed5d696 100644 > --- a/drivers/bus/pci/linux/pci_vfio.c > +++ b/drivers/bus/pci/linux/pci_vfio.c > @@ -110,74 +110,34 @@ static int > pci_vfio_get_msix_bar(const struct rte_pci_device *dev, > struct pci_msix_table *msix_table) > { > - int ret; > - uint32_t reg; > - uint16_t flags; > - uint8_t cap_id, cap_offset; > + off_t cap_offset; >=20 > - /* read PCI capability pointer from config space */ > - ret =3D rte_pci_read_config(dev, ®, sizeof(reg), > PCI_CAPABILITY_LIST); > - if (ret !=3D sizeof(reg)) { > - RTE_LOG(ERR, EAL, > - "Cannot read capability pointer from PCI config > space!\n"); > + cap_offset =3D rte_pci_find_capability(dev, PCI_CAP_ID_MSIX); I notice in some cases we use rte_pci_has_capability_list() to check first, then looking for specific cap, in other cases we don't use rte_pci_has_capability_list(). Since we define this API, should we always d= o the check? > + if (cap_offset < 0) > return -1; > - } >=20 > - /* we need first byte */ > - cap_offset =3D reg & 0xFF; > + if (cap_offset !=3D 0) { > + uint16_t flags; > + uint32_t reg; >=20 > - while (cap_offset) { > - > - /* read PCI capability ID */ > - ret =3D rte_pci_read_config(dev, ®, sizeof(reg), cap_offset); > - if (ret !=3D sizeof(reg)) { > + /* table offset resides in the next 4 bytes */ > + if (rte_pci_read_config(dev, ®, sizeof(reg), cap_offset + 4) > < 0) { > RTE_LOG(ERR, EAL, > - "Cannot read capability ID from PCI config > space!\n"); > + "Cannot read MSIX table from PCI config space!\n"); > return -1; > } >=20 > - /* we need first byte */ > - cap_id =3D reg & 0xFF; > - > - /* if we haven't reached MSI-X, check next capability */ > - if (cap_id !=3D PCI_CAP_ID_MSIX) { > - ret =3D rte_pci_read_config(dev, ®, sizeof(reg), > cap_offset); > - if (ret !=3D sizeof(reg)) { > - RTE_LOG(ERR, EAL, > - "Cannot read capability pointer from PCI > config space!\n"); > - return -1; > - } > - > - /* we need second byte */ > - cap_offset =3D (reg & 0xFF00) >> 8; > - > - continue; > + if (rte_pci_read_config(dev, &flags, sizeof(flags), cap_offset > + 2) < 0) { > + RTE_LOG(ERR, EAL, > + "Cannot read MSIX flags from PCI config space!\n"); > + return -1; > } > - /* else, read table offset */ > - else { > - /* table offset resides in the next 4 bytes */ > - ret =3D rte_pci_read_config(dev, ®, sizeof(reg), > cap_offset + 4); > - if (ret !=3D sizeof(reg)) { > - RTE_LOG(ERR, EAL, > - "Cannot read table offset from PCI config > space!\n"); > - return -1; > - } > - > - ret =3D rte_pci_read_config(dev, &flags, sizeof(flags), > cap_offset + 2); > - if (ret !=3D sizeof(flags)) { > - RTE_LOG(ERR, EAL, > - "Cannot read table flags from PCI config > space!\n"); > - return -1; > - } > - > - msix_table->bar_index =3D reg & RTE_PCI_MSIX_TABLE_BIR; > - msix_table->offset =3D reg & RTE_PCI_MSIX_TABLE_OFFSET; > - msix_table->size =3D > - 16 * (1 + (flags & RTE_PCI_MSIX_FLAGS_QSIZE)); >=20 > - return 0; > - } > + msix_table->bar_index =3D reg & RTE_PCI_MSIX_TABLE_BIR; > + msix_table->offset =3D reg & RTE_PCI_MSIX_TABLE_OFFSET; > + msix_table->size =3D 16 * (1 + (flags & > RTE_PCI_MSIX_FLAGS_QSIZE)); > } > + > return 0; > } >=20 > diff --git a/drivers/bus/pci/pci_common.c b/drivers/bus/pci/pci_common.c > index 382b0b8946..52272617eb 100644 > --- a/drivers/bus/pci/pci_common.c > +++ b/drivers/bus/pci/pci_common.c > @@ -813,6 +813,51 @@ rte_pci_get_iommu_class(void) > return iova_mode; > } >=20 > +bool > +rte_pci_has_capability_list(const struct rte_pci_device *dev) > +{ > + uint16_t status; > + > + if (rte_pci_read_config(dev, &status, sizeof(status), > RTE_PCI_STATUS) !=3D sizeof(status)) > + return false; > + > + return (status & RTE_PCI_STATUS_CAP_LIST) !=3D 0; > +} > + > +off_t > +rte_pci_find_capability(const struct rte_pci_device *dev, uint8_t cap) > +{ > + off_t offset; > + uint8_t pos; > + int ttl; > + > + offset =3D RTE_PCI_CAPABILITY_LIST; > + ttl =3D (RTE_PCI_CFG_SPACE_SIZE - RTE_PCI_STD_HEADER_SIZEOF) / > RTE_PCI_CAP_SIZEOF; > + > + if (rte_pci_read_config(dev, &pos, sizeof(pos), offset) < 0) > + return -1; > + > + while (pos && ttl--) { > + uint16_t ent; > + uint8_t id; > + > + offset =3D pos; > + if (rte_pci_read_config(dev, &ent, sizeof(ent), offset) < 0) > + return -1; > + > + id =3D ent & 0xff; > + if (id =3D=3D 0xff) > + break; > + > + if (id =3D=3D cap) > + return offset; > + > + pos =3D (ent >> 8); > + } > + > + return 0; > +} > + > off_t > rte_pci_find_ext_capability(const struct rte_pci_device *dev, uint32_t > cap) > { > diff --git a/drivers/bus/pci/rte_bus_pci.h b/drivers/bus/pci/rte_bus_pci.= h > index 75d0030eae..1ed33dbf3d 100644 > --- a/drivers/bus/pci/rte_bus_pci.h > +++ b/drivers/bus/pci/rte_bus_pci.h > @@ -68,6 +68,37 @@ void rte_pci_unmap_device(struct rte_pci_device *dev); > */ > void rte_pci_dump(FILE *f); >=20 > +/** > + * Check whether this device has a PCI capability list. > + * > + * @param dev > + * A pointer to rte_pci_device structure. > + * > + * @return > + * true/false > + */ > +__rte_experimental > +bool rte_pci_has_capability_list(const struct rte_pci_device *dev); > + > +/** > + * Find device's PCI capability. > + * > + * @param dev > + * A pointer to rte_pci_device structure. > + * > + * @param cap > + * Capability to be found, which can be any from > + * RTE_PCI_CAP_ID_*, defined in librte_pci. > + * > + * @return > + * > 0: The offset of the next matching capability structure > + * within the device's PCI configuration space. > + * < 0: An error in PCI config space read. > + * =3D 0: Device does not support it. > + */ > +__rte_experimental > +off_t rte_pci_find_capability(const struct rte_pci_device *dev, uint8_t > cap); > + > /** > * Find device's extended PCI capability. > * > diff --git a/drivers/bus/pci/version.map b/drivers/bus/pci/version.map > index a0000f7938..2674f30235 100644 > --- a/drivers/bus/pci/version.map > +++ b/drivers/bus/pci/version.map > @@ -25,6 +25,10 @@ EXPERIMENTAL { > # added in 23.07 > rte_pci_mmio_read; > rte_pci_mmio_write; > + > + # added in 23.11 > + rte_pci_find_capability; > + rte_pci_has_capability_list; > }; >=20 > INTERNAL { > diff --git a/drivers/crypto/virtio/virtio_pci.c > b/drivers/crypto/virtio/virtio_pci.c > index 95a43c8801..abc52b4701 100644 > --- a/drivers/crypto/virtio/virtio_pci.c > +++ b/drivers/crypto/virtio/virtio_pci.c > @@ -19,7 +19,6 @@ > * we can't simply include that header here, as there is no such > * file for non-Linux platform. > */ > -#define PCI_CAPABILITY_LIST 0x34 > #define PCI_CAP_ID_VNDR 0x09 > #define PCI_CAP_ID_MSIX 0x11 >=20 > @@ -343,8 +342,9 @@ get_cfg_addr(struct rte_pci_device *dev, struct > virtio_pci_cap *cap) > static int > virtio_read_caps(struct rte_pci_device *dev, struct virtio_crypto_hw *hw= ) > { > - uint8_t pos; > struct virtio_pci_cap cap; > + uint16_t flags; > + off_t pos; > int ret; >=20 > if (rte_pci_map_device(dev)) { > @@ -352,44 +352,26 @@ virtio_read_caps(struct rte_pci_device *dev, struct > virtio_crypto_hw *hw) > return -1; > } >=20 > - ret =3D rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST); > - if (ret < 0) { > - VIRTIO_CRYPTO_INIT_LOG_DBG("failed to read pci capability > list"); > - return -1; > + /* > + * Transitional devices would also have this capability, > + * that's why we also check if msix is enabled. > + */ > + pos =3D rte_pci_find_capability(dev, PCI_CAP_ID_MSIX); > + if (pos > 0 && rte_pci_read_config(dev, &flags, sizeof(flags), > + pos + 2) =3D=3D sizeof(flags)) { > + if (flags & PCI_MSIX_ENABLE) > + hw->use_msix =3D VIRTIO_MSIX_ENABLED; > + else > + hw->use_msix =3D VIRTIO_MSIX_DISABLED; > + } else { > + hw->use_msix =3D VIRTIO_MSIX_NONE; > } >=20 > - while (pos) { > - ret =3D rte_pci_read_config(dev, &cap, sizeof(cap), pos); > - if (ret < 0) { > - VIRTIO_CRYPTO_INIT_LOG_ERR( > - "failed to read pci cap at pos: %x", pos); > - break; > - } > - > - if (cap.cap_vndr =3D=3D PCI_CAP_ID_MSIX) { > - /* Transitional devices would also have this capability, > - * that's why we also check if msix is enabled. > - * 1st byte is cap ID; 2nd byte is the position of next > - * cap; next two bytes are the flags. > - */ > - uint16_t flags =3D ((uint16_t *)&cap)[1]; > - > - if (flags & PCI_MSIX_ENABLE) > - hw->use_msix =3D VIRTIO_MSIX_ENABLED; > - else > - hw->use_msix =3D VIRTIO_MSIX_DISABLED; > - } > - > - if (cap.cap_vndr !=3D PCI_CAP_ID_VNDR) { > - VIRTIO_CRYPTO_INIT_LOG_DBG( > - "[%2x] skipping non VNDR cap id: %02x", > - pos, cap.cap_vndr); > - goto next; > - } > - > + pos =3D rte_pci_find_capability(dev, PCI_CAP_ID_VNDR); The logic of vendor cap init seems incorrect. Virtio devices have multiple Vendor cap (different cfg type). But now the logic seems to only init the f= irst one. > + if (pos > 0 && rte_pci_read_config(dev, &cap, sizeof(cap), pos) =3D=3D > sizeof(cap)) { > VIRTIO_CRYPTO_INIT_LOG_DBG( > "[%2x] cfg type: %u, bar: %u, offset: %04x, len: %u", > - pos, cap.cfg_type, cap.bar, cap.offset, cap.length); > + (unsigned int)pos, cap.cfg_type, cap.bar, cap.offset, > cap.length); >=20 > switch (cap.cfg_type) { > case VIRTIO_PCI_CAP_COMMON_CFG: > @@ -411,9 +393,6 @@ virtio_read_caps(struct rte_pci_device *dev, struct > virtio_crypto_hw *hw) > hw->isr =3D get_cfg_addr(dev, &cap); > break; > } > - > -next: > - pos =3D cap.cap_next; > } ... > diff --git a/drivers/net/virtio/virtio_pci.c > b/drivers/net/virtio/virtio_pci.c > index 29eb739b04..9fd9db3e03 100644 > --- a/drivers/net/virtio/virtio_pci.c > +++ b/drivers/net/virtio/virtio_pci.c > @@ -20,7 +20,6 @@ > * we can't simply include that header here, as there is no such > * file for non-Linux platform. > */ > -#define PCI_CAPABILITY_LIST 0x34 > #define PCI_CAP_ID_VNDR 0x09 > #define PCI_CAP_ID_MSIX 0x11 >=20 > @@ -38,46 +37,16 @@ struct virtio_pci_internal > virtio_pci_internal[RTE_MAX_ETHPORTS]; > static enum virtio_msix_status > vtpci_msix_detect(struct rte_pci_device *dev) > { > - uint8_t pos; > - int ret; > + uint16_t flags; > + off_t pos; >=20 > - ret =3D rte_pci_read_config(dev, &pos, 1, PCI_CAPABILITY_LIST); > - if (ret !=3D 1) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci capability list, ret %d", ret); > - return VIRTIO_MSIX_NONE; > - } > - > - while (pos) { > - uint8_t cap[2]; > - > - ret =3D rte_pci_read_config(dev, cap, sizeof(cap), pos); > - if (ret !=3D sizeof(cap)) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci cap at pos: %x ret %d", > - pos, ret); > - break; > - } > - > - if (cap[0] =3D=3D PCI_CAP_ID_MSIX) { > - uint16_t flags; > - > - ret =3D rte_pci_read_config(dev, &flags, sizeof(flags), > - pos + sizeof(cap)); > - if (ret !=3D sizeof(flags)) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci cap at pos:" > - " %x ret %d", pos + 2, ret); > - break; > - } > - > - if (flags & PCI_MSIX_ENABLE) > - return VIRTIO_MSIX_ENABLED; > - else > - return VIRTIO_MSIX_DISABLED; > - } > - > - pos =3D cap[1]; > + pos =3D rte_pci_find_capability(dev, PCI_CAP_ID_MSIX); > + if (pos > 0 && rte_pci_read_config(dev, &flags, sizeof(flags), > + pos + 2) =3D=3D sizeof(flags)) { > + if (flags & PCI_MSIX_ENABLE) > + return VIRTIO_MSIX_ENABLED; > + else > + return VIRTIO_MSIX_DISABLED; > } >=20 > return VIRTIO_MSIX_NONE; > @@ -623,8 +592,8 @@ static int > virtio_read_caps(struct rte_pci_device *pci_dev, struct virtio_hw *hw) > { > struct virtio_pci_dev *dev =3D virtio_pci_get_dev(hw); > - uint8_t pos; > struct virtio_pci_cap cap; > + off_t pos; > int ret; >=20 > if (rte_pci_map_device(pci_dev)) { > @@ -632,72 +601,25 @@ virtio_read_caps(struct rte_pci_device *pci_dev, > struct virtio_hw *hw) > return -1; > } >=20 > - ret =3D rte_pci_read_config(pci_dev, &pos, 1, PCI_CAPABILITY_LIST); > - if (ret !=3D 1) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci capability list, ret %d", ret); > - return -1; > - } > - > - while (pos) { > - ret =3D rte_pci_read_config(pci_dev, &cap, 2, pos); > - if (ret !=3D 2) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci cap at pos: %x ret %d", > - pos, ret); > - break; > - } > - > - if (cap.cap_vndr =3D=3D PCI_CAP_ID_MSIX) { > - /* Transitional devices would also have this capability, > - * that's why we also check if msix is enabled. > - * 1st byte is cap ID; 2nd byte is the position of next > - * cap; next two bytes are the flags. > - */ > - uint16_t flags; > - > - ret =3D rte_pci_read_config(pci_dev, &flags, sizeof(flags), > - pos + 2); > - if (ret !=3D sizeof(flags)) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci cap at pos:" > - " %x ret %d", pos + 2, ret); > - break; > - } > - > - if (flags & PCI_MSIX_ENABLE) > - dev->msix_status =3D VIRTIO_MSIX_ENABLED; > - else > - dev->msix_status =3D VIRTIO_MSIX_DISABLED; > - } > - > - if (cap.cap_vndr !=3D PCI_CAP_ID_VNDR) { > - PMD_INIT_LOG(DEBUG, > - "[%2x] skipping non VNDR cap id: %02x", > - pos, cap.cap_vndr); > - goto next; > - } > - > - ret =3D rte_pci_read_config(pci_dev, &cap, sizeof(cap), pos); > - if (ret !=3D sizeof(cap)) { > - PMD_INIT_LOG(DEBUG, > - "failed to read pci cap at pos: %x ret %d", > - pos, ret); > - break; > - } > + /* > + * Transitional devices would also have this capability, > + * that's why we also check if msix is enabled. > + */ > + dev->msix_status =3D vtpci_msix_detect(pci_dev); >=20 > + pos =3D rte_pci_find_capability(pci_dev, PCI_CAP_ID_VNDR); > + if (pos > 0 && rte_pci_read_config(pci_dev, &cap, sizeof(cap), pos) > =3D=3D sizeof(cap)) { > PMD_INIT_LOG(DEBUG, > "[%2x] cfg type: %u, bar: %u, offset: %04x, len: %u", > - pos, cap.cfg_type, cap.bar, cap.offset, cap.length); > + (unsigned int)pos, cap.cfg_type, cap.bar, cap.offset, > cap.length); >=20 Same comment about the vendor cap. Thanks, Chenbo > switch (cap.cfg_type) { > case VIRTIO_PCI_CAP_COMMON_CFG: > dev->common_cfg =3D get_cfg_addr(pci_dev, &cap); > break; > case VIRTIO_PCI_CAP_NOTIFY_CFG: > - ret =3D rte_pci_read_config(pci_dev, > - &dev->notify_off_multiplier, > - 4, pos + sizeof(cap)); > + ret =3D rte_pci_read_config(pci_dev, &dev- > >notify_off_multiplier, > + 4, pos + sizeof(cap)); > if (ret !=3D 4) > PMD_INIT_LOG(DEBUG, > "failed to read notify_off_multiplier, > ret %d", > @@ -712,9 +634,6 @@ virtio_read_caps(struct rte_pci_device *pci_dev, > struct virtio_hw *hw) > dev->isr =3D get_cfg_addr(pci_dev, &cap); > break; > } > - > -next: > - pos =3D cap.cap_next; > } >=20 > if (dev->common_cfg =3D=3D NULL || dev->notify_base =3D=3D NULL || > diff --git a/lib/pci/rte_pci.h b/lib/pci/rte_pci.h > index aab761b918..49fd5b1d02 100644 > --- a/lib/pci/rte_pci.h > +++ b/lib/pci/rte_pci.h > @@ -28,13 +28,24 @@ extern "C" { > #define RTE_PCI_CFG_SPACE_SIZE 256 > #define RTE_PCI_CFG_SPACE_EXP_SIZE 4096 >=20 > +#define RTE_PCI_STD_HEADER_SIZEOF 64 > + > +/* Standard register offsets in the PCI configuration space */ > #define RTE_PCI_VENDOR_ID 0x00 /* 16 bits */ > #define RTE_PCI_DEVICE_ID 0x02 /* 16 bits */ > #define RTE_PCI_COMMAND 0x04 /* 16 bits */ > +#define RTE_PCI_STATUS 0x06 /* 16 bits */ > +#define RTE_PCI_CAPABILITY_LIST 0x34 /* 32 bits */ >=20 > /* PCI Command Register */ > #define RTE_PCI_COMMAND_MASTER 0x4 /* Bus Master Enable */ >=20 > +/* PCI Status Register (RTE_PCI_STATUS) */ > +#define RTE_PCI_STATUS_CAP_LIST 0x10 /* Support Capability List > */ > + > +/* Capability registers (RTE_PCI_CAPABILITY_LIST) */ > +#define RTE_PCI_CAP_SIZEOF 4 > + > /* PCI Express capability registers */ > #define RTE_PCI_EXP_DEVCTL 8 /* Device Control */ >=20 > -- > 2.41.0