From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mails.dpdk.org (xvm-189-124.dc0.ghst.net [217.70.189.124]) by inbox.dpdk.org (Postfix) with ESMTP id 2D13EA0A02 for ; Mon, 4 Jan 2021 03:54:27 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id 1DE421606C4; Mon, 4 Jan 2021 03:54:27 +0100 (CET) Received: from mga18.intel.com (mga18.intel.com [134.134.136.126]) by mails.dpdk.org (Postfix) with ESMTP id B48531606B7; Mon, 4 Jan 2021 03:54:23 +0100 (CET) IronPort-SDR: G/b7jWDDtAaJs51feehf1iQ+0FNuiDF9kkNN7kCermpgYxIan9zxLH9A21lPSh7zURhNln0p7Z tQb1KVk4s7kA== X-IronPort-AV: E=McAfee;i="6000,8403,9853"; a="164608543" X-IronPort-AV: E=Sophos;i="5.78,472,1599548400"; d="scan'208";a="164608543" Received: from orsmga008.jf.intel.com ([10.7.209.65]) by orsmga106.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Jan 2021 18:54:22 -0800 IronPort-SDR: F5831CtN39eOOxfzQpR0mBHSaXKTlL8I7FAlMYGO655m8gSS/9C2dTAqzKtsVpGMnbYe5S0phw oSSAAIAcgv5w== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.78,472,1599548400"; d="scan'208";a="378242468" Received: from fmsmsx604.amr.corp.intel.com ([10.18.126.84]) by orsmga008.jf.intel.com with ESMTP; 03 Jan 2021 18:54:22 -0800 Received: from fmsmsx604.amr.corp.intel.com (10.18.126.84) by fmsmsx604.amr.corp.intel.com (10.18.126.84) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Sun, 3 Jan 2021 18:54:21 -0800 Received: from FMSEDG603.ED.cps.intel.com (10.1.192.133) by fmsmsx604.amr.corp.intel.com (10.18.126.84) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Sun, 3 Jan 2021 18:54:21 -0800 Received: from NAM12-MW2-obe.outbound.protection.outlook.com (104.47.66.46) 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.1713.5; Sun, 3 Jan 2021 18:54:19 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=YUVeBxJPTaoZgQlnb9Kaz7c8+hLvc+zdMnGritOSfI9lCAoJkFnzWPzqlIg9pNQVHf8NlgJQWqhHdDr1cwWWQLLY0ZVg0K/Xd+vKQ+pMZ3FWmgwjA9vcf+WEoqakV2pF3fdHYP+ycBQ6WPxjb5nanYpmwCpUyEy7RPeHr38ZdznGQfO6Y0He6xeG1jff+owmBbjcm+Grr07JR+uY+3YoCi9+25+xdxUPwk5BouJe2DwZXP61jfDAzK4Pb1TNc1qsIICZ+nsXKDXtTr32BhIc0qqgIJ43VA4zM1qyMSnlXgW+LZVDth+Zs/JClGFxwReIQv8CRffoXuAncBXs8w/RNw== 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-SenderADCheck; bh=L6AmSkBnM6PzNPKgxwmzHuJaiEr9P50oP+n8y/LHWO0=; b=SDVEgWv8RWmuMg8kOnPVq+77wMtuicIab9cbYdRe9afxTn3ChS5g9W6n1cfMlaX8OHAfKfQnN/jFCnw5hVoFf9caeSxyircAkErmtPRZZkcCADEKw8qKDXBS4rAa19IOUB0ou5CU938a1SqorEqSnIRZYOxFgsgz+0svJOyh48+1xbL7ePfI0c+JizmSQRSayo0ZLLKMMVp+gB4aYpjwlI+aZyNAQWc8Ww83NZkgqhOhZNa4Yv5VQCL+ZcEXB3Z7JDX09h9N0RuZyQrmzXr/JfMGRTrdtFQYbRcviC6bCyU8O5+EeIWJ3O1P7I2iwoGH8JkMYxTHbEy8yQmL0u3amQ== 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 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=intel.onmicrosoft.com; s=selector2-intel-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=L6AmSkBnM6PzNPKgxwmzHuJaiEr9P50oP+n8y/LHWO0=; b=vi1p3+x7vdzDEGHy+Uh0TPmhQbHcXYSWk6XyiAeA+qkYRr3iIIpkmaPlD/J2AApPgnWpC9M3Oo9rGZUGhcuAuwneRIJLqQItAhfJH3ZcxgR3WVtRy1fPH1s13x56AeGNo4tVJ8Av52eEAmt8JQSxGQVJDUlkzeLGJEKHVmFZ7/U= Received: from BYAPR11MB2901.namprd11.prod.outlook.com (2603:10b6:a03:91::23) by BYAPR11MB2840.namprd11.prod.outlook.com (2603:10b6:a02:c9::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3721.20; Mon, 4 Jan 2021 02:54:14 +0000 Received: from BYAPR11MB2901.namprd11.prod.outlook.com ([fe80::4946:fd9f:86f7:43f9]) by BYAPR11MB2901.namprd11.prod.outlook.com ([fe80::4946:fd9f:86f7:43f9%7]) with mapi id 15.20.3721.024; Mon, 4 Jan 2021 02:54:14 +0000 From: "Xu, Rosen" To: "Huang, Wei" , "dev@dpdk.org" , "Zhang, Qi Z" CC: "stable@dpdk.org" , "Zhang, Tianfei" Thread-Topic: [PATCH v4 3/4] raw/ifpga: add opae API for Cyborg Thread-Index: AQHW3n/VQ9A8UdA0oUqC99cpKkxqv6oS2o2QgAPXZICAABqtoA== Date: Mon, 4 Jan 2021 02:54:14 +0000 Message-ID: References: <1609314362-11174-1-git-send-email-wei.huang@intel.com> <1609314362-11174-4-git-send-email-wei.huang@intel.com> In-Reply-To: Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: dlp-product: dlpe-windows dlp-version: 11.5.1.3 dlp-reaction: no-action x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNGJlYTNhNTAtMjhhZS00ZDViLTljNmUtNjhmZDJiOTJiY2IwIiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoiR2lBeU9TRFR5Y0cwRVVNdTdzdWZ1ZmZUUmg5VGJKUThVSXVcLzZoTGlqUnpyZ0pcL0lGSDM0T1Q2a21kZ3BScXM5In0= x-ctpclassification: CTP_NT authentication-results: intel.com; dkim=none (message not signed) header.d=none;intel.com; dmarc=none action=none header.from=intel.com; x-originating-ip: [192.198.147.217] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: ec4a21c8-049d-4b35-8629-08d8b05c057f x-ms-traffictypediagnostic: BYAPR11MB2840: x-ld-processed: 46c98d88-e344-4ed4-8496-4ed7712e255d,ExtAddr x-ms-exchange-transport-forked: True x-microsoft-antispam-prvs: x-ms-oob-tlc-oobclassifiers: OLM:109; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: OHc3JQzsoTC4wZhxb5tBXMv0PxkrL62k2eskvYfkmweVNdKViY02CGpDj/PnFH/rY5yH4ypMLP7KqBlyn/vX6lZm3CtAvygYaXIrf4/8sedIBuoLy7Z4apR4uM2lWIcBuKK18LOVh1lfhGRjwC6lm/bTajDBZxIIo3xSXqXW/J5CGTMO3rTZMxaZu1KI8dDM4ks+reU29QRR/J9lbq3hoeKLJYWiMmU8JuJ/9s3AnYt1cuceD/QsSQmQkcUExClr6g3Vu2aSI4C74ifGtzxB0UMwVb2iok0RnmTyWdCVs2UXWltiN868csBsESEXQnK8VylPF9VD+XixPElhs7PYCfEQmVMoBfLIrw59jdpQFgYD8cRYcq4SMLKvTpTucEn6wLRYw2nrBjeD5NHVbp8bJQ== x-forefront-antispam-report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:BYAPR11MB2901.namprd11.prod.outlook.com; PTR:; CAT:NONE; SFS:(4636009)(396003)(346002)(376002)(136003)(39860400002)(366004)(26005)(2906002)(4326008)(30864003)(186003)(6636002)(86362001)(6506007)(107886003)(316002)(53546011)(54906003)(450100002)(110136005)(8936002)(9686003)(66946007)(76116006)(66476007)(64756008)(66446008)(66556008)(8676002)(7696005)(52536014)(55016002)(478600001)(5660300002)(83380400001)(33656002)(71200400001)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?Qg5eRc2UB/GaO0DEAyB6TKYSZlfSGigjEtNS/9xUqkSnUFNa7IEhqp8qXFwf?= =?us-ascii?Q?2uaVsg5beH2AJOX+fp6GOiWIWlY5LyfImViqmRPcO6akFgjtDTjSY+VXM8bG?= =?us-ascii?Q?/OqPoOoWN5eFe6b3te2STikVOuOb3PUVtiEnb9DVQi+VhCOrQ6f0nDp0F+PK?= =?us-ascii?Q?r2IwHg2OhnuDCtL1bvUqZvw2JE/L47RC0gbAqkcLlHHbuEkbxj0wBVhrICpc?= =?us-ascii?Q?jqxjOAxzolt3OWw/83keMbJ/73YAbhyRe7Fwe1Z5nBb6uxh1Do2CLgtiux2W?= =?us-ascii?Q?D3z+pwAxQYiVpYb5Aj/hAE61eAdLA6PKaTmVyZ4o6KEkcrhh8j8V46QoXeJa?= =?us-ascii?Q?WlQN0FSCTxThE4XLNr/0ivmjysCZQQeGRkD7zey3kLAHyx1WNe/J4DvOzhbj?= =?us-ascii?Q?OaqKHxfB6hjxKAj2TSlgiVAZxzdzg5rQbUtFghhV6jlqBhJ8Nss9iio73wSt?= =?us-ascii?Q?qD98zY7mTlJwQ4/sgZv3Rm7mVhnc640KSkt0R3Zpl/f6BrLUYHAS+JU9TUaE?= =?us-ascii?Q?GLsGDmWZvf1gScSgfGLx1SjQGpPW0i8kRenYGp2xDcwlMh+qFNoVSFQshm0p?= =?us-ascii?Q?7PQG1V02rC9Rom0xVvU1WtYGwiuf/H+4F9TLAlyqYS5JBWn66PUw0YT+pAdF?= =?us-ascii?Q?A3FFZZ0+0ujCKoCA0rDfTBArsTrDTip8BL5azSqpFqKBTiVAi5t5mjT49U67?= =?us-ascii?Q?5mvOb1MyxpxZem9B6D8lkJiAN0GxG0ddPbxLQr18lJZiYXHzqVMaC+FQqMls?= =?us-ascii?Q?Uw+XdcK6mnJt85W5Q4Pivu8hzinEcOQlZzj5IPlQtxKq8HCBblDz9lSnHr3u?= =?us-ascii?Q?TdAfkCaiOkWXk2YNMyQlwIN8hZw6oHJW5JaXuGXf5Eu51Az6ZNUzo6F7wEMX?= =?us-ascii?Q?rc7SKiinqJKf0Gu5bcyItnevYElnlv/1zgkY9cKrzRw1JEgFkVVjZ2zQKblU?= =?us-ascii?Q?iYg0JSR2Y0GD9uHidCcHBHPB1KXN37SoMFRvKc1mXtc=3D?= 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: BYAPR11MB2901.namprd11.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: ec4a21c8-049d-4b35-8629-08d8b05c057f X-MS-Exchange-CrossTenant-originalarrivaltime: 04 Jan 2021 02:54:14.6869 (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: bAv6xXqZWPqCGZ1gsSQNIjnEKzD5VE72rtNFpjsVtD8DjiGYwNfBvFLKi6gRFFv0JVPJVXt0/Yl4iAoNkD+30g== X-MS-Exchange-Transport-CrossTenantHeadersStamped: BYAPR11MB2840 X-OriginatorOrg: intel.com Subject: Re: [dpdk-stable] [PATCH v4 3/4] raw/ifpga: add opae API for Cyborg X-BeenThere: stable@dpdk.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: patches for DPDK stable branches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: stable-bounces@dpdk.org Sender: "stable" Hi Wei, Let's align and review it offline. Thanks, Rosen > -----Original Message----- > From: Huang, Wei > Sent: Monday, January 04, 2021 9:18 > To: Xu, Rosen ; dev@dpdk.org; Zhang, Qi Z > > Cc: stable@dpdk.org; Zhang, Tianfei > Subject: RE: [PATCH v4 3/4] raw/ifpga: add opae API for Cyborg >=20 > Hi Rosen, >=20 > I cannot change "master" to "primary", how to fix it ? >=20 > Wei >=20 > -----Original Message----- > From: Xu, Rosen > Sent: Friday, January 1, 2021 22:39 > To: Huang, Wei ; dev@dpdk.org; Zhang, Qi Z > > Cc: stable@dpdk.org; Zhang, Tianfei > Subject: RE: [PATCH v4 3/4] raw/ifpga: add opae API for Cyborg >=20 > Hi Wei, >=20 > Could you pls fix coding style issues? Thanks a lot. >=20 > Thanks, > Rosen >=20 > > -----Original Message----- > > From: Huang, Wei > > Sent: Wednesday, December 30, 2020 15:46 > > To: dev@dpdk.org; Xu, Rosen ; Zhang, Qi Z > > > > Cc: stable@dpdk.org; Zhang, Tianfei ; Huang, > Wei > > > > Subject: [PATCH v4 3/4] raw/ifpga: add opae API for Cyborg > > > > Cyborg is part of OpenStack, it needs some OPAE type APIs to manage > > PACs (Programmable Acceleration Card) with Intel FPGA. Below major > > functions are added to meets Cyborg requirements. > > 1. opae_init_eal() set up EAL environment. > > 2. opae_cleanup_eal() clean up EAL environment. > > 3. opae_enumerate() searches PAC with specific FPGA. > > 4. opae_get_property() gets properties of FPGA. > > 5. opae_partial_reconfigure() perform partial configuration on FPGA. > > 6. opae_get_image_info() gets information of image file. > > 7. opae_update_flash() updates FPGA flash with specific image file. > > 8. opae_cancel_flash_update() cancel process of FPGA flash update. > > 9. opae_probe_device() manually probe specific FPGA with ifpga driver. > > 10. opae_remove_device() manually remove specific FPGA from ifpga > driver. > > 11. opae_bind_driver() binds specific FPGA with specified kernel driver= . > > 12. opae_unbind_driver() unbinds specific FPGA from kernel driver. > > 13. opae_reboot_device() reboots specific FPGA (do reconfiguration). > > > > Signed-off-by: Wei Huang > > --- > > v2: fix typo in commit log and ifpga_opae_api.h > > --- > > v3: fix coding style issue in ifpga_opae_api.c > > --- > > v4: enclose macro PCI_EXT_CAP_ID in parentheses > > --- > > drivers/raw/ifpga/ifpga_opae_api.c | 1801 > > ++++++++++++++++++++++++++++ > > drivers/raw/ifpga/ifpga_opae_api.h | 245 ++++ > > drivers/raw/ifpga/ifpga_rawdev.c | 152 ++- > > drivers/raw/ifpga/ifpga_rawdev.h | 15 + > > drivers/raw/ifpga/meson.build | 4 +- > > 5 files changed, 2210 insertions(+), 7 deletions(-) > > create mode 100644 drivers/raw/ifpga/ifpga_opae_api.c > > create mode 100644 drivers/raw/ifpga/ifpga_opae_api.h > > > > diff --git a/drivers/raw/ifpga/ifpga_opae_api.c > > b/drivers/raw/ifpga/ifpga_opae_api.c > > new file mode 100644 > > index 000000000..9210092ab > > --- /dev/null > > +++ b/drivers/raw/ifpga/ifpga_opae_api.c > > @@ -0,0 +1,1801 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright(c) 2020 Intel Corporation > > + */ > > + > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include > > +#include "base/opae_hw_api.h" > > +#include "base/ifpga_sec_mgr.h" > > +#include "ifpga_rawdev.h" > > +#include "ifpga_opae_api.h" > > + > > + > > +int opae_log_level; > > +FILE *opae_log_file; > > + > > +static opae_api_version api_ver =3D {21, 2, 0}; > > +static int eal_inited; > > +static uint32_t dev_aer[2] =3D {0}; > > + > > +static const char * const log_level_name[] =3D {"CRITICAL", "ERROR", > > + "WARNING", "INFORMATION", "DEBUG"}; > > +static const char * const proc_type_name[] =3D {"NON-DPDK", "PRIMARY", > > + "SECONDARY"}; > > +static const char * const platform_name[] =3D {"Vista Creek", "Rush Cr= eek", > > + "Darby Creek", "Lightning Creek"}; > > +static const char * const release_name[] =3D {"Pre-Alpha", "Alpha", "B= eta", > > "PV"}; > > +static const char * const interface_type[] =3D {"8x10G", "4x25G", "2x1= x25G", > > + "4x25G+2x25G", "2x2x25G", "2x1x25Gx2FVL", "1x2x25G"}; > > +static const char * const kdrv[] =3D {OPAE_KDRV_UNKNOWN, > > OPAE_KDRV_IGB_UIO, > > + OPAE_KDRV_VFIO_PCI, OPAE_KDRV_UIO_PCI}; > > + > > +RTE_INIT(init_api_env) > > +{ > > + eal_inited =3D 0; > > + opae_log_level =3D OPAE_LOG_ERR; > > + opae_log_file =3D NULL; > > + ifpga_rawdev_logtype =3D 0; > > + > > + opae_log_info("API environment is initialized\n"); > > +} > > + > > +RTE_FINI(clean_api_env) > > +{ > > + if (opae_log_file) { > > + fclose(opae_log_file); > > + opae_log_file =3D NULL; > > + } > > + opae_log_info("API environment is cleaned\n"); > > +} > > + > > +void opae_get_api_version(opae_api_version *version) > > +{ > > + if (version) > > + memcpy(version, &api_ver, sizeof(opae_api_version)); > > + opae_log_info("API version is %u.%u.%u\n", > > + api_ver.major, api_ver.minor, api_ver.micro); > > +} > > + > > +int opae_set_log_level(int level) > > +{ > > + if ((level >=3D OPAE_LOG_API) && (level <=3D OPAE_LOG_DEBUG)) > > + opae_log_level =3D level; > > + opae_log_api("Current log level is %s\n", > > + log_level_name[opae_log_level]); > > + return opae_log_level; > > +} > > + > > +int opae_set_log_file(char *path, int clean) > > +{ > > + FILE *f =3D NULL; > > + time_t start; > > + struct tm *lt =3D NULL; > > + > > + if (path) { > > + if (clean) > > + f =3D fopen(path, "w+"); > > + else > > + f =3D fopen(path, "a+"); > > + > > + if (f) { > > + if (opae_log_file) { > > + fclose(opae_log_file); > > + opae_log_file =3D NULL; > > + } > > + time(&start); > > + lt =3D localtime(&start); > > + if (lt) > > + fprintf(f, "=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D%d-%02= d- > > %02d " > > + > > "%02d:%02d:%02d=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D\n", > > + 1900 + lt->tm_year, 1 + lt->tm_mon, > > + lt->tm_mday, > > + lt->tm_hour, lt->tm_min, lt->tm_sec); > > + fflush(f); > > + opae_log_file =3D f; > > + } else { > > + opae_log_err("failed to open log file \'%s\'\n", path); > > + return -1; > > + } > > + } else { > > + if (opae_log_file) { > > + fclose(opae_log_file); > > + opae_log_file =3D NULL; > > + } > > + } > > + > > + return 0; > > +} > > + > > +int opae_get_image_info(const char *image, opae_img_info *info) > > +{ > > + int fd =3D -1; > > + off_t file_size =3D 0; > > + opae_img_hdr hdr; > > + ssize_t read_size =3D 0; > > + int ret =3D 0; > > + > > + if (!image || !info) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + fd =3D open(image, O_RDONLY); > > + if (fd < 0) { > > + opae_log_err("Failed to open \'%s\' for RD [e:%s]\n", > > + image, strerror(errno)); > > + return -EIO; > > + } > > + > > + file_size =3D lseek(fd, 0, SEEK_END); > > + opae_log_dbg("Size of \'%s\' is %lu\n", image, file_size); > > + if (file_size < (OPAE_IMG_HDR_SIZE + OPAE_IMG_PL_MIN_SIZE)) { > > + opae_log_err("Size of \'%s\' is less than expected [e:%u]\n", > > + image, OPAE_IMG_HDR_SIZE + > > OPAE_IMG_PL_MIN_SIZE); > > + ret =3D -EINVAL; > > + goto close_fd; > > + } > > + > > + /* read image header */ > > + lseek(fd, 0, SEEK_SET); > > + read_size =3D read(fd, (void *)&hdr, sizeof(opae_img_hdr)); > > + if (read_size < 0) { > > + opae_log_err("Failed to read from \'%s\' [e:%s]\n", > > + image, strerror(errno)); > > + ret =3D -EIO; > > + goto close_fd; > > + } > > + if ((size_t)read_size !=3D sizeof(opae_img_hdr)) { > > + opae_log_err("Read length %zd is not expected [e:%zu]\n", > > + read_size, sizeof(opae_img_hdr)); > > + ret =3D -EIO; > > + goto close_fd; > > + } > > + > > + info->total_len =3D file_size; > > + /* check signed image header */ > > + if (hdr.magic =3D=3D OPAE_IMG_BLK0_MAGIC) { > > + info->type =3D OPAE_IMG_TYPE(hdr.payload_type); > > + info->subtype =3D OPAE_IMG_SUBTYPE(hdr.payload_type); > > + info->payload_offset =3D OPAE_IMG_HDR_SIZE; > > + info->payload_len =3D hdr.payload_len; > > + } else { > > + opae_log_err("Image \'%s\' can not be recognized\n", > > image); > > + ret =3D -EINVAL; > > + } > > +close_fd: > > + close(fd); > > + return ret; > > +} > > + > > +static int write_file(char *path, char *buf, int size) > > +{ > > + int fd =3D -1; > > + ssize_t n =3D 0; > > + > > + if (!path || !buf || (size <=3D 0)) > > + return -EINVAL; > > + > > + fd =3D open(path, O_WRONLY); > > + if (fd < 0) { > > + opae_log_err("Failed to open \'%s\' for WR [e:%s]\n", > > + path, strerror(errno)); > > + return -EIO; > > + } > > + opae_log_dbg("Write \"%s\" to \'%s\'\n", buf, path); > > + n =3D write(fd, buf, size); > > + if (n < size) { > > + opae_log_err("Failed to write to \'%s\' [e:%s]\n", > > + path, strerror(errno)); > > + close(fd); > > + return -EIO; > > + } > > + close(fd); > > + > > + return 0; > > +} > > + > > +static int read_file(char *path, char *buf, int size) > > +{ > > + int fd =3D -1; > > + ssize_t n =3D 0; > > + > > + if (!path || !buf || (size <=3D 0)) > > + return -EINVAL; > > + > > + fd =3D open(path, O_RDONLY); > > + if (fd < 0) { > > + opae_log_err("Failed to open \'%s\' for RD [e:%s]\n", > > + path, strerror(errno)); > > + return -EIO; > > + } > > + n =3D read(fd, buf, size); > > + if (n < 0) { > > + opae_log_err("Failed to read from \'%s\' [e:%s]\n", > > + path, strerror(errno)); > > + close(fd); > > + return -EIO; > > + } > > + close(fd); > > + > > + if (n > 0) > > + buf[n-1] =3D 0; > > + > > + opae_log_dbg("Read \"%s\" from \'%s\'\n", buf, path); > > + return 0; > > +} > > + > > +int opae_get_proc_type(void) > > +{ > > + int type =3D -1; > > + > > + if (eal_inited) { > > + if (rte_eal_process_type() =3D=3D RTE_PROC_PRIMARY) > > + type =3D 0; > > + else > > + type =3D 1; > > + } > > + opae_log_info("Current process type is %s\n", > > proc_type_name[type+1]); > > + > > + return type; > > +} > > + > > +static bool check_eal(int inited) > > +{ > > + if (!eal_inited) { > > + if (inited) { > > + opae_log_warn("EAL is not initialized\n"); > > + return 0; > > + } > > + } else { > > + if (!inited) { > > + opae_log_warn("EAL is already initialized\n"); > > + return 0; > > + } > > + } > > + > > + return 1; > > +} > > + > > +int opae_init_eal(int argc, char **argv) > > +{ > > + int ret =3D 0; > > + > > + if (!check_eal(0)) > > + return ret; > > + > > + ret =3D rte_eal_init(argc, argv); > > + if (ret < 0) { > > + if (rte_errno =3D=3D EALREADY) { > > + eal_inited =3D 1; > > + return 0; > > + } > > + opae_log_err("Cannot initialize EAL [e:%d]\n", ret); > > + if (rte_eal_cleanup()) > > + opae_log_warn("EAL could not release all > > resources\n"); > > + } else { > > + eal_inited =3D 1; > > + opae_log_info("Initialize EAL done\n"); > > + } > > + > > + return ret; > > +} > > + > > +int opae_cleanup_eal(void) > > +{ > > + int ret =3D 0; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + ifpga_rawdev_cleanup(); > > + > > + ret =3D rte_eal_cleanup(); > > + if (ret) > > + opae_log_err("Failed to cleanup EAL [e:%d]\n", ret); > > + > > + return ret; > > +} > > + > > +static int compare_pci_id(opae_pci_id *id, opae_pci_id *expected_id) > > +{ > > + if ((expected_id->class_id !=3D BIT_SET_32) && > > + (expected_id->class_id !=3D id->class_id)) > > + return -1; > > + if ((expected_id->vendor_id !=3D BIT_SET_16) && > > + (expected_id->vendor_id !=3D id->vendor_id)) > > + return -1; > > + if ((expected_id->device_id !=3D BIT_SET_16) && > > + (expected_id->device_id !=3D id->device_id)) > > + return -1; > > + if ((expected_id->subsystem_vendor_id !=3D BIT_SET_16) && > > + (expected_id->subsystem_vendor_id !=3D id- > > >subsystem_vendor_id)) > > + return -1; > > + if ((expected_id->subsystem_device_id !=3D BIT_SET_16) && > > + (expected_id->subsystem_device_id !=3D id- > > >subsystem_device_id)) > > + return -1; > > + > > + return 0; > > +} > > + > > +static int parse_sysfs_value(char *node, uint32_t *val) > > +{ > > + char buf[16]; > > + char *end =3D NULL; > > + int ret =3D 0; > > + > > + ret =3D read_file(node, buf, sizeof(buf)); > > + if (ret < 0) > > + return ret; > > + > > + *val =3D (uint32_t)strtoul(buf, &end, 0); > > + return 0; > > +} > > + > > +static int get_pci_id(const char *dev_path, opae_pci_id *id) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + uint32_t tmp; > > + > > + if (!dev_path || !id) > > + return -EINVAL; > > + > > + snprintf(path, sizeof(path), "%s/vendor", dev_path); > > + if (parse_sysfs_value(path, &tmp) < 0) > > + return -ENODEV; > > + id->vendor_id =3D (uint16_t)tmp; > > + > > + snprintf(path, sizeof(path), "%s/device", dev_path); > > + if (parse_sysfs_value(path, &tmp) < 0) > > + return -ENODEV; > > + id->device_id =3D (uint16_t)tmp; > > + > > + snprintf(path, sizeof(path), "%s/subsystem_vendor", dev_path); > > + if (parse_sysfs_value(path, &tmp) < 0) > > + return -ENODEV; > > + id->subsystem_vendor_id =3D (uint16_t)tmp; > > + > > + snprintf(path, sizeof(path), "%s/subsystem_device", dev_path); > > + if (parse_sysfs_value(path, &tmp) < 0) > > + return -ENODEV; > > + id->subsystem_device_id =3D (uint16_t)tmp; > > + > > + snprintf(path, sizeof(path), "%s/class", dev_path); > > + if (parse_sysfs_value(path, &tmp) < 0) > > + return -ENODEV; > > + id->class_id =3D (uint32_t)tmp & RTE_CLASS_ANY_ID; > > + > > + return 0; > > +} > > + > > +static int extract_path(char *in, int ridx, char *out, uint32_t size) > > +{ > > + char src[PATH_MAX] =3D {0}; > > + char *p =3D NULL; > > + int ret =3D 0; > > + > > + if (!in || (strlen(in) > PATH_MAX) || (ridx < 0) || !out) > > + return -EINVAL; > > + > > + strncpy(src, in, sizeof(src)); > > + *out =3D 0; > > + > > + while (1) { > > + p =3D strrchr(src, '/'); > > + if (p) { > > + *p++ =3D 0; > > + if (*p) { > > + if (ridx-- <=3D 0) { > > + if (size > strlen(p)) { > > + strncpy(out, p, size); > > + ret =3D strlen(p); > > + } > > + break; > > + } > > + } > > + } else { > > + break; > > + } > > + } > > + > > + return ret; > > +} > > + > > +int opae_enumerate(opae_pci_id *filter, pcidev_id list, int size) > > +{ > > + DIR *dir =3D NULL; > > + struct dirent *dirent =3D NULL; > > + char path[PATH_MAX] =3D {0}; > > + opae_pci_id id; > > + int n =3D 0; > > + > > + if (!filter || (size < 0) || (!list && (size > 0))) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + dir =3D opendir(rte_pci_get_sysfs_path()); > > + if (!dir) { > > + opae_log_err("Failed to open \'%s\'\n", > > + rte_pci_get_sysfs_path()); > > + return -EINVAL; > > + } > > + while ((dirent =3D readdir(dir))) { > > + if (!strcmp(dirent->d_name, ".")) > > + continue; > > + if (!strcmp(dirent->d_name, "..")) > > + continue; > > + > > + snprintf(path, PATH_MAX, "%s/%s", > > rte_pci_get_sysfs_path(), > > + dirent->d_name); > > + if (get_pci_id(path, &id) < 0) > > + continue; > > + if (compare_pci_id(&id, filter) < 0) > > + continue; > > + > > + if (n++ < size) { > > + snprintf(list->bdf, sizeof(list->bdf), "%s", > > + dirent->d_name); > > + list++; > > + } > > + } > > + closedir(dir); > > + > > + return n; > > +} > > + > > +static int get_driver(pcidev_id id, char *drv_name, uint32_t size) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char link[PATH_MAX] =3D {0}; > > + int ret =3D 0; > > + > > + if (!id || !drv_name) { > > + ret =3D -EINVAL; > > + goto end; > > + } > > + size--; /* reserve one byte for the end of string */ > > + > > + snprintf(path, PATH_MAX, "%s/%s/driver", > > + rte_pci_get_sysfs_path(), id->bdf); > > + ret =3D readlink(path, link, PATH_MAX); > > + if (ret >=3D PATH_MAX) { > > + opae_log_err("Link path too long [%d]\n", ret); > > + ret =3D -ENAMETOOLONG; > > + goto end; > > + } > > + if (ret > 0) { > > + ret =3D extract_path(link, 0, drv_name, size); > > + } else { > > + *drv_name =3D 0; > > + opae_log_info("No link path for \'%s\'\n", path); > > + ret =3D 0; > > + } > > + > > +end: > > + if (ret < 0) > > + opae_log_err("Failed to get driver of %s\n", id->bdf); > > + > > + return ret; > > +} > > + > > +static int get_pci_addr(const char *bdf, opae_pci_addr *addr) > > +{ > > + unsigned int domain =3D 0; > > + unsigned int bus =3D 0; > > + unsigned int devid =3D 0; > > + unsigned int function =3D 0; > > + int ret =3D 0; > > + > > + if (!bdf || !addr) > > + return -EINVAL; > > + > > + ret =3D sscanf(bdf, "%04x:%02x:%02x.%d", > > + &domain, &bus, &devid, &function); > > + if (ret =3D=3D 4) { > > + addr->domain =3D (uint32_t)domain; > > + addr->bus =3D (uint8_t)bus; > > + addr->devid =3D (uint8_t)devid; > > + addr->function =3D (uint8_t)function; > > + return 0; > > + } > > + > > + return -EINVAL; > > +} > > + > > +static struct rte_rawdev *get_rte_rawdev(pcidev_id id, int log) > > +{ > > + opae_pci_addr addr; > > + struct rte_rawdev *rdev =3D NULL; > > + char rdev_name[OPAE_NAME_SIZE] =3D {0}; > > + > > + if (!id) > > + return NULL; > > + > > + if (get_pci_addr(id->bdf, &addr) < 0) > > + return NULL; > > + > > + snprintf(rdev_name, OPAE_NAME_SIZE, "IFPGA:%02x:%02x.%x", > > + addr.bus, addr.devid, addr.function); > > + rdev =3D rte_rawdev_pmd_get_named_dev(rdev_name); > > + if (log && !rdev) > > + opae_log_warn("%s is not probed\n", id->bdf); > > + > > + return rdev; > > +} > > + > > +static struct rte_pci_device *get_rte_pcidev(pcidev_id id, int log) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + struct rte_pci_bus *pci_bus =3D NULL; > > + struct rte_pci_device *pci_dev =3D NULL; > > + > > + if (!id) > > + return NULL; > > + > > + pci_bus =3D ifpga_get_pci_bus(); > > + if (pci_bus) { > > + TAILQ_FOREACH(pci_dev, &pci_bus->device_list, next) { > > + if (!strcmp(id->bdf, pci_dev->name)) > > + return pci_dev; > > + } > > + } else { > > + rdev =3D get_rte_rawdev(id, 0); > > + if (rdev && rdev->device) { > > + pci_dev =3D RTE_DEV_TO_PCI(rdev->device); > > + return pci_dev; > > + } > > + } > > + > > + if (log) > > + opae_log_err("No rte_pci_device for %s\n", id->bdf); > > + > > + return NULL; > > +} > > + > > +static int lock(pcidev_id id) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + int ret =3D 0; > > + > > + rdev =3D get_rte_rawdev(id, 0); > > + if (rdev) > > + ret =3D ifpga_rawdev_lock(rdev); > > + > > + return ret; > > +} > > + > > +static int unlock(pcidev_id id) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + int ret =3D 0; > > + > > + rdev =3D get_rte_rawdev(id, 0); > > + if (rdev) > > + ret =3D ifpga_rawdev_unlock(rdev); > > + > > + return ret; > > +} > > + > > +int opae_load_rsu_status(pcidev_id id, uint32_t *status, uint32_t > *progress) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + uint32_t value =3D 0; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (rdev) > > + value =3D ifpga_rawdev_get_rsu_stat(rdev); > > + else > > + return -ENODEV; > > + > > + if (status) > > + *status =3D (value >> 16) & 0xffff; > > + if (progress) > > + *progress =3D value & 0xffff; > > + > > + return 0; > > +} > > + > > +int opae_store_rsu_status(pcidev_id id, uint32_t status, uint32_t > progress) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + uint32_t value =3D 0; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (rdev) { > > + value =3D ((status << 16) & 0xffff0000) | (progress & 0xffff); > > + ifpga_rawdev_set_rsu_stat(rdev, value); > > + } else { > > + return -ENODEV; > > + } > > + > > + return 0; > > +} > > + > > +static int get_pci_property(pcidev_id id, opae_pci_property *prop) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + int ret =3D 0; > > + > > + if (!id || !prop) > > + return -EINVAL; > > + > > + snprintf(path, PATH_MAX, "%s/%s", rte_pci_get_sysfs_path(), id- > > >bdf); > > + > > + ret =3D get_pci_id(path, &prop->id); > > + if (ret < 0) > > + return ret; > > + > > + ret =3D get_pci_addr(id->bdf, &prop->addr); > > + if (ret < 0) > > + return ret; > > + > > + snprintf(prop->pci_addr, OPAE_NAME_SIZE, "%s", id->bdf); > > + get_driver(id, prop->drv_name, sizeof(prop->drv_name)); > > + > > + return 0; > > +} > > + > > +static int get_fme_property(pcidev_id id, opae_fme_property *prop) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + ifpga_fme_property fme_prop; > > + opae_bitstream_id bbs_id; > > + int ret =3D 0; > > + > > + if (!prop) > > + return -EINVAL; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + ret =3D ifpga_rawdev_get_fme_property(rdev, &fme_prop); > > + if (!ret) { > > + prop->boot_page =3D fme_prop.boot_page; > > + prop->num_ports =3D fme_prop.num_ports; > > + prop->bitstream_id =3D fme_prop.bitstream_id; > > + prop->bitstream_metadata =3D fme_prop.bitstream_metadata; > > + memcpy(prop->pr_id.b, fme_prop.pr_id.b, > > sizeof(opae_uuid)); > > + > > + bbs_id.id =3D prop->bitstream_id; > > + if (bbs_id.major < sizeof(platform_name) / sizeof(char *)) { > > + snprintf(prop->platform_name, > > + sizeof(prop->platform_name), "%s", > > + platform_name[bbs_id.major]); > > + } else { > > + snprintf(prop->platform_name, > > + sizeof(prop->platform_name), "unknown"); > > + } > > + > > + snprintf(prop->dcp_version, sizeof(prop->dcp_version), > > + "DCP 1.%u", bbs_id.minor); > > + > > + if (bbs_id.patch < sizeof(release_name)/sizeof(char *)) { > > + snprintf(prop->release_name, sizeof(prop- > > >release_name), > > + "%s", release_name[bbs_id.patch]); > > + } else { > > + snprintf(prop->release_name, sizeof(prop- > > >release_name), > > + "unknown"); > > + } > > + > > + if (bbs_id.major =3D=3D 0) { /* Vista Creek */ > > + if (bbs_id.interface < > > + sizeof(interface_type) / sizeof(char *)) { > > + snprintf(prop->interface_type, > > + sizeof(prop->interface_type), "%s", > > + interface_type[bbs_id.interface]); > > + } else { > > + snprintf(prop->interface_type, > > + sizeof(prop->interface_type), > > "unknown"); > > + } > > + } else { > > + snprintf(prop->interface_type, > > + sizeof(prop->interface_type), "unknown"); > > + } > > + > > + snprintf(prop->build_version, sizeof(prop->build_version), > > + "%u.%u.%u", bbs_id.build_major, > > bbs_id.build_minor, > > + bbs_id.build_patch); > > + } > > + > > + return ret; > > +} > > + > > +static int get_port_property(pcidev_id id, uint32_t port, > > + opae_port_property *prop) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + ifpga_port_property port_prop; > > + int ret =3D 0; > > + > > + if (!prop || (port >=3D OPAE_MAX_PORT_NUM)) > > + return -EINVAL; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + ret =3D ifpga_rawdev_get_port_property(rdev, port, &port_prop); > > + if (!ret) { > > + memcpy(prop->afu_id.b, port_prop.afu_id.b, > > sizeof(opae_uuid)); > > + prop->type =3D port_prop.type; > > + prop->index =3D port; > > + } > > + > > + return 0; > > +} > > + > > +static int get_bmc_property(pcidev_id id, opae_bmc_property *prop) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + ifpga_bmc_property bmc_prop; > > + opae_bmc_version ver; > > + int ret =3D 0; > > + > > + if (!prop) > > + return -EINVAL; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + ret =3D ifpga_rawdev_get_bmc_property(rdev, &bmc_prop); > > + if (!ret) { > > + ver.version =3D bmc_prop.bmc_version; > > + snprintf(prop->bmc_version, sizeof(prop->bmc_version), > > "%C.%u.%u.%u", > > + ver.board, ver.major, ver.minor, ver.micro); > > + > > + ver.version =3D bmc_prop.fw_version; > > + snprintf(prop->fw_version, sizeof(prop->fw_version), > > "%C.%u.%u.%u", > > + ver.board, ver.major, ver.minor, ver.micro); > > + } > > + > > + return 0; > > +} > > + > > +int opae_get_property(pcidev_id id, opae_fpga_property *prop, int type= ) > > +{ > > + uint32_t status =3D 0; > > + uint32_t i =3D 0; > > + int ret =3D 0; > > + > > + if (!prop) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + if (type =3D=3D 0) > > + type =3D OPAE_PROP_ALL; > > + > > + memset(prop, 0, sizeof(opae_fpga_property)); > > + > > + /* PCI properties */ > > + if (type & OPAE_PROP_PCI) { > > + ret =3D get_pci_property(id, &prop->pci); > > + if (ret < 0) { > > + opae_log_err("Failed to get PCI property\n"); > > + return ret; > > + } > > + } > > + > > + if (type =3D=3D OPAE_PROP_PCI) > > + return 0; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + if (!get_rte_rawdev(id, 1)) > > + return -ENODEV; > > + > > + lock(id); > > + opae_load_rsu_status(id, &status, NULL); > > + if (status =3D=3D IFPGA_RSU_REBOOT) { > > + opae_log_warn("Reboot is in progress\n"); > > + ret =3D -EAGAIN; > > + goto unlock_dev; > > + } > > + > > + /* FME properties */ > > + if (type & (OPAE_PROP_FME | OPAE_PROP_PORT)) { > > + ret =3D get_fme_property(id, &prop->fme); > > + if (ret) { > > + opae_log_err("Failed to get FME property\n"); > > + goto unlock_dev; > > + } > > + } > > + > > + /* PORT properties */ > > + if (type & OPAE_PROP_PORT) { > > + for (i =3D 0; i < prop->fme.num_ports; i++) { > > + ret =3D get_port_property(id, i, &prop->port[i]); > > + if (ret) { > > + opae_log_err("Failed to get port > > property\n"); > > + goto unlock_dev; > > + } > > + } > > + } > > + > > + /* BMC properties */ > > + if (type & OPAE_PROP_BMC) { > > + ret =3D get_bmc_property(id, &prop->bmc); > > + if (ret) { > > + opae_log_err("Failed to get BMC property\n"); > > + goto unlock_dev; > > + } > > + } > > + > > +unlock_dev: > > + unlock(id); > > + return ret; > > +} > > + > > +int opae_get_phy_info(pcidev_id id, opae_phy_info *info) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + ifpga_phy_info phy_info; > > + int ret =3D 0; > > + > > + if (!info) > > + return -EINVAL; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + ret =3D ifpga_rawdev_get_phy_info(rdev, &phy_info); > > + if (!ret) { > > + info->num_retimers =3D phy_info.num_retimers; > > + info->link_speed =3D phy_info.link_speed; > > + info->link_status =3D phy_info.link_status; > > + } > > + > > + return ret; > > +} > > + > > +static int update_driver(pcidev_id id, char *drv_name) > > +{ > > + struct rte_pci_device *pci_dev =3D NULL; > > + char name[OPAE_NAME_SIZE] =3D {0}; > > + int ret =3D 0; > > + > > + if (!id) > > + return -EINVAL; > > + > > + if (drv_name) { > > + if (strlen(drv_name) >=3D OPAE_NAME_SIZE) { > > + opae_log_err("Driver name \'%s\' too long\n", > > + drv_name); > > + return -EINVAL; > > + } > > + strncpy(name, drv_name, sizeof(name)); > > + } else { > > + ret =3D get_driver(id, name, sizeof(name)); > > + if (ret < 0) > > + return ret; > > + } > > + > > + pci_dev =3D get_rte_pcidev(id, 0); > > + if (pci_dev) { > > + if (strlen(name) =3D=3D 0) { > > + pci_dev->kdrv =3D RTE_PCI_KDRV_NONE; > > + } else { > > + if (!strcmp(name, OPAE_KDRV_VFIO_PCI)) > > + pci_dev->kdrv =3D RTE_PCI_KDRV_VFIO; > > + else if (!strcmp(name, OPAE_KDRV_IGB_UIO)) > > + pci_dev->kdrv =3D RTE_PCI_KDRV_IGB_UIO; > > + else if (!strcmp(name, OPAE_KDRV_UIO_PCI)) > > + pci_dev->kdrv =3D > > RTE_PCI_KDRV_UIO_GENERIC; > > + else > > + pci_dev->kdrv =3D RTE_PCI_KDRV_UNKNOWN; > > + } > > + } > > + > > + return 0; > > +} > > + > > +int opae_unbind_driver(pcidev_id id) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char drv_name[OPAE_NAME_SIZE] =3D {0}; > > + char null[] =3D {0}; > > + int ret =3D 0; > > + > > + if (get_rte_rawdev(id, 0)) { > > + opae_log_err("%s is probed, remove it first\n", id->bdf); > > + return -EBUSY; > > + } > > + > > + ret =3D get_driver(id, drv_name, sizeof(drv_name)); > > + if (ret < 0) > > + return ret; > > + > > + if (strlen(drv_name) > 0) { > > + snprintf(path, PATH_MAX, "/sys/bus/pci/drivers/%s/unbind", > > + drv_name); > > + ret =3D write_file(path, id->bdf, strlen(id->bdf) + 1); > > + if (ret =3D=3D 0) > > + ret =3D update_driver(id, null); > > + } > > + > > + return ret; > > +} > > + > > +static int check_driver(const char *drv_name) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + struct stat buf; > > + > > + if (!drv_name) > > + return -EINVAL; > > + > > + if (strlen(drv_name) > 0) { > > + snprintf(path, PATH_MAX, "/sys/bus/pci/drivers/%s", > > drv_name); > > + if ((stat(path, &buf) < 0) || ((buf.st_mode & S_IFDIR) =3D=3D 0)) { > > + opae_log_warn("Driver %s is not installed\n", > > + drv_name); > > + return -EINVAL; > > + } > > + } > > + > > + return 0; > > +} > > + > > +int opae_bind_driver(pcidev_id id, char *drv_name) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char name[OPAE_NAME_SIZE] =3D {0}; > > + char null[] =3D {0}; > > + int ret =3D 0; > > + > > + ret =3D check_driver(drv_name); > > + if (ret < 0) > > + return ret; > > + > > + ret =3D get_driver(id, name, sizeof(name)); > > + if (ret < 0) > > + return ret; > > + > > + if (!strcmp(drv_name, name)) /* driver not change */ > > + return 0; > > + > > + ret =3D opae_unbind_driver(id); > > + if (ret < 0) > > + return ret; > > + > > + if (strlen(drv_name) > 0) { > > + /* bind driver */ > > + snprintf(path, PATH_MAX, "%s/%s/driver_override", > > + rte_pci_get_sysfs_path(), id->bdf); > > + ret =3D write_file(path, drv_name, strlen(drv_name) + 1); > > + if (ret < 0) > > + goto update_drv; > > + > > + snprintf(path, PATH_MAX, "/sys/bus/pci/drivers/%s/bind", > > + drv_name); > > + ret =3D write_file(path, id->bdf, strlen(id->bdf) + 1); > > + if (ret < 0) > > + goto update_drv; > > + > > + snprintf(path, PATH_MAX, "%s/%s/driver_override", > > + rte_pci_get_sysfs_path(), id->bdf); > > + ret =3D write_file(path, null, 1); > > + if (ret < 0) > > + goto update_drv; > > + } > > + > > +update_drv: > > + ret =3D update_driver(id, NULL); > > + if (ret < 0) > > + opae_log_err("Failed to update driver information of %s\n", > > + id->bdf); > > + > > + return 0; > > +} > > + > > +int opae_probe_device(pcidev_id id) > > +{ > > + struct rte_pci_bus *pci_bus =3D NULL; > > + struct rte_pci_device *pci_dev =3D NULL; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + /* make sure device is added in rte_pci_bus devices list */ > > + pci_bus =3D ifpga_get_pci_bus(); > > + if (pci_bus && pci_bus->bus.scan) > > + pci_bus->bus.scan(); > > + > > + pci_dev =3D get_rte_pcidev(id, 1); > > + if (!pci_dev) > > + return -ENODEV; > > + > > + if (pci_dev->kdrv !=3D RTE_PCI_KDRV_VFIO) { > > + opae_log_err("vfio-pci driver is not bound to %s\n", id->bdf); > > + return -EINVAL; > > + } > > + > > + if (!pci_bus || !pci_bus->bus.plug) > > + return -ENODEV; > > + > > + return pci_bus->bus.plug(&pci_dev->device); > > +} > > + > > +int opae_remove_device(pcidev_id id) > > +{ > > + struct rte_pci_device *pci_dev =3D NULL; > > + struct rte_pci_driver *pci_drv =3D NULL; > > + int ret =3D 0; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + pci_dev =3D get_rte_pcidev(id, 0); > > + if (pci_dev && pci_dev->driver) { > > + pci_drv =3D pci_dev->driver; > > + ret =3D pci_drv->remove(pci_dev); > > + if (ret < 0) { > > + opae_log_err("Failed to remove %s [e:%d]\n", > > + id->bdf, ret); > > + return ret; > > + } > > + pci_dev->driver =3D NULL; > > + pci_dev->device.driver =3D NULL; > > + if (pci_drv->drv_flags & RTE_PCI_DRV_NEED_MAPPING) > > + rte_pci_unmap_device(pci_dev); > > + } > > + > > + return ret; > > +} > > + > > +static int is_pac(pcidev_id id) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + opae_pci_id pci_id; > > + > > + if (!id) > > + return 0; > > + > > + snprintf(path, PATH_MAX, "%s/%s", rte_pci_get_sysfs_path(), id- > > >bdf); > > + if (get_pci_id(path, &pci_id) < 0) > > + return 0; > > + > > + if ((pci_id.vendor_id =3D=3D 0x8086) && (pci_id.device_id =3D=3D 0x0b= 30)) > > + return 1; > > + > > + return 0; > > +} > > + > > +int opae_get_parent(pcidev_id id, pcidev_id parent) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char link[PATH_MAX] =3D {0}; > > + int ret =3D 0; > > + > > + if (!id || !parent) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + ret =3D -EINVAL; > > + goto end; > > + } > > + > > + snprintf(path, PATH_MAX, "%s/%s", rte_pci_get_sysfs_path(), id- > > >bdf); > > + ret =3D readlink(path, link, PATH_MAX); > > + if (ret >=3D PATH_MAX) { > > + opae_log_err("Length of link path exceeds %u\n", > > PATH_MAX); > > + ret =3D -ENAMETOOLONG; > > + goto end; > > + } > > + > > + if (ret > 0) { > > + ret =3D extract_path(link, 1, parent->bdf, sizeof(parent->bdf)); > > + if (!strncmp(parent->bdf, "pci", 3)) { > > + parent->bdf[0] =3D 0; > > + ret =3D -ENODEV; > > + } > > + } else { > > + parent->bdf[0] =3D 0; > > + if (ret =3D=3D 0) > > + opae_log_err("Length of link path is 0\n"); > > + else > > + opae_log_err("No link path for \'%s\'\n", path); > > + } > > +end: > > + if (ret <=3D 0) > > + opae_log_err("%s has no parent\n", id->bdf); > > + > > + return ret; > > +} > > + > > +int opae_get_child(pcidev_id id, pcidev_id child, int size) > > +{ > > + glob_t pglob =3D {.gl_pathc =3D 0, .gl_pathv =3D NULL}; > > + char path[PATH_MAX] =3D {0}; > > + int i, count =3D 0; > > + int len =3D 0; > > + int ret =3D 0; > > + > > + if (!id || (size < 0)) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + snprintf(path, PATH_MAX, "%s/%s/*:*:*.?", > > rte_pci_get_sysfs_path(), > > + id->bdf); > > + ret =3D glob(path, 0, NULL, &pglob); > > + if (ret =3D=3D 0) { > > + if (child && (size > 0)) { > > + for (i =3D 0; i < (int)pglob.gl_pathc; i++) { > > + len =3D extract_path(pglob.gl_pathv[i], 0, > > + child->bdf, sizeof(child->bdf)); > > + if (len <=3D 0) { > > + child->bdf[0] =3D 0; > > + continue; > > + } > > + if (++count >=3D size) > > + break; > > + child++; > > + } > > + } else { > > + count =3D (int)pglob.gl_pathc; > > + } > > + globfree(&pglob); > > + } else { > > + if (pglob.gl_pathv) > > + globfree(&pglob); > > + } > > + > > + return count; > > +} > > + > > +int opae_get_pf1(pcidev_id id, pcidev_id peer, int size) > > +{ > > + opae_pci_device parent; > > + opae_pci_device child[4]; > > + int n =3D 0; > > + int ret =3D 0; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + if (!is_pac(id)) { > > + opae_log_info("%s has no peer function\n", id->bdf); > > + return -EINVAL; > > + } > > + > > + ret =3D opae_get_parent(id, &parent); > > + if (ret < 0) > > + return -ENODEV; > > + ret =3D opae_get_parent(&parent, &parent); > > + if (ret < 0) > > + return -ENODEV; > > + > > + n =3D opae_get_child(&parent, child, > > + sizeof(child) / sizeof(opae_pci_device)); > > + /* there should have four downstream ports of PCI switch on board > > */ > > + if (n =3D=3D 4) { > > + n =3D opae_get_child(&child[3], peer, size); > > + } else { > > + peer->bdf[0] =3D 0; > > + opae_log_dbg("%s has %d child(s)\n", parent.bdf, n); > > + n =3D 0; > > + } > > + > > + return n; > > +} > > + > > +void opae_check_pcidev_list(void) > > +{ > > + int i =3D 0; > > + unsigned int k =3D 0; > > + struct rte_pci_bus *pci_bus =3D NULL; > > + struct rte_pci_device *pci_dev =3D NULL; > > + > > + if (!check_eal(1)) > > + return; > > + > > + pci_bus =3D ifpga_get_pci_bus(); > > + if (!pci_bus) > > + return; > > + > > + printf(" ID NAME SEG BUS DEV FUNC VID DID KDRV\n"); > > + TAILQ_FOREACH(pci_dev, &pci_bus->device_list, next) { > > + k =3D pci_dev->kdrv; > > + printf("%3d %s %04x %02x %02x %2d %04x %04x %s\n", > > + i, pci_dev->name, pci_dev->addr.domain, > > + pci_dev->addr.bus, pci_dev->addr.devid, > > + pci_dev->addr.function, pci_dev->id.vendor_id, > > + pci_dev->id.device_id, > > + k > RTE_PCI_KDRV_UIO_GENERIC ? "" : kdrv[k]); > > + i++; > > + } > > +} > > + > > +int opae_update_flash(pcidev_id id, const char *image, uint64_t *statu= s) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + opae_img_info info; > > + int ret =3D 0; > > + > > + ret =3D opae_get_image_info(image, &info); > > + if (ret < 0) { > > + opae_log_err("Failed to get image information [e:%d]\n", > > ret); > > + return -EINVAL; > > + } > > + > > + if ((info.type !=3D OPAE_IMG_TYPE_BBS) && > > + (info.type !=3D OPAE_IMG_TYPE_BMC)) { > > + opae_log_err("Image is not supported [t:%u]\n", info.type); > > + return -EOPNOTSUPP; > > + } > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + return ifpga_rawdev_update_flash(rdev, image, status); > > +} > > + > > +int opae_cancel_flash_update(pcidev_id id, int force) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + return ifpga_rawdev_stop_flash_update(rdev, force); > > +} > > + > > +#define PCI_EXT_CAP_ID_ERR 0x01 /* Advanced Error > > Reporting */ > > +#define PCI_CFG_SPACE_SIZE 256 > > +#define PCI_CFG_SPACE_EXP_SIZE 4096 > > +#define PCI_EXT_CAP_ID(hdr) ((int)((hdr) & 0x0000ffff)) > > +#define PCI_EXT_CAP_NEXT(hdr) (((hdr) >> 20) & 0xffc) > > + > > +static int find_pci_ecap(int fd, int cap) > > +{ > > + uint32_t header =3D 0; > > + int ttl =3D (PCI_CFG_SPACE_EXP_SIZE - PCI_CFG_SPACE_SIZE) / 8; > > + int pos =3D PCI_CFG_SPACE_SIZE; /* start of extension capability are= a > > */ > > + int ret =3D 0; > > + > > + ret =3D pread(fd, &header, sizeof(header), pos); > > + if (ret < 0) { > > + opae_log_err("Failed to read from PCI configuration space > > [e:%s]\n", > > + strerror(errno)); > > + return ret; > > + } > > + opae_log_dbg("Read 0x%08x from PCI configuration space 0x%x\n", > > + header, pos); > > + > > + if (header =3D=3D 0) { > > + opae_log_err("Capability is empty\n"); > > + return 0; > > + } > > + > > + while (ttl-- > 0) { > > + if ((PCI_EXT_CAP_ID(header) =3D=3D cap) && (pos !=3D 0)) > > + return pos; > > + > > + pos =3D PCI_EXT_CAP_NEXT(header); > > + if (pos < PCI_CFG_SPACE_SIZE) { > > + opae_log_err("Position of capability is invalid" > > + "[e:%d]\n", pos); > > + break; > > + } > > + ret =3D pread(fd, &header, sizeof(header), pos); > > + if (ret < 0) { > > + opae_log_err("Failed to read from PCI config space > > [e:%s]\n", > > + strerror(errno)); > > + return ret; > > + } > > + opae_log_dbg("Read 0x%08x from PCI configuration space > > 0x%x\n", > > + header, pos); > > + } > > + > > + return 0; > > +} > > + > > +static int set_aer(pcidev_id id, uint32_t v1, uint32_t v2, int record) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + uint32_t val =3D 0; > > + int fd =3D -1; > > + int pos =3D 0; > > + int ret =3D 0; > > + > > + if (!id) > > + return -EINVAL; > > + > > + snprintf(path, PATH_MAX, "%s/%s/config", > > + rte_pci_get_sysfs_path(), id->bdf); > > + fd =3D open(path, O_RDWR); > > + if (fd < 0) { > > + opae_log_err("Failed to open \'%s\' for RDWR [e:%s]\n", > > + path, strerror(errno)); > > + return -EIO; > > + } > > + > > + pos =3D find_pci_ecap(fd, PCI_EXT_CAP_ID_ERR); > > + if (pos <=3D 0) { > > + opae_log_warn("AER capability is not present\n"); > > + ret =3D -ENXIO; > > + goto close_fd; > > + } > > + > > + if (record) { > > + ret =3D pread(fd, &val, sizeof(val), pos + 0x08); > > + if (ret < 0) { > > + opae_log_err("Failed to read from PCI config space > > [e:%s]\n", > > + strerror(errno)); > > + goto close_fd; > > + } > > + opae_log_dbg("Read 0x%08x from PCI configuration space > > 0x%x\n", > > + val, pos + 0x08); > > + dev_aer[0] =3D val; > > + > > + ret =3D pread(fd, &val, sizeof(val), pos + 0x14); > > + if (ret < 0) { > > + opae_log_err("Failed to read from PCI config space > > [e:%s]\n", > > + strerror(errno)); > > + goto close_fd; > > + } > > + opae_log_dbg("Read 0x%08x from PCI configuration space > > 0x%x\n", > > + val, pos + 0x14); > > + dev_aer[1] =3D val; > > + } > > + > > + opae_log_dbg("Write 0x%08x to PCI configuration space 0x%x\n", > > + v1, pos + 0x08); > > + ret =3D pwrite(fd, &v1, sizeof(v1), pos + 0x08); > > + if (ret < 0) { > > + opae_log_err("Failed to write to PCI config space 0x%x > > [e:%s]\n", > > + pos + 0x08, strerror(errno)); > > + goto close_fd; > > + } > > + > > + opae_log_dbg("Write 0x%08x to PCI configuration space 0x%x\n", > > + v2, pos + 0x14); > > + ret =3D pwrite(fd, &v2, sizeof(v2), pos + 0x14); > > + if (ret < 0) { > > + opae_log_err("Failed to write to PCI config space 0x%x > > [e:%s]\n", > > + pos + 0x14, strerror(errno)); > > + } > > + > > +close_fd: > > + close(fd); > > + return ret < 0 ? ret : 0; > > +} > > + > > +static int enable_aer(pcidev_id id) > > +{ > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + opae_log_info("Enable AER of %s\n", id->bdf); > > + > > + return set_aer(id, dev_aer[0], dev_aer[1], 0); > > +} > > + > > +static int disable_aer(pcidev_id id) > > +{ > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + opae_log_info("Disable AER of %s\n", id->bdf); > > + > > + return set_aer(id, 0xffffffff, 0xffffffff, 1); > > +} > > + > > +static int reload(pcidev_id id, int type, int page) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + int ret =3D 0; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (rdev) > > + ret =3D ifpga_rawdev_reload(rdev, type, page); > > + else > > + ret =3D -ENODEV; > > + > > + return ret; > > +} > > + > > +static int remove_tree(pcidev_id id) > > +{ > > + int i, n =3D 0; > > + pcidev_id child; > > + int ret =3D 0; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + n =3D opae_get_child(id, NULL, 0); > > + if (n > 0) { > > + child =3D (pcidev_id)rte_zmalloc(NULL, > > + sizeof(opae_pci_device) * n, 0); > > + if (!child) { > > + opae_log_err("Failed to malloc for children of %s\n", > > + id->bdf); > > + ret =3D -ENOMEM; > > + goto end; > > + } > > + > > + opae_get_child(id, child, n); > > + for (i =3D 0; i < n; i++) > > + remove_tree(&child[i]); > > + opae_free(child); > > + } > > + > > +end: > > + opae_remove_device(id); > > + return ret; > > +} > > + > > +static int remove_device(pcidev_id id) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char one[] =3D {'1', 0}; > > + int ret =3D 0; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + opae_log_info("Remove %s from system\n", id->bdf); > > + > > + snprintf(path, PATH_MAX, "%s/%s/remove", > > + rte_pci_get_sysfs_path(), id->bdf); > > + ret =3D write_file(path, one, strlen(one)); > > + if (ret < 0) { > > + opae_log_err("Failed to remove %s from system\n", id->bdf); > > + return ret; > > + } > > + > > + remove_tree(id); > > + > > + return 0; > > +} > > + > > +static int scan_device(pcidev_id parent, pcidev_id id) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + char bus[8] =3D {0}; > > + char one[] =3D {'1', 0}; > > + char pwr[16] =3D {0}; > > + char pwr_on[] =3D {'o', 'n', 0}; > > + int pwr_on_failed =3D 0; > > + int ret =3D 0; > > + > > + if (!parent) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + opae_log_info("Rescan devices under %s\n", parent->bdf); > > + > > + if (id) { /* scan specified bus under parent device */ > > + snprintf(path, PATH_MAX, "%s/%s/power/control", > > + rte_pci_get_sysfs_path(), parent->bdf); > > + ret =3D read_file(path, pwr, sizeof(pwr)); > > + if (ret < 0) > > + return ret; > > + > > + if (strcmp(pwr, "on")) { > > + ret =3D write_file(path, pwr_on, strlen(pwr_on)); > > + if (ret < 0) > > + pwr_on_failed =3D 1; > > + else > > + sleep(1); > > + } > > + > > + snprintf(bus, sizeof(bus), "%s", id->bdf); > > + snprintf(path, PATH_MAX, "%s/%s/pci_bus/%s/rescan", > > + rte_pci_get_sysfs_path(), parent->bdf, bus); > > + ret =3D write_file(path, one, strlen(one)); > > + if (ret < 0) > > + return ret; > > + > > + if (pwr_on_failed) { /* workaround for power on failed */ > > + ret =3D write_file(path, one, strlen(one)); > > + if (ret < 0) > > + return ret; > > + } > > + > > + if (strcmp(pwr, "on")) { > > + snprintf(path, PATH_MAX, "%s/%s/power/control", > > + rte_pci_get_sysfs_path(), parent->bdf); > > + ret =3D write_file(path, pwr, strlen(pwr)); > > + } > > + } else { /* scan all buses under parent device */ > > + snprintf(path, PATH_MAX, "%s/%s/rescan", > > + rte_pci_get_sysfs_path(), parent->bdf); > > + ret =3D write_file(path, one, strlen(one)); > > + } > > + > > + return ret; > > +} > > + > > +int opae_reboot_device(pcidev_id id, int type, int page) > > +{ > > + opae_pci_device fpga; /* FPGA after reboot */ > > + opae_pci_device parent; > > + opae_pci_device peer[2]; /* physical function 1 of FPGA */ > > + opae_pci_device peer_parent; > > + opae_pci_device ups; /* upstream port device */ > > + opae_pci_device root; /* port connected to PAC */ > > + pcidev_id peer_master =3D NULL; > > + uint32_t rsu_stat =3D 0; > > + char drv_name[OPAE_NAME_SIZE] =3D {0}; > > + int n =3D 0; > > + int i =3D 0; > > + int ret =3D 0; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + if (!is_pac(id)) { > > + opae_log_err("%s can not be rebooted\n", id->bdf); > > + return -EINVAL; > > + } > > + > > + ret =3D opae_get_parent(id, &parent); > > + if (ret < 0) > > + return -ENODEV; > > + ret =3D opae_get_parent(&parent, &ups); > > + if (ret < 0) > > + return -ENODEV; > > + ret =3D opae_get_parent(&ups, &root); > > + if (ret < 0) > > + return -ENODEV; > > + > > + n =3D opae_get_pf1(id, peer, sizeof(peer) / sizeof(opae_pci_device)); > > + if (n <=3D 0) { > > + opae_log_err("PF1 of %s is not found\n", id->bdf); > > + } else { > > + peer_master =3D &peer[0]; > > + ret =3D opae_get_parent(peer_master, &peer_parent); > > + if (ret < 0) > > + return -ENODEV; > > + } > > + > > + get_driver(id, drv_name, sizeof(drv_name)); /* save original driver > > */ > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + if (!get_rte_rawdev(id, 1)) > > + return -ENODEV; > > + > > + lock(id); > > + opae_load_rsu_status(id, &rsu_stat, NULL); > > + if (rsu_stat !=3D IFPGA_RSU_IDLE) { > > + unlock(id); > > + if (rsu_stat =3D=3D IFPGA_RSU_REBOOT) > > + opae_log_warn("Reboot is in progress\n"); > > + else > > + opae_log_warn("Flash is in progress\n"); > > + return -EAGAIN; > > + } > > + opae_store_rsu_status(id, IFPGA_RSU_REBOOT, 0); > > + unlock(id); > > + > > + if (type =3D=3D IFPGA_BOOT_TYPE_FPGA) { > > + /* disable AER */ > > + ret =3D disable_aer(&parent); > > + if (ret < 0) { > > + opae_log_err("Failed to disable AER of %s\n", > > + parent.bdf); > > + goto reboot_end; > > + } > > + ret =3D disable_aer(&peer_parent); > > + if (ret < 0) { > > + opae_log_err("Failed to disable AER of %s\n", > > + peer_parent.bdf); > > + goto reboot_end; > > + } > > + opae_store_rsu_status(id, IFPGA_RSU_REBOOT, 1); > > + > > + /* trigger reconfiguration */ > > + ret =3D reload(id, type, page); > > + opae_store_rsu_status(id, IFPGA_RSU_REBOOT, 2); > > + if (ret =3D=3D 0) { > > + ret =3D remove_device(id); > > + for (i =3D 0; i < n; i++) > > + ret +=3D remove_device(&peer[i]); > > + if (ret =3D=3D 0) { > > + opae_log_info("Wait 10 seconds for FPGA > > reloading\n"); > > + sleep(10); > > + ret =3D scan_device(&parent, id); > > + if (ret < 0) > > + opae_log_err("Failed to rescan %s\n", > > + id->bdf); > > + if (peer_master) { > > + ret =3D scan_device(&peer_parent, > > + peer_master); > > + if (ret < 0) { > > + opae_log_err("Failed to > > rescan %s\n", > > + peer_master->bdf); > > + } > > + } > > + } > > + } > > + > > + /* restore AER */ > > + if (enable_aer(&parent) < 0) { > > + opae_log_err("Failed to enable AER of %s\n", > > + parent.bdf); > > + } > > + if (enable_aer(&peer_parent) < 0) { > > + opae_log_err("Failed to enable AER of %s\n", > > + peer_parent.bdf); > > + } > > + } else if (type =3D=3D IFPGA_BOOT_TYPE_BMC) { > > + /* disable AER */ > > + ret =3D disable_aer(&root); > > + if (ret < 0) { > > + opae_log_err("Failed to disable AER of %s\n", > > root.bdf); > > + goto reboot_end; > > + } > > + opae_store_rsu_status(id, IFPGA_RSU_REBOOT, 1); > > + > > + /* trigger reconfiguration */ > > + ret =3D reload(id, type, page); > > + opae_store_rsu_status(id, IFPGA_RSU_REBOOT, 2); > > + if (ret =3D=3D 0) { > > + ret +=3D remove_device(&ups); > > + if (ret =3D=3D 0) { > > + opae_log_info("Wait 10 seconds for BMC > > reloading\n"); > > + sleep(10); > > + ret =3D scan_device(&root, &ups); > > + if (ret < 0) > > + opae_log_err("Failed to rescan %s\n", > > + ups.bdf); > > + } > > + } > > + > > + /* restore AER */ > > + if (enable_aer(&root) < 0) > > + opae_log_err("Failed to enable AER of %s\n", > > root.bdf); > > + } else { > > + opae_log_err("Type of reboot is not supported [t:%d]\n", > > type); > > + ret =3D -EINVAL; > > + goto reboot_end; > > + } > > + > > + /* update id if bdf changed after reboot */ > > + if (opae_get_child(&parent, &fpga, 1) =3D=3D 1) { > > + if (strcmp(id->bdf, fpga.bdf)) > > + id =3D &fpga; > > + } > > + > > + ret =3D opae_bind_driver(id, drv_name); > > + if (ret < 0) > > + opae_log_err("Failed to bind original driver of %s\n", id- > > >bdf); > > + > > + ret =3D opae_probe_device(id); > > + if (ret < 0) > > + opae_log_err("Failed to probe %s [e:%d]\n", id->bdf, ret); > > + > > +reboot_end: > > + opae_store_rsu_status(id, IFPGA_RSU_IDLE, 0); > > + return ret; > > +} > > + > > +int opae_partial_reconfigure(pcidev_id id, int port, const char *gbs) > > +{ > > + struct rte_rawdev *rdev =3D NULL; > > + > > + if (!id || !gbs) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + if (!check_eal(1)) > > + return -EPERM; > > + > > + rdev =3D get_rte_rawdev(id, 1); > > + if (!rdev) > > + return -ENODEV; > > + > > + return ifpga_rawdev_partial_reconfigure(rdev, port, gbs); > > +} > > + > > +int opae_read_pci_cfg(pcidev_id id, uint32_t address, uint32_t *value) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + int fd =3D -1; > > + int ret =3D 0; > > + > > + if (!id || !value) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + snprintf(path, PATH_MAX, "%s/%s/config", > > rte_pci_get_sysfs_path(), > > + id->bdf); > > + fd =3D open(path, O_RDONLY); > > + if (fd < 0) { > > + opae_log_dbg("Failed to open \'%s\' for RDONLY [e:%s]\n", > > + path, strerror(errno)); > > + return -EIO; > > + } > > + > > + ret =3D pread(fd, value, 4, address); > > + if (ret < 0) { > > + opae_log_err("Failed to read from PCI device %s [e:%s]\n", > > + id->bdf, strerror(errno)); > > + close(fd); > > + return ret; > > + } > > + > > + opae_log_dbg("CONFIG+0x%08x -> 0x%08x\n", address, *value); > > + close(fd); > > + return 0; > > +} > > + > > +int opae_write_pci_cfg(pcidev_id id, uint32_t address, uint32_t value) > > +{ > > + char path[PATH_MAX] =3D {0}; > > + int fd =3D -1; > > + int ret =3D 0; > > + > > + if (!id) { > > + opae_log_err("Input parameter of %s is invalid\n", > > __func__); > > + return -EINVAL; > > + } > > + > > + snprintf(path, PATH_MAX, "%s/%s/config", > > rte_pci_get_sysfs_path(), > > + id->bdf); > > + fd =3D open(path, O_WRONLY); > > + if (fd < 0) { > > + opae_log_dbg("Failed to open \'%s\' for WRONLY [e:%s]\n", > > + path, strerror(errno)); > > + return -EIO; > > + } > > + > > + ret =3D pwrite(fd, &value, 4, address); > > + if (ret < 0) { > > + opae_log_err("Failed to write to PCI device %s [e:%s]\n", > > + id->bdf, strerror(errno)); > > + close(fd); > > + return ret; > > + } > > + > > + opae_log_dbg("CONFIG+0x%08x <- 0x%08x\n", address, value); > > + close(fd); > > + return 0; > > +} > > diff --git a/drivers/raw/ifpga/ifpga_opae_api.h > > b/drivers/raw/ifpga/ifpga_opae_api.h > > new file mode 100644 > > index 000000000..d4ce64280 > > --- /dev/null > > +++ b/drivers/raw/ifpga/ifpga_opae_api.h > > @@ -0,0 +1,245 @@ > > +/* SPDX-License-Identifier: BSD-3-Clause > > + * Copyright(c) 2020 Intel Corporation > > + */ > > + > > +#ifndef _OPAE_API_H > > +#define _OPAE_API_H > > + > > + > > +#ifdef __cplusplus > > +extern "C" { > > +#endif > > + > > +#include > > + > > +extern int opae_log_level; > > +extern FILE *opae_log_file; > > + > > +#define OPAE_LOG_API 0 /**< Critical conditions. */ > > +#define OPAE_LOG_ERR 1 /**< Error conditions. */ > > +#define OPAE_LOG_WARN 2 /**< Warning conditions. */ > > +#define OPAE_LOG_INFO 3 /**< Informational. */ > > +#define OPAE_LOG_DEBUG 4 /**< Debug-level messages. */ > > + > > +#define opae_log(type, fmt, args...) \ > > +do { \ > > + if (opae_log_level >=3D OPAE_LOG_##type) { \ > > + printf(fmt, ##args); \ > > + if (opae_log_file) { \ > > + fprintf(opae_log_file, fmt, ##args); \ > > + fflush(opae_log_file); \ > > + } \ > > + } \ > > +} while (0) > > + > > +#define opae_log_api(fmt, args...) opae_log(API, "OPAE-API: "fmt, > ##args) > > +#define opae_log_err(fmt, args...) opae_log(ERR, "OPAE-ERR: "fmt, > ##args) > > +#define opae_log_dbg(fmt, args...) opae_log(DEBUG, "OPAE-DBG: "fmt, > > ##args) > > +#define opae_log_warn(fmt, args...) opae_log(WARN, "OPAE-WARN: > "fmt, > > ##args) > > +#define opae_log_info(fmt, args...) opae_log(INFO, "OPAE-INFO: "fmt, > > ##args) > > + > > +#define EAL_INIT_FUNCTION "init" > > +#define EAL_DEFAULT_OPTIONS "--proc-type auto" > > + > > +#define OPAE_KDRV_UNKNOWN "unknown" > > +#define OPAE_KDRV_VFIO_PCI "vfio-pci" > > +#define OPAE_KDRV_IGB_UIO "igb_uio" > > +#define OPAE_KDRV_UIO_PCI "uio_pci_generic" > > +#define OPAE_KDRV_INTEL_FPGA_PCI "intel-fpga-pci" > > + > > +typedef struct { > > + uint32_t major; > > + uint32_t minor; > > + uint32_t micro; > > +} opae_api_version; > > + > > +#define OPAE_NAME_SIZE 32 > > + > > +typedef struct { > > + char bdf[OPAE_NAME_SIZE]; /* segment:bus:device.function */ > > +} opae_pci_device; > > + > > +typedef opae_pci_device *pcidev_id; > > + > > +typedef struct { > > + uint32_t class_id; /**< Class ID or RTE_CLASS_ANY_ID. */ > > + uint16_t vendor_id; /**< Vendor ID or PCI_ANY_ID. */ > > + uint16_t device_id; /**< Device ID or PCI_ANY_ID. */ > > + uint16_t subsystem_vendor_id; /**< Subsystem vendor ID or > > PCI_ANY_ID. */ > > + uint16_t subsystem_device_id; /**< Subsystem device ID or > > PCI_ANY_ID. */ > > +} opae_pci_id; > > + > > +typedef struct { > > + uint32_t domain; /**< Device domain */ > > + uint8_t bus; /**< Device bus */ > > + uint8_t devid; /**< Device ID */ > > + uint8_t function; /**< Device function. */ > > +} opae_pci_addr; > > + > > +typedef struct { > > + char pci_addr[OPAE_NAME_SIZE]; /* segment:bus:device.function > > */ > > + char drv_name[OPAE_NAME_SIZE]; /* vfio-pci, intel-fpga-pci, etc. > > */ > > + opae_pci_id id; > > + opae_pci_addr addr; > > +} opae_pci_property; > > + > > +#define BIT_SET_8 0xFF > > +#define BIT_SET_16 0xFFFF > > +#define BIT_SET_32 0xFFFFFFFF > > + > > +typedef struct { > > + uint8_t b[16]; > > +} opae_uuid; > > + > > +typedef struct { > > + uint32_t boot_page; > > + uint32_t num_ports; > > + uint64_t bitstream_id; > > + uint64_t bitstream_metadata; > > + opae_uuid pr_id; > > + char platform_name[OPAE_NAME_SIZE]; > > + char dcp_version[OPAE_NAME_SIZE]; > > + char release_name[OPAE_NAME_SIZE]; > > + char interface_type[OPAE_NAME_SIZE]; > > + char build_version[OPAE_NAME_SIZE]; > > +} opae_fme_property; > > + > > +typedef struct { > > + opae_uuid afu_id; > > + uint32_t type; /* AFU memory access control type */ > > + uint32_t index; /* PORT index */ > > +} opae_port_property; > > + > > +typedef struct { > > + char bmc_version[OPAE_NAME_SIZE]; > > + char fw_version[OPAE_NAME_SIZE]; > > +} opae_bmc_property; > > + > > +typedef struct { > > + uint32_t num_retimers; > > + uint32_t link_speed; > > + uint32_t link_status; /* each bit corresponding to one link status *= / > > +} opae_phy_info; > > + > > +typedef struct { > > + union { > > + uint64_t id; > > + struct { > > + uint8_t build_patch; > > + uint8_t build_minor; > > + uint8_t build_major; > > + uint8_t fvl_bypass:1; > > + uint8_t mac_lightweight:1; > > + uint8_t disagregate:1; > > + uint8_t lightweiht:1; > > + uint8_t seu:1; > > + uint8_t ptp:1; > > + uint8_t reserve:2; > > + uint16_t interface:4; > > + uint16_t afu_revision:12; > > + uint16_t patch:4; > > + uint16_t minor:4; > > + uint16_t major:4; > > + uint16_t reserved:4; > > + }; > > + }; > > +} opae_bitstream_id; > > + > > +typedef struct { > > + union { > > + uint32_t version; > > + struct { > > + uint8_t micro; > > + uint8_t minor; > > + uint8_t major; > > + uint8_t board; > > + }; > > + }; > > +} opae_bmc_version; > > + > > +#define OPAE_MAX_PORT_NUM 4 > > + > > +#define OPAE_PROP_PCI 0x01 > > +#define OPAE_PROP_FME 0x02 > > +#define OPAE_PROP_PORT 0x04 > > +#define OPAE_PROP_BMC 0x08 > > +#define OPAE_PROP_ALL \ > > + (OPAE_PROP_PCI | OPAE_PROP_FME | OPAE_PROP_PORT | > > OPAE_PROP_BMC) > > + > > +typedef struct { > > + opae_pci_property pci; > > + opae_fme_property fme; > > + opae_port_property port[OPAE_MAX_PORT_NUM]; > > + opae_bmc_property bmc; > > +} opae_fpga_property; > > + > > +typedef struct { > > + uint64_t guid_h; > > + uint64_t guid_l; > > + uint32_t metadata_len; > > +} gbs_header; > > + > > +#define OPAE_IMG_TYPE_BBS 0 > > +#define OPAE_IMG_TYPE_BMC 1 > > +#define OPAE_IMG_TYPE_GBS 2 > > +#define OPAE_IMG_TYPE(t) ((t) & 0xff) > > + > > +#define OPAE_IMG_SUBTYPE_UPDATE 0 > > +#define OPAE_IMG_SUBTYPE_CANCELLATION 1 > > +#define OPAE_IMG_SUBTYPE_ROOT_KEY_HASH_256 2 > > +#define OPAE_IMG_SUBTYPE_ROOT_KEY_HASH_384 3 > > +#define OPAE_IMG_SUBTYPE(t) (((t) >> 8) & 0xff) > > + > > +#define OPAE_IMG_BLK0_SIZE 128 > > +#define OPAE_IMG_BLK0_MAGIC 0xb6eafd19 > > +#define OPAE_IMG_BLK1_SIZE 896 > > +#define OPAE_IMG_HDR_SIZE (OPAE_IMG_BLK0_SIZE + > > OPAE_IMG_BLK1_SIZE) > > +#define OPAE_IMG_PL_MIN_SIZE 128 > > + > > +typedef struct { > > + uint32_t magic; > > + uint32_t payload_len; > > + uint32_t payload_type; > > +} opae_img_hdr; > > + > > +typedef struct { > > + int type; > > + int subtype; > > + uint32_t total_len; > > + uint32_t payload_offset; > > + uint32_t payload_len; > > +} opae_img_info; > > + > > +void opae_get_api_version(opae_api_version *version); > > +void opae_check_pcidev_list(void); > > +int opae_set_log_level(int level); > > +int opae_set_log_file(char *path, int clean); > > +int opae_get_proc_type(void); > > +int opae_get_parent(pcidev_id id, pcidev_id parent); > > +int opae_get_child(pcidev_id id, pcidev_id child, int size); > > +int opae_get_pf1(pcidev_id id, pcidev_id peer, int size); > > +int opae_init_eal(int argc, char **argv); > > +int opae_cleanup_eal(void); > > +int opae_enumerate(opae_pci_id *filter, pcidev_id list, int size); > > +int opae_probe_device(pcidev_id id); > > +int opae_remove_device(pcidev_id id); > > +int opae_unbind_driver(pcidev_id id); > > +int opae_bind_driver(pcidev_id id, char *drv_name); > > +int opae_get_property(pcidev_id id, opae_fpga_property *prop, int > type); > > +int opae_get_phy_info(pcidev_id id, opae_phy_info *info); > > +int opae_partial_reconfigure(pcidev_id id, int port, const char *gbs); > > +int opae_get_image_info(const char *image, opae_img_info *info); > > +int opae_cancel_flash_update(pcidev_id id, int force); > > +int opae_update_flash(pcidev_id id, const char *image, uint64_t *statu= s); > > +int opae_reboot_device(pcidev_id id, int type, int page); > > +int opae_store_rsu_status(pcidev_id id, uint32_t status, uint32_t > progress); > > +int opae_load_rsu_status(pcidev_id id, uint32_t *status, uint32_t > > *progress); > > +int opae_read_pci_cfg(pcidev_id id, uint32_t address, uint32_t *value)= ; > > +int opae_write_pci_cfg(pcidev_id id, uint32_t address, uint32_t value)= ; > > + > > +#ifdef __cplusplus > > +} > > +#endif > > + > > + > > +#endif /* _OPAE_API_H */ > > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c > > b/drivers/raw/ifpga/ifpga_rawdev.c > > index 8dd566e44..64ed9903e 100644 > > --- a/drivers/raw/ifpga/ifpga_rawdev.c > > +++ b/drivers/raw/ifpga/ifpga_rawdev.c > > @@ -1738,6 +1738,79 @@ > > RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, > > "port=3D " > > "afu_bts=3D"); > > > > +struct rte_pci_bus *ifpga_get_pci_bus(void) > > +{ > > + return rte_ifpga_rawdev_pmd.bus; > > +} > > + > > +int ifpga_rawdev_lock(struct rte_rawdev *dev) > > +{ > > + if (!dev) { > > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + return -EINVAL; > > + } > > + return opae_adapter_lock(ifpga_rawdev_get_priv(dev), -1); > > +} > > + > > +int ifpga_rawdev_unlock(struct rte_rawdev *dev) > > +{ > > + if (!dev) { > > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + return -EINVAL; > > + } > > + return opae_adapter_unlock(ifpga_rawdev_get_priv(dev)); > > +} > > + > > +uint32_t ifpga_rawdev_get_rsu_stat(struct rte_rawdev *dev) > > +{ > > + struct opae_adapter *adapter =3D NULL; > > + opae_share_data *sd =3D NULL; > > + > > + if (!dev) { > > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + return 0; > > + } > > + > > + adapter =3D ifpga_rawdev_get_priv(dev); > > + if (!adapter) { > > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > > + return 0; > > + } > > + > > + sd =3D (opae_share_data *)adapter->shm.ptr; > > + if (!sd) { > > + IFPGA_RAWDEV_PMD_ERR("shared memory is invalid"); > > + return 0; > > + } > > + > > + return sd->rsu_stat; > > +} > > + > > +void ifpga_rawdev_set_rsu_stat(struct rte_rawdev *dev, uint32_t value) > > +{ > > + struct opae_adapter *adapter =3D NULL; > > + opae_share_data *sd =3D NULL; > > + > > + if (!dev) { > > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + return; > > + } > > + > > + adapter =3D ifpga_rawdev_get_priv(dev); > > + if (!adapter) { > > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > > + return; > > + } > > + > > + sd =3D (opae_share_data *)adapter->shm.ptr; > > + if (!sd) { > > + IFPGA_RAWDEV_PMD_ERR("shared memory is invalid"); > > + return; > > + } > > + > > + sd->rsu_stat =3D value; > > +} > > + > > int ifpga_rawdev_get_fme_property(struct rte_rawdev *dev, > > ifpga_fme_property *prop) > > { > > @@ -1748,8 +1821,8 @@ int ifpga_rawdev_get_fme_property(struct > > rte_rawdev *dev, > > struct uuid pr_id; > > int ret =3D 0; > > > > - if (!dev) { > > - IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + if (!dev || !prop) { > > + IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); > > return -EINVAL; > > } > > > > @@ -1820,8 +1893,8 @@ int ifpga_rawdev_get_port_property(struct > > rte_rawdev *dev, uint32_t port, > > struct uuid afu_id; > > int ret =3D 0; > > > > - if (!dev) { > > - IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + if (!dev || !prop) { > > + IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); > > return -EINVAL; > > } > > > > @@ -1867,8 +1940,8 @@ int ifpga_rawdev_get_bmc_property(struct > > rte_rawdev *dev, > > struct opae_board_info *info =3D NULL; > > int ret =3D 0; > > > > - if (!dev) { > > - IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + if (!dev || !prop) { > > + IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); > > return -EINVAL; > > } > > > > @@ -1895,6 +1968,48 @@ int ifpga_rawdev_get_bmc_property(struct > > rte_rawdev *dev, > > return 0; > > } > > > > +int ifpga_rawdev_get_phy_info(struct rte_rawdev *dev, ifpga_phy_info > > *info) > > +{ > > + struct opae_adapter *adapter =3D NULL; > > + struct opae_retimer_info rtm_info; > > + struct opae_retimer_status rtm_status; > > + int ret =3D 0; > > + > > + if (!dev || !info) { > > + IFPGA_RAWDEV_PMD_ERR("Input parameter is invalid"); > > + return -EINVAL; > > + } > > + > > + adapter =3D ifpga_rawdev_get_priv(dev); > > + if (!adapter) { > > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > > + return -ENODEV; > > + } > > + > > + if (!adapter->mgr) { > > + IFPGA_RAWDEV_PMD_ERR("manager is invalid"); > > + return -ENODEV; > > + } > > + > > + ret =3D opae_manager_get_retimer_info(adapter->mgr, &rtm_info); > > + if (ret) { > > + IFPGA_RAWDEV_PMD_ERR("Failed to get retimer info"); > > + return ret; > > + } > > + > > + ret =3D opae_manager_get_retimer_status(adapter->mgr, > > &rtm_status); > > + if (ret) { > > + IFPGA_RAWDEV_PMD_ERR("Failed to get retimer status"); > > + return ret; > > + } > > + > > + info->num_retimers =3D rtm_info.nums_retimer; > > + info->link_speed =3D rtm_status.speed; > > + info->link_status =3D rtm_status.line_link_bitmap; > > + > > + return 0; > > +} > > + > > int ifpga_rawdev_update_flash(struct rte_rawdev *dev, const char > *image, > > uint64_t *status) > > { > > @@ -1949,3 +2064,28 @@ int ifpga_rawdev_reload(struct rte_rawdev > *dev, > > int type, int page) > > > > return opae_mgr_reload(adapter->mgr, type, page); > > } > > + > > +int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port, > > + const char *file) > > +{ > > + if (!dev) { > > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > > + return -EINVAL; > > + } > > + > > + return rte_fpga_do_pr(dev, port, file); > > +} > > + > > +void ifpga_rawdev_cleanup(void) > > +{ > > + struct ifpga_rawdev *dev; > > + unsigned int i; > > + > > + for (i =3D 0; i < IFPGA_RAWDEV_NUM; i++) { > > + dev =3D &ifpga_rawdevices[i]; > > + if (dev->rawdev) { > > + rte_rawdev_pmd_release(dev->rawdev); > > + dev->rawdev =3D NULL; > > + } > > + } > > +} > > diff --git a/drivers/raw/ifpga/ifpga_rawdev.h > > b/drivers/raw/ifpga/ifpga_rawdev.h > > index d4be7913d..185e79071 100644 > > --- a/drivers/raw/ifpga/ifpga_rawdev.h > > +++ b/drivers/raw/ifpga/ifpga_rawdev.h > > @@ -89,6 +89,12 @@ typedef struct { > > uint32_t fw_version; > > } ifpga_bmc_property; > > > > +typedef struct { > > + uint32_t num_retimers; > > + uint32_t link_speed; > > + uint32_t link_status; > > +} ifpga_phy_info; > > + > > int > > ifpga_register_msix_irq(struct rte_rawdev *dev, int port_id, > > enum ifpga_irq_type type, int vec_start, int count, > > @@ -98,15 +104,24 @@ int > > ifpga_unregister_msix_irq(enum ifpga_irq_type type, > > int vec_start, rte_intr_callback_fn handler, void *arg); > > > > +struct rte_pci_bus *ifpga_get_pci_bus(void); > > +int ifpga_rawdev_lock(struct rte_rawdev *dev); > > +int ifpga_rawdev_unlock(struct rte_rawdev *dev); > > +uint32_t ifpga_rawdev_get_rsu_stat(struct rte_rawdev *dev); > > +void ifpga_rawdev_set_rsu_stat(struct rte_rawdev *dev, uint32_t value)= ; > > int ifpga_rawdev_get_fme_property(struct rte_rawdev *dev, > > ifpga_fme_property *prop); > > int ifpga_rawdev_get_port_property(struct rte_rawdev *dev, uint32_t > port, > > ifpga_port_property *prop); > > int ifpga_rawdev_get_bmc_property(struct rte_rawdev *dev, > > ifpga_bmc_property *prop); > > +int ifpga_rawdev_get_phy_info(struct rte_rawdev *dev, ifpga_phy_info > > *info); > > int ifpga_rawdev_update_flash(struct rte_rawdev *dev, const char > *image, > > uint64_t *status); > > int ifpga_rawdev_stop_flash_update(struct rte_rawdev *dev, int force); > > int ifpga_rawdev_reload(struct rte_rawdev *dev, int type, int page); > > +int ifpga_rawdev_partial_reconfigure(struct rte_rawdev *dev, int port, > > + const char *file); > > +void ifpga_rawdev_cleanup(void); > > > > #endif /* _IFPGA_RAWDEV_H_ */ > > diff --git a/drivers/raw/ifpga/meson.build > b/drivers/raw/ifpga/meson.build > > index 027ff8056..417480f19 100644 > > --- a/drivers/raw/ifpga/meson.build > > +++ b/drivers/raw/ifpga/meson.build > > @@ -13,8 +13,10 @@ objs =3D [base_objs] > > deps +=3D ['ethdev', 'rawdev', 'pci', 'bus_pci', 'kvargs', > > 'bus_vdev', 'bus_ifpga', 'net', 'net_i40e', 'net_ipn3ke'] > > > > -sources =3D files('ifpga_rawdev.c') > > +sources =3D files('ifpga_rawdev.c', 'ifpga_opae_api.c') > > > > includes +=3D include_directories('base') > > includes +=3D include_directories('../../net/ipn3ke') > > includes +=3D include_directories('../../net/i40e') > > + > > +install_headers('ifpga_opae_api.h') > > -- > > 2.29.2