/** @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
+ Implementation of receiving a packet from a network interface.\r
+\r
+Copyright (c) 2004 - 2010, 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
- receive.c\r
-\r
-Abstract:\r
-\r
-Revision history:\r
- 2000-Feb-03 M(f)J Genesis.\r
-\r
**/\r
\r
\r
#include "Snp.h"\r
\r
/**\r
- this routine calls undi to receive a packet and fills in the data in the\r
- input pointers!\r
-\r
- @param snp pointer to snp driver structure\r
- @param BufferPtr pointer to the memory for the received data\r
- @param BuffSizePtr is a pointer to the length of the buffer on entry and\r
- contains the length of the received data on return\r
- @param HeaderSizePtr pointer to the header portion of the data received.\r
- @param SourceAddrPtr optional parameter, is a pointer to contain the\r
- source ethernet address on return\r
- @param DestinationAddrPtr optional parameter, is a pointer to contain the\r
- destination ethernet address on return\r
- @param ProtocolPtr optional parameter, is a pointer to contain the\r
- protocol type from the ethernet header on return\r
-\r
+ Call UNDI to receive a packet and fills in the data in the input pointers.\r
+\r
+ @param Snp Pointer to snp driver structure\r
+ @param Buffer Pointer to the memory for the received data\r
+ @param BufferSize Pointer to the length of the buffer on entry and contains\r
+ the length of the received data on return\r
+ @param HeaderSize Pointer to the header portion of the data received.\r
+ @param SrcAddr Pointer to contain the source ethernet address on return\r
+ @param DestAddr Pointer to contain the destination ethernet address on\r
+ return\r
+ @param Protocol Pointer to contain the protocol type from the ethernet\r
+ header on return\r
+\r
+\r
+ @retval EFI_SUCCESS The received data was stored in Buffer, and\r
+ BufferSize has been updated to the number of\r
+ bytes received.\r
+ @retval EFI_DEVICE_ERROR Fail to execute UNDI command.\r
+ @retval EFI_NOT_READY No packets have been received on the network\r
+ interface.\r
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received\r
+ packets. BufferSize has been updated to the\r
+ required size.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
-pxe_receive (\r
- SNP_DRIVER *snp,\r
- VOID *BufferPtr,\r
- UINTN *BuffSizePtr,\r
- UINTN *HeaderSizePtr,\r
- EFI_MAC_ADDRESS *SourceAddrPtr,\r
- EFI_MAC_ADDRESS *DestinationAddrPtr,\r
- UINT16 *ProtocolPtr\r
+PxeReceive (\r
+ SNP_DRIVER *Snp,\r
+ VOID *Buffer,\r
+ UINTN *BufferSize,\r
+ UINTN *HeaderSize,\r
+ EFI_MAC_ADDRESS *SrcAddr,\r
+ EFI_MAC_ADDRESS *DestAddr,\r
+ UINT16 *Protocol\r
)\r
{\r
- PXE_CPB_RECEIVE *cpb;\r
- PXE_DB_RECEIVE *db;\r
- UINTN buf_size;\r
+ PXE_CPB_RECEIVE *Cpb;\r
+ PXE_DB_RECEIVE *Db;\r
+ UINTN BuffSize;\r
\r
- cpb = snp->cpb;\r
- db = snp->db;\r
- buf_size = *BuffSizePtr;\r
+ Cpb = Snp->Cpb;\r
+ Db = Snp->Db;\r
+ BuffSize = *BufferSize;\r
\r
- cpb->BufferAddr = (UINT64)(UINTN) BufferPtr;\r
- cpb->BufferLen = (UINT32) *BuffSizePtr;\r
+ Cpb->BufferAddr = (UINT64)(UINTN) Buffer;\r
+ Cpb->BufferLen = (UINT32) *BufferSize;\r
\r
- cpb->reserved = 0;\r
+ Cpb->reserved = 0;\r
\r
- snp->cdb.OpCode = PXE_OPCODE_RECEIVE;\r
- snp->cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
+ Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE;\r
+ Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;\r
\r
- snp->cdb.CPBsize = sizeof (PXE_CPB_RECEIVE);\r
- snp->cdb.CPBaddr = (UINT64)(UINTN) cpb;\r
+ Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_RECEIVE);\r
+ Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;\r
\r
- snp->cdb.DBsize = sizeof (PXE_DB_RECEIVE);\r
- snp->cdb.DBaddr = (UINT64)(UINTN) db;\r
+ Snp->Cdb.DBsize = (UINT16) sizeof (PXE_DB_RECEIVE);\r
+ Snp->Cdb.DBaddr = (UINT64)(UINTN) Db;\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.receive () "));\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
break;\r
\r
DEBUG (\r
(EFI_D_NET,\r
"\nsnp->undi.receive () %xh:%xh\n",\r
- snp->cdb.StatFlags,\r
- snp->cdb.StatCode)\r
+ Snp->Cdb.StatFlags,\r
+ Snp->Cdb.StatCode)\r
);\r
\r
return EFI_NOT_READY;\r
DEBUG (\r
(EFI_D_ERROR,\r
"\nsnp->undi.receive() %xh:%xh\n",\r
- snp->cdb.StatFlags,\r
- snp->cdb.StatCode)\r
+ Snp->Cdb.StatFlags,\r
+ Snp->Cdb.StatCode)\r
);\r
\r
return EFI_DEVICE_ERROR;\r
}\r
\r
- *BuffSizePtr = db->FrameLen;\r
+ *BufferSize = Db->FrameLen;\r
\r
- if (HeaderSizePtr != NULL) {\r
- *HeaderSizePtr = db->MediaHeaderLen;\r
+ if (HeaderSize != NULL) {\r
+ *HeaderSize = Db->MediaHeaderLen;\r
}\r
\r
- if (SourceAddrPtr != NULL) {\r
- CopyMem (SourceAddrPtr, &db->SrcAddr, snp->mode.HwAddressSize);\r
+ if (SrcAddr != NULL) {\r
+ CopyMem (SrcAddr, &Db->SrcAddr, Snp->Mode.HwAddressSize);\r
}\r
\r
- if (DestinationAddrPtr != NULL) {\r
- CopyMem (DestinationAddrPtr, &db->DestAddr, snp->mode.HwAddressSize);\r
+ if (DestAddr != NULL) {\r
+ CopyMem (DestAddr, &Db->DestAddr, Snp->Mode.HwAddressSize);\r
}\r
\r
- if (ProtocolPtr != NULL) {\r
- *ProtocolPtr = (UINT16) PXE_SWAP_UINT16 (db->Protocol); /* we need to do the byte swapping */\r
+ if (Protocol != NULL) {\r
+ //\r
+ // We need to do the byte swapping\r
+ //\r
+ *Protocol = (UINT16) PXE_SWAP_UINT16 (Db->Protocol);\r
}\r
\r
- return (*BuffSizePtr <= buf_size) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
-}\r
+ //\r
+ // We have received a packet from network interface, which implies that the\r
+ // network cable should be present. While, some UNDI driver may not report\r
+ // correct media status during Snp->Initialize(). So, we need ensure\r
+ // MediaPresent in SNP mode data is set to correct value.\r
+ //\r
+ if (Snp->Mode.MediaPresentSupported && !Snp->Mode.MediaPresent) {\r
+ Snp->Mode.MediaPresent = TRUE;\r
+ }\r
\r
+ return (*BufferSize <= BuffSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;\r
+}\r
\r
/**\r
- This is the SNP interface routine for receiving network data.\r
- This routine basically retrieves snp structure, checks the SNP state and\r
- calls the pxe_receive routine to actually do the receive!\r
-\r
- @param this context pointer\r
- @param HeaderSizePtr optional parameter and is a pointer to the header\r
- portion of the data received.\r
- @param BuffSizePtr is a pointer to the length of the buffer on entry and\r
- contains the length of the received data on return\r
- @param BufferPtr pointer to the memory for the received data\r
- @param SourceAddrPtr optional parameter, is a pointer to contain the\r
- source ethernet address on return\r
- @param DestinationAddrPtr optional parameter, is a pointer to contain the\r
- destination ethernet address on return\r
- @param ProtocolPtr optional parameter, is a pointer to contain the\r
- protocol type from the ethernet header on return\r
-\r
+ Receives a packet from a network interface.\r
+\r
+ This function retrieves one packet from the receive queue of a network interface.\r
+ If there are no packets on the receive queue, then EFI_NOT_READY will be\r
+ returned. If there is a packet on the receive queue, and the size of the packet\r
+ is smaller than BufferSize, then the contents of the packet will be placed in\r
+ Buffer, and BufferSize will be updated with the actual size of the packet.\r
+ In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values\r
+ will be extracted from the media header and returned. EFI_SUCCESS will be\r
+ returned if a packet was successfully received.\r
+ If BufferSize is smaller than the received packet, then the size of the receive\r
+ packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.\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 received on the network\r
+ interface. If this parameter is NULL, then the media header size\r
+ will not be returned.\r
+ @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in\r
+ bytes, of the packet that was received on the network interface.\r
+ @param Buffer A pointer to the data buffer to receive both the media\r
+ header and the data.\r
+ @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW\r
+ MAC source address will not be extracted from the media header.\r
+ @param DestAddr The destination HW MAC address. If this parameter is NULL,\r
+ the HW MAC destination address will not be extracted from\r
+ the media header.\r
+ @param Protocol The media header type. If this parameter is NULL, then the\r
+ protocol will not be extracted from the media header. See\r
+ RFC 1700 section "Ether Types" for examples.\r
+\r
+ @retval EFI_SUCCESS The received data was stored in Buffer, and\r
+ BufferSize has been updated to the number of\r
+ bytes received.\r
+ @retval EFI_NOT_STARTED The network interface has not been started.\r
+ @retval EFI_NOT_READY No packets have been received on the network interface.\r
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received packets.\r
+ BufferSize has been updated to the required size.\r
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:\r
+ * The This parameter is NULL\r
+ * The This parameter does not point to a valid\r
+ EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
+ * The BufferSize parameter is NULL\r
+ * The Buffer parameter is NULL\r
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
-snp_undi32_receive (\r
- IN EFI_SIMPLE_NETWORK_PROTOCOL * this,\r
- OUT UINTN *HeaderSizePtr OPTIONAL,\r
- IN OUT UINTN *BuffSizePtr,\r
- OUT VOID *BufferPtr,\r
- OUT EFI_MAC_ADDRESS * SourceAddrPtr OPTIONAL,\r
- OUT EFI_MAC_ADDRESS * DestinationAddrPtr OPTIONAL,\r
- OUT UINT16 *ProtocolPtr OPTIONAL\r
+SnpUndi32Receive (\r
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
+ OUT UINTN *HeaderSize OPTIONAL,\r
+ IN OUT UINTN *BufferSize,\r
+ OUT VOID *Buffer,\r
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,\r
+ OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,\r
+ OUT UINT16 *Protocol OPTIONAL\r
)\r
{\r
- SNP_DRIVER *snp;\r
+ SNP_DRIVER *Snp;\r
EFI_TPL OldTpl;\r
EFI_STATUS Status;\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
- switch (snp->mode.State) {\r
+ switch (Snp->Mode.State) {\r
case EfiSimpleNetworkInitialized:\r
break;\r
\r
goto ON_EXIT;\r
}\r
\r
- if ((BuffSizePtr == NULL) || (BufferPtr == NULL)) {\r
+ if ((BufferSize == NULL) || (Buffer == NULL)) {\r
Status = EFI_INVALID_PARAMETER;\r
goto ON_EXIT;\r
}\r
\r
- if (!snp->mode.ReceiveFilterSetting) {\r
+ if (Snp->Mode.ReceiveFilterSetting == 0) {\r
Status = EFI_DEVICE_ERROR;\r
goto ON_EXIT;\r
}\r
\r
- Status = pxe_receive (\r
- snp,\r
- BufferPtr,\r
- BuffSizePtr,\r
- HeaderSizePtr,\r
- SourceAddrPtr,\r
- DestinationAddrPtr,\r
- ProtocolPtr\r
+ Status = PxeReceive (\r
+ Snp,\r
+ Buffer,\r
+ BufferSize,\r
+ HeaderSize,\r
+ SrcAddr,\r
+ DestAddr,\r
+ Protocol\r
);\r
\r
ON_EXIT:\r