]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/SnpDxe/Snp.c
Update the structure of EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL, PXE_HW_UNDI, PXE_S...
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Snp.c
index 58451608e5737f30be2cc7f719068f1233b06ae1..ed583b488832d0326e1c6e60a7d81c4bc5ec82d0 100644 (file)
@@ -1,11 +1,11 @@
 /** @file\r
-    Implementation of driver entry point and driver binding protocol.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR> \r
-All rights reserved. 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
+  Implementation of driver entry point and driver binding protocol.\r
+\r
+Copyright (c) 2004 - 2013, 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
 \r
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
@@ -22,18 +22,43 @@ V2P                         *mV2p = NULL; // undi3.0 map_list head
 // End Global variables\r
 //\r
 \r
+/**\r
+  One notified function to stop UNDI device when gBS->ExitBootServices() called.\r
+\r
+  @param  Event                   Pointer to this event\r
+  @param  Context                 Event hanlder private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+SnpNotifyExitBootServices (\r
+  EFI_EVENT Event,\r
+  VOID      *Context\r
+  )\r
+{\r
+  SNP_DRIVER             *Snp;\r
+\r
+  Snp  = (SNP_DRIVER *)Context;\r
+\r
+  //\r
+  // Shutdown and stop UNDI driver\r
+  //\r
+  PxeShutdown (Snp);\r
+  PxeStop (Snp);\r
+}\r
 \r
 /**\r
   Send command to UNDI. It does nothing currently.\r
-  \r
+\r
   @param Cdb   command to be sent to UNDI.\r
-   \r
-  @retval EFI_INVALID_PARAMETER  The command is 0. \r
-  @retval EFI_UNSUPPORTED        Default return status because it's not \r
+\r
+  @retval EFI_INVALID_PARAMETER  The command is 0.\r
+  @retval EFI_UNSUPPORTED        Default return status because it's not\r
                                  supported currently.\r
-   \r
+\r
 **/\r
 EFI_STATUS\r
+EFIAPI\r
 IssueHwUndiCommand (\r
   UINT64 Cdb\r
   )\r
@@ -57,7 +82,7 @@ IssueHwUndiCommand (
   @param  Buffer               Pointer to buffer.\r
   @param  Length               Length of buffer in bytes.\r
 \r
-  @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len \r
+  @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len\r
           is zero.\r
 \r
 **/\r
@@ -154,37 +179,37 @@ SimpleNetworkDriverSupported (
   //\r
   // Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.\r
   //\r
-  if (NiiProtocol->ID & 0x0F) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));\r
+  if ((NiiProtocol->Id & 0x0F) != 0) {\r
+    DEBUG ((EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
 \r
-  Pxe = (PXE_UNDI *) (UINTN) (NiiProtocol->ID);\r
+  Pxe = (PXE_UNDI *) (UINTN) (NiiProtocol->Id);\r
 \r
   //\r
   //  Verify !PXE revisions.\r
   //\r
   if (Pxe->hw.Signature != PXE_ROMID_SIGNATURE) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE signature is not valid.\n"));\r
+    DEBUG ((EFI_D_NET, "\n!PXE signature is not valid.\n"));\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
 \r
   if (Pxe->hw.Rev < PXE_ROMID_REV) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE.Rev is not supported.\n"));\r
+    DEBUG ((EFI_D_NET, "\n!PXE.Rev is not supported.\n"));\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
 \r
   if (Pxe->hw.MajorVer < PXE_ROMID_MAJORVER) {\r
 \r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE.MajorVer is not supported.\n"));\r
+    DEBUG ((EFI_D_NET, "\n!PXE.MajorVer is not supported.\n"));\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
 \r
   } else if (Pxe->hw.MajorVer == PXE_ROMID_MAJORVER && Pxe->hw.MinorVer < PXE_ROMID_MINORVER) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE.MinorVer is not supported."));\r
+    DEBUG ((EFI_D_NET, "\n!PXE.MinorVer is not supported."));\r
     Status = EFI_UNSUPPORTED;\r
     goto Done;\r
   }\r
@@ -193,13 +218,13 @@ SimpleNetworkDriverSupported (
   //\r
   if ((Pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) == 0) {\r
     if (Pxe->sw.EntryPoint < Pxe->sw.Len) {\r
-      DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE S/W entry point is not valid."));\r
+      DEBUG ((EFI_D_NET, "\n!PXE S/W entry point is not valid."));\r
       Status = EFI_UNSUPPORTED;\r
       goto Done;\r
     }\r
 \r
     if (Pxe->sw.BusCnt == 0) {\r
-      DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE.BusCnt is zero."));\r
+      DEBUG ((EFI_D_NET, "\n!PXE.BusCnt is zero."));\r
       Status = EFI_UNSUPPORTED;\r
       goto Done;\r
     }\r
@@ -233,7 +258,7 @@ Done:
                                device to start.\r
 \r
   @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
-  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
+  @retval EFI_DEVICE_ERROR     This driver could not be started due to a device error\r
   @retval other                This driver does not support this device\r
 \r
 **/\r
@@ -258,7 +283,7 @@ SimpleNetworkDriverStart (
   UINT8                                     BarIndex;\r
   PXE_STATFLAGS                             InitStatFlags;\r
 \r
-  DEBUG ((EFI_D_INFO, "\nSnpNotifyNetworkInterfaceIdentifier()  "));\r
+  DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier()  "));\r
 \r
   Status = gBS->OpenProtocol (\r
                   Controller,\r
@@ -317,10 +342,10 @@ SimpleNetworkDriverStart (
 \r
   DEBUG ((EFI_D_INFO, "Start(): UNDI3.1 found\n"));\r
 \r
-  Pxe = (PXE_UNDI *) (UINTN) (Nii->ID);\r
+  Pxe = (PXE_UNDI *) (UINTN) (Nii->Id);\r
 \r
   if (Calc8BitCksum (Pxe, Pxe->hw.Len) != 0) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\n!PXE checksum is not correct.\n"));\r
+    DEBUG ((EFI_D_NET, "\n!PXE checksum is not correct.\n"));\r
     goto NiiError;\r
   }\r
 \r
@@ -335,7 +360,7 @@ SimpleNetworkDriverStart (
     //  broadcast support or we cannot do DHCP!\r
     //\r
   } else {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\nUNDI does not have promiscuous or broadcast support."));\r
+    DEBUG ((EFI_D_NET, "\nUNDI does not have promiscuous or broadcast support."));\r
     goto NiiError;\r
   }\r
   //\r
@@ -352,7 +377,7 @@ SimpleNetworkDriverStart (
                         );\r
 \r
   if (Status != EFI_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));\r
+    DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));\r
     goto NiiError;\r
   }\r
 \r
@@ -385,8 +410,13 @@ SimpleNetworkDriverStart (
 \r
   Snp->TxRxBufferSize     = 0;\r
   Snp->TxRxBuffer         = NULL;\r
\r
+  if (Nii->Revision >= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION) {\r
+       Snp->IfNum = Nii->IfNum;\r
 \r
-  Snp->IfNum              = Nii->IfNum;\r
+  } else {\r
+    Snp->IfNum = (UINT8) (Nii->IfNum & 0xFF);\r
+  }\r
 \r
   if ((Pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) != 0) {\r
     Snp->IsSwUndi             = FALSE;\r
@@ -426,7 +456,7 @@ SimpleNetworkDriverStart (
                         );\r
 \r
   if (Status != EFI_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));\r
+    DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));\r
     goto Error_DeleteSNP;\r
   }\r
 \r
