TianoCore EDK2 master
Loading...
Searching...
No Matches
Initialize.c
Go to the documentation of this file.
1
9#include "Snp.h"
10
25 SNP_DRIVER *Snp,
26 UINT16 CableDetectFlag
27 )
28{
30 VOID *Addr;
31 EFI_STATUS Status;
32
33 Status = EFI_SUCCESS;
34
35 Cpb = Snp->Cpb;
36 if (Snp->TxRxBufferSize != 0) {
37 Status = Snp->PciIo->AllocateBuffer (
38 Snp->PciIo,
41 SNP_MEM_PAGES (Snp->TxRxBufferSize),
42 &Addr,
43 0
44 );
45
46 if (Status != EFI_SUCCESS) {
47 DEBUG (
48 (DEBUG_ERROR,
49 "\nSnp->PxeInit() AllocateBuffer %xh (%r)\n",
50 Status,
51 Status)
52 );
53
54 return Status;
55 }
56
57 ASSERT (Addr);
58
59 Snp->TxRxBuffer = Addr;
60 }
61
62 Cpb->MemoryAddr = (UINT64)(UINTN)Snp->TxRxBuffer;
63
64 Cpb->MemoryLength = Snp->TxRxBufferSize;
65
66 //
67 // let UNDI decide/detect these values
68 //
69 Cpb->LinkSpeed = 0;
70 Cpb->TxBufCnt = 0;
71 Cpb->TxBufSize = 0;
72 Cpb->RxBufCnt = 0;
73 Cpb->RxBufSize = 0;
74
75 Cpb->DuplexMode = PXE_DUPLEX_DEFAULT;
76
77 Cpb->LoopBackMode = LOOPBACK_NORMAL;
78
79 Snp->Cdb.OpCode = PXE_OPCODE_INITIALIZE;
80 Snp->Cdb.OpFlags = CableDetectFlag;
81
82 Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_INITIALIZE);
83 Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_INITIALIZE);
84
85 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Snp->Cpb;
86 Snp->Cdb.DBaddr = (UINT64)(UINTN)Snp->Db;
87
88 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;
89 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;
90 Snp->Cdb.IFnum = Snp->IfNum;
91 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;
92
93 DEBUG ((DEBUG_NET, "\nSnp->undi.initialize() "));
94
95 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);
96
97 //
98 // There are two fields need to be checked here:
99 // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report
100 // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.
101 // Second is the CDB.StatCode field. After command execution completes, either successfully or not,
102 // the CDB.StatCode field contains the result of the command execution.
103 //
104 if ((((Snp->Cdb.StatFlags) & PXE_STATFLAGS_STATUS_MASK) == PXE_STATFLAGS_COMMAND_COMPLETE) &&
105 (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS))
106 {
107 //
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.
111 //
112 if (CableDetectFlag == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {
114 Snp->Mode.MediaPresent = TRUE;
115 } else {
116 Snp->Mode.MediaPresent = FALSE;
117 }
118 }
119
120 Snp->Mode.State = EfiSimpleNetworkInitialized;
121 Status = EFI_SUCCESS;
122 } else {
123 DEBUG (
124 (DEBUG_WARN,
125 "\nSnp->undi.initialize() %xh:%xh\n",
126 Snp->Cdb.StatFlags,
127 Snp->Cdb.StatCode)
128 );
129
130 if (Snp->TxRxBuffer != NULL) {
131 Snp->PciIo->FreeBuffer (
132 Snp->PciIo,
133 SNP_MEM_PAGES (Snp->TxRxBufferSize),
134 (VOID *)Snp->TxRxBuffer
135 );
136 }
137
138 Snp->TxRxBuffer = NULL;
139
140 Status = EFI_DEVICE_ERROR;
141 }
142
143 return Status;
144}
145
180EFIAPI
183 IN UINTN ExtraRxBufferSize OPTIONAL,
184 IN UINTN ExtraTxBufferSize OPTIONAL
185 )
186{
187 EFI_STATUS EfiStatus;
188 SNP_DRIVER *Snp;
189 EFI_TPL OldTpl;
190
191 if (This == NULL) {
192 return EFI_INVALID_PARAMETER;
193 }
194
195 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);
196
197 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);
198
199 if (Snp == NULL) {
200 EfiStatus = EFI_INVALID_PARAMETER;
201 goto ON_EXIT;
202 }
203
204 switch (Snp->Mode.State) {
205 case EfiSimpleNetworkStarted:
206 break;
207
208 case EfiSimpleNetworkStopped:
209 EfiStatus = EFI_NOT_STARTED;
210 goto ON_EXIT;
211
212 default:
213 EfiStatus = EFI_DEVICE_ERROR;
214 goto ON_EXIT;
215 }
216
217 EfiStatus = gBS->CreateEvent (
218 EVT_NOTIFY_WAIT,
219 TPL_NOTIFY,
221 Snp,
222 &Snp->Snp.WaitForPacket
223 );
224
225 if (EFI_ERROR (EfiStatus)) {
226 Snp->Snp.WaitForPacket = NULL;
227 EfiStatus = EFI_DEVICE_ERROR;
228 goto ON_EXIT;
229 }
230
231 //
232 //
233 //
234 Snp->Mode.MCastFilterCount = 0;
235 Snp->Mode.ReceiveFilterSetting = 0;
236 ZeroMem (Snp->Mode.MCastFilter, sizeof Snp->Mode.MCastFilter);
237 CopyMem (
238 &Snp->Mode.CurrentAddress,
239 &Snp->Mode.PermanentAddress,
240 sizeof (EFI_MAC_ADDRESS)
241 );
242
243 //
244 // Compute tx/rx buffer sizes based on UNDI init info and parameters.
245 //
246 Snp->TxRxBufferSize = (UINT32)(Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);
247
248 //
249 // If UNDI support cable detect for INITIALIZE command, try it first.
250 //
251 if (Snp->CableDetectSupported) {
252 if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {
253 goto ON_EXIT;
254 }
255 }
256
257 Snp->Mode.MediaPresent = FALSE;
258
259 EfiStatus = PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);
260
261 if (EFI_ERROR (EfiStatus)) {
262 gBS->CloseEvent (Snp->Snp.WaitForPacket);
263 goto ON_EXIT;
264 }
265
266 //
267 // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.
268 //
269 if (Snp->MediaStatusSupported) {
270 PxeGetStatus (Snp, NULL, FALSE);
271 }
272
273ON_EXIT:
274 gBS->RestoreTPL (OldTpl);
275
276 return EfiStatus;
277}
UINT64 UINTN
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
VOID *EFIAPI ZeroMem(OUT VOID *Buffer, IN UINTN Length)
EFI_STATUS PxeGetStatus(IN SNP_DRIVER *Snp, OUT UINT32 *InterruptStatusPtr, IN BOOLEAN GetTransmittedBuf)
Definition: Get_status.c:30
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define DEBUG(Expression)
Definition: DebugLib.h:434
EFI_STATUS PxeInit(SNP_DRIVER *Snp, UINT16 CableDetectFlag)
Definition: Initialize.c:24
EFI_STATUS EFIAPI SnpUndi32Initialize(IN EFI_SIMPLE_NETWORK_PROTOCOL *This, IN UINTN ExtraRxBufferSize OPTIONAL, IN UINTN ExtraTxBufferSize OPTIONAL)
Definition: Initialize.c:181
VOID EFIAPI SnpWaitForPacketNotify(EFI_EVENT Event, VOID *SnpPtr)
Definition: WaitForPacket.c:20
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
UINTN EFI_TPL
Definition: UefiBaseType.h:41
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
@ EfiBootServicesData
#define PXE_STATFLAGS_STATUS_MASK
Definition: UefiPxe.h:413
#define PXE_OPCODE_INITIALIZE
Definition: UefiPxe.h:110
#define PXE_STATFLAGS_INITIALIZED_NO_MEDIA
Definition: UefiPxe.h:446
#define PXE_STATCODE_SUCCESS
Definition: UefiPxe.h:602
@ AllocateAnyPages
Definition: UefiSpec.h:33
EFI_MAC_ADDRESS CurrentAddress
EFI_MAC_ADDRESS MCastFilter[MAX_MCAST_FILTER_CNT]
EFI_MAC_ADDRESS PermanentAddress
Definition: Snp.h:55
PXE_UINT32 MemoryLength
Definition: UefiPxe.h:1252
PXE_UINT64 MemoryAddr
Definition: UefiPxe.h:1246
PXE_UINT16 TxBufCnt
Definition: UefiPxe.h:1271
PXE_UINT8 DuplexMode
Definition: UefiPxe.h:1280
PXE_UINT32 LinkSpeed
Definition: UefiPxe.h:1259
PXE_UINT32 MemoryRequired
Definition: UefiPxe.h:1100