]> git.proxmox.com Git - mirror_edk2.git/blobdiff - EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
Retiring the ANT/JAVA build and removing the older EDK II packages that required...
[mirror_edk2.git] / EdkModulePkg / Universal / Network / PxeBc / Dxe / bc.c
diff --git a/EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c b/EdkModulePkg/Universal/Network/PxeBc/Dxe/bc.c
deleted file mode 100644 (file)
index 0eceddf..0000000
+++ /dev/null
@@ -1,2403 +0,0 @@
-/*++\r
-\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which 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
-\r
-Module Name:\r
-        bc.c\r
-\r
-Abstract:\r
-\r
---*/\r
-\r
-#include "Bc.h"\r
-\r
-//\r
-// helper routines\r
-//\r
-VOID\r
-CvtNum (\r
-  IN UINTN  Number,\r
-  IN UINT8  *Buffer,\r
-  IN INTN   Length\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Convert number to ASCII value\r
-\r
-  Arguments:\r
-    Number              - Numeric value to convert to decimal ASCII value.\r
-    Buffer              - Buffer to place ASCII version of the Number\r
-    Length              - Length of Buffer.\r
-\r
-  Returns:\r
-    none                - none\r
-\r
---*/\r
-{\r
-  UINTN Remainder;\r
-\r
-  while (Length--) {\r
-    Remainder = Number % 10;\r
-    Number /= 10;\r
-    Buffer[Length] = (UINT8) ('0' + Remainder);\r
-  }\r
-}\r
-\r
-VOID\r
-UtoA10 (\r
-  IN UINTN Number,\r
-  IN UINT8 *Buffer\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Convert number to decimal ASCII value at Buffer location\r
-\r
-  Arguments:\r
-    Number              - Numeric value to convert to decimal ASCII value.\r
-    Buffer              - Buffer to place ASCII version of the Number\r
-\r
-  Returns:\r
-    none                - none\r
-\r
---*/\r
-{\r
-  INTN  Index;\r
-  UINT8 BuffArray[31];\r
-\r
-  BuffArray[30] = 0;\r
-  CvtNum (Number, BuffArray, 30);\r
-\r
-  for (Index = 0; Index < 30; ++Index) {\r
-    if (BuffArray[Index] != '0') {\r
-      break;\r
-    }\r
-  }\r
-\r
-  CopyMem (Buffer, BuffArray + Index, 31 - Index);\r
-}\r
-\r
-UINTN\r
-AtoU (\r
-  IN UINT8 *Buffer\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Convert ASCII numeric string to a UINTN value\r
-\r
-  Arguments:\r
-    Number              - Numeric value to convert to decimal ASCII value.\r
-    Buffer              - Buffer to place ASCII version of the Number\r
-\r
-  Returns:\r
-    Value                - UINTN value of the ASCII string.\r
-\r
---*/\r
-{\r
-  UINTN Value;\r
-  INT8  Character;\r
-\r
-  Value     = 0;\r
-  Character = *Buffer++;\r
-  do {\r
-    Value     = Value * 10 + Character - '0';\r
-    Character = *Buffer++;\r
-  } while (Character);\r
-\r
-  return Value;\r
-}\r
-\r
-UINT64\r
-AtoU64 (\r
-  IN UINT8 *Buffer\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Convert ASCII numeric string to a UINTN value\r
-\r
-  Arguments:\r
-    Number              - Numeric value to convert to decimal ASCII value.\r
-    Buffer              - Buffer to place ASCII version of the Number\r
-\r
-  Returns:\r
-    Value                - UINTN value of the ASCII string.\r
-\r
---*/\r
-{\r
-  UINT64  Value;\r
-  UINT8   Character;\r
-\r
-  Value = 0;\r
-  while ((Character = *Buffer++) != '\0') {\r
-    Value = MultU64x32 (Value, 10) + (Character - '0');\r
-  }\r
-\r
-  return Value;\r
-}\r
-//\r
-// random number generator\r
-//\r
-#define RANDOM_MULTIPLIER   2053\r
-#define RANDOM_ADD_IN_VALUE 19\r
-\r
-VOID\r
-SeedRandom (\r
-  IN PXE_BASECODE_DEVICE  *Private,\r
-  IN UINT16               InitialSeed\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Initialize the Seed for the random number generator\r
-\r
-  Arguments:\r
-\r
-  Returns:\r
-    none                -\r
-\r
---*/\r
-{\r
-  if (Private != NULL) {\r
-    Private->RandomSeed = InitialSeed;\r
-  }\r
-}\r
-\r
-UINT16\r
-Random (\r
-  IN PXE_BASECODE_DEVICE  *Private\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Generate and return a pseudo-random number\r
-\r
-  Arguments:\r
-\r
-  Returns:\r
-    Number           - UINT16 random number\r
-\r
---*/\r
-{\r
-  UINTN Number;\r
-\r
-  if (Private != NULL) {\r
-    Number = -(INTN) Private->RandomSeed * RANDOM_MULTIPLIER + RANDOM_ADD_IN_VALUE;\r
-\r
-    return Private->RandomSeed = (UINT16) Number;\r
-  } else {\r
-    return 0;\r
-  }\r
-}\r
-//\r
-// calculate the internet checksum (RFC 1071)\r
-// return 16 bit ones complement of ones complement sum of 16 bit words\r
-//\r
-UINT16\r
-IpChecksum (\r
-  IN UINT16 *Packet,\r
-  IN UINTN  Length\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Calculate the internet checksum (see RFC 1071)\r
-\r
-  Arguments:\r
-    Packet             - Buffer which contains the data to be checksummed\r
-    Length             - Length to be checksummed\r
-\r
-  Returns:\r
-    Checksum           - Returns the 16 bit ones complement of\r
-                         ones complement sum of 16 bit words\r
-\r
---*/\r
-{\r
-  UINT32  Sum;\r
-  UINT8   Odd;\r
-\r
-  Sum = 0;\r
-  Odd = (UINT8) (Length & 1);\r
-  Length >>= 1;\r
-  while (Length--) {\r
-    Sum += *Packet++;\r
-  }\r
-\r
-  if (Odd) {\r
-    Sum += *(UINT8 *) Packet;\r
-  }\r
-\r
-  Sum = (Sum & 0xffff) + (Sum >> 16);\r
-  //\r
-  // in case above carried\r
-  //\r
-  Sum += Sum >> 16;\r
-\r
-  return (UINT16) (~ (UINT16) Sum);\r
-}\r
-\r
-UINT16\r
-IpChecksum2 (\r
-  IN UINT16 *Header,\r
-  IN UINTN  HeaderLen,\r
-  IN UINT16 *Message,\r
-  IN UINTN  MessageLen\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Calculate the internet checksum (see RFC 1071)\r
-    on a non contiguous header and data\r
-\r
-  Arguments:\r
-    Header        - Buffer which contains the data to be checksummed\r
-    HeaderLen     - Length to be checksummed\r
-    Message       - Buffer which contains the data to be checksummed\r
-    MessageLen    - Length to be checksummed\r
-\r
-  Returns:\r
-    Checksum      - Returns the 16 bit ones complement of\r
-                    ones complement sum of 16 bit words\r
-\r
---*/\r
-{\r
-  UINT32  Sum;\r
-\r
-  Sum = (UINT16)~IpChecksum (Header, HeaderLen);\r
-  Sum = Sum + (UINT16)~IpChecksum (Message, MessageLen);\r
-  //\r
-  // in case above carried\r
-  //\r
-  Sum += Sum >> 16;\r
-\r
-  return (UINT16) (~ (UINT16) Sum);\r
-}\r
-\r
-UINT16\r
-UpdateChecksum (\r
-  IN UINT16 OldChksum,\r
-  IN UINT16 OldWord,\r
-  IN UINT16 NewWord\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Adjust the internet checksum (see RFC 1071) on a single word update.\r
-\r
-  Arguments:\r
-    OldChkSum          - Checksum previously calculated\r
-    OldWord            - Value\r
-    NewWord            - New Value\r
-\r
-  Returns:\r
-    Checksum           - Returns the 16 bit ones complement of\r
-                         ones complement sum of 16 bit words\r
-\r
---*/\r
-{\r
-  UINT32  sum;\r
-\r
-  sum = ~OldChksum + NewWord - OldWord;\r
-  //\r
-  // in case above carried\r
-  //\r
-  sum += sum >> 16;\r
-  return (UINT16) (~ (UINT16) sum);\r
-}\r
-\r
-STATIC\r
-BOOLEAN\r
-SetMakeCallback (\r
-  IN PXE_BASECODE_DEVICE *Private\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    See if a callback is in play\r
-\r
-  Arguments:\r
-    Private                - Pointer to Pxe BaseCode Protocol\r
-\r
-  Returns:\r
-    0                  - Callbacks are active on the handle\r
-    1                  - Callbacks are not active on the handle\r
-\r
---*/\r
-{\r
-  Private->EfiBc.Mode->MakeCallbacks = (BOOLEAN) (gBS->HandleProtocol (\r
-                                                        Private->Handle,\r
-                                                        &gEfiPxeBaseCodeCallbackProtocolGuid,\r
-                                                        (VOID *) &Private->CallbackProtocolPtr\r
-                                                        ) == EFI_SUCCESS);\r
-\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nMode->MakeCallbacks == %d  ",\r
-    Private->EfiBc.Mode->MakeCallbacks)\r
-    );\r
-\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nPrivate->CallbackProtocolPtr == %xh  ",\r
-    Private->CallbackProtocolPtr)\r
-    );\r
-\r
-  if (Private->CallbackProtocolPtr != NULL) {\r
-    DEBUG (\r
-      (EFI_D_INFO,\r
-      "\nCallbackProtocolPtr->Revision = %xh  ",\r
-      Private->CallbackProtocolPtr->Revision)\r
-      );\r
-\r
-    DEBUG (\r
-      (EFI_D_INFO,\r
-      "\nCallbackProtocolPtr->Callback = %xh  ",\r
-      Private->CallbackProtocolPtr->Callback)\r
-      );\r
-  }\r
-\r
-  return Private->EfiBc.Mode->MakeCallbacks;\r
-}\r
-\r
-/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */\r
-EFI_STATUS\r
-WaitForReceive (\r
-  IN PXE_BASECODE_DEVICE        *Private,\r
-  IN EFI_PXE_BASE_CODE_FUNCTION Function,\r
-  IN EFI_EVENT                  TimeoutEvent,\r
-  IN OUT UINTN                  *HeaderSizePtr,\r
-  IN OUT UINTN                  *BufferSizePtr,\r
-  IN OUT UINT16                 *ProtocolPtr\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Routine which does an SNP->Receive over a timeout period and doing callbacks\r
-\r
-  Arguments:\r
-    Private       - Pointer to Pxe BaseCode Protocol\r
-    Function      - What PXE function to callback\r
-    TimeoutEvent  - Timer event that will trigger when we have waited too\r
-                    long for an incoming packet\r
-    HeaderSizePtr - Pointer to the size of the Header size\r
-    BufferSizePtr - Pointer to the size of the Buffer size\r
-    ProtocolPtr   - The protocol to sniff for (namely, UDP/etc)\r
-\r
-  Returns:\r
-    0             - Something was returned\r
-    !0            - Like there was nothing to receive (EFI_TIMEOUT/NOT_READY)\r
-\r
---*/\r
-{\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-  EFI_PXE_CALLBACK            CallbackPtr;\r
-  EFI_STATUS                  StatCode;\r
-  EFI_EVENT                   CallbackEvent;\r
-\r
-  //\r
-  // Initialize pointer to SNP interface\r
-  //\r
-  SnpPtr = Private->SimpleNetwork;\r
-\r
-  //\r
-  // Initialize pointer to PxeBc callback routine - if any\r
-  //\r
-  CallbackPtr = (Private->EfiBc.Mode->MakeCallbacks) ? Private->CallbackProtocolPtr->Callback : NULL;\r
-\r
-  //\r
-  // Create callback event and set timer\r
-  //\r
-  StatCode = gBS->CreateEvent (\r
-                    EVT_TIMER,\r
-                    TPL_CALLBACK,\r
-                    NULL,\r
-                    NULL,\r
-                    &CallbackEvent\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // every 100 milliseconds\r
-  //\r
-  StatCode = gBS->SetTimer (\r
-                    CallbackEvent,\r
-                    TimerPeriodic,\r
-                    1000000\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    gBS->CloseEvent (CallbackEvent);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-  //\r
-  // Loop until a packet is received or a receive error is detected or\r
-  // a callback abort is detected or a timeout event occurs.\r
-  //\r
-  for (;;)\r
-  {\r
-    //\r
-    // Poll for received packet.\r
-    //\r
-    *BufferSizePtr = BUFFER_ALLOCATE_SIZE;\r
-\r
-    StatCode = SnpPtr->Receive (\r
-                        SnpPtr,\r
-                        HeaderSizePtr,\r
-                        BufferSizePtr,\r
-                        Private->ReceiveBufferPtr,\r
-                        0,\r
-                        0,\r
-                        ProtocolPtr\r
-                        );\r
-\r
-    if (!EFI_ERROR (StatCode)) {\r
-      //\r
-      // Packet was received.  Make received callback then return.\r
-      //\r
-      if (CallbackPtr != NULL) {\r
-        StatCode = CallbackPtr (\r
-                    Private->CallbackProtocolPtr,\r
-                    Function,\r
-                    TRUE,\r
-                    (UINT32) *BufferSizePtr,\r
-                    (EFI_PXE_BASE_CODE_PACKET *) Private->ReceiveBufferPtr\r
-                    );\r
-\r
-        if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
-          StatCode = EFI_ABORTED;\r
-        } else {\r
-          StatCode = EFI_SUCCESS;\r
-        }\r
-      }\r
-\r
-      break;\r
-    }\r
-\r
-    if (StatCode != EFI_NOT_READY) {\r
-      break;\r
-    }\r
-\r
-    //\r
-    // Check for callback event.\r
-    //\r
-    if (!EFI_ERROR (gBS->CheckEvent (CallbackEvent))) {\r
-      //\r
-      // Make periodic callback if callback pointer is initialized.\r
-      //\r
-      if (CallbackPtr != NULL) {\r
-        StatCode = CallbackPtr (\r
-                    Private->CallbackProtocolPtr,\r
-                    Function,\r
-                    FALSE,\r
-                    0,\r
-                    NULL\r
-                    );\r
-\r
-        //\r
-        // Abort if directed to by callback routine.\r
-        //\r
-        if (StatCode != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
-          StatCode = EFI_ABORTED;\r
-          break;\r
-        }\r
-      }\r
-    }\r
-    //\r
-    // Check for timeout event.\r
-    //\r
-    if (TimeoutEvent == 0) {\r
-      StatCode = EFI_TIMEOUT;\r
-      break;\r
-    }\r
-\r
-    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
-      StatCode = EFI_TIMEOUT;\r
-      break;\r
-    }\r
-    //\r
-    // Check IGMP timer events.\r
-    //\r
-    IgmpCheckTimers (Private);\r
-  }\r
-\r
-  gBS->CloseEvent (CallbackEvent);\r
-\r
-  return StatCode;\r
-}\r
-\r
-EFI_STATUS\r
-SendPacket (\r
-  PXE_BASECODE_DEVICE           *Private,\r
-  VOID                          *HeaderPtr,\r
-  VOID                          *PacketPtr,\r
-  INTN                          PacketLen,\r
-  VOID                          *HardwareAddr,\r
-  UINT16                        MediaProtocol,\r
-  IN EFI_PXE_BASE_CODE_FUNCTION Function\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Routine which does an SNP->Transmit of a buffer\r
-\r
-  Arguments:\r
-    Private       - Pointer to Pxe BaseCode Protocol\r
-    HeaderPtr          - Pointer to the buffer\r
-    PacketPtr          - Pointer to the packet to send\r
-    PacketLen        - The length of the entire packet to send\r
-    HardwareAddr        - Pointer to the MAC address of the destination\r
-    MediaProtocol - What type of frame to create (RFC 1700) - IE. Ethernet\r
-    Function      - What PXE function to callback\r
-\r
-  Returns:\r
-    0             - Something was sent\r
-    !0            - An error was encountered during sending of a packet\r
-\r
---*/\r
-{\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;\r
-  EFI_PXE_CALLBACK            CallbackPtr;\r
-  EFI_STATUS                  StatCode;\r
-  EFI_EVENT                   TimeoutEvent;\r
-  UINT32                      IntStatus;\r
-  VOID                        *TxBuf;\r
-\r
-  //\r
-  //\r
-  //\r
-  CallbackPtr = Private->EfiBc.Mode->MakeCallbacks ? Private->CallbackProtocolPtr->Callback : 0;\r
-\r
-  SnpPtr      = Private->SimpleNetwork;\r
-  SnpModePtr  = SnpPtr->Mode;\r
-\r
-  //\r
-  // clear prior interrupt status\r
-  //\r
-  StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, 0);\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nSendPacket()  Exit #1  %xh (%r)",\r
-      StatCode,\r
-      StatCode)\r
-      );\r
-    return StatCode;\r
-  }\r
-\r
-  Private->DidTransmit = FALSE;\r
-\r
-  if (CallbackPtr != NULL) {\r
-    if (CallbackPtr (\r
-          Private->CallbackProtocolPtr,\r
-          Function,\r
-          FALSE,\r
-          (UINT32) PacketLen,\r
-          PacketPtr\r
-          ) != EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE) {\r
-      DEBUG (\r
-        (EFI_D_WARN,\r
-        "\nSendPacket()  Exit #2  %xh (%r)",\r
-        EFI_ABORTED,\r
-        EFI_ABORTED)\r
-        );\r
-      return EFI_ABORTED;\r
-    }\r
-  }\r
-  //\r
-  // put packet in transmit queue\r
-  // headersize should be zero if not filled in\r
-  //\r
-  StatCode = gBS->CreateEvent (\r
-                    EVT_TIMER,\r
-                    TPL_CALLBACK,\r
-                    NULL,\r
-                    NULL,\r
-                    &TimeoutEvent\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_ERROR,\r
-      "Could not create transmit timeout event.  %r\n",\r
-      StatCode)\r
-      );\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // 5 milliseconds\r
-  //\r
-  StatCode = gBS->SetTimer (\r
-                    TimeoutEvent,\r
-                    TimerRelative,\r
-                    50000\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_ERROR,\r
-      "Could not set transmit timeout event timer.  %r\n",\r
-      StatCode)\r
-      );\r
-    gBS->CloseEvent (TimeoutEvent);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  for (;;) {\r
-    StatCode = SnpPtr->Transmit (\r
-                        SnpPtr,\r
-                        (UINTN) SnpPtr->Mode->MediaHeaderSize,\r
-                        (UINTN) (PacketLen + SnpPtr->Mode->MediaHeaderSize),\r
-                        HeaderPtr,\r
-                        &SnpModePtr->CurrentAddress,\r
-                        (EFI_MAC_ADDRESS *) HardwareAddr,\r
-                        &MediaProtocol\r
-                        );\r
-\r
-    if (StatCode != EFI_NOT_READY) {\r
-      break;\r
-    }\r
-\r
-    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
-      StatCode = EFI_TIMEOUT;\r
-      break;\r
-    }\r
-  }\r
-\r
-  gBS->CloseEvent (TimeoutEvent);\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nSendPacket()  Exit #3  %xh (%r)",\r
-      StatCode,\r
-      StatCode)\r
-      );\r
-    return StatCode;\r
-  }\r
-  //\r
-  // remove transmit buffer from snp's unused queue\r
-  // done this way in case someday things are buffered and we don't get it back\r
-  // immediately\r
-  //\r
-  StatCode = gBS->CreateEvent (\r
-                    EVT_TIMER,\r
-                    TPL_CALLBACK,\r
-                    NULL,\r
-                    NULL,\r
-                    &TimeoutEvent\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_ERROR,\r
-      "Could not create transmit status timeout event.  %r\n",\r
-      StatCode)\r
-      );\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  //\r
-  // 5 milliseconds\r
-  //\r
-  StatCode = gBS->SetTimer (\r
-                    TimeoutEvent,\r
-                    TimerRelative,\r
-                    50000\r
-                    );\r
-\r
-  if (EFI_ERROR (StatCode)) {\r
-    DEBUG (\r
-      (EFI_D_ERROR,\r
-      "Could not set transmit status timeout event timer.  %r\n",\r
-      StatCode)\r
-      );\r
-    gBS->CloseEvent (TimeoutEvent);\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  for (;;) {\r
-    StatCode = SnpPtr->GetStatus (SnpPtr, &IntStatus, &TxBuf);\r
-\r
-    if (EFI_ERROR (StatCode)) {\r
-      DEBUG (\r
-        (EFI_D_WARN,\r
-        "\nSendPacket()  Exit #4  %xh (%r)",\r
-        StatCode,\r
-        StatCode)\r
-        );\r
-      break;\r
-    }\r
-\r
-    if (IntStatus & EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT) {\r
-      Private->DidTransmit = TRUE;\r
-    }\r
-\r
-    if (TxBuf != NULL) {\r
-      break;\r
-    }\r
-\r
-    if (!EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
-      StatCode = EFI_TIMEOUT;\r
-      break;\r
-    }\r
-  }\r
-\r
-  gBS->CloseEvent (TimeoutEvent);\r
-\r
-  return StatCode;\r
-}\r
-//\r
-//\r
-//\r
-EFI_BIS_PROTOCOL *\r
-PxebcBisStart (\r
-  IN PXE_BASECODE_DEVICE      *Private,\r
-  OUT BIS_APPLICATION_HANDLE  *BisAppHandle,\r
-  OUT OPTIONAL EFI_BIS_DATA            **BisDataSigInfo\r
-  )\r
-/*++\r
-Routine description:\r
-  Locate BIS interface and if found, try to start it.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeBc protocol\r
-  BisAppHandle := Pointer to BIS application handle storage\r
-  BisDataSigInfo := Pointer to BIS signature information storage\r
-Returns:\r
---*/\r
-{\r
-  EFI_STATUS        EfiStatus;\r
-  EFI_HANDLE        BisHandleBuffer;\r
-  UINTN             BisHandleCount;\r
-  EFI_BIS_PROTOCOL  *BisPtr;\r
-  EFI_BIS_VERSION   BisInterfaceVersion;\r
-  BOOLEAN           BisCheckFlag;\r
-\r
-  BisHandleCount  = sizeof (EFI_HANDLE);\r
-  BisCheckFlag    = FALSE;\r
-\r
-  //\r
-  // Locate BIS protocol handle (if present).\r
-  // If BIS protocol handle is not found, return NULL.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\ngBS->LocateHandle()  "));\r
-\r
-  EfiStatus = gBS->LocateHandle (\r
-                    ByProtocol,\r
-                    &gEfiBisProtocolGuid,\r
-                    NULL,\r
-                    &BisHandleCount,\r
-                    &BisHandleBuffer\r
-                    );\r
-\r
-  if (EFI_ERROR (EfiStatus)) {\r
-    //\r
-    // Any error means that there is no BIS.\r
-    // Note - It could mean that there are more than\r
-    // one BIS protocols installed, but that scenario\r
-    // is not yet supported.\r
-    //\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  gBS->LocateHandle()  %r (%xh)\n",\r
-      EfiStatus,\r
-      EfiStatus)\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-\r
-  if (BisHandleCount != sizeof (BisHandleBuffer)) {\r
-    //\r
-    // This really should never happen, but I am paranoid.\r
-    //\r
-    DEBUG (\r
-      (EFI_D_NET,\r
-      "\nPxebcBisStart()  BisHandleCount != %d\n",\r
-      sizeof BisHandleBuffer)\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "BIS handle found."));\r
-\r
-  //\r
-  // Locate BIS protocol interface.\r
-  // If the BIS protocol interface cannot be found, return NULL.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\ngBS->HandleProtocol()  "));\r
-\r
-  EfiStatus = gBS->HandleProtocol (\r
-                    BisHandleBuffer,\r
-                    &gEfiBisProtocolGuid,\r
-                    (VOID **) &BisPtr\r
-                    );\r
-\r
-  if (EFI_ERROR (EfiStatus)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  gBS->HandleProtocol()  %r (%xh)\n",\r
-      EfiStatus,\r
-      EfiStatus)\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-\r
-  if (BisPtr == NULL) {\r
-    //\r
-    // This really should never happen.\r
-    //\r
-    DEBUG (\r
-      (EFI_D_NET,\r
-      "\nPxebcBisStart()""\n  gBS->HandleProtocoL()  ""BIS protocol interface pointer is NULL!\n")\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "BIS protocol interface found."));\r
-\r
-  //\r
-  // Check that all of the BIS API function pointers are not NULL.\r
-  //\r
-  if (BisPtr->Initialize == NULL ||\r
-      BisPtr->Shutdown == NULL ||\r
-      BisPtr->Free == NULL ||\r
-      BisPtr->GetBootObjectAuthorizationCertificate == NULL ||\r
-      BisPtr->GetBootObjectAuthorizationCheckFlag == NULL ||\r
-      BisPtr->GetBootObjectAuthorizationUpdateToken == NULL ||\r
-      BisPtr->GetSignatureInfo == NULL ||\r
-      BisPtr->UpdateBootObjectAuthorization == NULL ||\r
-      BisPtr->VerifyBootObject == NULL ||\r
-      BisPtr->VerifyObjectWithCredential == NULL\r
-      ) {\r
-    DEBUG (\r
-      (\r
-      EFI_D_NET,\r
-      "\nPxebcBisStart()""\n  BIS protocol interface is invalid."\r
-      "\n  At least one BIS protocol function pointer is NULL.\n"\r
-      )\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-  //\r
-  // Initialize BIS.\r
-  // If BIS does not initialize, return NULL.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\nBisPtr->Initialize()  "));\r
-\r
-  BisInterfaceVersion.Major = BIS_VERSION_1;\r
-\r
-  EfiStatus = BisPtr->Initialize (\r
-                        BisPtr,\r
-                        BisAppHandle,\r
-                        &BisInterfaceVersion,\r
-                        NULL\r
-                        );\r
-\r
-  if (EFI_ERROR (EfiStatus)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  BisPtr->Initialize()  %r (%xh)\n",\r
-      EfiStatus,\r
-      EfiStatus)\r
-      );\r
-\r
-    return NULL;\r
-  }\r
-\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "  BIS version: %d.%d",\r
-    BisInterfaceVersion.Major,\r
-    BisInterfaceVersion.Minor)\r
-    );\r
-\r
-  //\r
-  // If the requested BIS API version is not supported,\r
-  // shutdown BIS and return NULL.\r
-  //\r
-  if (BisInterfaceVersion.Major != BIS_VERSION_1) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  BIS version %d.%d not supported by PXE BaseCode.\n",\r
-      BisInterfaceVersion.Major,\r
-      BisInterfaceVersion.Minor)\r
-      );\r
-\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  }\r
-  //\r
-  // Get BIS check flag.\r
-  // If the BIS check flag cannot be read, shutdown BIS and return NULL.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\nBisPtr->GetBootObjectAuthorizationCheckFlag()  "));\r
-\r
-  EfiStatus = BisPtr->GetBootObjectAuthorizationCheckFlag (*BisAppHandle, &BisCheckFlag);\r
-\r
-  if (EFI_ERROR (EfiStatus)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  BisPtr->GetBootObjectAuthorizationCheckFlag()  %r (%xh)\n",\r
-      EfiStatus,\r
-      EfiStatus)\r
-      );\r
-\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  }\r
-  //\r
-  // If the BIS check flag is FALSE, shutdown BIS and return NULL.\r
-  //\r
-  if (!BisCheckFlag) {\r
-    DEBUG ((EFI_D_INFO, "\nBIS check flag is FALSE.\n"));\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  } else {\r
-    DEBUG ((EFI_D_INFO, "\nBIS check flag is TRUE."));\r
-  }\r
-  //\r
-  // Early out if caller does not want signature information.\r
-  //\r
-  if (BisDataSigInfo == NULL) {\r
-    return BisPtr;\r
-  }\r
-  //\r
-  // Get BIS signature information.\r
-  // If the signature information cannot be read or is invalid,\r
-  // shutdown BIS and return NULL.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\nBisPtr->GetSignatureInfo()  "));\r
-\r
-  EfiStatus = BisPtr->GetSignatureInfo (*BisAppHandle, BisDataSigInfo);\r
-\r
-  if (EFI_ERROR (EfiStatus)) {\r
-    DEBUG (\r
-      (EFI_D_WARN,\r
-      "\nPxebcBisStart()""\n  BisPtr_GetSignatureInfo()  %r (%xh)\n",\r
-      EfiStatus,\r
-      EfiStatus)\r
-      );\r
-\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  }\r
-\r
-  if (*BisDataSigInfo == NULL) {\r
-    //\r
-    // This should never happen.\r
-    //\r
-    DEBUG (\r
-      (EFI_D_NET,\r
-      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Data pointer is NULL!\n")\r
-      );\r
-\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  }\r
-\r
-  if ((*BisDataSigInfo)->Length < sizeof (EFI_BIS_SIGNATURE_INFO) ||\r
-      (*BisDataSigInfo)->Length % sizeof (EFI_BIS_SIGNATURE_INFO) ||\r
-      (*BisDataSigInfo)->Length > sizeof (EFI_BIS_SIGNATURE_INFO) * 63\r
-      ) {\r
-    //\r
-    // This should never happen.\r
-    //\r
-    DEBUG (\r
-      (EFI_D_NET,\r
-      "\nPxebcBisStart()""\n  BisPtr->GetSignatureInfo()  Invalid BIS siginfo length.\n")\r
-      );\r
-\r
-    BisPtr->Free (*BisAppHandle, *BisDataSigInfo);\r
-    BisPtr->Shutdown (*BisAppHandle);\r
-    return NULL;\r
-  }\r
-\r
-  return BisPtr;\r
-}\r
-\r
-VOID\r
-PxebcBisStop (\r
-  EFI_BIS_PROTOCOL        *BisPtr,\r
-  BIS_APPLICATION_HANDLE  BisAppHandle,\r
-  EFI_BIS_DATA            *BisDataSigInfo\r
-  )\r
-/*++\r
-Routine description:\r
-  Stop the BIS interface and release allocations.\r
-\r
-Parameters:\r
-  BisPtr := Pointer to BIS interface\r
-  BisAppHandle := BIS application handle\r
-  BisDataSigInfo := Pointer to BIS signature information data\r
-\r
-Returns:\r
-\r
---*/\r
-{\r
-  if (BisPtr == NULL) {\r
-    return ;\r
-  }\r
-  //\r
-  // Free BIS allocated resources and shutdown BIS.\r
-  // Return TRUE - BIS support is officially detected.\r
-  //\r
-  if (BisDataSigInfo != NULL) {\r
-    BisPtr->Free (BisAppHandle, BisDataSigInfo);\r
-  }\r
-\r
-  BisPtr->Shutdown (BisAppHandle);\r
-}\r
-\r
-BOOLEAN\r
-PxebcBisVerify (\r
-  PXE_BASECODE_DEVICE *Private,\r
-  VOID                *FileBuffer,\r
-  UINTN               FileLength,\r
-  VOID                *CredentialBuffer,\r
-  UINTN               CredentialLength\r
-  )\r
-/*++\r
-Routine description:\r
-  Verify image and credential file.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeBc interface\r
-  FileBuffer := Pointer to image buffer\r
-  FileLength := Image length in bytes\r
-  CredentialBuffer := Pointer to credential buffer\r
-  CredentialLength := Credential length in bytes\r
-\r
-Returns:\r
-  TRUE := verified\r
-  FALSE := not verified\r
---*/\r
-{\r
-  EFI_BIS_PROTOCOL        *BisPtr;\r
-  BIS_APPLICATION_HANDLE  BisAppHandle;\r
-  EFI_BIS_DATA            FileData;\r
-  EFI_BIS_DATA            CredentialData;\r
-  EFI_STATUS              EfiStatus;\r
-  BOOLEAN                 IsVerified;\r
-\r
-  if (Private == NULL || FileBuffer == NULL || FileLength == 0 || CredentialBuffer == NULL || CredentialLength == 0) {\r
-    return FALSE;\r
-  }\r
-\r
-  BisPtr = PxebcBisStart (Private, &BisAppHandle, NULL);\r
-\r
-  if (BisPtr == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  FileData.Length       = (UINT32) FileLength;\r
-  FileData.Data         = FileBuffer;\r
-  CredentialData.Length = (UINT32) CredentialLength;\r
-  CredentialData.Data   = CredentialBuffer;\r
-\r
-  EfiStatus = BisPtr->VerifyBootObject (\r
-                        BisAppHandle,\r
-                        &CredentialData,\r
-                        &FileData,\r
-                        &IsVerified\r
-                        );\r
-\r
-  PxebcBisStop (BisPtr, BisAppHandle, NULL);\r
-\r
-  return (BOOLEAN) ((EFI_ERROR (EfiStatus)) ? FALSE : (IsVerified ? TRUE : FALSE));\r
-}\r
-\r
-BOOLEAN\r
-PxebcBisDetect (\r
-  PXE_BASECODE_DEVICE *Private\r
-  )\r
-/*++\r
-Routine description:\r
-  Check for BIS interface presence.\r
-\r
-Parameters:\r
-  Private := Pointer to PxeBc interface\r
-\r
-Returns:\r
-  TRUE := BIS present\r
-  FALSE := BIS not present\r
---*/\r
-{\r
-  EFI_BIS_PROTOCOL        *BisPtr;\r
-  BIS_APPLICATION_HANDLE  BisAppHandle;\r
-  EFI_BIS_DATA            *BisDataSigInfo;\r
-\r
-  BisPtr = PxebcBisStart (Private, &BisAppHandle, &BisDataSigInfo);\r
-\r
-  if (BisPtr == NULL) {\r
-    return FALSE;\r
-  }\r
-\r
-  PxebcBisStop (BisPtr, BisAppHandle, BisDataSigInfo);\r
-\r
-  return TRUE;\r
-}\r
-\r
-VOID *BCNotifyReg;\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BcStart (\r
-  IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
-  IN BOOLEAN                    UseIPv6\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Start and initialize the BaseCode protocol, Simple Network protocol and UNDI.\r
-\r
-  Arguments:\r
-    Private                - Pointer to Pxe BaseCode Protocol\r
-    UseIPv6            - Do we want to support IPv6?\r
-\r
-  Returns:\r
-    EFI_SUCCESS\r
-    EFI_INVALID_PARAMETER\r
-    EFI_UNSUPPORTED\r
-    EFI_ALREADY_STARTED\r
-    EFI_OUT_OF_RESOURCES\r
-    Status is also returned from SNP.Start() and SNP.Initialize().\r
-\r
---*/\r
-{\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;\r
-  EFI_STATUS                  StatCode;\r
-  PXE_BASECODE_DEVICE         *Private;\r
-\r
-  //\r
-  // Lock the instance data\r
-  //\r
-  StatCode = EFI_SUCCESS;\r
-\r
-  if (This == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
-\r
-  if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  //\r
-  // Make sure BaseCode is not already started.\r
-  //\r
-  if (This->Mode->Started) {\r
-    DEBUG ((EFI_D_WARN, "\nBcStart()  BC is already started.\n"));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
-  //\r
-  // Fail if IPv6 is requested and not supported.\r
-  //\r
-  if (UseIPv6) {\r
-    DEBUG ((EFI_D_WARN, "\nBcStart()  IPv6 is not supported.\n"));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  //\r
-  // Setup shortcuts to SNP protocol and data structure.\r
-  //\r
-  SnpPtr      = Private->SimpleNetwork;\r
-  SnpModePtr  = SnpPtr->Mode;\r
-\r
-  //\r
-  // Start and initialize SNP.\r
-  //\r
-  if (SnpModePtr->State == EfiSimpleNetworkStopped) {\r
-    StatCode = (*SnpPtr->Start) (SnpPtr);\r
-\r
-    if (SnpModePtr->State != EfiSimpleNetworkStarted) {\r
-      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not start SNP.\n"));\r
-      EfiReleaseLock (&Private->Lock);\r
-      return StatCode;\r
-    }\r
-  }\r
-  //\r
-  // acquire memory for mode and transmit/receive buffers\r
-  //\r
-  if (SnpModePtr->State == EfiSimpleNetworkStarted) {\r
-    StatCode = (*SnpPtr->Initialize) (SnpPtr, 0, 0);\r
-\r
-    if (SnpModePtr->State != EfiSimpleNetworkInitialized) {\r
-      DEBUG ((EFI_D_WARN, "\nBcStart()  Could not initialize SNP."));\r
-      EfiReleaseLock (&Private->Lock);\r
-      return StatCode;\r
-    }\r
-  }\r
-  //\r
-  // Dump debug info.\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\nBC Start()"));\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->State                    %Xh",\r
-    SnpModePtr->State)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->HwAddressSize            %Xh",\r
-    SnpModePtr->HwAddressSize)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MediaHeaderSize          %Xh",\r
-    SnpModePtr->MediaHeaderSize)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MaxPacketSize            %Xh",\r
-    SnpModePtr->MaxPacketSize)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MacAddressChangeable     %Xh",\r
-    SnpModePtr->MacAddressChangeable)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MultipleTxSupported      %Xh",\r
-    SnpModePtr->MultipleTxSupported)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->CurrentAddress           %Xh",\r
-     *((UINTN *)&SnpModePtr->CurrentAddress))\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->BroadcastAddress         %Xh",\r
-    *((UINTN *)&SnpModePtr->BroadcastAddress))\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->PermanentAddress         %Xh",\r
-    *((UINTN *)&SnpModePtr->PermanentAddress))\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->NvRamSize                %Xh",\r
-    SnpModePtr->NvRamSize)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->NvRamAccessSize          %Xh",\r
-    SnpModePtr->NvRamAccessSize)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->ReceiveFilterMask        %Xh",\r
-    SnpModePtr->ReceiveFilterMask)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->ReceiveFilterSetting     %Xh",\r
-    SnpModePtr->ReceiveFilterSetting)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MCastFilterCount         %Xh",\r
-    SnpModePtr->MCastFilterCount)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MCastFilter              %Xh",\r
-    SnpModePtr->MCastFilter)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->IfType                   %Xh",\r
-    SnpModePtr->IfType)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MediaPresentSupported    %Xh",\r
-    SnpModePtr->MediaPresentSupported)\r
-    );\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nSnpModePtr->MediaPresent             %Xh",\r
-    SnpModePtr->MediaPresent)\r
-    );\r
-\r
-  //\r
-  // If media check is supported and there is no media,\r
-  // return error to caller.\r
-  //\r
-  if (SnpModePtr->MediaPresentSupported && !SnpModePtr->MediaPresent) {\r
-    DEBUG ((EFI_D_WARN, "\nBcStart()  Media not present.\n"));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_NO_MEDIA;\r
-  }\r
-  //\r
-  // Allocate Tx/Rx buffers\r
-  //\r
-  Private->TransmitBufferPtr = AllocateZeroPool (BUFFER_ALLOCATE_SIZE);\r
-  if (Private->TransmitBufferPtr == NULL) {\r
-    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc TxBuf.\n"));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Private->ReceiveBufferPtr = AllocateZeroPool (BUFFER_ALLOCATE_SIZE);\r
-  if (Private->ReceiveBufferPtr == NULL) {\r
-    DEBUG ((EFI_D_NET, "\nBcStart()  Could not alloc RxBuf.\n"));\r
-    FreePool (Private->TransmitBufferPtr);\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Private->TftpErrorBuffer = AllocatePool (256);\r
-  if (Private->TftpErrorBuffer == NULL) {\r
-    FreePool (Private->ReceiveBufferPtr);\r
-    FreePool (Private->TransmitBufferPtr);\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Private->TftpAckBuffer = AllocatePool (256);\r
-  if (Private->TftpAckBuffer == NULL) {\r
-    FreePool (Private->TftpErrorBuffer);\r
-    FreePool (Private->ReceiveBufferPtr);\r
-    FreePool (Private->TransmitBufferPtr);\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // Initialize private BaseCode instance data\r
-  //\r
-  do {\r
-    Private->RandomPort = (UINT16) (Private->RandomPort + PXE_RND_PORT_LOW + Random (Private));\r
-  } while (Private->RandomPort < PXE_RND_PORT_LOW);\r
-\r
-  Private->Igmpv1TimeoutEvent = NULL;\r
-  Private->UseIgmpv1Reporting = TRUE;\r
-  Private->IpLength           = IP_ADDRESS_LENGTH (Private->EfiBc.Mode);\r
-\r
-  //\r
-  // Initialize Mode structure\r
-  //\r
-  //\r
-  // check for callback protocol and set boolean\r
-  //\r
-  SetMakeCallback (Private);\r
-  Private->EfiBc.Mode->Started              = TRUE;\r
-  Private->EfiBc.Mode->TTL                  = DEFAULT_TTL;\r
-  Private->EfiBc.Mode->ToS                  = DEFAULT_ToS;\r
-  Private->EfiBc.Mode->UsingIpv6            = UseIPv6;\r
-  Private->EfiBc.Mode->DhcpDiscoverValid    = FALSE;\r
-  Private->EfiBc.Mode->DhcpAckReceived      = FALSE;\r
-  Private->EfiBc.Mode->ProxyOfferReceived   = FALSE;\r
-  Private->EfiBc.Mode->PxeDiscoverValid     = FALSE;\r
-  Private->EfiBc.Mode->PxeReplyReceived     = FALSE;\r
-  Private->EfiBc.Mode->PxeBisReplyReceived  = FALSE;\r
-  Private->EfiBc.Mode->IcmpErrorReceived    = FALSE;\r
-  Private->EfiBc.Mode->TftpErrorReceived    = FALSE;\r
-  ZeroMem (&Private->EfiBc.Mode->StationIp, sizeof (EFI_IP_ADDRESS));\r
-  ZeroMem (&Private->EfiBc.Mode->SubnetMask, sizeof (EFI_IP_ADDRESS));\r
-  Private->EfiBc.Mode->IpFilter.Filters   = 0;\r
-  Private->EfiBc.Mode->IpFilter.IpCnt     = 0;\r
-  Private->EfiBc.Mode->ArpCacheEntries    = 0;\r
-  Private->EfiBc.Mode->RouteTableEntries  = 0;\r
-  ZeroMem (&Private->EfiBc.Mode->IcmpError, sizeof (EFI_PXE_BASE_CODE_ICMP_ERROR));\r
-  ZeroMem (&Private->EfiBc.Mode->TftpError, sizeof (EFI_PXE_BASE_CODE_TFTP_ERROR));\r
-\r
-  //\r
-  // Set to PXE_TRUE by the BC constructor if this BC implementation\r
-  // supports IPv6.\r
-  //\r
-  Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;\r
-  Private->EfiBc.Mode->Ipv6Available = FALSE;\r
-\r
-  //\r
-  // Set to TRUE by the BC constructor if this BC implementation\r
-  // supports BIS.\r
-  //\r
-  Private->EfiBc.Mode->BisSupported = TRUE;\r
-  Private->EfiBc.Mode->BisDetected  = PxebcBisDetect (Private);\r
-\r
-  //\r
-  // This field is set to PXE_TRUE by the BC Start() function.  When this\r
-  // field is PXE_TRUE, ARP packets are sent as needed to get IP and MAC\r
-  // addresses.  This can cause unexpected delays in the DHCP(), Discover()\r
-  // and MTFTP() functions.  Setting this to PXE_FALSE will cause these\r
-  // functions to fail if the required IP/MAC information is not in the\r
-  // ARP cache.  The value of this field can be changed by an application\r
-  // at any time.\r
-  //\r
-  Private->EfiBc.Mode->AutoArp = TRUE;\r
-\r
-  //\r
-  // Unlock the instance data\r
-  //\r
-  EfiReleaseLock (&Private->Lock);\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BcStop (\r
-  IN EFI_PXE_BASE_CODE_PROTOCOL *This\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Stop the BaseCode protocol, Simple Network protocol and UNDI.\r
-\r
-  Arguments:\r
-    Private                - Pointer to Pxe BaseCode Protocol\r
-\r
-  Returns:\r
-\r
-    0                  - Successfully stopped\r
-    !0                 - Failed\r
---*/\r
-{\r
-  //\r
-  // Lock the instance data\r
-  //\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;\r
-  EFI_STATUS                  StatCode;\r
-  PXE_BASECODE_DEVICE         *Private;\r
-\r
-  StatCode = EFI_SUCCESS;\r
-\r
-  if (This == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
-\r
-  if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  SnpPtr      = Private->SimpleNetwork;\r
-  SnpModePtr  = SnpPtr->Mode;\r
-\r
-  //\r
-  // Issue BC command\r
-  //\r
-  StatCode = EFI_NOT_STARTED;\r
-\r
-  if (SnpModePtr->State == EfiSimpleNetworkInitialized) {\r
-    StatCode = (*SnpPtr->Shutdown) (SnpPtr);\r
-  }\r
-\r
-  if (SnpModePtr->State == EfiSimpleNetworkStarted) {\r
-    StatCode = (*SnpPtr->Stop) (SnpPtr);\r
-  }\r
-\r
-  if (Private->TransmitBufferPtr != NULL) {\r
-    FreePool (Private->TransmitBufferPtr);\r
-    Private->TransmitBufferPtr = NULL;\r
-  }\r
-\r
-  if (Private->ReceiveBufferPtr != NULL) {\r
-    FreePool (Private->ReceiveBufferPtr);\r
-    Private->ReceiveBufferPtr = NULL;\r
-  }\r
-\r
-  if (Private->ArpBuffer != NULL) {\r
-    FreePool (Private->ArpBuffer);\r
-    Private->ArpBuffer = NULL;\r
-  }\r
-\r
-  if (Private->TftpErrorBuffer != NULL) {\r
-    FreePool (Private->TftpErrorBuffer);\r
-    Private->TftpErrorBuffer = NULL;\r
-  }\r
-\r
-  if (Private->TftpAckBuffer != NULL) {\r
-    FreePool (Private->TftpAckBuffer);\r
-    Private->TftpAckBuffer = NULL;\r
-  }\r
-\r
-  if (Private->Igmpv1TimeoutEvent != NULL) {\r
-    gBS->CloseEvent (Private->Igmpv1TimeoutEvent);\r
-    Private->Igmpv1TimeoutEvent = NULL;\r
-  }\r
-\r
-  Private->FileSize             = 0;\r
-  Private->EfiBc.Mode->Started  = FALSE;\r
-\r
-  //\r
-  // Unlock the instance data\r
-  //\r
-  EfiReleaseLock (&Private->Lock);\r
-  return StatCode;\r
-}\r
-\r
-const IPV4_ADDR AllSystemsGroup = { { 224, 0, 0, 1 } };\r
-\r
-EFI_STATUS\r
-IpFilter (\r
-  IN PXE_BASECODE_DEVICE          *Private,\r
-  IN EFI_PXE_BASE_CODE_IP_FILTER  *Filter\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Set up the IP filter\r
-\r
-  Arguments:\r
-    Private                - Pointer to Pxe BaseCode Protocol\r
-    Filter             - Pointer to the filter\r
-\r
-  Returns:\r
-\r
-    0                  - Successfully set the filter\r
-    !0                 - Failed\r
---*/\r
-{\r
-  EFI_STATUS                  StatCode;\r
-  EFI_MAC_ADDRESS             MACadds[PXE_IP_FILTER_SIZE];\r
-  EFI_PXE_BASE_CODE_MODE      *PxebcMode;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-  EFI_SIMPLE_NETWORK_MODE     *SnpModePtr;\r
-  UINT32                      Enable;\r
-  UINT32                      Disable;\r
-  UINTN                       Index;\r
-  UINTN                       Index2;\r
-\r
-  PxebcMode   = Private->EfiBc.Mode;\r
-  SnpPtr      = Private->SimpleNetwork;\r
-  SnpModePtr  = SnpPtr->Mode;\r
-\r
-  //\r
-  // validate input parameters\r
-  // must have a filter\r
-  // must not have any extra filter bits set\r
-  //\r
-  if (Filter == NULL ||\r
-      (Filter->Filters &~FILTER_BITS)\r
-      //\r
-      // must not have a count which is too large or with no IP list\r
-      //\r
-      ||\r
-      (Filter->IpCnt && (!Filter->IpList || Filter->IpCnt > PXE_IP_FILTER_SIZE))\r
-      //\r
-      // must not have incompatible filters - promiscuous incompatible with anything else\r
-      //\r
-      ||\r
-      (\r
-        (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) &&\r
-      ((Filter->Filters &~EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) || Filter->IpCnt)\r
-    )\r
-      ) {\r
-    DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #1"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // promiscuous multicast incompatible with multicast in IP list\r
-  //\r
-  if (Filter->IpCnt && (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST)) {\r
-    for (Index = 0; Index < Filter->IpCnt; ++Index) {\r
-      if (IS_MULTICAST (&Filter->IpList[Index])) {\r
-        DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #2"));\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-  //\r
-  // leave groups for all those multicast which are no longer enabled\r
-  //\r
-  for (Index = 0; Index < PxebcMode->IpFilter.IpCnt; ++Index) {\r
-    if (!IS_MULTICAST (&PxebcMode->IpFilter.IpList[Index])) {\r
-      continue;\r
-    }\r
-\r
-    for (Index2 = 0; Index2 < Filter->IpCnt; ++Index2) {\r
-      if (!CompareMem (&PxebcMode->IpFilter.IpList[Index], &Filter->IpList[Index2], IP_ADDRESS_LENGTH (PxebcMode))) {\r
-        //\r
-        // still enabled\r
-        //\r
-        break;\r
-      }\r
-    }\r
-    //\r
-    // if we didn't find it, remove from group\r
-    //\r
-    if (Index2 == Filter->IpCnt) {\r
-      IgmpLeaveGroup (Private, &PxebcMode->IpFilter.IpList[Index]);\r
-    }\r
-  }\r
-  //\r
-  // set enable bits, convert multicast ip adds, join groups\r
-  // allways leave receive broadcast enabled at hardware layer\r
-  //\r
-  Index2 = 0;\r
-\r
-  if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS) {\r
-    Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;\r
-  } else {\r
-    if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_PROMISCUOUS_MULTICAST) {\r
-      Enable = EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;\r
-    } else {\r
-      Enable = EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;\r
-\r
-      for (Index = 0; Index < Filter->IpCnt; ++Index) {\r
-        CopyMem (&(PxebcMode->IpFilter.IpList[Index]), &(Filter->IpList[Index]), sizeof (EFI_IP_ADDRESS));\r
-\r
-        if (IS_MULTICAST (&Filter->IpList[Index])) {\r
-          EFI_IP_ADDRESS  *TmpIp;\r
-\r
-          Enable |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;\r
-\r
-          //\r
-          // if this is the first group, add the all systems group to mcast list\r
-          //\r
-          if (!Index2)\r
-          {\r
-            TmpIp = (EFI_IP_ADDRESS *) &AllSystemsGroup;\r
-            --Index;\r
-          } else {\r
-            TmpIp = (EFI_IP_ADDRESS *) &Filter->IpList[Index];\r
-          }\r
-          //\r
-          // get MAC address of IP\r
-          //\r
-          StatCode = (*SnpPtr->MCastIpToMac) (SnpPtr, PxebcMode->UsingIpv6, TmpIp, &MACadds[Index2++]);\r
-\r
-          if (EFI_ERROR (StatCode)) {\r
-            DEBUG (\r
-              (EFI_D_INFO,\r
-              "\nIpFilter()  Exit #2  %Xh (%r)",\r
-              StatCode,\r
-              StatCode)\r
-              );\r
-            return StatCode;\r
-          }\r
-        } else {\r
-          Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
-        }\r
-      }\r
-    }\r
-\r
-    if (Filter->Filters & EFI_PXE_BASE_CODE_IP_FILTER_STATION_IP) {\r
-      Enable |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;\r
-    }\r
-  }\r
-  //\r
-  // if nothing changed, just return\r
-  //\r
-  DEBUG (\r
-    (EFI_D_INFO,\r
-    "\nsnp->ReceiveFilterSetting == %Xh  Filter->IpCnt == %Xh",\r
-    SnpModePtr->ReceiveFilterSetting,\r
-    Filter->IpCnt)\r
-    );\r
-\r
-  if (SnpModePtr->ReceiveFilterSetting == Enable && !Filter->IpCnt) {\r
-    DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #4"));\r
-    return EFI_SUCCESS;\r
-  }\r
-  //\r
-  // disable those currently set but not set in new filter\r
-  //\r
-  Disable                   = SnpModePtr->ReceiveFilterSetting &~Enable;\r
-\r
-  StatCode                  = SnpPtr->ReceiveFilters (SnpPtr, Enable, Disable, FALSE, Index2, MACadds);\r
-\r
-  PxebcMode->IpFilter.IpCnt = Filter->IpCnt;\r
-\r
-  //\r
-  // join groups for all multicast in list\r
-  //\r
-  for (Index = 0; Index < Filter->IpCnt; ++Index) {\r
-    if (IS_MULTICAST (&Filter->IpList[Index])) {\r
-      IgmpJoinGroup (Private, &Filter->IpList[Index]);\r
-    }\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "\nIpFilter()  Exit #5  %Xh (%r)", StatCode, StatCode));\r
-\r
-  return StatCode;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BcIpFilter (\r
-  IN EFI_PXE_BASE_CODE_PROTOCOL  *This,\r
-  IN EFI_PXE_BASE_CODE_IP_FILTER *Filter\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Call the IP filter\r
-\r
-  Arguments:\r
-    Private                - Pointer to Pxe BaseCode Protocol\r
-    Filter             - Pointer to the filter\r
-\r
-  Returns:\r
-\r
-    0                  - Successfully set the filter\r
-    !0                 - Failed\r
---*/\r
-{\r
-  EFI_STATUS          StatCode;\r
-  PXE_BASECODE_DEVICE *Private;\r
-\r
-  //\r
-  // Lock the instance data and make sure started\r
-  //\r
-  StatCode = EFI_SUCCESS;\r
-\r
-  if (This == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
-\r
-  if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  if (This->Mode == NULL || !This->Mode->Started) {\r
-    DEBUG ((EFI_D_ERROR, "BC was not started."));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_NOT_STARTED;\r
-  }\r
-\r
-  if (Filter == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-  //\r
-  // Issue BC command\r
-  //\r
-  StatCode = IpFilter (Private, Filter);\r
-\r
-  //\r
-  // Unlock the instance data\r
-  //\r
-  EfiReleaseLock (&Private->Lock);\r
-  return StatCode;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-BcSetParameters (\r
-  EFI_PXE_BASE_CODE_PROTOCOL  *This,\r
-  BOOLEAN                     *AutoArpPtr,\r
-  BOOLEAN                     *SendGuidPtr,\r
-  UINT8                       *TimeToLivePtr,\r
-  UINT8                       *TypeOfServicePtr,\r
-  BOOLEAN                     *MakeCallbackPtr\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Set the Base Code behavior parameters\r
-\r
-  Arguments:\r
-    This               - Pointer to Pxe BaseCode Protocol\r
-    AutoArpPtr           - Boolean to do ARP stuff\r
-    SendGuidPtr          - Boolean whether or not to send GUID info\r
-    TimeToLivePtr               - Value for Total time to live\r
-    TypeOfServicePtr               - Value for Type of Service\r
-    MakeCallbackPtr      - Boolean to determine if we make callbacks\r
-\r
-  Returns:\r
-\r
-    0                  - Successfully set the parameters\r
-    !0                 - Failed\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_MODE  *PxebcMode;\r
-  EFI_GUID                TmpGuid;\r
-  CHAR8                   *SerialNumberPtr;\r
-  EFI_STATUS              StatCode;\r
-  PXE_BASECODE_DEVICE     *Private;\r
-\r
-  //\r
-  // Lock the instance data and make sure started\r
-  //\r
-  StatCode = EFI_SUCCESS;\r
-\r
-  if (This == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
-\r
-  if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  if (This->Mode == NULL || !This->Mode->Started) {\r
-    DEBUG ((EFI_D_ERROR, "BC was not started."));\r
-    EfiReleaseLock (&Private->Lock);\r
-    return EFI_NOT_STARTED;\r
-  }\r
-\r
-  DEBUG ((EFI_D_INFO, "\nSetParameters()  Entry.  "));\r
-\r
-  PxebcMode = Private->EfiBc.Mode;\r
-  StatCode  = EFI_SUCCESS;\r
-\r
-  if (SendGuidPtr != NULL) {\r
-    if (*SendGuidPtr) {\r
-      if (PxeBcLibGetSmbiosSystemGuidAndSerialNumber (&TmpGuid, &SerialNumberPtr) != EFI_SUCCESS) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-  }\r
-\r
-  if (MakeCallbackPtr != NULL) {\r
-    if (*MakeCallbackPtr) {\r
-      if (!SetMakeCallback (Private)) {\r
-        return EFI_INVALID_PARAMETER;\r
-      }\r
-    }\r
-\r
-    PxebcMode->MakeCallbacks = *MakeCallbackPtr;\r
-  }\r
-\r
-  if (AutoArpPtr != NULL) {\r
-    PxebcMode->AutoArp = *AutoArpPtr;\r
-  }\r
-\r
-  if (SendGuidPtr != NULL) {\r
-    PxebcMode->SendGUID = *SendGuidPtr;\r
-  }\r
-\r
-  if (TimeToLivePtr != NULL) {\r
-    PxebcMode->TTL = *TimeToLivePtr;\r
-  }\r
-\r
-  if (TypeOfServicePtr != NULL) {\r
-    PxebcMode->ToS = *TypeOfServicePtr;\r
-  }\r
-  //\r
-  // Unlock the instance data\r
-  //\r
-  DEBUG ((EFI_D_INFO, "\nSetparameters()  Exit = %xh  ", StatCode));\r
-\r
-  EfiReleaseLock (&Private->Lock);\r
-  return StatCode;\r
-}\r
-//\r
-// //////////////////////////////////////////////////////////\r
-//\r
-//  BC Set Station IP Routine\r
-//\r
-EFI_STATUS\r
-EFIAPI\r
-BcSetStationIP (\r
-  IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
-  IN EFI_IP_ADDRESS             *StationIpPtr,\r
-  IN EFI_IP_ADDRESS             *SubnetMaskPtr\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Set the station IP address\r
-\r
-  Arguments:\r
-    This                 - Pointer to Pxe BaseCode Protocol\r
-    StationIpPtr         - Pointer to the requested IP address to set in base code\r
-    SubnetMaskPtr        - Pointer to the requested subnet mask for the base code\r
-\r
-  Returns:\r
-\r
-    EFI_SUCCESS          - Successfully set the parameters\r
-    EFI_NOT_STARTED      - BC has not started\r
---*/\r
-{\r
-  EFI_PXE_BASE_CODE_MODE  *PxebcMode;\r
-  EFI_STATUS              StatCode;\r
-  PXE_BASECODE_DEVICE     *Private;\r
-  UINT32                  SubnetMask;\r
-\r
-  //\r
-  // Lock the instance data and make sure started\r
-  //\r
-  StatCode = EFI_SUCCESS;\r
-\r
-  if (This == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "BC *This pointer == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Private = CR (This, PXE_BASECODE_DEVICE, EfiBc, PXE_BASECODE_DEVICE_SIGNATURE);\r
-\r
-  if (Private == NULL) {\r
-    DEBUG ((EFI_D_ERROR, "PXE_BASECODE_DEVICE poiner == NULL"));\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  if (This->Mode == NULL || !This->Mode->Started) {\r
-    DEBUG ((EFI_D_ERROR, "BC was not started."));\r
-    StatCode = EFI_NOT_STARTED;\r
-    goto RELEASE_LOCK;\r
-  }\r
-\r
-  PxebcMode = Private->EfiBc.Mode;\r
-\r
-  if (!Private->GoodStationIp && ((StationIpPtr == NULL) || (SubnetMaskPtr == NULL))) {\r
-    //\r
-    // It's not allowed to only set one of the two addresses while there isn't a previous\r
-    // GOOD address configuration.\r
-    //\r
-    StatCode = EFI_INVALID_PARAMETER;\r
-    goto RELEASE_LOCK;\r
-  }\r
-\r
-  if (SubnetMaskPtr != NULL) {\r
-    SubnetMask = SubnetMaskPtr->Addr[0];\r
-\r
-    if (SubnetMask & (SubnetMask + 1)) {\r
-      //\r
-      // the subnet mask is valid if it's with leading continuous 1 bits.\r
-      //\r
-      StatCode = EFI_INVALID_PARAMETER;\r
-      goto RELEASE_LOCK;\r
-    }\r
-  } else {\r
-    SubnetMaskPtr = &PxebcMode->SubnetMask;\r
-    SubnetMask    = SubnetMaskPtr->Addr[0];\r
-  }\r
-\r
-  if (StationIpPtr == NULL) {\r
-    StationIpPtr = &PxebcMode->StationIp;\r
-  }\r
-\r
-  if (!IS_INADDR_UNICAST (StationIpPtr) ||\r
-      ((StationIpPtr->Addr[0] | SubnetMask) == BROADCAST_IPv4)) {\r
-    //\r
-    // The station IP is not a unicast address.\r
-    //\r
-    StatCode = EFI_INVALID_PARAMETER;\r
-    goto RELEASE_LOCK;\r
-  }\r
-\r
-  CopyMem (&PxebcMode->StationIp, StationIpPtr, sizeof (EFI_IP_ADDRESS));\r
-  CopyMem (&PxebcMode->SubnetMask, SubnetMaskPtr, sizeof (EFI_IP_ADDRESS));\r
-\r
-  Private->GoodStationIp = TRUE;\r
-\r
-RELEASE_LOCK:\r
-  //\r
-  // Unlock the instance data\r
-  //\r
-  EfiReleaseLock (&Private->Lock);\r
-\r
-  return StatCode;\r
-}\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gPxeBcDriverBinding = {\r
-  PxeBcDriverSupported,\r
-  PxeBcDriverStart,\r
-  PxeBcDriverStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PxeBcDriverSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Test to see if this driver supports Controller. Any Controller\r
-    than contains a Snp protocol can be supported.\r
-\r
-  Arguments:\r
-    This                - Protocol instance pointer.\r
-    Controller          - Handle of device to test.\r
-    RemainingDevicePath - Not used.\r
-\r
-  Returns:\r
-    EFI_SUCCESS         - This driver supports this device.\r
-    EFI_ALREADY_STARTED - This driver is already running on this device.\r
-    other               - This driver does not support this device.\r
-\r
---*/\r
-{\r
-  EFI_STATUS                  Status;\r
-  EFI_SIMPLE_NETWORK_PROTOCOL *SnpPtr;\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiDevicePathProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  (VOID **) &SnpPtr,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-\r
-  gBS->CloseProtocol (\r
-        Controller,\r
-        &gEfiSimpleNetworkProtocolGuid,\r
-        This->DriverBindingHandle,\r
-        Controller\r
-        );\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PxeBcDriverStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN EFI_HANDLE                     Controller,\r
-  IN EFI_DEVICE_PATH_PROTOCOL       *RemainingDevicePath\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Start the Base code driver.\r
-\r
-  Arguments:\r
-    This                - Protocol instance pointer.\r
-    Controller          - Handle of device to test.\r
-    RemainingDevicePath - Not used.\r
-\r
-  Returns:\r
-    EFI_SUCCESS         - This driver supports this device.\r
-    EFI_ALREADY_STARTED - This driver is already running on this device.\r
-    other               - This driver does not support this device.\r
-\r
---*/\r
-{\r
-  EFI_STATUS          Status;\r
-  PXE_BASECODE_DEVICE *Private;\r
-  LOADFILE_DEVICE     *pLF;\r
-\r
-  //\r
-  // Allocate structures needed by BaseCode and LoadFile protocols.\r
-  //\r
-  Private = AllocateZeroPool (sizeof (PXE_BASECODE_DEVICE));\r
-\r
-  if (Private == NULL ) {\r
-    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc PXE_BASECODE_DEVICE structure.\n"));\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  pLF = AllocateZeroPool (sizeof (LOADFILE_DEVICE));\r
-  if (pLF == NULL) {\r
-    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc LOADFILE_DEVICE structure.\n"));\r
-    FreePool (Private);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  Private->EfiBc.Mode = AllocateZeroPool (sizeof (EFI_PXE_BASE_CODE_MODE));\r
-  if (Private->EfiBc.Mode == NULL) {\r
-    DEBUG ((EFI_D_NET, "\nBcNotifySnp()  Could not alloc Mode structure.\n"));\r
-    FreePool (Private);\r
-    FreePool (pLF);\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-  //\r
-  // Lock access, just in case\r
-  //\r
-  EfiInitializeLock (&Private->Lock, TPL_CALLBACK);\r
-  EfiAcquireLock (&Private->Lock);\r
-\r
-  EfiInitializeLock (&pLF->Lock, TPL_CALLBACK);\r
-  EfiAcquireLock (&pLF->Lock);\r
-\r
-  //\r
-  // Initialize PXE structure\r
-  //\r
-  //\r
-  // First initialize the internal 'private' data that the application\r
-  // does not see.\r
-  //\r
-  Private->Signature  = PXE_BASECODE_DEVICE_SIGNATURE;\r
-  Private->Handle     = Controller;\r
-\r
-  //\r
-  // Get the NII interface\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiNetworkInterfaceIdentifierProtocolGuid_31,\r
-                  (VOID **) &Private->NiiPtr,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    Status = gBS->OpenProtocol (\r
-                    Controller,\r
-                    &gEfiNetworkInterfaceIdentifierProtocolGuid,\r
-                    (VOID **) &Private->NiiPtr,\r
-                    This->DriverBindingHandle,\r
-                    Controller,\r
-                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                    );\r
-\r
-    if (EFI_ERROR (Status)) {\r
-      goto PxeBcError;\r
-    }\r
-  }\r
-  //\r
-  // Get the Snp interface\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiSimpleNetworkProtocolGuid,\r
-                  (VOID **) &Private->SimpleNetwork,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto PxeBcError;\r
-  }\r
-\r
-  //\r
-  // Next, initialize the external 'public' data that\r
-  // the application does see.\r
-  //\r
-  Private->EfiBc.Revision       = EFI_PXE_BASE_CODE_INTERFACE_REVISION;\r
-  Private->EfiBc.Start          = BcStart;\r
-  Private->EfiBc.Stop           = BcStop;\r
-  Private->EfiBc.Dhcp           = BcDhcp;\r
-  Private->EfiBc.Discover       = BcDiscover;\r
-  Private->EfiBc.Mtftp          = BcMtftp;\r
-  Private->EfiBc.UdpWrite       = BcUdpWrite;\r
-  Private->EfiBc.UdpRead        = BcUdpRead;\r
-  Private->EfiBc.Arp            = BcArp;\r
-  Private->EfiBc.SetIpFilter    = BcIpFilter;\r
-  Private->EfiBc.SetParameters  = BcSetParameters;\r
-  Private->EfiBc.SetStationIp   = BcSetStationIP;\r
-  Private->EfiBc.SetPackets     = BcSetPackets;\r
-\r
-  //\r
-  // Initialize BaseCode Mode structure\r
-  //\r
-  Private->EfiBc.Mode->Started    = FALSE;\r
-  Private->EfiBc.Mode->TTL        = DEFAULT_TTL;\r
-  Private->EfiBc.Mode->ToS        = DEFAULT_ToS;\r
-  Private->EfiBc.Mode->UsingIpv6  = FALSE;\r
-  Private->EfiBc.Mode->AutoArp    = TRUE;\r
-\r
-  //\r
-  // Set to PXE_TRUE by the BC constructor if this BC\r
-  // implementation supports IPv6.\r
-  //\r
-  Private->EfiBc.Mode->Ipv6Supported = SUPPORT_IPV6;\r
-  Private->EfiBc.Mode->Ipv6Available = FALSE;\r
-\r
-  //\r
-  // Set to TRUE by the BC constructor if this BC\r
-  // implementation supports BIS.\r
-  //\r
-  Private->EfiBc.Mode->BisSupported = TRUE;\r
-  Private->EfiBc.Mode->BisDetected  = PxebcBisDetect (Private);\r
-\r
-  //\r
-  // Initialize LoadFile structure.\r
-  //\r
-  pLF->Signature          = LOADFILE_DEVICE_SIGNATURE;\r
-  pLF->LoadFile.LoadFile  = LoadFile;\r
-  pLF->Private            = Private;\r
-\r
-  //\r
-  // Install protocol interfaces.\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &Controller,\r
-                  &gEfiPxeBaseCodeProtocolGuid,\r
-                  &Private->EfiBc,\r
-                  &gEfiLoadFileProtocolGuid,\r
-                  &pLF->LoadFile,\r
-                  NULL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->CloseProtocol (\r
-          Controller,\r
-          &gEfiSimpleNetworkProtocolGuid,\r
-          This->DriverBindingHandle,\r
-          Controller\r
-          );\r
-\r
-    goto PxeBcError;\r
-  }\r
-  //\r
-  // Release locks.\r
-  //\r
-  EfiReleaseLock (&pLF->Lock);\r
-  EfiReleaseLock (&Private->Lock);\r
-  return Status;\r
-\r
-PxeBcError: ;\r
-  FreePool (Private->EfiBc.Mode);\r
-  FreePool (Private);\r
-  FreePool (pLF);\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-PxeBcDriverStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL    *This,\r
-  IN  EFI_HANDLE                     Controller,\r
-  IN  UINTN                          NumberOfChildren,\r
-  IN  EFI_HANDLE                     *ChildHandleBuffer\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Stop the Base code driver.\r
-\r
-  Arguments:\r
-    This                - Protocol instance pointer.\r
-    Controller          - Handle of device to test.\r
-    NumberOfChildren    - Not used\r
-    ChildHandleBuffer   - Not used\r
-\r
-  Returns:\r
-    EFI_SUCCESS         - This driver supports this device.\r
-    EFI_ALREADY_STARTED - This driver is already running on this device.\r
-    other               - This driver does not support this device.\r
-\r
---*/\r
-{\r
-  EFI_STATUS              Status;\r
-  EFI_LOAD_FILE_PROTOCOL  *LfProtocol;\r
-  LOADFILE_DEVICE         *LoadDevice;\r
-\r
-  //\r
-  // Get our context back.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  Controller,\r
-                  &gEfiLoadFileProtocolGuid,\r
-                  (VOID **) &LfProtocol,\r
-                  This->DriverBindingHandle,\r
-                  Controller,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  LoadDevice = EFI_LOAD_FILE_DEV_FROM_THIS (LfProtocol);\r
-\r
-  Status = gBS->UninstallMultipleProtocolInterfaces (\r
-                  Controller,\r
-                  &gEfiLoadFileProtocolGuid,\r
-                  &LoadDevice->LoadFile,\r
-                  &gEfiPxeBaseCodeProtocolGuid,\r
-                  &LoadDevice->Private->EfiBc,\r
-                  NULL\r
-                  );\r
-\r
-  if (!EFI_ERROR (Status)) {\r
-\r
-    Status = gBS->CloseProtocol (\r
-                    Controller,\r
-                    &gEfiSimpleNetworkProtocolGuid,\r
-                    This->DriverBindingHandle,\r
-                    Controller\r
-                    );\r
-\r
-    FreePool (LoadDevice->Private->EfiBc.Mode);\r
-    FreePool (LoadDevice->Private);\r
-    FreePool (LoadDevice);\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-EFI_STATUS\r
-EFIAPI\r
-InitializeBCDriver (\r
-  IN EFI_HANDLE       ImageHandle,\r
-  IN EFI_SYSTEM_TABLE *SystemTable\r
-  )\r
-/*++\r
-\r
-  Routine Description:\r
-    Initialize the base code drivers and install the driver binding\r
-\r
-  Arguments:\r
-    Standard EFI Image Entry\r
-\r
-  Returns:\r
-    EFI_SUCCESS         - This driver was successfully bound\r
-\r
---*/\r
-{\r
-  InitArpHeader ();\r
-  OptionsStrucInit ();\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-/* eof - bc.c */\r