]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/UefiPxeBcDxe/PxeBcImpl.c
1. Import UEFI PxeBc module in MdeModulePkg
[mirror_edk2.git] / MdeModulePkg / Universal / Network / UefiPxeBcDxe / PxeBcImpl.c
CommitLineData
dc361cc5 1/** @file\r
2\r
3Copyright (c) 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 PxeBcImpl.c\r
15\r
16Abstract:\r
17\r
18 Interface routines for PxeBc\r
19\r
20\r
21**/\r
22\r
23\r
24#include "PxeBcImpl.h"\r
25\r
26\r
27/**\r
28 GC_NOTO: Add function description\r
29\r
30 @param This GC_NOTO: add argument\r
31 description\r
32 @param UseIpv6 GC_NOTO: add argument\r
33 description\r
34\r
35 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
36 return value\r
37 @retval EFI_ALREADY_STARTED GC_NOTO: Add description for\r
38 return value\r
39 @retval EFI_UNSUPPORTED GC_NOTO: Add description for\r
40 return value\r
41 @retval EFI_SUCCESS GC_NOTO: Add description for\r
42 return value\r
43\r
44**/\r
45EFI_STATUS\r
46EFIAPI\r
47EfiPxeBcStart (\r
48 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
49 IN BOOLEAN UseIpv6\r
50 )\r
51{\r
52 PXEBC_PRIVATE_DATA *Private;\r
53 EFI_PXE_BASE_CODE_MODE *Mode;\r
54 EFI_STATUS Status;\r
55\r
56 if (This == NULL) {\r
57 return EFI_INVALID_PARAMETER;\r
58 }\r
59\r
60 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
61 Mode = Private->PxeBc.Mode;\r
62\r
63 if (Mode->Started) {\r
64 return EFI_ALREADY_STARTED;\r
65 }\r
66\r
67 if (UseIpv6) {\r
68 //\r
69 // IPv6 is not supported now.\r
70 //\r
71 return EFI_UNSUPPORTED;\r
72 }\r
73\r
74 //\r
75 // Configure the udp4 instance to let it receive data\r
76 //\r
77 Status = Private->Udp4->Configure (Private->Udp4, &Private->Udp4CfgData);\r
78 if (EFI_ERROR (Status)) {\r
79 return Status;\r
80 }\r
81\r
82 Private->AddressIsOk = FALSE;\r
83\r
84 ZeroMem (Mode, sizeof (EFI_PXE_BASE_CODE_MODE));\r
85\r
86 Mode->Started = TRUE;\r
87 Mode->TTL = DEFAULT_TTL;\r
88 Mode->ToS = DEFAULT_ToS;\r
89 Mode->AutoArp = TRUE;\r
90\r
91 return EFI_SUCCESS;\r
92}\r
93\r
94\r
95/**\r
96 GC_NOTO: Add function description\r
97\r
98 @param This GC_NOTO: add argument\r
99 description\r
100\r
101 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
102 return value\r
103 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
104 return value\r
105 @retval EFI_SUCCESS GC_NOTO: Add description for\r
106 return value\r
107\r
108**/\r
109EFI_STATUS\r
110EFIAPI\r
111EfiPxeBcStop (\r
112 IN EFI_PXE_BASE_CODE_PROTOCOL *This\r
113 )\r
114{\r
115 PXEBC_PRIVATE_DATA *Private;\r
116 EFI_PXE_BASE_CODE_MODE *Mode;\r
117\r
118 if (This == NULL) {\r
119 return EFI_INVALID_PARAMETER;\r
120 }\r
121\r
122 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
123 Mode = Private->PxeBc.Mode;\r
124\r
125 if (!Mode->Started) {\r
126 return EFI_NOT_STARTED;\r
127 }\r
128\r
129 Mode->Started = FALSE;\r
130\r
131 Private->Udp4->Configure (Private->Udp4, NULL);\r
132\r
133 Private->Dhcp4->Stop (Private->Dhcp4);\r
134 Private->Dhcp4->Configure (Private->Dhcp4, NULL);\r
135\r
136 Private->FileSize = 0;\r
137\r
138 return EFI_SUCCESS;\r
139}\r
140\r
141\r
142/**\r
143 GC_NOTO: Add function description\r
144\r
145 @param This GC_NOTO: add argument\r
146 description\r
147 @param SortOffers GC_NOTO: add argument\r
148 description\r
149\r
150 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
151 return value\r
152 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
153 return value\r
154\r
155**/\r
156EFI_STATUS\r
157EFIAPI\r
158EfiPxeBcDhcp (\r
159 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
160 IN BOOLEAN SortOffers\r
161 )\r
162{\r
163 PXEBC_PRIVATE_DATA *Private;\r
164 EFI_PXE_BASE_CODE_MODE *Mode;\r
165 EFI_DHCP4_PROTOCOL *Dhcp4;\r
166 EFI_DHCP4_CONFIG_DATA Dhcp4CfgData;\r
167 EFI_DHCP4_MODE_DATA Dhcp4Mode;\r
168 EFI_DHCP4_PACKET_OPTION *OptList[PXEBC_DHCP4_MAX_OPTION_NUM];\r
169 UINT32 OptCount;\r
170 UINT32 DiscoverTimeout;\r
171 UINTN Index;\r
172 EFI_STATUS Status;\r
173\r
174 if (This == NULL) {\r
175 return EFI_INVALID_PARAMETER;\r
176 }\r
177\r
178 Status = EFI_SUCCESS;\r
179 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
180 Mode = Private->PxeBc.Mode;\r
181 Dhcp4 = Private->Dhcp4;\r
182 Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DHCP;\r
183 Private->SortOffers = SortOffers;\r
184\r
185 if (!Mode->Started) {\r
186 return EFI_NOT_STARTED;\r
187 }\r
188 //\r
189 // Initialize the DHCP options and build the option list\r
190 //\r
191 OptCount = PxeBcBuildDhcpOptions (Private, OptList, TRUE);\r
192\r
193 //\r
194 // Set the DHCP4 config data.\r
195 //\r
196 NetZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
197 Dhcp4CfgData.OptionCount = OptCount;\r
198 Dhcp4CfgData.OptionList = OptList;\r
199 Dhcp4CfgData.Dhcp4Callback = PxeBcDhcpCallBack;\r
200 Dhcp4CfgData.CallbackContext = Private;\r
201 Dhcp4CfgData.DiscoverTryCount = 1;\r
202 Dhcp4CfgData.DiscoverTimeout = &DiscoverTimeout;\r
203\r
204 for (Index = 0; Index < PXEBC_DHCP4_DISCOVER_RETRIES; Index++) {\r
205 //\r
206 // The four discovery timeouts are 4, 8, 16, 32 seconds respectively.\r
207 //\r
208 DiscoverTimeout = (PXEBC_DHCP4_DISCOVER_INIT_TIMEOUT << Index);\r
209\r
210 Status = Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);\r
211 if (EFI_ERROR (Status)) {\r
212 break;\r
213 }\r
214 //\r
215 // Zero those arrays to record the varies numbers of DHCP OFFERS.\r
216 //\r
217 Private->NumOffers = 0;\r
218 Private->BootpIndex = 0;\r
219 NetZeroMem (Private->ServerCount, sizeof (Private->ServerCount));\r
220 NetZeroMem (Private->ProxyIndex, sizeof (Private->ProxyIndex));\r
221\r
222 Status = Dhcp4->Start (Dhcp4, NULL);\r
223 if (EFI_ERROR (Status)) {\r
224 if (Status == EFI_TIMEOUT) {\r
225 //\r
226 // If no response is received or all received offers don't match\r
227 // the PXE boot requirements, EFI_TIMEOUT will be returned.\r
228 //\r
229 continue;\r
230 }\r
231 //\r
232 // Other error status means the DHCP really fails.\r
233 //\r
234 break;\r
235 }\r
236\r
237 Status = Dhcp4->GetModeData (Dhcp4, &Dhcp4Mode);\r
238 if (EFI_ERROR (Status)) {\r
239 break;\r
240 }\r
241\r
242 ASSERT (Dhcp4Mode.State == Dhcp4Bound);\r
243\r
244 NetCopyMem (&Private->StationIp, &Dhcp4Mode.ClientAddress, sizeof (EFI_IPv4_ADDRESS));\r
245 NetCopyMem (&Private->SubnetMask, &Dhcp4Mode.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
246 NetCopyMem (&Private->GatewayIp, &Dhcp4Mode.RouterAddress, sizeof (EFI_IPv4_ADDRESS));\r
247\r
248 //\r
249 // Check the selected offer to see whether BINL is required, if no or BINL is\r
250 // finished, set the various Mode members.\r
251 //\r
252 Status = PxeBcCheckSelectedOffer (Private);\r
253 if (!EFI_ERROR (Status)) {\r
254 break;\r
255 }\r
256 }\r
257\r
258 if (EFI_ERROR (Status)) {\r
259 Dhcp4->Stop (Dhcp4);\r
260 Dhcp4->Configure (Dhcp4, NULL);\r
261 } else {\r
262 //\r
263 // Remove the previously configured option list and callback function\r
264 //\r
265 NetZeroMem (&Dhcp4CfgData, sizeof (EFI_DHCP4_CONFIG_DATA));\r
266 Dhcp4->Configure (Dhcp4, &Dhcp4CfgData);\r
267\r
268 Private->AddressIsOk = TRUE;\r
269 }\r
270\r
271 return Status;\r
272}\r
273\r
274\r
275/**\r
276 GC_NOTO: Add function description\r
277\r
278 @param This GC_NOTO: add argument\r
279 description\r
280 @param Type GC_NOTO: add argument\r
281 description\r
282 @param Layer GC_NOTO: add argument\r
283 description\r
284 @param UseBis GC_NOTO: add argument\r
285 description\r
286 @param Info GC_NOTO: add argument\r
287 description\r
288\r
289 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
290 return value\r
291 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
292 return value\r
293 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
294 return value\r
295 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
296 return value\r
297 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
298 return value\r
299 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
300 return value\r
301\r
302**/\r
303EFI_STATUS\r
304EFIAPI\r
305EfiPxeBcDiscover (\r
306 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
307 IN UINT16 Type,\r
308 IN UINT16 *Layer,\r
309 IN BOOLEAN UseBis,\r
310 IN EFI_PXE_BASE_CODE_DISCOVER_INFO *Info OPTIONAL\r
311 )\r
312{\r
313 PXEBC_PRIVATE_DATA *Private;\r
314 EFI_PXE_BASE_CODE_MODE *Mode;\r
315 EFI_PXE_BASE_CODE_DISCOVER_INFO DefaultInfo;\r
316 EFI_PXE_BASE_CODE_SRVLIST *SrvList;\r
317 EFI_PXE_BASE_CODE_SRVLIST DefaultSrvList;\r
318 PXEBC_CACHED_DHCP4_PACKET *Packet;\r
319 PXEBC_VENDOR_OPTION *VendorOpt;\r
320 UINT16 Index;\r
321 EFI_STATUS Status;\r
322 PXEBC_BOOT_SVR_ENTRY *BootSvrEntry;\r
323\r
324 if (This == NULL) {\r
325 return EFI_INVALID_PARAMETER;\r
326 }\r
327\r
328 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
329 Mode = Private->PxeBc.Mode;\r
330 BootSvrEntry = NULL;\r
331 SrvList = NULL;\r
332 Status = EFI_DEVICE_ERROR;\r
333 Private->Function = EFI_PXE_BASE_CODE_FUNCTION_DISCOVER;\r
334\r
335 if (!Private->AddressIsOk) {\r
336 return EFI_INVALID_PARAMETER;\r
337 }\r
338\r
339 if (!Mode->Started) {\r
340 return EFI_NOT_STARTED;\r
341 }\r
342\r
343 //\r
344 // If layer isn't EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL,\r
345 // use the previous setting;\r
346 // If info isn't offered,\r
347 // use the cached DhcpAck and ProxyOffer packets.\r
348 //\r
349 if (*Layer != EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL) {\r
350\r
351 if (!Mode->PxeDiscoverValid || !Mode->PxeReplyReceived || (!Mode->PxeBisReplyReceived && UseBis)) {\r
352\r
353 return EFI_INVALID_PARAMETER;\r
354 }\r
355\r
356 DefaultInfo.IpCnt = 1;\r
357 DefaultInfo.UseUCast = TRUE;\r
358\r
359 DefaultSrvList.Type = Type;\r
360 DefaultSrvList.AcceptAnyResponse = FALSE;\r
361 DefaultSrvList.IpAddr.Addr[0] = Private->ServerIp.Addr[0];\r
362\r
363 SrvList = &DefaultSrvList;\r
364 Info = &DefaultInfo;\r
365 } else if (Info == NULL) {\r
366 //\r
367 // Create info by the cached packet before\r
368 //\r
369 Packet = (Mode->ProxyOfferReceived) ? &Private->ProxyOffer : &Private->Dhcp4Ack;\r
370 VendorOpt = &Packet->PxeVendorOption;\r
371\r
372 if (!Mode->DhcpAckReceived || !IS_VALID_DISCOVER_VENDOR_OPTION (VendorOpt->BitMap)) {\r
373 //\r
374 // Address is not acquired or no discovery options.\r
375 //\r
376 return EFI_INVALID_PARAMETER;\r
377 }\r
378\r
379 DefaultInfo.UseMCast = (BOOLEAN)!IS_DISABLE_MCAST_DISCOVER (VendorOpt->DiscoverCtrl);\r
380 DefaultInfo.UseBCast = (BOOLEAN)!IS_DISABLE_BCAST_DISCOVER (VendorOpt->DiscoverCtrl);\r
381 DefaultInfo.MustUseList = (BOOLEAN) IS_ENABLE_USE_SERVER_LIST (VendorOpt->DiscoverCtrl);\r
382 DefaultInfo.UseUCast = DefaultInfo.MustUseList;\r
383\r
384 if (DefaultInfo.UseMCast) {\r
385 //\r
386 // Get the multicast discover ip address from vendor option.\r
387 //\r
388 NetCopyMem (&DefaultInfo.ServerMCastIp.Addr, &VendorOpt->DiscoverMcastIp, sizeof (EFI_IPv4_ADDRESS));\r
389 }\r
390\r
391 DefaultInfo.IpCnt = 0;\r
392\r
393 if (DefaultInfo.MustUseList) {\r
394 BootSvrEntry = VendorOpt->BootSvr;\r
395 Status = EFI_INVALID_PARAMETER;\r
396\r
397 while (((UINT8) (BootSvrEntry - VendorOpt->BootSvr)) < VendorOpt->BootSvrLen) {\r
398\r
399 if (BootSvrEntry->Type == HTONS (Type)) {\r
400 Status = EFI_SUCCESS;\r
401 break;\r
402 }\r
403\r
404 BootSvrEntry = GET_NEXT_BOOT_SVR_ENTRY (BootSvrEntry);\r
405 }\r
406\r
407 if (EFI_ERROR (Status)) {\r
408 return Status;\r
409 }\r
410\r
411 DefaultInfo.IpCnt = BootSvrEntry->IpCnt;\r
412 }\r
413\r
414 Info = &DefaultInfo;\r
415 } else {\r
416\r
417 SrvList = Info->SrvList;\r
418\r
419 if (!SrvList[0].AcceptAnyResponse) {\r
420\r
421 for (Index = 1; Index < Info->IpCnt; Index++) {\r
422 if (SrvList[Index].AcceptAnyResponse) {\r
423 break;\r
424 }\r
425 }\r
426\r
427 if (Index != Info->IpCnt) {\r
428 return EFI_INVALID_PARAMETER;\r
429 }\r
430 }\r
431 }\r
432\r
433 if ((!Info->UseUCast && !Info->UseBCast && !Info->UseMCast) || (Info->MustUseList && Info->IpCnt == 0)) {\r
434\r
435 return EFI_INVALID_PARAMETER;\r
436 }\r
437 //\r
438 // Execute discover by UniCast/BroadCast/MultiCast\r
439 //\r
440 if (Info->UseUCast) {\r
441\r
442 for (Index = 0; Index < Info->IpCnt; Index++) {\r
443\r
444 if (BootSvrEntry == NULL) {\r
445 Private->ServerIp.Addr[0] = SrvList[Index].IpAddr.Addr[0];\r
446 } else {\r
447 NetCopyMem (&Private->ServerIp, &BootSvrEntry->IpAddr[Index], sizeof (EFI_IPv4_ADDRESS));\r
448 }\r
449\r
450 Status = PxeBcDiscvBootService (\r
451 Private,\r
452 Type,\r
453 Layer,\r
454 UseBis,\r
455 &SrvList[Index].IpAddr,\r
456 0,\r
457 NULL,\r
458 TRUE,\r
459 &Private->PxeReply.Packet.Ack\r
460 );\r
461 }\r
462\r
463 } else if (Info->UseMCast) {\r
464\r
465 Status = PxeBcDiscvBootService (\r
466 Private,\r
467 Type,\r
468 Layer,\r
469 UseBis,\r
470 &Info->ServerMCastIp,\r
471 0,\r
472 NULL,\r
473 TRUE,\r
474 &Private->PxeReply.Packet.Ack\r
475 );\r
476\r
477 } else if (Info->UseBCast) {\r
478\r
479 Status = PxeBcDiscvBootService (\r
480 Private,\r
481 Type,\r
482 Layer,\r
483 UseBis,\r
484 NULL,\r
485 Info->IpCnt,\r
486 SrvList,\r
487 TRUE,\r
488 &Private->PxeReply.Packet.Ack\r
489 );\r
490 }\r
491\r
492 if (EFI_ERROR (Status) || !Mode->PxeReplyReceived || (!Mode->PxeBisReplyReceived && UseBis)) {\r
493\r
494 Status = EFI_DEVICE_ERROR;\r
495 } else {\r
496 PxeBcParseCachedDhcpPacket (&Private->PxeReply);\r
497 }\r
498\r
499 if (Mode->PxeBisReplyReceived) {\r
500 NetCopyMem (&Private->ServerIp, &Mode->PxeReply.Dhcpv4.BootpSiAddr, sizeof (EFI_IPv4_ADDRESS));\r
501 }\r
502\r
503 return Status;\r
504}\r
505\r
506\r
507/**\r
508 GC_NOTO: Add function description\r
509\r
510 @param This GC_NOTO: add argument\r
511 description\r
512 @param Operation GC_NOTO: add argument\r
513 description\r
514 @param BufferPtr GC_NOTO: add argument\r
515 description\r
516 @param Overwrite GC_NOTO: add argument\r
517 description\r
518 @param BufferSize GC_NOTO: add argument\r
519 description\r
520 @param BlockSize GC_NOTO: add argument\r
521 description\r
522 @param ServerIp GC_NOTO: add argument\r
523 description\r
524 @param Filename GC_NOTO: add argument\r
525 description\r
526 @param Info GC_NOTO: add argument\r
527 description\r
528 @param DontUseBuffer GC_NOTO: add argument\r
529 description\r
530\r
531 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
532 return value\r
533\r
534**/\r
535EFI_STATUS\r
536EFIAPI\r
537EfiPxeBcMtftp (\r
538 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
539 IN EFI_PXE_BASE_CODE_TFTP_OPCODE Operation,\r
540 IN OUT VOID *BufferPtr,\r
541 IN BOOLEAN Overwrite,\r
542 IN OUT UINT64 *BufferSize,\r
543 IN UINTN *BlockSize OPTIONAL,\r
544 IN EFI_IP_ADDRESS *ServerIp,\r
545 IN UINT8 *Filename,\r
546 IN EFI_PXE_BASE_CODE_MTFTP_INFO *Info OPTIONAL,\r
547 IN BOOLEAN DontUseBuffer\r
548 )\r
549{\r
550 PXEBC_PRIVATE_DATA *Private;\r
551 EFI_MTFTP4_CONFIG_DATA Mtftp4Config;\r
552 EFI_STATUS Status;\r
553\r
554 if ((This == NULL) ||\r
555 (Filename == NULL) ||\r
556 (BufferSize == NULL) ||\r
557 ((ServerIp == NULL) || !Ip4IsUnicast (NTOHL (ServerIp->Addr[0]), 0)) ||\r
558 ((BufferPtr == NULL) && DontUseBuffer) ||\r
559 ((BlockSize != NULL) && (*BlockSize < 512))) {\r
560\r
561 return EFI_INVALID_PARAMETER;\r
562 }\r
563\r
564 Status = EFI_DEVICE_ERROR;\r
565 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
566\r
567 Mtftp4Config.UseDefaultSetting = FALSE;\r
568 Mtftp4Config.TimeoutValue = PXEBC_MTFTP_TIMEOUT;\r
569 Mtftp4Config.TryCount = PXEBC_MTFTP_RETRIES;\r
570\r
571 NetCopyMem (&Mtftp4Config.StationIp, &Private->StationIp, sizeof (EFI_IPv4_ADDRESS));\r
572 NetCopyMem (&Mtftp4Config.SubnetMask, &Private->SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
573 NetCopyMem (&Mtftp4Config.GatewayIp, &Private->GatewayIp, sizeof (EFI_IPv4_ADDRESS));\r
574 NetCopyMem (&Mtftp4Config.ServerIp, ServerIp, sizeof (EFI_IPv4_ADDRESS));\r
575\r
576 switch (Operation) {\r
577\r
578 case EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE:\r
579\r
580 Status = PxeBcTftpGetFileSize (\r
581 Private,\r
582 &Mtftp4Config,\r
583 Filename,\r
584 BlockSize,\r
585 BufferSize\r
586 );\r
587\r
588 if (!EFI_ERROR (Status)) {\r
589 Status = EFI_BUFFER_TOO_SMALL;\r
590 }\r
591\r
592 break;\r
593\r
594 case EFI_PXE_BASE_CODE_TFTP_READ_FILE:\r
595\r
596 Status = PxeBcTftpReadFile (\r
597 Private,\r
598 &Mtftp4Config,\r
599 Filename,\r
600 BlockSize,\r
601 BufferPtr,\r
602 BufferSize,\r
603 DontUseBuffer\r
604 );\r
605\r
606 break;\r
607\r
608 case EFI_PXE_BASE_CODE_TFTP_WRITE_FILE:\r
609\r
610 Status = PxeBcTftpWriteFile (\r
611 Private,\r
612 &Mtftp4Config,\r
613 Filename,\r
614 Overwrite,\r
615 BlockSize,\r
616 BufferPtr,\r
617 BufferSize\r
618 );\r
619\r
620 break;\r
621\r
622 case EFI_PXE_BASE_CODE_TFTP_READ_DIRECTORY:\r
623\r
624 Status = PxeBcTftpReadDirectory (\r
625 Private,\r
626 &Mtftp4Config,\r
627 Filename,\r
628 BlockSize,\r
629 BufferPtr,\r
630 BufferSize,\r
631 DontUseBuffer\r
632 );\r
633\r
634 break;\r
635\r
636 case EFI_PXE_BASE_CODE_MTFTP_GET_FILE_SIZE:\r
637 case EFI_PXE_BASE_CODE_MTFTP_READ_FILE:\r
638 case EFI_PXE_BASE_CODE_MTFTP_READ_DIRECTORY:\r
639 Status = EFI_UNSUPPORTED;\r
640 break;\r
641\r
642 default:\r
643\r
644 Status = EFI_INVALID_PARAMETER;\r
645 break;\r
646 }\r
647\r
648 return Status;\r
649}\r
650\r
651\r
652/**\r
653 GC_NOTO: Add function description\r
654\r
655 @param This GC_NOTO: add argument\r
656 description\r
657 @param OpFlags GC_NOTO: add argument\r
658 description\r
659 @param DestIp GC_NOTO: add argument\r
660 description\r
661 @param DestPort GC_NOTO: add argument\r
662 description\r
663 @param GatewayIp GC_NOTO: add argument\r
664 description\r
665 @param SrcIp GC_NOTO: add argument\r
666 description\r
667 @param SrcPort GC_NOTO: add argument\r
668 description\r
669 @param HeaderSize GC_NOTO: add argument\r
670 description\r
671 @param HeaderPtr GC_NOTO: add argument\r
672 description\r
673 @param BufferSize GC_NOTO: add argument\r
674 description\r
675 @param BufferPtr GC_NOTO: add argument\r
676 description\r
677\r
678 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
679 return value\r
680 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
681 return value\r
682 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
683 return value\r
684 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
685 return value\r
686 @retval EFI_OUT_OF_RESOURCES GC_NOTO: Add description for\r
687 return value\r
688\r
689**/\r
690EFI_STATUS\r
691EFIAPI\r
692EfiPxeBcUdpWrite (\r
693 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
694 IN UINT16 OpFlags,\r
695 IN EFI_IP_ADDRESS *DestIp,\r
696 IN EFI_PXE_BASE_CODE_UDP_PORT *DestPort,\r
697 IN EFI_IP_ADDRESS *GatewayIp OPTIONAL,\r
698 IN EFI_IP_ADDRESS *SrcIp OPTIONAL,\r
699 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort OPTIONAL,\r
700 IN UINTN *HeaderSize OPTIONAL,\r
701 IN VOID *HeaderPtr OPTIONAL,\r
702 IN UINTN *BufferSize,\r
703 IN VOID *BufferPtr\r
704 )\r
705{\r
706 PXEBC_PRIVATE_DATA *Private;\r
707 EFI_UDP4_PROTOCOL *Udp4;\r
708 EFI_UDP4_COMPLETION_TOKEN Token;\r
709 EFI_UDP4_TRANSMIT_DATA *Udp4TxData;\r
710 UINT32 FragCount;\r
711 UINT32 DataLength;\r
712 EFI_UDP4_SESSION_DATA Udp4Session;\r
713 EFI_STATUS Status;\r
714 BOOLEAN IsDone;\r
715 UINT16 RandomSrcPort;\r
716\r
717 IsDone = FALSE;\r
718\r
719 if ((This == NULL) || (DestIp == NULL) || (DestPort == NULL)) {\r
720 return EFI_INVALID_PARAMETER;\r
721 }\r
722\r
723 if ((GatewayIp != NULL) && !Ip4IsUnicast (NTOHL (GatewayIp->Addr[0]), 0)) {\r
724 //\r
725 // Gateway is provided but it's not a unicast IP address.\r
726 //\r
727 return EFI_INVALID_PARAMETER;\r
728 }\r
729\r
730 if ((HeaderSize != NULL) && ((*HeaderSize == 0) || (HeaderPtr == NULL))) {\r
731 //\r
732 // The HeaderSize ptr isn't NULL and: 1. the value is zero; or 2. the HeaderPtr\r
733 // is NULL.\r
734 //\r
735 return EFI_INVALID_PARAMETER;\r
736 }\r
737\r
738 if ((BufferSize == NULL) || ((*BufferSize != 0) && (BufferPtr == NULL))) {\r
739 return EFI_INVALID_PARAMETER;\r
740 }\r
741\r
742 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
743 Udp4 = Private->Udp4;\r
744\r
745 if (!Private->AddressIsOk && (SrcIp == NULL)) {\r
746 return EFI_INVALID_PARAMETER;\r
747 }\r
748\r
749 if (SrcIp == NULL) {\r
750 SrcIp = &Private->StationIp;\r
751\r
752 if (GatewayIp == NULL) {\r
753 GatewayIp = &Private->GatewayIp;\r
754 }\r
755 }\r
756\r
757 if ((SrcPort == NULL) || (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT)) {\r
758 RandomSrcPort = (UINT16) (NET_RANDOM (NetRandomInitSeed ()) % 10000 + 1024);\r
759\r
760 if (SrcPort == NULL) {\r
761\r
762 SrcPort = &RandomSrcPort;\r
763 } else {\r
764\r
765 *SrcPort = RandomSrcPort;\r
766 }\r
767 }\r
768\r
769 ZeroMem (&Token, sizeof (EFI_UDP4_COMPLETION_TOKEN));\r
770 ZeroMem (&Udp4Session, sizeof (EFI_UDP4_SESSION_DATA));\r
771\r
772 NetCopyMem (&Udp4Session.DestinationAddress, DestIp, sizeof (EFI_IPv4_ADDRESS));\r
773 Udp4Session.DestinationPort = *DestPort;\r
774 NetCopyMem (&Udp4Session.SourceAddress, SrcIp, sizeof (EFI_IPv4_ADDRESS));\r
775 Udp4Session.SourcePort = *SrcPort;\r
776\r
777 FragCount = (HeaderSize != NULL) ? 2 : 1;\r
778 Udp4TxData = (EFI_UDP4_TRANSMIT_DATA *) NetAllocatePool (sizeof (EFI_UDP4_TRANSMIT_DATA) + (FragCount - 1) * sizeof (EFI_UDP4_FRAGMENT_DATA));\r
779 if (Udp4TxData == NULL) {\r
780 return EFI_OUT_OF_RESOURCES;\r
781 }\r
782\r
783 Udp4TxData->FragmentCount = FragCount;\r
784 Udp4TxData->FragmentTable[FragCount - 1].FragmentLength = (UINT32) *BufferSize;\r
785 Udp4TxData->FragmentTable[FragCount - 1].FragmentBuffer = BufferPtr;\r
786 DataLength = (UINT32) *BufferSize;\r
787\r
788 if (FragCount == 2) {\r
789\r
790 Udp4TxData->FragmentTable[0].FragmentLength = (UINT32) *HeaderSize;\r
791 Udp4TxData->FragmentTable[0].FragmentBuffer = HeaderPtr;\r
792 DataLength += (UINT32) *HeaderSize;\r
793 }\r
794\r
795 Udp4TxData->GatewayAddress = (EFI_IPv4_ADDRESS *) GatewayIp;\r
796 Udp4TxData->UdpSessionData = &Udp4Session;\r
797 Udp4TxData->DataLength = DataLength;\r
798 Token.Packet.TxData = Udp4TxData;\r
799\r
800 Status = gBS->CreateEvent (\r
801 EVT_NOTIFY_SIGNAL,\r
802 NET_TPL_EVENT,\r
803 PxeBcCommonNotify,\r
804 &IsDone,\r
805 &Token.Event\r
806 );\r
807 if (EFI_ERROR (Status)) {\r
808 goto ON_EXIT;\r
809 }\r
810\r
811 Status = Udp4->Transmit (Udp4, &Token);\r
812 if (EFI_ERROR (Status)) {\r
813 goto ON_EXIT;\r
814 }\r
815\r
816 while (!IsDone) {\r
817\r
818 Udp4->Poll (Udp4);\r
819 }\r
820\r
821 Status = Token.Status;\r
822\r
823ON_EXIT:\r
824\r
825 if (Token.Event != NULL) {\r
826 gBS->CloseEvent (Token.Event);\r
827 }\r
828\r
829 NetFreePool (Udp4TxData);\r
830\r
831 return Status;\r
832}\r
833\r
834\r
835/**\r
836 GC_NOTO: Add function description\r
837\r
838 @param This GC_NOTO: add argument\r
839 description\r
840 @param OpFlags GC_NOTO: add argument\r
841 description\r
842 @param DestIp GC_NOTO: add argument\r
843 description\r
844 @param DestPort GC_NOTO: add argument\r
845 description\r
846 @param SrcIp GC_NOTO: add argument\r
847 description\r
848 @param SrcPort GC_NOTO: add argument\r
849 description\r
850 @param HeaderSize GC_NOTO: add argument\r
851 description\r
852 @param HeaderPtr GC_NOTO: add argument\r
853 description\r
854 @param BufferSize GC_NOTO: add argument\r
855 description\r
856 @param BufferPtr GC_NOTO: add argument\r
857 description\r
858\r
859 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
860 return value\r
861 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
862 return value\r
863 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
864 return value\r
865 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
866 return value\r
867 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
868 return value\r
869 @retval EFI_OUT_OF_RESOURCES GC_NOTO: Add description for\r
870 return value\r
871\r
872**/\r
873EFI_STATUS\r
874EFIAPI\r
875EfiPxeBcUdpRead (\r
876 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
877 IN UINT16 OpFlags,\r
878 IN OUT EFI_IP_ADDRESS *DestIp, OPTIONAL\r
879 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *DestPort, OPTIONAL\r
880 IN OUT EFI_IP_ADDRESS *SrcIp, OPTIONAL\r
881 IN OUT EFI_PXE_BASE_CODE_UDP_PORT *SrcPort, OPTIONAL\r
882 IN UINTN *HeaderSize, OPTIONAL\r
883 IN VOID *HeaderPtr, OPTIONAL\r
884 IN OUT UINTN *BufferSize,\r
885 IN VOID *BufferPtr\r
886 )\r
887{\r
888 PXEBC_PRIVATE_DATA *Private;\r
889 EFI_PXE_BASE_CODE_MODE *Mode;\r
890 EFI_UDP4_PROTOCOL *Udp4;\r
891 EFI_UDP4_COMPLETION_TOKEN Token;\r
892 EFI_UDP4_RECEIVE_DATA *RxData;\r
893 EFI_UDP4_SESSION_DATA *Session;\r
894 EFI_STATUS Status;\r
895 BOOLEAN IsDone;\r
896 BOOLEAN Matched;\r
897 UINTN CopyLen;\r
898\r
899 if (This == NULL || DestIp == NULL || DestPort == NULL) {\r
900 return EFI_INVALID_PARAMETER;\r
901 }\r
902\r
903 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_USE_FILTER) {\r
904 return EFI_UNSUPPORTED;\r
905 }\r
906\r
907 if ((!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && (DestPort == NULL)) ||\r
908 (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) && (SrcIp == NULL)) ||\r
909 (!(OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) && (SrcPort == NULL))) {\r
910 return EFI_INVALID_PARAMETER;\r
911 }\r
912\r
913 if (((HeaderSize != NULL) && (*HeaderSize == 0)) || ((HeaderPtr == NULL) && (*HeaderSize != 0))) {\r
914 return EFI_INVALID_PARAMETER;\r
915 }\r
916\r
917 if ((BufferSize == NULL) || ((BufferPtr == NULL) && (*BufferSize != 0))) {\r
918 return EFI_INVALID_PARAMETER;\r
919 }\r
920\r
921 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
922 Mode = Private->PxeBc.Mode;\r
923 Udp4 = Private->Udp4;\r
924\r
925 if (!Mode->Started) {\r
926 return EFI_NOT_STARTED;\r
927 }\r
928\r
929 Status = gBS->CreateEvent (\r
930 EVT_NOTIFY_SIGNAL,\r
931 NET_TPL_EVENT,\r
932 PxeBcCommonNotify,\r
933 &IsDone,\r
934 &Token.Event\r
935 );\r
936 if (EFI_ERROR (Status)) {\r
937 return EFI_OUT_OF_RESOURCES;\r
938 }\r
939\r
940 IsDone = FALSE;\r
941 Status = Udp4->Receive (Udp4, &Token);\r
942 if (EFI_ERROR (Status)) {\r
943 goto ON_EXIT;\r
944 }\r
945\r
946 Udp4->Poll (Udp4);\r
947\r
948 if (!IsDone) {\r
949 Status = EFI_TIMEOUT;\r
950 } else {\r
951\r
952 //\r
953 // check whether this packet matches the filters\r
954 //\r
955 if (EFI_ERROR (Token.Status)){\r
956 goto ON_EXIT;\r
957 }\r
958\r
959 RxData = Token.Packet.RxData;\r
960 Session = &RxData->UdpSession;\r
961\r
962 Matched = FALSE;\r
963\r
964 //\r
965 // Match the destination ip of the received udp dgram\r
966 //\r
967 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_IP) {\r
968 Matched = TRUE;\r
969\r
970 if (DestIp != NULL) {\r
971 NetCopyMem (DestIp, &Session->DestinationAddress, sizeof (EFI_IPv4_ADDRESS));\r
972 }\r
973 } else {\r
974 if (DestIp != NULL) {\r
975 if (EFI_IP4_EQUAL (DestIp, &Session->DestinationAddress)) {\r
976 Matched = TRUE;\r
977 }\r
978 } else {\r
979 if (EFI_IP4_EQUAL (&Private->StationIp, &Session->DestinationAddress)) {\r
980 Matched = TRUE;\r
981 }\r
982 }\r
983 }\r
984\r
985 if (Matched) {\r
986 //\r
987 // Match the destination port of the received udp dgram\r
988 //\r
989 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_DEST_PORT) {\r
990\r
991 if (DestPort != NULL) {\r
992 *DestPort = Session->DestinationPort;\r
993 }\r
994 } else {\r
995\r
996 if (*DestPort != Session->DestinationPort) {\r
997 Matched = FALSE;\r
998 }\r
999 }\r
1000 }\r
1001\r
1002 if (Matched) {\r
1003 //\r
1004 // Match the source ip of the received udp dgram\r
1005 //\r
1006 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_IP) {\r
1007\r
1008 if (SrcIp != NULL) {\r
1009 NetCopyMem (SrcIp, &Session->SourceAddress, sizeof (EFI_IPv4_ADDRESS));\r
1010 }\r
1011 } else {\r
1012\r
1013 if (!EFI_IP4_EQUAL (SrcIp, &Session->SourceAddress)) {\r
1014 Matched = FALSE;\r
1015 }\r
1016 }\r
1017 }\r
1018\r
1019 if (Matched) {\r
1020 //\r
1021 // Match the source port of the received udp dgram\r
1022 //\r
1023 if (OpFlags & EFI_PXE_BASE_CODE_UDP_OPFLAGS_ANY_SRC_PORT) {\r
1024\r
1025 if (SrcPort != NULL) {\r
1026 *SrcPort = Session->SourcePort;\r
1027 }\r
1028 } else {\r
1029\r
1030 if (*SrcPort != Session->SourcePort) {\r
1031 Matched = FALSE;\r
1032 }\r
1033 }\r
1034 }\r
1035\r
1036 if (Matched) {\r
1037\r
1038 CopyLen = 0;\r
1039\r
1040 if (HeaderSize != NULL) {\r
1041 CopyLen = MIN (*HeaderSize, RxData->DataLength);\r
1042 NetCopyMem (HeaderPtr, RxData->FragmentTable[0].FragmentBuffer, CopyLen);\r
1043 *HeaderSize = CopyLen;\r
1044 }\r
1045\r
1046 if (RxData->DataLength - CopyLen > *BufferSize) {\r
1047\r
1048 Status = EFI_BUFFER_TOO_SMALL;\r
1049 } else {\r
1050\r
1051 *BufferSize = RxData->DataLength - CopyLen;\r
1052 NetCopyMem (BufferPtr, (UINT8 *) RxData->FragmentTable[0].FragmentBuffer + CopyLen, *BufferSize);\r
1053 }\r
1054 } else {\r
1055\r
1056 Status = EFI_TIMEOUT;\r
1057 }\r
1058\r
1059 //\r
1060 // Recycle the RxData\r
1061 //\r
1062 gBS->SignalEvent (RxData->RecycleSignal);\r
1063 }\r
1064\r
1065ON_EXIT:\r
1066\r
1067 Udp4->Cancel (Udp4, &Token);\r
1068\r
1069 gBS->CloseEvent (Token.Event);\r
1070\r
1071 return Status;\r
1072}\r
1073\r
1074\r
1075/**\r
1076 GC_NOTO: Add function description\r
1077\r
1078 @param This GC_NOTO: add argument\r
1079 description\r
1080 @param NewFilter GC_NOTO: add argument\r
1081 description\r
1082\r
1083 @retval EFI_UNSUPPORTED GC_NOTO: Add description for\r
1084 return value\r
1085\r
1086**/\r
1087EFI_STATUS\r
1088EFIAPI\r
1089EfiPxeBcSetIpFilter (\r
1090 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
1091 IN EFI_PXE_BASE_CODE_IP_FILTER *NewFilter\r
1092 )\r
1093{\r
1094 return EFI_UNSUPPORTED;\r
1095}\r
1096\r
1097\r
1098/**\r
1099 GC_NOTO: Add function description\r
1100\r
1101 @param This GC_NOTO: add argument\r
1102 description\r
1103 @param IpAddr GC_NOTO: add argument\r
1104 description\r
1105 @param MacAddr GC_NOTO: add argument\r
1106 description\r
1107\r
1108 @retval EFI_UNSUPPORTED GC_NOTO: Add description for\r
1109 return value\r
1110\r
1111**/\r
1112EFI_STATUS\r
1113EFIAPI\r
1114EfiPxeBcArp (\r
1115 IN EFI_PXE_BASE_CODE_PROTOCOL * This,\r
1116 IN EFI_IP_ADDRESS * IpAddr,\r
1117 IN EFI_MAC_ADDRESS * MacAddr OPTIONAL\r
1118 )\r
1119{\r
1120 return EFI_UNSUPPORTED;\r
1121}\r
1122\r
1123\r
1124/**\r
1125 GC_NOTO: Add function description\r
1126\r
1127 @param This GC_NOTO: add argument\r
1128 description\r
1129 @param NewAutoArp GC_NOTO: add argument\r
1130 description\r
1131 @param NewSendGUID GC_NOTO: add argument\r
1132 description\r
1133 @param NewTTL GC_NOTO: add argument\r
1134 description\r
1135 @param NewToS GC_NOTO: add argument\r
1136 description\r
1137 @param NewMakeCallback GC_NOTO: add argument\r
1138 description\r
1139\r
1140 @return GC_NOTO: add return values\r
1141\r
1142**/\r
1143EFI_STATUS\r
1144EFIAPI\r
1145EfiPxeBcSetParameters (\r
1146 IN EFI_PXE_BASE_CODE_PROTOCOL *This,\r
1147 IN BOOLEAN *NewAutoArp, OPTIONAL\r
1148 IN BOOLEAN *NewSendGUID, OPTIONAL\r
1149 IN UINT8 *NewTTL, OPTIONAL\r
1150 IN UINT8 *NewToS, OPTIONAL\r
1151 IN BOOLEAN *NewMakeCallback // OPTIONAL\r
1152 )\r
1153{\r
1154 PXEBC_PRIVATE_DATA *Private;\r
1155 EFI_PXE_BASE_CODE_MODE *Mode;\r
1156 EFI_STATUS Status;\r
1157\r
1158 Status = EFI_SUCCESS;\r
1159\r
1160 if (This == NULL) {\r
1161 Status = EFI_INVALID_PARAMETER;\r
1162 goto ON_EXIT;\r
1163 }\r
1164\r
1165 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
1166 Mode = Private->PxeBc.Mode;\r
1167\r
1168 if (NewSendGUID != NULL && *NewSendGUID == TRUE) {\r
1169 //\r
1170 // FixMe, cann't locate SendGuid\r
1171 //\r
1172 }\r
1173\r
1174 if (NewMakeCallback != NULL && *NewMakeCallback == TRUE) {\r
1175\r
1176 Status = gBS->HandleProtocol (\r
1177 Private->Controller,\r
1178 &gEfiPxeBaseCodeCallbackProtocolGuid,\r
1179 (VOID **) &Private->PxeBcCallback\r
1180 );\r
1181 if (EFI_ERROR (Status) || (Private->PxeBcCallback->Callback == NULL)) {\r
1182\r
1183 Status = EFI_INVALID_PARAMETER;\r
1184 goto ON_EXIT;\r
1185 }\r
1186 }\r
1187\r
1188 if (!Mode->Started) {\r
1189 Status = EFI_NOT_STARTED;\r
1190 goto ON_EXIT;\r
1191 }\r
1192\r
1193 if (NewMakeCallback != NULL) {\r
1194\r
1195 if (*NewMakeCallback) {\r
1196 //\r
1197 // Update the Callback protocol.\r
1198 //\r
1199 Status = gBS->HandleProtocol (\r
1200 Private->Controller,\r
1201 &gEfiPxeBaseCodeCallbackProtocolGuid,\r
1202 (VOID **) &Private->PxeBcCallback\r
1203 );\r
1204\r
1205 if (EFI_ERROR (Status) || (Private->PxeBcCallback->Callback == NULL)) {\r
1206 Status = EFI_INVALID_PARAMETER;\r
1207 goto ON_EXIT;\r
1208 }\r
1209 } else {\r
1210 Private->PxeBcCallback = NULL;\r
1211 }\r
1212\r
1213 Mode->MakeCallbacks = *NewMakeCallback;\r
1214 }\r
1215\r
1216 if (NewAutoArp != NULL) {\r
1217 Mode->AutoArp = *NewAutoArp;\r
1218 }\r
1219\r
1220 if (NewSendGUID != NULL) {\r
1221 Mode->SendGUID = *NewSendGUID;\r
1222 }\r
1223\r
1224 if (NewTTL != NULL) {\r
1225 Mode->TTL = *NewTTL;\r
1226 }\r
1227\r
1228 if (NewToS != NULL) {\r
1229 Mode->ToS = *NewToS;\r
1230 }\r
1231\r
1232ON_EXIT:\r
1233 return Status;\r
1234}\r
1235\r
1236\r
1237/**\r
1238 GC_NOTO: Add function description\r
1239\r
1240 @param This GC_NOTO: add argument\r
1241 description\r
1242 @param NewStationIp GC_NOTO: add argument\r
1243 description\r
1244 @param NewSubnetMask GC_NOTO: add argument\r
1245 description\r
1246\r
1247 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
1248 return value\r
1249 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
1250 return value\r
1251 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
1252 return value\r
1253 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
1254 return value\r
1255 @retval EFI_SUCCESS GC_NOTO: Add description for\r
1256 return value\r
1257\r
1258**/\r
1259EFI_STATUS\r
1260EFIAPI\r
1261EfiPxeBcSetStationIP (\r
1262 IN EFI_PXE_BASE_CODE_PROTOCOL * This,\r
1263 IN EFI_IP_ADDRESS * NewStationIp, OPTIONAL\r
1264 IN EFI_IP_ADDRESS * NewSubnetMask OPTIONAL\r
1265 )\r
1266{\r
1267 PXEBC_PRIVATE_DATA *Private;\r
1268 EFI_PXE_BASE_CODE_MODE *Mode;\r
1269\r
1270 if (This == NULL) {\r
1271 return EFI_INVALID_PARAMETER;\r
1272 }\r
1273\r
1274 if (NewStationIp != NULL && !Ip4IsUnicast (NTOHL (NewStationIp->Addr[0]), 0)) {\r
1275 return EFI_INVALID_PARAMETER;\r
1276 }\r
1277\r
1278 if (NewSubnetMask != NULL && !IP4_IS_VALID_NETMASK (NTOHL (NewSubnetMask->Addr[0]))) {\r
1279 return EFI_INVALID_PARAMETER;\r
1280 }\r
1281\r
1282 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
1283 Mode = Private->PxeBc.Mode;\r
1284\r
1285 if (!Mode->Started) {\r
1286 return EFI_NOT_STARTED;\r
1287 }\r
1288\r
1289 if (NewStationIp != NULL) {\r
1290 Mode->StationIp = *NewStationIp;\r
1291 }\r
1292\r
1293 if (NewSubnetMask != NULL) {\r
1294 Mode->SubnetMask = *NewSubnetMask;\r
1295 }\r
1296\r
1297 Private->AddressIsOk = TRUE;\r
1298\r
1299 return EFI_SUCCESS;\r
1300}\r
1301\r
1302\r
1303/**\r
1304 GC_NOTO: Add function description\r
1305\r
1306 @param This GC_NOTO: add argument\r
1307 description\r
1308 @param NewDhcpDiscoverValid GC_NOTO: add argument\r
1309 description\r
1310 @param NewDhcpAckReceived GC_NOTO: add argument\r
1311 description\r
1312 @param NewProxyOfferReceived GC_NOTO: add argument\r
1313 description\r
1314 @param NewPxeDiscoverValid GC_NOTO: add argument\r
1315 description\r
1316 @param NewPxeReplyReceived GC_NOTO: add argument\r
1317 description\r
1318 @param NewPxeBisReplyReceived GC_NOTO: add argument\r
1319 description\r
1320 @param NewDhcpDiscover GC_NOTO: add argument\r
1321 description\r
1322 @param NewDhcpAck GC_NOTO: add argument\r
1323 description\r
1324 @param NewProxyOffer GC_NOTO: add argument\r
1325 description\r
1326 @param NewPxeDiscover GC_NOTO: add argument\r
1327 description\r
1328 @param NewPxeReply GC_NOTO: add argument\r
1329 description\r
1330 @param NewPxeBisReply GC_NOTO: add argument\r
1331 description\r
1332\r
1333 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
1334 return value\r
1335 @retval EFI_NOT_STARTED GC_NOTO: Add description for\r
1336 return value\r
1337 @retval EFI_SUCCESS GC_NOTO: Add description for\r
1338 return value\r
1339\r
1340**/\r
1341EFI_STATUS\r
1342EFIAPI\r
1343EfiPxeBcSetPackets (\r
1344 IN EFI_PXE_BASE_CODE_PROTOCOL * This,\r
1345 IN BOOLEAN * NewDhcpDiscoverValid, OPTIONAL\r
1346 IN BOOLEAN * NewDhcpAckReceived, OPTIONAL\r
1347 IN BOOLEAN * NewProxyOfferReceived, OPTIONAL\r
1348 IN BOOLEAN * NewPxeDiscoverValid, OPTIONAL\r
1349 IN BOOLEAN * NewPxeReplyReceived, OPTIONAL\r
1350 IN BOOLEAN * NewPxeBisReplyReceived, OPTIONAL\r
1351 IN EFI_PXE_BASE_CODE_PACKET * NewDhcpDiscover, OPTIONAL\r
1352 IN EFI_PXE_BASE_CODE_PACKET * NewDhcpAck, OPTIONAL\r
1353 IN EFI_PXE_BASE_CODE_PACKET * NewProxyOffer, OPTIONAL\r
1354 IN EFI_PXE_BASE_CODE_PACKET * NewPxeDiscover, OPTIONAL\r
1355 IN EFI_PXE_BASE_CODE_PACKET * NewPxeReply, OPTIONAL\r
1356 IN EFI_PXE_BASE_CODE_PACKET * NewPxeBisReply OPTIONAL\r
1357 )\r
1358{\r
1359 PXEBC_PRIVATE_DATA *Private;\r
1360 EFI_PXE_BASE_CODE_MODE *Mode;\r
1361\r
1362 if (This == NULL) {\r
1363 return EFI_INVALID_PARAMETER;\r
1364 }\r
1365\r
1366 Private = PXEBC_PRIVATE_DATA_FROM_PXEBC (This);\r
1367 Mode = Private->PxeBc.Mode;\r
1368\r
1369 if (!Mode->Started) {\r
1370 return EFI_NOT_STARTED;\r
1371 }\r
1372\r
1373 Private->FileSize = 0;\r
1374\r
1375 if (NewDhcpDiscoverValid != NULL) {\r
1376 Mode->DhcpDiscoverValid = *NewDhcpDiscoverValid;\r
1377 }\r
1378\r
1379 if (NewDhcpAckReceived != NULL) {\r
1380 Mode->DhcpAckReceived = *NewDhcpAckReceived;\r
1381 }\r
1382\r
1383 if (NewProxyOfferReceived != NULL) {\r
1384 Mode->ProxyOfferReceived = *NewProxyOfferReceived;\r
1385 }\r
1386\r
1387 if (NewPxeDiscoverValid != NULL) {\r
1388 Mode->PxeDiscoverValid = *NewPxeDiscoverValid;\r
1389 }\r
1390\r
1391 if (NewPxeReplyReceived != NULL) {\r
1392 Mode->PxeReplyReceived = *NewPxeReplyReceived;\r
1393 }\r
1394\r
1395 if (NewPxeBisReplyReceived != NULL) {\r
1396 Mode->PxeBisReplyReceived = *NewPxeBisReplyReceived;\r
1397 }\r
1398\r
1399 if (NewDhcpDiscover != NULL) {\r
1400 NetCopyMem (&Mode->DhcpDiscover, NewDhcpDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1401 }\r
1402\r
1403 if (NewDhcpAck != NULL) {\r
1404 NetCopyMem (&Mode->DhcpAck, NewDhcpAck, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1405 }\r
1406\r
1407 if (NewProxyOffer != NULL) {\r
1408 NetCopyMem (&Mode->ProxyOffer, NewProxyOffer, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1409 }\r
1410\r
1411 if (NewPxeDiscover != NULL) {\r
1412 NetCopyMem (&Mode->PxeDiscover, NewPxeDiscover, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1413 }\r
1414\r
1415 if (NewPxeReply != NULL) {\r
1416 NetCopyMem (&Mode->PxeReply, NewPxeReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1417 }\r
1418\r
1419 if (NewPxeBisReply != NULL) {\r
1420 NetCopyMem (&Mode->PxeBisReply, NewPxeBisReply, sizeof (EFI_PXE_BASE_CODE_PACKET));\r
1421 }\r
1422\r
1423 return EFI_SUCCESS;\r
1424}\r
1425\r
1426EFI_PXE_BASE_CODE_PROTOCOL mPxeBcProtocolTemplate = {\r
1427 EFI_PXE_BASE_CODE_PROTOCOL_REVISION,\r
1428 EfiPxeBcStart,\r
1429 EfiPxeBcStop,\r
1430 EfiPxeBcDhcp,\r
1431 EfiPxeBcDiscover,\r
1432 EfiPxeBcMtftp,\r
1433 EfiPxeBcUdpWrite,\r
1434 EfiPxeBcUdpRead,\r
1435 EfiPxeBcSetIpFilter,\r
1436 EfiPxeBcArp,\r
1437 EfiPxeBcSetParameters,\r
1438 EfiPxeBcSetStationIP,\r
1439 EfiPxeBcSetPackets,\r
1440 NULL\r
1441};\r
1442\r
1443\r
1444/**\r
1445 GC_NOTO: Add function description\r
1446\r
1447 @param This GC_NOTO: add argument\r
1448 description\r
1449 @param Function GC_NOTO: add argument\r
1450 description\r
1451 @param Received GC_NOTO: add argument\r
1452 description\r
1453 @param PacketLength GC_NOTO: add argument\r
1454 description\r
1455 @param PacketPtr GC_NOTO: add argument\r
1456 description\r
1457\r
1458 @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT GC_NOTO: Add description for\r
1459 return value\r
1460 @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE GC_NOTO: Add description for\r
1461 return value\r
1462 @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE GC_NOTO: Add description for\r
1463 return value\r
1464 @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE GC_NOTO: Add description for\r
1465 return value\r
1466 @retval EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE GC_NOTO: Add description for\r
1467 return value\r
1468\r
1469**/\r
1470EFI_PXE_BASE_CODE_CALLBACK_STATUS\r
1471EFIAPI\r
1472EfiPxeLoadFileCallback (\r
1473 IN EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL * This,\r
1474 IN EFI_PXE_BASE_CODE_FUNCTION Function,\r
1475 IN BOOLEAN Received,\r
1476 IN UINT32 PacketLength,\r
1477 IN EFI_PXE_BASE_CODE_PACKET * PacketPtr OPTIONAL\r
1478 )\r
1479{\r
1480 EFI_INPUT_KEY Key;\r
1481 EFI_STATUS Status;\r
1482\r
1483 //\r
1484 // Catch Ctrl-C or ESC to abort.\r
1485 //\r
1486 Status = gST->ConIn->ReadKeyStroke (gST->ConIn, &Key);\r
1487\r
1488 if (!EFI_ERROR (Status)) {\r
1489\r
1490 if (Key.ScanCode == SCAN_ESC || Key.UnicodeChar == (0x1F & 'c')) {\r
1491\r
1492 return EFI_PXE_BASE_CODE_CALLBACK_STATUS_ABORT;\r
1493 }\r
1494 }\r
1495 //\r
1496 // No print if receive packet\r
1497 //\r
1498 if (Received) {\r
1499 return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
1500 }\r
1501 //\r
1502 // Print only for three functions\r
1503 //\r
1504 switch (Function) {\r
1505\r
1506 case EFI_PXE_BASE_CODE_FUNCTION_MTFTP:\r
1507 //\r
1508 // Print only for open MTFTP packets, not every MTFTP packets\r
1509 //\r
1510 if (PacketLength != 0 && PacketPtr != NULL) {\r
1511 if (PacketPtr->Raw[0x1C] != 0x00 || PacketPtr->Raw[0x1D] != 0x01) {\r
1512 return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
1513 }\r
1514 }\r
1515 break;\r
1516\r
1517 case EFI_PXE_BASE_CODE_FUNCTION_DHCP:\r
1518 case EFI_PXE_BASE_CODE_FUNCTION_DISCOVER:\r
1519 break;\r
1520\r
1521 default:\r
1522 return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
1523 }\r
1524\r
1525 if (PacketLength != 0 && PacketPtr != NULL) {\r
1526 //\r
1527 // Print '.' when transmit a packet\r
1528 //\r
1529 AsciiPrint (".");\r
1530\r
1531 }\r
1532\r
1533 return EFI_PXE_BASE_CODE_CALLBACK_STATUS_CONTINUE;\r
1534}\r
1535\r
1536EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL mPxeBcCallBackTemplate = {\r
1537 EFI_PXE_BASE_CODE_CALLBACK_PROTOCOL_REVISION,\r
1538 EfiPxeLoadFileCallback\r
1539};\r
1540\r
1541\r
1542/**\r
1543 GC_NOTO: Add function description\r
1544\r
1545 @param Private GC_NOTO: add argument\r
1546 description\r
1547 @param BufferSize GC_NOTO: add argument\r
1548 description\r
1549 @param Buffer GC_NOTO: add argument\r
1550 description\r
1551\r
1552 @return GC_NOTO: add return values\r
1553\r
1554**/\r
1555EFI_STATUS\r
1556DiscoverBootFile (\r
1557 IN PXEBC_PRIVATE_DATA *Private,\r
1558 IN OUT UINT64 *BufferSize,\r
1559 IN VOID *Buffer\r
1560 )\r
1561{\r
1562 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;\r
1563 EFI_PXE_BASE_CODE_MODE *Mode;\r
1564 EFI_STATUS Status;\r
1565 UINT16 Type;\r
1566 UINT16 Layer;\r
1567 BOOLEAN UseBis;\r
1568 UINTN BlockSize;\r
1569 PXEBC_CACHED_DHCP4_PACKET *Packet;\r
1570 UINT16 Value;\r
1571\r
1572 PxeBc = &Private->PxeBc;\r
1573 Mode = PxeBc->Mode;\r
1574 Type = EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP;\r
1575 Layer = EFI_PXE_BASE_CODE_BOOT_LAYER_INITIAL;\r
1576\r
1577 //\r
1578 // do DHCP.\r
1579 //\r
1580 Status = PxeBc->Dhcp (PxeBc, TRUE);\r
1581 if (EFI_ERROR (Status)) {\r
1582 return Status;\r
1583 }\r
1584\r
1585 //\r
1586 // Select a boot server\r
1587 //\r
1588 Status = PxeBcSelectBootPrompt (Private);\r
1589\r
1590 if (Status == EFI_SUCCESS) {\r
1591 Status = PxeBcSelectBootMenu (Private, &Type, TRUE);\r
1592 } else if (Status == EFI_TIMEOUT) {\r
1593 Status = PxeBcSelectBootMenu (Private, &Type, FALSE);\r
1594 }\r
1595\r
1596 if (!EFI_ERROR (Status)) {\r
1597\r
1598 if (Type == EFI_PXE_BASE_CODE_BOOT_TYPE_BOOTSTRAP) {\r
1599 //\r
1600 // Local boot(PXE bootstrap server) need abort\r
1601 //\r
1602 return EFI_ABORTED;\r
1603 }\r
1604\r
1605 UseBis = (BOOLEAN) (Mode->BisSupported && Mode->BisDetected);\r
1606 Status = PxeBc->Discover (PxeBc, Type, &Layer, UseBis, NULL);\r
1607 if (EFI_ERROR (Status)) {\r
1608 return Status;\r
1609 }\r
1610 }\r
1611\r
1612 *BufferSize = 0;\r
1613 BlockSize = 0x8000;\r
1614\r
1615 //\r
1616 // Get bootfile name and (m)tftp server ip addresss\r
1617 //\r
1618 if (Mode->PxeReplyReceived) {\r
1619 Packet = &Private->PxeReply;\r
1620 } else if (Mode->ProxyOfferReceived) {\r
1621 Packet = &Private->ProxyOffer;\r
1622 } else {\r
1623 Packet = &Private->Dhcp4Ack;\r
1624 }\r
1625\r
1626 NetCopyMem (&Private->ServerIp, &Packet->Packet.Offer.Dhcp4.Header.ServerAddr, sizeof (EFI_IPv4_ADDRESS));\r
1627 if (Private->ServerIp.Addr[0] == 0) {\r
1628 //\r
1629 // next server ip address is zero, use option 54 instead\r
1630 //\r
1631 NetCopyMem (\r
1632 &Private->ServerIp,\r
1633 Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_SERVER_ID]->Data,\r
1634 sizeof (EFI_IPv4_ADDRESS)\r
1635 );\r
1636 }\r
1637\r
1638 ASSERT (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE] != NULL);\r
1639\r
1640 //\r
1641 // bootlfile name\r
1642 //\r
1643 Private->BootFileName = (CHAR8 *) (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE]->Data);\r
1644\r
1645 if (Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN] != NULL) {\r
1646 //\r
1647 // Already have the bootfile length option, compute the file size\r
1648 //\r
1649 NetCopyMem (&Value, Packet->Dhcp4Option[PXEBC_DHCP4_TAG_INDEX_BOOTFILE_LEN]->Data, sizeof (Value));\r
1650 Value = NTOHS (Value);\r
1651 *BufferSize = 512 * Value;\r
1652 Status = EFI_BUFFER_TOO_SMALL;\r
1653 } else {\r
1654 //\r
1655 // Get the bootfile size from tftp\r
1656 //\r
1657 Status = PxeBc->Mtftp (\r
1658 PxeBc,\r
1659 EFI_PXE_BASE_CODE_TFTP_GET_FILE_SIZE,\r
1660 Buffer,\r
1661 FALSE,\r
1662 BufferSize,\r
1663 &BlockSize,\r
1664 &Private->ServerIp,\r
1665 (UINT8 *) Private->BootFileName,\r
1666 NULL,\r
1667 FALSE\r
1668 );\r
1669 }\r
1670\r
1671 Private->FileSize = (UINTN) *BufferSize;\r
1672\r
1673 return Status;\r
1674}\r
1675\r
1676\r
1677/**\r
1678 GC_NOTO: Add function description\r
1679\r
1680 @param This GC_NOTO: add argument\r
1681 description\r
1682 @param FilePath GC_NOTO: add argument\r
1683 description\r
1684 @param BootPolicy GC_NOTO: add argument\r
1685 description\r
1686 @param BufferSize GC_NOTO: add argument\r
1687 description\r
1688 @param Buffer GC_NOTO: add argument\r
1689 description\r
1690\r
1691 @retval EFI_INVALID_PARAMETER GC_NOTO: Add description for\r
1692 return value\r
1693 @retval EFI_UNSUPPORTED GC_NOTO: Add description for\r
1694 return value\r
1695\r
1696**/\r
1697EFI_STATUS\r
1698EFIAPI\r
1699EfiPxeLoadFile (\r
1700 IN EFI_LOAD_FILE_PROTOCOL * This,\r
1701 IN EFI_DEVICE_PATH_PROTOCOL * FilePath,\r
1702 IN BOOLEAN BootPolicy,\r
1703 IN OUT UINTN *BufferSize,\r
1704 IN VOID *Buffer OPTIONAL\r
1705 )\r
1706{\r
1707 PXEBC_PRIVATE_DATA *Private;\r
1708 EFI_PXE_BASE_CODE_PROTOCOL *PxeBc;\r
1709 BOOLEAN NewMakeCallback;\r
1710 UINTN BlockSize;\r
1711 EFI_STATUS Status;\r
1712 UINT64 TmpBufSize;\r
1713\r
1714 Private = PXEBC_PRIVATE_DATA_FROM_LOADFILE (This);\r
1715 PxeBc = &Private->PxeBc;\r
1716 NewMakeCallback = FALSE;\r
1717 BlockSize = 0x8000;\r
1718 Status = EFI_DEVICE_ERROR;\r
1719\r
1720 if (This == NULL || BufferSize == NULL) {\r
1721\r
1722 return EFI_INVALID_PARAMETER;\r
1723 }\r
1724\r
1725 //\r
1726 // Only support BootPolicy\r
1727 //\r
1728 if (!BootPolicy) {\r
1729 return EFI_UNSUPPORTED;\r
1730 }\r
1731\r
1732 Status = PxeBc->Start (PxeBc, FALSE);\r
1733 if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {\r
1734 return Status;\r
1735 }\r
1736\r
1737 Status = gBS->HandleProtocol (\r
1738 Private->Controller,\r
1739 &gEfiPxeBaseCodeCallbackProtocolGuid,\r
1740 (VOID **) &Private->PxeBcCallback\r
1741 );\r
1742 if (Status == EFI_UNSUPPORTED) {\r
1743\r
1744 CopyMem (&Private->LoadFileCallback, &mPxeBcCallBackTemplate, sizeof (Private->LoadFileCallback));\r
1745\r
1746 Status = gBS->InstallProtocolInterface (\r
1747 &Private->Controller,\r
1748 &gEfiPxeBaseCodeCallbackProtocolGuid,\r
1749 EFI_NATIVE_INTERFACE,\r
1750 &Private->LoadFileCallback\r
1751 );\r
1752\r
1753 NewMakeCallback = (BOOLEAN) (Status == EFI_SUCCESS);\r
1754\r
1755 Status = PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, &NewMakeCallback);\r
1756 if (EFI_ERROR (Status)) {\r
1757 PxeBc->Stop (PxeBc);\r
1758 return Status;\r
1759 }\r
1760 }\r
1761\r
1762 if (Private->FileSize == 0) {\r
1763 TmpBufSize = 0;\r
1764 Status = DiscoverBootFile (Private, &TmpBufSize, Buffer);\r
1765\r
1766 if (sizeof (UINTN) < sizeof (UINT64) && (TmpBufSize > 0xFFFFFFFF)) {\r
1767 Status = EFI_DEVICE_ERROR;\r
1768 } else {\r
1769 *BufferSize = (UINTN) TmpBufSize;\r
1770 }\r
1771 } else if (Buffer == NULL) {\r
1772 *BufferSize = Private->FileSize;\r
1773 Status = EFI_BUFFER_TOO_SMALL;\r
1774 } else {\r
1775 //\r
1776 // Download the file.\r
1777 //\r
1778 TmpBufSize = (UINT64) (*BufferSize);\r
1779 Status = PxeBc->Mtftp (\r
1780 PxeBc,\r
1781 EFI_PXE_BASE_CODE_TFTP_READ_FILE,\r
1782 Buffer,\r
1783 FALSE,\r
1784 &TmpBufSize,\r
1785 &BlockSize,\r
1786 &Private->ServerIp,\r
1787 (UINT8 *) Private->BootFileName,\r
1788 NULL,\r
1789 FALSE\r
1790 );\r
1791 }\r
1792 //\r
1793 // If we added a callback protocol, now is the time to remove it.\r
1794 //\r
1795 if (NewMakeCallback) {\r
1796\r
1797 NewMakeCallback = FALSE;\r
1798\r
1799 PxeBc->SetParameters (PxeBc, NULL, NULL, NULL, NULL, &NewMakeCallback);\r
1800\r
1801 gBS->UninstallProtocolInterface (\r
1802 Private->Controller,\r
1803 &gEfiPxeBaseCodeCallbackProtocolGuid,\r
1804 &Private->LoadFileCallback\r
1805 );\r
1806 }\r
1807 //\r
1808 // Check download status\r
1809 //\r
1810 switch (Status) {\r
1811\r
1812 case EFI_SUCCESS:\r
1813 break;\r
1814\r
1815 case EFI_BUFFER_TOO_SMALL:\r
1816 if (Buffer != NULL) {\r
1817 AsciiPrint ("PXE-E05: Download buffer is smaller than requested file.\n");\r
1818 } else {\r
1819 return Status;\r
1820 }\r
1821 break;\r
1822\r
1823 case EFI_DEVICE_ERROR:\r
1824 AsciiPrint ("PXE-E07: Network device error.\n");\r
1825 break;\r
1826\r
1827 case EFI_OUT_OF_RESOURCES:\r
1828 AsciiPrint ("PXE-E09: Could not allocate I/O buffers.\n");\r
1829 break;\r
1830\r
1831 case EFI_NO_MEDIA:\r
1832 AsciiPrint ("PXE-E12: Could not detect network connection.\n");\r
1833 break;\r
1834\r
1835 case EFI_NO_RESPONSE:\r
1836 AsciiPrint ("PXE-E16: No offer received.\n");\r
1837 break;\r
1838\r
1839 case EFI_TIMEOUT:\r
1840 AsciiPrint ("PXE-E18: Server response timeout.\n");\r
1841 break;\r
1842\r
1843 case EFI_ABORTED:\r
1844 AsciiPrint ("PXE-E21: Remote boot cancelled.\n");\r
1845 break;\r
1846\r
1847 case EFI_ICMP_ERROR:\r
1848 AsciiPrint ("PXE-E22: Client received ICMP error from server.\n");\r
1849 break;\r
1850\r
1851 case EFI_TFTP_ERROR:\r
1852 AsciiPrint ("PXE-E23: Client received TFTP error from server.\n");\r
1853 break;\r
1854\r
1855 default:\r
1856 AsciiPrint ("PXE-E99: Unexpected network error.\n");\r
1857 break;\r
1858 }\r
1859\r
1860 PxeBc->Stop (PxeBc);\r
1861\r
1862 return Status;\r
1863}\r
1864\r
1865EFI_LOAD_FILE_PROTOCOL mLoadFileProtocolTemplate = { EfiPxeLoadFile };\r
1866\r