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