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 E23EEA09EF for ; Tue, 12 Jan 2021 11:46:19 +0100 (CET) Received: from [217.70.189.124] (localhost [127.0.0.1]) by mails.dpdk.org (Postfix) with ESMTP id D31A0140E5A; Tue, 12 Jan 2021 11:46:19 +0100 (CET) Received: from mga02.intel.com (mga02.intel.com [134.134.136.20]) by mails.dpdk.org (Postfix) with ESMTP id 0EE7F140E4E; Tue, 12 Jan 2021 11:46:14 +0100 (CET) IronPort-SDR: Bw6Qqo7JXDLP5uIfMrfpLaGF7A+CMilx3AS3m//zJUeU6/uZM1Bv0t7axosT1qq7pDIUDAp5KT pMpd4HjqFs0Q== X-IronPort-AV: E=McAfee;i="6000,8403,9861"; a="165103405" X-IronPort-AV: E=Sophos;i="5.79,341,1602572400"; d="scan'208";a="165103405" Received: from fmsmga006.fm.intel.com ([10.253.24.20]) by orsmga101.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 12 Jan 2021 02:46:13 -0800 IronPort-SDR: 0dIqwISzB1/tDwALfQ8Kt6xnmpp4HXLcDrduU+2iDMM8ZJKjZ+4qJ+h/X480aMkPH4cwdID05t vPo5C/6nMPZA== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.79,341,1602572400"; d="scan'208";a="569053285" Received: from orsmsx606.amr.corp.intel.com ([10.22.229.19]) by fmsmga006.fm.intel.com with ESMTP; 12 Jan 2021 02:46:12 -0800 Received: from orsmsx607.amr.corp.intel.com (10.22.229.20) by ORSMSX606.amr.corp.intel.com (10.22.229.19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 12 Jan 2021 02:46:12 -0800 Received: from orsmsx604.amr.corp.intel.com (10.22.229.17) by ORSMSX607.amr.corp.intel.com (10.22.229.20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5; Tue, 12 Jan 2021 02:46:11 -0800 Received: from ORSEDG602.ED.cps.intel.com (10.7.248.7) by orsmsx604.amr.corp.intel.com (10.22.229.17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.1713.5 via Frontend Transport; Tue, 12 Jan 2021 02:46:11 -0800 Received: from NAM02-BL2-obe.outbound.protection.outlook.com (104.47.38.58) by edgegateway.intel.com (134.134.137.103) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.1.1713.5; Tue, 12 Jan 2021 02:46:11 -0800 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=Ta7Zx/C/gOAJc+Hd3DCNM0ypFy6JOZoUSBmpvq+bgfjxV234/0VDutbNG1r/czLRAofrVuSam0cKtlKOG6AJC/3TRGXZEBQW98hgzVK6fcIZRO70Owr+7jLS12GSsKJWnISBsQGtVLz6ydkgGZuoD/vveFV2P76t+0Hv0vNyfUeq99bEh5YYxBUh5t0fV3TeM4lrixgVLuwDXWyp1NZJ/iWORHb5+99R/QUlaLkIRdZUvLdbclgWCQBucMN7uuczgA+2QV+RB7kiOzzcYDCtf5hZSw4TGdxyaTQTyN6k469ObxYp3yH0eW8vAm+nY4bcjE9sMhVpnDlZhQny4+NWzg== 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=ly7QE6If8IM81cvVhj3S3lZoWh2XFIi9ECOKt/gXG7w=; b=l7p1mYU6zESjV1wxqBQtxcNtRqfcGcTy3q5Etf4hkBZD5Ksf0zGd4n7U6PddbR5+i1MYvNKApZi+Uw5uOVeH6Cna7zq5xfSDYQaQryXkzjQ27URlAuuc33HaJQfG93YdF+og+2X5NpMgGXG2UsAwEaFy1ex95VHJvk4zlcT3ihj00I5wtbo5rADdyxG40Pxuqp7ZH0qb8CXsPo9xr/N7WVW/XslXE7vjx70MXVCvvpK3a1pY8mX9tTpDHMeIj+leU269KDVSQtqy+RRDwmtxekLNfPq68KlCXTGb5sGE4yTAOihvZW0UHr4S3fi3FoL+FBTTjaWHT+/tv4HSDdEZIg== 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=ly7QE6If8IM81cvVhj3S3lZoWh2XFIi9ECOKt/gXG7w=; b=mLdgubw8kNT8+wX8gt8xp7kQC6c7489a/W/W/K+wZQZgxTscM2RqMi67D27jUoQridzO/8bXRXNIEFLK6kc5bIYdPD1eajDNtXbfvNhS9iJWx94c+5H7OdURmAtTSUVDN8KjoC7CE/DEYWFRHnbczNbIBTqu+1Tb7oXneqPcrd4= Received: from BYAPR11MB2901.namprd11.prod.outlook.com (2603:10b6:a03:91::23) by SJ0PR11MB5053.namprd11.prod.outlook.com (2603:10b6:a03:2af::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3763.9; Tue, 12 Jan 2021 10:46:08 +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.3742.012; Tue, 12 Jan 2021 10:46:08 +0000 From: "Xu, Rosen" To: "Huang, Wei" , "dev@dpdk.org" , "Zhang, Qi Z" CC: "stable@dpdk.org" , "Zhang, Tianfei" Thread-Topic: [PATCH v9 1/4] raw/ifpga: add fpga rsu function Thread-Index: AQHW6KJNILuAOXefRkyWlzYiPKKxz6ojzRig Date: Tue, 12 Jan 2021 10:46:08 +0000 Message-ID: References: <1610428684-20708-1-git-send-email-wei.huang@intel.com> <1610428684-20708-2-git-send-email-wei.huang@intel.com> In-Reply-To: <1610428684-20708-2-git-send-email-wei.huang@intel.com> 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: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiNzc1MmZhY2QtMTg2Ni00YzQwLWI3ODktZDViNDdhNDk3Zjg0IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX05UIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE3LjEwLjE4MDQuNDkiLCJUcnVzdGVkTGFiZWxIYXNoIjoia1c1SkFVQjdXTjdITWMybmVobjZlN05waE9XU20rMzA2QzJYUVwvN1hxUDdVUFZldUxJVklLdXB5clJQQXl6WDAifQ== 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.218] x-ms-publictraffictype: Email x-ms-office365-filtering-correlation-id: 5a0f3b01-5c1a-4ff5-8037-08d8b6e7452e x-ms-traffictypediagnostic: SJ0PR11MB5053: 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:114; x-ms-exchange-senderadcheck: 1 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: ezw05TUwaIbkzvqg5upeupMSYthjwk6wSZK8KsDt6H2os9GtDz3Q36CVGts/sol4ZlUkR0jPBrd170MuRfm6N99Pujp2fgTbgACaGqegXxGXE9nNSHftgkITfmJMfQsLYPfN7AmG0T8w084F+tvoE8zO04rhIaWLMFVuGuRDipTKdrpPtN3d0ilsKEPUhSxvDOlC+3xGEGWNcUezc+Bdp/HavwjLdMS30VQF2p7JmSOdtg9Zirq7bYKjoKhFQK+0v0/BKbd3DALRIbDI9rX0xsYn+LI0xBmWv0+Q9JRIzq6FoFyI5mzwG/nrbvofIrmOw1djuzsH4HZLYD/XSpPtEiEbvFrzaHaAlF1MqVsW9fJ/L0lfaqvTRRL9uJE3cEi8VlNTI+0xuMIxgiA8xEeazQ== 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)(366004)(396003)(136003)(346002)(39860400002)(376002)(478600001)(110136005)(54906003)(8676002)(316002)(8936002)(86362001)(450100002)(52536014)(71200400001)(30864003)(55016002)(9686003)(7696005)(26005)(107886003)(4326008)(64756008)(66946007)(33656002)(2906002)(66556008)(83380400001)(76116006)(6636002)(66476007)(66446008)(186003)(5660300002)(53546011)(6506007)(559001)(579004); DIR:OUT; SFP:1102; x-ms-exchange-antispam-messagedata: =?us-ascii?Q?feN05HWkr1XNzm571i1C+NESoD54VI0CjRE1UjwCCHO5zmVsnWEgNFP3Djzm?= =?us-ascii?Q?xoPE27SpCNiinLHAzUjd5EIhUX56gfdLTEt7LkgpK4T0fJ2dZt8Oou5LhO8w?= =?us-ascii?Q?6NhtW9J7x5KMEWvOZw/xhMl1OHq68XQR/aMLQ8xVa2ZSU3gC/YtXWq1b7P+R?= =?us-ascii?Q?FZeqPUBp+exvihi1cAa5FA51Mp6HYq2iw8oD1cPRrreWBGYsz2cLz6tnMEkL?= =?us-ascii?Q?dIndEdI9U3nTsB65AnG8bYsx/ae6AsM0kHhMu82J5drvDtBsE19R4PS+nrs2?= =?us-ascii?Q?sfw50f9KYfMZnda8ePGCGmh9gpmSWY0jdtvUwVSjn7Nz59F5RGKxwrXL2o+t?= =?us-ascii?Q?sz3ozmRQO4QHfZye6uFcGhjmRNI9MDvcp92GLchWaqrEJEoqkVKHaspJSa8n?= =?us-ascii?Q?Nnkk34KybhTfGSrYHp+O2DVMeEgD+g8NWQDeIA7/W67SutJ4pMNM3UiHc87r?= =?us-ascii?Q?tgOVYNBk0Y/VbeSumPOcV0YEd/ssJcoHxMZA7oq4+z+fFANmGGgjs1sJ3D3E?= =?us-ascii?Q?sdj7or0j8T0yWcw35aJhQzD5xCH6wM9VaSK2gx9oMSlzUWfALqrp5QHIHVon?= =?us-ascii?Q?Xnjc8qAuSZvRY9GejfJx05/mJkSt8lLDeSLVlxXHbIPdoCgarSh1iwzs2kpl?= =?us-ascii?Q?UJ7910AEYQDtlz28okILNv8y7/ENcGgAHk9gfclnmeg3Nr9BHsC9IEk0aQhH?= =?us-ascii?Q?lu+in5Unl9IJUPLkiKEuJKcdZX8U2PE3rNG9uOaEC0ylko0nMbPqdKDt+23J?= =?us-ascii?Q?ftW1DLvgeJ+iBwHwrmaLf5YDABDrS5MAkoB5vIDJdxm51GWQp0mUGKGphr5j?= =?us-ascii?Q?GPDOsfuHpWMddiOAgDkQ8XGox4FHSecFe2aHjptkKkKoR3zBweqwu7QrOv1O?= =?us-ascii?Q?od+4pyN+omLycmYpFttENIiZeaxf21GWexnstCLVC8dYWqNbLz6KEzJ20/9z?= =?us-ascii?Q?jNV6gXeMjeMamInFExZDol1qaJwunWGQti4ZH1B/J5BhmiinK9m/K64nWETw?= =?us-ascii?Q?AbVy?= 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: 5a0f3b01-5c1a-4ff5-8037-08d8b6e7452e X-MS-Exchange-CrossTenant-originalarrivaltime: 12 Jan 2021 10:46:08.6231 (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: ehyvyVkxJR2htZZRYYlkVJo9CpyUlo3K878w0z6SX4aBj7bAQUXP5Pem89fyDeGrXILB/VdoGTb7cooDdLfLJw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ0PR11MB5053 X-OriginatorOrg: intel.com Subject: Re: [dpdk-stable] [PATCH v9 1/4] raw/ifpga: add fpga rsu function 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, > -----Original Message----- > From: Huang, Wei > Sent: Tuesday, January 12, 2021 13:18 > To: dev@dpdk.org; Xu, Rosen ; Zhang, Qi Z > > Cc: stable@dpdk.org; Zhang, Tianfei ; Huang, Wei > > Subject: [PATCH v9 1/4] raw/ifpga: add fpga rsu function >=20 > RSU (Remote System Update) depends on secure manager which may be > different on various implementations, so a new secure manager device is > implemented for adapting such difference. > There are three major functions added: > 1. ifpga_rawdev_update_flash() updates flash with specific image file. > 2. ifpga_rawdev_stop_flash_update() aborts flash update process. > 3. ifpga_rawdev_reload() reloads FPGA from updated flash. >=20 > Signed-off-by: Wei Huang > --- > v2: fix coding style issue in ifpga_fme_rsu.c and ifpga_sec_mgr.c > --- > v3: fix compilation issues in ifpga_fme_rsu.c > --- > v4: fix compilation issues in opae_intel_max10.c > --- > drivers/raw/ifpga/base/ifpga_api.c | 26 + > drivers/raw/ifpga/base/ifpga_fme.c | 8 + > drivers/raw/ifpga/base/ifpga_fme_rsu.c | 435 +++++++++++++++ > drivers/raw/ifpga/base/ifpga_hw.h | 1 + > drivers/raw/ifpga/base/ifpga_sec_mgr.c | 639 ++++++++++++++++++++++ > drivers/raw/ifpga/base/ifpga_sec_mgr.h | 89 +++ > drivers/raw/ifpga/base/meson.build | 2 + > drivers/raw/ifpga/base/opae_hw_api.c | 59 ++ > drivers/raw/ifpga/base/opae_hw_api.h | 11 + > drivers/raw/ifpga/base/opae_intel_max10.c | 48 ++ > drivers/raw/ifpga/base/opae_intel_max10.h | 44 ++ > drivers/raw/ifpga/ifpga_rawdev.c | 55 ++ > drivers/raw/ifpga/ifpga_rawdev.h | 7 +- > 13 files changed, 1423 insertions(+), 1 deletion(-) create mode 100644 > drivers/raw/ifpga/base/ifpga_fme_rsu.c > create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.c > create mode 100644 drivers/raw/ifpga/base/ifpga_sec_mgr.h >=20 > diff --git a/drivers/raw/ifpga/base/ifpga_api.c > b/drivers/raw/ifpga/base/ifpga_api.c > index 1ff57fa18..1aedf150b 100644 > --- a/drivers/raw/ifpga/base/ifpga_api.c > +++ b/drivers/raw/ifpga/base/ifpga_api.c > @@ -5,6 +5,7 @@ > #include "ifpga_api.h" > #include "ifpga_enumerate.h" > #include "ifpga_feature_dev.h" > +#include "ifpga_sec_mgr.h" >=20 > #include "opae_hw_api.h" >=20 > @@ -228,11 +229,36 @@ static int ifpga_mgr_get_board_info(struct > opae_manager *mgr, > return 0; > } >=20 > +static int ifpga_mgr_update_flash(struct opae_manager *mgr, const char > *image, > + u64 *status) > +{ > + struct ifpga_fme_hw *fme =3D mgr->data; > + > + return fpga_update_flash(fme, image, status); } > + > +static int ifpga_mgr_stop_flash_update(struct opae_manager *mgr, int > +force) { > + struct ifpga_fme_hw *fme =3D mgr->data; > + > + return fpga_stop_flash_update(fme, force); } > + > +static int ifpga_mgr_reload(struct opae_manager *mgr, int type, int > +page) { > + struct ifpga_fme_hw *fme =3D mgr->data; > + > + return fpga_reload(fme, type, page); > +} > + > struct opae_manager_ops ifpga_mgr_ops =3D { > .flash =3D ifpga_mgr_flash, > .get_eth_group_region_info =3D ifpga_mgr_get_eth_group_region_info, > .get_sensor_value =3D ifpga_mgr_get_sensor_value, > .get_board_info =3D ifpga_mgr_get_board_info, > + .update_flash =3D ifpga_mgr_update_flash, > + .stop_flash_update =3D ifpga_mgr_stop_flash_update, > + .reload =3D ifpga_mgr_reload, > }; >=20 > static int ifpga_mgr_read_mac_rom(struct opae_manager *mgr, int offset, > diff --git a/drivers/raw/ifpga/base/ifpga_fme.c > b/drivers/raw/ifpga/base/ifpga_fme.c > index f29ff3159..34fd9a818 100644 > --- a/drivers/raw/ifpga/base/ifpga_fme.c > +++ b/drivers/raw/ifpga/base/ifpga_fme.c > @@ -7,6 +7,7 @@ > #include "opae_intel_max10.h" > #include "opae_i2c.h" > #include "opae_at24_eeprom.h" > +#include "ifpga_sec_mgr.h" >=20 > #define PWR_THRESHOLD_MAX 0x7F >=20 > @@ -1152,6 +1153,12 @@ static int fme_nios_spi_init(struct ifpga_feature > *feature) > if (spi_self_checking(max10)) > goto spi_fail; >=20 > + ret =3D init_sec_mgr(fme); > + if (ret) { > + dev_err(fme, "security manager init fail\n"); > + goto spi_fail; > + } > + > return ret; >=20 > spi_fail: > @@ -1165,6 +1172,7 @@ static void fme_nios_spi_uinit(struct ifpga_feature > *feature) { > struct ifpga_fme_hw *fme =3D (struct ifpga_fme_hw *)feature->parent; >=20 > + release_sec_mgr(fme); > if (fme->max10_dev) > intel_max10_device_remove(fme->max10_dev); > } > diff --git a/drivers/raw/ifpga/base/ifpga_fme_rsu.c > b/drivers/raw/ifpga/base/ifpga_fme_rsu.c > new file mode 100644 > index 000000000..fad1ac416 > --- /dev/null > +++ b/drivers/raw/ifpga/base/ifpga_fme_rsu.c > @@ -0,0 +1,435 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation > + */ > + > +#include > +#include > +#include > +#include "ifpga_sec_mgr.h" > + > +static struct ifpga_sec_mgr *sec_mgr; > + > +static void set_rsu_control(struct ifpga_sec_mgr *smgr, uint32_t ctrl) > +{ > + if (smgr && smgr->rsu_control) > + *smgr->rsu_control =3D ctrl; > +} > + > +static uint32_t get_rsu_control(struct ifpga_sec_mgr *smgr) { > + if (smgr && smgr->rsu_control) > + return *smgr->rsu_control; > + return 0; > +} > + > +static void set_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t status, > + uint32_t progress) > +{ > + if (smgr && smgr->rsu_status) > + *smgr->rsu_status =3D ((status << 16) & 0xffff0000) | > + (progress & 0xffff); > +} > + > +static void get_rsu_status(struct ifpga_sec_mgr *smgr, uint32_t *status, > + uint32_t *progress) > +{ > + if (smgr && smgr->rsu_status) { > + if (status) > + *status =3D (*smgr->rsu_status >> 16) & 0xffff; > + if (progress) > + *progress =3D *smgr->rsu_status & 0xffff; > + } > + if (smgr && smgr->rsu_status) { > + if (status) > + *status =3D (*smgr->rsu_status >> 16) & 0xffff; > + if (progress) > + *progress =3D *smgr->rsu_status & 0xffff; > + } > +} > + > +static void sig_handler(int sig, siginfo_t *info, void *data) { > + (void)(info); > + (void)(data); > + > + switch (sig) { > + case SIGINT: > + if (sec_mgr) { > + dev_info(sec_mgr, "Interrupt secure flash update" > + " by keyboard\n"); > + set_rsu_control(sec_mgr, IFPGA_RSU_ABORT); > + } > + break; > + default: > + break; > + } > +} > + > +static void log_time(time_t t, const char *msg) { > + uint32_t h =3D 0; > + uint32_t m =3D 0; > + uint32_t s =3D 0; > + > + if (t < 60) { > + s =3D (uint32_t)t; > + } else if (t < 3600) { > + s =3D (uint32_t)(t % 60); > + m =3D (uint32_t)(t / 60); > + } else { > + s =3D (uint32_t)(t % 60); > + m =3D (uint32_t)((t % 3600) / 60); > + h =3D (uint32_t)(t / 3600); > + } > + printf("%s - %02u:%02u:%02u\n", msg, h, m, s); } > + > +static int start_flash_update(struct ifpga_sec_mgr *smgr) { > + if (!smgr) > + return -ENODEV; > + > + if (!smgr->ops || !smgr->ops->prepare) > + return -EINVAL; > + > + return smgr->ops->prepare(smgr); > +} > + > +static int write_flash_image(struct ifpga_sec_mgr *smgr, const char *ima= ge, > + uint32_t offset) > +{ > + void *buf =3D NULL; > + int retry =3D 0; > + uint32_t length =3D 0; > + uint32_t to_transfer =3D 0; > + uint32_t one_percent =3D 0; > + uint32_t prog =3D 0; > + uint32_t old_prog =3D -1; > + ssize_t read_size =3D 0; > + int fd =3D -1; > + int ret =3D 0; > + > + if (!smgr) > + return -ENODEV; > + > + if (!smgr->ops || !smgr->ops->write_blk) > + return -EINVAL; > + > + fd =3D open(image, O_RDONLY); > + if (fd < 0) { > + dev_err(smgr, > + "Failed to open \'%s\' for RD [e:%s]\n", > + image, strerror(errno)); > + return -EIO; > + } > + > + buf =3D malloc(IFPGA_RSU_DATA_BLK_SIZE); Why not opae_malloc() or rte_malloc()? > + if (!buf) { > + dev_err(smgr, "Failed to allocate memory for flash > update\n"); > + close(fd); > + return -ENOMEM; > + } > + > + length =3D smgr->rsu_length; > + one_percent =3D length / 100; > + do { > + to_transfer =3D (length > IFPGA_RSU_DATA_BLK_SIZE) ? > + IFPGA_RSU_DATA_BLK_SIZE : length; > + lseek(fd, offset, SEEK_SET); > + read_size =3D read(fd, buf, to_transfer); > + if (read_size < 0) { > + dev_err(smgr, "Failed to read from \'%s\' [e:%s]\n", > + image, strerror(errno)); > + ret =3D -EIO; > + goto end; > + } > + if ((uint32_t)read_size !=3D to_transfer) { > + dev_err(smgr, > + "Read length %zd is not expected [e:%u]\n", > + read_size, to_transfer); > + ret =3D -EIO; > + goto end; > + } > + > + retry =3D 0; > + do { > + if (get_rsu_control(smgr) =3D=3D IFPGA_RSU_ABORT) { > + ret =3D -EAGAIN; > + goto end; > + } > + ret =3D smgr->ops->write_blk(smgr, buf, offset, > + to_transfer); > + if (ret =3D=3D 0) > + break; > + sleep(1); > + } while (++retry <=3D IFPGA_RSU_WRITE_RETRY); > + if (retry > IFPGA_RSU_WRITE_RETRY) { > + dev_err(smgr, "Failed to write to staging area > 0x%x\n", > + offset); > + ret =3D -EAGAIN; > + goto end; > + } > + > + length -=3D to_transfer; > + offset +=3D to_transfer; > + prog =3D offset / one_percent; > + if (prog !=3D old_prog) { > + printf("\r%d%%", prog); > + fflush(stdout); > + set_rsu_status(smgr, IFPGA_RSU_READY, prog); > + old_prog =3D prog; > + } > + } while (length > 0); > + set_rsu_status(smgr, IFPGA_RSU_READY, 100); > + printf("\n"); > + > +end: > + free(buf); > + close(fd); > + return ret; > +} > + > +static int apply_flash_update(struct ifpga_sec_mgr *smgr) { > + uint32_t one_percent =3D 0; > + uint32_t one_percent_time =3D 0; > + uint32_t prog =3D 0; > + uint32_t old_prog =3D -1; > + uint32_t copy_time =3D 0; > + int ret =3D 0; > + > + if (!smgr) > + return -ENODEV; > + > + if (!smgr->ops || !smgr->ops->write_done || !smgr->ops- > >check_complete) > + return -EINVAL; > + > + if (smgr->ops->write_done(smgr) < 0) { > + dev_err(smgr, "Failed to apply flash update\n"); > + return -EAGAIN; > + } > + > + one_percent =3D (smgr->rsu_length + 99) / 100; > + if (smgr->copy_speed =3D=3D 0) /* avoid zero divide fault */ > + smgr->copy_speed =3D 1; > + one_percent_time =3D (one_percent + smgr->copy_speed - 1) / > + smgr->copy_speed; > + if (one_percent_time =3D=3D 0) /* avoid zero divide fault */ > + one_percent_time =3D 1; > + > + do { > + ret =3D smgr->ops->check_complete(smgr); > + if (ret !=3D -EAGAIN) > + break; > + sleep(1); > + copy_time +=3D 1; > + prog =3D copy_time / one_percent_time; > + if (prog >=3D 100) > + prog =3D 99; > + if (prog !=3D old_prog) { > + printf("\r%d%%", prog); > + fflush(stdout); > + set_rsu_status(smgr, IFPGA_RSU_COPYING, prog); > + old_prog =3D prog; > + } > + } while (true); > + > + if (ret < 0) { > + printf("\n"); > + dev_err(smgr, "Failed to complete secure flash update\n"); > + } else { > + printf("\r100%%\n"); > + set_rsu_status(smgr, IFPGA_RSU_COPYING, 100); > + } > + > + return ret; > +} > + > +static int secure_update_cancel(struct ifpga_sec_mgr *smgr) { > + if (!smgr) > + return -ENODEV; > + > + if (!smgr->ops || !smgr->ops->cancel) > + return -EINVAL; > + > + return smgr->ops->cancel(smgr); > +} > + > +static int secure_update_status(struct ifpga_sec_mgr *smgr, uint64_t > +*status) { > + if (!smgr) > + return -ENODEV; > + > + if (!smgr->ops || !smgr->ops->get_hw_errinfo) > + return -EINVAL; > + > + if (status) > + *status =3D smgr->ops->get_hw_errinfo(smgr); > + > + return 0; > +} > + > +int fpga_update_flash(struct ifpga_fme_hw *fme, const char *image, > + uint64_t *status) > +{ > + struct ifpga_hw *hw =3D NULL; > + struct ifpga_sec_mgr *smgr =3D NULL; > + uint32_t rsu_stat =3D 0; > + int fd =3D -1; > + struct sigaction old_sigint_action; > + struct sigaction sa; > + time_t start; > + int ret =3D 0; > + > + if (!fme || !image || !status) { > + dev_err(fme, "Input parameter of %s is invalid\n", __func__); > + return -EINVAL; > + } > + > + hw =3D (struct ifpga_hw *)fme->parent; > + if (!hw) { > + dev_err(fme, "Parent of FME not found\n"); > + return -ENODEV; > + } > + > + smgr =3D (struct ifpga_sec_mgr *)fme->sec_mgr; > + if (!smgr || !smgr->max10_dev) { > + dev_err(smgr, "Security manager not initialized\n"); > + return -ENODEV; > + } > + > + opae_adapter_lock(hw->adapter, -1); > + get_rsu_status(smgr, &rsu_stat, NULL); > + if (rsu_stat !=3D IFPGA_RSU_IDLE) { > + opae_adapter_unlock(hw->adapter); > + if (rsu_stat =3D=3D IFPGA_RSU_REBOOT) > + dev_info(smgr, "Reboot is in progress\n"); > + else > + dev_info(smgr, "Update is in progress\n"); > + return -EAGAIN; > + } > + set_rsu_control(smgr, 0); > + set_rsu_status(smgr, IFPGA_RSU_PREPARE, 0); > + opae_adapter_unlock(hw->adapter); > + > + fd =3D open(image, O_RDONLY); > + if (fd < 0) { > + dev_err(smgr, > + "Failed to open \'%s\' for RD [e:%s]\n", > + image, strerror(errno)); > + return -EIO; > + } > + smgr->rsu_length =3D lseek(fd, 0, SEEK_END); > + close(fd); > + > + if (smgr->max10_dev->staging_area_size < smgr->rsu_length) { > + dev_err(dev, "Size of staging area is small than image length " > + "[%u<%u]\n", smgr->max10_dev->staging_area_size, > + smgr->rsu_length); > + return -EINVAL; > + } > + > + printf("Updating from file \'%s\' with size %u\n", > + image, smgr->rsu_length); > + > + sec_mgr =3D smgr; > + memset(&sa, 0, sizeof(struct sigaction)); > + sa.sa_flags =3D SA_SIGINFO | SA_RESETHAND; > + sa.sa_sigaction =3D sig_handler; > + ret =3D sigaction(SIGINT, &sa, &old_sigint_action); > + if (ret < 0) { > + dev_warn(dev, "Failed to register signal handler" > + " [e:%d]\n", ret); > + sec_mgr =3D NULL; > + } > + > + start =3D time(NULL); > + log_time(time(NULL) - start, "Starting secure flash update"); > + ret =3D start_flash_update(smgr); > + if (ret < 0) > + goto end; > + > + set_rsu_status(smgr, IFPGA_RSU_READY, 0); > + log_time(time(NULL) - start, "Writing to staging area"); > + ret =3D write_flash_image(smgr, image, 0); > + if (ret < 0) > + goto end; > + > + set_rsu_status(smgr, IFPGA_RSU_COPYING, 0); > + log_time(time(NULL) - start, "Applying secure flash update"); > + ret =3D apply_flash_update(smgr); > + > +end: > + if (sec_mgr) { > + sec_mgr =3D NULL; > + if (sigaction(SIGINT, &old_sigint_action, NULL) < 0) > + dev_err(smgr, "Failed to unregister signal handler\n"); > + } > + > + secure_update_status(smgr, status); > + if (ret < 0) { > + log_time(time(NULL) - start, "Secure flash update ERROR"); > + if (ret =3D=3D -EAGAIN) > + secure_update_cancel(smgr); > + } else { > + log_time(time(NULL) - start, "Secure flash update OK"); > + } > + set_rsu_status(smgr, IFPGA_RSU_IDLE, 0); > + > + return ret; > +} > + > +int fpga_stop_flash_update(struct ifpga_fme_hw *fme, int force) { > + struct ifpga_sec_mgr *smgr =3D NULL; > + uint32_t status =3D 0; > + int retry =3D IFPGA_RSU_CANCEL_RETRY; > + int ret =3D 0; > + > + if (!fme) { > + dev_err(fme, "Input parameter of %s is invalid\n", __func__); > + return -EINVAL; > + } > + smgr =3D (struct ifpga_sec_mgr *)fme->sec_mgr; > + > + get_rsu_status(smgr, &status, NULL); > + if (status !=3D IFPGA_RSU_IDLE) { > + dev_info(smgr, "Cancel secure flash update\n"); > + set_rsu_control(smgr, IFPGA_RSU_ABORT); > + } > + > + if (force) { > + sleep(2); > + do { > + get_rsu_status(smgr, &status, NULL); > + if (status =3D=3D IFPGA_RSU_IDLE) > + break; > + if (secure_update_cancel(smgr) =3D=3D 0) > + set_rsu_status(smgr, IFPGA_RSU_IDLE, 0); > + sleep(1); > + } while (--retry > 0); > + if (retry <=3D 0) { > + dev_err(smgr, "Failed to stop flash update\n"); > + ret =3D -EAGAIN; > + } > + } > + > + return ret; > +} > + > +int fpga_reload(struct ifpga_fme_hw *fme, int type, int page) { > + struct ifpga_sec_mgr *smgr =3D NULL; > + > + if (!fme) { > + dev_err(fme, "Input parameter of %s is invalid\n", __func__); > + return -EINVAL; > + } > + smgr =3D (struct ifpga_sec_mgr *)fme->sec_mgr; > + > + if (!smgr || !smgr->ops || !smgr->ops->reload) > + return -EINVAL; > + > + return smgr->ops->reload(smgr, type, page); } > diff --git a/drivers/raw/ifpga/base/ifpga_hw.h > b/drivers/raw/ifpga/base/ifpga_hw.h > index 7c3307fe7..ed5edc601 100644 > --- a/drivers/raw/ifpga/base/ifpga_hw.h > +++ b/drivers/raw/ifpga/base/ifpga_hw.h > @@ -91,6 +91,7 @@ struct ifpga_fme_hw { > struct opae_board_info board_info; > int nums_eth_dev; > unsigned int nums_acc_region; > + void *sec_mgr; > }; >=20 > enum ifpga_port_state { > diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.c > b/drivers/raw/ifpga/base/ifpga_sec_mgr.c > new file mode 100644 > index 000000000..4cf1db304 > --- /dev/null > +++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.c > @@ -0,0 +1,639 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation > + */ > + > +#include > +#include > +#include > +#include "ifpga_sec_mgr.h" > + > + > +static const char * const rsu_prog[] =3D {"IDLE", "PREPARING", "SLEEPING= ", > + "READY", "AUTHENTICATING", "COPYING", "CANCELLATION", > "PROGRAMMING_KEY", > + "DONE", "PKVL_DONE"}; > +static const char * const rsu_statl[] =3D {"NORMAL", "TIMEOUT", "AUTH_FA= IL", > + "COPY_FAIL", "FATAL", "PKVL_REJECT", "NON_INCR", "ERASE_FAIL", > + "WEAROUT"}; > +static const char * const rsu_stath[] =3D {"NIOS_OK", "USER_OK", > "FACTORY_OK", > + "USER_FAIL", "FACTORY_FAIL", "NIOS_FLASH_ERR", > "FPGA_FLASH_ERR"}; > + > +static const char *rsu_progress_name(uint32_t prog) { > + if (prog > SEC_PROGRESS_PKVL_PROM_DONE) > + return "UNKNOWN"; > + else > + return rsu_prog[prog]; > +} > + > +static const char *rsu_status_name(uint32_t stat) { > + if (stat >=3D SEC_STATUS_NIOS_OK) { > + if (stat > SEC_STATUS_FPGA_FLASH_ERR) > + return "UNKNOWN"; > + else > + return rsu_stath[stat-SEC_STATUS_NIOS_OK]; > + } else { > + if (stat > SEC_STATUS_WEAROUT) > + return "UNKNOWN"; > + else > + return rsu_statl[stat]; > + } > +} > + > +static bool secure_start_done(uint32_t doorbell) { > + return (SEC_STATUS_G(doorbell) =3D=3D SEC_STATUS_ERASE_FAIL || > + SEC_STATUS_G(doorbell) =3D=3D SEC_STATUS_WEAROUT || > + (SEC_PROGRESS_G(doorbell) !=3D SEC_PROGRESS_IDLE && > + SEC_PROGRESS_G(doorbell) !=3D SEC_PROGRESS_RSU_DONE)); } > + > +static bool secure_prog_ready(uint32_t doorbell) { > + return (SEC_PROGRESS_G(doorbell) !=3D SEC_PROGRESS_READY); } > + > +static int poll_timeout(struct intel_max10_device *dev, uint32_t offset, > + bool (*cond)(uint32_t), uint32_t interval_ms, uint32_t timeout_ms) { > + uint32_t val =3D 0; > + int ret =3D 0; > + > + for (;;) { > + ret =3D max10_sys_read(dev, offset, &val); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 register 0x%x > [e:%d]\n", > + offset, ret); > + break; > + } > + > + if (cond(val)) { > + dev_debug(dev, > + "Read 0x%08x from max10 register 0x%x " > + "[poll success]\n", val, offset); > + ret =3D 0; > + break; > + } > + if (timeout_ms > interval_ms) > + timeout_ms -=3D interval_ms; > + else > + timeout_ms =3D 0; > + if (timeout_ms =3D=3D 0) { > + dev_debug(dev, > + "Read 0x%08x from max10 register 0x%x " > + "[poll timeout]\n", val, offset); > + ret =3D -ETIMEDOUT; > + break; > + } > + msleep(interval_ms); > + } > + > + return ret; > +} > + > +static int n3000_secure_update_start(struct intel_max10_device *dev) { > + uint32_t doorbell =3D 0; > + uint32_t prog =3D 0; > + uint32_t status =3D 0; > + int ret =3D 0; > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + prog =3D SEC_PROGRESS_G(doorbell); > + if ((prog !=3D SEC_PROGRESS_IDLE) && (prog !=3D > SEC_PROGRESS_RSU_DONE)) { > + dev_debug(dev, "Current RSU progress is %s\n", > + rsu_progress_name(prog)); > + return -EBUSY; > + } > + > + ret =3D max10_sys_update_bits(dev, MAX10_DOORBELL, > + RSU_REQUEST | HOST_STATUS, RSU_REQUEST); > + if (ret < 0) { > + dev_err(dev, > + "Failed to updt max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + ret =3D poll_timeout(dev, MAX10_DOORBELL, secure_start_done, > + IFPGA_SEC_START_INTERVAL_MS, > IFPGA_SEC_START_TIMEOUT_MS); > + if (ret < 0) { > + dev_err(dev, > + "Failed to poll max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + status =3D SEC_STATUS_G(doorbell); > + if (status =3D=3D SEC_STATUS_WEAROUT) > + return -EAGAIN; > + > + if (status =3D=3D SEC_STATUS_ERASE_FAIL) > + return -EIO; > + > + return 0; > +} > + > +static int n3000_cancel(struct ifpga_sec_mgr *smgr) { > + struct intel_max10_device *dev =3D NULL; > + uint32_t doorbell =3D 0; > + uint32_t prog =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + prog =3D SEC_PROGRESS_G(doorbell); > + if (prog =3D=3D SEC_PROGRESS_IDLE) > + return 0; > + if (prog !=3D SEC_PROGRESS_READY) > + return -EBUSY; > + > + return max10_sys_update_bits(dev, MAX10_DOORBELL, > HOST_STATUS, > + HOST_STATUS_S(HOST_STATUS_ABORT_RSU)); > +} > + > +static int n3000_prepare(struct ifpga_sec_mgr *smgr) { > + struct intel_max10_device *dev =3D NULL; > + int retry =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + ret =3D n3000_secure_update_start(dev); > + if (ret =3D=3D -EBUSY) > + n3000_cancel(smgr); > + > + while (ret) { > + if (++retry > IFPGA_RSU_START_RETRY) > + break; > + msleep(1000); Why not rte_delay_ms()? > + ret =3D n3000_secure_update_start(dev); > + } > + if (retry > IFPGA_RSU_START_RETRY) { > + dev_err(dev, "Failed to start secure flash update\n"); > + ret =3D -EAGAIN; > + } > + > + return ret; > +} > + > +static int n3000_bulk_write(struct intel_max10_device *dev, uint32_t add= r, > + char *buf, uint32_t len) > +{ > + uint32_t i =3D 0; > + uint32_t n =3D 0; > + uint32_t v =3D 0; > + uint32_t p =3D 0; > + int ret =3D 0; > + > + if (len & 0x3) { > + dev_err(dev, > + "Length of data block is not 4 bytes aligned [e:%u]\n", > + len); > + return -EINVAL; > + } > + > + n =3D len >> 2; > + for (i =3D 0; i < n; i++) { > + p =3D i << 2; > + v =3D *(uint32_t *)(buf + p); > + ret =3D max10_reg_write(dev, addr + p, v); > + if (ret < 0) { > + dev_err(dev, > + "Failed to write to staging area 0x%08x > [e:%d]\n", > + addr + p, ret); > + return ret; > + } > + usleep(1); > + } > + > + return 0; > +} > + > +static int n3000_write_blk(struct ifpga_sec_mgr *smgr, char *buf, > + uint32_t offset, uint32_t len) > +{ > + struct intel_max10_device *dev =3D NULL; > + uint32_t doorbell =3D 0; > + uint32_t prog =3D 0; > + uint32_t m =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + if (offset + len > dev->staging_area_size) { > + dev_err(dev, > + "Write position would be out of staging area > [e:%u]\n", > + dev->staging_area_size); > + return -ENOMEM; > + } > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + prog =3D SEC_PROGRESS_G(doorbell); > + if (prog =3D=3D SEC_PROGRESS_PREPARE) > + return -EAGAIN; > + else if (prog !=3D SEC_PROGRESS_READY) > + return -EBUSY; > + > + m =3D len & 0x3; > + if (m !=3D 0) > + len +=3D 4 - m; /* make length to 4 bytes align */ > + > + return n3000_bulk_write(dev, dev->staging_area_base + offset, buf, > +len); } > + > +static int n3000_write_done(struct ifpga_sec_mgr *smgr) { > + struct intel_max10_device *dev =3D NULL; > + uint32_t doorbell =3D 0; > + uint32_t prog =3D 0; > + uint32_t status =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + prog =3D SEC_PROGRESS_G(doorbell); > + if (prog !=3D SEC_PROGRESS_READY) > + return -EBUSY; > + > + ret =3D max10_sys_update_bits(dev, MAX10_DOORBELL, HOST_STATUS, > + HOST_STATUS_S(HOST_STATUS_WRITE_DONE)); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + ret =3D poll_timeout(dev, MAX10_DOORBELL, secure_prog_ready, > + IFPGA_NIOS_HANDSHAKE_INTERVAL_MS, > + IFPGA_NIOS_HANDSHAKE_TIMEOUT_MS); > + if (ret < 0) { > + dev_err(dev, > + "Failed to poll max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + status =3D SEC_STATUS_G(doorbell); > + switch (status) { > + case SEC_STATUS_NORMAL: > + case SEC_STATUS_NIOS_OK: > + case SEC_STATUS_USER_OK: > + case SEC_STATUS_FACTORY_OK: > + ret =3D 0; > + break; > + default: > + ret =3D -EIO; > + break; > + } > + > + return ret; > +} > + > +static int n3000_check_complete(struct ifpga_sec_mgr *smgr) { > + struct intel_max10_device *dev =3D NULL; > + uint32_t doorbell =3D 0; > + uint32_t status =3D 0; > + uint32_t prog =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read max10 doorbell register [e:%d]\n", > + ret); > + return ret; > + } > + > + status =3D SEC_STATUS_G(doorbell); > + switch (status) { > + case SEC_STATUS_NORMAL: > + case SEC_STATUS_NIOS_OK: > + case SEC_STATUS_USER_OK: > + case SEC_STATUS_FACTORY_OK: > + case SEC_STATUS_WEAROUT: > + break; > + default: > + return -EIO; > + } > + > + prog =3D SEC_PROGRESS_G(doorbell); > + switch (prog) { > + case SEC_PROGRESS_IDLE: > + case SEC_PROGRESS_RSU_DONE: > + return 0; > + case SEC_PROGRESS_AUTHENTICATING: > + case SEC_PROGRESS_COPYING: > + case SEC_PROGRESS_UPDATE_CANCEL: > + case SEC_PROGRESS_PROGRAM_KEY_HASH: > + return -EAGAIN; > + case SEC_PROGRESS_PREPARE: > + case SEC_PROGRESS_READY: > + return -EBUSY; > + default: > + return -EIO; > + } > + > + return 0; > +} > + > +static int n3000_reload_fpga(struct intel_max10_device *dev, int page) > +{ > + int ret =3D 0; > + > + dev_info(dev, "Reload FPGA\n"); > + > + if (!dev || ((page !=3D 0) && (page !=3D 1))) { > + dev_err(dev, "Input parameter of %s is invalid\n", __func__); > + ret =3D -EINVAL; > + goto end; > + } > + > + if (dev->flags & MAX10_FLAGS_SECURE) { > + ret =3D max10_sys_update_bits(dev, FPGA_RECONF_REG, > + SFPGA_RP_LOAD, 0); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 reconfig register > [e:%d]\n", > + ret); > + goto end; > + } > + ret =3D max10_sys_update_bits(dev, FPGA_RECONF_REG, > + SFPGA_RP_LOAD | SFPGA_RECONF_PAGE, > + SFPGA_RP_LOAD | SFPGA_PAGE(page)); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 reconfig register > [e:%d]\n", > + ret); > + goto end; > + } > + } else { > + ret =3D max10_sys_update_bits(dev, RSU_REG, FPGA_RP_LOAD, > 0); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 rsu register > [e:%d]\n", > + ret); > + goto end; > + } > + ret =3D max10_sys_update_bits(dev, RSU_REG, > + FPGA_RP_LOAD | FPGA_RECONF_PAGE, > + FPGA_RP_LOAD | FPGA_PAGE(page)); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 rsu register > [e:%d]\n", > + ret); > + goto end; > + } > + } > + > + ret =3D max10_sys_update_bits(dev, FPGA_RECONF_REG, > COUNTDOWN_START, 0); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 reconfig register [e:%d]\n", > + ret); > + goto end; > + } > + > + ret =3D max10_sys_update_bits(dev, FPGA_RECONF_REG, > COUNTDOWN_START, > + COUNTDOWN_START); > + if (ret < 0) { > + dev_err(dev, > + "Failed to update max10 reconfig register [e:%d]\n", > + ret); > + } > +end: > + if (ret < 0) > + dev_err(dev, "Failed to reload FPGA\n"); > + > + return ret; > +} > + > +static int n3000_reload_bmc(struct intel_max10_device *dev, int page) { > + uint32_t val =3D 0; > + int ret =3D 0; > + > + dev_info(dev, "Reload BMC\n"); > + > + if (!dev || ((page !=3D 0) && (page !=3D 1))) { > + dev_err(dev, "Input parameter of %s is invalid\n", __func__); > + ret =3D -EINVAL; > + goto end; > + } > + > + if (dev->flags & MAX10_FLAGS_SECURE) { > + ret =3D max10_sys_update_bits(dev, MAX10_DOORBELL, > + CONFIG_SEL | REBOOT_REQ, > + CONFIG_SEL_S(page) | REBOOT_REQ); > + } else { > + val =3D (page =3D=3D 0) ? 0x1 : 0x3; > + ret =3D max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL1, val); > + if (ret < 0) { > + dev_err(dev, > + "Failed to write to dual config1 register > [e:%d]\n", > + ret); > + goto end; > + } > + > + ret =3D max10_reg_write(dev, IFPGA_DUAL_CFG_CTRL0, 0x1); > + if (ret < 0) { > + if (ret =3D=3D -EIO) { > + ret =3D 0; > + goto end; > + } > + dev_err(dev, > + "Failed to write to dual config0 register > [e:%d]\n", > + ret); > + } > + } > + > +end: > + if (ret < 0) > + dev_err(dev, "Failed to reload BMC\n"); > + > + return ret; > +} > + > +static int n3000_reload(struct ifpga_sec_mgr *smgr, int type, int page) > +{ > + int psel =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + > + if (type =3D=3D IFPGA_BOOT_TYPE_FPGA) { > + psel =3D (page =3D=3D IFPGA_BOOT_PAGE_FACTORY ? 0 : 1); > + ret =3D n3000_reload_fpga(smgr->max10_dev, psel); > + } else if (type =3D=3D IFPGA_BOOT_TYPE_BMC) { > + psel =3D (page =3D=3D IFPGA_BOOT_PAGE_FACTORY ? 1 : 0); > + ret =3D n3000_reload_bmc(smgr->max10_dev, psel); > + } else { > + ret =3D -EINVAL; > + } > + > + return ret; > +} > + > +static uint64_t n3000_get_hw_errinfo(struct ifpga_sec_mgr *smgr) { > + struct intel_max10_device *dev =3D NULL; > + uint32_t doorbell =3D 0; > + uint32_t stat =3D 0; > + uint32_t prog =3D 0; > + uint32_t auth_result =3D 0; > + int ret =3D 0; > + > + if (!smgr || !smgr->max10_dev) > + return -ENODEV; > + dev =3D (struct intel_max10_device *)smgr->max10_dev; > + > + ret =3D max10_sys_read(dev, MAX10_DOORBELL, &doorbell); > + if (ret < 0) { > + dev_err(dev, "Failed to read max10 doorbell register > [e:%d]\n", > + ret); > + return -1; > + } > + stat =3D SEC_STATUS_G(doorbell); > + prog =3D SEC_PROGRESS_G(doorbell); > + dev_debug(dev, "Current RSU status is %s, progress is %s\n", > + rsu_status_name(stat), rsu_progress_name(prog)); > + > + ret =3D max10_sys_read(dev, MAX10_AUTH_RESULT, &auth_result); > + if (ret < 0) { > + dev_err(dev, > + "Failed to read authenticate result register [e:%d]\n", > + ret); > + return -1; > + } > + > + return (uint64_t)doorbell << 32 | (uint64_t)auth_result; } > + > +static const struct ifpga_sec_ops n3000_sec_ops =3D { > + .prepare =3D n3000_prepare, > + .write_blk =3D n3000_write_blk, > + .write_done =3D n3000_write_done, > + .check_complete =3D n3000_check_complete, > + .reload =3D n3000_reload, > + .cancel =3D n3000_cancel, > + .cleanup =3D NULL, > + .get_hw_errinfo =3D n3000_get_hw_errinfo, }; > + > +int init_sec_mgr(struct ifpga_fme_hw *fme) { > + struct ifpga_hw *hw =3D NULL; > + opae_share_data *sd =3D NULL; > + struct ifpga_sec_mgr *smgr =3D NULL; > + > + if (!fme || !fme->max10_dev) > + return -ENODEV; > + > + smgr =3D (struct ifpga_sec_mgr *)malloc(sizeof(*smgr)); > + if (!smgr) { > + dev_err(NULL, "Failed to allocate memory for security > manager\n"); > + return -ENOMEM; > + } > + fme->sec_mgr =3D smgr; > + > + hw =3D (struct ifpga_hw *)fme->parent; > + if (hw && hw->adapter && hw->adapter->shm.ptr) { > + sd =3D (opae_share_data *)hw->adapter->shm.ptr; > + smgr->rsu_control =3D &sd->rsu_ctrl; > + smgr->rsu_status =3D &sd->rsu_stat; > + } else { > + smgr->rsu_control =3D NULL; > + smgr->rsu_status =3D NULL; > + } > + > + if ((hw->pci_data->device_id =3D=3D IFPGA_N3000_DID) && > + (hw->pci_data->vendor_id =3D=3D IFPGA_N3000_VID)) { > + smgr->ops =3D &n3000_sec_ops; > + smgr->copy_speed =3D IFPGA_N3000_COPY_SPEED; > + } else { > + dev_err(NULL, "No operation for security manager\n"); > + smgr->ops =3D NULL; > + } > + > + smgr->fme =3D fme; > + smgr->max10_dev =3D fme->max10_dev; > + > + return 0; > +} > + > +void release_sec_mgr(struct ifpga_fme_hw *fme) { > + struct ifpga_sec_mgr *smgr =3D NULL; > + > + if (fme) { > + smgr =3D (struct ifpga_sec_mgr *)fme->sec_mgr; > + if (smgr) { > + fme->sec_mgr =3D NULL; > + free(smgr); > + } > + } > +} > diff --git a/drivers/raw/ifpga/base/ifpga_sec_mgr.h > b/drivers/raw/ifpga/base/ifpga_sec_mgr.h > new file mode 100644 > index 000000000..17f38ca68 > --- /dev/null > +++ b/drivers/raw/ifpga/base/ifpga_sec_mgr.h > @@ -0,0 +1,89 @@ > +/* SPDX-License-Identifier: BSD-3-Clause > + * Copyright(c) 2020 Intel Corporation > + */ > + > +#ifndef _IFPGA_FME_RSU_H_ > +#define _IFPGA_FME_RSU_H_ > + > + > +#include "ifpga_hw.h" > + > +#define IFPGA_N3000_VID 0x8086 > +#define IFPGA_N3000_DID 0x0b30 > + > +#define IFPGA_BOOT_TYPE_FPGA 0 > +#define IFPGA_BOOT_TYPE_BMC 1 > + > +#define IFPGA_BOOT_PAGE_FACTORY 0 > +#define IFPGA_BOOT_PAGE_USER 1 > + > +#define IFPGA_RSU_DATA_BLK_SIZE 32768 > +#define IFPGA_RSU_START_RETRY 120 > +#define IFPGA_RSU_WRITE_RETRY 10 > +#define IFPGA_RSU_CANCEL_RETRY 30 > + > +#define IFPGA_N3000_COPY_SPEED 42700 > + > +/* status */ > +#define IFPGA_RSU_IDLE 0 > +#define IFPGA_RSU_PREPARE 1 > +#define IFPGA_RSU_READY 2 > +#define IFPGA_RSU_COPYING 3 > +#define IFPGA_RSU_REBOOT 4 > + > +/* control */ > +#define IFPGA_RSU_ABORT 1 > + > +#define IFPGA_DUAL_CFG_CTRL0 0x200020 > +#define IFPGA_DUAL_CFG_CTRL1 0x200024 > + > +#define IFPGA_SEC_START_INTERVAL_MS 100 > +#define IFPGA_SEC_START_TIMEOUT_MS 20000 > +#define IFPGA_NIOS_HANDSHAKE_INTERVAL_MS 100 > +#define IFPGA_NIOS_HANDSHAKE_TIMEOUT_MS 5000 > + > +#define IFPGA_RSU_ERR_HW_ERROR -1 > +#define IFPGA_RSU_ERR_TIMEOUT -2 > +#define IFPGA_RSU_ERR_CANCELED -3 > +#define IFPGA_RSU_ERR_BUSY -4 > +#define IFPGA_RSU_ERR_INVALID_SIZE -5 > +#define IFPGA_RSU_ERR_RW_ERROR -6 > +#define IFPGA_RSU_ERR_WEAROUT -7 > +#define IFPGA_RSU_ERR_FILE_READ -8 > + > +struct ifpga_sec_mgr; > + > +struct ifpga_sec_ops { > + int (*prepare)(struct ifpga_sec_mgr *smgr); > + int (*write_blk)(struct ifpga_sec_mgr *smgr, char *buf, uint32_t > offset, > + uint32_t size); > + int (*write_done)(struct ifpga_sec_mgr *smgr); > + int (*check_complete)(struct ifpga_sec_mgr *smgr); > + int (*reload)(struct ifpga_sec_mgr *smgr, int type, int page); > + int (*cancel)(struct ifpga_sec_mgr *smgr); > + void (*cleanup)(struct ifpga_sec_mgr *smgr); > + u64 (*get_hw_errinfo)(struct ifpga_sec_mgr *smgr); }; > + > +struct ifpga_sec_mgr { > + struct ifpga_fme_hw *fme; > + struct intel_max10_device *max10_dev; > + unsigned int rsu_length; > + /* number of bytes that copied from staging area to working area > + * in one second, which is calculated by experiment > + */ > + unsigned int copy_speed; > + unsigned int *rsu_control; > + unsigned int *rsu_status; > + const struct ifpga_sec_ops *ops; > +}; > + > +int init_sec_mgr(struct ifpga_fme_hw *fme); void release_sec_mgr(struct > +ifpga_fme_hw *fme); int fpga_update_flash(struct ifpga_fme_hw *fme, > +const char *image, > + uint64_t *status); > +int fpga_stop_flash_update(struct ifpga_fme_hw *fme, int force); int > +fpga_reload(struct ifpga_fme_hw *fme, int type, int page); > + > + > +#endif /* _IFPGA_FME_RSU_H_ */ > diff --git a/drivers/raw/ifpga/base/meson.build > b/drivers/raw/ifpga/base/meson.build > index da2d6e33c..3549afafa 100644 > --- a/drivers/raw/ifpga/base/meson.build > +++ b/drivers/raw/ifpga/base/meson.build > @@ -12,6 +12,8 @@ sources =3D [ > 'ifpga_port.c', > 'ifpga_port_error.c', > 'ifpga_fme_pr.c', > + 'ifpga_fme_rsu.c', > + 'ifpga_sec_mgr.c', > 'opae_hw_api.c', > 'opae_ifpga_hw_api.c', > 'opae_debug.c', > diff --git a/drivers/raw/ifpga/base/opae_hw_api.c > b/drivers/raw/ifpga/base/opae_hw_api.c > index d5cd5fe60..86ad88f72 100644 > --- a/drivers/raw/ifpga/base/opae_hw_api.c > +++ b/drivers/raw/ifpga/base/opae_hw_api.c > @@ -470,6 +470,8 @@ static void opae_adapter_shm_init(struct > opae_adapter *adapter) > opae_mutex_init(&sd->i2c_mutex); > sd->ref_cnt =3D 0; > sd->dtb_size =3D SHM_BLK_SIZE; > + sd->rsu_ctrl =3D 0; > + sd->rsu_stat =3D 0; > } >=20 > static void *opae_adapter_shm_alloc(struct opae_adapter *adapter) @@ - > 964,3 +966,60 @@ opae_mgr_get_board_info(struct opae_manager *mgr, >=20 > return -ENOENT; > } > + > +/** > + * opae_mgr_update_flash - update image in flash. > + * @mgr: targeted manager > + * @image: name of image file > + * @status: status of update > + * > + * Return: 0 on success, otherwise error code. > + */ > +int opae_mgr_update_flash(struct opae_manager *mgr, const char *image, > + uint64_t *status) > +{ > + if (!mgr) > + return -EINVAL; > + > + if (mgr->ops && mgr->ops->update_flash) > + return mgr->ops->update_flash(mgr, image, status); > + > + return -ENOENT; > +} > + > +/** > + * opae_stop_flash_update - stop flash update. > + * @mgr: targeted manager > + * @force: make sure the update process is stopped > + * > + * Return: 0 on success, otherwise error code. > + */ > +int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force) { > + if (!mgr) > + return -EINVAL; > + > + if (mgr->ops && mgr->ops->stop_flash_update) > + return mgr->ops->stop_flash_update(mgr, force); > + > + return -ENOENT; > +} > + > +/** > + * opae_mgr_reload - reload FPGA. > + * @mgr: targeted manager > + * @type: FPGA type > + * @page: reload from which page > + * > + * Return: 0 on success, otherwise error code. > + */ > +int opae_mgr_reload(struct opae_manager *mgr, int type, int page) { > + if (!mgr) > + return -EINVAL; > + > + if (mgr->ops && mgr->ops->reload) > + return mgr->ops->reload(mgr, type, page); > + > + return -ENOENT; > +} > diff --git a/drivers/raw/ifpga/base/opae_hw_api.h > b/drivers/raw/ifpga/base/opae_hw_api.h > index e99ee4564..c819dc3d2 100644 > --- a/drivers/raw/ifpga/base/opae_hw_api.h > +++ b/drivers/raw/ifpga/base/opae_hw_api.h > @@ -55,6 +55,10 @@ struct opae_manager_ops { > unsigned int *value); > int (*get_board_info)(struct opae_manager *mgr, > struct opae_board_info **info); > + int (*update_flash)(struct opae_manager *mgr, const char *image, > + u64 *status); > + int (*stop_flash_update)(struct opae_manager *mgr, int force); > + int (*reload)(struct opae_manager *mgr, int type, int page); > }; >=20 > /* networking management ops in FME */ > @@ -276,6 +280,8 @@ typedef struct { > pthread_mutex_t i2c_mutex; > u32 ref_cnt; /* reference count of shared memory > */ > u32 dtb_size; /* actual length of DTB data in byte */ > + u32 rsu_ctrl; /* used to control rsu */ > + u32 rsu_stat; /* used to report status for rsu */ > }; > }; > u8 dtb[SHM_BLK_SIZE]; /* DTB data */ > @@ -354,4 +360,9 @@ int opae_manager_eth_group_read_reg(struct > opae_manager *mgr, u8 group_id, > u8 type, u8 index, u16 addr, u32 *data); int > opae_mgr_get_board_info(struct opae_manager *mgr, > struct opae_board_info **info); > +int opae_mgr_update_flash(struct opae_manager *mgr, const char *image, > + uint64_t *status); > +int opae_mgr_stop_flash_update(struct opae_manager *mgr, int force); > +int opae_mgr_reload(struct opae_manager *mgr, int type, int page); > + > #endif /* _OPAE_HW_API_H_*/ > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.c > b/drivers/raw/ifpga/base/opae_intel_max10.c > index 1a526ea54..443e248fb 100644 > --- a/drivers/raw/ifpga/base/opae_intel_max10.c > +++ b/drivers/raw/ifpga/base/opae_intel_max10.c > @@ -51,6 +51,22 @@ int max10_sys_write(struct intel_max10_device *dev, > return max10_reg_write(dev, dev->base + offset, val); } >=20 > +int max10_sys_update_bits(struct intel_max10_device *dev, unsigned int > offset, > + unsigned int msk, unsigned int val) { > + int ret =3D 0; > + unsigned int temp =3D 0; > + > + ret =3D max10_sys_read(dev, offset, &temp); > + if (ret < 0) > + return ret; > + > + temp &=3D ~msk; > + temp |=3D val & msk; > + > + return max10_sys_write(dev, offset, temp); } > + > static struct max10_compatible_id max10_id_table[] =3D { > {.compatible =3D MAX10_PAC,}, > {.compatible =3D MAX10_PAC_N3000,}, > @@ -557,6 +573,36 @@ static int check_max10_version(struct > intel_max10_device *dev) > return -ENODEV; > } >=20 > +static int max10_staging_area_init(struct intel_max10_device *dev) { > + char *fdt_root =3D dev->fdt_root; > + int ret, offset =3D 0; > + u64 start, size; > + > + if (!fdt_root) { > + dev_debug(dev, > + "skip staging area init as not find Device Tree\n"); > + return -ENODEV; > + } > + > + dev->staging_area_size =3D 0; > + > + fdt_for_each_subnode(offset, fdt_root, 0) { > + if (fdt_node_check_compatible(fdt_root, offset, > + "ifpga-sec-mgr,staging-area")) > + continue; > + > + ret =3D fdt_get_reg(fdt_root, offset, 0, &start, &size); > + if (!ret) { > + dev->staging_area_base =3D start; > + dev->staging_area_size =3D size; > + } > + return ret; > + } > + > + return -ENODEV; > +} > + > static int > max10_secure_hw_init(struct intel_max10_device *dev) { @@ -581,6 > +627,8 @@ max10_secure_hw_init(struct intel_max10_device *dev) >=20 > max10_sensor_init(dev, sysmgr_offset); >=20 > + max10_staging_area_init(dev); > + > return 0; > } >=20 > diff --git a/drivers/raw/ifpga/base/opae_intel_max10.h > b/drivers/raw/ifpga/base/opae_intel_max10.h > index 123cdc48b..670683f01 100644 > --- a/drivers/raw/ifpga/base/opae_intel_max10.h > +++ b/drivers/raw/ifpga/base/opae_intel_max10.h > @@ -38,6 +38,8 @@ struct intel_max10_device { > unsigned int base; /* max10 base address */ > u16 bus; > struct opae_sensor_list opae_sensor_list; > + u32 staging_area_base; > + u32 staging_area_size; > }; >=20 > /* retimer speed */ > @@ -98,6 +100,7 @@ struct opae_retimer_status { > #define MAX10_MAC_COUNT GENMASK(23, 16) > #define RSU_REG 0x2c > #define FPGA_RECONF_PAGE GENMASK(2, 0) > +#define FPGA_PAGE(p) ((p) & 0x1) > #define FPGA_RP_LOAD BIT(3) > #define NIOS2_PRERESET BIT(4) > #define NIOS2_HANG BIT(5) > @@ -106,6 +109,9 @@ struct opae_retimer_status { > #define NIOS2_I2C2_POLL_STOP BIT(13) > #define PKVL_EEPROM_LOAD BIT(31) > #define FPGA_RECONF_REG 0x30 > +#define SFPGA_RECONF_PAGE GENMASK(22, 20) > +#define SFPGA_PAGE(p) (((p) & 0x1) << 20) > +#define SFPGA_RP_LOAD BIT(23) > #define MAX10_TEST_REG 0x3c > #define COUNTDOWN_START BIT(18) > #define MAX10_BUILD_VER 0x68 > @@ -118,8 +124,44 @@ struct opae_retimer_status { > #define MAX10_DOORBELL 0x400 > #define RSU_REQUEST BIT(0) > #define SEC_PROGRESS GENMASK(7, 4) > +#define SEC_PROGRESS_G(v) (((v) >> 4) & 0xf) > +#define SEC_PROGRESS_IDLE 0x0 > +#define SEC_PROGRESS_PREPARE 0x1 > +#define SEC_PROGRESS_SLEEP 0x2 > +#define SEC_PROGRESS_READY 0x3 > +#define SEC_PROGRESS_AUTHENTICATING 0x4 > +#define SEC_PROGRESS_COPYING 0x5 > +#define SEC_PROGRESS_UPDATE_CANCEL 0x6 > +#define SEC_PROGRESS_PROGRAM_KEY_HASH 0x7 > +#define SEC_PROGRESS_RSU_DONE 0x8 > +#define SEC_PROGRESS_PKVL_PROM_DONE 0x9 > #define HOST_STATUS GENMASK(11, 8) > +#define HOST_STATUS_S(v) (((v) << 8) & 0xf00) > +#define HOST_STATUS_IDLE 0x0 > +#define HOST_STATUS_WRITE_DONE 0x1 > +#define HOST_STATUS_ABORT_RSU 0x2 > #define SEC_STATUS GENMASK(23, 16) > +#define SEC_STATUS_G(v) (((v) >> 16) & 0xff) > +#define SEC_STATUS_NORMAL 0x0 > +#define SEC_STATUS_TIMEOUT 0x1 > +#define SEC_STATUS_AUTH_FAIL 0x2 > +#define SEC_STATUS_COPY_FAIL 0x3 > +#define SEC_STATUS_FATAL 0x4 > +#define SEC_STATUS_PKVL_REJECT 0x5 > +#define SEC_STATUS_NON_INC 0x6 > +#define SEC_STATUS_ERASE_FAIL 0x7 > +#define SEC_STATUS_WEAROUT 0x8 > +#define SEC_STATUS_NIOS_OK 0x80 > +#define SEC_STATUS_USER_OK 0x81 > +#define SEC_STATUS_FACTORY_OK 0x82 > +#define SEC_STATUS_USER_FAIL 0x83 > +#define SEC_STATUS_FACTORY_FAIL 0x84 > +#define SEC_STATUS_NIOS_FLASH_ERR 0x85 > +#define SEC_STATUS_FPGA_FLASH_ERR 0x86 > +#define CONFIG_SEL BIT(28) > +#define CONFIG_SEL_S(v) (((v) & 0x1) << 28) > +#define REBOOT_REQ BIT(29) > +#define MAX10_AUTH_RESULT 0x404 >=20 > /* PKVL related registers, in system register region */ > #define PKVL_POLLING_CTRL 0x80 > @@ -149,6 +191,8 @@ int max10_sys_read(struct intel_max10_device *dev, > unsigned int offset, unsigned int *val); int max10_sys_write(struct > intel_max10_device *dev, > unsigned int offset, unsigned int val); > +int max10_sys_update_bits(struct intel_max10_device *dev, > + unsigned int offset, unsigned int msk, unsigned int val); > struct intel_max10_device * > intel_max10_device_probe(struct altera_spi_device *spi, > int chipselect); > diff --git a/drivers/raw/ifpga/ifpga_rawdev.c > b/drivers/raw/ifpga/ifpga_rawdev.c > index 27129b133..660ea2051 100644 > --- a/drivers/raw/ifpga/ifpga_rawdev.c > +++ b/drivers/raw/ifpga/ifpga_rawdev.c > @@ -1737,3 +1737,58 @@ > RTE_PMD_REGISTER_PARAM_STRING(ifpga_rawdev_cfg, > "ifpga=3D " > "port=3D " > "afu_bts=3D"); > + > +int ifpga_rawdev_update_flash(struct rte_rawdev *dev, const char *image, > + uint64_t *status) > +{ > + struct opae_adapter *adapter =3D NULL; > + > + if (!dev) { > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > + return -EINVAL; > + } > + > + adapter =3D ifpga_rawdev_get_priv(dev); > + if (!adapter) { > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > + return -ENODEV; > + } > + > + return opae_mgr_update_flash(adapter->mgr, image, status); } > + > +int ifpga_rawdev_stop_flash_update(struct rte_rawdev *dev, int force) { > + struct opae_adapter *adapter =3D NULL; > + > + if (!dev) { > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > + return -EINVAL; > + } > + > + adapter =3D ifpga_rawdev_get_priv(dev); > + if (!adapter) { > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > + return -ENODEV; > + } > + > + return opae_mgr_stop_flash_update(adapter->mgr, force); } > + > +int ifpga_rawdev_reload(struct rte_rawdev *dev, int type, int page) { > + struct opae_adapter *adapter =3D NULL; > + > + if (!dev) { > + IFPGA_RAWDEV_PMD_ERR("rawdev is invalid"); > + return -EINVAL; > + } > + > + adapter =3D ifpga_rawdev_get_priv(dev); > + if (!adapter) { > + IFPGA_RAWDEV_PMD_ERR("adapter is invalid"); > + return -ENODEV; > + } > + > + return opae_mgr_reload(adapter->mgr, type, page); } > diff --git a/drivers/raw/ifpga/ifpga_rawdev.h > b/drivers/raw/ifpga/ifpga_rawdev.h > index 7754beb02..bf74a5eb3 100644 > --- a/drivers/raw/ifpga/ifpga_rawdev.h > +++ b/drivers/raw/ifpga/ifpga_rawdev.h > @@ -43,7 +43,7 @@ enum ifpga_rawdev_device_state { static inline struct > opae_adapter * ifpga_rawdev_get_priv(const struct rte_rawdev *rawdev) { > - return rawdev->dev_private; > + return (struct opae_adapter *)rawdev->dev_private; > } >=20 > #define IFPGA_RAWDEV_MSIX_IRQ_NUM 7 > @@ -76,4 +76,9 @@ int > ifpga_unregister_msix_irq(enum ifpga_irq_type type, > int vec_start, rte_intr_callback_fn handler, void *arg); >=20 > +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); > + > #endif /* _IFPGA_RAWDEV_H_ */ > -- > 2.29.2