1 /** @file
2   PCI/PCIe network interface instace of RedfishPlatformHostInterfaceLib
3 
4   Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
5   (C) Copyright 2020 Hewlett Packard Enterprise Development LP<BR>
6 
7   SPDX-License-Identifier: BSD-2-Clause-Patent
8 
9 **/
10 
11 #include <Uefi.h>
12 #include <Library/BaseLib.h>
13 #include <Library/BaseMemoryLib.h>
14 #include <Library/DebugLib.h>
15 #include <Library/DevicePathLib.h>
16 #include <Library/MemoryAllocationLib.h>
17 #include <Library/PrintLib.h>
18 #include <Library/RedfishHostInterfaceLib.h>
19 #include <Library/UefiLib.h>
20 #include <Library/UefiBootServicesTableLib.h>
21 #include <Library/UefiRuntimeServicesTableLib.h>
22 
23 #include <Pcd/RestExServiceDevicePath.h>
24 #include <Guid/GlobalVariable.h>
25 
26 #define VERBOSE_COLUME_SIZE  (16)
27 
28 REDFISH_OVER_IP_PROTOCOL_DATA  *mRedfishOverIpProtocolData;
29 UINT8 mRedfishProtocolDataSize;
30 
31 /**
32   Get the MAC address of NIC.
33 
34   @param[out] MacAddress      Pointer to retrieve MAC address
35 
36   @retval   EFI_SUCCESS      MAC address is returned in MacAddress
37 
38 **/
39 EFI_STATUS
GetMacAddressInformation(OUT EFI_MAC_ADDRESS * MacAddress)40 GetMacAddressInformation (
41   OUT EFI_MAC_ADDRESS *MacAddress
42   )
43 {
44   MAC_ADDR_DEVICE_PATH                     *Mac;
45   REST_EX_SERVICE_DEVICE_PATH_DATA         *RestExServiceDevicePathData;
46   EFI_DEVICE_PATH_PROTOCOL                 *RestExServiceDevicePath;
47   MAC_ADDR_DEVICE_PATH                     *MacAddressDevicePath;
48 
49   Mac = NULL;
50   RestExServiceDevicePathData  = NULL;
51   RestExServiceDevicePath      = NULL;
52 
53   RestExServiceDevicePathData = (REST_EX_SERVICE_DEVICE_PATH_DATA *)PcdGetPtr(PcdRedfishRestExServiceDevicePath);
54   if (RestExServiceDevicePathData == NULL ||
55       RestExServiceDevicePathData->DevicePathNum == 0 ||
56       !IsDevicePathValid (RestExServiceDevicePathData->DevicePath, 0)) {
57     return EFI_NOT_FOUND;
58   }
59 
60   RestExServiceDevicePath = RestExServiceDevicePathData->DevicePath;
61   if (RestExServiceDevicePathData->DevicePathMatchMode != DEVICE_PATH_MATCH_MAC_NODE) {
62     return EFI_NOT_FOUND;
63   }
64 
65   //
66   // Find Mac DevicePath Node.
67   //
68   while (!IsDevicePathEnd (RestExServiceDevicePath) &&
69          ((DevicePathType (RestExServiceDevicePath) != MESSAGING_DEVICE_PATH) ||
70           (DevicePathSubType (RestExServiceDevicePath) != MSG_MAC_ADDR_DP))) {
71     RestExServiceDevicePath = NextDevicePathNode (RestExServiceDevicePath);
72   }
73 
74   if (!IsDevicePathEnd (RestExServiceDevicePath)) {
75     MacAddressDevicePath = (MAC_ADDR_DEVICE_PATH *)RestExServiceDevicePath;
76     CopyMem ((VOID *)MacAddress, (VOID *)&MacAddressDevicePath->MacAddress, sizeof (EFI_MAC_ADDRESS));
77     return EFI_SUCCESS;
78   }
79   return EFI_NOT_FOUND;
80 }
81 
82 /**
83   Get platform Redfish host interface device descriptor.
84 
85   @param[out] DeviceType        Pointer to retrieve device type.
86   @param[out] DeviceDescriptor  Pointer to retrieve REDFISH_INTERFACE_DATA, caller has to free
87                                 this memory using FreePool().
88   @retval EFI_SUCCESS     Device descriptor is returned successfully in DeviceDescriptor.
89   @retval EFI_NOT_FOUND   No Redfish host interface descriptor provided on this platform.
90   @retval Others          Fail to get device descriptor.
91 **/
92 EFI_STATUS
RedfishPlatformHostInterfaceDeviceDescriptor(OUT UINT8 * DeviceType,OUT REDFISH_INTERFACE_DATA ** DeviceDescriptor)93 RedfishPlatformHostInterfaceDeviceDescriptor (
94   OUT UINT8 *DeviceType,
95   OUT REDFISH_INTERFACE_DATA  **DeviceDescriptor
96 )
97 {
98   EFI_STATUS Status;
99   EFI_MAC_ADDRESS MacAddress;
100   REDFISH_INTERFACE_DATA *RedfishInterfaceData;
101   PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *ThisDeviceDescriptor;
102 
103   RedfishInterfaceData = AllocateZeroPool (sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1);
104   if (RedfishInterfaceData == NULL) {
105     return EFI_OUT_OF_RESOURCES;
106   }
107   RedfishInterfaceData->DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;
108   //
109   // Fill up device type information.
110   //
111   ThisDeviceDescriptor = (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2 *)((UINT8 *)RedfishInterfaceData + 1);
112   ThisDeviceDescriptor->Length = sizeof (PCI_OR_PCIE_INTERFACE_DEVICE_DESCRIPTOR_V2) + 1;
113   Status = GetMacAddressInformation (&MacAddress);
114   if (EFI_ERROR (Status)) {
115     FreePool (RedfishInterfaceData);
116     return EFI_NOT_FOUND;
117   }
118   CopyMem ((VOID *)&ThisDeviceDescriptor->MacAddress, (VOID *)&MacAddress, sizeof (ThisDeviceDescriptor->MacAddress));
119   *DeviceType = REDFISH_HOST_INTERFACE_DEVICE_TYPE_PCI_PCIE_V2;
120   *DeviceDescriptor = RedfishInterfaceData;
121   return EFI_SUCCESS;
122 }
123 /**
124   Get platform Redfish host interface protocol data.
125   Caller should pass NULL in ProtocolRecord to retrive the first protocol record.
126   Then continuously pass previous ProtocolRecord for retrieving the next ProtocolRecord.
127 
128   @param[out] ProtocolRecord     Pointer to retrieve the protocol record.
129                                  caller has to free the new protocol record returned from
130                                  this function using FreePool().
131   @param[in] IndexOfProtocolData The index of protocol data.
132 
133   @retval EFI_SUCCESS     Protocol records are all returned.
134   @retval EFI_NOT_FOUND   No more protocol records.
135   @retval Others          Fail to get protocol records.
136 **/
137 EFI_STATUS
RedfishPlatformHostInterfaceProtocolData(OUT MC_HOST_INTERFACE_PROTOCOL_RECORD ** ProtocolRecord,IN UINT8 IndexOfProtocolData)138 RedfishPlatformHostInterfaceProtocolData (
139   OUT MC_HOST_INTERFACE_PROTOCOL_RECORD **ProtocolRecord,
140   IN UINT8  IndexOfProtocolData
141 )
142 {
143   MC_HOST_INTERFACE_PROTOCOL_RECORD *ThisProtocolRecord;
144 
145   if (mRedfishOverIpProtocolData == 0) {
146     return EFI_NOT_FOUND;
147   }
148   if (IndexOfProtocolData == 0) {
149     //
150     // Return the first Redfish protocol data to caller. We only have
151     // one protocol data in this case.
152     //
153     ThisProtocolRecord = (MC_HOST_INTERFACE_PROTOCOL_RECORD *) AllocatePool (mRedfishProtocolDataSize + sizeof (MC_HOST_INTERFACE_PROTOCOL_RECORD) - 1);
154     ThisProtocolRecord->ProtocolType = MCHostInterfaceProtocolTypeRedfishOverIP;
155     ThisProtocolRecord->ProtocolTypeDataLen = mRedfishProtocolDataSize;
156     CopyMem ((VOID *)&ThisProtocolRecord->ProtocolTypeData, (VOID *)mRedfishOverIpProtocolData, mRedfishProtocolDataSize);
157     *ProtocolRecord = ThisProtocolRecord;
158     return EFI_SUCCESS;
159   }
160   return EFI_NOT_FOUND;
161 }
162 /**
163   Dump IPv4 address.
164 
165   @param[in] Ip IPv4 address
166 **/
167 VOID
InternalDumpIp4Addr(IN EFI_IPv4_ADDRESS * Ip)168 InternalDumpIp4Addr (
169   IN EFI_IPv4_ADDRESS   *Ip
170   )
171 {
172   UINTN                 Index;
173 
174   for (Index = 0; Index < 4; Index++) {
175     DEBUG ((DEBUG_VERBOSE, "%d", Ip->Addr[Index]));
176     if (Index < 3) {
177       DEBUG ((DEBUG_VERBOSE, "."));
178     }
179   }
180 
181   DEBUG ((DEBUG_VERBOSE, "\n"));
182 }
183 /**
184   Dump IPv6 address.
185 
186   @param[in] Ip IPv6 address
187 **/
188 VOID
InternalDumpIp6Addr(IN EFI_IPv6_ADDRESS * Ip)189 InternalDumpIp6Addr (
190   IN EFI_IPv6_ADDRESS   *Ip
191   )
192 {
193   UINTN Index;
194 
195   for (Index = 0; Index < 16; Index++) {
196     if (Ip->Addr[Index] != 0) {
197       DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));
198     }
199     Index++;
200 
201     if (Index > 15) {
202       return;
203     }
204 
205     if (((Ip->Addr[Index] & 0xf0) == 0) && (Ip->Addr[Index - 1] != 0)) {
206       DEBUG ((DEBUG_VERBOSE, "0"));
207     }
208     DEBUG ((DEBUG_VERBOSE, "%x", Ip->Addr[Index]));
209 
210     if (Index < 15) {
211       DEBUG ((DEBUG_VERBOSE, ":"));
212     }
213   }
214   DEBUG ((DEBUG_VERBOSE, "\n"));
215 }
216 /**
217   Dump data
218 
219   @param[in] Data Pointer to data.
220   @param[in] Size size of data to dump.
221 **/
222 VOID
InternalDumpData(IN UINT8 * Data,IN UINTN Size)223 InternalDumpData (
224   IN UINT8  *Data,
225   IN UINTN  Size
226   )
227 {
228   UINTN  Index;
229   for (Index = 0; Index < Size; Index++) {
230     DEBUG ((DEBUG_VERBOSE, "%02x ", (UINTN)Data[Index]));
231   }
232 }
233 /**
234   Dump hex data
235 
236   @param[in] Data Pointer to hex data.
237   @param[in] Size size of hex data to dump.
238 **/
239 VOID
InternalDumpHex(IN UINT8 * Data,IN UINTN Size)240 InternalDumpHex (
241   IN UINT8  *Data,
242   IN UINTN  Size
243   )
244 {
245   UINTN   Index;
246   UINTN   Count;
247   UINTN   Left;
248 
249   Count = Size / VERBOSE_COLUME_SIZE;
250   Left  = Size % VERBOSE_COLUME_SIZE;
251   for (Index = 0; Index < Count; Index++) {
252     InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, VERBOSE_COLUME_SIZE);
253     DEBUG ((DEBUG_VERBOSE, "\n"));
254   }
255 
256   if (Left != 0) {
257     InternalDumpData (Data + Index * VERBOSE_COLUME_SIZE, Left);
258     DEBUG ((DEBUG_VERBOSE, "\n"));
259   }
260 
261   DEBUG ((DEBUG_VERBOSE, "\n"));
262 }
263 /**
264   Dump Redfish over IP protocol data
265 
266   @param[in] RedfishProtocolData     Pointer to REDFISH_OVER_IP_PROTOCOL_DATA
267   @param[in] RedfishProtocolDataSize size of data to dump.
268 **/
269 VOID
DumpRedfishIpProtocolData(IN REDFISH_OVER_IP_PROTOCOL_DATA * RedfishProtocolData,IN UINT8 RedfishProtocolDataSize)270 DumpRedfishIpProtocolData (
271   IN REDFISH_OVER_IP_PROTOCOL_DATA   *RedfishProtocolData,
272   IN UINT8                           RedfishProtocolDataSize
273   )
274 {
275   CHAR16 Hostname[16];
276 
277   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData: \n"));
278   InternalDumpHex ((UINT8 *) RedfishProtocolData, RedfishProtocolDataSize);
279 
280   DEBUG ((DEBUG_VERBOSE, "Parsing as below: \n"));
281 
282   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->ServiceUuid - %g\n", &(RedfishProtocolData->ServiceUuid)));
283 
284   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAssignmentType - %d\n", RedfishProtocolData->HostIpAssignmentType));
285 
286   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddressFormat - %d\n", RedfishProtocolData->HostIpAddressFormat));
287 
288   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpAddress: \n"));
289   if (RedfishProtocolData->HostIpAddressFormat == 0x01) {
290     InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpAddress));
291   } else {
292     InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpAddress));
293   }
294 
295   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->HostIpMask: \n"));
296   if (RedfishProtocolData->HostIpAddressFormat == 0x01) {
297     InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->HostIpMask));
298   } else {
299     InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->HostIpMask));
300   }
301 
302   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpDiscoveryType - %d\n", RedfishProtocolData->RedfishServiceIpDiscoveryType));
303 
304   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddressFormat - %d\n", RedfishProtocolData->RedfishServiceIpAddressFormat));
305 
306   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpAddress: \n"));
307   if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {
308     InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));
309   } else {
310     InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpAddress));
311   }
312 
313   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpMask: \n"));
314   if (RedfishProtocolData->RedfishServiceIpAddressFormat == 0x01) {
315     InternalDumpIp4Addr ((EFI_IPv4_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));
316   } else {
317     InternalDumpIp6Addr ((EFI_IPv6_ADDRESS *) (RedfishProtocolData->RedfishServiceIpMask));
318   }
319 
320   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceIpPort - %d\n", RedfishProtocolData->RedfishServiceIpPort));
321 
322   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceVlanId - %d\n", RedfishProtocolData->RedfishServiceVlanId));
323 
324   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostnameLength - %d\n", RedfishProtocolData->RedfishServiceHostnameLength));
325 
326   AsciiStrToUnicodeStrS((CHAR8 *) RedfishProtocolData->RedfishServiceHostname, Hostname, sizeof (Hostname) / sizeof (Hostname[0]));
327   DEBUG ((DEBUG_VERBOSE, "RedfishProtocolData->RedfishServiceHostname - %s\n", Hostname));
328 }
329 
330 /**
331   Get Redfish host interface protocol data from variale.
332 
333   @param[out] RedfishProtocolData  Pointer to retrieve REDFISH_OVER_IP_PROTOCOL_DATA.
334   @param[out] RedfishProtocolDataSize  Size of REDFISH_OVER_IP_PROTOCOL_DATA.
335 
336   @retval EFI_SUCESS   REDFISH_OVER_IP_PROTOCOL_DATA is returned successfully.
337 **/
338 EFI_STATUS
GetRedfishRecordFromVariable(OUT REDFISH_OVER_IP_PROTOCOL_DATA ** RedfishProtocolData,OUT UINT8 * RedfishProtocolDataSize)339 GetRedfishRecordFromVariable (
340   OUT REDFISH_OVER_IP_PROTOCOL_DATA   **RedfishProtocolData,
341   OUT UINT8 *RedfishProtocolDataSize
342   )
343 {
344   EFI_STATUS                      Status;
345   UINT8                           HostIpAssignmentType;
346   UINTN                           HostIpAssignmentTypeSize;
347   EFI_IPv4_ADDRESS                HostIpAddress;
348   UINTN                           IPv4DataSize;
349   EFI_IPv4_ADDRESS                HostIpMask;
350   EFI_IPv4_ADDRESS                RedfishServiceIpAddress;
351   EFI_IPv4_ADDRESS                RedfishServiceIpMask;
352   UINT16                          RedfishServiceIpPort;
353   UINTN                           IpPortDataSize;
354   UINT8                           HostNameSize;
355   CHAR8                           RedfishHostName[20];
356 
357   if (RedfishProtocolData == NULL || RedfishProtocolDataSize == NULL) {
358     return EFI_INVALID_PARAMETER;
359   }
360 
361   //
362   // 1. Retrieve Address Information from variable.
363   //
364   Status = gRT->GetVariable (
365                   L"HostIpAssignmentType",
366                   &gEmuRedfishServiceGuid,
367                   NULL,
368                   &HostIpAssignmentTypeSize,
369                   &HostIpAssignmentType
370                   );
371   if (EFI_ERROR (Status)) {
372     DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAssignmentType - %r\n", Status));
373     return Status;
374   }
375 
376   IPv4DataSize = sizeof (EFI_IPv4_ADDRESS);
377   if (HostIpAssignmentType == 1 ) {
378     Status = gRT->GetVariable (
379                     L"HostIpAddress",
380                     &gEmuRedfishServiceGuid,
381                     NULL,
382                     &IPv4DataSize,
383                     &HostIpAddress
384                     );
385     if (EFI_ERROR (Status)) {
386       DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpAddress - %r\n", Status));
387       return Status;
388     }
389 
390     Status = gRT->GetVariable (
391                     L"HostIpMask",
392                     &gEmuRedfishServiceGuid,
393                     NULL,
394                     &IPv4DataSize,
395                     &HostIpMask
396                     );
397     if (EFI_ERROR (Status)) {
398       DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable HostIpMask - %r\n", Status));
399       return Status;
400     }
401   }
402 
403   Status = gRT->GetVariable (
404                   L"RedfishServiceIpAddress",
405                   &gEmuRedfishServiceGuid,
406                   NULL,
407                   &IPv4DataSize,
408                   &RedfishServiceIpAddress
409                   );
410   if (EFI_ERROR (Status)) {
411     DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpAddress - %r\n", Status));
412     return Status;
413   }
414 
415   Status = gRT->GetVariable (
416                   L"RedfishServiceIpMask",
417                   &gEmuRedfishServiceGuid,
418                   NULL,
419                   &IPv4DataSize,
420                   &RedfishServiceIpMask
421                   );
422   if (EFI_ERROR (Status)) {
423     DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpMask - %r\n", Status));
424     return Status;
425   }
426 
427   Status = gRT->GetVariable (
428                   L"RedfishServiceIpPort",
429                   &gEmuRedfishServiceGuid,
430                   NULL,
431                   &IpPortDataSize,
432                   &RedfishServiceIpPort
433                   );
434   if (EFI_ERROR (Status)) {
435     DEBUG ((DEBUG_ERROR, "RedfishPlatformDxe: GetVariable RedfishServiceIpPort - %r\n", Status));
436     return Status;
437   }
438 
439   AsciiSPrint (
440     RedfishHostName,
441     sizeof (RedfishHostName),
442     "%d.%d.%d.%d",
443     RedfishServiceIpAddress.Addr[0],
444     RedfishServiceIpAddress.Addr[1],
445     RedfishServiceIpAddress.Addr[2],
446     RedfishServiceIpAddress.Addr[3]
447     );
448 
449   HostNameSize = (UINT8) AsciiStrLen (RedfishHostName) + 1;
450 
451   //
452   // 2. Protocol Data Size.
453   //
454   *RedfishProtocolDataSize = sizeof (REDFISH_OVER_IP_PROTOCOL_DATA) - 1 + HostNameSize;
455 
456   //
457   // 3. Protocol Data.
458   //
459   *RedfishProtocolData = (REDFISH_OVER_IP_PROTOCOL_DATA *) AllocateZeroPool (*RedfishProtocolDataSize);
460   if (*RedfishProtocolData == NULL) {
461     return EFI_OUT_OF_RESOURCES;
462   }
463 
464   CopyGuid (&(*RedfishProtocolData)->ServiceUuid, &gEmuRedfishServiceGuid);
465 
466   (*RedfishProtocolData)->HostIpAssignmentType = HostIpAssignmentType;
467   (*RedfishProtocolData)->HostIpAddressFormat = 1;   // Only support IPv4
468 
469   if (HostIpAssignmentType == 1 ) {
470     (*RedfishProtocolData)->HostIpAddress[0] = HostIpAddress.Addr[0];
471     (*RedfishProtocolData)->HostIpAddress[1] = HostIpAddress.Addr[1];
472     (*RedfishProtocolData)->HostIpAddress[2] = HostIpAddress.Addr[2];
473     (*RedfishProtocolData)->HostIpAddress[3] = HostIpAddress.Addr[3];
474 
475     (*RedfishProtocolData)->HostIpMask[0] = HostIpMask.Addr[0];
476     (*RedfishProtocolData)->HostIpMask[1] = HostIpMask.Addr[1];
477     (*RedfishProtocolData)->HostIpMask[2] = HostIpMask.Addr[2];
478     (*RedfishProtocolData)->HostIpMask[3] = HostIpMask.Addr[3];
479   }
480 
481   (*RedfishProtocolData)->RedfishServiceIpDiscoveryType = 1;  // Use static IP address
482   (*RedfishProtocolData)->RedfishServiceIpAddressFormat = 1;  // Only support IPv4
483 
484   (*RedfishProtocolData)->RedfishServiceIpAddress[0] = RedfishServiceIpAddress.Addr[0];
485   (*RedfishProtocolData)->RedfishServiceIpAddress[1] = RedfishServiceIpAddress.Addr[1];
486   (*RedfishProtocolData)->RedfishServiceIpAddress[2] = RedfishServiceIpAddress.Addr[2];
487   (*RedfishProtocolData)->RedfishServiceIpAddress[3] = RedfishServiceIpAddress.Addr[3];
488 
489   (*RedfishProtocolData)->RedfishServiceIpMask[0] = RedfishServiceIpMask.Addr[0];
490   (*RedfishProtocolData)->RedfishServiceIpMask[1] = RedfishServiceIpMask.Addr[1];
491   (*RedfishProtocolData)->RedfishServiceIpMask[2] = RedfishServiceIpMask.Addr[2];
492   (*RedfishProtocolData)->RedfishServiceIpMask[3] = RedfishServiceIpMask.Addr[3];
493 
494   (*RedfishProtocolData)->RedfishServiceIpPort = RedfishServiceIpPort;
495   (*RedfishProtocolData)->RedfishServiceVlanId = 0xffffffff;
496 
497   (*RedfishProtocolData)->RedfishServiceHostnameLength = HostNameSize;
498   AsciiStrCpyS ((CHAR8 *) ((*RedfishProtocolData)->RedfishServiceHostname), HostNameSize, RedfishHostName);
499 
500   return Status;
501 }
502 
503 /**
504   Construct Redfish host interface protocol data.
505 
506   @param ImageHandle     The image handle.
507   @param SystemTable     The system table.
508 
509   @retval  EFI_SUCEESS  Install Boot manager menu success.
510   @retval  Other        Return error status.
511 
512 **/
513 EFI_STATUS
514 EFIAPI
RedfishPlatformHostInterfaceConstructor(IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE * SystemTable)515 RedfishPlatformHostInterfaceConstructor (
516   IN EFI_HANDLE                            ImageHandle,
517   IN EFI_SYSTEM_TABLE                      *SystemTable
518 )
519 {
520   EFI_STATUS Status;
521 
522   Status = GetRedfishRecordFromVariable (&mRedfishOverIpProtocolData, &mRedfishProtocolDataSize);
523   DEBUG ((DEBUG_INFO, "%a: GetRedfishRecordFromVariable() - %r\n", __FUNCTION__, Status));
524   if (!EFI_ERROR (Status)) {
525     DumpRedfishIpProtocolData (mRedfishOverIpProtocolData, mRedfishProtocolDataSize);
526   }
527   return EFI_SUCCESS;
528 }
529