@@ -459,8 +489,8 @@ SimpleNetworkDriverStart (
   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
   Snp->Cdb.CPBaddr    = PXE_DBADDR_NOT_USED;\r
 \r
-  Snp->Cdb.DBsize     = sizeof Snp->InitInfo;\r
-  Snp->Cdb.DBaddr     = (UINT64)(UINTN) &Snp->InitInfo;\r
+  Snp->Cdb.DBsize     = (UINT16) sizeof (Snp->InitInfo);\r
+  Snp->Cdb.DBaddr     = (UINT64)(UINTN) (&Snp->InitInfo);\r
 \r
   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
   Snp->Cdb.StatFlags  = PXE_STATFLAGS_INITIALIZE;\r
@@ -468,7 +498,7 @@ SimpleNetworkDriverStart (
   Snp->Cdb.IFnum      = Snp->IfNum;\r
   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
 \r
-  DEBUG ((EFI_D_INFO | EFI_D_NET, "\nSnp->undi.get_init_info()  "));\r
+  DEBUG ((EFI_D_NET, "\nSnp->undi.get_init_info()  "));\r
 \r
   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
 \r
@@ -478,7 +508,7 @@ SimpleNetworkDriverStart (
   InitStatFlags = Snp->Cdb.StatFlags;\r
 \r
   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\nSnp->undi.init_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
+    DEBUG ((EFI_D_NET, "\nSnp->undi.init_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
     PxeStop (Snp);\r
     goto Error_DeleteSNP;\r
   }\r
@@ -489,7 +519,7 @@ SimpleNetworkDriverStart (
   Snp->Cdb.CPBsize    = PXE_CPBSIZE_NOT_USED;\r
   Snp->Cdb.CPBaddr    = PXE_DBADDR_NOT_USED;\r
 \r
-  Snp->Cdb.DBsize     = sizeof ConfigInfo;\r
+  Snp->Cdb.DBsize     = (UINT16) sizeof (ConfigInfo);\r
   Snp->Cdb.DBaddr     = (UINT64)(UINTN) &ConfigInfo;\r
 \r
   Snp->Cdb.StatCode   = PXE_STATCODE_INITIALIZE;\r
@@ -498,12 +528,12 @@ SimpleNetworkDriverStart (
   Snp->Cdb.IFnum      = Snp->IfNum;\r
   Snp->Cdb.Control    = PXE_CONTROL_LAST_CDB_IN_LIST;\r
 \r
-  DEBUG ((EFI_D_INFO | EFI_D_NET, "\nSnp->undi.get_config_info()  "));\r
+  DEBUG ((EFI_D_NET, "\nSnp->undi.get_config_info()  "));\r
 \r
   (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
 \r
   if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {\r
-    DEBUG ((EFI_D_ERROR | EFI_D_NET, "\nSnp->undi.config_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
+    DEBUG ((EFI_D_NET, "\nSnp->undi.config_info()  %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));\r
     PxeStop (Snp);\r
     goto Error_DeleteSNP;\r
   }\r
@@ -557,6 +587,16 @@ SimpleNetworkDriverStart (
     Snp->Mode.MediaPresentSupported = FALSE;\r
   }\r
 \r
+  switch (InitStatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK) {\r
+  case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED:\r
+    Snp->MediaStatusSupported = TRUE;\r
+    break;\r
+\r
+  case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED:\r
+  default:\r
+    Snp->MediaStatusSupported = FALSE;\r
+  }\r
+\r
   if ((Pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) {\r
     Snp->Mode.MacAddressChangeable = TRUE;\r
   } else {\r
@@ -591,7 +631,7 @@ SimpleNetworkDriverStart (
 \r
   }\r
 \r
-  if (Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) {\r
+  if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {\r
     Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
 \r
   }\r
@@ -634,6 +674,21 @@ SimpleNetworkDriverStart (
   PxeShutdown (Snp);\r
   PxeStop (Snp);\r
 \r
+  //\r
+  // Create EXIT_BOOT_SERIVES Event\r
+  //\r
+  Status = gBS->CreateEventEx (\r
+                  EVT_NOTIFY_SIGNAL,\r
+                  TPL_NOTIFY,\r
+                  SnpNotifyExitBootServices,\r
+                  Snp,\r
+                  &gEfiEventExitBootServicesGuid,\r
+                  &Snp->ExitBootServicesEvent\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    goto Error_DeleteSNP;\r
+  }\r
+\r
   //\r
   //  add SNP to the undi handle\r
   //\r
@@ -648,11 +703,11 @@ SimpleNetworkDriverStart (
     return Status;\r
   }\r
 \r
-  Status = mPciIo->FreeBuffer (\r
-                        mPciIo,\r
-                        SNP_MEM_PAGES (4096),\r
-                        Snp->Cpb\r
-                        );\r
+  mPciIo->FreeBuffer (\r
+            mPciIo,\r
+            SNP_MEM_PAGES (4096),\r
+            Snp->Cpb\r
+            );\r
 \r
 Error_DeleteSNP:\r
 \r
@@ -676,6 +731,13 @@ NiiError:
         Controller\r
         );\r
 \r
+  //\r
+  // If we got here that means we are in error state.\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = EFI_DEVICE_ERROR;\r
+  }\r
+\r
   return Status;\r
 }\r
 \r
@@ -686,7 +748,7 @@ NiiError:
   restrictions for this service. DisconnectController()\r
   must follow these calling restrictions. If any other agent wishes\r
   to call Stop() it must also follow these calling restrictions.\r
-  \r
+\r
   @param  This              Protocol instance pointer.\r
   @param  ControllerHandle  Handle of device to stop driver on\r
   @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
@@ -738,6 +800,11 @@ SimpleNetworkDriverStop (
     return Status;\r
   }\r
 \r
+  //\r
+  // Close EXIT_BOOT_SERIVES Event\r
+  //\r
+  gBS->CloseEvent (Snp->ExitBootServicesEvent);\r
+\r
   Status = gBS->CloseProtocol (\r
                   Controller,\r
                   &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
@@ -773,7 +840,7 @@ SimpleNetworkDriverStop (
 //\r
 // Simple Network Protocol Driver Global Variables\r
 //\r
-EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {\r
+EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {\r
   SimpleNetworkDriverSupported,\r
   SimpleNetworkDriverStart,\r
   SimpleNetworkDriverStop,\r
@@ -816,7 +883,7 @@ AddV2P (
   }\r
 \r
   *V2p = AllocatePool (sizeof (V2P));\r
-  if (*V2p != NULL) {\r
+  if (*V2p == NULL) {\r
     return EFI_OUT_OF_RESOURCES;\r
   }\r
 \r
@@ -959,8 +1026,8 @@ InitializeSnpNiiDriver (
   return EfiLibInstallDriverBindingComponentName2 (\r
            ImageHandle,\r
            SystemTable,\r
-           &mSimpleNetworkDriverBinding,\r
-           NULL,\r
+           &gSimpleNetworkDriverBinding,\r
+           ImageHandle,\r
            &gSimpleNetworkComponentName,\r
            &gSimpleNetworkComponentName2\r
            );\r