]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/SnpDxe/Receive.c
BaseTools:Change the path of the file that Binary Cache
[mirror_edk2.git] / MdeModulePkg / Universal / Network / SnpDxe / Receive.c
index 48c47f15e0556ddc0e6768c1b0c5707e3ee259ed..28cea0d2e9722fbfa5482e7398a2a8388d7a1f9a 100644 (file)
@@ -1,20 +1,8 @@
 /** @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 receiving a packet from a network interface.\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
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
 \r
@@ -22,69 +10,77 @@ Revision history:
 #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
 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
@@ -92,8 +88,8 @@ pxe_receive (
     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
@@ -102,80 +98,120 @@ pxe_receive (
     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
@@ -188,24 +224,24 @@ snp_undi32_receive (
     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