BZ#:2906 EDK2 EFI Redfish Discover Protocol implementation. Refer to UEFI spec 2.9 section 31.1. Signed-off-by: Abner Chang <abner.chang@hpe.com> Cc: Nickle Wang <nickle.wang@hpe.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Fan Wang <fan.wang@intel.com> Cc: Jiewen Yao <jiewen.yao@intel.com> Reviewed-by: Nickle Wang <nickle.wang@hpe.com>
		
			
				
	
	
		
			119 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			119 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
|   RedfishSmbiosHostInterface.c
 | |
| 
 | |
|   Discover Redfish SMBIOS Host Interface.
 | |
| 
 | |
|   (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
 | |
| 
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #include "RedfishDiscoverInternal.h"
 | |
| 
 | |
| SMBIOS_TABLE_TYPE42  *mType42Record;
 | |
| 
 | |
| /**
 | |
|   The function gets information reported in Redfish Host Interface.
 | |
| 
 | |
|   It simply frees the packet.
 | |
| 
 | |
|   @param[in]  Smbios           SMBIOS protocol.
 | |
|   @param[out] DeviceDescriptor Pointer to REDFISH_INTERFACE_DATA.
 | |
|   @param[out] ProtocolData     Pointer to REDFISH_OVER_IP_PROTOCOL_DATA.
 | |
| 
 | |
|   @retval EFI_SUCCESS    Get host interface succesfully.
 | |
|   @retval Otherwise      Fail to tet host interface.
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| RedfishGetHostInterfaceProtocolData (
 | |
|   IN EFI_SMBIOS_PROTOCOL              *Smbios,
 | |
|   OUT REDFISH_INTERFACE_DATA          **DeviceDescriptor,
 | |
|   OUT REDFISH_OVER_IP_PROTOCOL_DATA   **ProtocolData
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                        Status;
 | |
|   EFI_SMBIOS_HANDLE                 SmbiosHandle;
 | |
|   EFI_SMBIOS_TABLE_HEADER           *Record;
 | |
|   UINT16                            Offset;
 | |
|   UINT8                             *RecordTmp;
 | |
|   UINT8                             ProtocolLength;
 | |
|   UINT8                             SpecificDataLen;
 | |
| 
 | |
|   if ((Smbios == NULL) || (ProtocolData == NULL)) {
 | |
|     return EFI_INVALID_PARAMETER;
 | |
|   }
 | |
| 
 | |
|   SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
 | |
|   Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
 | |
|   while (!EFI_ERROR (Status) && SmbiosHandle != SMBIOS_HANDLE_PI_RESERVED) {
 | |
|     if (Record->Type == SMBIOS_TYPE_MANAGEMENT_CONTROLLER_HOST_INTERFACE) {
 | |
|       //
 | |
|       // Check Interface Type, should be Network Host Interface = 40h
 | |
|       //
 | |
|       mType42Record = (SMBIOS_TABLE_TYPE42 *) Record;
 | |
|       if (mType42Record->InterfaceType == MCHostInterfaceTypeNetworkHostInterface) {
 | |
|         ASSERT (Record->Length >= 9);
 | |
|         Offset = 5;
 | |
|         RecordTmp = (UINT8 *) Record + Offset;
 | |
|         //
 | |
|         // Get interface specific data length.
 | |
|         //
 | |
|         SpecificDataLen = *RecordTmp;
 | |
|         Offset += 1;
 | |
|         RecordTmp = (UINT8 *) Record + Offset;
 | |
| 
 | |
|         //
 | |
|         // Check Device Type, only PCI/PCIe Network Interface v2 is supported now.
 | |
|         //
 | |
|         if (*RecordTmp == REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2) {
 | |
|           ASSERT (SpecificDataLen == sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1);
 | |
|           *DeviceDescriptor = (REDFISH_INTERFACE_DATA *)RecordTmp;
 | |
|           Offset = Offset + SpecificDataLen;
 | |
|           RecordTmp = (UINT8 *) Record + Offset;
 | |
|           //
 | |
|           // Check Protocol count. if > 1, only use the first protocol.
 | |
|           //
 | |
|           ASSERT (*RecordTmp == 1);
 | |
|           Offset += 1;
 | |
|           RecordTmp = (UINT8 *) Record + Offset;
 | |
|           //
 | |
|           // Check protocol identifier.
 | |
|           //
 | |
|           if (*RecordTmp == MCHostInterfaceProtocolTypeRedfishOverIP) {
 | |
|             Offset += 1;
 | |
|             RecordTmp = (UINT8 *) Record + Offset;
 | |
|             ProtocolLength = *RecordTmp;
 | |
| 
 | |
|             Offset += 1;
 | |
|             RecordTmp = (UINT8 *) Record + Offset;
 | |
| 
 | |
|             //
 | |
|             // This SMBIOS record is invalid, if the length of protocol specific data for
 | |
|             // Redfish Over IP protocol is wrong.
 | |
|             //
 | |
|             if ((*(RecordTmp + 90) + sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1) != ProtocolLength) {
 | |
|               return EFI_SECURITY_VIOLATION;
 | |
|             }
 | |
| 
 | |
|             Offset += ProtocolLength;
 | |
|             //
 | |
|             // This SMBIOS record is invalid, if the length is smaller than the offset.
 | |
|             //
 | |
|             if (Offset > mType42Record->Hdr.Length) {
 | |
|               return EFI_SECURITY_VIOLATION;
 | |
|             }
 | |
|             *ProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *)RecordTmp;
 | |
|             return EFI_SUCCESS;
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|     Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
 | |
|   }
 | |
| 
 | |
|   *ProtocolData = NULL;
 | |
|   return EFI_NOT_FOUND;
 | |
| }
 |