RedfishPkg/RedfishDiscoverDxe: Install protocol on each network interface

BZ 4037:
Install EFI_DISCOVER_PROTOCOL on each network interface.

This fixes the issue that causes the high-level Redfish driver
on the network interface is stopped when:
1. EFI_DISCOVER_PROTOCOL is reinstalled on a new-found network
   interface, or
2. EFI_DISCOVER_PROTOCOL is stopped on the network interface
   other than the one which is used to communicate with Redfish
   service.

Cc: Nickle Wang <nickle@csie.io>
Cc: Igor Kulchytskyy <igork@ami.com>
Signed-off-by: Abner Chang <abner.chang@amd.com>
Reviewed-by: Nickle Wang <nickle@csie.io>
Reviewed-by: Igor Kulchytskyy <igork@ami.com>
This commit is contained in:
Abner Chang 2022-08-30 12:15:47 +08:00 committed by mergify[bot]
parent 39596c41c8
commit f7da805b50
2 changed files with 79 additions and 50 deletions

View File

@ -3,6 +3,7 @@
The implementation of EFI Redfidh Discover Protocol. The implementation of EFI Redfidh Discover Protocol.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@ -23,8 +24,6 @@ EFI_GUID mRedfishDiscoverTcp4InstanceGuid = EFI_REDFISH_DISCOVER_TCP4_INSTANC
EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID; EFI_GUID mRedfishDiscoverTcp6InstanceGuid = EFI_REDFISH_DISCOVER_TCP6_INSTANCE_GUID;
EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID; EFI_GUID mRedfishDiscoverRestExInstanceGuid = EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;
EFI_HANDLE EfiRedfishDiscoverProtocolHandle = NULL;
EFI_STATUS EFI_STATUS
EFIAPI EFIAPI
Tcp4GetSubnetInfo ( Tcp4GetSubnetInfo (
@ -325,6 +324,38 @@ GetTargetNetworkInterfaceInternal (
return NULL; return NULL;
} }
/**
This function searches EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL
instance with the given Controller handle.
@param[in] ControllerHandle The controller handle associated with network interface.
@retval Non-NULL EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL is returned.
@retval NULL Non of EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL instance is returned.
**/
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *
GetTargetNetworkInterfaceInternalByController (
IN EFI_HANDLE ControllerHandle
)
{
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) {
if (ThisNetworkInterface->OpenDriverControllerHandle == ControllerHandle) {
return ThisNetworkInterface;
}
if (IsNodeAtEnd (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry)) {
return NULL;
}
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetNextNode (&mEfiRedfishDiscoverNetworkInterface, &ThisNetworkInterface->Entry);
}
return NULL;
}
/** /**
This function validate if target network interface is ready for discovering This function validate if target network interface is ready for discovering
Redfish service. Redfish service.
@ -1619,29 +1650,30 @@ BuildupNetworkInterface (
EFI_OPEN_PROTOCOL_BY_DRIVER EFI_OPEN_PROTOCOL_BY_DRIVER
); );
if (!EFI_ERROR (Status)) { if (!EFI_ERROR (Status)) {
if ((EfiRedfishDiscoverProtocolHandle == NULL) && if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
(gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx) && // Install Redfish Discover Protocol when EFI REST EX protcol is discovered.
!IsListEmpty (&mEfiRedfishDiscoverNetworkInterface) // This ensures EFI REST EX is ready while the consumer of EFI_REDFISH_DISCOVER_PROTOCOL
) // acquires Redfish serivce over network interface.
{
// Install the fisrt Redfish Discover Protocol when EFI REST EX protcol is discovered.
// This ensures EFI REST EX is ready while EFI_REDFISH_DISCOVER_PROTOCOL consumer acquires
// Redfish serivce over network interface.
Status = gBS->InstallProtocolInterface ( if (!NewNetworkInterfaceInstalled) {
&EfiRedfishDiscoverProtocolHandle, NetworkInterface = GetTargetNetworkInterfaceInternalByController (ControllerHandle);
&gEfiRedfishDiscoverProtocolGuid, if (NetworkInterface == NULL) {
EFI_NATIVE_INTERFACE, DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by ControllerHandle\n", __FUNCTION__));
(VOID *)&mRedfishDiscover return Status;
); }
} else if ((EfiRedfishDiscoverProtocolHandle != NULL) && NewNetworkInterfaceInstalled) { }
Status = gBS->ReinstallProtocolInterface (
EfiRedfishDiscoverProtocolHandle, NewNetworkInterfaceInstalled = FALSE;
&gEfiRedfishDiscoverProtocolGuid, NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
(VOID *)&mRedfishDiscover, Status = gBS->InstallProtocolInterface (
(VOID *)&mRedfishDiscover &NetworkInterface->EfiRedfishDiscoverProtocolHandle,
); &gEfiRedfishDiscoverProtocolGuid,
NewNetworkInterfaceInstalled = FALSE; EFI_NATIVE_INTERFACE,
(VOID *)&mRedfishDiscover
);
if (EFI_ERROR (Status)) {
DEBUG ((DEBUG_ERROR, "%a: Fail to install EFI_REDFISH_DISCOVER_PROTOCOL\n", __FUNCTION__));
}
} }
} }
@ -1724,6 +1756,7 @@ StopServiceOnNetworkInterface (
EFI_STATUS Status; EFI_STATUS Status;
VOID *Interface; VOID *Interface;
EFI_TPL OldTpl; EFI_TPL OldTpl;
EFI_HANDLE DiscoverProtocolHandle;
EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface; EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *ThisNetworkInterface;
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance; EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL *RestExInstance;
@ -1743,8 +1776,11 @@ StopServiceOnNetworkInterface (
ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface); ThisNetworkInterface = (EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode (&mEfiRedfishDiscoverNetworkInterface);
while (TRUE) { while (TRUE) {
if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) { if (ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == ControllerHandle) {
DiscoverProtocolHandle = ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
//
// Close protocol and destroy service.
//
Status = CloseProtocolService ( Status = CloseProtocolService (
// Close protocol and destroy service.
ThisBindingProtocol, ThisBindingProtocol,
ControllerHandle, ControllerHandle,
&gRequiredProtocol[Index], &gRequiredProtocol[Index],
@ -1756,17 +1792,18 @@ StopServiceOnNetworkInterface (
} }
gBS->RestoreTPL (OldTpl); gBS->RestoreTPL (OldTpl);
// Reinstall Redfish Discover protocol to notify network
// interface change.
Status = gBS->ReinstallProtocolInterface ( //
EfiRedfishDiscoverProtocolHandle, // Disconnect EFI Redfish discover driver controller to notify the
&gEfiRedfishDiscoverProtocolGuid, // clinet which uses .EFI Redfish discover protocol.
(VOID *)&mRedfishDiscover, //
(VOID *)&mRedfishDiscover if (DiscoverProtocolHandle != NULL) {
); gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
if (EFI_ERROR (Status)) { Status = gBS->UninstallProtocolInterface (
DEBUG ((DEBUG_ERROR, "%a: Reinstall gEfiRedfishDiscoverProtocolGuid fail.", __FUNCTION__)); DiscoverProtocolHandle,
&gEfiRedfishDiscoverProtocolGuid,
(VOID *)&mRedfishDiscover
);
} }
return Status; return Status;
@ -2032,20 +2069,5 @@ RedfishDiscoverUnload (
StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle); StopServiceOnNetworkInterface (&gRedfishDiscoverDriverBinding, ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle);
} }
// Disconnect EFI Redfish discover driver controller to notify the
// clinet which uses .EFI Redfish discover protocol.
if (EfiRedfishDiscoverProtocolHandle != NULL) {
//
// Notify user EFI_REDFISH_DISCOVER_PROTOCOL is unloaded.
//
gBS->DisconnectController (EfiRedfishDiscoverProtocolHandle, NULL, NULL);
Status = gBS->UninstallProtocolInterface (
EfiRedfishDiscoverProtocolHandle,
&gEfiRedfishDiscoverProtocolGuid,
(VOID *)&mRedfishDiscover
);
}
return Status; return Status;
} }

View File

@ -2,6 +2,7 @@
This file defines the EFI Redfish Discover Protocol interface. This file defines the EFI Redfish Discover Protocol interface.
(C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR> (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
Copyright (c) 2022, AMD Incorporated. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent SPDX-License-Identifier: BSD-2-Clause-Patent
@ -107,6 +108,12 @@ typedef struct {
///< NETWORK_INTERFACE_PROTOCOL_TYPE. ///< NETWORK_INTERFACE_PROTOCOL_TYPE.
REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL NetworkInterfaceProtocolInfo; ///< Network interface protocol information. REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL NetworkInterfaceProtocolInfo; ///< Network interface protocol information.
EFI_HANDLE RestExHandle; ///< REST EX handle associated with this network interface. EFI_HANDLE RestExHandle; ///< REST EX handle associated with this network interface.
//
// EFI_REDFISH_DISCOVER_PROTOCOL instance installed
// on this network interface.
//
EFI_HANDLE EfiRedfishDiscoverProtocolHandle; ///< EFI_REDFISH_DISCOVER_PROTOTOCOL instance installed
///< on this network interface.
} EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL; } EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL;
// //