X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=MdeModulePkg%2FUniversal%2FNetwork%2FSnpDxe%2FSnp.c;h=a23af05078bc8939c7ea42dc83f2d26ad9489888;hp=213b724e5f6da7691df0fc338e3d9ba955f4189d;hb=c0fd7f734e2d33e22215899b40a47b843129541d;hpb=894d038a8d0e99d456042e2b6d1554c4a406ea70
diff --git a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
index 213b724e5f..a23af05078 100644
--- a/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
+++ b/MdeModulePkg/Universal/Network/SnpDxe/Snp.c
@@ -1,32 +1,18 @@
/** @file
Implementation of driver entry point and driver binding protocol.
-
-Copyright (c) 2004 - 2009, 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.
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.
+SPDX-License-Identifier: BSD-2-Clause-Patent
**/
#include "Snp.h"
-//
-// Module global variables needed to support undi 3.0 interface
-//
-EFI_PCI_IO_PROTOCOL *mPciIo;
-V2P *mV2p = NULL; // undi3.0 map_list head
-// End Global variables
-//
-
/**
One notified function to stop UNDI device when gBS->ExitBootServices() called.
@param Event Pointer to this event
- @param Context Event hanlder private data
+ @param Context Event handler private data
**/
VOID
@@ -49,15 +35,16 @@ SnpNotifyExitBootServices (
/**
Send command to UNDI. It does nothing currently.
-
+
@param Cdb command to be sent to UNDI.
-
- @retval EFI_INVALID_PARAMETER The command is 0.
- @retval EFI_UNSUPPORTED Default return status because it's not
+
+ @retval EFI_INVALID_PARAMETER The command is 0.
+ @retval EFI_UNSUPPORTED Default return status because it's not
supported currently.
-
+
**/
EFI_STATUS
+EFIAPI
IssueHwUndiCommand (
UINT64 Cdb
)
@@ -81,7 +68,7 @@ IssueHwUndiCommand (
@param Buffer Pointer to buffer.
@param Length Length of buffer in bytes.
- @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len
+ @return 8-bit checksum of all bytes in buffer, or zero if ptr is NULL or len
is zero.
**/
@@ -178,7 +165,7 @@ SimpleNetworkDriverSupported (
//
// Check to see if !PXE structure is valid. Paragraph alignment of !PXE structure is required.
//
- if (NiiProtocol->Id & 0x0F) {
+ if ((NiiProtocol->Id & 0x0F) != 0) {
DEBUG ((EFI_D_NET, "\n!PXE structure is not paragraph aligned.\n"));
Status = EFI_UNSUPPORTED;
goto Done;
@@ -257,7 +244,7 @@ Done:
device to start.
@retval EFI_SUCCESS This driver is added to ControllerHandle
- @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle
+ @retval EFI_DEVICE_ERROR This driver could not be started due to a device error
@retval other This driver does not support this device
**/
@@ -276,11 +263,12 @@ SimpleNetworkDriverStart (
SNP_DRIVER *Snp;
VOID *Address;
EFI_HANDLE Handle;
- PXE_PCI_CONFIG_INFO ConfigInfo;
- PCI_TYPE00 *ConfigHeader;
- UINT32 *TempBar;
UINT8 BarIndex;
PXE_STATFLAGS InitStatFlags;
+ EFI_PCI_IO_PROTOCOL *PciIo;
+ EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *BarDesc;
+ BOOLEAN FoundIoBar;
+ BOOLEAN FoundMemoryBar;
DEBUG ((EFI_D_NET, "\nSnpNotifyNetworkInterfaceIdentifier() "));
@@ -310,7 +298,7 @@ SimpleNetworkDriverStart (
Status = gBS->OpenProtocol (
Handle,
&gEfiPciIoProtocolGuid,
- (VOID **) &mPciIo,
+ (VOID **) &PciIo,
This->DriverBindingHandle,
Controller,
EFI_OPEN_PROTOCOL_GET_PROTOCOL
@@ -366,14 +354,14 @@ SimpleNetworkDriverStart (
// OK, we like this UNDI, and we know snp is not already there on this handle
// Allocate and initialize a new simple network protocol structure.
//
- Status = mPciIo->AllocateBuffer (
- mPciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
- &Address,
- 0
- );
+ Status = PciIo->AllocateBuffer (
+ PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
+ &Address,
+ 0
+ );
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_NET, "\nCould not allocate SNP_DRIVER structure.\n"));
@@ -384,7 +372,7 @@ SimpleNetworkDriverStart (
ZeroMem (Snp, sizeof (SNP_DRIVER));
- Snp->PciIo = mPciIo;
+ Snp->PciIo = PciIo;
Snp->Signature = SNP_DRIVER_SIGNATURE;
EfiInitializeLock (&Snp->Lock, TPL_NOTIFY);
@@ -410,7 +398,20 @@ SimpleNetworkDriverStart (
Snp->TxRxBufferSize = 0;
Snp->TxRxBuffer = NULL;
- Snp->IfNum = Nii->IfNum;
+ Snp->RecycledTxBuf = AllocatePool (sizeof (UINT64) * SNP_TX_BUFFER_INCREASEMENT);
+ if (Snp->RecycledTxBuf == NULL) {
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error_DeleteSNP;
+ }
+ Snp->MaxRecycledTxBuf = SNP_TX_BUFFER_INCREASEMENT;
+ Snp->RecycledTxBufCount = 0;
+
+ if (Nii->Revision >= EFI_NETWORK_INTERFACE_IDENTIFIER_PROTOCOL_REVISION) {
+ Snp->IfNum = Nii->IfNum;
+
+ } else {
+ Snp->IfNum = (UINT8) (Nii->IfNum & 0xFF);
+ }
if ((Pxe->hw.Implementation & PXE_ROMID_IMP_HW_UNDI) != 0) {
Snp->IsSwUndi = FALSE;
@@ -440,14 +441,14 @@ SimpleNetworkDriverStart (
// -it is OK to allocate one global set of CPB, DB pair for each UNDI
// interface as EFI does not multi-task and so SNP will not be re-entered!
//
- Status = mPciIo->AllocateBuffer (
- mPciIo,
- AllocateAnyPages,
- EfiBootServicesData,
- SNP_MEM_PAGES (4096),
- &Address,
- 0
- );
+ Status = PciIo->AllocateBuffer (
+ PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ SNP_MEM_PAGES (4096),
+ &Address,
+ 0
+ );
if (Status != EFI_SUCCESS) {
DEBUG ((EFI_D_NET, "\nCould not allocate CPB and DB structures.\n"));
@@ -458,19 +459,44 @@ SimpleNetworkDriverStart (
Snp->Db = (VOID *) ((UINTN) Address + 2048);
//
- // PxeStart call is going to give the callback functions to UNDI, these callback
- // functions use the BarIndex values from the snp structure, so these must be initialized
- // with default values before doing a PxeStart. The correct values can be obtained after
- // getting the config information from UNDI
+ // Find the correct BAR to do IO.
+ //
+ // Enumerate through the PCI BARs for the device to determine which one is
+ // the IO BAR. Save the index of the BAR into the adapter info structure.
+ // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
//
Snp->MemoryBarIndex = 0;
Snp->IoBarIndex = 1;
+ FoundMemoryBar = FALSE;
+ FoundIoBar = FALSE;
+ for (BarIndex = 0; BarIndex < PCI_MAX_BAR; BarIndex++) {
+ Status = PciIo->GetBarAttributes (
+ PciIo,
+ BarIndex,
+ NULL,
+ (VOID**) &BarDesc
+ );
+ if (Status == EFI_UNSUPPORTED) {
+ continue;
+ } else if (EFI_ERROR (Status)) {
+ goto Error_DeleteSNP;
+ }
+
+ if ((!FoundMemoryBar) && (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_MEM)) {
+ Snp->MemoryBarIndex = BarIndex;
+ FoundMemoryBar = TRUE;
+ } else if ((!FoundIoBar) && (BarDesc->ResType == ACPI_ADDRESS_SPACE_TYPE_IO)) {
+ Snp->IoBarIndex = BarIndex;
+ FoundIoBar = TRUE;
+ }
+
+ FreePool (BarDesc);
+
+ if (FoundMemoryBar && FoundIoBar) {
+ break;
+ }
+ }
- //
- // we need the undi init information many times in this snp code, just get it
- // once here and store it in the snp driver structure. to get Init Info
- // from UNDI we have to start undi first.
- //
Status = PxeStart (Snp);
if (Status != EFI_SUCCESS) {
@@ -483,8 +509,8 @@ SimpleNetworkDriverStart (
Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
Snp->Cdb.CPBaddr = PXE_DBADDR_NOT_USED;
- Snp->Cdb.DBsize = sizeof Snp->InitInfo;
- Snp->Cdb.DBaddr = (UINT64)(UINTN) &Snp->InitInfo;
+ Snp->Cdb.DBsize = (UINT16) sizeof (Snp->InitInfo);
+ Snp->Cdb.DBaddr = (UINT64)(UINTN) (&Snp->InitInfo);
Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
@@ -507,57 +533,6 @@ SimpleNetworkDriverStart (
goto Error_DeleteSNP;
}
- Snp->Cdb.OpCode = PXE_OPCODE_GET_CONFIG_INFO;
- Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
-
- Snp->Cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
- Snp->Cdb.CPBaddr = PXE_DBADDR_NOT_USED;
-
- Snp->Cdb.DBsize = sizeof ConfigInfo;
- Snp->Cdb.DBaddr = (UINT64)(UINTN) &ConfigInfo;
-
- Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
- Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
-
- Snp->Cdb.IFnum = Snp->IfNum;
- Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
-
- DEBUG ((EFI_D_NET, "\nSnp->undi.get_config_info() "));
-
- (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
-
- if (Snp->Cdb.StatCode != PXE_STATCODE_SUCCESS) {
- DEBUG ((EFI_D_NET, "\nSnp->undi.config_info() %xh:%xh\n", Snp->Cdb.StatFlags, Snp->Cdb.StatCode));
- PxeStop (Snp);
- goto Error_DeleteSNP;
- }
- //
- // Find the correct BAR to do IO.
- //
- //
- // Enumerate through the PCI BARs for the device to determine which one is
- // the IO BAR. Save the index of the BAR into the adapter info structure.
- // for regular 32bit BARs, 0 is memory mapped, 1 is io mapped
- //
- ConfigHeader = (PCI_TYPE00 *) &ConfigInfo.Config.Byte[0];
- TempBar = (UINT32 *) &ConfigHeader->Device.Bar[0];
- for (BarIndex = 0; BarIndex <= 5; BarIndex++) {
- if ((*TempBar & PCI_BAR_MEM_MASK) == PCI_BAR_MEM_64BIT) {
- //
- // This is a 64-bit memory bar, skip this and the
- // next bar as well.
- //
- TempBar++;
- }
-
- if ((*TempBar & PCI_BAR_IO_MASK) == PCI_BAR_IO_MODE) {
- Snp->IoBarIndex = BarIndex;
- break;
- }
-
- TempBar++;
- }
-
//
// Initialize simple network protocol mode structure
//
@@ -573,12 +548,26 @@ SimpleNetworkDriverStart (
switch (InitStatFlags & PXE_STATFLAGS_CABLE_DETECT_MASK) {
case PXE_STATFLAGS_CABLE_DETECT_SUPPORTED:
- Snp->Mode.MediaPresentSupported = TRUE;
+ Snp->CableDetectSupported = TRUE;
break;
case PXE_STATFLAGS_CABLE_DETECT_NOT_SUPPORTED:
default:
- Snp->Mode.MediaPresentSupported = FALSE;
+ Snp->CableDetectSupported = FALSE;
+ }
+
+ switch (InitStatFlags & PXE_STATFLAGS_GET_STATUS_NO_MEDIA_MASK) {
+ case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_SUPPORTED:
+ Snp->MediaStatusSupported = TRUE;
+ break;
+
+ case PXE_STATFLAGS_GET_STATUS_NO_MEDIA_NOT_SUPPORTED:
+ default:
+ Snp->MediaStatusSupported = FALSE;
+ }
+
+ if (Snp->CableDetectSupported || Snp->MediaStatusSupported) {
+ Snp->Mode.MediaPresentSupported = TRUE;
}
if ((Pxe->hw.Implementation & PXE_ROMID_IMP_STATION_ADDR_SETTABLE) != 0) {
@@ -615,7 +604,7 @@ SimpleNetworkDriverStart (
}
- if (Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) {
+ if ((Pxe->hw.Implementation & PXE_ROMID_IMP_PROMISCUOUS_MULTICAST_RX_SUPPORTED) != 0) {
Snp->Mode.ReceiveFilterMask |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
}
@@ -687,19 +676,23 @@ SimpleNetworkDriverStart (
return Status;
}
- Status = mPciIo->FreeBuffer (
- mPciIo,
- SNP_MEM_PAGES (4096),
- Snp->Cpb
- );
+ PciIo->FreeBuffer (
+ PciIo,
+ SNP_MEM_PAGES (4096),
+ Snp->Cpb
+ );
Error_DeleteSNP:
- mPciIo->FreeBuffer (
- mPciIo,
- SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
- Snp
- );
+ if (Snp->RecycledTxBuf != NULL) {
+ FreePool (Snp->RecycledTxBuf);
+ }
+
+ PciIo->FreeBuffer (
+ PciIo,
+ SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
+ Snp
+ );
NiiError:
gBS->CloseProtocol (
Controller,
@@ -715,6 +708,13 @@ NiiError:
Controller
);
+ //
+ // If we got here that means we are in error state.
+ //
+ if (!EFI_ERROR (Status)) {
+ Status = EFI_DEVICE_ERROR;
+ }
+
return Status;
}
@@ -725,7 +725,7 @@ NiiError:
restrictions for this service. DisconnectController()
must follow these calling restrictions. If any other agent wishes
to call Stop() it must also follow these calling restrictions.
-
+
@param This Protocol instance pointer.
@param ControllerHandle Handle of device to stop driver on
@param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of
@@ -748,6 +748,7 @@ SimpleNetworkDriverStop (
EFI_STATUS Status;
EFI_SIMPLE_NETWORK_PROTOCOL *SnpProtocol;
SNP_DRIVER *Snp;
+ EFI_PCI_IO_PROTOCOL *PciIo;
//
// Get our context back.
@@ -799,17 +800,20 @@ SimpleNetworkDriverStop (
PxeShutdown (Snp);
PxeStop (Snp);
- mPciIo->FreeBuffer (
- mPciIo,
- SNP_MEM_PAGES (4096),
- Snp->Cpb
- );
+ FreePool (Snp->RecycledTxBuf);
- mPciIo->FreeBuffer (
- mPciIo,
- SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
- Snp
- );
+ PciIo = Snp->PciIo;
+ PciIo->FreeBuffer (
+ PciIo,
+ SNP_MEM_PAGES (4096),
+ Snp->Cpb
+ );
+
+ PciIo->FreeBuffer (
+ PciIo,
+ SNP_MEM_PAGES (sizeof (SNP_DRIVER)),
+ Snp
+ );
return Status;
}
@@ -817,7 +821,7 @@ SimpleNetworkDriverStop (
//
// Simple Network Protocol Driver Global Variables
//
-EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {
+EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding = {
SimpleNetworkDriverSupported,
SimpleNetworkDriverStart,
SimpleNetworkDriverStop,
@@ -826,159 +830,6 @@ EFI_DRIVER_BINDING_PROTOCOL mSimpleNetworkDriverBinding = {
NULL
};
-
-/**
- This routine maps the given CPU address to a Device address. It creates a
- an entry in the map list with the virtual and physical addresses and the
- un map cookie.
-
- @param V2p pointer to return a map list node pointer.
- @param Type the direction in which the data flows from the given
- virtual address device->cpu or cpu->device or both
- ways.
- @param VirtualAddress virtual address (or CPU address) to be mapped.
- @param BufferSize size of the buffer to be mapped.
-
- @retval EFI_SUCEESS routine has completed the mapping.
- @retval EFI_INVALID_PARAMETER invalid parameter.
- @retval EFI_OUT_OF_RESOURCES out of resource.
- @retval other error as indicated.
-
-**/
-EFI_STATUS
-AddV2P (
- IN OUT V2P **V2p,
- EFI_PCI_IO_PROTOCOL_OPERATION Type,
- VOID *VirtualAddress,
- UINTN BufferSize
- )
-{
- EFI_STATUS Status;
-
- if ((V2p == NULL) || (VirtualAddress == NULL) || (BufferSize == 0)) {
- return EFI_INVALID_PARAMETER;
- }
-
- *V2p = AllocatePool (sizeof (V2P));
- if (*V2p == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- Status = mPciIo->Map (
- mPciIo,
- Type,
- VirtualAddress,
- &BufferSize,
- &(*V2p)->PhysicalAddress,
- &(*V2p)->Unmap
- );
- if (Status != EFI_SUCCESS) {
- FreePool (*V2p);
- return Status;
- }
- (*V2p)->VirtualAddress = VirtualAddress;
- (*V2p)->BufferSize = BufferSize;
- (*V2p)->Next = mV2p;
- mV2p = *V2p;
-
- return EFI_SUCCESS;
-}
-
-
-/**
- This routine searches the linked list of mapped address nodes (for undi3.0
- interface) to find the node that corresponds to the given virtual address and
- returns a pointer to that node.
-
- @param V2p pointer to return a map list node pointer.
- @param VirtualAddr virtual address (or CPU address) to be searched in
- the map list
-
- @retval EFI_SUCEESS A match was found.
- @retval Other A match cannot be found.
-
-**/
-EFI_STATUS
-FindV2p (
- V2P **V2p,
- VOID *VirtualAddr
- )
-{
- V2P *Ptr;
-
- if (V2p == NULL || VirtualAddr == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- for (Ptr = mV2p; Ptr != NULL; Ptr = Ptr->Next) {
- if (Ptr->VirtualAddress == VirtualAddr) {
- *V2p = Ptr;
- return EFI_SUCCESS;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-
-/**
- Unmap the given virtual address and free the memory allocated for the map list
- node corresponding to that address.
-
- @param VirtualAddress virtual address (or CPU address) to be unmapped.
-
- @retval EFI_SUCEESS Successfully unmapped.
- @retval Other Other errors as indicated.
-
-**/
-EFI_STATUS
-DelV2p (
- VOID *VirtualAddress
- )
-{
- V2P *Current;
- V2P *Next;
- EFI_STATUS Status;
-
- if (VirtualAddress == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (mV2p == NULL) {
- return EFI_NOT_FOUND;
- }
- //
- // Is our node at the head of the list??
- //
- if ((Current = mV2p)->VirtualAddress == VirtualAddress) {
- mV2p = mV2p->Next;
-
- Status = mPciIo->Unmap (mPciIo, Current->Unmap);
-
- FreePool (Current);
-
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));
- }
- return Status;
- }
-
- for (; Current->Next != NULL; Current = Next) {
- if ((Next = Current->Next)->VirtualAddress == VirtualAddress) {
- Current->Next = Next->Next;
- Status = mPciIo->Unmap (mPciIo, Next->Unmap);
- FreePool (Next);
-
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "Unmap failed with status = %r\n", Status));
- }
- return Status;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
/**
The SNP driver entry point.
@@ -1003,8 +854,8 @@ InitializeSnpNiiDriver (
return EfiLibInstallDriverBindingComponentName2 (
ImageHandle,
SystemTable,
- &mSimpleNetworkDriverBinding,
- NULL,
+ &gSimpleNetworkDriverBinding,
+ ImageHandle,
&gSimpleNetworkComponentName,
&gSimpleNetworkComponentName2
);