/** @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.
  Copyright (c) 2025, NVIDIA CORPORATION & AFFILIATES. 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.
          FALSE  No, it is not supported.

**/
BOOLEAN
ProbeRedfishCredentialBootstrap (
  VOID
  )
{
  EDKII_REDFISH_AUTH_METHOD           AuthMethod;
  EDKII_REDFISH_CREDENTIAL2_PROTOCOL  *CredentialProtocol;
  CHAR8                               *UserName;
  CHAR8                               *Password;
  BOOLEAN                             ReturnBool;
  EFI_STATUS                          Status;

  DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry\n", __func__));

  ReturnBool = FALSE;
  //
  // Locate HII credential protocol.
  //
  Status = gBS->LocateProtocol (
                  &gEdkIIRedfishCredential2ProtocolGuid,
                  NULL,
                  (VOID **)&CredentialProtocol
                  );
  if (EFI_ERROR (Status)) {
    ASSERT_EFI_ERROR (Status);
    return FALSE;
  }

  Status = CredentialProtocol->GetAuthInfo (
                                 CredentialProtocol,
                                 &AuthMethod,
                                 &UserName,
                                 &Password
                                 );
  if (!EFI_ERROR (Status)) {
    ZeroMem (Password, AsciiStrSize (Password));
    FreePool (Password);
    ZeroMem (UserName, AsciiStrSize (UserName));
    FreePool (UserName);
    ReturnBool = TRUE;
  } else {
    if (Status == EFI_ACCESS_DENIED) {
      // bootstrap credential support was disabled
      ReturnBool = TRUE;
    }
  }

  DEBUG ((
    DEBUG_REDFISH_HOST_INTERFACE,
    "    Redfish Credential Bootstrapping is %a\n",
    ReturnBool ? "supported" : "not supported"
    ));
  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_MANAGEABILITY, "%a: Entry\n", __func__));

  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_MANAGEABILITY, "%a: Entry\n", __func__));

  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) - 1 +
                                                                  HostNameLength
                                                                  );
      if (ThisProtocolRecord == NULL) {
        DEBUG ((DEBUG_ERROR, "    Allocate 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) -1 + 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);
        DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " Service UUID: %g", &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 = PcdGet16 (PcdRedfishServicePort);

      // 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_MANAGEABILITY, "%a: Entry\n", __func__));

  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 the design spec:
      // https://github.com/tianocore/edk2/tree/master/RedfishPkg#platform-with-bmc-and-the-bmc-exposed-usb-network-device
      // 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_MANAGEABILITY, "%a: Entry.\n", __func__));

  GetLanConfigReps = NULL;
  AlreadyCached    = FALSE;
  if (!IsListEmpty (&mBmcIpmiLan)) {
    AlreadyCached = TRUE;
  }

  // Initial the get MAC address request.
  GetLanConfigReq.ChannelNumber.Uint8 = 0;
  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.Uint8          = 0;
      GetChanelInfoRequest.ChannelNumber.Bits.ChannelNo = (UINT8)ChannelNum;
      Status                                            = IpmiGetChannelInfo (
                                                            &GetChanelInfoRequest,
                                                            &GetChanelInfoResponse,
                                                            &ResponseDataSize
                                                            );
      if (EFI_ERROR (Status)) {
        DEBUG ((DEBUG_ERROR, "    - Channel %d 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.
      // https://github.com/tianocore/edk2/tree/master/RedfishPkg#platform-with-bmc-and-the-bmc-exposed-usb-network-device
      // Compare the first five elements of MAC address and the 6th element of MAC address.
      // The 6th element of MAC address must be the 6th element of
      // IPMI channel MAC address minus 1.
      //
      if ((IpmiLanMacAddressSize != UsbNicInfo->MacAddressSize) ||
          (CompareMem (
             (VOID *)UsbNicInfo->MacAddress,
             (VOID *)&IpmiLanChannelMacAddress.Addr,
             IpmiLanMacAddressSize - 1
             ) != 0) ||
          ((IpmiLanChannelMacAddress.Addr[IpmiLanMacAddressSize - 1] - 1) !=
           *(UsbNicInfo->MacAddress + IpmiLanMacAddressSize - 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_MANAGEABILITY, "%a: Entry.\n", __func__));
  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);
  if (DevicePathStr != NULL) {
    DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr));
    FreePool (DevicePathStr);
  } else {
    DEBUG ((DEBUG_ERROR, "Failed to convert device path.\n"));
    return EFI_INVALID_PARAMETER;
  }

  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);
    if (DevicePathStr != NULL) {
      DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "%s\n", DevicePathStr));
      FreePool (DevicePathStr);
    } else {
      DEBUG ((DEBUG_ERROR, "Failed to convert device path on #%d instance of UsbIo.\n", Index));
      continue;
    }

    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 has MAC address and internet
  protocol device path installed. (Only support IPv4)

  @param[in] UsbDevicePath     USB device path.

  @retval EFI_SUCCESS          Yes, this is IPv4 SNP handle
  @retval EFI_NOT_FOUND        No, this is not IPv4 SNP handle

**/
EFI_STATUS
IdentifyNetworkMessageDevicePath (
  IN EFI_DEVICE_PATH_PROTOCOL  *UsbDevicePath
  )
{
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;

  DevicePath = UsbDevicePath;
  while (TRUE) {
    DevicePath = NextDevicePathNode (DevicePath);
    if (IsDevicePathEnd (DevicePath)) {
      DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "MAC address device path is not found on this handle.\n"));
      break;
    }

    if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_MAC_ADDR_DP)) {
      DevicePath = NextDevicePathNode (DevicePath); // Advance to next device path protocol.
      if (IsDevicePathEnd (DevicePath)) {
        DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "IPv4 device path is not found on this handle.\n"));
        break;
      }

      if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_IPv4_DP)) {
        return EFI_SUCCESS;
      }

      break;
    }
  }

  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_MANAGEABILITY, "%a: Entry.\n", __func__));
  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     = AllocatePool (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                   GotBmcUsbNic;
  CHAR16                    *DevicePathStr;

  if ((HandleNumer == 0) || (HandleBuffer == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, #%d SNP handle\n", __func__, HandleNumer));

  GotBmcUsbNic = FALSE;
  for (Index = 0; Index < HandleNumer; Index++) {
    DEBUG ((DEBUG_MANAGEABILITY, "    Locate device path on handle 0x%08x\n", *(HandleBuffer + Index)));
    Status = gBS->HandleProtocol (
                    *(HandleBuffer + Index),
                    &gEfiDevicePathProtocolGuid,
                    (VOID **)&DevicePath
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "    Failed to locate device path on %d handle.\n", Index));
      continue;
    }

    DevicePathStr = ConvertDevicePathToText (DevicePath, FALSE, FALSE);
    if (DevicePathStr != NULL) {
      DEBUG ((DEBUG_MANAGEABILITY, "    Device path: %s\n", DevicePathStr));
      FreePool (DevicePathStr);
    }

    // Check if this is an BMC exposed USB NIC device.
    while (TRUE) {
      if ((DevicePath->Type == MESSAGING_DEVICE_PATH) && (DevicePath->SubType == MSG_USB_DP)) {
        Status = IdentifyNetworkMessageDevicePath (DevicePath);
        if (!EFI_ERROR (Status)) {
          Status = IdentifyUsbNicBmcChannel (*(HandleBuffer + Index), DevicePath);
          if (!EFI_ERROR (Status)) {
            GotBmcUsbNic = TRUE;
          }
        }

        break; // Advance to next SNP handle.
      }

      DevicePath = NextDevicePathNode (DevicePath);
      if (IsDevicePathEnd (DevicePath)) {
        break;
      }
    }
  }

  if (GotBmcUsbNic) {
    return EFI_SUCCESS;
  }

  DEBUG ((DEBUG_MANAGEABILITY, "No BMC USB NIC found on SNP handles\n"));
  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_MANAGEABILITY, "%a: Entry, the registration key - 0x%08x.\n", __func__, Registration));

  Handle       = NULL;
  HandleBuffer = NULL;
  Status       = EFI_SUCCESS;

  do {
    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 instance(s).\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)) {
      if (Registration != NULL) {
        DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, "    No more newly installed SNP protocol for this registration - %r.\n", Status));
        return EFI_SUCCESS;
      }

      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);
  } while (Registration != NULL);

  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_MANAGEABILITY, "%a: Entry.\n", __func__));

  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_MANAGEABILITY, "%a: Entry\n", __func__));

  *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", __func__));

    // 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.", __func__));
      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.", __func__));
      return Status;
    }

    *InformationReadinessGuid = &mPlatformHostInterfaceBmcUsbNicReadinessGuid;
    return EFI_SUCCESS;
  }

  DEBUG ((DEBUG_ERROR, "%a: Something wrong when look for BMC USB NIC.\n", __func__));
  return Status;
}

/**
  Get USB device serial number.

  @param[out] SerialNumber    Pointer to retrieve complete serial number.
                              It is the responsibility of the caller to free the allocated
                              memory for serial number.
  @retval EFI_SUCCESS         Serial number is returned.
  @retval Others              Failed to get the serial number
**/
EFI_STATUS
RedfishPlatformHostInterfaceSerialNumber (
  OUT CHAR8  **SerialNumber
  )
{
  return EFI_UNSUPPORTED;
}
