2 Implementation of initializing a network adapter.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
13 Call UNDI to initialize the interface.
15 @param Snp Pointer to snp driver structure.
16 @param CableDetectFlag Do/don't detect the cable (depending on what
19 @retval EFI_SUCCESS UNDI is initialized successfully.
20 @retval EFI_DEVICE_ERROR UNDI could not be initialized.
21 @retval Other Other errors as indicated.
27 UINT16 CableDetectFlag
30 PXE_CPB_INITIALIZE
*Cpb
;
37 if (Snp
->TxRxBufferSize
!= 0) {
38 Status
= Snp
->PciIo
->AllocateBuffer (
42 SNP_MEM_PAGES (Snp
->TxRxBufferSize
),
47 if (Status
!= EFI_SUCCESS
) {
50 "\nSnp->PxeInit() AllocateBuffer %xh (%r)\n",
60 Snp
->TxRxBuffer
= Addr
;
63 Cpb
->MemoryAddr
= (UINT64
)(UINTN
) Snp
->TxRxBuffer
;
65 Cpb
->MemoryLength
= Snp
->TxRxBufferSize
;
68 // let UNDI decide/detect these values
76 Cpb
->DuplexMode
= PXE_DUPLEX_DEFAULT
;
78 Cpb
->LoopBackMode
= LOOPBACK_NORMAL
;
80 Snp
->Cdb
.OpCode
= PXE_OPCODE_INITIALIZE
;
81 Snp
->Cdb
.OpFlags
= CableDetectFlag
;
83 Snp
->Cdb
.CPBsize
= (UINT16
) sizeof (PXE_CPB_INITIALIZE
);
84 Snp
->Cdb
.DBsize
= (UINT16
) sizeof (PXE_DB_INITIALIZE
);
86 Snp
->Cdb
.CPBaddr
= (UINT64
)(UINTN
) Snp
->Cpb
;
87 Snp
->Cdb
.DBaddr
= (UINT64
)(UINTN
) Snp
->Db
;
89 Snp
->Cdb
.StatCode
= PXE_STATCODE_INITIALIZE
;
90 Snp
->Cdb
.StatFlags
= PXE_STATFLAGS_INITIALIZE
;
91 Snp
->Cdb
.IFnum
= Snp
->IfNum
;
92 Snp
->Cdb
.Control
= PXE_CONTROL_LAST_CDB_IN_LIST
;
94 DEBUG ((EFI_D_NET
, "\nSnp->undi.initialize() "));
96 (*Snp
->IssueUndi32Command
) ((UINT64
)(UINTN
) &Snp
->Cdb
);
99 // There are two fields need to be checked here:
100 // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report
101 // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.
102 // Second is the CDB.StatCode field. After command execution completes, either successfully or not,
103 // the CDB.StatCode field contains the result of the command execution.
105 if ((((Snp
->Cdb
.StatFlags
) & PXE_STATFLAGS_STATUS_MASK
) == PXE_STATFLAGS_COMMAND_COMPLETE
) &&
106 (Snp
->Cdb
.StatCode
== PXE_STATCODE_SUCCESS
)) {
108 // If cable detect feature is enabled in CDB.OpFlags, check the CDB.StatFlags to see if there is an
109 // active connection to this network device. If the no media StatFlag is set, the UNDI and network
110 // device are still initialized.
112 if (CableDetectFlag
== PXE_OPFLAGS_INITIALIZE_DETECT_CABLE
) {
113 if(((Snp
->Cdb
.StatFlags
) & PXE_STATFLAGS_INITIALIZED_NO_MEDIA
) != PXE_STATFLAGS_INITIALIZED_NO_MEDIA
) {
114 Snp
->Mode
.MediaPresent
= TRUE
;
116 Snp
->Mode
.MediaPresent
= FALSE
;
120 Snp
->Mode
.State
= EfiSimpleNetworkInitialized
;
121 Status
= EFI_SUCCESS
;
125 "\nSnp->undi.initialize() %xh:%xh\n",
130 if (Snp
->TxRxBuffer
!= NULL
) {
131 Snp
->PciIo
->FreeBuffer (
133 SNP_MEM_PAGES (Snp
->TxRxBufferSize
),
134 (VOID
*) Snp
->TxRxBuffer
138 Snp
->TxRxBuffer
= NULL
;
140 Status
= EFI_DEVICE_ERROR
;
148 Resets a network adapter and allocates the transmit and receive buffers
149 required by the network interface; optionally, also requests allocation of
150 additional transmit and receive buffers.
152 This function allocates the transmit and receive buffers required by the network
153 interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.
154 If the allocation succeeds and the network interface is successfully initialized,
155 then EFI_SUCCESS will be returned.
157 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.
159 @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space
160 that the driver should allocate for the network interface.
161 Some network interfaces will not be able to use the
162 extra buffer, and the caller will not know if it is
164 @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space
165 that the driver should allocate for the network interface.
166 Some network interfaces will not be able to use the
167 extra buffer, and the caller will not know if it is
170 @retval EFI_SUCCESS The network interface was initialized.
171 @retval EFI_NOT_STARTED The network interface has not been started.
172 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and
174 @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid
175 EFI_SIMPLE_NETWORK_PROTOCOL structure.
176 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.
177 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.
182 SnpUndi32Initialize (
183 IN EFI_SIMPLE_NETWORK_PROTOCOL
*This
,
184 IN UINTN ExtraRxBufferSize OPTIONAL
,
185 IN UINTN ExtraTxBufferSize OPTIONAL
188 EFI_STATUS EfiStatus
;
193 return EFI_INVALID_PARAMETER
;
196 Snp
= EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This
);
198 OldTpl
= gBS
->RaiseTPL (TPL_CALLBACK
);
201 EfiStatus
= EFI_INVALID_PARAMETER
;
205 switch (Snp
->Mode
.State
) {
206 case EfiSimpleNetworkStarted
:
209 case EfiSimpleNetworkStopped
:
210 EfiStatus
= EFI_NOT_STARTED
;
214 EfiStatus
= EFI_DEVICE_ERROR
;
218 EfiStatus
= gBS
->CreateEvent (
221 &SnpWaitForPacketNotify
,
223 &Snp
->Snp
.WaitForPacket
226 if (EFI_ERROR (EfiStatus
)) {
227 Snp
->Snp
.WaitForPacket
= NULL
;
228 EfiStatus
= EFI_DEVICE_ERROR
;
234 Snp
->Mode
.MCastFilterCount
= 0;
235 Snp
->Mode
.ReceiveFilterSetting
= 0;
236 ZeroMem (Snp
->Mode
.MCastFilter
, sizeof Snp
->Mode
.MCastFilter
);
238 &Snp
->Mode
.CurrentAddress
,
239 &Snp
->Mode
.PermanentAddress
,
240 sizeof (EFI_MAC_ADDRESS
)
244 // Compute tx/rx buffer sizes based on UNDI init info and parameters.
246 Snp
->TxRxBufferSize
= (UINT32
) (Snp
->InitInfo
.MemoryRequired
+ ExtraRxBufferSize
+ ExtraTxBufferSize
);
249 // If UNDI support cable detect for INITIALIZE command, try it first.
251 if (Snp
->CableDetectSupported
) {
252 if (PxeInit (Snp
, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE
) == EFI_SUCCESS
) {
257 Snp
->Mode
.MediaPresent
= FALSE
;
259 EfiStatus
= PxeInit (Snp
, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE
);
261 if (EFI_ERROR (EfiStatus
)) {
262 gBS
->CloseEvent (Snp
->Snp
.WaitForPacket
);
267 // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.
269 if (Snp
->MediaStatusSupported
) {
270 PxeGetStatus (Snp
, NULL
, FALSE
);
274 gBS
->RestoreTPL (OldTpl
);