/** @file\r
- Implementation of initializing a network adapter.\r
+ Implementation of initializing a network adapter.\r
\r
-Copyright (c) 2004 - 2008, Intel Corporation. <BR> \r
-All rights reserved. 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
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
Call UNDI to initialize the interface.\r
\r
@param Snp Pointer to snp driver structure.\r
- @param CableDetectFlag Do/don't detect the cable (depending on what \r
+ @param CableDetectFlag Do/don't detect the cable (depending on what\r
undi supports).\r
- \r
+\r
@retval EFI_SUCCESS UNDI is initialized successfully.\r
@retval EFI_DEVICE_ERROR UNDI could not be initialized.\r
@retval Other Other errors as indicated.\r
VOID *Addr;\r
EFI_STATUS Status;\r
\r
+ Status = EFI_SUCCESS;\r
+\r
Cpb = Snp->Cpb;\r
if (Snp->TxRxBufferSize != 0) {\r
Status = Snp->PciIo->AllocateBuffer (\r
Snp->Cdb.OpCode = PXE_OPCODE_INITIALIZE;\r
Snp->Cdb.OpFlags = CableDetectFlag;\r
\r
- Snp->Cdb.CPBsize = sizeof (PXE_CPB_INITIALIZE);\r
- Snp->Cdb.DBsize = sizeof (PXE_DB_INITIALIZE);\r
+ Snp->Cdb.CPBsize = (UINT16) sizeof (PXE_CPB_INITIALIZE);\r
+ Snp->Cdb.DBsize = (UINT16) sizeof (PXE_DB_INITIALIZE);\r
\r
Snp->Cdb.CPBaddr = (UINT64)(UINTN) Snp->Cpb;\r
Snp->Cdb.DBaddr = (UINT64)(UINTN) Snp->Db;\r
Snp->Cdb.IFnum = Snp->IfNum;\r
Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
\r
- DEBUG ((EFI_D_INFO | EFI_D_NET, "\nSnp->undi.initialize() "));\r
+ DEBUG ((EFI_D_NET, "\nSnp->undi.initialize() "));\r
\r
(*Snp->IssueUndi32Command) ((UINT64)(UINTN) &Snp->Cdb);\r
\r
- if (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS) {\r
- Snp->Mode.State = EfiSimpleNetworkInitialized;\r
+ //\r
+ // There are two fields need to be checked here:\r
+ // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report\r
+ // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.\r
+ // Second is the CDB.StatCode field. After command execution completes, either successfully or not,\r
+ // the CDB.StatCode field contains the result of the command execution.\r
+ //\r
+ if ((((Snp->Cdb.StatFlags) & PXE_STATFLAGS_STATUS_MASK) == PXE_STATFLAGS_COMMAND_COMPLETE) &&\r
+ (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS)) {\r
+ //\r
+ // If cable detect feature is enabled in CDB.OpFlags, check the CDB.StatFlags to see if there is an\r
+ // active connection to this network device. If the no media StatFlag is set, the UNDI and network\r
+ // device are still initialized.\r
+ //\r
+ if (CableDetectFlag == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {\r
+ if(((Snp->Cdb.StatFlags) & PXE_STATFLAGS_INITIALIZED_NO_MEDIA) != PXE_STATFLAGS_INITIALIZED_NO_MEDIA) {\r
+ Snp->Mode.MediaPresent = TRUE;\r
+ } else {\r
+ Snp->Mode.MediaPresent = FALSE;\r
+ }\r
+ }\r
\r
- Status = EFI_SUCCESS;\r
+ Snp->Mode.State = EfiSimpleNetworkInitialized;\r
+ Status = EFI_SUCCESS;\r
} else {\r
DEBUG (\r
- (EFI_D_ERROR,\r
+ (EFI_D_WARN,\r
"\nSnp->undi.initialize() %xh:%xh\n",\r
Snp->Cdb.StatFlags,\r
Snp->Cdb.StatCode)\r
\r
\r
/**\r
- Resets a network adapter and allocates the transmit and receive buffers \r
- required by the network interface; optionally, also requests allocation of \r
+ Resets a network adapter and allocates the transmit and receive buffers\r
+ required by the network interface; optionally, also requests allocation of\r
additional transmit and receive buffers.\r
\r
This function allocates the transmit and receive buffers required by the network\r
\r
@param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r
that the driver should allocate for the network interface.\r
- Some network interfaces will not be able to use the \r
- extra buffer, and the caller will not know if it is \r
+ Some network interfaces will not be able to use the\r
+ extra buffer, and the caller will not know if it is\r
actually being used.\r
@param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r
that the driver should allocate for the network interface.\r
//\r
Snp->TxRxBufferSize = (UINT32) (Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);\r
\r
- if (Snp->Mode.MediaPresentSupported) {\r
+ //\r
+ // If UNDI support cable detect for INITIALIZE command, try it first.\r
+ //\r
+ if (Snp->CableDetectSupported) {\r
if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {\r
- Snp->Mode.MediaPresent = TRUE;\r
goto ON_EXIT;\r
}\r
}\r
\r
if (EFI_ERROR (EfiStatus)) {\r
gBS->CloseEvent (Snp->Snp.WaitForPacket);\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ //\r
+ // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.\r
+ //\r
+ if (Snp->MediaStatusSupported) {\r
+ PxeGetStatus (Snp, NULL, FALSE);\r
}\r
\r
ON_EXIT:\r