[edk2-devel] [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host Interface
Chang, Abner via groups.io
abner.chang=amd.com at groups.io
Mon Mar 20 08:14:34 UTC 2023
[AMD Official Use Only - General]
Hi Nickle,
Thanks for those good comments. V2 patch was just sent!
Abner
> -----Original Message-----
> From: Nickle Wang <nicklew at nvidia.com>
> Sent: Monday, March 20, 2023 11:13 AM
> To: Chang, Abner <Abner.Chang at amd.com>; devel at edk2.groups.io
> Cc: Igor Kulchytskyy <igork at ami.com>
> Subject: RE: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host
> Interface
>
> Caution: This message originated from an External Source. Use proper
> caution when opening attachments, clicking links, or responding.
>
>
> Please find my comment inline below, thanks!
>
> Regards,
> Nickle
>
> -----Original Message-----
> From: abner.chang at amd.com <abner.chang at amd.com>
> Sent: Thursday, March 9, 2023 11:41 PM
> To: devel at edk2.groups.io
> Cc: Nickle Wang <nicklew at nvidia.com>; Igor Kulchytskyy <igork at ami.com>
> Subject: [PATCH 1/3] RedfishPkg/Library: Redfish BMC USBNIC Host Interface
>
> External email: Use caution opening links or attachments
>
>
> From: Abner Chang <abner.chang at amd.com>
>
> BMC exposed USB NIC platform Redfish Host Interface library
> implementation.
>
> Signed-off-by: Abner Chang <abner.chang at amd.com>
> Cc: Nickle Wang <nicklew at nvidia.com>
> Cc: Igor Kulchytskyy <igork at ami.com>
> ---
> 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
>
> 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.
> #
>
> 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
>
> Would it be good to provide dummy string for above PCDs? For example:
>
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishHostName|"edk2_redfishpkg"|V
> OID*|0x00001005
> gEfiRedfishPkgTokenSpaceGuid.PcdRedfishServiceUuid|L"0000000000000000
> "|VOID*|0x0000100
>
> 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 = 0x0001000b
> + BASE_NAME = PlatformHostInterfaceBmcUsbNicLib
> + FILE_GUID = C4837B58-225E-4352-8FDC-4C52A5D65891
> + MODULE_TYPE = DXE_DRIVER
> + VERSION_STRING = 1.0
> + LIBRARY_CLASS = 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 <Library/JsonLib.h>
> #include <Library/RedfishLib.h>
>
> -#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
>
> /**
>
> 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 <Uefi.h>
> +#include <IndustryStandard/Ipmi.h>
> +#include <IndustryStandard/IpmiNetFnApp.h> #include
> +<IndustryStandard/IpmiNetFnTransport.h>
> +#include <IndustryStandard/RedfishHostInterfaceIpmi.h>
> +#include <IndustryStandard/SmBios.h>
> +#include <Library/BaseLib.h>
> +#include <Library/BaseMemoryLib.h>
> +#include <Library/DebugLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/IpmiLib.h>
> +#include <Library/IpmiCommandLib.h>
> +#include <Library/RedfishHostInterfaceLib.h>
> +#include <Library/MemoryAllocationLib.h> #include
> +<Library/UefiBootServicesTableLib.h>
> +#include <Library/DevicePathLib.h>
> +#include <Library/RedfishDebugLib.h>
> +
> +#include <Protocol/SimpleNetwork.h>
> +#include <Protocol/UsbIo.h>
> +
> +#define BMC_USB_NIC_HOST_INTERFASCE_READINESS_GUID \
> + { \
> + 0xDD96F5D7, 0x4AE1, 0x4E6C, {0xA1, 0x30, 0xA5, 0xAC, 0x77, 0xDD, 0xE4,
> 0xA5} \
> + }
> +
> +//
> +// This is the structure for BMC exposed // USB NIC information.
> +//
> +typedef struct {
> + LIST_ENTRY NextInstance; ///< Link to the next instance.
> + BOOLEAN IsExposedByBmc; ///< Flag indicates this USB
> NIC is
> + ///< exposed by BMC.
> + BOOLEAN IsSuppportedHostInterface; ///< This BMC USB NIC is
> supported
> + ///< as Redfish host interface
> + EFI_SIMPLE_NETWORK_PROTOCOL *ThisSnp; ///< The SNP
> instance associated with
> + ///< this USB NIC.
> + EFI_USB_IO_PROTOCOL *ThisUsbIo; ///< The USBIO instance
> associated with
> + ///< this USB NIC.
> + UINT16 UsbVendorId; ///< USB Vendor ID of this BMC
> exposed USB NIC.
> + UINT16 UsbProductId; ///< USB Product ID of this BMC
> exposed USB NIC.
> + UINTN MacAddressSize; ///< HW address size.
> + UINT8 *MacAddress; ///< HW address.
> + UINT8 IpmiLanChannelNumber; ///< BMC IPMI Lan Channel
> number.
> +
> + //
> + // Below is the infortmation for building SMBIOS type 42.
> + //
> + UINT8 IpAssignedType; ///< Redfish service IP assign type.
> + UINT8 IpAddressFormat; ///< Redfish service IP version.
> + UINT8 HostIpAddressIpv4[4]; ///< Host IP address.
> + UINT8 RedfishIpAddressIpv4[4]; ///< Redfish service IP
> address.
> + UINT8 SubnetMaskIpv4[4]; ///< Subnet mask.
> + UINT8 GatewayIpv4[4]; ///< Gateway IP address.
> + UINT16 VLanId; ///< VLAN ID.
> + BOOLEAN CredentialBootstrapping; ///< If Credential
> 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 =
> + BMC_USB_NIC_HOST_INTERFASCE_READINESS_GUID;
> +static EFI_EVENT mPlatformHostInterfaceSnpEvent = NULL;
> +static VOID *mPlatformHostInterfaceSnpRegistration = 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 =
> REDFISH_IPMI_GROUP_EXTENSION;
> + CommandData.DisableBootstrapControl =
> REDFISH_IPMI_BOOTSTRAP_CREDENTIAL_ENABLE;
> + ResponseData.CompletionCode = IPMI_COMP_CODE_UNSPECIFIED;
> + ResponseSize = sizeof (ResponseData);
> + //
> + // Response data: Ignored.
> + //
> + Status = IpmiSubmitCommand (
> + IPMI_NETFN_GROUP_EXT,
> + REDFISH_IPMI_GET_BOOTSTRAP_CREDENTIALS_CMD,
> + (UINT8 *)&CommandData,
> + sizeof (CommandData),
> + (UINT8 *)&ResponseData,
> + &ResponseSize
> + );
> + if (!EFI_ERROR (Status) &&
> + ((ResponseData.CompletionCode == IPMI_COMP_CODE_NORMAL) ||
> + (ResponseData.CompletionCode ==
> REDFISH_IPMI_COMP_CODE_BOOTSTRAP_CREDENTIAL_DISABLED)
> + ))
> + {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credentail
> Bootstrapping is supported\n", __FUNCTION__));
> + ReturnBool = TRUE;
> + } else {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Redfish Credentail
> Bootstrapping is not supported\n", __FUNCTION__));
> + ReturnBool = 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 = (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode
> + (&mBmcUsbNic); while (TRUE) {
> + if (ThisInstance->IsExposedByBmc && ThisInstance-
> >IsSuppportedHostInterface) {
> + *DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2;
> +
> + // Fill up REDFISH_INTERFACE_DATA defined in Redfish host interface
> spec v1.3
> + InterfaceData = (REDFISH_INTERFACE_DATA *)AllocateZeroPool
> (USB_INTERFACE_DEVICE_DESCRIPTOR_V2_SIZE_1_3);
> + if (InterfaceData == NULL) {
> + DEBUG ((DEBUG_ERROR, "Failed to allocate memory for
> REDFISH_INTERFACE_DATA\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + InterfaceData->DeviceType =
> REDFISH_HOST_INTERFACE_DEVICE_TYPE_USB_V2;
> + InterfaceData->DeviceDescriptor.UsbDeviceV2.Length =
> USB_INTERFACE_DEVICE_DESCRIPTOR_V2_SIZE_1_3;
> + InterfaceData->DeviceDescriptor.UsbDeviceV2.IdVendor =
> ThisInstance->UsbVendorId;
> + InterfaceData->DeviceDescriptor.UsbDeviceV2.IdProduct =
> ThisInstance->UsbProductId;
> + InterfaceData->DeviceDescriptor.UsbDeviceV2.SerialNumberStr = 0;
> + CopyMem (
> + (VOID *)&InterfaceData->DeviceDescriptor.UsbDeviceV2.MacAddress,
> + (VOID *)&ThisInstance->MacAddress,
> + sizeof (InterfaceData->DeviceDescriptor.UsbDeviceV2.MacAddress)
> + );
> + InterfaceData->DeviceDescriptor.UsbDeviceV2.Characteristics |=
> (UINT16)ThisInstance->CredentialBootstrapping;
> + InterfaceData-
> >DeviceDescriptor.UsbDeviceV2.CredentialBootstrappingHandle = 0;
> + *DeviceDescriptor = InterfaceData;
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "
> REDFISH_INTERFACE_DATA is returned successfully.\n"));
> + return EFI_SUCCESS;
> + }
> +
> + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) {
> + break;
> + }
> +
> + ThisInstance = (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 protocol
> record.
> + Then continuously pass previous ProtocolRecord for retrieving the next
> ProtocolRecord.
> +
> + @param[in, out] ProtocolRecord Pointer to retrieve the first or the next
> protocol record.
> + caller has to free the new protocol record 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 = (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode
> + (&mBmcUsbNic); while (TRUE) {
> + if (ThisInstance->IsExposedByBmc && ThisInstance-
> >IsSuppportedHostInterface) {
> + // Get the host name before allocating memory.
> + HostNameString = (CHAR8 *)PcdGetPtr (PcdRedfishHostName);
> + HostNameLength = (UINT8)AsciiStrSize (HostNameString);
> + ThisProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD
> *)AllocateZeroPool (
> + sizeof
> (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1 +
> + sizeof
> (REDFISH_OVER_IP_PROTOCOL_DATA) +
> + HostNameLength
> + );
> + if (ThisProtocolRecord == NULL) {
> + DEBUG ((DEBUG_ERROR, " Aloocate memory fail for
> MC_HOST_INTERFACE_PROTOCOL_RECORD.\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + ThisProtocolRecord->ProtocolType =
> MCHostInterfaceProtocolTypeRedfishOverIP;
> + ThisProtocolRecord->ProtocolTypeDataLen = sizeof
> (REDFISH_OVER_IP_PROTOCOL_DATA) + HostNameLength;
> + RedfishOverIpData = (REDFISH_OVER_IP_PROTOCOL_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)) != 0) {
> + StrToGuid ((CONST CHAR16 *)PcdGetPtr (PcdRedfishServiceUuid),
> &RedfishOverIpData->ServiceUuid);
> + }
> +
> + // HostIpAddressFormat and RedfishServiceIpDiscoveryType
> + RedfishOverIpData->HostIpAssignmentType =
> RedfishHostIpAssignmentUnknown;
> + RedfishOverIpData->RedfishServiceIpDiscoveryType =
> RedfishHostIpAssignmentUnknown;
> + if (ThisInstance->IpAssignedType == IpmiStaticAddrsss) {
> + RedfishOverIpData->HostIpAssignmentType =
> RedfishHostIpAssignmentStatic;
> + RedfishOverIpData->RedfishServiceIpDiscoveryType =
> RedfishHostIpAssignmentStatic;
> + } else if (ThisInstance->IpAssignedType ==
> IpmiDynamicAddressBmcDhcp) {
> + RedfishOverIpData->HostIpAssignmentType =
> RedfishHostIpAssignmentDhcp;
> + RedfishOverIpData->RedfishServiceIpDiscoveryType =
> RedfishHostIpAssignmentDhcp;
> + }
> +
> + // HostIpAddressFormat and RedfishServiceIpAddressFormat, only
> support IPv4 for now.
> + RedfishOverIpData->HostIpAddressFormat =
> REDFISH_HOST_INTERFACE_HOST_IP_ADDRESS_FORMAT_IP4;
> + RedfishOverIpData->RedfishServiceIpAddressFormat =
> + 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 = 0;
> +
> + // RedfishServiceVlanId
> + RedfishOverIpData->RedfishServiceVlanId = ThisInstance->VLanId;
> +
> + // RedfishServiceHostnameLength
> + RedfishOverIpData->RedfishServiceHostnameLength =
> 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 = ThisProtocolRecord;
> + return EFI_SUCCESS;
> + }
> +
> + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) {
> + break;
> + }
> +
> + ThisInstance = (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 = (HOST_INTERFACE_BMC_USB_NIC_INFO *)GetFirstNode
> + (&mBmcUsbNic); while (TRUE) {
> + if (ThisInstance->IsExposedByBmc) {
> + ThisInstance->IsSuppportedHostInterface = FALSE;
> +
> + // Probe if Redfish Host Interface Credential Bootstrapping is supported.
> + ThisInstance->CredentialBootstrapping =
> + ProbeRedfishCredentialBootstrap ();
> +
> + // Get IP address source
> + GetLanConfigReq.SetSelector = 0;
> + GetLanConfigReq.BlockSelector = 0;
> + GetLanConfigReq.ChannelNumber.Bits.ChannelNo = ThisInstance-
> >IpmiLanChannelNumber;
> + GetLanConfigReq.ChannelNumber.Bits.GetParameter = 0;
> + GetLanConfigReq.ChannelNumber.Bits.Reserved = 0;
> + GetLanConfigReq.ParameterSelector = IpmiLanIpAddressSource;
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof
> (IPMI_LAN_IP_ADDRESS_SRC);
> + GetLanConfigReps =
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=
> IPMI_COMP_CODE_NORMAL)) {
> + DEBUG ((DEBUG_ERROR, " Failed to get IP address source at channel
> %d: %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status,
> GetLanConfigReps->CompletionCode));
> + FreePool (GetLanConfigReps);
> + return Status;
> + }
> +
> + IpAddressSrc = (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 = IpAddressSrc->Bits.AddressSrc;
> + FreePool (GetLanConfigReps);
> +
> + // Get LAN IPv4 IP address
> + GetLanConfigReq.ParameterSelector = IpmiLanIpAddress;
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof
> (IPMI_LAN_IP_ADDRESS);
> + GetLanConfigReps =
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=
> IPMI_COMP_CODE_NORMAL)) {
> + DEBUG ((DEBUG_ERROR, " Failed to get Dest IP address at channel %d:
> %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status,
> GetLanConfigReps->CompletionCode));
> + FreePool (GetLanConfigReps);
> + return Status;
> + }
> +
> + DestIpAddress = (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] -= 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 = IpmiLanSubnetMask;
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof
> (IPMI_LAN_SUBNET_MASK);
> + GetLanConfigReps =
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=
> 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 = (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 = IpmiLanDefaultGateway;
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof
> (IPMI_LAN_DEFAULT_GATEWAY);
> + GetLanConfigReps =
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=
> IPMI_COMP_CODE_NORMAL)) {
> + DEBUG ((DEBUG_ERROR, " Failed to get default gateway at channel
> %d: %r, 0x%02x.\n", ThisInstance->IpmiLanChannelNumber, Status,
> GetLanConfigReps->CompletionCode));
> + FreePool (GetLanConfigReps);
> + return Status;
> + }
> +
> + DefaultGateway = (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 = IpmiLanVlanId;
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) + sizeof
> (IPMI_LAN_VLAN_ID);
> + GetLanConfigReps =
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if ((EFI_ERROR (Status)) || (GetLanConfigReps->CompletionCode !=
> 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 = (IPMI_LAN_VLAN_ID *)(GetLanConfigReps + 1);
> + ThisInstance->VLanId = 0;
> + if (LanVlanId->Data2.Bits.Enabled == 1) {
> + ThisInstance->VLanId = LanVlanId->Data1.VanIdLowByte | (LanVlanId-
> >Data2.Bits.VanIdHighByte << 8);
> + }
> +
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " VLAN ID %x\n",
> ThisInstance->VLanId));
> +
> + FreePool (GetLanConfigReps);
> +
> + //
> + // Read USB device information.
> + //
> + if (ThisInstance->ThisUsbIo != NULL) {
> + Status = 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 = UsbDeviceDescriptor.IdVendor;
> + ThisInstance->UsbProductId = UsbDeviceDescriptor.IdProduct;
> + } else {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Fail to get USB device
> descriptor.\n"));
> + }
> + }
> +
> + // All information is retrieved.
> + ThisInstance->IsSuppportedHostInterface = TRUE;
> + return EFI_SUCCESS;
> + }
> +
> + if (IsNodeAtEnd (&mBmcUsbNic, &ThisInstance->NextInstance)) {
> + break;
> + }
> +
> + ThisInstance = (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 = (BMC_IPMI_LAN_CHANNEL_INFO *)AllocateZeroPool
> (sizeof
> + (BMC_IPMI_LAN_CHANNEL_INFO)); if (ChannelInfo == NULL) {
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + ChannelInfo->Channel = ChannelNum;
> + CopyMem ((VOID *)&ChannelInfo->MacAddress.Addr, (VOID
> +*)IpmiLanChannelMacAddress->Addr, IpmiLanMacAddressSize);
> + ChannelInfo->MacAddressSize = 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 = (BMC_IPMI_LAN_CHANNEL_INFO *)GetFirstNode
> + (&mBmcIpmiLan); while (TRUE) {
> + if (ThisInstance->Channel == ChannelNum) {
> + *CachedIpmiLanChannel = ThisInstance;
> + return EFI_SUCCESS;
> + }
> +
> + if (IsNodeAtEnd (&mBmcIpmiLan, &ThisInstance->NextInstance)) {
> + break;
> + }
> +
> + ThisInstance = (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 IpmiLanChannelMacAddress;
> + BOOLEAN AlreadyCached;
> +
> + DEBUG ((DEBUG_INFO, "%a: Entry.\n", __FUNCTION__));
> +
> + GetLanConfigReps = NULL;
> + AlreadyCached = FALSE;
> + if (!IsListEmpty (&mBmcIpmiLan)) {
> + AlreadyCached = TRUE;
> + }
> +
> + // Initial the get MAC address request.
> + GetLanConfigReq.SetSelector = 0;
> + GetLanConfigReq.BlockSelector = 0;
> + GetLanConfigReq.ParameterSelector = IpmiLanMacAddress;
> +
> + ExitStatus = EFI_NOT_FOUND;
> + for (ChannelNum =
> IPMI_CHANNEL_NUMBER_IMPLEMENTATION_SPECIFIC_1;
> + ChannelNum <=
> IPMI_CHANNEL_NUMBER_IMPLEMENTATION_SPECIFIC_11;
> + ChannelNum++)
> + {
> + IpmiLanMacAddressSize = 0;
> +
> + // Check if the IPMI channel information is already cached.
> + Status = EFI_NOT_FOUND;
> + if (AlreadyCached) {
> + Status = CheckCachedIpmiLanMac ((UINT8)ChannelNum,
> &CachedIpmiLanChannel);
> + }
> +
> + if (Status == EFI_SUCCESS) {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Got cached IPMI LAN
> info.\n"));
> + IpmiLanMacAddressSize = 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 = App,
> Command = 0x42 to channel %d\n", ChannelNum));
> + GetChanelInfoRequest.ChannelNumber.Bits.ChannelNo =
> (UINT8)ChannelNum;
> + Status = IpmiGetChannelInfo (
> + &GetChanelInfoRequest,
> + &GetChanelInfoResponse,
> + &ResponseDataSize
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, " - Fails to send command.\n",
> ChannelNum));
> + continue;
> + }
> +
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " - Response data size =
> 0x%x\n", ResponseDataSize));
> + if ((GetChanelInfoResponse.CompletionCode !=
> IPMI_COMP_CODE_NORMAL) || (ResponseDataSize == 0)) {
> + DEBUG ((DEBUG_ERROR, " - Command returned fail: 0x%x.\n",
> GetChanelInfoResponse.CompletionCode));
> + continue;
> + }
> +
> + DEBUG ((
> + DEBUG_REDFISH_HOST_INTERFACE,
> + " - Channel protocol = 0x%x, Media = 0x%x\n",
> + GetChanelInfoResponse.ProtocolType.Bits.ChannelProtocolType,
> + GetChanelInfoResponse.MediumType.Bits.ChannelMediumType
> + ));
> +
> + if (GetChanelInfoResponse.ChannelNumber.Bits.ChannelNo !=
> ChannelNum) {
> + DEBUG ((
> + DEBUG_ERROR,
> + " - ChannelNumber = %d in the response which is not macthed to the
> request.\n",
> + GetChanelInfoResponse.ChannelNumber.Bits.ChannelNo
> + ));
> + continue;
> + }
> +
> + if ((GetChanelInfoResponse.MediumType.Bits.ChannelMediumType ==
> IPMI_CHANNEL_MEDIA_TYPE_802_3_LAN) &&
> + (GetChanelInfoResponse.ProtocolType.Bits.ChannelProtocolType ==
> IPMI_CHANNEL_PROTOCOL_TYPE_IPMB_1_0))
> + {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " - Channel %d is a LAN
> device!\n", ChannelNum));
> +
> + ResponseDataSize = sizeof
> (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE) +
> + sizeof (IPMI_LAN_MAC_ADDRESS);
> + if (GetLanConfigReps == NULL) {
> + GetLanConfigReps =
> + (IPMI_GET_LAN_CONFIGURATION_PARAMETERS_RESPONSE
> *)AllocateZeroPool (ResponseDataSize);
> + if (GetLanConfigReps == NULL) {
> + DEBUG ((DEBUG_ERROR, " Allocate memory failed for getting MAC
> address.\n"));
> + continue;
> + }
> + }
> +
> + GetLanConfigReq.ChannelNumber.Bits.ChannelNo =
> (UINT8)ChannelNum;
> + GetLanConfigReps->CompletionCode =
> IPMI_COMP_CODE_UNSPECIFIED;
> + Status = IpmiGetLanConfigurationParameters (
> + &GetLanConfigReq,
> + GetLanConfigReps,
> + &ResponseDataSize
> + );
> + if (EFI_ERROR (Status) || (GetLanConfigReps->CompletionCode !=
> IPMI_COMP_CODE_NORMAL)) {
> + DEBUG ((
> + DEBUG_ERROR,
> + " Fails to get MAC address of channel %d, CompletionCode =
> %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 = sizeof (IPMI_LAN_MAC_ADDRESS);
> + CopyMem ((VOID *)&IpmiLanChannelMacAddress.Addr, (VOID
> *)(GetLanConfigReps + 1), IpmiLanMacAddressSize);
> + }
> + }
> + }
> +
> + if (IpmiLanMacAddressSize != 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 != UsbNicInfo->MacAddressSize) ||
> + (CompareMem (
> + (VOID *)UsbNicInfo->MacAddress,
> + (VOID *)&IpmiLanChannelMacAddress.Addr,
> + IpmiLanMacAddressSize - 1
> + ) != 0) ||
> + (IpmiLanChannelMacAddress.Addr[IpmiLanMacAddressSize - 1] !=
> + *(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 = (UINT8)ChannelNum;
> + UsbNicInfo->IsExposedByBmc = TRUE;
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address is
> matched.\n"));
> + ExitStatus = EFI_SUCCESS;
> + break;
> + }
> + }
> +
> + if (GetLanConfigReps != 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 == NULL) {
> + return NULL;
> + }
> +
> + while (TRUE) {
> + ThisDevicePath = NextDevicePathNode (ThisDevicePath);
> + if (IsDevicePathEnd (ThisDevicePath)) {
> + return NULL;
> + }
> +
> + if ((ThisDevicePath->Type == MESSAGING_DEVICE_PATH) &&
> (ThisDevicePath->SubType == 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 =
> + ConvertDevicePathToText (UsbDevicePath, FALSE, FALSE); DEBUG
> + ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr)); FreePool
> + (DevicePathStr);
>
> It would be better to consider the case when ConvertDevicePathToText()
> returns NULL pointer.
>
> +
> + BufferSize = 0;
> + HandleBuffer = NULL;
> + *UsbIo = NULL;
> + Status = gBS->LocateHandle (
> + ByProtocol,
> + &gEfiUsbIoProtocolGuid,
> + NULL,
> + &BufferSize,
> + NULL
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " %d UsbIo protocol
> instances.\n", BufferSize/sizeof (EFI_HANDLE)));
> + HandleBuffer = AllocateZeroPool (BufferSize);
> + if (HandleBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, " Falied to allocate buffer for the
> handles.\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = 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 = 0; Index < (BufferSize/sizeof (EFI_HANDLE)); Index++) {
> + Status = 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 = ConvertDevicePathToText (ThisDevicePath, FALSE,
> FALSE);
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr));
> + FreePool (DevicePathStr);
>
> It would be better to consider the case when ConvertDevicePathToText()
> returns NULL pointer.
>
> Thanks,
> Nickle
>
> +
> + Status = EFI_NOT_FOUND;
> +
> + // Search for the starting MSG_USB_DP node.
> + ThisUsbDevicePath = UsbDevicePath;
> + if ((DevicePathType (ThisUsbDevicePath) != MESSAGING_DEVICE_PATH)
> ||
> + (DevicePathSubType (ThisUsbDevicePath) != MSG_USB_DP))
> + {
> + ThisUsbDevicePath = UsbNicGetNextMsgUsbDp (ThisUsbDevicePath);
> + if (ThisUsbDevicePath == NULL) {
> + continue;
> + }
> + }
> +
> + if ((DevicePathType (ThisDevicePath) != MESSAGING_DEVICE_PATH) ||
> + (DevicePathSubType (ThisDevicePath) != MSG_USB_DP))
> + {
> + ThisDevicePath = UsbNicGetNextMsgUsbDp (ThisDevicePath);
> + if (ThisDevicePath == NULL) {
> + continue;
> + }
> + }
> +
> + // Search for the ending MSG_USB_DP node.
> + ThisDevicePathEnd = ThisDevicePath;
> + ThisUsbDevicePathEnd = ThisUsbDevicePath;
> + while (TRUE) {
> + TempDevicePath = UsbNicGetNextMsgUsbDp (ThisDevicePathEnd);
> + if (TempDevicePath == NULL) {
> + break;
> + }
> +
> + ThisDevicePathEnd = TempDevicePath;
> + }
> +
> + while (TRUE) {
> + TempDevicePath = UsbNicGetNextMsgUsbDp (ThisUsbDevicePathEnd);
> + if (TempDevicePath == NULL) {
> + break;
> + }
> +
> + ThisUsbDevicePathEnd = TempDevicePath;
> + }
> +
> + // Compare these two device paths
> + Length = (UINT16)((UINTN)(UINT8 *)ThisDevicePathEnd +
> DevicePathNodeLength (ThisDevicePathEnd) - (UINTN)(UINT8
> *)ThisDevicePath);
> + if (Length != ((UINTN)(UINT8 *)ThisUsbDevicePathEnd +
> DevicePathNodeLength (ThisUsbDevicePathEnd) - (UINTN)(UINT8
> *)ThisUsbDevicePath)) {
> + continue;
> + }
> +
> + if (CompareMem (
> + (VOID *)ThisDevicePath,
> + (VOID *)ThisUsbDevicePath,
> + Length
> + ) == 0)
> + {
> + Status = 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 == EFI_SUCCESS) {
> + // Locate UsbIo from this handle.
> + Status = 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 =
> + gBS->HandleProtocol (
> + Handle,
> + &gEfiSimpleNetworkProtocolGuid,
> + (VOID **)&Snp
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, " Failed to locate SNP.\n"));
> + return Status;
> + }
> +
> + Status = 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 = AllocateZeroPool (sizeof
> + (HOST_INTERFACE_BMC_USB_NIC_INFO));
> + if (BmcUsbNic == 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 = Snp->Mode->HwAddressSize;
> + BmcUsbNic->MacAddress = AllocateZeroPool (sizeof (BmcUsbNic-
> >MacAddressSize));
> + if (BmcUsbNic->MacAddress == 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 = 0; Index < BmcUsbNic->MacAddressSize; Index++) {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%02x ",
> + *(BmcUsbNic->MacAddress + Index))); }
> +
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "\n"));
> + BmcUsbNic->ThisSnp = Snp;
> + BmcUsbNic->ThisUsbIo = UsbIo;
> +
> + Status = HostInterfaceIpmiCheckMacAddress (BmcUsbNic); if (Status ==
> + EFI_SUCCESS) {
> + BmcUsbNic->IsExposedByBmc = 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 == 0) || (HandleBuffer == NULL)) {
> + return EFI_INVALID_PARAMETER;
> + }
> +
> + DEBUG ((DEBUG_INFO, "%a: Entry, #%d SNP handle\n", __FUNCTION__,
> + HandleNumer));
> +
> + GotOneUsbNIc = FALSE;
> + for (Index = 0; Index < HandleNumer; Index++) {
> + Status = 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 == MESSAGING_DEVICE_PATH) && (DevicePath-
> >SubType == MSG_USB_DP)) {
> + Status = IdentifyUsbNicBmcChannel (*(HandleBuffer + Index),
> DevicePath);
> + if (!EFI_ERROR (Status)) {
> + GotOneUsbNIc = TRUE;
> + break;
> + }
> + }
> +
> + DevicePath = 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 existing
> + 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 = NULL;
> + Status = EFI_SUCCESS;
> + BufferSize = 0;
> +
> + Status = gBS->LocateHandle (
> + Registration == NULL ? ByProtocol : ByRegisterNotify,
> + &gEfiSimpleNetworkProtocolGuid,
> + Registration,
> + &BufferSize,
> + NULL
> + );
> + if (Status == EFI_BUFFER_TOO_SMALL) {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " %d SNP protocol
> instances.\n", BufferSize/sizeof (EFI_HANDLE)));
> + HandleBuffer = AllocateZeroPool (BufferSize);
> + if (HandleBuffer == NULL) {
> + DEBUG ((DEBUG_ERROR, " Falied to allocate buffer for the
> handles.\n"));
> + return EFI_OUT_OF_RESOURCES;
> + }
> +
> + Status = gBS->LocateHandle (
> + Registration == NULL ? ByProtocol : ByRegisterNotify,
> + &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 = 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 = RetrievedBmcUsbNicInfo ();
> + if (!EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Install protocol to
> notify the platform Redfish Host Interface information is ready.\n"));
> + Status = 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 function'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 ready.
> + @retval Others Other errors.
> +**/
> +EFI_STATUS
> +RedfishPlatformHostInterfaceNotification (
> + OUT EFI_GUID **InformationReadinessGuid
> + )
> +{
> + EFI_STATUS Status;
> +
> + DEBUG ((DEBUG_INFO, "%a: Entry\n", __FUNCTION__));
> +
> + *InformationReadinessGuid = NULL;
> + InitializeListHead (&mBmcUsbNic);
> + InitializeListHead (&mBmcIpmiLan);
> +
> + //
> + // Check if USB NIC exposed by BMC is already // connected.
> + //
> + Status = CheckBmcUsbNic (NULL);
> + if (!EFI_ERROR (Status)) {
> + return EFI_ALREADY_STARTED;
> + }
> +
> + if (Status == 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 = gBS->CreateEvent (
> + EVT_NOTIFY_SIGNAL,
> + TPL_CALLBACK,
> + PlatformHostInterfaceSnpCallback,
> + NULL,
> + &mPlatformHostInterfaceSnpEvent
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a: Fail to create event for the installation of
> SNP protocol.", __FUNCTION__));
> + return Status;
> + }
> +
> + Status = gBS->RegisterProtocolNotify (
> + &gEfiSimpleNetworkProtocolGuid,
> + mPlatformHostInterfaceSnpEvent,
> + &mPlatformHostInterfaceSnpRegistration
> + );
> + if (EFI_ERROR (Status)) {
> + DEBUG ((DEBUG_ERROR, "%a: Fail to register event for the installation of
> SNP protocol.", __FUNCTION__));
> + return Status;
> + }
> +
> + *InformationReadinessGuid =
> &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
-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#101409): https://edk2.groups.io/g/devel/message/101409
Mute This Topic: https://groups.io/mt/97498499/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-
More information about the edk2-devel-archive
mailing list