From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from NAM11-DM6-obe.outbound.protection.outlook.com (NAM11-DM6-obe.outbound.protection.outlook.com [40.107.223.86]) by mx.groups.io with SMTP id smtpd.web10.8873.1679300077777192184 for ; Mon, 20 Mar 2023 01:14:37 -0700 Authentication-Results: mx.groups.io; dkim=pass header.i=@amd.com header.s=selector1 header.b=hYG/w1LM; spf=permerror, err=parse error for token &{10 18 %{i}._ip.%{h}._ehlo.%{d}._spf.vali.email}: invalid domain name (domain: amd.com, ip: 40.107.223.86, mailfrom: abner.chang@amd.com) ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=h9BpAsMGAq8JAYDMn0cU3MeTXu9m6PdRDNdzi6mmAXkiYiy4zaZj6+6KEzYZJr/U3vY6KzUtThd02d6zvsxK7jOiUJUDcBHVaFFfDcUA3fNYeFIS9yTUkYHw+RJ9UBVoLRwWIk41THYNKM6mRaHOfv7s5JCD2VG7Fn1MI3a/uCGeM1owb9wHm7iu5X4jELuMQ5msEDe7QN5Wb5K4ZqczT5R3dnqKd+j9YJe1FviExQjFqPR9o9ey6VB04wLiUbmC5hR//srGzXF9+PtN6Y1rf1mrybnSrCjvPvUgiQsFgPzBRs3fc51opdOTQKidDgXK2HKvDBHN/snmU+q/de+i+w== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=4sok83KEJ/vLCxLwAzf6lzo/VFtMEE4L0QrTWHgzwCE=; b=kg3zSIShcVHLMad9Z0qYXl8LBrc2MJYel+m9VAPm24JG2X3Z7vACLf53dKwr8nIhwlItoty8M32QJefjOah+NXfaHvB8AuAleolkpilib6/C1nGWmcW1um8Hcj5ixbwn5xYsFq5kWLSyJr+vX55d+mpp8nOhIaUhtjq4ckRaZhLYNiuz3XLw9etg9GChGMpl+rog4tvQmynss5DuIirRu6SUdF0SVN7rPeFqRpLL8ViY4QqcUdxJpCntTXF9SEBj/K174qfZv9A4SK+qdQXXmc6o9HuO7UupB13kbPXzyVH03PjxvYaenUO+in5v4Rq6aoHn6kqgRzx26bKLUwiP6w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=amd.com; dmarc=pass action=none header.from=amd.com; dkim=pass header.d=amd.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=amd.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=4sok83KEJ/vLCxLwAzf6lzo/VFtMEE4L0QrTWHgzwCE=; b=hYG/w1LM5PLNgG+EiBc4O8jMmo7ftSykBsU4qdWF+wV7k9OSoeZGHskDN9yz2s2zrP+Mvcew9KxaxdqzsO7Dc2IlELRIo9hI5QpOsooXuB8+FrUmvSNKZ4Hl9b0mm8FrCjqGw+NKTYmi8nHBlDKc9+T72tAbzzaanfS7rA9ZWMw= Received: from MN2PR12MB3966.namprd12.prod.outlook.com (2603:10b6:208:165::18) by CH0PR12MB5249.namprd12.prod.outlook.com (2603:10b6:610:d0::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6178.37; Mon, 20 Mar 2023 08:14:34 +0000 Received: from MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::8136:1f56:53e5:6fe]) by MN2PR12MB3966.namprd12.prod.outlook.com ([fe80::8136:1f56:53e5:6fe%3]) with mapi id 15.20.6178.037; Mon, 20 Mar 2023 08:14:34 +0000 From: "Chang, Abner" To: Nickle Wang , "devel@edk2.groups.io" CC: Igor Kulchytskyy Subject: Re: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host Interface Thread-Topic: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host Interface Thread-Index: AQHZUp2ZYNGQdwDcokG0hsNG1cusAa8DCh7AgABYgzA= Date: Mon, 20 Mar 2023 08:14:34 +0000 Message-ID: References: <20230309154055.505-1-abner.chang@amd.com> <20230309154055.505-2-abner.chang@amd.com> In-Reply-To: Accept-Language: zh-CN, en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: msip_labels: MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Enabled=true; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SetDate=2023-03-20T08:14:31Z; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Method=Standard; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_Name=General; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_SiteId=3dd8961f-e488-4e60-8e11-a82d994e183d; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ActionId=34367048-bafe-4cf8-b945-928585cdebf7; MSIP_Label_4342314e-0df4-4b58-84bf-38bed6170a0f_ContentBits=1 authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=amd.com; x-ms-publictraffictype: Email x-ms-traffictypediagnostic: MN2PR12MB3966:EE_|CH0PR12MB5249:EE_ x-ms-office365-filtering-correlation-id: 50721466-6e1e-4b1d-f3c2-08db291b23a2 x-ms-exchange-senderadcheck: 1 x-ms-exchange-antispam-relay: 0 x-microsoft-antispam: BCL:0; x-microsoft-antispam-message-info: 1zAC+Tbuk+YStx5d3W3XNcku/vE2WS9/pWIjBVw1Atun9MXIslfUiqymxIruo3btK6w1Dcz2YgwyQcnN+qT+nt1tW1ffuofkNEjZmmeQ3ZMdudz+8JxoD45YIDk87knN0dXBlBQv3qiT0ymi79ugUVgw7A60NXHKSAuwUJiaam8aW4c2FNai028uMorlJTqdW9LmQ0cfZETjO/1h3fKydLruI5/Ypldx1zfaePewfDrfq1Og3wOx3tPEPRKEs7af5PfdybU4VEqdnTi2JUsy4EEPRHuj0+O/m9EaOx64+Q6TPPE65lAm0X7cK2HCi7okkQGqFAS1QGG0fTgJl2dzazRQQyHkfb5olvbeWRZ83xAfu1HUJtsFCrcCn0qjqwTne++I3Ksv7aU914ZLChi1mStVjTBbkv98k2FySX1Aj4P+x+kiMQKma9kq7KTqv6z8+WiDWmEQyGvcKF5Eou3p6aAP6mWmK5PmNgN0b/W2ui/fAYsVSVwr5EpZgtlT/sGVEaBdU58bzrDF1c9OnRpUrPHm/R/iRMgLn7DBn3rhoCcVdRlD1HuYpz3z0qkIbPabp+Led5fhidbOqB3eIu0uPqgq6aDPtJ5LPtR6kchJ4rEPeMAENWlKM23JGzxdQt6NxNz7vASTUVTPj4ZLJsjdFk1zVmJp6oahhZTp0Qey/zZdq2T7k5G+dw2P5vmyc26O8RzNZALnMxwrM6X6q2F1LA== x-forefront-antispam-report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:MN2PR12MB3966.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230025)(4636009)(396003)(136003)(39860400002)(376002)(346002)(366004)(451199018)(52536014)(5660300002)(30864003)(8936002)(41300700001)(55016003)(86362001)(38070700005)(33656002)(38100700002)(2906002)(4326008)(122000001)(83380400001)(478600001)(71200400001)(7696005)(53546011)(26005)(9686003)(186003)(6506007)(110136005)(316002)(64756008)(76116006)(66476007)(66556008)(66446008)(66946007)(8676002)(559001)(579004);DIR:OUT;SFP:1101; x-ms-exchange-antispam-messagedata-chunkcount: 1 x-ms-exchange-antispam-messagedata-0: =?us-ascii?Q?c/rlHsc26btQf6xGR378vyCN1oVb0HGFGsiIHoDjlrYWA+CC8VbTtI1bUHi0?= =?us-ascii?Q?BA8+e4jCjMT9Veaf01rWkDiViST0hsM3yZBP5AcuRISYdPL90uWqZhuW5x/0?= =?us-ascii?Q?WioFvNcL84XI2HBqjUf05RgtgGKEFST3DT/NUw0TOPXwwjf5q818J7ehIEz6?= =?us-ascii?Q?tW4QGYuXPZa7eyvKRzG7i51cusufb2JbPwKiW18jcv77wN2utD7E5Aaxcpgm?= =?us-ascii?Q?wmub2wnj1xwzLFc+N/kO/h3pkRUNcc+1IWVGkjnEH9AL88fqizihH4wYQXrE?= =?us-ascii?Q?5yLHhYsnhLC5xJknqu+bPbVfOsRcd91Fud5KXEAEijjZIsiNZOQyW9p/kKGl?= =?us-ascii?Q?Kq8stuqSCIFVfL9iGLfa1cYRzQBH9cJGCSUkaUV0r23+83i7Nf/fqauQ3xzN?= =?us-ascii?Q?xC7yeukbpTq8JKjdKj/6qx6ICmVa9RO+r2PdHtUTyYj/jtfoHuVcrm86Fp1E?= =?us-ascii?Q?QPD2AiVk8PvgDJzF4pVSyohKlCxPezKHbUdT5m1dfNdokPVXcz9Vd49DnoMw?= =?us-ascii?Q?IovjSxlxD4NWNLa9UMiE6Pgf4ThcNNVlpoyndNriPoQewc1+yzlnLCU2NJfE?= =?us-ascii?Q?lby8hHT1Gf1vYG/jIEyYdXzr6+zHzrMCPa5YBujmDjWDYYFRM+/tjHB9iYby?= =?us-ascii?Q?nlLCgvtawFg5J/0du6Lfw4NonURvqcPdbybkcQrnYA1RtRwECLQRi4RNOQuc?= =?us-ascii?Q?X69tFtulhRXUkS8yBGs/g4UNiOwCH6QjUs8of6nJ34+5UDmhyZSZPYIKLvFu?= =?us-ascii?Q?8dnj3UM9bCHYN+RpScsjyDVNScV1Tnh/YB9eQXZzyOOEg1jDBf+ZKHGI8XNK?= =?us-ascii?Q?flmPF7RbRsAmd9sxZe4d1ahzYkWipxwYKXe814/0FwKzoWdng4+AZqYz+5wx?= =?us-ascii?Q?TZ5VgSClShV6lGV8jvHj5Kvgeu1+O1vKFl9rDaW5aZ4gK7tsgRanIvGVBjUq?= =?us-ascii?Q?DYFKMh03mGkdHdSnpmdRwPZ17zBbE48jN5m53PbjlySvkr9KKPJh3T9T1FHU?= =?us-ascii?Q?N9uvnQrheyqSUWTHC8dhDUdQcukqYAuJyiEU7x4PryCa/7bXcrDu/7EoiBHk?= =?us-ascii?Q?ayVZ/C6DW3SNpiF+kO06oyhHmcEC9s7C4ACXPlwvNOsD3lk3f0E0LucOvHhy?= =?us-ascii?Q?86O/ZX7zyJKUy1+lFqFWm5qSVOOiZk3EHAii9SU+OHLrBI8xVNeBCQH5JCcU?= =?us-ascii?Q?+s7Y8zDvnfErQ89ajfa7TAbO2Sy0iWnikuH9sb7PlAFL1b0VlbQm3oURFpF+?= =?us-ascii?Q?+g4ahXw8vTy0r6enPg01N2Cgefc0h4F9t5FUhnP/rHDhmDyufYBKFYXC7MGI?= =?us-ascii?Q?5+WzB/C7J+WMwPAeIQ7Wg3eiQlSSM8F+De98BlHQ19rworsx9Ve7gG684oQB?= =?us-ascii?Q?t614MBWdjSfHmXfahNJU7dKq9PRvuqWe0U1iCvHVd/W4QMvMhpupDpUaAzLw?= =?us-ascii?Q?JcfZ/DSoRzYZMMD+NvhakPfC5EjibGQ8g5mTT+hpOCJ8kPb5NzeH0dja13O8?= =?us-ascii?Q?i6D4JDDJrBxltDm7wGz4IZtbWAaFtMRqv9iKjeVDZOcjYC8J1zXTlLab2FjS?= =?us-ascii?Q?G/QFymiiLeWK8eMK8bUv662rBn5OBtns0vtFHxq0?= MIME-Version: 1.0 X-OriginatorOrg: amd.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-AuthSource: MN2PR12MB3966.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-Network-Message-Id: 50721466-6e1e-4b1d-f3c2-08db291b23a2 X-MS-Exchange-CrossTenant-originalarrivaltime: 20 Mar 2023 08:14:34.1482 (UTC) X-MS-Exchange-CrossTenant-fromentityheader: Hosted X-MS-Exchange-CrossTenant-id: 3dd8961f-e488-4e60-8e11-a82d994e183d X-MS-Exchange-CrossTenant-mailboxtype: HOSTED X-MS-Exchange-CrossTenant-userprincipalname: 9GmnSFZm3FT9gzG2/YRmy/qKMU+Hq6twYjnhJfYeoVvlKMPFF3piJtReytx2WnSOIfAUT1nwLOrvddy9TyX6dw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH0PR12MB5249 Content-Language: en-US Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable [AMD Official Use Only - General] Hi Nickle, Thanks for those good comments. V2 patch was just sent! Abner > -----Original Message----- > From: Nickle Wang > Sent: Monday, March 20, 2023 11:13 AM > To: Chang, Abner ; devel@edk2.groups.io > Cc: Igor Kulchytskyy > Subject: RE: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host > Interface >=20 > Caution: This message originated from an External Source. Use proper > caution when opening attachments, clicking links, or responding. >=20 >=20 > Please find my comment inline below, thanks! >=20 > Regards, > Nickle >=20 > -----Original Message----- > From: abner.chang@amd.com > Sent: Thursday, March 9, 2023 11:41 PM > To: devel@edk2.groups.io > Cc: Nickle Wang ; Igor Kulchytskyy > Subject: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host Interfac= e >=20 > External email: Use caution opening links or attachments >=20 >=20 > From: Abner Chang >=20 > BMC exposed USB NIC platform Redfish Host Interface library > implementation. >=20 > Signed-off-by: Abner Chang > Cc: Nickle Wang > Cc: Igor Kulchytskyy > --- > RedfishPkg/RedfishPkg.dec | 10 + > .../PlatformHostInterfaceBmcUsbNicLib.inf | 48 + > RedfishPkg/Include/Library/RedfishDebugLib.h | 3 +- > .../PlatformHostInterfaceBmcUsbNicLib.h | 84 ++ > .../PlatformHostInterfaceBmcUsbNicLib.c | 1280 +++++++++++++++++ > 5 files changed, 1424 insertions(+), 1 deletion(-) create mode 100644 > RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterf > aceBmcUsbNicLib.inf > create mode 100644 > RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterf > aceBmcUsbNicLib.h > create mode 100644 > RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInterf > aceBmcUsbNicLib.c >=20 > diff --git a/RedfishPkg/RedfishPkg.dec b/RedfishPkg/RedfishPkg.dec index > 53e52c2b008..251aa5e2b76 100644 > --- a/RedfishPkg/RedfishPkg.dec > +++ b/RedfishPkg/RedfishPkg.dec > @@ -113,3 +113,13 @@ > # Default is set to not add. > # >=20 > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishRestExAddingExpect|FALSE|BOO > LEAN|0x00001004 > + # > + # Use PCD to declare the Redfish host nmae becasue there is no # > + specification for that. > + # > + > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName|""|VOID*|0x0000100 > 5 > + # > + # Use PCD to declare the Redfish service UUID becasue there is no # > + specification for that. > + # > + > + > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishServiceUuid|L""|VOID*|0x00001 > 00 > + 6 >=20 > Would it be good to provide dummy string for above PCDs? For example: >=20 > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName|"edk2_redfishpkg"|V > OID*|0x00001005 > gEfiRedfishPkgTokenSpaceGuid.PcdRedfishServiceUuid|L"0000000000000000 > "|VOID*|0x0000100 >=20 > diff --git > a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.inf > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.inf > new file mode 100644 > index 00000000000..f2c7d7fec89 > --- /dev/null > +++ > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostI > +++ nterfaceBmcUsbNicLib.inf > @@ -0,0 +1,48 @@ > +## @file > +# Module to provide the platform Redfish Host Interface information # > +of USB NIC Device exposed by BMC. > +# > +# Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. > +# > +# SPDX-License-Identifier: BSD-2-Clause-Patent # ## > + > +[Defines] > + INF_VERSION =3D 0x0001000b > + BASE_NAME =3D PlatformHostInterfaceBmcUsbNicLib > + FILE_GUID =3D C4837B58-225E-4352-8FDC-4C52A5D6589= 1 > + MODULE_TYPE =3D DXE_DRIVER > + VERSION_STRING =3D 1.0 > + LIBRARY_CLASS =3D PlatformHostInterfaceBmcUsbNicLib > + > +[Sources] > + PlatformHostInterfaceBmcUsbNicLib.c > + PlatformHostInterfaceBmcUsbNicLib.h > + > +[Packages] > + MdePkg/MdePkg.dec > + MdeModulePkg/MdeModulePkg.dec > + NetworkPkg/NetworkPkg.dec > + RedfishPkg/RedfishPkg.dec > + > +[LibraryClasses] > + BaseMemoryLib > + DebugLib > + IpmiLib > + IpmiCommandLib > + MemoryAllocationLib > + UefiLib > + UefiBootServicesTableLib > + > +[Protocols] > + gEfiSimpleNetworkProtocolGuid ## CONSUMED > + gEfiUsbIoProtocolGuid ## CONSUMED > + gEfiDevicePathProtocolGuid ## CONSUMED > + > +[Pcd] > + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName ## CONSUMED > + gEfiRedfishPkgTokenSpaceGuid.PcdRedfishServiceUuid ## CONSUMED > + > +[Depex] > + gIpmiProtocolGuid > diff --git a/RedfishPkg/Include/Library/RedfishDebugLib.h > b/RedfishPkg/Include/Library/RedfishDebugLib.h > index 21f01353ede..913f2b2f358 100644 > --- a/RedfishPkg/Include/Library/RedfishDebugLib.h > +++ b/RedfishPkg/Include/Library/RedfishDebugLib.h > @@ -14,7 +14,8 @@ > #include > #include >=20 > -#define DEBUG_REDFISH_NETWORK DEBUG_INFO ///< Debug error level > for Redfish networking function > +#define DEBUG_REDFISH_NETWORK DEBUG_INFO ///< Debug error > level for Redfish networking function > +#define DEBUG_REDFISH_HOST_INTERFACE DEBUG_INFO ///< Debug > error level for Redfish networking function >=20 > /** >=20 > diff --git > a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.h > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.h > new file mode 100644 > index 00000000000..669c304fc3d > --- /dev/null > +++ > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostI > +++ nterfaceBmcUsbNicLib.h > @@ -0,0 +1,84 @@ > +/** @file > + Header file to provide the platform Redfish Host Interface > +information > + of USB NIC Device exposed by BMC. > + > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#ifndef PLATFORM_HOST_INTERFACE_BMC_USB_NIC_LIB_H_ > +#define PLATFORM_HOST_INTERFACE_BMC_USB_NIC_LIB_H_ > + > +#include > +#include > +#include #include > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include #include > + > +#include > +#include > + > +#include > +#include > + > +#define BMC_USB_NIC_HOST_INTERFASCE_READINESS_GUID \ > + { \ > + 0xDD96F5D7, 0x4AE1, 0x4E6C, {0xA1, 0x30, 0xA5, 0xAC, 0x77, 0xDD, 0= xE4, > 0xA5} \ > + } > + > +// > +// This is the structure for BMC exposed // USB NIC information. > +// > +typedef struct { > + LIST_ENTRY NextInstance; ///< Link to= the next instance. > + BOOLEAN IsExposedByBmc; ///< Flag in= dicates this USB > NIC is > + ///< exposed= by BMC. > + BOOLEAN IsSuppportedHostInterface; ///< This BM= C USB NIC is > supported > + ///< as Redf= ish host interface > + EFI_SIMPLE_NETWORK_PROTOCOL *ThisSnp; ///< The SNP > instance associated with > + ///< this US= B NIC. > + EFI_USB_IO_PROTOCOL *ThisUsbIo; ///< The USB= IO instance > associated with > + ///< this US= B NIC. > + UINT16 UsbVendorId; ///< USB Ven= dor ID of this BMC > exposed USB NIC. > + UINT16 UsbProductId; ///< USB Pro= duct ID of this BMC > exposed USB NIC. > + UINTN MacAddressSize; ///< HW addr= ess size. > + UINT8 *MacAddress; ///< HW addr= ess. > + UINT8 IpmiLanChannelNumber; ///< BMC IPM= I Lan Channel > number. > + > + // > + // Below is the infortmation for building SMBIOS type 42. > + // > + UINT8 IpAssignedType; ///< Redfish s= ervice IP assign type. > + UINT8 IpAddressFormat; ///< Redfish s= ervice IP version. > + UINT8 HostIpAddressIpv4[4]; ///< Host IP a= ddress. > + UINT8 RedfishIpAddressIpv4[4]; ///< Redfish s= ervice IP > address. > + UINT8 SubnetMaskIpv4[4]; ///< Subnet ma= sk. > + UINT8 GatewayIpv4[4]; ///< Gateway I= P address. > + UINT16 VLanId; ///< VLAN ID. > + BOOLEAN CredentialBootstrapping; ///< If Creden= tial > bootstrapping is > + ///< supported= . > +} HOST_INTERFACE_BMC_USB_NIC_INFO; > + > +// > +// This is the structure for caching > +// BMC IPMI LAN Channel > +// > +typedef struct { > + LIST_ENTRY NextInstance; ///< Link to the next IPMI= LAN > Channel. > + UINT8 Channel; ///< IPMI Channel number. > + EFI_MAC_ADDRESS MacAddress; ///< IPMI LAN Channel MAC > address. > + UINT8 MacAddressSize; ///< MAC address size; > +} BMC_IPMI_LAN_CHANNEL_INFO; > +#endif > diff --git > a/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.c > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostInte > rfaceBmcUsbNicLib.c > new file mode 100644 > index 00000000000..1c530b692e8 > --- /dev/null > +++ > b/RedfishPkg/Library/PlatformHostInterfaceBmcUsbNicLib/PlatformHostI > +++ nterfaceBmcUsbNicLib.c > @@ -0,0 +1,1280 @@ > +/** @file > + Source file to provide the platform Redfish Host Interface > +information > + of USB NIC Device exposed by BMC. > + > + Copyright (C) 2023 Advanced Micro Devices, Inc. All rights reserved. > + > + SPDX-License-Identifier: BSD-2-Clause-Patent > + > +**/ > + > +#include "PlatformHostInterfaceBmcUsbNicLib.h" > + > +static EFI_GUID mPlatformHostInterfaceBmcUsbNicReadinessGuid =3D > + BMC_USB_NIC_HOST_INTERFASCE_READINESS_GUID; > +static EFI_EVENT mPlatformHostInterfaceSnpEvent =3D NULL; > +static VOID *mPlatformHostInterfaceSnpRegistration =3D NULL; > + > +static LIST_ENTRY mBmcUsbNic; > +static LIST_ENTRY mBmcIpmiLan; > + > +/** > + Probe if the system supports Redfish Host Interface Credentail > + Bootstrapping. > + > + @retval TRUE Yes, it is supported. > + TRUE No, it is not supported. > + > +**/ > +BOOLEAN > +ProbeRedfishCredentialBootstrap ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + IPMI_BOOTSTRAP_CREDENTIALS_COMMAND_DATA CommandData; > + IPMI_BOOTSTRAP_CREDENTIALS_RESULT_RESPONSE ResponseData; > + UINT32 ResponseSize; > + BOOLEAN ReturnBool; > + > + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); > + > + // > + // IPMI callout to NetFn 2C, command 02 > + // Request data: > + // Byte 1: REDFISH_IPMI_GROUP_EXTENSION > + // Byte 2: DisableBootstrapControl > + // > + CommandData.GroupExtensionId =3D > REDFISH_IPMI_GROUP_EXTENSION; > + CommandData.DisableBootstrapControl =3D > REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE; > + ResponseData.CompletionCode =3D IPMI_COMP_CODE_UNSPECIFIED; > + ResponseSize =3D sizeof (ResponseData); > + // > + // Response data: Ignored. > + // > + Status =3D IpmiSubmitCommand ( > + IPMI_NETFN_GROUP_EXT, > + REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD, > + (UINT8 *)&CommandData, > + sizeof (CommandData), > + (UINT8 *)&ResponseData, > + &ResponseSize > + ); > + if (!EFI_ERROR (Status) && > + ((ResponseData.CompletionCode =3D=3D IPMI_COMP_CODE_NORMAL) || > + (ResponseData.CompletionCode =3D=3D > REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED) > + )) > + { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credentail > Bootstrapping is supported\n", __FUNCTION__)); > + ReturnBool =3D TRUE; > + } else { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credentail > Bootstrapping is not supported\n", __FUNCTION__)); > + ReturnBool =3D FALSE; > + } > + > + return ReturnBool; > +} > + > +/** > + Get platform Redfish host interface device descriptor. > + > + @param[in] DeviceType Pointer to retrieve device type. > + @param[out] DeviceDescriptor Pointer to retrieve > REDFISH_INTERFACE_DATA, caller has to free > + this memory using FreePool(). > + > + @retval EFI_NOT_FOUND No Redfish host interface descriptor provided > on this platform. > + > +**/ > +EFI_STATUS > +RedfishPlatformHostInterfaceDeviceDescriptor ( > + IN UINT8 *DeviceType, > + OUT REDFISH_INTERFACE_DATA **DeviceDescriptor > + ) > +{ > + HOST_INTERFACE_BMC_USB_NIC_INFO *ThisInstance; > + REDFISH_INTERFACE_DATA *InterfaceData; > + > + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); > + > + if (IsListEmpty (&mBmcUsbNic)) { > + return EFI_NOT_FOUND; > + } > + > + // Check if BMC exposed USB NIC is found and ready for using. > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode > + (&mBmcUsbNic); while (TRUE) { > + if (ThisInstance->IsExposedByBmc && ThisInstance- > >IsSuppportedHostInterface) { > + *DeviceType =3D REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2; > + > + // Fill up REDFISH_INTERFACE_DATA defined in Redfish host interfac= e > spec v1.3 > + InterfaceData =3D (REDFISH_INTERFACE_DATA *)AllocateZeroPool > (USB_INTERFACE_DEVICE_DESCRIPTOR_V2_SIZE_1_3); > + if (InterfaceData =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, "Failed to allocate memory for > REDFISH_INTERFACE_DATA\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + InterfaceData->DeviceType =3D > REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2; > + InterfaceData->DeviceDescriptor.UsbDeviceV2.Length =3D > USB_INTERFACE_DEVICE_DESCRIPTOR_V2_SIZE_1_3; > + InterfaceData->DeviceDescriptor.UsbDeviceV2.IdVendor =3D > ThisInstance->UsbVendorId; > + InterfaceData->DeviceDescriptor.UsbDeviceV2.IdProduct =3D > ThisInstance->UsbProductId; > + InterfaceData->DeviceDescriptor.UsbDeviceV2.SerialNumberStr =3D 0; > + CopyMem ( > + (VOID *)&InterfaceData->DeviceDescriptor.UsbDeviceV2.MacAddress, > + (VOID *)&ThisInstance->MacAddress, > + sizeof (InterfaceData->DeviceDescriptor.UsbDeviceV2.MacAddress) > + ); > + InterfaceData->DeviceDescriptor.UsbDeviceV2.Characteristics = |=3D > (UINT16)ThisInstance->CredentialBootstrapping; > + InterfaceData- > >DeviceDescriptor.UsbDeviceV2.CredentialBootstrappingHandle =3D 0; > + *DeviceDescriptor = =3D InterfaceData; > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " > REDFISH_INTERFACE_DATA is returned successfully.\n")); > + return EFI_SUCCESS; > + } > + > + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) { > + break; > + } > + > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *) > + GetNextNode (&mBmcUsbNic, > + &ThisInstance->NextInstance); } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + Get platform Redfish host interface protocol data. > + Caller should pass NULL in ProtocolRecord to retrive the first protoco= l > record. > + Then continuously pass previous ProtocolRecord for retrieving the next > ProtocolRecord. > + > + @param[in, out] ProtocolRecord Pointer to retrieve the first or the n= ext > protocol record. > + caller has to free the new protocol re= cord returned from > + this function using FreePool(). > + @param[in] IndexOfProtocolData The index of protocol data. > + > + @retval EFI_NOT_FOUND No more protocol records. > + > +**/ > +EFI_STATUS > +RedfishPlatformHostInterfaceProtocolData ( > + IN OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord, > + IN UINT8 IndexOfProtocolData > + ) > +{ > + HOST_INTERFACE_BMC_USB_NIC_INFO *ThisInstance; > + MC_HOST_INTERFACE_PROTOCOL_RECORD *ThisProtocolRecord; > + REDFISH_OVER_IP_PROTOCOL_DATA *RedfishOverIpData; > + UINT8 HostNameLength; > + CHAR8 *HostNameString; > + > + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); > + > + if (IsListEmpty (&mBmcUsbNic) || (IndexOfProtocolData > 0)) { > + return EFI_NOT_FOUND; > + } > + > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode > + (&mBmcUsbNic); while (TRUE) { > + if (ThisInstance->IsExposedByBmc && ThisInstance- > >IsSuppportedHostInterface) { > + // Get the host name before allocating memory. > + HostNameString =3D (CHAR8 *)PcdGetPtr (PcdRedfishHostName); > + HostNameLength =3D (UINT8)AsciiStrSize (HostNameString); > + ThisProtocolRecord =3D (MC_HOST_INTERFACE_PROTOCOL_RECORD > *)AllocateZeroPool ( > + sizeof > (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1 + > + sizeof > (REDFISH_OVER_IP_PROTOCOL_DATA) + > + HostNa= meLength > + ); > + if (ThisProtocolRecord =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Aloocate memory fail for > MC_HOST_INTERFACE_PROTOCOL_RECORD.\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + ThisProtocolRecord->ProtocolType =3D > MCHostInterfaceProtocolTypeRedfishOverIP; > + ThisProtocolRecord->ProtocolTypeDataLen =3D sizeof > (REDFISH_OVER_IP_PROTOCOL_DATA) + HostNameLength; > + RedfishOverIpData =3D (REDFISH_OVER_IP_PROTO= COL_DATA > *)&ThisProtocolRecord->ProtocolTypeData[0]; > + // > + // Fill up REDFISH_OVER_IP_PROTOCOL_DATA > + // > + > + // Service UUID > + ZeroMem ((VOID *)&RedfishOverIpData->ServiceUuid, sizeof > (EFI_GUID)); > + if (StrLen ((CONST CHAR16 *)PcdGetPtr (PcdRedfishServiceUuid)) != =3D 0) { > + StrToGuid ((CONST CHAR16 *)PcdGetPtr (PcdRedfishServiceUuid), > &RedfishOverIpData->ServiceUuid); > + } > + > + // HostIpAddressFormat and RedfishServiceIpDiscoveryType > + RedfishOverIpData->HostIpAssignmentType =3D > RedfishHostIpAssignmentUnknown; > + RedfishOverIpData->RedfishServiceIpDiscoveryType =3D > RedfishHostIpAssignmentUnknown; > + if (ThisInstance->IpAssignedType =3D=3D IpmiStaticAddrsss) { > + RedfishOverIpData->HostIpAssignmentType =3D > RedfishHostIpAssignmentStatic; > + RedfishOverIpData->RedfishServiceIpDiscoveryType =3D > RedfishHostIpAssignmentStatic; > + } else if (ThisInstance->IpAssignedType =3D=3D > IpmiDynamicAddressBmcDhcp) { > + RedfishOverIpData->HostIpAssignmentType =3D > RedfishHostIpAssignmentDhcp; > + RedfishOverIpData->RedfishServiceIpDiscoveryType =3D > RedfishHostIpAssignmentDhcp; > + } > + > + // HostIpAddressFormat and RedfishServiceIpAddressFormat, only > support IPv4 for now. > + RedfishOverIpData->HostIpAddressFormat =3D > REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4; > + RedfishOverIpData->RedfishServiceIpAddressFormat =3D > + REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4; > + > + // HostIpAddress > + CopyMem ( > + (VOID *)RedfishOverIpData->HostIpAddress, > + (VOID *)ThisInstance->HostIpAddressIpv4, > + sizeof (ThisInstance->HostIpAddressIpv4) > + ); > + > + // HostIpMask and RedfishServiceIpMask > + CopyMem ( > + (VOID *)RedfishOverIpData->HostIpMask, > + (VOID *)ThisInstance->SubnetMaskIpv4, > + sizeof (ThisInstance->SubnetMaskIpv4) > + ); > + CopyMem ( > + (VOID *)RedfishOverIpData->RedfishServiceIpMask, > + (VOID *)ThisInstance->SubnetMaskIpv4, > + sizeof (ThisInstance->SubnetMaskIpv4) > + ); > + > + // RedfishServiceIpAddress > + CopyMem ( > + (VOID *)RedfishOverIpData->RedfishServiceIpAddress, > + (VOID *)ThisInstance->RedfishIpAddressIpv4, > + sizeof (ThisInstance->RedfishIpAddressIpv4) > + ); > + > + // RedfishServiceIpPort > + RedfishOverIpData->RedfishServiceIpPort =3D 0; > + > + // RedfishServiceVlanId > + RedfishOverIpData->RedfishServiceVlanId =3D ThisInstance->VLanId; > + > + // RedfishServiceHostnameLength > + RedfishOverIpData->RedfishServiceHostnameLength =3D > HostNameLength; > + > + // Redfish host name. > + CopyMem ( > + (VOID *)&RedfishOverIpData->RedfishServiceHostname, > + (VOID *)HostNameString, > + HostNameLength > + ); > + > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " > MC_HOST_INTERFACE_PROTOCOL_RECORD is returned successfully.\n")); > + *ProtocolRecord =3D ThisProtocolRecord; > + return EFI_SUCCESS; > + } > + > + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) { > + break; > + } > + > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *) > + GetNextNode (&mBmcUsbNic, > + &ThisInstance->NextInstance); } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + This function retrieve the information of BMC USB NIC. > + > + @retval EFI_SUCCESS All necessary information is retrieved. > + @retval EFI_NOT_FOUND There is no BMC exposed USB NIC. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +RetrievedBmcUsbNicInfo ( > + VOID > + ) > +{ > + EFI_STATUS Status; > + UINT32 ResponseDataSize; > + HOST_INTERFACE_BMC_USB_NIC_INFO *ThisInstance; > + IPMI_GET_LAN_CONFIGURATION_PARAMETERS_REQUEST > GetLanConfigReq; > + IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *GetLanConfigReps; > + IPMI_LAN_IP_ADDRESS_SRC *IpAddressSrc; > + IPMI_LAN_IP_ADDRESS *DestIpAddress; > + IPMI_LAN_SUBNET_MASK *SubnetMask; > + IPMI_LAN_DEFAULT_GATEWAY *DefaultGateway; > + IPMI_LAN_VLAN_ID *LanVlanId; > + EFI_USB_DEVICE_DESCRIPTOR UsbDeviceDescriptor; > + > + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); > + > + if (IsListEmpty (&mBmcUsbNic)) { > + return EFI_NOT_FOUND; > + } > + > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode > + (&mBmcUsbNic); while (TRUE) { > + if (ThisInstance->IsExposedByBmc) { > + ThisInstance->IsSuppportedHostInterface =3D FALSE; > + > + // Probe if Redfish Host Interface Credential Bootstrapping is sup= ported. > + ThisInstance->CredentialBootstrapping =3D > + ProbeRedfishCredentialBootstrap (); > + > + // Get IP address source > + GetLanConfigReq.SetSelector =3D 0; > + GetLanConfigReq.BlockSelector =3D 0; > + GetLanConfigReq.ChannelNumber.Bits.ChannelNo =3D ThisInstance- > >IpmiLanChannelNumber; > + GetLanConfigReq.ChannelNumber.Bits.GetParameter =3D 0; > + GetLanConfigReq.ChannelNumber.Bits.Reserved =3D 0; > + GetLanConfigReq.ParameterSelector =3D IpmiLanIpAddre= ssSource; > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof > (IPMI_LAN_IP_ADDRESS_SRC); > + GetLanConfigReps =3D > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConf= igurationParameters ( > + &GetLanConfigR= eq, > + GetLanConfigRe= ps, > + &ResponseDataS= ize > + ); > + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG ((DEBUG_ERROR, " Failed to get IP address source at cha= nnel > %d: %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status, > GetLanConfigReps->CompletionCode)); > + FreePool (GetLanConfigReps); > + return Status; > + } > + > + IpAddressSrc =3D (IPMI_LAN_IP_ADDRESS_SRC *)(GetLanConfigReps + 1)= ; > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " IP address source at > channel %d: %x\n", ThisInstance->IpmiLanChannelNumber, IpAddressSrc- > >Bits.AddressSrc)); > + ThisInstance->IpAssignedType =3D IpAddressSrc->Bits.AddressSrc; > + FreePool (GetLanConfigReps); > + > + // Get LAN IPv4 IP address > + GetLanConfigReq.ParameterSelector =3D IpmiLanIpAddress; > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof > (IPMI_LAN_IP_ADDRESS); > + GetLanConfigReps =3D > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConfigurationParam= eters ( > + &GetLanConfigReq, > + GetLanConfigReps, > + &ResponseDataSize > + ); > + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG ((DEBUG_ERROR, " Failed to get Dest IP address at chann= el %d: > %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status, > GetLanConfigReps->CompletionCode)); > + FreePool (GetLanConfigReps); > + return Status; > + } > + > + DestIpAddress =3D (IPMI_LAN_IP_ADDRESS *)(GetLanConfigReps + 1); > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " Dest IP address at channel %d: %d.%d.%d.%d\n", > + ThisInstance->IpmiLanChannelNumber, > + DestIpAddress->IpAddress[0], > + DestIpAddress->IpAddress[1], > + DestIpAddress->IpAddress[2], > + DestIpAddress->IpAddress[3] > + )); > + CopyMem ((VOID *)&ThisInstance->RedfishIpAddressIpv4, (VOID > *)&DestIpAddress->IpAddress, sizeof (DestIpAddress->IpAddress)); > + // > + // According to UEFI spec, the IP address at BMC USB NIC host end = is the > IP address at BMC end minus 1. > + // > + CopyMem ((VOID *)&ThisInstance->HostIpAddressIpv4, (VOID > *)&DestIpAddress->IpAddress, sizeof (DestIpAddress->IpAddress)); > + ThisInstance->HostIpAddressIpv4[sizeof (ThisInstance- > >HostIpAddressIpv4) - 1] -=3D 1; > + FreePool (GetLanConfigReps); > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " Host IP address at channel %d: %d.%d.%d.%d\n", > + ThisInstance->IpmiLanChannelNumber, > + ThisInstance->HostIpAddressIpv4[0], > + ThisInstance->HostIpAddressIpv4[1], > + ThisInstance->HostIpAddressIpv4[2], > + ThisInstance->HostIpAddressIpv4[3] > + )); > + > + // Get IPv4 subnet mask > + GetLanConfigReq.ParameterSelector =3D IpmiLanSubnetMask; > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof > (IPMI_LAN_SUBNET_MASK); > + GetLanConfigReps =3D > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConfigurationParam= eters ( > + &GetLanConfigReq, > + GetLanConfigReps, > + &ResponseDataSize > + ); > + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG ((DEBUG_ERROR, " Failed to get subnet mask at channel %= d: > %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status, > GetLanConfigReps->CompletionCode)); > + FreePool (GetLanConfigReps); > + return Status; > + } > + > + SubnetMask =3D (IPMI_LAN_SUBNET_MASK *)(GetLanConfigReps + 1); > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " Subnet mask at channel %d: %d.%d.%d.%d\n", > + ThisInstance->IpmiLanChannelNumber, > + SubnetMask->IpAddress[0], > + SubnetMask->IpAddress[1], > + SubnetMask->IpAddress[2], > + SubnetMask->IpAddress[3] > + )); > + CopyMem ((VOID *)&ThisInstance->SubnetMaskIpv4, (VOID > *)&SubnetMask->IpAddress, sizeof (SubnetMask->IpAddress)); > + FreePool (GetLanConfigReps); > + > + // Get Gateway IP address. > + GetLanConfigReq.ParameterSelector =3D IpmiLanDefaultGateway; > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof > (IPMI_LAN_DEFAULT_GATEWAY); > + GetLanConfigReps =3D > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConfigurationParam= eters ( > + &GetLanConfigReq, > + GetLanConfigReps, > + &ResponseDataSize > + ); > + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG ((DEBUG_ERROR, " Failed to get default gateway at chann= el > %d: %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status, > GetLanConfigReps->CompletionCode)); > + FreePool (GetLanConfigReps); > + return Status; > + } > + > + DefaultGateway =3D (IPMI_LAN_DEFAULT_GATEWAY > *)(GetLanConfigReps + 1); > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " Gateway at channel %d: %d.%d.%d.%d\n", > + ThisInstance->IpmiLanChannelNumber, > + DefaultGateway->IpAddress[0], > + DefaultGateway->IpAddress[1], > + DefaultGateway->IpAddress[2], > + DefaultGateway->IpAddress[3] > + )); > + CopyMem ((VOID *)&ThisInstance->GatewayIpv4, (VOID > *)&DefaultGateway->IpAddress, sizeof (DefaultGateway->IpAddress)); > + FreePool (GetLanConfigReps); > + > + // Get VLAN ID > + GetLanConfigReq.ParameterSelector =3D IpmiLanVlanId; > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof > (IPMI_LAN_VLAN_ID); > + GetLanConfigReps =3D > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConfigurationParam= eters ( > + &GetLanConfigReq, > + GetLanConfigReps, > + &ResponseDataSize > + ); > + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG ((DEBUG_ERROR, " Failed to get VLAN ID at channel %d: %= r, > 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status, > GetLanConfigReps->CompletionCode)); > + FreePool (GetLanConfigReps); > + return Status; > + } > + > + LanVlanId =3D (IPMI_LAN_VLAN_ID *)(GetLanConfigReps + 1= ); > + ThisInstance->VLanId =3D 0; > + if (LanVlanId->Data2.Bits.Enabled =3D=3D 1) { > + ThisInstance->VLanId =3D LanVlanId->Data1.VanIdLowByte | (LanVla= nId- > >Data2.Bits.VanIdHighByte << 8); > + } > + > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " VLAN ID %x\n", > ThisInstance->VLanId)); > + > + FreePool (GetLanConfigReps); > + > + // > + // Read USB device information. > + // > + if (ThisInstance->ThisUsbIo !=3D NULL) { > + Status =3D ThisInstance->ThisUsbIo->UsbGetDeviceDescriptor > (ThisInstance->ThisUsbIo, &UsbDeviceDescriptor); > + if (!EFI_ERROR (Status)) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " USB NIC Vendor ID: > 0x%04x, Device ID: 0x%04x\n", UsbDeviceDescriptor.IdVendor, > UsbDeviceDescriptor.IdProduct)); > + ThisInstance->UsbVendorId =3D UsbDeviceDescriptor.IdVendor; > + ThisInstance->UsbProductId =3D UsbDeviceDescriptor.IdProduct; > + } else { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Fail to get USB dev= ice > descriptor.\n")); > + } > + } > + > + // All information is retrieved. > + ThisInstance->IsSuppportedHostInterface =3D TRUE; > + return EFI_SUCCESS; > + } > + > + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) { > + break; > + } > + > + ThisInstance =3D (HOST_INTERFACE_BMC_USB_NIC_INFO *) > + GetNextNode (&mBmcUsbNic, > + &ThisInstance->NextInstance); } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + This function caches the found IPMI LAN channel. So we > + don't have to sedn IPMI commands again if the USB NIC is > + connected later. > + > + @param[in] ChannelNum The IPMI channel number. > + @param[in] IpmiLanChannelMacAddress Pointer to EFI_MAC_ADDRESS. > + @param[in] IpmiLanMacAddressSize The MAC address size. > + > + @retval EFI_SUCCESS IPMI LAN channel is cached. > + @retval EFI_OUT_OF_RESOURCE Memory allocated failed. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +CacheIpmiLanMac ( > + IN UINT8 ChannelNum, > + IN EFI_MAC_ADDRESS *IpmiLanChannelMacAddress, > + IN UINT8 IpmiLanMacAddressSize > + ) > +{ > + BMC_IPMI_LAN_CHANNEL_INFO *ChannelInfo; > + > + ChannelInfo =3D (BMC_IPMI_LAN_CHANNEL_INFO *)AllocateZeroPool > (sizeof > + (BMC_IPMI_LAN_CHANNEL_INFO)); if (ChannelInfo =3D=3D NULL) { > + return EFI_OUT_OF_RESOURCES; > + } > + > + ChannelInfo->Channel =3D ChannelNum; > + CopyMem ((VOID *)&ChannelInfo->MacAddress.Addr, (VOID > +*)IpmiLanChannelMacAddress->Addr, IpmiLanMacAddressSize); > + ChannelInfo->MacAddressSize =3D IpmiLanMacAddressSize; > + InitializeListHead (&ChannelInfo->NextInstance); > + InsertTailList (&mBmcIpmiLan, &ChannelInfo->NextInstance); > + return EFI_SUCCESS; > +} > + > +/** > + This function checks if the IPMI channel already identified > + previously. > + > + @param[in] ChannelNum The IPMI channel number. > + @param[out] CachedIpmiLanChannel Pointer to retrieve the cached > + BMC_IPMI_LAN_CHANNEL_INFO. > + > + @retval EFI_SUCCESS IPMI LAN channel is found. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +CheckCachedIpmiLanMac ( > + IN UINT8 ChannelNum, > + OUT BMC_IPMI_LAN_CHANNEL_INFO **CachedIpmiLanChannel > + ) > +{ > + BMC_IPMI_LAN_CHANNEL_INFO *ThisInstance; > + > + if (IsListEmpty (&mBmcIpmiLan)) { > + return EFI_NOT_FOUND; > + } > + > + ThisInstance =3D (BMC_IPMI_LAN_CHANNEL_INFO *)GetFirstNode > + (&mBmcIpmiLan); while (TRUE) { > + if (ThisInstance->Channel =3D=3D ChannelNum) { > + *CachedIpmiLanChannel =3D ThisInstance; > + return EFI_SUCCESS; > + } > + > + if (IsNodeAtEnd (&mBmcIpmiLan, &ThisInstance->NextInstance)) { > + break; > + } > + > + ThisInstance =3D (BMC_IPMI_LAN_CHANNEL_INFO *) > + GetNextNode (&mBmcIpmiLan, > + &ThisInstance->NextInstance); } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + This function goes through IPMI channels to find the > + mactched MAC addrss of BMC USB NIC endpoint. > + > + @param[in] UsbNicInfo The instance of > HOST_INTERFACE_BMC_USB_NIC_INFO. > + > + @retval EFI_SUCCESS Yes, USB NIC exposed by BMC is found. > + @retval EFI_NOT_FOUND No, USB NIC exposed by BMC is not found > + on the existing SNP handle. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +HostInterfaceIpmiCheckMacAddress ( > + IN HOST_INTERFACE_BMC_USB_NIC_INFO *UsbNicInfo > + ) > +{ > + EFI_STATUS Status; > + EFI_STATUS ExitStatus; > + UINTN ChannelNum; > + UINT32 ResponseDataSize; > + IPMI_GET_CHANNEL_INFO_REQUEST GetChanelInfoRequest; > + IPMI_GET_CHANNEL_INFO_RESPONSE GetChanelInfoResponse; > + IPMI_GET_LAN_CONFIGURATION_PARAMETERS_REQUEST > GetLanConfigReq; > + IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *GetLanConfigReps; > + BMC_IPMI_LAN_CHANNEL_INFO *CachedIpmiLanChannel; > + UINT8 IpmiLanMacAddressSize; > + EFI_MAC_ADDRESS IpmiLanChannelMacAddre= ss; > + BOOLEAN AlreadyCached; > + > + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); > + > + GetLanConfigReps =3D NULL; > + AlreadyCached =3D FALSE; > + if (!IsListEmpty (&mBmcIpmiLan)) { > + AlreadyCached =3D TRUE; > + } > + > + // Initial the get MAC address request. > + GetLanConfigReq.SetSelector =3D 0; > + GetLanConfigReq.BlockSelector =3D 0; > + GetLanConfigReq.ParameterSelector =3D IpmiLanMacAddress; > + > + ExitStatus =3D EFI_NOT_FOUND; > + for (ChannelNum =3D > IPMI_CHANNEL_NUMBER_IMPLEMENTATION_SPECIFIC_1; > + ChannelNum <=3D > IPMI_CHANNEL_NUMBER_IMPLEMENTATION_SPECIFIC_11; > + ChannelNum++) > + { > + IpmiLanMacAddressSize =3D 0; > + > + // Check if the IPMI channel information is already cached. > + Status =3D EFI_NOT_FOUND; > + if (AlreadyCached) { > + Status =3D CheckCachedIpmiLanMac ((UINT8)ChannelNum, > &CachedIpmiLanChannel); > + } > + > + if (Status =3D=3D EFI_SUCCESS) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Got cached IPMI LAN > info.\n")); > + IpmiLanMacAddressSize =3D sizeof (IPMI_LAN_MAC_ADDRESS); > + CopyMem ((VOID *)&IpmiLanChannelMacAddress.Addr, (VOID > *)&CachedIpmiLanChannel->MacAddress.Addr, IpmiLanMacAddressSize); > + } else { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " No cached IPMI LAN > info\n")); > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Send NetFn =3D App, > Command =3D 0x42 to channel %d\n", ChannelNum)); > + GetChanelInfoRequest.ChannelNumber.Bits.ChannelNo =3D > (UINT8)ChannelNum; > + Status =3D IpmiGetChann= elInfo ( > + &GetChanelIn= foRequest, > + &GetChanelIn= foResponse, > + &ResponseDat= aSize > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " - Fails to send command.\n", > ChannelNum)); > + continue; > + } > + > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " - Response data size = =3D > 0x%x\n", ResponseDataSize)); > + if ((GetChanelInfoResponse.CompletionCode !=3D > IPMI_COMP_CODE_NORMAL) || (ResponseDataSize =3D=3D 0)) { > + DEBUG ((DEBUG_ERROR, " - Command returned fail: 0x%x.\n", > GetChanelInfoResponse.CompletionCode)); > + continue; > + } > + > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " - Channel protocol =3D 0x%x, Media =3D 0x%x\n", > + GetChanelInfoResponse.ProtocolType.Bits.ChannelProtocolType, > + GetChanelInfoResponse.MediumType.Bits.ChannelMediumType > + )); > + > + if (GetChanelInfoResponse.ChannelNumber.Bits.ChannelNo !=3D > ChannelNum) { > + DEBUG (( > + DEBUG_ERROR, > + " - ChannelNumber =3D %d in the response which is not macth= ed to the > request.\n", > + GetChanelInfoResponse.ChannelNumber.Bits.ChannelNo > + )); > + continue; > + } > + > + if ((GetChanelInfoResponse.MediumType.Bits.ChannelMediumType =3D= =3D > IPMI_CHANNEL_MEDIA_TYPE_802_3_LAN) && > + (GetChanelInfoResponse.ProtocolType.Bits.ChannelProtocolType = =3D=3D > IPMI_CHANNEL_PROTOCOL_TYPE_IPMB_1_0)) > + { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " - Channel %d is a LAN > device!\n", ChannelNum)); > + > + ResponseDataSize =3D sizeof > (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + > + sizeof (IPMI_LAN_MAC_ADDRESS); > + if (GetLanConfigReps =3D=3D NULL) { > + GetLanConfigReps =3D > + (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE > *)AllocateZeroPool (ResponseDataSize); > + if (GetLanConfigReps =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Allocate memory failed for getting= MAC > address.\n")); > + continue; > + } > + } > + > + GetLanConfigReq.ChannelNumber.Bits.ChannelNo =3D > (UINT8)ChannelNum; > + GetLanConfigReps->CompletionCode =3D > IPMI_COMP_CODE_UNSPECIFIED; > + Status =3D IpmiGetLanConfi= gurationParameters ( > + &GetLanConfigRe= q, > + GetLanConfigRep= s, > + &ResponseDataSi= ze > + ); > + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=3D > IPMI_COMP_CODE_NORMAL)) { > + DEBUG (( > + DEBUG_ERROR, > + " Fails to get MAC address of channel %d, CompletionCode = =3D > %02x.\n", > + ChannelNum, > + GetLanConfigReps->CompletionCode > + )); > + continue; > + } else { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " The MAC address of > channel %d.\n", ChannelNum)); > + DEBUG (( > + DEBUG_REDFISH_HOST_INTERFACE, > + " %02x:%02x:%02x:%02x:%02x:%02x\n", > + *((UINT8 *)(GetLanConfigReps + 1) + 0), > + *((UINT8 *)(GetLanConfigReps + 1) + 1), > + *((UINT8 *)(GetLanConfigReps + 1) + 2), > + *((UINT8 *)(GetLanConfigReps + 1) + 3), > + *((UINT8 *)(GetLanConfigReps + 1) + 4), > + *((UINT8 *)(GetLanConfigReps + 1) + 5) > + )); > + IpmiLanMacAddressSize =3D sizeof (IPMI_LAN_MAC_ADDRESS); > + CopyMem ((VOID *)&IpmiLanChannelMacAddress.Addr, (VOID > *)(GetLanConfigReps + 1), IpmiLanMacAddressSize); > + } > + } > + } > + > + if (IpmiLanMacAddressSize !=3D 0) { > + if (!AlreadyCached) { > + // Cache this IPMI LAN channel. > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Cache this IPMI LAN > channel.\n")); > + CacheIpmiLanMac ((UINT8)ChannelNum, &IpmiLanChannelMacAddress, > IpmiLanMacAddressSize); > + } > + > + // > + // According to design spec in Readme file under RedfishPkg. > + // Compare the first five MAC address and > + // the 6th MAC address. > + // > + if ((IpmiLanMacAddressSize !=3D UsbNicInfo->MacAddressSize) || > + (CompareMem ( > + (VOID *)UsbNicInfo->MacAddress, > + (VOID *)&IpmiLanChannelMacAddress.Addr, > + IpmiLanMacAddressSize - 1 > + ) !=3D 0) || > + (IpmiLanChannelMacAddress.Addr[IpmiLanMacAddressSize - 1] !=3D > + *(UsbNicInfo->MacAddress + IpmiLanMacAddressSize - 1) - 1) > + ) > + { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address is not > matched.\n")); > + continue; > + } > + > + // This is the NIC exposed by BMC. > + UsbNicInfo->IpmiLanChannelNumber =3D (UINT8)ChannelNum; > + UsbNicInfo->IsExposedByBmc =3D TRUE; > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address is > matched.\n")); > + ExitStatus =3D EFI_SUCCESS; > + break; > + } > + } > + > + if (GetLanConfigReps !=3D NULL) { > + FreePool (GetLanConfigReps); > + } > + > + return ExitStatus; > +} > + > +/** > + This function searches the next MSG_USB_DP device path node. > + > + @param[in] ThisDevicePath Device path to search. > + > + @retval NULL MSG_USB_DP is not found. > + Otherwise MSG_USB_DP is found. > + > +**/ > +EFI_DEVICE_PATH_PROTOCOL * > +UsbNicGetNextMsgUsbDp ( > + IN EFI_DEVICE_PATH_PROTOCOL *ThisDevicePath > + ) > +{ > + if (ThisDevicePath =3D=3D NULL) { > + return NULL; > + } > + > + while (TRUE) { > + ThisDevicePath =3D NextDevicePathNode (ThisDevicePath); > + if (IsDevicePathEnd (ThisDevicePath)) { > + return NULL; > + } > + > + if ((ThisDevicePath->Type =3D=3D MESSAGING_DEVICE_PATH) && > (ThisDevicePath->SubType =3D=3D MSG_USB_DP)) { > + return ThisDevicePath; > + } > + } > + > + return NULL; > +} > + > +/** > + This function search the UsbIo handle that matches the UsbDevicePath. > + > + @param[in] UsbDevicePath Device path of this SNP handle. > + @param[out] UsbIo Return the UsbIo protocol. > + > + @retval EFI_SUCCESS Yes, UsbIo protocl is found. > + @retval EFI_NOT_FOUND No, UsbIo protocl is not found > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +UsbNicSearchUsbIo ( > + IN EFI_DEVICE_PATH_PROTOCOL *UsbDevicePath, > + OUT EFI_USB_IO_PROTOCOL **UsbIo > + ) > +{ > + EFI_STATUS Status; > + UINTN BufferSize; > + EFI_HANDLE *HandleBuffer; > + UINT16 Length; > + UINTN Index; > + CHAR16 *DevicePathStr; > + EFI_DEVICE_PATH_PROTOCOL *TempDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *ThisDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *ThisDevicePathEnd; > + EFI_DEVICE_PATH_PROTOCOL *ThisUsbDevicePath; > + EFI_DEVICE_PATH_PROTOCOL *ThisUsbDevicePathEnd; > + > + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); DEBUG > + ((DEBUG_REDFISH_HOST_INTERFACE, "Device path on the EFI handle > which > + has UsbIo and SNP instaleld on it.\n")); DevicePathStr =3D > + ConvertDevicePathToText (UsbDevicePath, FALSE, FALSE); DEBUG > + ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr)); FreePool > + (DevicePathStr); >=20 > It would be better to consider the case when ConvertDevicePathToText() > returns NULL pointer. >=20 > + > + BufferSize =3D 0; > + HandleBuffer =3D NULL; > + *UsbIo =3D NULL; > + Status =3D gBS->LocateHandle ( > + ByProtocol, > + &gEfiUsbIoProtocolGuid, > + NULL, > + &BufferSize, > + NULL > + ); > + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " %d UsbIo protocol > instances.\n", BufferSize/sizeof (EFI_HANDLE))); > + HandleBuffer =3D AllocateZeroPool (BufferSize); > + if (HandleBuffer =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Falied to allocate buffer for the > handles.\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status =3D gBS->LocateHandle ( > + ByProtocol, > + &gEfiUsbIoProtocolGuid, > + NULL, > + &BufferSize, > + HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " Falied to locate UsbIo protocol handles.\n= ")); > + FreePool (HandleBuffer); > + return Status; > + } > + } else { > + return Status; > + } > + > + for (Index =3D 0; Index < (BufferSize/sizeof (EFI_HANDLE)); Index++) { > + Status =3D gBS->HandleProtocol ( > + *(HandleBuffer + Index), > + &gEfiDevicePathProtocolGuid, > + (VOID **)&ThisDevicePath > + ); > + if (EFI_ERROR (Status)) { > + continue; > + } > + > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "Device path on #%d > instance of UsbIo.\n", Index)); > + DevicePathStr =3D ConvertDevicePathToText (ThisDevicePath, FALSE, > FALSE); > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr)); > + FreePool (DevicePathStr); >=20 > It would be better to consider the case when ConvertDevicePathToText() > returns NULL pointer. >=20 > Thanks, > Nickle >=20 > + > + Status =3D EFI_NOT_FOUND; > + > + // Search for the starting MSG_USB_DP node. > + ThisUsbDevicePath =3D UsbDevicePath; > + if ((DevicePathType (ThisUsbDevicePath) !=3D MESSAGING_DEVICE_PATH) > || > + (DevicePathSubType (ThisUsbDevicePath) !=3D MSG_USB_DP)) > + { > + ThisUsbDevicePath =3D UsbNicGetNextMsgUsbDp (ThisUsbDevicePath); > + if (ThisUsbDevicePath =3D=3D NULL) { > + continue; > + } > + } > + > + if ((DevicePathType (ThisDevicePath) !=3D MESSAGING_DEVICE_PATH) || > + (DevicePathSubType (ThisDevicePath) !=3D MSG_USB_DP)) > + { > + ThisDevicePath =3D UsbNicGetNextMsgUsbDp (ThisDevicePath); > + if (ThisDevicePath =3D=3D NULL) { > + continue; > + } > + } > + > + // Search for the ending MSG_USB_DP node. > + ThisDevicePathEnd =3D ThisDevicePath; > + ThisUsbDevicePathEnd =3D ThisUsbDevicePath; > + while (TRUE) { > + TempDevicePath =3D UsbNicGetNextMsgUsbDp (ThisDevicePathEnd); > + if (TempDevicePath =3D=3D NULL) { > + break; > + } > + > + ThisDevicePathEnd =3D TempDevicePath; > + } > + > + while (TRUE) { > + TempDevicePath =3D UsbNicGetNextMsgUsbDp (ThisUsbDevicePathEnd); > + if (TempDevicePath =3D=3D NULL) { > + break; > + } > + > + ThisUsbDevicePathEnd =3D TempDevicePath; > + } > + > + // Compare these two device paths > + Length =3D (UINT16)((UINTN)(UINT8 *)ThisDevicePathEnd + > DevicePathNodeLength (ThisDevicePathEnd) - (UINTN)(UINT8 > *)ThisDevicePath); > + if (Length !=3D ((UINTN)(UINT8 *)ThisUsbDevicePathEnd + > DevicePathNodeLength (ThisUsbDevicePathEnd) - (UINTN)(UINT8 > *)ThisUsbDevicePath)) { > + continue; > + } > + > + if (CompareMem ( > + (VOID *)ThisDevicePath, > + (VOID *)ThisUsbDevicePath, > + Length > + ) =3D=3D 0) > + { > + Status =3D EFI_SUCCESS; > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "EFI handle with the > correct UsbIo is found at #%d instance of UsbIo.\n", Index)); > + break; > + } > + } > + > + if (Status =3D=3D EFI_SUCCESS) { > + // Locate UsbIo from this handle. > + Status =3D gBS->HandleProtocol ( > + *(HandleBuffer + Index), > + &gEfiUsbIoProtocolGuid, > + (VOID **)UsbIo > + ); > + return Status; > + } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + This function identifies if the USB NIC is exposed by BMC as > + the host-BMC channel. > + > + @param[in] Handle This is the EFI handle with SNP installed. > + @param[in] UsbDevicePath USB device path. > + > + @retval EFI_SUCCESS Yes, USB NIC exposed by BMC is found. > + @retval EFI_NOT_FOUND No, USB NIC exposed by BMC is not found > + on the existing SNP handle. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +IdentifyUsbNicBmcChannel ( > + IN EFI_HANDLE Handle, > + IN EFI_DEVICE_PATH_PROTOCOL *UsbDevicePath > + ) > +{ > + UINTN Index; > + EFI_STATUS Status; > + EFI_SIMPLE_NETWORK_PROTOCOL *Snp; > + EFI_USB_IO_PROTOCOL *UsbIo; > + HOST_INTERFACE_BMC_USB_NIC_INFO *BmcUsbNic; > + > + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); Status =3D > + gBS->HandleProtocol ( > + Handle, > + &gEfiSimpleNetworkProtocolGuid, > + (VOID **)&Snp > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " Failed to locate SNP.\n")); > + return Status; > + } > + > + Status =3D UsbNicSearchUsbIo (UsbDevicePath, &UsbIo); if (EFI_ERROR > + (Status)) { > + DEBUG ((DEBUG_ERROR, " Failed to find USBIO.\n")); > + return Status; > + } > + > + // Get the MAC address of this SNP instance. > + BmcUsbNic =3D AllocateZeroPool (sizeof > + (HOST_INTERFACE_BMC_USB_NIC_INFO)); > + if (BmcUsbNic =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Failed to allocate memory for > HOST_INTERFACE_BMC_USB_NIC_INFO.\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + InitializeListHead (&BmcUsbNic->NextInstance); > + BmcUsbNic->MacAddressSize =3D Snp->Mode->HwAddressSize; > + BmcUsbNic->MacAddress =3D AllocateZeroPool (sizeof (BmcUsbNic- > >MacAddressSize)); > + if (BmcUsbNic->MacAddress =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Failed to allocate memory for HW MAC > addresss.\n")); > + FreePool (BmcUsbNic); > + return EFI_OUT_OF_RESOURCES; > + } > + > + CopyMem ( > + (VOID *)BmcUsbNic->MacAddress, > + (VOID *)&Snp->Mode->CurrentAddress, > + BmcUsbNic->MacAddressSize > + ); > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address (in size %d) > for this SNP instance:\n ", BmcUsbNic->MacAddressSize)); > + for (Index =3D 0; Index < BmcUsbNic->MacAddressSize; Index++) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%02x ", > + *(BmcUsbNic->MacAddress + Index))); } > + > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "\n")); > + BmcUsbNic->ThisSnp =3D Snp; > + BmcUsbNic->ThisUsbIo =3D UsbIo; > + > + Status =3D HostInterfaceIpmiCheckMacAddress (BmcUsbNic); if (Status = =3D=3D > + EFI_SUCCESS) { > + BmcUsbNic->IsExposedByBmc =3D TRUE; > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " BMC exposed USB NIC > is found.\n")); > + } else { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " BMC exposed USB NIC > is not found.\n")); > + } > + > + InsertTailList (&mBmcUsbNic, &BmcUsbNic->NextInstance); > + return Status; > +} > + > +/** > + This function checks if the USB NIC exposed by BMC > + on each handle has SNP protocol installed on it. > + > + @param[in] HandleNumer Number of handles to check. > + @param[in] HandleBuffer Handles buffer. > + > + @retval EFI_SUCCESS Yes, USB NIC exposed by BMC is found. > + @retval EFI_NOT_FOUND No, USB NIC exposed by BMC is not found > + on the existing SNP handle. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +CheckBmcUsbNicOnHandles ( > + IN UINTN HandleNumer, > + IN EFI_HANDLE *HandleBuffer > + ) > +{ > + UINTN Index; > + EFI_STATUS Status; > + EFI_DEVICE_PATH_PROTOCOL *DevicePath; > + BOOLEAN GotOneUsbNIc; > + > + if ((HandleNumer =3D=3D 0) || (HandleBuffer =3D=3D NULL)) { > + return EFI_INVALID_PARAMETER; > + } > + > + DEBUG ((DEBUG_INFO, "%a: Entry, #%d SNP handle\n", __FUNCTION__, > + HandleNumer)); > + > + GotOneUsbNIc =3D FALSE; > + for (Index =3D 0; Index < HandleNumer; Index++) { > + Status =3D gBS->HandleProtocol ( > + *(HandleBuffer + Index), > + &gEfiDevicePathProtocolGuid, > + (VOID **)&DevicePath > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " Failed to locate SNP on %d handle.\n", > __FUNCTION__, Index)); > + continue; > + } > + > + // Check if this is an BMC exposed USB NIC device. > + while (TRUE) { > + if ((DevicePath->Type =3D=3D MESSAGING_DEVICE_PATH) && (DevicePath= - > >SubType =3D=3D MSG_USB_DP)) { > + Status =3D IdentifyUsbNicBmcChannel (*(HandleBuffer + Index), > DevicePath); > + if (!EFI_ERROR (Status)) { > + GotOneUsbNIc =3D TRUE; > + break; > + } > + } > + > + DevicePath =3D NextDevicePathNode (DevicePath); > + if (IsDevicePathEnd (DevicePath)) { > + break; > + } > + } > + } > + > + if (GotOneUsbNIc) { > + return EFI_SUCCESS; > + } > + > + return EFI_NOT_FOUND; > +} > + > +/** > + This function checks if the USB NIC exposed by BMC > + is already connected. > + > + @param[in] Registration Locate SNP protocol from the notification > + registeration key. > + NULL means locate SNP protocol from the e= xisting > + handles. > + > + @retval EFI_SUCCESS Yes, USB NIC exposed by BMC is found. > + @retval EFI_NOT_FOUND No, USB NIC exposed by BMC is not found > + on the existing SNP handle. > + @retval Others Other errors. > + > +**/ > +EFI_STATUS > +CheckBmcUsbNic ( > + VOID *Registration > + ) > +{ > + EFI_STATUS Status; > + EFI_HANDLE Handle; > + UINTN BufferSize; > + EFI_HANDLE *HandleBuffer; > + > + DEBUG ((DEBUG_INFO, "%a: Entry, the registration key - 0x%08x.\n", > + __FUNCTION__, Registration)); > + > + Handle =3D NULL; > + Status =3D EFI_SUCCESS; > + BufferSize =3D 0; > + > + Status =3D gBS->LocateHandle ( > + Registration =3D=3D NULL ? ByProtocol : ByRegisterNoti= fy, > + &gEfiSimpleNetworkProtocolGuid, > + Registration, > + &BufferSize, > + NULL > + ); > + if (Status =3D=3D EFI_BUFFER_TOO_SMALL) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " %d SNP protocol > instances.\n", BufferSize/sizeof (EFI_HANDLE))); > + HandleBuffer =3D AllocateZeroPool (BufferSize); > + if (HandleBuffer =3D=3D NULL) { > + DEBUG ((DEBUG_ERROR, " Falied to allocate buffer for the > handles.\n")); > + return EFI_OUT_OF_RESOURCES; > + } > + > + Status =3D gBS->LocateHandle ( > + Registration =3D=3D NULL ? ByProtocol : ByRegisterNo= tify, > + &gEfiSimpleNetworkProtocolGuid, > + Registration, > + &BufferSize, > + HandleBuffer > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " Falied to locate SNP protocol handles.\n= ")); > + FreePool (HandleBuffer); > + return Status; > + } > + } else if (EFI_ERROR (Status)) { > + return Status; > + } > + > + // Check USB NIC on handles. > + Status =3D CheckBmcUsbNicOnHandles (BufferSize/sizeof (EFI_HANDLE), > + HandleBuffer); if (!EFI_ERROR (Status)) { > + // Retrieve the rest of BMC USB NIC information for Redfish over IP > information > + // and USB Network Interface V2. > + Status =3D RetrievedBmcUsbNicInfo (); > + if (!EFI_ERROR (Status)) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Install protocol to > notify the platform Redfish Host Interface information is ready.\n")); > + Status =3D gBS->InstallProtocolInterface ( > + &Handle, > + &mPlatformHostInterfaceBmcUsbNicReadinessGuid, > + EFI_NATIVE_INTERFACE, > + NULL > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, " Install protocol fail %r.\n", Status))= ; > + } > + } > + } > + > + FreePool (HandleBuffer); > + return Status; > +} > + > +/** > + Notification event of SNP readiness. > + > + @param[in] Event Event whose notification function is= being > invoked. > + @param[in] Context The pointer to the notification func= tion's > context, > + which is implementation-dependent. > + > +**/ > +VOID > +EFIAPI > +PlatformHostInterfaceSnpCallback ( > + IN EFI_EVENT Event, > + IN VOID *Context > + ) > +{ > + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__)); > + > + CheckBmcUsbNic (mPlatformHostInterfaceSnpRegistration); > + return; > +} > + > +/** > + Get the EFI protocol GUID installed by platform library which > + indicates the necessary information is ready for building > + SMBIOS 42h record. > + > + @param[out] InformationReadinessGuid Pointer to retrive the protocol > + GUID. > + > + @retval EFI_SUCCESS Notification is required for building up > + SMBIOS type 42h record. > + @retval EFI_UNSUPPORTED Notification is not required for building= up > + SMBIOS type 42h record. > + @retval EFI_ALREADY_STARTED Platform host information is already read= y. > + @retval Others Other errors. > +**/ > +EFI_STATUS > +RedfishPlatformHostInterfaceNotification ( > + OUT EFI_GUID **InformationReadinessGuid > + ) > +{ > + EFI_STATUS Status; > + > + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__)); > + > + *InformationReadinessGuid =3D NULL; > + InitializeListHead (&mBmcUsbNic); > + InitializeListHead (&mBmcIpmiLan); > + > + // > + // Check if USB NIC exposed by BMC is already // connected. > + // > + Status =3D CheckBmcUsbNic (NULL); > + if (!EFI_ERROR (Status)) { > + return EFI_ALREADY_STARTED; > + } > + > + if (Status =3D=3D EFI_NOT_FOUND) { > + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%a: BMC USB NIC is not > + found. Register the notification.\n", __FUNCTION__)); > + > + // Register the notification of SNP installation. > + Status =3D gBS->CreateEvent ( > + EVT_NOTIFY_SIGNAL, > + TPL_CALLBACK, > + PlatformHostInterfaceSnpCallback, > + NULL, > + &mPlatformHostInterfaceSnpEvent > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installatio= n of > SNP protocol.", __FUNCTION__)); > + return Status; > + } > + > + Status =3D gBS->RegisterProtocolNotify ( > + &gEfiSimpleNetworkProtocolGuid, > + mPlatformHostInterfaceSnpEvent, > + &mPlatformHostInterfaceSnpRegistration > + ); > + if (EFI_ERROR (Status)) { > + DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installat= ion of > SNP protocol.", __FUNCTION__)); > + return Status; > + } > + > + *InformationReadinessGuid =3D > &mPlatformHostInterfaceBmcUsbNicReadinessGuid; > + return EFI_SUCCESS; > + } > + > + DEBUG ((DEBUG_ERROR, "%a: Something wrong when look for BMC USB > +NIC.\n", __FUNCTION__)); > + return Status; > +} > -- > 2.37.1.windows.1