summaryrefslogtreecommitdiffstats
path: root/NetworkPkg/SnpDxe/Receive.c
diff options
context:
space:
mode:
authorLiming Gao <liming.gao@intel.com>2019-05-15 20:02:18 +0800
committerLiming Gao <liming.gao@intel.com>2019-05-27 09:25:18 +0800
commit4542f8b8135f1f1ee5654e25139be9769e139ddd (patch)
tree6e05d7c624d89b3df27d0d3437815a2587f0640f /NetworkPkg/SnpDxe/Receive.c
parentc0fd7f734e2d33e22215899b40a47b843129541d (diff)
downloadedk2-4542f8b8135f1f1ee5654e25139be9769e139ddd.tar.gz
edk2-4542f8b8135f1f1ee5654e25139be9769e139ddd.tar.bz2
edk2-4542f8b8135f1f1ee5654e25139be9769e139ddd.zip
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
Signed-off-by: Liming Gao <liming.gao@intel.com> Cc: Siyuan Fu <siyuan.fu@intel.com> Cc: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Jiaxin Wu <jiaxin.wu@intel.com> Reviewed-by: Siyuan Fu <siyuan.fu@intel.com>
Diffstat (limited to 'NetworkPkg/SnpDxe/Receive.c')
-rw-r--r--NetworkPkg/SnpDxe/Receive.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/NetworkPkg/SnpDxe/Receive.c b/NetworkPkg/SnpDxe/Receive.c
new file mode 100644
index 0000000000..28cea0d2e9
--- /dev/null
+++ b/NetworkPkg/SnpDxe/Receive.c
@@ -0,0 +1,251 @@
+/** @file
+ Implementation of receiving a packet from a network interface.
+
+Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Snp.h"
+
+/**
+ Call UNDI to receive a packet and fills in the data in the input pointers.
+
+ @param Snp Pointer to snp driver structure
+ @param Buffer Pointer to the memory for the received data
+ @param BufferSize Pointer to the length of the buffer on entry and contains
+ the length of the received data on return
+ @param HeaderSize Pointer to the header portion of the data received.
+ @param SrcAddr Pointer to contain the source ethernet address on return
+ @param DestAddr Pointer to contain the destination ethernet address on
+ return
+ @param Protocol Pointer to contain the protocol type from the ethernet
+ header on return
+
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and
+ BufferSize has been updated to the number of
+ bytes received.
+ @retval EFI_DEVICE_ERROR Fail to execute UNDI command.
+ @retval EFI_NOT_READY No packets have been received on the network
+ interface.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received
+ packets. BufferSize has been updated to the
+ required size.
+
+**/
+EFI_STATUS
+PxeReceive (
+ SNP_DRIVER *Snp,
+ VOID *Buffer,
+ UINTN *BufferSize,
+ UINTN *HeaderSize,
+ EFI_MAC_ADDRESS *SrcAddr,
+ EFI_MAC_ADDRESS *DestAddr,
+ UINT16 *Protocol
+ )
+{
+ PXE_CPB_RECEIVE *Cpb;
+ PXE_DB_RECEIVE *Db;
+ UINTN BuffSize;
+
+ Cpb = Snp->Cpb;
+ Db = Snp->Db;
+ BuffSize = *BufferSize;
+
+ Cpb->BufferAddr = (UINT64)(UINTN) Buffer;
+ Cpb->BufferLen = (UINT32) *BufferSize;
+
+ Cpb->reserved = 0;
+
+ Snp->Cdb.OpCode = PXE_OPCODE_RECEIVE;
+ Snp->Cdb.OpFlags = PXE_OPFLAGS_NOT_USED;
+
+ Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_RECEIVE);
+ Snp->Cdb.CPBaddr = (UINT64)(UINTN) Cpb;
+
+ Snp->Cdb.DBsize = (UINT16) 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->IfNum;
+ Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
+
+ //
+ // Issue UNDI command and check result.
+ //
+ DEBUG ((EFI_D_NET, "\nsnp->undi.receive () "));
+
+ (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
+
+ switch (Snp->Cdb.StatCode) {
+ case PXE_STATCODE_SUCCESS:
+ break;
+
+ case PXE_STATCODE_NO_DATA:
+ DEBUG (
+ (EFI_D_NET,
+ "\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;
+ }
+
+ *BufferSize = Db->FrameLen;
+
+ if (HeaderSize != NULL) {
+ *HeaderSize = Db->MediaHeaderLen;
+ }
+
+ if (SrcAddr != NULL) {
+ CopyMem (SrcAddr, &Db->SrcAddr, Snp->Mode.HwAddressSize);
+ }
+
+ if (DestAddr != NULL) {
+ CopyMem (DestAddr, &Db->DestAddr, Snp->Mode.HwAddressSize);
+ }
+
+ if (Protocol != NULL) {
+ //
+ // We need to do the byte swapping
+ //
+ *Protocol = (UINT16) PXE_SWAP_UINT16 (Db->Protocol);
+ }
+
+ //
+ // We have received a packet from network interface, which implies that the
+ // network cable should be present. While, some UNDI driver may not report
+ // correct media status during Snp->Initialize(). So, we need ensure
+ // MediaPresent in SNP mode data is set to correct value.
+ //
+ if (Snp->Mode.MediaPresentSupported && !Snp->Mode.MediaPresent) {
+ Snp->Mode.MediaPresent = TRUE;
+ }
+
+ return (*BufferSize <= BuffSize) ? EFI_SUCCESS : EFI_BUFFER_TOO_SMALL;
+}
+
+/**
+ Receives a packet from a network interface.
+
+ This function retrieves one packet from the receive queue of a network interface.
+ If there are no packets on the receive queue, then EFI_NOT_READY will be
+ returned. If there is a packet on the receive queue, and the size of the packet
+ is smaller than BufferSize, then the contents of the packet will be placed in
+ Buffer, and BufferSize will be updated with the actual size of the packet.
+ In addition, if SrcAddr, DestAddr, and Protocol are not NULL, then these values
+ will be extracted from the media header and returned. EFI_SUCCESS will be
+ returned if a packet was successfully received.
+ If BufferSize is smaller than the received packet, then the size of the receive
+ packet will be placed in BufferSize and EFI_BUFFER_TOO_SMALL will be returned.
+ If the driver has not been initialized, EFI_DEVICE_ERROR will be returned.
+
+ @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+ @param HeaderSize The size, in bytes, of the media header received on the network
+ interface. If this parameter is NULL, then the media header size
+ will not be returned.
+ @param BufferSize On entry, the size, in bytes, of Buffer. On exit, the size, in
+ bytes, of the packet that was received on the network interface.
+ @param Buffer A pointer to the data buffer to receive both the media
+ header and the data.
+ @param SrcAddr The source HW MAC address. If this parameter is NULL, the HW
+ MAC source address will not be extracted from the media header.
+ @param DestAddr The destination HW MAC address. If this parameter is NULL,
+ the HW MAC destination address will not be extracted from
+ the media header.
+ @param Protocol The media header type. If this parameter is NULL, then the
+ protocol will not be extracted from the media header. See
+ RFC 1700 section "Ether Types" for examples.
+
+ @retval EFI_SUCCESS The received data was stored in Buffer, and
+ BufferSize has been updated to the number of
+ bytes received.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_NOT_READY No packets have been received on the network interface.
+ @retval EFI_BUFFER_TOO_SMALL BufferSize is too small for the received packets.
+ BufferSize has been updated to the required size.
+ @retval EFI_INVALID_PARAMETER One or more of the following conditions is TRUE:
+ * The This parameter is NULL
+ * The This parameter does not point to a valid
+ EFI_SIMPLE_NETWORK_PROTOCOL structure.
+ * The BufferSize parameter is NULL
+ * The Buffer parameter is NULL
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpUndi32Receive (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ OUT UINTN *HeaderSize OPTIONAL,
+ IN OUT UINTN *BufferSize,
+ OUT VOID *Buffer,
+ OUT EFI_MAC_ADDRESS *SrcAddr OPTIONAL,
+ OUT EFI_MAC_ADDRESS *DestAddr OPTIONAL,
+ OUT UINT16 *Protocol OPTIONAL
+ )
+{
+ SNP_DRIVER *Snp;
+ EFI_TPL OldTpl;
+ EFI_STATUS Status;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ switch (Snp->Mode.State) {
+ case EfiSimpleNetworkInitialized:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ Status = EFI_NOT_STARTED;
+ goto ON_EXIT;
+
+ default:
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ if ((BufferSize == NULL) || (Buffer == NULL)) {
+ Status = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ if (Snp->Mode.ReceiveFilterSetting == 0) {
+ Status = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ Status = PxeReceive (
+ Snp,
+ Buffer,
+ BufferSize,
+ HeaderSize,
+ SrcAddr,
+ DestAddr,
+ Protocol
+ );
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return Status;
+}