Initial import.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
bbahnsen
2006-04-21 22:54:32 +00:00
commit 878ddf1fc3
2651 changed files with 624620 additions and 0 deletions

View File

@@ -0,0 +1,160 @@
/*++
Copyright (c) 2006, 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:
ComponentName.c
Abstract:
--*/
#include "Snp.h"
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
SimpleNetworkComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
SimpleNetworkComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName = {
SimpleNetworkComponentNameGetDriverName,
SimpleNetworkComponentNameGetControllerName,
"eng"
};
static EFI_UNICODE_STRING_TABLE mSimpleNetworkDriverNameTable[] = {
{
"eng",
(CHAR16 *) L"Simple Network Protocol Driver"
},
{
NULL,
NULL
}
};
EFI_STATUS
EFIAPI
SimpleNetworkComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
Language - A pointer to a three character ISO 639-2 language identifier.
This is the language of the driver name that that the caller
is requesting, and it must match one of the languages specified
in SupportedLanguages. The number of languages supported by a
driver is up to the driver writer.
DriverName - A pointer to the Unicode string to return. This Unicode string
is the name of the driver specified by This in the language
specified by Language.
Returns:
EFI_SUCCESS - The Unicode string for the Driver specified by This
and the language specified by Language was returned
in DriverName.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - DriverName is NULL.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return LookupUnicodeString (
Language,
gSimpleNetworkComponentName.SupportedLanguages,
mSimpleNetworkDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
SimpleNetworkComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle OPTIONAL,
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by an EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME_PROTOCOL instance.
ControllerHandle - The handle of a controller that the driver specified by
This is managing. This handle specifies the controller
whose name is to be returned.
ChildHandle - The handle of the child controller to retrieve the name
of. This is an optional parameter that may be NULL. It
will be NULL for device drivers. It will also be NULL
for a bus drivers that wish to retrieve the name of the
bus controller. It will not be NULL for a bus driver
that wishes to retrieve the name of a child controller.
Language - A pointer to a three character ISO 639-2 language
identifier. This is the language of the controller name
that that the caller is requesting, and it must match one
of the languages specified in SupportedLanguages. The
number of languages supported by a driver is up to the
driver writer.
ControllerName - A pointer to the Unicode string to return. This Unicode
string is the name of the controller specified by
ControllerHandle and ChildHandle in the language specified
by Language from the point of view of the driver specified
by This.
Returns:
EFI_SUCCESS - The Unicode string for the user readable name in the
language specified by Language for the driver
specified by This was returned in DriverName.
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - ControllerName is NULL.
EFI_UNSUPPORTED - The driver specified by This is not currently managing
the controller specified by ControllerHandle and
ChildHandle.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return EFI_UNSUPPORTED;
}

View File

@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2006, 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.
-->
<ModuleBuildDescription xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MbdHeader>
<BaseName>SNP</BaseName>
<Guid>A2f436EA-A127-4EF8-957C-8048606FF670</Guid>
<Version>0</Version>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
<License>
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.
</License>
<Created>2006-03-12 17:09</Created>
<Modified>2006-03-19 15:19</Modified>
</MbdHeader>
<Libraries>
<Library>UefiBootServicesTableLib</Library>
<Library>BaseMemoryLib</Library>
<Library>UefiLib</Library>
<Library>UefiDriverEntryPoint</Library>
<Library>UefiDriverModelLib</Library>
<Library>DxeReportStatusCodeLib</Library>
<Library>BaseDebugLibReportStatusCode</Library>
<Library>BaseLib</Library>
<Library>DxeMemoryAllocationLib</Library>
</Libraries>
</ModuleBuildDescription>

View File

@@ -0,0 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2006, 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.
-->
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.TianoCore.org/2006/Edk2.0 http://www.TianoCore.org/2006/Edk2.0/SurfaceArea.xsd">
<MsaHeader>
<BaseName>SNP</BaseName>
<ModuleType>UEFI_DRIVER</ModuleType>
<ComponentType>BS_DRIVER</ComponentType>
<Guid>A2f436EA-A127-4EF8-957C-8048606FF670</Guid>
<Version>0</Version>
<Abstract>Component description file for DiskIo module.</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2004-2006, Intel Corporation</Copyright>
<License>
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.
</License>
<Specification>0</Specification>
<Created>2006-03-12 17:09</Created>
<Updated>2006-03-19 15:19</Updated>
</MsaHeader>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">DebugLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverModelLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiDriverEntryPoint</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">BaseMemoryLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">MemoryAllocationLib</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">UefiBootServicesTableLib</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>callback.c</Filename>
<Filename>get_status.c</Filename>
<Filename>initialize.c</Filename>
<Filename>mcast_ip_to_mac.c</Filename>
<Filename>nvdata.c</Filename>
<Filename>receive.c</Filename>
<Filename>receive_filters.c</Filename>
<Filename>reset.c</Filename>
<Filename>shutdown.c</Filename>
<Filename>snp.c</Filename>
<Filename>snp.h</Filename>
<Filename>start.c</Filename>
<Filename>station_address.c</Filename>
<Filename>statistics.c</Filename>
<Filename>stop.c</Filename>
<Filename>transmit.c</Filename>
<Filename>WaitForPacket.c</Filename>
<Filename>ComponentName.c</Filename>
</SourceFiles>
<Includes>
<PackageName>MdePkg</PackageName>
<PackageName>EdkModulePkg</PackageName>
</Includes>
<Protocols>
<Protocol Usage="BY_START">SimpleNetwork</Protocol>
<Protocol Usage="TO_START">PciIo</Protocol>
<Protocol Usage="TO_START">DevicePath</Protocol>
<Protocol Usage="SOMETIMES_CONSUMED">NetworkInterfaceIdentifier</Protocol>
<Protocol Usage="TO_START">NetworkInterfaceIdentifier2</Protocol>
</Protocols>
<Externs>
<Extern>
<ModuleEntryPoint></ModuleEntryPoint>
<ModuleUnloadImage></ModuleUnloadImage>
</Extern>
<Extern>
<DriverBinding>mSimpleNetworkDriverBinding</DriverBinding>
<ComponentName>gSimpleNetworkComponentName</ComponentName>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@@ -0,0 +1,100 @@
/*++
Copyright (c) 2006, 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:
WaitForPacket.c
Abstract:
Event handler to check for available packet.
--*/
#include "snp.h"
VOID
EFIAPI
SnpWaitForPacketNotify (
EFI_EVENT Event,
VOID *SnpPtr
)
/*++
Routine Description:
Arguments:
Returns:
--*/
{
PXE_DB_GET_STATUS PxeDbGetStatus;
//
// Do nothing if either parameter is a NULL pointer.
//
if (Event == NULL || SnpPtr == NULL) {
return ;
}
//
// Do nothing if the SNP interface is not initialized.
//
switch (((SNP_DRIVER *) SnpPtr)->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
case EfiSimpleNetworkStarted:
default:
return ;
}
//
// Fill in CDB for UNDI GetStatus().
//
((SNP_DRIVER *) SnpPtr)->cdb.OpCode = PXE_OPCODE_GET_STATUS;
((SNP_DRIVER *) SnpPtr)->cdb.OpFlags = 0;
((SNP_DRIVER *) SnpPtr)->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
((SNP_DRIVER *) SnpPtr)->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
((SNP_DRIVER *) SnpPtr)->cdb.DBsize = sizeof (UINT32) * 2;
((SNP_DRIVER *) SnpPtr)->cdb.DBaddr = (UINT64) (UINTN) (((SNP_DRIVER *) SnpPtr)->db);
((SNP_DRIVER *) SnpPtr)->cdb.StatCode = PXE_STATCODE_INITIALIZE;
((SNP_DRIVER *) SnpPtr)->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
((SNP_DRIVER *) SnpPtr)->cdb.IFnum = ((SNP_DRIVER *) SnpPtr)->if_num;
((SNP_DRIVER *) SnpPtr)->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Clear contents of DB buffer.
//
ZeroMem (((SNP_DRIVER *) SnpPtr)->db, sizeof (UINT32) * 2);
//
// Issue UNDI command and check result.
//
(*((SNP_DRIVER *) SnpPtr)->issue_undi32_command) ((UINT64) (UINTN) &((SNP_DRIVER *) SnpPtr)->cdb);
if (((SNP_DRIVER *) SnpPtr)->cdb.StatCode != EFI_SUCCESS) {
return ;
}
//
// We might have a packet. Check the receive length and signal
// the event if the length is not zero.
//
CopyMem (
&PxeDbGetStatus,
((SNP_DRIVER *) SnpPtr)->db,
sizeof (UINT32) * 2
);
if (PxeDbGetStatus.RxFrameLen != 0) {
gBS->SignalEvent (Event);
}
}
/* eof - WaitForPacket.c */

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?><!-- Copyright (c) 2006, 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.-->
<project basedir="." default="SNP"><!--Apply external ANT tasks-->
<taskdef resource="GenBuild.tasks"/>
<taskdef resource="net/sf/antcontrib/antlib.xml"/>
<property environment="env"/>
<property name="WORKSPACE_DIR" value="${env.WORKSPACE}"/>
<import file="${WORKSPACE_DIR}\Tools\Conf\BuildMacro.xml"/><!--MODULE_RELATIVE PATH is relative to PACKAGE_DIR-->
<property name="MODULE_RELATIVE_PATH" value="Universal\Network\Snp32_64\Dxe"/>
<property name="MODULE_DIR" value="${PACKAGE_DIR}\${MODULE_RELATIVE_PATH}"/>
<property name="COMMON_FILE" value="${WORKSPACE_DIR}\Tools\Conf\Common.xml"/>
<target name="SNP">
<GenBuild baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
</target>
<target depends="SNP_clean" name="clean"/>
<target depends="SNP_cleanall" name="cleanall"/>
<target name="SNP_clean">
<OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\SNP_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\SNP_build.xml" target="clean"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}" excludes="*.xml"/>
</target>
<target name="SNP_cleanall">
<OutputDirSetup baseName="SNP" mbdFilename="${MODULE_DIR}\SNP.mbd" msaFilename="${MODULE_DIR}\SNP.msa"/>
<if>
<available file="${DEST_DIR_OUTPUT}\SNP_build.xml"/>
<then>
<ant antfile="${DEST_DIR_OUTPUT}\SNP_build.xml" target="cleanall"/>
</then>
</if>
<delete dir="${DEST_DIR_OUTPUT}"/>
<delete dir="${DEST_DIR_DEBUG}"/>
<delete>
<fileset dir="${BIN_DIR}" includes="**SNP*"/>
</delete>
</target>
</project>

