RedfishPkg/BmcUsbNicLib: Update BMC USB NIC searching algorithm

Update BMC USB NIC searching algorithm for IPv4 only.

Signed-off-by: Abner Chang <abner.chang@amd.com>
Co-authored-by: Mike Maslenkin <mike.maslenkin@gmail.com>
Cc: Nickle Wang <nicklew@nvidia.com>
Cc: Igor Kulchytskyy <igork@ami.com>
Cc: Mike Maslenkin <mike.maslenkin@gmail.com>
Reviewed-by: Igor Kulchytskyy <igork@ami.com>
Reviewed-by: Nickle Wang <nicklew@nvidia.com>
Acked-by: Mike Maslenkin <mike.maslenkin@gmail.com>
This commit is contained in:
Abner Chang 2023-11-22 21:41:32 +08:00 committed by mergify[bot]
parent 3e133f730b
commit a3b56f93e1
1 changed files with 130 additions and 62 deletions

View File

@ -368,7 +368,9 @@ RetrievedBmcUsbNicInfo (
));
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.
// 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;
@ -729,8 +731,10 @@ HostInterfaceIpmiCheckMacAddress (
//
// According to design spec in Readme file under RedfishPkg.
// Compare the first five MAC address and
// the 6th MAC address.
// 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 (
@ -738,8 +742,8 @@ HostInterfaceIpmiCheckMacAddress (
(VOID *)&IpmiLanChannelMacAddress.Addr,
IpmiLanMacAddressSize - 1
) != 0) ||
(IpmiLanChannelMacAddress.Addr[IpmiLanMacAddressSize - 1] !=
*(UsbNicInfo->MacAddress + IpmiLanMacAddressSize - 1) - 1)
((IpmiLanChannelMacAddress.Addr[IpmiLanMacAddressSize - 1] - 1) !=
*(UsbNicInfo->MacAddress + IpmiLanMacAddressSize - 1))
)
{
DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address is not matched.\n"));
@ -962,6 +966,49 @@ UsbNicSearchUsbIo (
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.
@ -1025,7 +1072,7 @@ IdentifyUsbNicBmcChannel (
(VOID *)&Snp->Mode->CurrentAddress,
BmcUsbNic->MacAddressSize
);
DEBUG ((DEBUG_REDFISH_HOST_INTERFACE, " MAC address (in size %d) for this SNP instance:\n ", 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)));
}
@ -1068,7 +1115,8 @@ CheckBmcUsbNicOnHandles (
UINTN Index;
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
BOOLEAN GotOneUsbNIc;
BOOLEAN GotBmcUsbNic;
CHAR16 *DevicePathStr;
if ((HandleNumer == 0) || (HandleBuffer == NULL)) {
return EFI_INVALID_PARAMETER;
@ -1076,26 +1124,37 @@ CheckBmcUsbNicOnHandles (
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, #%d SNP handle\n", __func__, HandleNumer));
GotOneUsbNIc = FALSE;
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 SNP on %d handle.\n", Index));
DEBUG ((DEBUG_ERROR, " Failed to locate device path on %d handle.\n", __func__, 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 = IdentifyUsbNicBmcChannel (*(HandleBuffer + Index), DevicePath);
Status = IdentifyNetworkMessageDevicePath (DevicePath);
if (!EFI_ERROR (Status)) {
GotOneUsbNIc = TRUE;
break;
Status = IdentifyUsbNicBmcChannel (*(HandleBuffer + Index), DevicePath);
if (!EFI_ERROR (Status)) {
GotBmcUsbNic = TRUE;
}
}
break; // Advance to next SNP handle.
}
DevicePath = NextDevicePathNode (DevicePath);
@ -1105,10 +1164,11 @@ CheckBmcUsbNicOnHandles (
}
}
if (GotOneUsbNIc) {
if (GotBmcUsbNic) {
return EFI_SUCCESS;
}
DEBUG ((DEBUG_MANAGEABILITY, "No BMC USB NIC found on SNP handles\n"));
return EFI_NOT_FOUND;
}
@ -1139,62 +1199,70 @@ CheckBmcUsbNic (
DEBUG ((DEBUG_MANAGEABILITY, "%a: Entry, the registration key - 0x%08x.\n", __func__, Registration));
Handle = NULL;
Status = EFI_SUCCESS;
BufferSize = 0;
Handle = NULL;
Status = EFI_SUCCESS;
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;
}
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)) {
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
Status = gBS->LocateHandle (
Registration == NULL ? ByProtocol : ByRegisterNotify,
&gEfiSimpleNetworkProtocolGuid,
Registration,
&BufferSize,
HandleBuffer
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, " Install protocol fail %r.\n", 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);
FreePool (HandleBuffer);
} while (Registration != NULL);
return Status;
}