]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/SnpDxe/Initialize.c
MdeModulePkg: Fix SNP.Initialize() spec conformance issue
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Initialize.c
index 6173058e101fd70114fe8d359ec9f15e1ea52f99..63bdf92f5593a008d292755b2045a63bb130bf00 100644 (file)
@@ -1,8 +1,8 @@
 /** @file\r
                Implementation of initializing a network adapter.\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR> \r
-All rights reserved. This program and the accompanying materials are licensed \r
+Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed \r
 and made available under the terms and conditions of the BSD License which \r
 accompanies this distribution. The full text of the license may be found at \r
 http://opensource.org/licenses/bsd-license.php \r
@@ -37,6 +37,8 @@ PxeInit (
   VOID                *Addr;\r
   EFI_STATUS          Status;\r
 \r
+  Status = EFI_SUCCESS;\r
+\r
   Cpb = Snp->Cpb;\r
   if (Snp->TxRxBufferSize != 0) {\r
     Status = Snp->PciIo->AllocateBuffer (\r
@@ -84,8 +86,8 @@ PxeInit (
   Snp->Cdb.OpCode     = PXE_OPCODE_INITIALIZE;\r
   Snp->Cdb.OpFlags    = CableDetectFlag;\r
 \r
-  Snp->Cdb.CPBsize    = sizeof (PXE_CPB_INITIALIZE);\r
-  Snp->Cdb.DBsize     = sizeof (PXE_DB_INITIALIZE);\r
+  Snp->Cdb.CPBsize    = (UINT16) sizeof (PXE_CPB_INITIALIZE);\r
+  Snp->Cdb.DBsize     = (UINT16) sizeof (PXE_DB_INITIALIZE);\r
 \r
   Snp->Cdb.CPBaddr    = (UINT64)(UINTN) Snp->Cpb;\r
   Snp->Cdb.DBaddr     = (UINT64)(UINTN) Snp->Db;\r
@@ -99,10 +101,30 @@ PxeInit (
 \r
   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
 \r
-  if (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS) {\r
-    Snp->Mode.State = EfiSimpleNetworkInitialized;\r
-\r
-    Status          = EFI_SUCCESS;\r
+  //\r
+  // There are two fields need to be checked here:\r
+  // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report \r
+  // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.\r
+  // Second is the CDB.StatCode field. After command execution completes, either successfully or not, \r
+  // the CDB.StatCode field contains the result of the command execution.\r
+  //\r
+  if ((((Snp->Cdb.StatFlags) & PXE_STATFLAGS_STATUS_MASK) == PXE_STATFLAGS_COMMAND_COMPLETE) &&\r
+      (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS)) {\r
+    //\r
+    // If cable detect feature is enabled in CDB.OpFlags, check the CDB.StatFlags to see if there is an \r
+    // active connection to this network device. If the no media StatFlag is set, the UNDI and network \r
+    // device are still initialized.    \r
+    //\r
+    if (CableDetectFlag == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {\r
+      if(((Snp->Cdb.StatFlags) & PXE_STATFLAGS_INITIALIZED_NO_MEDIA) != PXE_STATFLAGS_INITIALIZED_NO_MEDIA) {\r
+        Snp->Mode.MediaPresent = TRUE;\r
+      } else {\r
+        Snp->Mode.MediaPresent = FALSE;\r
+      }\r
+    }\r
+    \r
+    Snp->Mode.State   = EfiSimpleNetworkInitialized;\r
+    Status            = EFI_SUCCESS;\r
   } else {\r
     DEBUG (\r
       (EFI_D_WARN,\r
@@ -229,9 +251,11 @@ SnpUndi32Initialize (
   //\r
   Snp->TxRxBufferSize = (UINT32) (Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);\r
 \r
-  if (Snp->Mode.MediaPresentSupported) {\r
+  //\r
+  // If UNDI support cable detect for INITIALIZE command, try it first.\r
+  //\r
+  if (Snp->CableDetectSupported) {\r
     if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {\r
-      Snp->Mode.MediaPresent = TRUE;\r
       goto ON_EXIT;\r
     }\r
   }\r
@@ -242,6 +266,14 @@ SnpUndi32Initialize (
 \r
   if (EFI_ERROR (EfiStatus)) {\r
     gBS->CloseEvent (Snp->Snp.WaitForPacket);\r
+    goto ON_EXIT;\r
+  }\r
+\r
+  //\r
+  // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.\r
+  //\r
+  if (Snp->MediaStatusSupported) {\r
+    PxeGetStatus (Snp, NULL, FALSE);\r
   }\r
 \r
 ON_EXIT:\r