summaryrefslogtreecommitdiffstats
path: root/NetworkPkg/SnpDxe/Initialize.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/Initialize.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/Initialize.c')
-rw-r--r--NetworkPkg/SnpDxe/Initialize.c277
1 files changed, 277 insertions, 0 deletions
diff --git a/NetworkPkg/SnpDxe/Initialize.c b/NetworkPkg/SnpDxe/Initialize.c
new file mode 100644
index 0000000000..4d33154241
--- /dev/null
+++ b/NetworkPkg/SnpDxe/Initialize.c
@@ -0,0 +1,277 @@
+/** @file
+ Implementation of initializing a network adapter.
+
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
+SPDX-License-Identifier: BSD-2-Clause-Patent
+
+**/
+
+
+#include "Snp.h"
+
+/**
+ Call UNDI to initialize the interface.
+
+ @param Snp Pointer to snp driver structure.
+ @param CableDetectFlag Do/don't detect the cable (depending on what
+ undi supports).
+
+ @retval EFI_SUCCESS UNDI is initialized successfully.
+ @retval EFI_DEVICE_ERROR UNDI could not be initialized.
+ @retval Other Other errors as indicated.
+
+**/
+EFI_STATUS
+PxeInit (
+ SNP_DRIVER *Snp,
+ UINT16 CableDetectFlag
+ )
+{
+ PXE_CPB_INITIALIZE *Cpb;
+ VOID *Addr;
+ EFI_STATUS Status;
+
+ Status = EFI_SUCCESS;
+
+ Cpb = Snp->Cpb;
+ if (Snp->TxRxBufferSize != 0) {
+ Status = Snp->PciIo->AllocateBuffer (
+ Snp->PciIo,
+ AllocateAnyPages,
+ EfiBootServicesData,
+ SNP_MEM_PAGES (Snp->TxRxBufferSize),
+ &Addr,
+ 0
+ );
+
+ if (Status != EFI_SUCCESS) {
+ DEBUG (
+ (EFI_D_ERROR,
+ "\nSnp->PxeInit() AllocateBuffer %xh (%r)\n",
+ Status,
+ Status)
+ );
+
+ return Status;
+ }
+
+ ASSERT (Addr);
+
+ Snp->TxRxBuffer = Addr;
+ }
+
+ Cpb->MemoryAddr = (UINT64)(UINTN) Snp->TxRxBuffer;
+
+ Cpb->MemoryLength = Snp->TxRxBufferSize;
+
+ //
+ // 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 = (UINT16) sizeof (PXE_CPB_INITIALIZE);
+ Snp->Cdb.DBsize = (UINT16) 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->IfNum;
+ Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
+
+ DEBUG ((EFI_D_NET, "\nSnp->undi.initialize() "));
+
+ (*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);
+
+ //
+ // There are two fields need to be checked here:
+ // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report
+ // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.
+ // Second is the CDB.StatCode field. After command execution completes, either successfully or not,
+ // the CDB.StatCode field contains the result of the command execution.
+ //
+ if ((((Snp->Cdb.StatFlags) & PXE_STATFLAGS_STATUS_MASK) == PXE_STATFLAGS_COMMAND_COMPLETE) &&
+ (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS)) {
+ //
+ // If cable detect feature is enabled in CDB.OpFlags, check the CDB.StatFlags to see if there is an
+ // active connection to this network device. If the no media StatFlag is set, the UNDI and network
+ // device are still initialized.
+ //
+ if (CableDetectFlag == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {
+ if(((Snp->Cdb.StatFlags) & PXE_STATFLAGS_INITIALIZED_NO_MEDIA) != PXE_STATFLAGS_INITIALIZED_NO_MEDIA) {
+ Snp->Mode.MediaPresent = TRUE;
+ } else {
+ Snp->Mode.MediaPresent = FALSE;
+ }
+ }
+
+ 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->TxRxBuffer != NULL) {
+ Snp->PciIo->FreeBuffer (
+ Snp->PciIo,
+ SNP_MEM_PAGES (Snp->TxRxBufferSize),
+ (VOID *) Snp->TxRxBuffer
+ );
+ }
+
+ Snp->TxRxBuffer = NULL;
+
+ Status = EFI_DEVICE_ERROR;
+ }
+
+ return Status;
+}
+
+
+/**
+ Resets a network adapter and allocates the transmit and receive buffers
+ required by the network interface; optionally, also requests allocation of
+ additional transmit and receive buffers.
+
+ This function allocates the transmit and receive buffers required by the network
+ interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.
+ If the allocation succeeds and the network interface is successfully initialized,
+ then EFI_SUCCESS will be returned.
+
+ @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
+
+ @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the
+ extra buffer, and the caller will not know if it is
+ actually being used.
+ @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
+ that the driver should allocate for the network interface.
+ Some network interfaces will not be able to use the
+ extra buffer, and the caller will not know if it is
+ actually being used.
+
+ @retval EFI_SUCCESS The network interface was initialized.
+ @retval EFI_NOT_STARTED The network interface has not been started.
+ @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
+ receive buffers.
+ @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid
+ EFI_SIMPLE_NETWORK_PROTOCOL structure.
+ @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
+ @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
+
+**/
+EFI_STATUS
+EFIAPI
+SnpUndi32Initialize (
+ IN EFI_SIMPLE_NETWORK_PROTOCOL *This,
+ IN UINTN ExtraRxBufferSize OPTIONAL,
+ IN UINTN ExtraTxBufferSize OPTIONAL
+ )
+{
+ EFI_STATUS EfiStatus;
+ SNP_DRIVER *Snp;
+ EFI_TPL OldTpl;
+
+ if (This == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
+
+ OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
+
+ if (Snp == NULL) {
+ EfiStatus = EFI_INVALID_PARAMETER;
+ goto ON_EXIT;
+ }
+
+ switch (Snp->Mode.State) {
+ case EfiSimpleNetworkStarted:
+ break;
+
+ case EfiSimpleNetworkStopped:
+ EfiStatus = EFI_NOT_STARTED;
+ goto ON_EXIT;
+
+ default:
+ EfiStatus = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+
+ EfiStatus = gBS->CreateEvent (
+ EVT_NOTIFY_WAIT,
+ TPL_NOTIFY,
+ &SnpWaitForPacketNotify,
+ Snp,
+ &Snp->Snp.WaitForPacket
+ );
+
+ if (EFI_ERROR (EfiStatus)) {
+ Snp->Snp.WaitForPacket = NULL;
+ EfiStatus = EFI_DEVICE_ERROR;
+ goto ON_EXIT;
+ }
+ //
+ //
+ //
+ 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->TxRxBufferSize = (UINT32) (Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);
+
+ //
+ // If UNDI support cable detect for INITIALIZE command, try it first.
+ //
+ if (Snp->CableDetectSupported) {
+ if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
+ goto ON_EXIT;
+ }
+ }
+
+ Snp->Mode.MediaPresent = FALSE;
+
+ EfiStatus = PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
+
+ if (EFI_ERROR (EfiStatus)) {
+ gBS->CloseEvent (Snp->Snp.WaitForPacket);
+ goto ON_EXIT;
+ }
+
+ //
+ // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.
+ //
+ if (Snp->MediaStatusSupported) {
+ PxeGetStatus (Snp, NULL, FALSE);
+ }
+
+ON_EXIT:
+ gBS->RestoreTPL (OldTpl);
+
+ return EfiStatus;
+}