]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/SnpDxe/Initialize.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / SnpDxe / Initialize.c
CommitLineData
c74593cd 1/** @file\r
d1102dba 2 Implementation of initializing a network adapter.\r
4cda7726 3\r
d1102dba 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
9d510e61 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
c74593cd 6\r
c74593cd 7**/\r
8\r
c74593cd 9#include "Snp.h"\r
10\r
c74593cd 11/**\r
f3816027 12 Call UNDI to initialize the interface.\r
c74593cd 13\r
f3816027 14 @param Snp Pointer to snp driver structure.\r
d1102dba 15 @param CableDetectFlag Do/don't detect the cable (depending on what\r
f3816027 16 undi supports).\r
d1102dba 17\r
f3816027 18 @retval EFI_SUCCESS UNDI is initialized successfully.\r
19 @retval EFI_DEVICE_ERROR UNDI could not be initialized.\r
20 @retval Other Other errors as indicated.\r
c74593cd 21\r
22**/\r
23EFI_STATUS\r
4cda7726 24PxeInit (\r
d1050b9d
MK
25 SNP_DRIVER *Snp,\r
26 UINT16 CableDetectFlag\r
c74593cd 27 )\r
28{\r
4cda7726 29 PXE_CPB_INITIALIZE *Cpb;\r
30 VOID *Addr;\r
c74593cd 31 EFI_STATUS Status;\r
32\r
43b9d23d
JW
33 Status = EFI_SUCCESS;\r
34\r
4cda7726 35 Cpb = Snp->Cpb;\r
36 if (Snp->TxRxBufferSize != 0) {\r
37 Status = Snp->PciIo->AllocateBuffer (\r
38 Snp->PciIo,\r
39 AllocateAnyPages,\r
40 EfiBootServicesData,\r
41 SNP_MEM_PAGES (Snp->TxRxBufferSize),\r
42 &Addr,\r
43 0\r
44 );\r
c74593cd 45\r
46 if (Status != EFI_SUCCESS) {\r
47 DEBUG (\r
c49ca4a2 48 (DEBUG_ERROR,\r
d1050b9d
MK
49 "\nSnp->PxeInit() AllocateBuffer %xh (%r)\n",\r
50 Status,\r
51 Status)\r
c74593cd 52 );\r
53\r
54 return Status;\r
55 }\r
56\r
4cda7726 57 ASSERT (Addr);\r
c74593cd 58\r
4cda7726 59 Snp->TxRxBuffer = Addr;\r
c74593cd 60 }\r
61\r
d1050b9d 62 Cpb->MemoryAddr = (UINT64)(UINTN)Snp->TxRxBuffer;\r
c74593cd 63\r
4cda7726 64 Cpb->MemoryLength = Snp->TxRxBufferSize;\r
c74593cd 65\r
66 //\r
67 // let UNDI decide/detect these values\r
68 //\r
d1050b9d
MK
69 Cpb->LinkSpeed = 0;\r
70 Cpb->TxBufCnt = 0;\r
71 Cpb->TxBufSize = 0;\r
72 Cpb->RxBufCnt = 0;\r
73 Cpb->RxBufSize = 0;\r
c74593cd 74\r
d1050b9d 75 Cpb->DuplexMode = PXE_DUPLEX_DEFAULT;\r
c74593cd 76\r
d1050b9d 77 Cpb->LoopBackMode = LOOPBACK_NORMAL;\r
c74593cd 78\r
d1050b9d
MK
79 Snp->Cdb.OpCode = PXE_OPCODE_INITIALIZE;\r
80 Snp->Cdb.OpFlags = CableDetectFlag;\r
c74593cd 81\r
d1050b9d
MK
82 Snp->Cdb.CPBsize = (UINT16)sizeof (PXE_CPB_INITIALIZE);\r
83 Snp->Cdb.DBsize = (UINT16)sizeof (PXE_DB_INITIALIZE);\r
c74593cd 84\r
d1050b9d
MK
85 Snp->Cdb.CPBaddr = (UINT64)(UINTN)Snp->Cpb;\r
86 Snp->Cdb.DBaddr = (UINT64)(UINTN)Snp->Db;\r
c74593cd 87\r
d1050b9d
MK
88 Snp->Cdb.StatCode = PXE_STATCODE_INITIALIZE;\r
89 Snp->Cdb.StatFlags = PXE_STATFLAGS_INITIALIZE;\r
90 Snp->Cdb.IFnum = Snp->IfNum;\r
91 Snp->Cdb.Control = PXE_CONTROL_LAST_CDB_IN_LIST;\r
c74593cd 92\r
c49ca4a2 93 DEBUG ((DEBUG_NET, "\nSnp->undi.initialize() "));\r
c74593cd 94\r
d1050b9d 95 (*Snp->IssueUndi32Command)((UINT64)(UINTN)&Snp->Cdb);\r
c74593cd 96\r
43b9d23d
JW
97 //\r
98 // There are two fields need to be checked here:\r
d1102dba 99 // First is the upper two bits (14 & 15) in the CDB.StatFlags field. Until these bits change to report\r
43b9d23d 100 // PXE_STATFLAGS_COMMAND_COMPLETE or PXE_STATFLAGS_COMMAND_FAILED, the command has not been executed by the UNDI.\r
d1102dba 101 // Second is the CDB.StatCode field. After command execution completes, either successfully or not,\r
43b9d23d
JW
102 // the CDB.StatCode field contains the result of the command execution.\r
103 //\r
104 if ((((Snp->Cdb.StatFlags) & PXE_STATFLAGS_STATUS_MASK) == PXE_STATFLAGS_COMMAND_COMPLETE) &&\r
d1050b9d
MK
105 (Snp->Cdb.StatCode == PXE_STATCODE_SUCCESS))\r
106 {\r
43b9d23d 107 //\r
d1102dba
LG
108 // If cable detect feature is enabled in CDB.OpFlags, check the CDB.StatFlags to see if there is an\r
109 // active connection to this network device. If the no media StatFlag is set, the UNDI and network\r
110 // device are still initialized.\r
43b9d23d
JW
111 //\r
112 if (CableDetectFlag == PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) {\r
d1050b9d 113 if (((Snp->Cdb.StatFlags) & PXE_STATFLAGS_INITIALIZED_NO_MEDIA) != PXE_STATFLAGS_INITIALIZED_NO_MEDIA) {\r
43b9d23d
JW
114 Snp->Mode.MediaPresent = TRUE;\r
115 } else {\r
116 Snp->Mode.MediaPresent = FALSE;\r
117 }\r
118 }\r
d1102dba 119\r
d1050b9d
MK
120 Snp->Mode.State = EfiSimpleNetworkInitialized;\r
121 Status = EFI_SUCCESS;\r
c74593cd 122 } else {\r
123 DEBUG (\r
c49ca4a2 124 (DEBUG_WARN,\r
d1050b9d
MK
125 "\nSnp->undi.initialize() %xh:%xh\n",\r
126 Snp->Cdb.StatFlags,\r
127 Snp->Cdb.StatCode)\r
c74593cd 128 );\r
129\r
4cda7726 130 if (Snp->TxRxBuffer != NULL) {\r
131 Snp->PciIo->FreeBuffer (\r
132 Snp->PciIo,\r
133 SNP_MEM_PAGES (Snp->TxRxBufferSize),\r
d1050b9d 134 (VOID *)Snp->TxRxBuffer\r
c74593cd 135 );\r
136 }\r
137\r
4cda7726 138 Snp->TxRxBuffer = NULL;\r
c74593cd 139\r
d1050b9d 140 Status = EFI_DEVICE_ERROR;\r
c74593cd 141 }\r
142\r
143 return Status;\r
144}\r
145\r
c74593cd 146/**\r
d1102dba
LG
147 Resets a network adapter and allocates the transmit and receive buffers\r
148 required by the network interface; optionally, also requests allocation of\r
4cda7726 149 additional transmit and receive buffers.\r
150\r
151 This function allocates the transmit and receive buffers required by the network\r
152 interface. If this allocation fails, then EFI_OUT_OF_RESOURCES is returned.\r
153 If the allocation succeeds and the network interface is successfully initialized,\r
154 then EFI_SUCCESS will be returned.\r
155\r
156 @param This A pointer to the EFI_SIMPLE_NETWORK_PROTOCOL instance.\r
157\r
158 @param ExtraRxBufferSize The size, in bytes, of the extra receive buffer space\r
159 that the driver should allocate for the network interface.\r
d1102dba
LG
160 Some network interfaces will not be able to use the\r
161 extra buffer, and the caller will not know if it is\r
4cda7726 162 actually being used.\r
163 @param ExtraTxBufferSize The size, in bytes, of the extra transmit buffer space\r
164 that the driver should allocate for the network interface.\r
165 Some network interfaces will not be able to use the\r
166 extra buffer, and the caller will not know if it is\r
167 actually being used.\r
168\r
169 @retval EFI_SUCCESS The network interface was initialized.\r
170 @retval EFI_NOT_STARTED The network interface has not been started.\r
171 @retval EFI_OUT_OF_RESOURCES There was not enough memory for the transmit and\r
172 receive buffers.\r
173 @retval EFI_INVALID_PARAMETER This parameter was NULL or did not point to a valid\r
174 EFI_SIMPLE_NETWORK_PROTOCOL structure.\r
175 @retval EFI_DEVICE_ERROR The command could not be sent to the network interface.\r
176 @retval EFI_UNSUPPORTED The increased buffer size feature is not supported.\r
c74593cd 177\r
178**/\r
179EFI_STATUS\r
180EFIAPI\r
4cda7726 181SnpUndi32Initialize (\r
d1050b9d
MK
182 IN EFI_SIMPLE_NETWORK_PROTOCOL *This,\r
183 IN UINTN ExtraRxBufferSize OPTIONAL,\r
184 IN UINTN ExtraTxBufferSize OPTIONAL\r
c74593cd 185 )\r
186{\r
187 EFI_STATUS EfiStatus;\r
4cda7726 188 SNP_DRIVER *Snp;\r
c74593cd 189 EFI_TPL OldTpl;\r
190\r
4cda7726 191 if (This == NULL) {\r
c74593cd 192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
4cda7726 195 Snp = EFI_SIMPLE_NETWORK_DEV_FROM_THIS (This);\r
c74593cd 196\r
197 OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
198\r
4cda7726 199 if (Snp == NULL) {\r
c74593cd 200 EfiStatus = EFI_INVALID_PARAMETER;\r
201 goto ON_EXIT;\r
202 }\r
203\r
4cda7726 204 switch (Snp->Mode.State) {\r
d1050b9d
MK
205 case EfiSimpleNetworkStarted:\r
206 break;\r
c74593cd 207\r
d1050b9d
MK
208 case EfiSimpleNetworkStopped:\r
209 EfiStatus = EFI_NOT_STARTED;\r
210 goto ON_EXIT;\r
c74593cd 211\r
d1050b9d
MK
212 default:\r
213 EfiStatus = EFI_DEVICE_ERROR;\r
214 goto ON_EXIT;\r
c74593cd 215 }\r
216\r
217 EfiStatus = gBS->CreateEvent (\r
d1050b9d
MK
218 EVT_NOTIFY_WAIT,\r
219 TPL_NOTIFY,\r
220 &SnpWaitForPacketNotify,\r
221 Snp,\r
222 &Snp->Snp.WaitForPacket\r
223 );\r
c74593cd 224\r
225 if (EFI_ERROR (EfiStatus)) {\r
4cda7726 226 Snp->Snp.WaitForPacket = NULL;\r
d1050b9d 227 EfiStatus = EFI_DEVICE_ERROR;\r
c74593cd 228 goto ON_EXIT;\r
229 }\r
d1050b9d 230\r
c74593cd 231 //\r
232 //\r
233 //\r
d1050b9d
MK
234 Snp->Mode.MCastFilterCount = 0;\r
235 Snp->Mode.ReceiveFilterSetting = 0;\r
4cda7726 236 ZeroMem (Snp->Mode.MCastFilter, sizeof Snp->Mode.MCastFilter);\r
c74593cd 237 CopyMem (\r
4cda7726 238 &Snp->Mode.CurrentAddress,\r
239 &Snp->Mode.PermanentAddress,\r
c74593cd 240 sizeof (EFI_MAC_ADDRESS)\r
241 );\r
242\r
243 //\r
244 // Compute tx/rx buffer sizes based on UNDI init info and parameters.\r
245 //\r
d1050b9d 246 Snp->TxRxBufferSize = (UINT32)(Snp->InitInfo.MemoryRequired + ExtraRxBufferSize + ExtraTxBufferSize);\r
c74593cd 247\r
128946c9
FS
248 //\r
249 // If UNDI support cable detect for INITIALIZE command, try it first.\r
250 //\r
251 if (Snp->CableDetectSupported) {\r
4cda7726 252 if (PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DETECT_CABLE) == EFI_SUCCESS) {\r
c74593cd 253 goto ON_EXIT;\r
254 }\r
255 }\r
256\r
d1050b9d 257 Snp->Mode.MediaPresent = FALSE;\r
c74593cd 258\r
d1050b9d 259 EfiStatus = PxeInit (Snp, PXE_OPFLAGS_INITIALIZE_DO_NOT_DETECT_CABLE);\r
c74593cd 260\r
261 if (EFI_ERROR (EfiStatus)) {\r
4cda7726 262 gBS->CloseEvent (Snp->Snp.WaitForPacket);\r
128946c9
FS
263 goto ON_EXIT;\r
264 }\r
265\r
266 //\r
267 // Try to update the MediaPresent field of EFI_SIMPLE_NETWORK_MODE if the UNDI support it.\r
268 //\r
269 if (Snp->MediaStatusSupported) {\r
270 PxeGetStatus (Snp, NULL, FALSE);\r
c74593cd 271 }\r
272\r
273ON_EXIT:\r
274 gBS->RestoreTPL (OldTpl);\r
275\r
276 return EfiStatus;\r
277}\r