/** @file\r
-Copyright (c) 2004 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+ Implementation of transmitting a packet.\r
+ \r
+Copyright (c) 2004 - 2007, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed \r
+and made available under the terms and conditions of the BSD License which \r
+accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
\r
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
\r
-Module name:\r
-\r
- transmit.c\r
-\r
-Abstract:\r
-\r
-Revision history:\r
- 2000-Feb-03 M(f)J Genesis.\r
-\r
**/\r
\r
#include "Snp.h"\r
\r
\r
/**\r
- This routine calls undi to create the meadia header for the given data buffer.\r
+ Call UNDI to create the meadia header for the given data buffer.\r
\r
- @param snp pointer to SNP driver structure\r
- @param MacHeaderPtr address where the media header will be filled in.\r
- @param MacHeaderSize size of the memory at MacHeaderPtr\r
- @param BufferPtr data buffer pointer\r
- @param BufferLength Size of data in the BufferPtr\r
- @param DestinationAddrPtr address of the destination mac address buffer\r
- @param SourceAddrPtr address of the source mac address buffer\r
- @param ProtocolPtr address of the protocol type\r
+ @param Snp Pointer to SNP driver structure.\r
+ @param MacHeaderPtr Address where the media header will be filled in.\r
+ @param HeaderSize Size of the memory at MacHeaderPtr.\r
+ @param Buffer Data buffer pointer.\r
+ @param BufferSize Size of data in the Buffer\r
+ @param DestAddr Address of the destination mac address buffer.\r
+ @param SrcAddr Address of the source mac address buffer.\r
+ @param ProtocolPtr Address of the protocol type.\r
\r
- @retval EFI_SUCCESS if successfully completed the undi call\r
- @retval Other error return from undi call.\r
+ @retval EFI_SUCCESS Successfully completed the undi call.\r
+ @retval Other Error return from undi call.\r
\r
**/\r
EFI_STATUS\r
-pxe_fillheader (\r
- SNP_DRIVER *snp,\r
+PxeFillHeader (\r
+ SNP_DRIVER *Snp,\r
VOID *MacHeaderPtr,\r
- UINTN MacHeaderSize,\r
- VOID *BufferPtr,\r
- UINTN BufferLength,\r
- EFI_MAC_ADDRESS *DestinationAddrPtr,\r
- EFI_MAC_ADDRESS *SourceAddrPtr,\r
+ UINTN HeaderSize,\r
+ VOID *Buffer,\r
+ UINTN BufferSize,\r
+ EFI_MAC_ADDRESS *DestAddr,\r
+ EFI_MAC_ADDRESS *SrcAddr,\r
UINT16 *ProtocolPtr\r
)\r
{\r
- PXE_CPB_FILL_HEADER_FRAGMENTED *cpb;\r
+ PXE_CPB_FILL_HEADER_FRAGMENTED *Cpb;\r
\r
- cpb = snp->cpb;\r
- if (SourceAddrPtr) {\r
+ Cpb = Snp->Cpb;\r
+ if (SrcAddr != NULL) {\r
CopyMem (\r
- (VOID *) cpb->SrcAddr,\r
- (VOID *) SourceAddrPtr,\r
- snp->mode.HwAddressSize\r
+ (VOID *) Cpb->SrcAddr,\r
+ (VOID *) SrcAddr,\r
+ Snp->Mode.HwAddressSize\r
);\r
} else {\r
CopyMem (\r
- (VOID *) cpb->SrcAddr,\r
- (VOID *) &(snp->mode.CurrentAddress),\r
- snp->mode.HwAddressSize\r
+ (VOID *) Cpb->SrcAddr,\r
+ (VOID *) &(Snp->Mode.CurrentAddress),\r
+ Snp->Mode.HwAddressSize\r
);\r
}\r
\r
CopyMem (\r
- (VOID *) cpb->DestAddr,\r
- (VOID *) DestinationAddrPtr,\r
- snp->mode.HwAddressSize\r
+ (VOID *) Cpb->DestAddr,\r
+ (VOID *) DestAddr,\r
+ Snp->Mode.HwAddressSize\r
);\r
\r
//\r
// we need to do the byte swapping\r
//\r
- cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);\r
+ Cpb->Protocol = (UINT16) PXE_SWAP_UINT16 (*ProtocolPtr);\r
\r
- cpb->PacketLen = (UINT32) (BufferLength);\r
- cpb->MediaHeaderLen = (UINT16) MacHeaderSize;\r
+ Cpb->PacketLen = (UINT32) (BufferSize);\r
+ Cpb->MediaHeaderLen = (UINT16) HeaderSize;\r
\r
- cpb->FragCnt = 2;\r
- cpb->reserved = 0;\r
+ Cpb->FragCnt = 2;\r
+ Cpb->reserved = 0;\r
\r
- cpb->FragDesc[0].FragAddr = (UINT64)(UINTN) MacHeaderPtr;\r
- cpb->FragDesc[0].FragLen = (UINT32) MacHeaderSize;\r
- cpb->FragDesc[1].FragAddr = (UINT64)(UINTN) BufferPtr;\r
- cpb->FragDesc[1].FragLen = (UINT32) BufferLength;\r
+ Cpb->FragDesc[0].FragAddr = (UINT64)(UINTN) MacHeaderPtr;\r
+ Cpb->FragDesc[0].FragLen = (UINT32) HeaderSize;\r
+ Cpb->FragDesc[1].FragAddr = (UINT64)(UINTN) Buffer;\r
+ Cpb->FragDesc[1].FragLen = (UINT32) BufferSize;\r
\r
- cpb->FragDesc[0].reserved = cpb->FragDesc[1].reserved = 0;\r
+ Cpb->FragDesc[0].reserved = Cpb->FragDesc[1].reserved = 0;\r
\r
- snp->cdb.OpCode = PXE_OPCODE_FILL_HEADER;\r
- snp->cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;\r
+ Snp->Cdb.OpCode = PXE_OPCODE_FILL_HEADER;\r
+ Snp->Cdb.OpFlags = PXE_OPFLAGS_FILL_HEADER_FRAGMENTED;\r
\r
- snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
- snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
+ Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
+ Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
\r
- snp->cdb.CPBsize = sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);\r
- snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;\r
+ Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_FILL_HEADER_FRAGMENTED);\r
+ Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;\r
\r
- snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
- snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
- snp->cdb.IFnum = snp->if_num;\r
- snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
+ Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
+ Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
+ Snp->Cdb.IFnum = Snp->IfNum;\r
+ Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
\r
//\r
// Issue UNDI command and check result.\r
//\r
- DEBUG ((EFI_D_NET, "\nsnp->undi.fill_header() "));\r
+ DEBUG ((EFI_D_NET, "\nSnp->undi.fill_header() "));\r
\r
- (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
+ (*Snp->IssueUndi32Command) ((UINT64) (UINTN) &Snp->Cdb);\r
\r
- switch (snp->cdb.StatCode) {\r
+ switch (Snp->Cdb.StatCode) {\r
case PXE_STATCODE_SUCCESS:\r
return EFI_SUCCESS;\r
\r
case PXE_STATCODE_INVALID_PARAMETER:\r
DEBUG (\r
(EFI_D_ERROR,\r
- "\nsnp->undi.fill_header() %xh:%xh\n",\r
- snp->cdb.StatFlags,\r
- snp->cdb.StatCode)\r
+ "\nSnp->undi.fill_header() %xh:%xh\n",\r
+ Snp->Cdb.StatFlags,\r
+ Snp->Cdb.StatCode)\r
);\r
\r
return EFI_INVALID_PARAMETER;\r
default:\r
DEBUG (\r
(EFI_D_ERROR,\r
- "\nsnp->undi.fill_header() %xh:%xh\n",\r
- snp->cdb.StatFlags,\r
- snp->cdb.StatCode)\r
+ "\nSnp->undi.fill_header() %xh:%xh\n",\r
+ Snp->Cdb.StatFlags,\r
+ Snp->Cdb.StatCode)\r
);\r
\r
return EFI_DEVICE_ERROR;\r
/**\r
This routine calls undi to transmit the given data buffer\r
\r
- @param snp pointer to SNP driver structure\r
- @param BufferPtr data buffer pointer\r
- @param BufferLength Size of data in the BufferPtr\r
+ @param Snp pointer to SNP driver structure\r
+ @param Buffer data buffer pointer\r
+ @param BufferSize Size of data in the Buffer\r
\r
@retval EFI_SUCCESS if successfully completed the undi call\r
@retval Other error return from undi call.\r
\r
**/\r
EFI_STATUS\r
-pxe_transmit (\r
- SNP_DRIVER *snp,\r
- VOID *BufferPtr,\r
- UINTN BufferLength\r
+PxeTransmit (\r
+ SNP_DRIVER *Snp,\r
+ VOID *Buffer,\r
+ UINTN BufferSize\r
)\r
{\r
- PXE_CPB_TRANSMIT *cpb;\r
+ PXE_CPB_TRANSMIT *Cpb;\r
EFI_STATUS Status;\r
\r
- cpb = snp->cpb;\r
- cpb->FrameAddr = (UINT64) (UINTN) BufferPtr;\r
- cpb->DataLen = (UINT32) BufferLength;\r
+ Cpb = Snp->Cpb;\r
+ Cpb->FrameAddr = (UINT64) (UINTN) Buffer;\r
+ Cpb->DataLen = (UINT32) BufferSize;\r
\r
- cpb->MediaheaderLen = 0;\r
- cpb->reserved = 0;\r
+ Cpb->MediaheaderLen = 0;\r
+ Cpb->reserved = 0;\r
\r
- snp->cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;\r
+ Snp->Cdb.OpFlags = PXE_OPFLAGS_TRANSMIT_WHOLE;\r
\r
- snp->cdb.CPBsize = sizeof (PXE_CPB_TRANSMIT);\r
- snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;\r
+ Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_TRANSMIT);\r
+ Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;\r
\r
- snp->cdb.OpCode = PXE_OPCODE_TRANSMIT;\r
- snp->cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
- snp->cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
+ Snp->Cdb.OpCode = PXE_OPCODE_TRANSMIT;\r
+ Snp->Cdb.DBsize = PXE_DBSIZE_NOT_USED;\r
+ Snp->Cdb.DBaddr = PXE_DBADDR_NOT_USED;\r
\r
- snp->cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
- snp->cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
- snp->cdb.IFnum = snp->if_num;\r
- snp->cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
+ Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
+ Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
+ Snp->Cdb.IFnum = Snp->IfNum;\r
+ Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
\r
//\r
// Issue UNDI command and check result.\r
//\r
- DEBUG ((EFI_D_NET, "\nsnp->undi.transmit() "));\r
- DEBUG ((EFI_D_NET, "\nsnp->cdb.OpCode == %x", snp->cdb.OpCode));\r
- DEBUG ((EFI_D_NET, "\nsnp->cdb.CPBaddr == %LX", snp->cdb.CPBaddr));\r
- DEBUG ((EFI_D_NET, "\nsnp->cdb.DBaddr == %LX", snp->cdb.DBaddr));\r
- DEBUG ((EFI_D_NET, "\ncpb->FrameAddr == %LX\n", cpb->FrameAddr));\r
+ DEBUG ((EFI_D_NET, "\nSnp->undi.transmit() "));\r
+ DEBUG ((EFI_D_NET, "\nSnp->Cdb.OpCode == %x", Snp->Cdb.OpCode));\r
+ DEBUG ((EFI_D_NET, "\nSnp->Cdb.CPBaddr == %LX", Snp->Cdb.CPBaddr));\r
+ DEBUG ((EFI_D_NET, "\nSnp->Cdb.DBaddr == %LX", Snp->Cdb.DBaddr));\r
+ DEBUG ((EFI_D_NET, "\nCpb->FrameAddr == %LX\n", Cpb->FrameAddr));\r
\r
- (*snp->issue_undi32_command) ((UINT64) (UINTN) &snp->cdb);\r
+ (*Snp->IssueUndi32Command) ((UINT64) (UINTN) &Snp->Cdb);\r
\r
- DEBUG ((EFI_D_NET, "\nexit snp->undi.transmit() "));\r
- DEBUG ((EFI_D_NET, "\nsnp->cdb.StatCode == %r", snp->cdb.StatCode));\r
+ DEBUG ((EFI_D_NET, "\nexit Snp->undi.transmit() "));\r
+ DEBUG ((EFI_D_NET, "\nSnp->Cdb.StatCode == %r", Snp->Cdb.StatCode));\r
\r
//\r
// we will unmap the buffers in get_status call, not here\r
//\r
- switch (snp->cdb.StatCode) {\r
+ switch (Snp->Cdb.StatCode) {\r
case PXE_STATCODE_SUCCESS:\r
return EFI_SUCCESS;\r
\r
\r
DEBUG (\r
(EFI_D_ERROR,\r
- "\nsnp->undi.transmit() %xh:%xh\n",\r
- snp->cdb.StatFlags,\r
- snp->cdb.StatCode)\r
+ "\nSnp->undi.transmit() %xh:%xh\n",\r
+ Snp->Cdb.StatFlags,\r
+ Snp->Cdb.StatCode)\r
);\r
\r
return Status;\r
}\r
\r
-\r
/**\r
- This is the snp interface routine for transmitting a packet. this routine\r
- basically retrieves the snp structure, checks the snp state and calls\r
- pxe_fill_header and pxe_transmit calls to complete the transmission.\r
-\r
- @param this pointer to SNP driver context\r
- @param MacHeaderSize size of the memory at MacHeaderPtr\r
- @param BufferLength Size of data in the BufferPtr\r
- @param BufferPtr data buffer pointer\r
- @param SourceAddrPtr address of the source mac address buffer\r
- @param DestinationAddrPtr address of the destination mac address buffer\r
- @param ProtocolPtr address of the protocol type\r
-\r
- @retval EFI_SUCCESS if successfully completed the undi call\r
- @retval Other error return from undi call.\r
+ Places a packet in the transmit queue of a network interface.\r
+ \r
+ This function places the packet specified by Header and Buffer on the transmit\r
+ queue. If HeaderSize is nonzero and HeaderSize is not equal to \r
+ This->Mode->MediaHeaderSize, then EFI_INVALID_PARAMETER will be returned. If \r
+ BufferSize is less than This->Mode->MediaHeaderSize, then EFI_BUFFER_TOO_SMALL\r
+ will be returned. If Buffer is NULL, then EFI_INVALID_PARAMETER will be \r
+ returned. If HeaderSize is nonzero and DestAddr or Protocol is NULL, then\r
+ EFI_INVALID_PARAMETER will be returned. If the transmit engine of the network\r
+ interface is busy, then EFI_NOT_READY will be returned. If this packet can be \r
+ accepted by the transmit engine of the network interface, the packet contents \r
+ specified by Buffer will be placed on the transmit queue of the network \r
+ interface, and EFI_SUCCESS will be returned. GetStatus() can be used to \r
+ determine when the packet has actually been transmitted. The contents of the \r
+ Buffer must not be modified until the packet has actually been transmitted. \r
+ The Transmit() function performs nonblocking I/O. A caller who wants to perform\r
+ blocking I/O, should call Transmit(), and then GetStatus() until the \r
+ transmitted buffer shows up in the recycled transmit buffer.\r
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.\r
+\r
+ @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
+ @param HeaderSize The size, in bytes, of the media header to be filled in by the \r
+ Transmit() function. If HeaderSize is nonzero, then it must\r
+ be equal to This->Mode->MediaHeaderSize and the DestAddr and\r
+ Protocol parameters must not be NULL.\r
+ @param BufferSize The size, in bytes, of the entire packet (media header and\r
+ data) to be transmitted through the network interface.\r
+ @param Buffer A pointer to the packet (media header followed by data) to be \r
+ transmitted. This parameter cannot be NULL. If HeaderSize is \r
+ zero, then the media header in Buffer must already be filled\r
+ in by the caller. If HeaderSize is nonzero, then the media \r
+ header will be filled in by the Transmit() function.\r
+ @param SrcAddr The source HW MAC address. If HeaderSize is zero, then this \r
+ parameter is ignored. If HeaderSize is nonzero and SrcAddr \r
+ is NULL, then This->Mode->CurrentAddress is used for the \r
+ source HW MAC address.\r
+ @param DestAddr The destination HW MAC address. If HeaderSize is zero, then \r
+ this parameter is ignored.\r
+ @param Protocol The type of header to build. If HeaderSize is zero, then this \r
+ parameter is ignored. See RFC 1700, section "Ether Types," \r
+ for examples.\r
+\r
+ @retval EFI_SUCCESS The packet was placed on the transmit queue.\r
+ @retval EFI_NOT_STARTED The network interface has not been started.\r
+ @retval EFI_NOT_READY The network interface is too busy to accept this\r
+ transmit request.\r
+ @retval EFI_BUFFER_TOO_SMALL The BufferSize parameter is too small.\r
+ @retval EFI_INVALID_PARAMETER One or more of the parameters has an unsupported\r
+ value.\r
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
+ @retval EFI_UNSUPPORTED This function is not supported by the network interface.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-snp_undi32_transmit (\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
- IN UINTN MacHeaderSize,\r
- IN UINTN BufferLength,\r
- IN VOID *BufferPtr,\r
- IN EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,\r
- IN EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,\r
- IN UINT16 *ProtocolPtr OPTIONAL\r
+SnpUndi32Transmit (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ IN UINTN HeaderSize,\r
+ IN UINTN BufferSize,\r
+ IN VOID *Buffer,\r
+ IN EFI_MAC_ADDRESS *SrcAddr, OPTIONAL\r
+ IN EFI_MAC_ADDRESS *DestAddr, OPTIONAL\r
+ IN UINT16 *Protocol OPTIONAL\r
)\r
{\r
- SNP_DRIVER *snp;\r
+ SNP_DRIVER *Snp;\r
EFI_STATUS Status;\r
EFI_TPL OldTpl;\r
\r
- if (this == NULL) {\r
+ if (This == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (this);\r
+ Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
\r
OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
\r
- if (snp == NULL) {\r
+ if (Snp == NULL) {\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- switch (snp->mode.State) {\r
+ switch (Snp->Mode.State) {\r
case EfiSimpleNetworkInitialized:\r
break;\r
\r
goto ON_EXIT;\r
}\r
\r
- if (BufferPtr == NULL) {\r
+ if (Buffer == NULL) {\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
\r
- if (BufferLength < snp->mode.MediaHeaderSize) {\r
+ if (BufferSize < Snp->Mode.MediaHeaderSize) {\r
Status = EFI_BUFFER_TOO_SMALL;\r
goto ON_EXIT;\r
}\r
\r
//\r
- // if the MacHeaderSize is non-zero, we need to fill up the header and for that\r
+ // if the HeaderSize is non-zero, we need to fill up the header and for that\r
// we need the destination address and the protocol\r
//\r
- if (MacHeaderSize != 0) {\r
- if (MacHeaderSize != snp->mode.MediaHeaderSize || DestinationAddrPtr == 0 || ProtocolPtr == 0) {\r
+ if (HeaderSize != 0) {\r
+ if (HeaderSize != Snp->Mode.MediaHeaderSize || DestAddr == 0 || Protocol == 0) {\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
\r
- Status = pxe_fillheader (\r
- snp,\r
- BufferPtr,\r
- MacHeaderSize,\r
- (UINT8 *) BufferPtr + MacHeaderSize,\r
- BufferLength - MacHeaderSize,\r
- DestinationAddrPtr,\r
- SourceAddrPtr,\r
- ProtocolPtr\r
+ Status = PxeFillHeader (\r
+ Snp,\r
+ Buffer,\r
+ HeaderSize,\r
+ (UINT8 *) Buffer + HeaderSize,\r
+ BufferSize - HeaderSize,\r
+ DestAddr,\r
+ SrcAddr,\r
+ Protocol\r
);\r
\r
if (EFI_ERROR (Status)) {\r
}\r
}\r
\r
- Status = pxe_transmit (snp, BufferPtr, BufferLength);\r
+ Status = PxeTransmit (Snp, Buffer, BufferSize);\r
\r
ON_EXIT:\r
gBS->RestoreTPL (OldTpl);\r