Reviewed-by:  Igor Kulchytskyy <ig...@ami.com>

Thank you,
Igor

-----Original Message-----
From: abner.ch...@amd.com <abner.ch...@amd.com>
Sent: Thursday, September 01, 2022 12:02 AM
To: devel@edk2.groups.io
Cc: Nickle Wang <nic...@csie.io>; Igor Kulchytskyy <ig...@ami.com>
Subject: [EXTERNAL] [PATCH V2] RedfishPkg/RedfishDiscoverDxe: Install 
EFI_DISCOVER_PROTOCOL on each network interface


**CAUTION: The e-mail below is from an external source. Please exercise caution 
before opening attachments, clicking links, or following guidance.**

From: Abner Chang <abner.ch...@amd.com>

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 <nic...@csie.io>
Cc: Igor Kulchytskyy <ig...@ami.com>
Signed-off-by: Abner Chang <abner.ch...@amd.com>
---
 .../RedfishDiscoverInternal.h                 |   7 +
 .../RedfishDiscoverDxe/RedfishDiscoverDxe.c   | 140 ++++++++++--------
 2 files changed, 88 insertions(+), 59 deletions(-)

diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h 
b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
index 4d1319b2641..04fa09e1cc2 100644
--- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
+++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverInternal.h
@@ -2,6 +2,7 @@
   This file defines the EFI Redfish Discover Protocol interface.

   (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+  Copyright (c) 2022, AMD Incorporated. All rights reserved.

   SPDX-License-Identifier: BSD-2-Clause-Patent

@@ -107,6 +108,12 @@ typedef struct {
                                                                                
///< NETWORK_INTERFACE_PROTOCOL_TYPE.
   REDFISH_DISCOVER_NETWORK_INTERFACE_PROTOCOL    NetworkInterfaceProtocolInfo; 
///< Network interface protocol information.
   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;

 //
diff --git a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c 
b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
index bf50c78c928..a271f6e942d 100644
--- a/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
+++ b/RedfishPkg/RedfishDiscoverDxe/RedfishDiscoverDxe.c
@@ -3,6 +3,7 @@
   The implementation of EFI Redfidh Discover Protocol.

   (C) Copyright 2021 Hewlett Packard Enterprise Development LP<BR>
+  Copyright (c) 2022, AMD Incorporated. All rights reserved.

   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  mRedfishDiscoverRestExInstanceGuid = 
EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_GUID;

-EFI_HANDLE  EfiRedfishDiscoverProtocolHandle = NULL;
-
 EFI_STATUS
 EFIAPI
 Tcp4GetSubnetInfo (
@@ -325,6 +324,38 @@ GetTargetNetworkInterfaceInternal (
   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
   Redfish service.
@@ -1619,29 +1650,30 @@ BuildupNetworkInterface (
                       EFI_OPEN_PROTOCOL_BY_DRIVER
                       );
       if (!EFI_ERROR (Status)) {
-        if ((EfiRedfishDiscoverProtocolHandle == NULL) &&
-            (gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx) &&
-            !IsListEmpty (&mEfiRedfishDiscoverNetworkInterface)
-            )
-        {
-          // 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 (
-                          &EfiRedfishDiscoverProtocolHandle,
-                          &gEfiRedfishDiscoverProtocolGuid,
-                          EFI_NATIVE_INTERFACE,
-                          (VOID *)&mRedfishDiscover
-                          );
-        } else if ((EfiRedfishDiscoverProtocolHandle != NULL) && 
NewNetworkInterfaceInstalled) {
-          Status = gBS->ReinstallProtocolInterface (
-                          EfiRedfishDiscoverProtocolHandle,
-                          &gEfiRedfishDiscoverProtocolGuid,
-                          (VOID *)&mRedfishDiscover,
-                          (VOID *)&mRedfishDiscover
-                          );
-          NewNetworkInterfaceInstalled = FALSE;
+        if ((gRequiredProtocol[Index].ProtocolType == ProtocolTypeRestEx)) {
+          // Install Redfish Discover Protocol when EFI REST EX protcol is 
discovered.
+          // This ensures EFI REST EX is ready while the consumer of 
EFI_REDFISH_DISCOVER_PROTOCOL
+          // acquires Redfish serivce over network interface.
+
+          if (!NewNetworkInterfaceInstalled) {
+            NetworkInterface = GetTargetNetworkInterfaceInternalByController 
(ControllerHandle);
+            if (NetworkInterface == NULL) {
+              DEBUG ((DEBUG_ERROR, "%a: Can't find network interface by 
ControllerHandle\n", __FUNCTION__));
+              return Status;
+            }
+          }
+
+          NewNetworkInterfaceInstalled                       = FALSE;
+          NetworkInterface->EfiRedfishDiscoverProtocolHandle = NULL;
+          Status                                             = 
gBS->InstallProtocolInterface (
+                                                                      
&NetworkInterface->EfiRedfishDiscoverProtocolHandle,
+                                                                      
&gEfiRedfishDiscoverProtocolGuid,
+                                                                      
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;
   VOID                                             *Interface;
   EFI_TPL                                          OldTpl;
+  EFI_HANDLE                                       DiscoverProtocolHandle;
   EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL  *ThisNetworkInterface;
   EFI_REDFISH_DISCOVER_REST_EX_INSTANCE_INTERNAL   *RestExInstance;

@@ -1743,30 +1776,34 @@ StopServiceOnNetworkInterface (
         ThisNetworkInterface = 
(EFI_REDFISH_DISCOVER_NETWORK_INTERFACE_INTERNAL *)GetFirstNode 
(&mEfiRedfishDiscoverNetworkInterface);
         while (TRUE) {
           if 
(ThisNetworkInterface->NetworkInterfaceProtocolInfo.ProtocolControllerHandle == 
ControllerHandle) {
-            Status = CloseProtocolService (
-                       // Close protocol and destroy service.
-                       ThisBindingProtocol,
-                       ControllerHandle,
-                       &gRequiredProtocol[Index],
-                       ThisNetworkInterface->OpenDriverAgentHandle,
-                       ThisNetworkInterface->OpenDriverControllerHandle
-                       );
+            DiscoverProtocolHandle = 
ThisNetworkInterface->EfiRedfishDiscoverProtocolHandle;
+            //
+            // Close protocol and destroy service.
+            //
+            Status                 = CloseProtocolService (
+                                       ThisBindingProtocol,
+                                       ControllerHandle,
+                                       &gRequiredProtocol[Index],
+                                       
ThisNetworkInterface->OpenDriverAgentHandle,
+                                       
ThisNetworkInterface->OpenDriverControllerHandle
+                                       );
             if (!EFI_ERROR (Status)) {
               Status = DestroyRedfishNetwrokInterface (ThisNetworkInterface);
             }

             gBS->RestoreTPL (OldTpl);
-            // Reinstall Redfish Discover protocol to notify network
-            // interface change.
-
-            Status = gBS->ReinstallProtocolInterface (
-                            EfiRedfishDiscoverProtocolHandle,
-                            &gEfiRedfishDiscoverProtocolGuid,
-                            (VOID *)&mRedfishDiscover,
-                            (VOID *)&mRedfishDiscover
-                            );
-            if (EFI_ERROR (Status)) {
-              DEBUG ((DEBUG_ERROR, "%a: Reinstall 
gEfiRedfishDiscoverProtocolGuid fail.", __FUNCTION__));
+
+            //
+            // Disconnect EFI Redfish discover driver controller to notify the
+            // clinet which uses .EFI Redfish discover protocol.
+            //
+            if (DiscoverProtocolHandle != NULL) {
+              gBS->DisconnectController (DiscoverProtocolHandle, NULL, NULL);
+              Status = gBS->UninstallProtocolInterface (
+                              DiscoverProtocolHandle,
+                              &gEfiRedfishDiscoverProtocolGuid,
+                              (VOID *)&mRedfishDiscover
+                              );
             }

             return Status;
@@ -2032,20 +2069,5 @@ RedfishDiscoverUnload (
     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;
 }
--
2.37.1.windows.1

-The information contained in this message may be confidential and proprietary 
to American Megatrends (AMI). This communication is intended to be read only by 
the individual or entity to whom it is addressed or by their designee. If the 
reader of this message is not the intended recipient, you are on notice that 
any distribution of this message, in any form, is strictly prohibited. Please 
promptly notify the sender by reply e-mail or by telephone at 770-246-8600, and 
then delete or destroy all copies of the transmission.


-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#93043): https://edk2.groups.io/g/devel/message/93043
Mute This Topic: https://groups.io/mt/93388097/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to