View File

@@ -0,0 +1,613 @@
/*++
Copyright (c) 2006, 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:
callback.c
Abstract:
This file contains two sets of callback routines for undi3.0 and undi3.1.
the callback routines for Undi3.1 have an extra parameter UniqueId which
stores the interface context for the NIC that snp is trying to talk..
--*/
#include "snp.h"
//
// Global variables
// these 2 global variables are used only for 3.0 undi. we could not place
// them in the snp structure because we will not know which snp structure
// in the callback context!
//
STATIC BOOLEAN mInitializeLock = TRUE;
STATIC EFI_LOCK mLock;
//
// End Global variables
//
extern EFI_PCI_IO_PROTOCOL *mPciIoFncs;
VOID
snp_undi32_callback_v2p_30 (
IN UINT64 CpuAddr,
IN OUT UINT64 DeviceAddrPtr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine with a virtual or CPU address that SNP provided
to convert it to a physical or device address. Since EFI uses the identical
mapping, this routine returns the physical address same as the virtual address
for most of the addresses. an address above 4GB cannot generally be used as a
device address, it needs to be mapped to a lower physical address. This routine
does not call the map routine itself, but it assumes that the mapping was done
at the time of providing the address to UNDI. This routine just looks up the
address in a map table (which is the v2p structure chain)
Arguments:
CpuAddr - virtual address of a buffer
DeviceAddrPtr - pointer to the physical address
Returns:
void - The DeviceAddrPtr will contain 0 in case of any error
--*/
{
struct s_v2p *v2p;
//
// Do nothing if virtual address is zero or physical pointer is NULL.
// No need to map if the virtual address is within 4GB limit since
// EFI uses identical mapping
//
if ((CpuAddr == 0) || (DeviceAddrPtr == 0)) {
DEBUG ((EFI_D_ERROR, "\nv2p: Null virtual address or physical pointer.\n"));
return ;
}
if (CpuAddr < FOUR_GIGABYTES) {
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
return ;
}
//
// SNP creates a vaddr tp paddr mapping at the time of calling undi with any
// big address, this callback routine just looks up in the v2p list and
// returns the physical address for any given virtual address.
//
if (find_v2p (&v2p, (VOID *) (UINTN) CpuAddr) != EFI_SUCCESS) {
*(UINT64 *) (UINTN) DeviceAddrPtr = CpuAddr;
} else {
*(UINT64 *) (UINTN) DeviceAddrPtr = v2p->paddr;
}
}
VOID
snp_undi32_callback_block_30 (
IN UINT32 Enable
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine when it wants to have exclusive access to a critical
section of the code/data
Arguments:
Enable - non-zero indicates acquire
zero indicates release
Returns:
void
--*/
{
//
// tcpip was calling snp at tpl_notify and if we acquire a lock that was
// created at a lower level (TPL_CALLBACK) it gives an assert!
//
if (mInitializeLock) {
EfiInitializeLock (&mLock, EFI_TPL_NOTIFY);
mInitializeLock = FALSE;
}
if (Enable != 0) {
EfiAcquireLock (&mLock);
} else {
EfiReleaseLock (&mLock);
}
}
VOID
snp_undi32_callback_delay_30 (
IN UINT64 MicroSeconds
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine with the number of micro seconds when it wants to
pause.
Arguments:
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
Returns:
void
--*/
{
if (MicroSeconds != 0) {
gBS->Stall ((UINTN) MicroSeconds);
}
}
VOID
snp_undi32_callback_memio_30 (
IN UINT8 ReadOrWrite,
IN UINT8 NumBytes,
IN UINT64 Address,
IN OUT UINT64 BufferAddr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
This is the IO routine for UNDI. This is not currently being used by UNDI3.0
because Undi3.0 uses io/mem offsets relative to the beginning of the device
io/mem address and so it needs to use the PCI_IO_FUNCTION that abstracts the
start of the device's io/mem addresses. Since SNP cannot retrive the context
of the undi3.0 interface it cannot use the PCI_IO_FUNCTION that specific for
that NIC and uses one global IO functions structure, this does not work.
This however works fine for EFI1.0 Undis because they use absolute addresses
for io/mem access.
Arguments:
ReadOrWrite - indicates read or write, IO or Memory
NumBytes - number of bytes to read or write
Address - IO or memory address to read from or write to
BufferAddr - memory location to read into or that contains the bytes
to write
Returns:
--*/
{
EFI_PCI_IO_PROTOCOL_WIDTH Width;
switch (NumBytes) {
case 2:
Width = 1;
break;
case 4:
Width = 2;
break;
case 8:
Width = 3;
break;
default:
Width = 0;
}
switch (ReadOrWrite) {
case PXE_IO_READ:
mPciIoFncs->Io.Read (
mPciIoFncs,
Width,
1, // BAR 1, IO base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_IO_WRITE:
mPciIoFncs->Io.Write (
mPciIoFncs,
Width,
1, // BAR 1, IO base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_MEM_READ:
mPciIoFncs->Mem.Read (
mPciIoFncs,
Width,
0, // BAR 0, Memory base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_MEM_WRITE:
mPciIoFncs->Mem.Write (
mPciIoFncs,
Width,
0, // BAR 0, Memory base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
}
return ;
}
//
// New callbacks for 3.1:
// there won't be a virtual2physical callback for UNDI 3.1 because undi3.1 uses
// the MemMap call to map the required address by itself!
//
VOID
snp_undi32_callback_block (
IN UINT64 UniqueId,
IN UINT32 Enable
)
/*++
Routine Description:
This is a callback routine supplied to UNDI3.1 at undi_start time.
UNDI call this routine when it wants to have exclusive access to a critical
section of the code/data
Arguments:
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
Undi interface context (Undi does not read or write this variable)
Enable - non-zero indicates acquire
zero indicates release
Returns:
void
--*/
{
SNP_DRIVER *snp;
snp = (SNP_DRIVER *) (UINTN) UniqueId;
//
// tcpip was calling snp at tpl_notify and when we acquire a lock that was
// created at a lower level (TPL_CALLBACK) it gives an assert!
//
if (Enable != 0) {
EfiAcquireLock (&snp->lock);
} else {
EfiReleaseLock (&snp->lock);
}
}
VOID
snp_undi32_callback_delay (
IN UINT64 UniqueId,
IN UINT64 MicroSeconds
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine with the number of micro seconds when it wants to
pause.
Arguments:
MicroSeconds - number of micro seconds to pause, ususlly multiple of 10
Returns:
void
--*/
{
if (MicroSeconds != 0) {
gBS->Stall ((UINTN) MicroSeconds);
}
}
/*
* IO routine for UNDI start CPB.
*/
VOID
snp_undi32_callback_memio (
UINT64 UniqueId,
UINT8 ReadOrWrite,
UINT8 NumBytes,
UINT64 Address,
UINT64 BufferAddr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
This is the IO routine for UNDI3.1.
Arguments:
ReadOrWrite - indicates read or write, IO or Memory
NumBytes - number of bytes to read or write
Address - IO or memory address to read from or write to
BufferAddr - memory location to read into or that contains the bytes
to write
Returns:
--*/
{
SNP_DRIVER *snp;
EFI_PCI_IO_PROTOCOL_WIDTH Width;
snp = (SNP_DRIVER *) (UINTN) UniqueId;
Width = 0;
switch (NumBytes) {
case 2:
Width = 1;
break;
case 4:
Width = 2;
break;
case 8:
Width = 3;
break;
}
switch (ReadOrWrite) {
case PXE_IO_READ:
snp->IoFncs->Io.Read (
snp->IoFncs,
Width,
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_IO_WRITE:
snp->IoFncs->Io.Write (
snp->IoFncs,
Width,
snp->IoBarIndex, // BAR 1 (for 32bit regs), IO base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_MEM_READ:
snp->IoFncs->Mem.Read (
snp->IoFncs,
Width,
snp->MemoryBarIndex, // BAR 0, Memory base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
case PXE_MEM_WRITE:
snp->IoFncs->Mem.Write (
snp->IoFncs,
Width,
snp->MemoryBarIndex, // BAR 0, Memory base address
Address,
1, // count
(VOID *) (UINTN) BufferAddr
);
break;
}
return ;
}
VOID
snp_undi32_callback_map (
IN UINT64 UniqueId,
IN UINT64 CpuAddr,
IN UINT32 NumBytes,
IN UINT32 Direction,
IN OUT UINT64 DeviceAddrPtr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine when it has to map a CPU address to a device
address.
Arguments:
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
Undi interface context (Undi does not read or write this variable)
CpuAddr - Virtual address to be mapped!
NumBytes - size of memory to be mapped
Direction - direction of data flow for this memory's usage:
cpu->device, device->cpu or both ways
DeviceAddrPtr - pointer to return the mapped device address
Returns:
None
--*/
{
EFI_PHYSICAL_ADDRESS *DevAddrPtr;
EFI_PCI_IO_PROTOCOL_OPERATION DirectionFlag;
UINTN BuffSize;
SNP_DRIVER *snp;
UINTN Index;
EFI_STATUS Status;
BuffSize = (UINTN) NumBytes;
snp = (SNP_DRIVER *) (UINTN) UniqueId;
DevAddrPtr = (EFI_PHYSICAL_ADDRESS *) (UINTN) DeviceAddrPtr;
if (CpuAddr == 0) {
*DevAddrPtr = 0;
return ;
}
switch (Direction) {
case TO_AND_FROM_DEVICE:
DirectionFlag = EfiPciIoOperationBusMasterCommonBuffer;
break;
case FROM_DEVICE:
DirectionFlag = EfiPciIoOperationBusMasterWrite;
break;
case TO_DEVICE:
DirectionFlag = EfiPciIoOperationBusMasterRead;
break;
default:
*DevAddrPtr = 0;
//
// any non zero indicates error!
//
return ;
}
//
// find an unused map_list entry
//
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
if (snp->map_list[Index].virt == 0) {
break;
}
}
if (Index >= MAX_MAP_LENGTH) {
SNP_PRINT (L"SNP maplist is FULL\n");
*DevAddrPtr = 0;
return ;
}
snp->map_list[Index].virt = (EFI_PHYSICAL_ADDRESS) CpuAddr;
Status = snp->IoFncs->Map (
snp->IoFncs,
DirectionFlag,
(VOID *) (UINTN) CpuAddr,
&BuffSize,
DevAddrPtr,
&(snp->map_list[Index].map_cookie)
);
if (Status != EFI_SUCCESS) {
*DevAddrPtr = 0;
snp->map_list[Index].virt = 0;
}
return ;
}
VOID
snp_undi32_callback_unmap (
IN UINT64 UniqueId,
IN UINT64 CpuAddr,
IN UINT32 NumBytes,
IN UINT32 Direction,
IN UINT64 DeviceAddr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine when it wants to unmap an address that was previously
mapped using map callback
Arguments:
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
Undi interface context (Undi does not read or write this variable)
CpuAddr - Virtual address that was mapped!
NumBytes - size of memory mapped
Direction- direction of data flow for this memory's usage:
cpu->device, device->cpu or both ways
DeviceAddr - the mapped device address
Returns:
--*/
{
SNP_DRIVER *snp;
UINT16 Index;
snp = (SNP_DRIVER *) (UINTN) UniqueId;
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
if (snp->map_list[Index].virt == CpuAddr) {
break;
}
}
if (Index >= MAX_MAP_LENGTH)
{
#if SNP_DEBUG
Print (L"SNP could not find a mapping, failed to unmap.\n");
#endif
return ;
}
snp->IoFncs->Unmap (snp->IoFncs, snp->map_list[Index].map_cookie);
snp->map_list[Index].virt = 0;
snp->map_list[Index].map_cookie = NULL;
return ;
}
VOID
snp_undi32_callback_sync (
UINT64 UniqueId,
UINT64 CpuAddr,
UINT32 NumBytes,
UINT32 Direction,
UINT64 DeviceAddr
)
/*++
Routine Description:
This is a callback routine supplied to UNDI at undi_start time.
UNDI call this routine when it wants synchronize the virtual buffer contents
with the mapped buffer contents. The virtual and mapped buffers need not
correspond to the same physical memory (especially if the virtual address is
> 4GB). Depending on the direction for which the buffer is mapped, undi will
need to synchronize their contents whenever it writes to/reads from the buffer
using either the cpu address or the device address.
EFI does not provide a sync call, since virt=physical, we sould just do
the synchronization ourself here!
Arguments:
UniqueId - This was supplied to UNDI at Undi_Start, SNP uses this to store
Undi interface context (Undi does not read or write this variable)
CpuAddr - Virtual address that was mapped!
NumBytes - size of memory mapped
Direction- direction of data flow for this memory's usage:
cpu->device, device->cpu or both ways
DeviceAddr - the mapped device address
Returns:
--*/
{
if ((CpuAddr == 0) || (DeviceAddr == 0) || (NumBytes == 0)) {
return ;
}
switch (Direction) {
case FROM_DEVICE:
CopyMem ((UINT8 *) (UINTN) CpuAddr, (UINT8 *) (UINTN) DeviceAddr, NumBytes);
break;
case TO_DEVICE:
CopyMem ((UINT8 *) (UINTN) DeviceAddr, (UINT8 *) (UINTN) CpuAddr, NumBytes);
break;
}
return ;
}

View File

@@ -0,0 +1,193 @@
/*++
Copyright (c) 2006, 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:
get_status.c
Abstract:
Revision history:
2000-Feb-03 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_getstatus (
SNP_DRIVER *snp,
UINT32 *InterruptStatusPtr,
VOID **TransmitBufferListPtr
)
/*++
Routine Description:
this routine calls undi to get the status of the interrupts, get the list of
transmit buffers that completed transmitting!
Arguments:
snp - pointer to snp driver structure
InterruptStatusPtr - a non null pointer gets the interrupt status
TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously
transmitted buffers whose transmission was completed
asynchrnously.
Returns:
--*/
{
PXE_DB_GET_STATUS *db;
UINT16 InterruptFlags;
UINT64 TempData;
db = snp->db;
snp->cdb.OpCode = PXE_OPCODE_GET_STATUS;
snp->cdb.OpFlags = 0;
if (TransmitBufferListPtr != NULL) {
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_TRANSMITTED_BUFFERS;
}
if (InterruptStatusPtr != NULL) {
snp->cdb.OpFlags |= PXE_OPFLAGS_GET_INTERRUPT_STATUS;
}
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
//
// size DB for return of one buffer
//
snp->cdb.DBsize = (UINT16) (((UINT16) (sizeof (PXE_DB_GET_STATUS)) - (UINT16) (sizeof db->TxBuffer)) + (UINT16) (sizeof db->TxBuffer[0]));
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.get_status() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != EFI_SUCCESS) {
DEBUG (
(EFI_D_NET,
"\nsnp->undi.get_status() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatFlags)
);
return EFI_DEVICE_ERROR;
}
//
// report the values back..
//
if (InterruptStatusPtr != NULL) {
InterruptFlags = (UINT16) (snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_INTERRUPT_MASK);
*InterruptStatusPtr = 0;
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_RECEIVE) {
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_RECEIVE_INTERRUPT;
}
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_TRANSMIT) {
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_TRANSMIT_INTERRUPT;
}
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_COMMAND) {
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
}
if (InterruptFlags & PXE_STATFLAGS_GET_STATUS_SOFTWARE) {
*InterruptStatusPtr |= EFI_SIMPLE_NETWORK_COMMAND_INTERRUPT;
}
}
if (TransmitBufferListPtr != NULL) {
*TransmitBufferListPtr =
(
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_NO_TXBUFS_WRITTEN) ||
(snp->cdb.StatFlags & PXE_STATFLAGS_GET_STATUS_TXBUF_QUEUE_EMPTY)
) ? 0 : (VOID *) (UINTN) db->TxBuffer[0];
TempData = (UINT64) (UINTN) (*TransmitBufferListPtr);
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
del_v2p ((VOID *) (UINTN) (db->TxBuffer[0]));
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_get_status (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
OUT UINT32 *InterruptStatusPtr OPTIONAL,
OUT VOID **TransmitBufferListPtr OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for getting the status
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_getstatus routine to actually get the undi status
Arguments:
this - context pointer
InterruptStatusPtr - a non null pointer gets the interrupt status
TransmitBufferListPtrs - a non null ointer gets the list of pointers of previously
transmitted buffers whose transmission was completed
asynchrnously.
Returns:
--*/
{
SNP_DRIVER *snp;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
if (InterruptStatusPtr == NULL && TransmitBufferListPtr == NULL) {
return EFI_INVALID_PARAMETER;
}
return pxe_getstatus (snp, InterruptStatusPtr, TransmitBufferListPtr);
}

View File

@@ -0,0 +1,244 @@
/*++
Copyright (c) 2006, 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:
initialize.c
Abstract:
Revision history:
2000-Feb-09 M(f)J Genesis.
--*/
#include "snp.h"
VOID
EFIAPI
SnpWaitForPacketNotify (
IN EFI_EVENT Event,
IN VOID *SnpPtr
);
EFI_STATUS
pxe_init (
SNP_DRIVER *snp,
UINT16 CableDetectFlag
)
/*++
Routine Description:
this routine calls undi to initialize the interface.
Arguments:
snp - pointer to snp driver structure
CableDetectFlag - Do/don't detect the cable (depending on what undi supports)
Returns:
--*/
{
PXE_CPB_INITIALIZE *cpb;
VOID *addr;
EFI_STATUS Status;
cpb = snp->cpb;
if (snp->tx_rx_bufsize != 0) {
Status = snp->IoFncs->AllocateBuffer (
snp->IoFncs,
AllocateAnyPages,
EfiBootServicesData,
SNP_MEM_PAGES (snp->tx_rx_bufsize),
&addr,
0
);
if (Status != EFI_SUCCESS) {
DEBUG (
(EFI_D_ERROR,
"\nsnp->pxe_init() AllocateBuffer %xh (%r)\n",
Status,
Status)
);
return Status;
}
ASSERT (addr);
snp->tx_rx_buffer = addr;
}
cpb->MemoryAddr = (UINT64) (UINTN) snp->tx_rx_buffer;
cpb->MemoryLength = snp->tx_rx_bufsize;
//
// let UNDI decide/detect these values
//
cpb->LinkSpeed = 0;
cpb->TxBufCnt = 0;
cpb->TxBufSize = 0;
cpb->RxBufCnt = 0;
cpb->RxBufSize = 0;
cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
cpb->LoopBackMode = LOOPBACK_NORMAL;
snp->cdb.OpCode = PXE_OPCODE_INITIALIZE;
snp->cdb.OpFlags = CableDetectFlag;
snp->cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);
snp->cdb.DBsize = sizeof (PXE_DB_INITIALIZE);
snp->cdb.CPBaddr = (UINT64) (UINTN) snp->cpb;
snp->cdb.DBaddr = (UINT64) (UINTN) snp->db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
DEBUG ((EFI_D_NET, "\nsnp->undi.initialize() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode == PXE_STATCODE_SUCCESS) {
snp->mode.State = EfiSimpleNetworkInitialized;
Status = EFI_SUCCESS;
} else {
DEBUG (
(EFI_D_WARN,
"\nsnp->undi.initialize() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
if (snp->tx_rx_buffer != NULL) {
snp->IoFncs->FreeBuffer (
snp->IoFncs,
SNP_MEM_PAGES (snp->tx_rx_bufsize),
(VOID *) snp->tx_rx_buffer
);
}
snp->tx_rx_buffer = NULL;
Status = EFI_DEVICE_ERROR;
}
return Status;
}
EFI_STATUS
EFIAPI
snp_undi32_initialize (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN UINTN extra_rx_buffer_size OPTIONAL,
IN UINTN extra_tx_buffer_size OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for initializing the interface
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_initialize routine to actually do the undi initialization
Arguments:
this - context pointer
extra_rx_buffer_size - optional parameter, indicates extra space for rx_buffers
extra_tx_buffer_size - optional parameter, indicates extra space for tx_buffers
Returns:
--*/
{
EFI_STATUS EfiStatus;
SNP_DRIVER *snp;
//
//
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_INVALID_PARAMETER;
}
//
//
//
switch (snp->mode.State) {
case EfiSimpleNetworkStarted:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkInitialized:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
//
//
EfiStatus = gBS->CreateEvent (
EFI_EVENT_NOTIFY_WAIT,
EFI_TPL_NOTIFY,
&SnpWaitForPacketNotify,
snp,
&snp->snp.WaitForPacket
);
if (EFI_ERROR (EfiStatus)) {
snp->snp.WaitForPacket = NULL;
return EFI_DEVICE_ERROR;
}
//
//
//
snp->mode.MCastFilterCount = 0;
snp->mode.ReceiveFilterSetting = 0;
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
CopyMem (
&snp->mode.CurrentAddress,
&snp->mode.PermanentAddress,
sizeof (EFI_MAC_ADDRESS)
);
//
// Compute tx/rx buffer sizes based on UNDI init info and parameters.
//
snp->tx_rx_bufsize = (UINT32) (snp->init_info.MemoryRequired + extra_rx_buffer_size + extra_tx_buffer_size);
if (snp->mode.MediaPresentSupported) {
if (pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
snp->mode.MediaPresent = TRUE;
return EFI_SUCCESS;
}
}
snp->mode.MediaPresent = FALSE;
EfiStatus = pxe_init (snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
if (EFI_ERROR (EfiStatus)) {
gBS->CloseEvent (snp->snp.WaitForPacket);
}
return EfiStatus;
}

View File

@@ -0,0 +1,167 @@
/*++
Copyright (c) 2006, 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:
mcast_ip_to_mac.c
Abstract:
Revision history:
2000-Feb-17 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_ip2mac (
IN SNP_DRIVER *snp,
IN BOOLEAN IPv6,
IN EFI_IP_ADDRESS *IP,
IN OUT EFI_MAC_ADDRESS *MAC
)
/*++
Routine Description:
this routine calls undi to convert an multicast IP address to a MAC address
Arguments:
snp - pointer to snp driver structure
IPv6 - flag to indicate if this is an ipv6 address
IP - multicast IP address
MAC - pointer to hold the return MAC address
Returns:
--*/
{
PXE_CPB_MCAST_IP_TO_MAC *cpb;
PXE_DB_MCAST_IP_TO_MAC *db;
cpb = snp->cpb;
db = snp->db;
snp->cdb.OpCode = PXE_OPCODE_MCAST_IP_TO_MAC;
snp->cdb.OpFlags = (UINT16) (IPv6 ? PXE_OPFLAGS_MCAST_IPV6_TO_MAC : PXE_OPFLAGS_MCAST_IPV4_TO_MAC);
snp->cdb.CPBsize = sizeof (PXE_CPB_MCAST_IP_TO_MAC);
snp->cdb.DBsize = sizeof (PXE_DB_MCAST_IP_TO_MAC);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
CopyMem (&cpb->IP, IP, sizeof (PXE_IP_ADDR));
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.mcast_ip_to_mac() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
break;
case PXE_STATCODE_INVALID_CPB:
return EFI_INVALID_PARAMETER;
case PXE_STATCODE_UNSUPPORTED:
DEBUG (
(EFI_D_NET,
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_UNSUPPORTED;
default:
//
// UNDI command failed. Return EFI_DEVICE_ERROR
// to caller.
//
DEBUG (
(EFI_D_NET,
"\nsnp->undi.mcast_ip_to_mac() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
CopyMem (MAC, &db->MAC, sizeof (PXE_MAC_ADDR));
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_mcast_ip_to_mac (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN IPv6,
IN EFI_IP_ADDRESS *IP,
OUT EFI_MAC_ADDRESS *MAC
)
/*++
Routine Description:
This is the SNP interface routine for converting a multicast IP address to
a MAC address.
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_ip2mac routine to actually do the conversion
Arguments:
this - context pointer
IPv6 - flag to indicate if this is an ipv6 address
IP - multicast IP address
MAC - pointer to hold the return MAC address
Returns:
--*/
{
SNP_DRIVER *snp;
//
// Get pointer to SNP driver instance for *this.
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
if (IP == NULL || MAC == NULL) {
return EFI_INVALID_PARAMETER;
}
return pxe_ip2mac (snp, IPv6, IP, MAC);
}

View File

@@ -0,0 +1,183 @@
/*++
Copyright (c) 2006, 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:
nvdata.c
Abstract:
Revision history:
2000-Feb-03 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_nvdata_read (
IN SNP_DRIVER *snp,
IN UINTN RegOffset,
IN UINTN NumBytes,
IN OUT VOID *BufferPtr
)
/*++
Routine Description:
This routine calls Undi to read the desired number of eeprom bytes.
Arguments:
snp - pointer to the snp driver structure
RegOffset - eeprom register value relative to the base address
NumBytes - number of bytes to read
BufferPtr - pointer where to read into
Returns:
--*/
{
PXE_DB_NVDATA *db;
db = snp->db;
snp->cdb.OpCode = PXE_OPCODE_NVDATA;
snp->cdb.OpFlags = PXE_OPFLAGS_NVDATA_READ;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBsize = sizeof (PXE_DB_NVDATA);
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.nvdata () "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
break;
case PXE_STATCODE_UNSUPPORTED:
DEBUG (
(EFI_D_NET,
"\nsnp->undi.nvdata() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_UNSUPPORTED;
default:
DEBUG (
(EFI_D_NET,
"\nsnp->undi.nvdata() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
CopyMem (BufferPtr, db->Data.Byte + RegOffset, NumBytes);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_nvdata (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN ReadOrWrite,
IN UINTN RegOffset,
IN UINTN NumBytes,
IN OUT VOID *BufferPtr
)
/*++
Routine Description:
This is an interface call provided by SNP.
It does the basic checking on the input parameters and retrieves snp structure
and then calls the read_nvdata() call which does the actual reading
Arguments:
this - context pointer
ReadOrWrite - true for reading and false for writing
RegOffset - eeprom register relative to the base
NumBytes - how many bytes to read
BufferPtr - address of memory to read into
Returns:
--*/
{
SNP_DRIVER *snp;
//
// Get pointer to SNP driver instance for *this.
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Return error if the SNP is not initialized.
//
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
// Return error if non-volatile memory variables are not valid.
//
if (snp->mode.NvRamSize == 0 || snp->mode.NvRamAccessSize == 0) {
return EFI_UNSUPPORTED;
}
//
// Check for invalid parameter combinations.
//
if ((NumBytes == 0) ||
(BufferPtr == NULL) ||
(RegOffset >= snp->mode.NvRamSize) ||
(RegOffset + NumBytes > snp->mode.NvRamSize) ||
(NumBytes % snp->mode.NvRamAccessSize != 0) ||
(RegOffset % snp->mode.NvRamAccessSize != 0)
) {
return EFI_INVALID_PARAMETER;
}
//
// check the implementation flags of undi if we can write the nvdata!
//
if (!ReadOrWrite) {
return EFI_UNSUPPORTED;
} else {
return pxe_nvdata_read (snp, RegOffset, NumBytes, BufferPtr);
}
}

View File

@@ -0,0 +1,255 @@
/*++
Copyright (c) 2006, 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:
receive.c
Abstract:
Revision history:
2000-Feb-03 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_receive (
SNP_DRIVER *snp,
VOID *BufferPtr,
UINTN *BuffSizePtr,
UINTN *HeaderSizePtr,
EFI_MAC_ADDRESS *SourceAddrPtr,
EFI_MAC_ADDRESS *DestinationAddrPtr,
UINT16 *ProtocolPtr
)
/*++
Routine Description:
this routine calls undi to receive a packet and fills in the data in the
input pointers!
Arguments:
snp - pointer to snp driver structure
BufferPtr - pointer to the memory for the received data
BuffSizePtr - is a pointer to the length of the buffer on entry and contains
the length of the received data on return
HeaderSizePtr - pointer to the header portion of the data received.
SourceAddrPtr - optional parameter, is a pointer to contain the source
ethernet address on return
DestinationAddrPtr - optional parameter, is a pointer to contain the destination
ethernet address on return
ProtocolPtr - optional parameter, is a pointer to contain the protocol type
from the ethernet header on return
Returns:
--*/
{
PXE_CPB_RECEIVE *cpb;
PXE_DB_RECEIVE *db;
UINTN buf_size;
UINT64 TempData;
cpb = snp->cpb;
db = snp->db;
buf_size = *BuffSizePtr;
//
// IMPORTANT NOTE:
// In case of the older 3.0 UNDI, if the input buffer address is beyond 4GB,
// DO NOT call the map function on the given buffer, instead use
// a global buffer. The reason is that UNDI3.0 has some unnecessary check of
// making sure that all the addresses (whether or not they will be given
// to the NIC ) supplied to it are below 4GB. It may or may not use
// the mapped address after all (like in case of CPB and DB)!
// Instead of using the global buffer whose address is allocated within the
// 2GB limit if I start mapping the given buffer we lose the data, here is
// why!!!
// if our address is > 4GB, the map call creates another buffer below 2GB and
// copies data to/from the original buffer to the mapped buffer either at
// map time or unmap time depending on the map direction.
// UNDI will not complain since we already mapped the buffer to be
// within the 2GB limit but will not use (I know undi) the mapped address
// since it does not give the user buffers to the NIC's receive unit,
// It just copies the received packet into the user buffer using the virtual
// (CPU) address rather than the mapped (device or physical) address.
// When the UNDI call returns, if we then unmap the buffer, we will lose
// the contents because unmap copies the contents of the mapped buffer into
// the original buffer (since the direction is FROM_DEVICE) !!!
//
// this is not a problem in Undi 3.1 because this undi uses it's map callback
// routine to map a cpu address to device address and it does it only if
// it is giving the address to the device and unmaps it before using the cpu
// address!
//
TempData = (UINT64) (UINTN) BufferPtr;
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
cpb->BufferAddr = (UINT64) (UINTN) snp->receive_buf;
cpb->BufferLen = (UINT32) (snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
} else {
cpb->BufferAddr = (UINT64) (UINTN) BufferPtr;
cpb->BufferLen = (UINT32) *BuffSizePtr;
}
cpb->reserved = 0;
snp->cdb.OpCode = PXE_OPCODE_RECEIVE;
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_INFO, "\nsnp->undi.receive () "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
break;
case PXE_STATCODE_NO_DATA:
DEBUG (
(EFI_D_INFO,
"\nsnp->undi.receive () %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_NOT_READY;
default:
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.receive() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
*BuffSizePtr = db->FrameLen;
if (HeaderSizePtr != NULL) {
*HeaderSizePtr = db->MediaHeaderLen;
}
if (SourceAddrPtr != NULL) {
CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);
}
if (DestinationAddrPtr != NULL) {
CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);
}
if (ProtocolPtr != NULL) {
*ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */
}
TempData = (UINT64) (UINTN) BufferPtr;
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
CopyMem (BufferPtr, snp->receive_buf, snp->init_info.MediaHeaderLen + snp->init_info.FrameDataLen);
}
return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
}
EFI_STATUS
EFIAPI
snp_undi32_receive (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
OUT UINTN *HeaderSizePtr OPTIONAL,
IN OUT UINTN *BuffSizePtr,
OUT VOID *BufferPtr,
OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
OUT UINT16 *ProtocolPtr OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for receiving network data.
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_receive routine to actually do the receive!
Arguments:
this - context pointer
HeaderSizePtr - optional parameter and is a pointer to the header portion of
the data received.
BuffSizePtr - is a pointer to the length of the buffer on entry and contains
the length of the received data on return
BufferPtr - pointer to the memory for the received data
SourceAddrPtr - optional parameter, is a pointer to contain the source
ethernet address on return
DestinationAddrPtr - optional parameter, is a pointer to contain the destination
ethernet address on return
ProtocolPtr - optional parameter, is a pointer to contain the protocol type
from the ethernet header on return
Returns:
--*/
{
SNP_DRIVER *snp;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {
return EFI_INVALID_PARAMETER;
}
if (!snp->mode.ReceiveFilterSetting) {
return EFI_DEVICE_ERROR;
}
return pxe_receive (
snp,
BufferPtr,
BuffSizePtr,
HeaderSizePtr,
SourceAddrPtr,
DestinationAddrPtr,
ProtocolPtr
);
}

View File

@@ -0,0 +1,411 @@
/*++
Copyright (c) 2006, 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:
receive_filters.c
Abstract:
Revision history:
2000-Feb-17 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_rcvfilter_enable (
SNP_DRIVER *snp,
UINT32 EnableFlags,
UINTN MCastAddressCount,
EFI_MAC_ADDRESS *MCastAddressList
)
/*++
Routine Description:
this routine calls undi to enable the receive filters.
Arguments:
snp - pointer to snp driver structure
EnableFlags - bit mask for enabling the receive filters
MCastAddressCount - multicast address count for a new multicast address list
MCastAddressList - list of new multicast addresses
Returns:
--*/
{
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_ENABLE;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
}
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
}
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
}
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
}
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
}
if (MCastAddressCount != 0) {
snp->cdb.CPBsize = (UINT16) (MCastAddressCount * sizeof (EFI_MAC_ADDRESS));
snp->cdb.CPBaddr = (UINT64) (UINTN) snp->cpb;
CopyMem (snp->cpb, MCastAddressList, snp->cdb.CPBsize);
}
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != EFI_SUCCESS) {
//
// UNDI command failed. Return UNDI status to caller.
//
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.receive_filters() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
switch (snp->cdb.StatCode) {
case PXE_STATCODE_INVALID_CDB:
case PXE_STATCODE_INVALID_CPB:
case PXE_STATCODE_INVALID_PARAMETER:
return EFI_INVALID_PARAMETER;
case PXE_STATCODE_UNSUPPORTED:
return EFI_UNSUPPORTED;
}
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
pxe_rcvfilter_disable (
SNP_DRIVER *snp,
UINT32 DisableFlags,
BOOLEAN ResetMCastList
)
/*++
Routine Description:
this routine calls undi to disable the receive filters.
Arguments:
snp - pointer to snp driver structure
DisableFlags - bit mask for disabling the receive filters
ResetMCastList - boolean flag to reset/delete the multicast filter list
Returns:
--*/
{
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
snp->cdb.OpFlags = (UINT16) (DisableFlags ? PXE_OPFLAGS_RECEIVE_FILTER_DISABLE : PXE_OPFLAGS_NOT_USED);
if (ResetMCastList) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_RESET_MCAST_LIST;
}
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_UNICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_UNICAST;
}
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_BROADCAST;
}
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_PROMISCUOUS;
}
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_ALL_MULTICAST;
}
if ((DisableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0) {
snp->cdb.OpFlags |= PXE_OPFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST;
}
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != EFI_SUCCESS) {
//
// UNDI command failed. Return UNDI status to caller.
//
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.receive_filters() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
pxe_rcvfilter_read (
SNP_DRIVER *snp
)
/*++
Routine Description:
this routine calls undi to read the receive filters.
Arguments:
snp - pointer to snp driver structure
Returns:
--*/
{
snp->cdb.OpCode = PXE_OPCODE_RECEIVE_FILTERS;
snp->cdb.OpFlags = PXE_OPFLAGS_RECEIVE_FILTER_READ;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = (UINT16) (snp->mode.MaxMCastFilterCount * sizeof (EFI_MAC_ADDRESS));
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
if (snp->cdb.DBsize == 0) {
snp->cdb.DBaddr = (UINT64) NULL;
} else {
snp->cdb.DBaddr = (UINT64) (UINTN) snp->db;
ZeroMem (snp->db, snp->cdb.DBsize);
}
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
DEBUG ((EFI_D_NET, "\nsnp->undi.receive_filters() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != EFI_SUCCESS) {
//
// UNDI command failed. Return UNDI status to caller.
//
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.receive_filters() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
//
// Convert UNDI32 StatFlags to EFI SNP filter flags.
//
snp->mode.ReceiveFilterSetting = 0;
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_UNICAST) != 0) {
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_UNICAST;
}
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_BROADCAST) != 0) {
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_BROADCAST;
}
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_PROMISCUOUS) != 0) {
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS;
}
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_ALL_MULTICAST) != 0) {
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_PROMISCUOUS_MULTICAST;
}
if ((snp->cdb.StatFlags & PXE_STATFLAGS_RECEIVE_FILTER_FILTERED_MULTICAST) != 0) {
snp->mode.ReceiveFilterSetting |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST;
}
CopyMem (snp->mode.MCastFilter, snp->db, snp->cdb.DBsize);
//
// Count number of active entries in multicast filter list.
//
{
EFI_MAC_ADDRESS ZeroMacAddr;
SetMem (&ZeroMacAddr, sizeof ZeroMacAddr, 0);
for (snp->mode.MCastFilterCount = 0;
snp->mode.MCastFilterCount < snp->mode.MaxMCastFilterCount;
snp->mode.MCastFilterCount++
) {
if (CompareMem (
&snp->mode.MCastFilter[snp->mode.MCastFilterCount],
&ZeroMacAddr,
sizeof ZeroMacAddr
) == 0) {
break;
}
}
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_receive_filters (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN UINT32 EnableFlags,
IN UINT32 DisableFlags,
IN BOOLEAN ResetMCastList,
IN UINTN MCastAddressCount OPTIONAL,
IN EFI_MAC_ADDRESS * MCastAddressList OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for reading/enabling/disabling the
receive filters.
This routine basically retrieves snp structure, checks the SNP state and
checks the parameter validity, calls one of the above routines to actually
do the work
Arguments:
this - context pointer
EnableFlags - bit mask for enabling the receive filters
DisableFlags - bit mask for disabling the receive filters
ResetMCastList - boolean flag to reset/delete the multicast filter list
MCastAddressCount - multicast address count for a new multicast address list
MCastAddressList - list of new multicast addresses
Returns:
--*/
{
SNP_DRIVER *snp;
EFI_STATUS Status;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
// check if we are asked to enable or disable something that the UNDI
// does not even support!
//
if ((EnableFlags &~snp->mode.ReceiveFilterMask) != 0) {
return EFI_INVALID_PARAMETER;
}
if ((DisableFlags &~snp->mode.ReceiveFilterMask) != 0) {
return EFI_INVALID_PARAMETER;
}
if (ResetMCastList) {
DisableFlags |= EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST & snp->mode.ReceiveFilterMask;
MCastAddressCount = 0;
MCastAddressList = NULL;
} else {
if (MCastAddressCount != 0) {
if (MCastAddressCount > snp->mode.MaxMCastFilterCount) {
return EFI_INVALID_PARAMETER;
}
if (MCastAddressList == NULL) {
return EFI_INVALID_PARAMETER;
}
}
}
if (EnableFlags == 0 && DisableFlags == 0 && !ResetMCastList && MCastAddressCount == 0) {
return EFI_SUCCESS;
}
if ((EnableFlags & EFI_SIMPLE_NETWORK_RECEIVE_MULTICAST) != 0 && MCastAddressCount == 0) {
return EFI_INVALID_PARAMETER;
}
if ((EnableFlags != 0) || (MCastAddressCount != 0)) {
Status = pxe_rcvfilter_enable (
snp,
EnableFlags,
MCastAddressCount,
MCastAddressList
);
if (Status != EFI_SUCCESS) {
return Status;
}
}
if ((DisableFlags != 0) || ResetMCastList) {
Status = pxe_rcvfilter_disable (snp, DisableFlags, ResetMCastList);
if (Status != EFI_SUCCESS) {
return Status;
}
}
return pxe_rcvfilter_read (snp);
}

View File

@@ -0,0 +1,129 @@
/*++
Copyright (c) 2006, 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:
reset.c
Abstract:
Revision history:
2000-Feb-09 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_reset (
SNP_DRIVER *snp
)
/*++
Routine Description:
This routine calls undi to reset the nic.
Arguments:
snp - pointer to the snp driver structure
Returns:
EFI_SUCCESSFUL for a successful completion
other for failed calls
--*/
{
snp->cdb.OpCode = PXE_OPCODE_RESET;
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.reset() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nsnp->undi32.reset() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
//
// UNDI could not be reset. Return UNDI error.
//
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_reset (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN ExtendedVerification
)
/*++
Routine Description:
This is the SNP interface routine for resetting the NIC
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_reset routine to actually do the reset!
Arguments:
this - context pointer
ExtendedVerification - not implemented
Returns:
--*/
{
SNP_DRIVER *snp;
//
// Resolve Warning 4 unreferenced parameter problem
//
ExtendedVerification = 0;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
return pxe_reset (snp);
}

View File

@@ -0,0 +1,152 @@
/*++
Copyright (c) 2006, 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:
shutdown.c
Abstract:
Revision history:
2000-Feb-14 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_shutdown (
IN SNP_DRIVER *snp
)
/*++
Routine Description:
this routine calls undi to shut down the interface.
Arguments:
snp - pointer to snp driver structure
Returns:
--*/
{
snp->cdb.OpCode = PXE_OPCODE_SHUTDOWN;
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.shutdown() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
//
// UNDI could not be shutdown. Return UNDI error.
//
DEBUG ((EFI_D_WARN, "\nsnp->undi.shutdown() %xh:%xh\n", snp->cdb.StatFlags, snp->cdb.StatCode));
return EFI_DEVICE_ERROR;
}
//
// Free allocated memory.
//
if (snp->tx_rx_buffer != NULL) {
snp->IoFncs->FreeBuffer (
snp->IoFncs,
SNP_MEM_PAGES (snp->tx_rx_bufsize),
(VOID *) snp->tx_rx_buffer
);
}
snp->tx_rx_buffer = NULL;
snp->tx_rx_bufsize = 0;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_shutdown (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
)
/*++
Routine Description:
This is the SNP interface routine for shutting down the interface
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_shutdown routine to actually do the undi shutdown
Arguments:
this - context pointer
Returns:
--*/
{
SNP_DRIVER *snp;
EFI_STATUS status;
//
//
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
//
//
//
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
//
//
status = pxe_shutdown (snp);
snp->mode.State = EfiSimpleNetworkStarted;
snp->mode.ReceiveFilterSetting = 0;
snp->mode.MCastFilterCount = 0;
snp->mode.ReceiveFilterSetting = 0;
ZeroMem (snp->mode.MCastFilter, sizeof snp->mode.MCastFilter);
CopyMem (
&snp->mode.CurrentAddress,
&snp->mode.PermanentAddress,
sizeof (EFI_MAC_ADDRESS)
);
gBS->CloseEvent (snp->snp.WaitForPacket);
return status;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,410 @@
/*++
Copyright (c) 2006, 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:
snp.h
Abstract:
Revision history:
2000-Feb-03 M(f)J Genesis.
--*/
#ifndef _SNP_H
#define _SNP_H
#include "IndustryStandard/pci22.h"
#define SNP_DEBUG 0
#define FOUR_GIGABYTES (UINT64) 0x100000000ULL
#if SNP_DEBUG
#undef D_NET
#define D_NET D_WARN
#define SNP_PRINT(DebugInfo) Print (DebugInfo)
#else
#define SNP_PRINT(DebugInfo)
#endif
#define SNP_DRIVER_SIGNATURE EFI_SIGNATURE_32 ('s', 'n', 'd', 's')
#define MAX_MAP_LENGTH 100
#define PCI_BAR_IO_MASK 0x00000003
#define PCI_BAR_IO_MODE 0x00000001
#define PCI_BAR_MEM_MASK 0x0000000F
#define PCI_BAR_MEM_MODE 0x00000000
#define PCI_BAR_MEM_64BIT 0x00000004
typedef struct {
UINT32 Signature;
EFI_LOCK lock;
EFI_SIMPLE_NETWORK_PROTOCOL snp;
EFI_SIMPLE_NETWORK_MODE mode;
EFI_HANDLE device_handle;
EFI_DEVICE_PATH_PROTOCOL *device_path;
//
// Local instance data needed by SNP driver
//
// Pointer to S/W UNDI API entry point
// This will be NULL for H/W UNDI
//
EFI_STATUS (*issue_undi32_command) (UINT64 cdb);
BOOLEAN is_swundi;
//
// undi interface number, if one undi manages more nics
//
PXE_IFNUM if_num;
//
// Allocated tx/rx buffer that was passed to UNDI Initialize.
//
UINT32 tx_rx_bufsize;
VOID *tx_rx_buffer;
//
// mappable buffers for receive and fill header for undi3.0
// these will be used if the user buffers are above 4GB limit (instead of
// mapping the user buffers)
//
UINT8 *receive_buf;
VOID *ReceiveBufUnmap;
UINT8 *fill_hdr_buf;
VOID *FillHdrBufUnmap;
EFI_PCI_IO_PROTOCOL *IoFncs;
UINT8 IoBarIndex;
UINT8 MemoryBarIndex;
BOOLEAN IsOldUndi; // true for EFI1.0 UNDI (3.0) drivers
//
// Buffers for command descriptor block, command parameter block
// and data block.
//
PXE_CDB cdb;
VOID *cpb;
VOID *CpbUnmap;
VOID *db;
//
// UNDI structure, we need to remember the init info for a long time!
//
PXE_DB_GET_INIT_INFO init_info;
VOID *SnpDriverUnmap;
//
// when ever we map an address, we must remember it's address and the un-map
// cookie so that we can unmap later
//
struct s_map_list {
EFI_PHYSICAL_ADDRESS virt;
VOID *map_cookie;
} map_list[MAX_MAP_LENGTH];
}
SNP_DRIVER;
#define EFI_SIMPLE_NETWORK_DEV_FROM_THIS(a) CR (a, SNP_DRIVER, snp, SNP_DRIVER_SIGNATURE)
//
// Global Variables
//
extern EFI_COMPONENT_NAME_PROTOCOL gSimpleNetworkComponentName;
extern EFI_DRIVER_BINDING_PROTOCOL gSimpleNetworkDriverBinding;
//
// Virtual to physical mapping for all UNDI 3.0s.
//
extern struct s_v2p {
struct s_v2p *next;
VOID *vaddr;
UINTN bsize;
EFI_PHYSICAL_ADDRESS paddr;
VOID *unmap;
}
*_v2p;
EFI_STATUS
add_v2p (
struct s_v2p **v2p,
EFI_PCI_IO_PROTOCOL_OPERATION type,
VOID *vaddr,
UINTN bsize
)
;
EFI_STATUS
find_v2p (
struct s_v2p **v2p,
VOID *vaddr
)
;
EFI_STATUS
del_v2p (
VOID *vaddr
)
;
extern
VOID
snp_undi32_callback_block_30 (
IN UINT32 Enable
)
;
extern
VOID
snp_undi32_callback_delay_30 (
IN UINT64 MicroSeconds
)
;
extern
VOID
snp_undi32_callback_memio_30 (
IN UINT8 ReadOrWrite,
IN UINT8 NumBytes,
IN UINT64 MemOrPortAddress,
IN OUT UINT64 BufferPtr
)
;
extern
VOID
snp_undi32_callback_v2p_30 (
IN UINT64 CpuAddr,
IN OUT UINT64 DeviceAddrPtr
)
;
extern
VOID
snp_undi32_callback_block (
IN UINT64 UniqueId,
IN UINT32 Enable
)
;
extern
VOID
snp_undi32_callback_delay (
IN UINT64 UniqueId,
IN UINT64 MicroSeconds
)
;
extern
VOID
snp_undi32_callback_memio (
IN UINT64 UniqueId,
IN UINT8 ReadOrWrite,
IN UINT8 NumBytes,
IN UINT64 MemOrPortAddr,
IN OUT UINT64 BufferPtr
)
;
extern
VOID
snp_undi32_callback_map (
IN UINT64 UniqueId,
IN UINT64 CpuAddr,
IN UINT32 NumBytes,
IN UINT32 Direction,
IN OUT UINT64 DeviceAddrPtr
)
;
extern
VOID
snp_undi32_callback_unmap (
IN UINT64 UniqueId,
IN UINT64 CpuAddr,
IN UINT32 NumBytes,
IN UINT32 Direction,
IN UINT64 DeviceAddr // not a pointer to device address
)
;
extern
VOID
snp_undi32_callback_sync (
IN UINT64 UniqueId,
IN UINT64 CpuAddr,
IN UINT32 NumBytes,
IN UINT32 Direction,
IN UINT64 DeviceAddr // not a pointer to device address
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_start (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_stop (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_initialize (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN UINTN extra_rx_buffer_size OPTIONAL,
IN UINTN extra_tx_buffer_size OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_reset (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN ExtendedVerification
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_shutdown (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_receive_filters (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN UINT32 enable,
IN UINT32 disable,
IN BOOLEAN reset_mcast_filter,
IN UINTN mcast_filter_count OPTIONAL,
IN EFI_MAC_ADDRESS * mcast_filter OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_station_address (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN BOOLEAN reset,
IN EFI_MAC_ADDRESS *new OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_statistics (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN BOOLEAN reset,
IN OUT UINTN *statistics_size OPTIONAL,
IN OUT EFI_NETWORK_STATISTICS * statistics_table OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_mcast_ip_to_mac (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN IPv6,
IN EFI_IP_ADDRESS *IP,
OUT EFI_MAC_ADDRESS *MAC
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_nvdata (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this,
IN BOOLEAN read_write,
IN UINTN offset,
IN UINTN buffer_size,
IN OUT VOID *buffer
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_get_status (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
OUT UINT32 *interrupt_status OPTIONAL,
OUT VOID **tx_buffer OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_transmit (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN UINTN header_size,
IN UINTN buffer_size,
IN VOID *buffer,
IN EFI_MAC_ADDRESS * src_addr OPTIONAL,
IN EFI_MAC_ADDRESS * dest_addr OPTIONAL,
IN UINT16 *protocol OPTIONAL
)
;
extern
EFI_STATUS
EFIAPI
snp_undi32_receive (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
OUT UINTN *header_size OPTIONAL,
IN OUT UINTN *buffer_size,
OUT VOID *buffer,
OUT EFI_MAC_ADDRESS * src_addr OPTIONAL,
OUT EFI_MAC_ADDRESS * dest_addr OPTIONAL,
OUT UINT16 *protocol OPTIONAL
)
;
typedef
EFI_STATUS
(*issue_undi32_command) (
UINT64 cdb
);
typedef
VOID
(*ptr) (
VOID
);
#define SNP_MEM_PAGES(x) (((x) - 1) / 4096 + 1)
#if SNP_DEBUG
extern
VOID
snp_wait_for_key (
VOID
)
;
#endif
#endif /* _SNP_H */

View File

@@ -0,0 +1,191 @@
/*++
Copyright (c) 2006, 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:
start.c
Abstract:
Revision history:
2000-Feb-07 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_start (
SNP_DRIVER *snp
)
/*++
Routine Description:
this routine calls undi to start the interface and changes the snp state!
Arguments:
snp - pointer to snp driver structure
Returns:
--*/
{
PXE_CPB_START_30 *cpb;
PXE_CPB_START_31 *cpb_31;
cpb = snp->cpb;
cpb_31 = snp->cpb;
//
// Initialize UNDI Start CDB for H/W UNDI
//
snp->cdb.OpCode = PXE_OPCODE_START;
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Make changes to H/W UNDI Start CDB if this is
// a S/W UNDI.
//
if (snp->is_swundi) {
if (snp->IsOldUndi) {
snp->cdb.CPBsize = sizeof (PXE_CPB_START_30);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
cpb->Delay = (UINT64) &snp_undi32_callback_delay_30;
cpb->Block = (UINT64) &snp_undi32_callback_block_30;
//
// Virtual == Physical. This can be set to zero.
//
cpb->Virt2Phys = (UINT64) &snp_undi32_callback_v2p_30;
cpb->Mem_IO = (UINT64) &snp_undi32_callback_memio_30;
} else {
snp->cdb.CPBsize = sizeof (PXE_CPB_START_31);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb_31;
cpb_31->Delay = (UINT64) &snp_undi32_callback_delay;
cpb_31->Block = (UINT64) &snp_undi32_callback_block;
//
// Virtual == Physical. This can be set to zero.
//
cpb_31->Virt2Phys = (UINT64) 0;
cpb_31->Mem_IO = (UINT64) &snp_undi32_callback_memio;
cpb_31->Map_Mem = (UINT64) &snp_undi32_callback_map;
cpb_31->UnMap_Mem = (UINT64) &snp_undi32_callback_unmap;
cpb_31->Sync_Mem = (UINT64) &snp_undi32_callback_sync;
cpb_31->Unique_ID = (UINT64) (UINTN) snp;
}
}
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.start() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
//
// UNDI could not be started. Return UNDI error.
//
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.start() %xh:%xh\n",
snp->cdb.StatCode,
snp->cdb.StatFlags)
);
return EFI_DEVICE_ERROR;
}
//
// Set simple network state to Started and return success.
//
snp->mode.State = EfiSimpleNetworkStarted;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_start (
IN EFI_SIMPLE_NETWORK_PROTOCOL *This
)
/*++
Routine Description:
This is the SNP interface routine for starting the interface
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_start routine to actually do start undi interface
Arguments:
This - context pointer
Returns:
EFI_INVALID_PARAMETER - "This" is Null
- No SNP driver can be extracted from "This"
EFI_ALREADY_STARTED - The state of SNP is EfiSimpleNetworkStarted
or EfiSimpleNetworkInitialized
EFI_DEVICE_ERROR - The state of SNP is other than EfiSimpleNetworkStarted,
EfiSimpleNetworkInitialized, and EfiSimpleNetworkStopped
EFI_SUCCESS - UNDI interface is succesfully started
Other - Error occurs while calling pxe_start function.
--*/
{
SNP_DRIVER *Snp;
EFI_STATUS Status;
UINTN Index;
if (This == NULL) {
return EFI_INVALID_PARAMETER;
}
Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
if (Snp == NULL) {
return EFI_INVALID_PARAMETER;
}
switch (Snp->mode.State) {
case EfiSimpleNetworkStopped:
break;
case EfiSimpleNetworkStarted:
case EfiSimpleNetworkInitialized:
return EFI_ALREADY_STARTED;
default:
return EFI_DEVICE_ERROR;
}
Status = pxe_start (Snp);
if (Status != EFI_SUCCESS) {
return Status;
}
//
// clear the map_list in SNP structure
//
for (Index = 0; Index < MAX_MAP_LENGTH; Index++) {
Snp->map_list[Index].virt = 0;
Snp->map_list[Index].map_cookie = 0;
}
Snp->mode.MCastFilterCount = 0;
return Status;
}

View File

@@ -0,0 +1,248 @@
/*++
Copyright (c) 2006, 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:
station_address.c
Abstract:
Revision history:
2000-Feb-17 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_get_stn_addr (
SNP_DRIVER *snp
)
/*++
Routine Description:
this routine calls undi to read the MAC address of the NIC and updates the
mode structure with the address.
Arguments:
snp - pointer to snp driver structure
Returns:
--*/
{
PXE_DB_STATION_ADDRESS *db;
db = snp->db;
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.station_addr() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
//
// Set new station address in SNP->Mode structure and return success.
//
CopyMem (
&(snp->mode.CurrentAddress),
&db->StationAddr,
snp->mode.HwAddressSize
);
CopyMem (
&snp->mode.BroadcastAddress,
&db->BroadcastAddr,
snp->mode.HwAddressSize
);
CopyMem (
&snp->mode.PermanentAddress,
&db->PermanentAddr,
snp->mode.HwAddressSize
);
return EFI_SUCCESS;
}
EFI_STATUS
pxe_set_stn_addr (
SNP_DRIVER *snp,
EFI_MAC_ADDRESS *NewMacAddr
)
/*++
Routine Description:
this routine calls undi to set a new MAC address for the NIC,
Arguments:
snp - pointer to snp driver structure
NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
then this routine resets the mac address to the NIC's original
address.
Returns:
--*/
{
PXE_CPB_STATION_ADDRESS *cpb;
PXE_DB_STATION_ADDRESS *db;
cpb = snp->cpb;
db = snp->db;
snp->cdb.OpCode = PXE_OPCODE_STATION_ADDRESS;
if (NewMacAddr == NULL) {
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_RESET;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
} else {
snp->cdb.OpFlags = PXE_OPFLAGS_STATION_ADDRESS_READ;
//
// even though the OPFLAGS are set to READ, supplying a new address
// in the CPB will make undi change the mac address to the new one.
//
CopyMem (&cpb->StationAddr, NewMacAddr, snp->mode.HwAddressSize);
snp->cdb.CPBsize = sizeof (PXE_CPB_STATION_ADDRESS);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
}
snp->cdb.DBsize = sizeof (PXE_DB_STATION_ADDRESS);
snp->cdb.DBaddr = (UINT64) (UINTN) db;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.station_addr() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.station_addr() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
//
// UNDI command failed. Return UNDI status to caller.
//
return EFI_DEVICE_ERROR;
}
//
// read the changed address and save it in SNP->Mode structure
//
pxe_get_stn_addr (snp);
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_station_address (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN BOOLEAN ResetFlag,
IN EFI_MAC_ADDRESS * NewMacAddr OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for changing the NIC's mac address.
This routine basically retrieves snp structure, checks the SNP state and
calls the above routines to actually do the work
Arguments:
this - context pointer
NewMacAddr - pointer to a mac address to be set for the nic, if this is NULL
then this routine resets the mac address to the NIC's original
address.
ResetFlag - If true, the mac address will change to NIC's original address
Returns:
--*/
{
SNP_DRIVER *snp;
EFI_STATUS Status;
//
// Get pointer to SNP driver instance for *this.
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Return error if the SNP is not initialized.
//
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
// Check for invalid parameter combinations.
//
if (!ResetFlag && NewMacAddr == NULL) {
return EFI_INVALID_PARAMETER;
}
if (ResetFlag) {
Status = pxe_set_stn_addr (snp, NULL);
} else {
Status = pxe_set_stn_addr (snp, NewMacAddr);
}
return Status;
}

View File

@@ -0,0 +1,193 @@
/*++
Copyright (c) 2006, 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:
statistics.c
Abstract:
Revision history:
2000-Feb-17 M(f)J Genesis.
--*/
#include "Snp.h"
EFI_STATUS
EFIAPI
snp_undi32_statistics (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN BOOLEAN ResetFlag,
IN OUT UINTN *StatTableSizePtr OPTIONAL,
IN OUT EFI_NETWORK_STATISTICS * StatTablePtr OPTIONAL
)
/*++
Routine Description:
This is the SNP interface routine for getting the NIC's statistics.
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_ routine to actually do the
Arguments:
this - context pointer
ResetFlag - true to reset the NIC's statistics counters to zero.
StatTableSizePtr - pointer to the statistics table size
StatTablePtr - pointer to the statistics table
Returns:
--*/
{
SNP_DRIVER *snp;
PXE_DB_STATISTICS *db;
UINT64 *stp;
UINT64 mask;
UINTN size;
UINTN n;
//
// Get pointer to SNP driver instance for *this.
//
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
//
// Return error if the SNP is not initialized.
//
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
//
// if we are not resetting the counters, we have to have a valid stat table
// with >0 size. if no reset, no table and no size, return success.
//
if (!ResetFlag && StatTableSizePtr == NULL) {
return StatTablePtr ? EFI_INVALID_PARAMETER : EFI_SUCCESS;
}
//
// Initialize UNDI Statistics CDB
//
snp->cdb.OpCode = PXE_OPCODE_STATISTICS;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
if (ResetFlag) {
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_RESET;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
db = snp->db;
} else {
snp->cdb.OpFlags = PXE_OPFLAGS_STATISTICS_READ;
snp->cdb.DBsize = sizeof (PXE_DB_STATISTICS);
snp->cdb.DBaddr = (UINT64) (UINTN) (db = snp->db);
}
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.statistics() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
break;
case PXE_STATCODE_UNSUPPORTED:
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.statistics() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_UNSUPPORTED;
default:
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.statistics() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
if (ResetFlag) {
return EFI_SUCCESS;
}
if (StatTablePtr == NULL) {
*StatTableSizePtr = sizeof (EFI_NETWORK_STATISTICS);
return EFI_BUFFER_TOO_SMALL;
}
//
// Convert the UNDI statistics information to SNP statistics
// information.
//
ZeroMem (StatTablePtr, *StatTableSizePtr);
stp = (UINT64 *) StatTablePtr;
size = 0;
for (n = 0, mask = 1; n < 64; n++, mask = LShiftU64 (mask, 1), stp++) {
//
// There must be room for a full UINT64. Partial
// numbers will not be stored.
//
if ((n + 1) * sizeof (UINT64) > *StatTableSizePtr) {
break;
}
if (db->Supported & mask) {
*stp = db->Data[n];
size = n + 1;
} else {
SetMem (stp, sizeof (UINT64), 0xFF);
}
}
//
// Compute size up to last supported statistic.
//
while (++n < 64) {
if (db->Supported & (mask = LShiftU64 (mask, 1))) {
size = n;
}
}
size *= sizeof (UINT64);
if (*StatTableSizePtr >= size) {
*StatTableSizePtr = size;
return EFI_SUCCESS;
} else {
*StatTableSizePtr = size;
return EFI_BUFFER_TOO_SMALL;
}
}

View File

@@ -0,0 +1,120 @@
/*++
Copyright (c) 2006, 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:
stop.c
Abstract:
Revision history:
2000-Feb-09 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_stop (
SNP_DRIVER *snp
)
/*++
Routine Description:
this routine calls undi to stop the interface and changes the snp state
Arguments:
snp - pointer to snp driver structure
Returns:
--*/
{
snp->cdb.OpCode = PXE_OPCODE_STOP;
snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
snp->cdb.CPBsize = PXE_CPBSIZE_NOT_USED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.CPBaddr = PXE_CPBADDR_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command
//
DEBUG ((EFI_D_NET, "\nsnp->undi.stop() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->cdb.StatCode != PXE_STATCODE_SUCCESS) {
DEBUG (
(EFI_D_WARN,
"\nsnp->undi.stop() %xh:%xh\n",
snp->cdb.StatCode,
snp->cdb.StatFlags)
);
return EFI_DEVICE_ERROR;
}
//
// Set simple network state to Started and return success.
//
snp->mode.State = EfiSimpleNetworkStopped;
return EFI_SUCCESS;
}
EFI_STATUS
EFIAPI
snp_undi32_stop (
IN EFI_SIMPLE_NETWORK_PROTOCOL *this
)
/*++
Routine Description:
This is the SNP interface routine for stopping the interface.
This routine basically retrieves snp structure, checks the SNP state and
calls the pxe_stop routine to actually stop the undi interface
Arguments:
this - context pointer
Returns:
--*/
{
SNP_DRIVER *snp;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkStarted:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkInitialized:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
return pxe_stop (snp);
}

View File

@@ -0,0 +1,396 @@
/*++
Copyright (c) 2006, 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:
transmit.c
Abstract:
Revision history:
2000-Feb-03 M(f)J Genesis.
--*/
#include "snp.h"
EFI_STATUS
pxe_fillheader (
SNP_DRIVER *snp,
VOID *MacHeaderPtr,
UINTN MacHeaderSize,
VOID *BufferPtr,
UINTN BufferLength,
EFI_MAC_ADDRESS *DestinationAddrPtr,
EFI_MAC_ADDRESS *SourceAddrPtr,
UINT16 *ProtocolPtr
)
/*++
Routine Description:
This routine calls undi to create the meadia header for the given data buffer.
Arguments:
snp - pointer to SNP driver structure
MacHeaderPtr - address where the media header will be filled in.
MacHeaderSize - size of the memory at MacHeaderPtr
BufferPtr - data buffer pointer
BufferLength - Size of data in the BufferPtr
DestinationAddrPtr - address of the destination mac address buffer
SourceAddrPtr - address of the source mac address buffer
ProtocolPtr - address of the protocol type
Returns:
EFI_SUCCESS - if successfully completed the undi call
Other - error return from undi call.
--*/
{
PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;
EFI_STATUS Status;
struct s_v2p *pkt_v2p;
UINT64 TempData;
cpb = snp->cpb;
if (SourceAddrPtr) {
CopyMem (
(VOID *) cpb->SrcAddr,
(VOID *) SourceAddrPtr,
snp->mode.HwAddressSize
);
} else {
CopyMem (
(VOID *) cpb->SrcAddr,
(VOID *) &(snp->mode.CurrentAddress),
snp->mode.HwAddressSize
);
}
CopyMem (
(VOID *) cpb->DestAddr,
(VOID *) DestinationAddrPtr,
snp->mode.HwAddressSize
);
//
// we need to do the byte swapping
//
cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);
cpb->PacketLen = (UINT32) (BufferLength);
cpb->MediaHeaderLen = (UINT16) MacHeaderSize;
cpb->FragCnt = 2;
cpb->reserved = 0;
cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) MacHeaderPtr;
cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;
cpb->FragDesc[1].FragAddr = (UINT64) (UINTN) BufferPtr;
cpb->FragDesc[1].FragLen = (UINT32) BufferLength;
cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;
if (snp->IsOldUndi) {
TempData = (UINT64) (UINTN) MacHeaderPtr;
if (TempData >= FOUR_GIGABYTES) {
cpb->FragDesc[0].FragAddr = (UINT64) (UINTN) snp->fill_hdr_buf;
cpb->FragDesc[0].FragLen = (UINT32) snp->init_info.MediaHeaderLen;
}
TempData = (UINT64) (UINTN) (BufferPtr);
if (TempData >= FOUR_GIGABYTES) {
//
// Let the device just read this buffer
//
Status = add_v2p (
&pkt_v2p,
EfiPciIoOperationBusMasterRead,
BufferPtr,
BufferLength
);
if (Status != EFI_SUCCESS) {
return Status;
}
//
// give the virtual address to UNDI and it will call back on Virt2Phys
// to get the mapped address, if it needs it
//
cpb->FragDesc[1].FragLen = (UINT32) pkt_v2p->bsize;
}
}
snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;
snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
if (snp->IsOldUndi) {
TempData = (UINT64) (UINTN) (BufferPtr);
if (TempData >= FOUR_GIGABYTES) {
del_v2p (BufferPtr);
}
//
// if we used the global buffer for header, copy the contents
//
TempData = (UINT64) (UINTN) MacHeaderPtr;
if (TempData >= FOUR_GIGABYTES) {
CopyMem (
MacHeaderPtr,
snp->fill_hdr_buf,
snp->init_info.MediaHeaderLen
);
}
}
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
return EFI_SUCCESS;
case PXE_STATCODE_INVALID_PARAMETER:
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.fill_header() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_INVALID_PARAMETER;
default:
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.fill_header() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return EFI_DEVICE_ERROR;
}
}
EFI_STATUS
pxe_transmit (
SNP_DRIVER *snp,
VOID *BufferPtr,
UINTN BufferLength
)
/*++
Routine Description:
This routine calls undi to transmit the given data buffer
Arguments:
snp - pointer to SNP driver structure
BufferPtr - data buffer pointer
BufferLength - Size of data in the BufferPtr
Returns:
EFI_SUCCESS - if successfully completed the undi call
Other - error return from undi call.
--*/
{
PXE_CPB_TRANSMIT *cpb;
EFI_STATUS Status;
struct s_v2p *v2p;
UINT64 TempData;
cpb = snp->cpb;
cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;
cpb->DataLen = (UINT32) BufferLength;
TempData = (UINT64) (UINTN) BufferPtr;
if (snp->IsOldUndi && (TempData >= FOUR_GIGABYTES)) {
//
// we need to create a mapping now and give it to the undi when it calls
// the Virt2Phys on this address.
// this is a transmit, just map it for the device to READ
//
Status = add_v2p (
&v2p,
EfiPciIoOperationBusMasterRead,
BufferPtr,
BufferLength
);
if (Status != EFI_SUCCESS) {
return Status;
}
cpb->DataLen = (UINT32) v2p->bsize;
}
cpb->MediaheaderLen = 0;
cpb->reserved = 0;
snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;
snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);
snp->cdb.CPBaddr = (UINT64) (UINTN) cpb;
snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;
snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;
snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;
snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;
snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
snp->cdb.IFnum = snp->if_num;
snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
//
// Issue UNDI command and check result.
//
DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));
DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));
DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %X", snp->cdb.CPBaddr));
DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %X", snp->cdb.DBaddr));
DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %X\n", cpb->FrameAddr));
(*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);
DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));
DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));
//
// we will unmap the buffers in get_status call, not here
//
switch (snp->cdb.StatCode) {
case PXE_STATCODE_SUCCESS:
return EFI_SUCCESS;
case PXE_STATCODE_QUEUE_FULL:
case PXE_STATCODE_BUSY:
Status = EFI_NOT_READY;
break;
default:
Status = EFI_DEVICE_ERROR;
}
DEBUG (
(EFI_D_ERROR,
"\nsnp->undi.transmit() %xh:%xh\n",
snp->cdb.StatFlags,
snp->cdb.StatCode)
);
return Status;
}
EFI_STATUS
EFIAPI
snp_undi32_transmit (
IN EFI_SIMPLE_NETWORK_PROTOCOL * this,
IN UINTN MacHeaderSize,
IN UINTN BufferLength,
IN VOID *BufferPtr,
IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,
IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,
IN UINT16 *ProtocolPtr OPTIONAL
)
/*++
Routine Description:
This is the snp interface routine for transmitting a packet. this routine
basically retrieves the snp structure, checks the snp state and calls
pxe_fill_header and pxe_transmit calls to complete the transmission.
Arguments:
this - pointer to SNP driver context
MacHeaderSize - size of the memory at MacHeaderPtr
BufferLength - Size of data in the BufferPtr
BufferPtr - data buffer pointer
SourceAddrPtr - address of the source mac address buffer
DestinationAddrPtr - address of the destination mac address buffer
ProtocolPtr - address of the protocol type
Returns:
EFI_SUCCESS - if successfully completed the undi call
Other - error return from undi call.
--*/
{
SNP_DRIVER *snp;
EFI_STATUS Status;
if (this == NULL) {
return EFI_INVALID_PARAMETER;
}
snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);
if (snp == NULL) {
return EFI_DEVICE_ERROR;
}
switch (snp->mode.State) {
case EfiSimpleNetworkInitialized:
break;
case EfiSimpleNetworkStopped:
return EFI_NOT_STARTED;
case EfiSimpleNetworkStarted:
return EFI_DEVICE_ERROR;
default:
return EFI_DEVICE_ERROR;
}
if (BufferPtr == NULL) {
return EFI_INVALID_PARAMETER;
}
if (BufferLength < snp->mode.MediaHeaderSize) {
return EFI_BUFFER_TOO_SMALL;
}
//
// if the MacHeaderSize is non-zero, we need to fill up the header and for that
// we need the destination address and the protocol
//
if (MacHeaderSize != 0) {
if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {
return EFI_INVALID_PARAMETER;
}
Status = pxe_fillheader (
snp,
BufferPtr,
MacHeaderSize,
(UINT8 *) BufferPtr + MacHeaderSize,
BufferLength - MacHeaderSize,
DestinationAddrPtr,
SourceAddrPtr,
ProtocolPtr
);
if (Status != EFI_SUCCESS) {
return Status;
}
}
return pxe_transmit (snp, BufferPtr, BufferLength);
}